From c48792c9b229fed93d679cf5e94df93976873583 Mon Sep 17 00:00:00 2001 From: Alan Griffiths Date: Wed, 3 Jul 2024 17:58:58 +0100 Subject: [PATCH 1/3] Add mir-x11-kiosk package --- debian/control | 12 ++ debian/mir-x11-kiosk.install | 2 + examples/CMakeLists.txt | 1 + examples/mir-x11-kiosk/CMakeLists.txt | 17 +++ .../mir-x11-kiosk/mir-x11-kiosk-launch.sh | 20 +++ examples/mir-x11-kiosk/x11_kiosk_main.cpp | 43 ++++++ .../x11_kiosk_window_manager.cpp | 123 ++++++++++++++++++ .../mir-x11-kiosk/x11_kiosk_window_manager.h | 49 +++++++ 8 files changed, 267 insertions(+) create mode 100644 debian/mir-x11-kiosk.install create mode 100644 examples/mir-x11-kiosk/CMakeLists.txt create mode 100755 examples/mir-x11-kiosk/mir-x11-kiosk-launch.sh create mode 100644 examples/mir-x11-kiosk/x11_kiosk_main.cpp create mode 100644 examples/mir-x11-kiosk/x11_kiosk_window_manager.cpp create mode 100644 examples/mir-x11-kiosk/x11_kiosk_window_manager.h diff --git a/debian/control b/debian/control index a05b93b6888..94b8c5472cb 100644 --- a/debian/control +++ b/debian/control @@ -628,3 +628,15 @@ Description: Display server for Ubuntu - generator for Wayland protocol extensio . This can be useful for implementing Wayland protocol extensions not already implemented in Mir. + +Package: mir-x11-kiosk +Architecture: linux-any +Depends: ${misc:Depends}, + ${shlibs:Depends}, + inotify-tools, + mir-platform-graphics-wayland, + xwayland, +Description: Display server for Ubuntu - kiosk hosting X11 apps + . + Contains compositor that use the Mir display server + diff --git a/debian/mir-x11-kiosk.install b/debian/mir-x11-kiosk.install new file mode 100644 index 00000000000..6ee29b24d3e --- /dev/null +++ b/debian/mir-x11-kiosk.install @@ -0,0 +1,2 @@ +usr/bin/mir-x11-kiosk +usr/bin/mir-x11-kiosk-launch diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a6c630d5c13..623ebfec1eb 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -4,5 +4,6 @@ add_subdirectory(miral-shell) add_subdirectory(miral-kiosk) add_subdirectory(miral-system-compositor) add_subdirectory(mir_demo_server) +add_subdirectory(mir-x11-kiosk) add_subdirectory(client) diff --git a/examples/mir-x11-kiosk/CMakeLists.txt b/examples/mir-x11-kiosk/CMakeLists.txt new file mode 100644 index 00000000000..b6cab1ad8fd --- /dev/null +++ b/examples/mir-x11-kiosk/CMakeLists.txt @@ -0,0 +1,17 @@ +mir_add_wrapped_executable(mir-x11-kiosk + x11_kiosk_main.cpp + x11_kiosk_window_manager.cpp x11_kiosk_window_manager.h +) + +target_link_libraries(mir-x11-kiosk PRIVATE miral) + +add_custom_target(mir-x11-kiosk-launch ALL + cp ${CMAKE_CURRENT_SOURCE_DIR}/mir-x11-kiosk-launch.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mir-x11-kiosk-launch +) + +install( + PROGRAMS + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mir-x11-kiosk + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mir-x11-kiosk-launch + DESTINATION ${CMAKE_INSTALL_PREFIX}/bin +) diff --git a/examples/mir-x11-kiosk/mir-x11-kiosk-launch.sh b/examples/mir-x11-kiosk/mir-x11-kiosk-launch.sh new file mode 100755 index 00000000000..a1334bcda4a --- /dev/null +++ b/examples/mir-x11-kiosk/mir-x11-kiosk-launch.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +bindir=$(dirname "$0") + +if [ "${bindir}" != "" ]; then bindir="${bindir}/"; fi + +unset WAYLAND_DISPLAY + +# ${x11_display_file} will contain the X11 display +x11_display_file=$(mktemp) + +MIR_SERVER_ENABLE_X11=1 "${bindir}"mir-x11-kiosk --x11-displayfd 5 5>"${x11_display_file}"& +mir_kiosk_x11_pid=$! + +inotifywait --event close_write "${x11_display_file}" +export DISPLAY +DISPLAY=:$(cat "${x11_display_file}") +rm "${x11_display_file}" +XDG_SESSION_TYPE=mir GDK_BACKEND=x11 QT_QPA_PLATFORM=xcb SDL_VIDEODRIVER=x11 NO_AT_BRIDGE=1 "$@" +kill $mir_kiosk_x11_pid diff --git a/examples/mir-x11-kiosk/x11_kiosk_main.cpp b/examples/mir-x11-kiosk/x11_kiosk_main.cpp new file mode 100644 index 00000000000..4279ea4f41d --- /dev/null +++ b/examples/mir-x11-kiosk/x11_kiosk_main.cpp @@ -0,0 +1,43 @@ +/* + * Copyright © Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU General Public License version 2 or 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Alan Griffiths + */ + +#include "x11_kiosk_window_manager.h" + +#include +#include +#include +#include +#include +#include + +int main(int argc, char const* argv[]) +{ + using namespace miral; + MirRunner runner{argc, argv}; + + DisplayConfiguration display_config{runner}; + + return runner.run_with( + { + display_config, + display_config.layout_option(), + set_window_management_policy(), + Keymap{}, + X11Support{} + }); +} diff --git a/examples/mir-x11-kiosk/x11_kiosk_window_manager.cpp b/examples/mir-x11-kiosk/x11_kiosk_window_manager.cpp new file mode 100644 index 00000000000..7d8d3f1508f --- /dev/null +++ b/examples/mir-x11-kiosk/x11_kiosk_window_manager.cpp @@ -0,0 +1,123 @@ +/* + * Copyright © Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 or 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored By: Alan Griffiths + */ + +#include "x11_kiosk_window_manager.h" + +#include +#include +#include +#include + +#include + +namespace ms = mir::scene; +using namespace miral; +using namespace miral::toolkit; + +bool X11KioskWindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* /*event*/) +{ + return false; +} + +bool X11KioskWindowManagerPolicy::handle_touch_event(MirTouchEvent const* event) +{ + auto const count = mir_touch_event_point_count(event); + + long total_x = 0; + long total_y = 0; + + for (auto i = 0U; i != count; ++i) + { + total_x += mir_touch_event_axis_value(event, i, mir_touch_axis_x); + total_y += mir_touch_event_axis_value(event, i, mir_touch_axis_y); + } + + Point const cursor{total_x/count, total_y/count}; + + tools.select_active_window(tools.window_at(cursor)); + + return false; +} + +bool X11KioskWindowManagerPolicy::handle_pointer_event(MirPointerEvent const* event) +{ + auto const action = mir_pointer_event_action(event); + + Point const cursor{ + mir_pointer_event_axis_value(event, mir_pointer_axis_x), + mir_pointer_event_axis_value(event, mir_pointer_axis_y)}; + + if (action == mir_pointer_action_button_down) + { + tools.select_active_window(tools.window_at(cursor)); + } + + return false; +} + +auto X11KioskWindowManagerPolicy::place_new_window(ApplicationInfo const& app_info, WindowSpecification const& request) +-> WindowSpecification +{ + WindowSpecification specification = CanonicalWindowManagerPolicy::place_new_window(app_info, request); + + if ((specification.type() == mir_window_type_normal || specification.type() == mir_window_type_freestyle) && + (!specification.parent().is_set() || !specification.parent().value().lock())) + { + specification.state() = mir_window_state_fullscreen; + specification.size() = mir::optional_value{}; // Ignore requested size (if any) when we maximize + tools.place_and_size_for_state(specification, WindowInfo{}); + + if (!request.state().is_set() || request.state().value() != mir_window_state_restored) + specification.state() = request.state(); + } + + return specification; +} + +void X11KioskWindowManagerPolicy::handle_modify_window(WindowInfo& window_info, WindowSpecification const& modifications) +{ + WindowSpecification specification = modifications; + + if ((window_info.type() == mir_window_type_normal || window_info.type() == mir_window_type_freestyle) && + !window_info.parent()) + { + specification.state() = mir_window_state_fullscreen; + specification.size() = mir::optional_value{}; // Ignore requested size (if any) when we maximize + tools.place_and_size_for_state(specification, window_info); + + if (!modifications.state().is_set() || modifications.state().value() != mir_window_state_restored) + specification.state() = modifications.state(); + } + + CanonicalWindowManagerPolicy::handle_modify_window(window_info, specification); +} + +void X11KioskWindowManagerPolicy::handle_request_move(WindowInfo& /*window_info*/, MirInputEvent const* /*input_event*/) +{ +} + +void X11KioskWindowManagerPolicy::handle_request_resize(WindowInfo& /*window_info*/, MirInputEvent const* /*input_event*/, MirResizeEdge /*edge*/) +{ +} + +Rectangle +X11KioskWindowManagerPolicy::confirm_placement_on_display(WindowInfo const& /*window_info*/, MirWindowState /*new_state*/, + Rectangle const& new_placement) +{ + return new_placement; +} diff --git a/examples/mir-x11-kiosk/x11_kiosk_window_manager.h b/examples/mir-x11-kiosk/x11_kiosk_window_manager.h new file mode 100644 index 00000000000..d003bbcbc97 --- /dev/null +++ b/examples/mir-x11-kiosk/x11_kiosk_window_manager.h @@ -0,0 +1,49 @@ +/* + * Copyright © Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 or 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored By: Alan Griffiths + */ + +#ifndef MIRAL_X11_KIOSK_WINDOW_MANAGER_H +#define MIRAL_X11_KIOSK_WINDOW_MANAGER_H + +#include + +#include + +using namespace mir::geometry; + +class X11KioskWindowManagerPolicy : public miral::CanonicalWindowManagerPolicy +{ +public: + using miral::CanonicalWindowManagerPolicy::CanonicalWindowManagerPolicy; + + auto place_new_window(miral::ApplicationInfo const& app_info, miral::WindowSpecification const& request) + -> miral::WindowSpecification override; + + bool handle_keyboard_event(MirKeyboardEvent const* event) override; + bool handle_touch_event(MirTouchEvent const* event) override; + bool handle_pointer_event(MirPointerEvent const* event) override; + void handle_modify_window(miral::WindowInfo& window_info, miral::WindowSpecification const& modifications) override; + + void handle_request_move(miral::WindowInfo& window_info, MirInputEvent const* input_event) override; + void handle_request_resize(miral::WindowInfo& window_info, MirInputEvent const* input_event, + MirResizeEdge edge) override; + + auto confirm_placement_on_display(const miral::WindowInfo& window_info, MirWindowState new_state, + Rectangle const& new_placement) -> Rectangle override; +}; + +#endif /* MIRAL_X11_KIOSK_WINDOW_MANAGER_H */ From 888f06b946e31a787b79fe7f239e29bb17472edf Mon Sep 17 00:00:00 2001 From: Alan Griffiths Date: Wed, 10 Jul 2024 10:36:36 +0100 Subject: [PATCH 2/3] Drop author from header comments --- examples/mir-x11-kiosk/x11_kiosk_main.cpp | 2 -- examples/mir-x11-kiosk/x11_kiosk_window_manager.cpp | 2 -- examples/mir-x11-kiosk/x11_kiosk_window_manager.h | 2 -- 3 files changed, 6 deletions(-) diff --git a/examples/mir-x11-kiosk/x11_kiosk_main.cpp b/examples/mir-x11-kiosk/x11_kiosk_main.cpp index 4279ea4f41d..4db4b5d31c1 100644 --- a/examples/mir-x11-kiosk/x11_kiosk_main.cpp +++ b/examples/mir-x11-kiosk/x11_kiosk_main.cpp @@ -12,8 +12,6 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * - * Authored by: Alan Griffiths */ #include "x11_kiosk_window_manager.h" diff --git a/examples/mir-x11-kiosk/x11_kiosk_window_manager.cpp b/examples/mir-x11-kiosk/x11_kiosk_window_manager.cpp index 7d8d3f1508f..cfd0d0524e5 100644 --- a/examples/mir-x11-kiosk/x11_kiosk_window_manager.cpp +++ b/examples/mir-x11-kiosk/x11_kiosk_window_manager.cpp @@ -12,8 +12,6 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * - * Authored By: Alan Griffiths */ #include "x11_kiosk_window_manager.h" diff --git a/examples/mir-x11-kiosk/x11_kiosk_window_manager.h b/examples/mir-x11-kiosk/x11_kiosk_window_manager.h index d003bbcbc97..4751d4056ba 100644 --- a/examples/mir-x11-kiosk/x11_kiosk_window_manager.h +++ b/examples/mir-x11-kiosk/x11_kiosk_window_manager.h @@ -12,8 +12,6 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * - * Authored By: Alan Griffiths */ #ifndef MIRAL_X11_KIOSK_WINDOW_MANAGER_H From 30f421a6b6122cbe6ccd39fea8cdee048f6c8531 Mon Sep 17 00:00:00 2001 From: Alan Griffiths Date: Fri, 12 Jul 2024 09:40:20 +0100 Subject: [PATCH 3/3] Better English --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 94b8c5472cb..b8a65a3c2ad 100644 --- a/debian/control +++ b/debian/control @@ -638,5 +638,5 @@ Depends: ${misc:Depends}, xwayland, Description: Display server for Ubuntu - kiosk hosting X11 apps . - Contains compositor that use the Mir display server + Contains an "X11 kiosk" compositor based on the Mir display server