diff --git a/src/server/frontend_xwayland/xwayland_wm.cpp b/src/server/frontend_xwayland/xwayland_wm.cpp index 14aa8f7dd94..80fa913b14f 100644 --- a/src/server/frontend_xwayland/xwayland_wm.cpp +++ b/src/server/frontend_xwayland/xwayland_wm.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #ifndef ARRAY_LENGTH #define ARRAY_LENGTH(a) mir::frontend::length_of(a) @@ -307,75 +308,18 @@ void mf::XWaylandWM::handle_events() while (xcb_generic_event_t* const event = xcb_poll_for_event(xcb_connection)) { - int type = event->response_type & ~0x80; - switch (type) + try { - case XCB_BUTTON_PRESS: - case XCB_BUTTON_RELEASE: - if (verbose_xwayland_logging_enabled()) - log_debug("XCB_BUTTON_RELEASE"); - //(reinterpret_cast(event)); - break; - case XCB_ENTER_NOTIFY: - if (verbose_xwayland_logging_enabled()) - log_debug("XCB_ENTER_NOTIFY"); - //(reinterpret_cast(event)); - break; - case XCB_LEAVE_NOTIFY: - if (verbose_xwayland_logging_enabled()) - log_debug("XCB_LEAVE_NOTIFY"); - //(reinterpret_cast(event)); - break; - case XCB_MOTION_NOTIFY: - handle_motion_notify(reinterpret_cast(event)); - //(reinterpret_cast(event)); - break; - case XCB_CREATE_NOTIFY: - handle_create_notify(reinterpret_cast(event)); - break; - case XCB_MAP_REQUEST: - handle_map_request(reinterpret_cast(event)); - break; - case XCB_MAP_NOTIFY: - if (verbose_xwayland_logging_enabled()) - log_debug("XCB_MAP_NOTIFY"); - //(reinterpret_cast(event)); - break; - case XCB_UNMAP_NOTIFY: - handle_unmap_notify(reinterpret_cast(event)); - break; - case XCB_REPARENT_NOTIFY: - if (verbose_xwayland_logging_enabled()) - log_debug("XCB_REPARENT_NOTIFY"); - //(reinterpret_cast(event)); - break; - case XCB_CONFIGURE_REQUEST: - handle_configure_request(reinterpret_cast(event)); - break; - case XCB_CONFIGURE_NOTIFY: - handle_configure_notify(reinterpret_cast(event)); - break; - case XCB_DESTROY_NOTIFY: - handle_destroy_notify(reinterpret_cast(event)); - break; - case XCB_MAPPING_NOTIFY: - if (verbose_xwayland_logging_enabled()) - log_debug("XCB_MAPPING_NOTIFY"); - break; - case XCB_PROPERTY_NOTIFY: - handle_property_notify(reinterpret_cast(event)); - break; - case XCB_CLIENT_MESSAGE: - handle_client_message(reinterpret_cast(event)); - break; - case XCB_FOCUS_IN: - if (verbose_xwayland_logging_enabled()) - log_debug("XCB_FOCUS_IN"); - //(reinterpret_cast(event)); - default: - break; + handle_event(event); + } + catch (...) + { + log( + logging::Severity::warning, + MIR_LOG_COMPONENT, + std::current_exception(), + "Failed to handle xcb event."); } - free(event); got_events = true; } @@ -386,6 +330,78 @@ void mf::XWaylandWM::handle_events() } } +void mf::XWaylandWM::handle_event(xcb_generic_event_t* event) +{ + int type = event->response_type & ~0x80; + switch (type) + { + case XCB_BUTTON_PRESS: + case XCB_BUTTON_RELEASE: + if (verbose_xwayland_logging_enabled()) + log_debug("XCB_BUTTON_RELEASE"); + //(reinterpret_cast(event)); + break; + case XCB_ENTER_NOTIFY: + if (verbose_xwayland_logging_enabled()) + log_debug("XCB_ENTER_NOTIFY"); + //(reinterpret_cast(event)); + break; + case XCB_LEAVE_NOTIFY: + if (verbose_xwayland_logging_enabled()) + log_debug("XCB_LEAVE_NOTIFY"); + //(reinterpret_cast(event)); + break; + case XCB_MOTION_NOTIFY: + handle_motion_notify(reinterpret_cast(event)); + //(reinterpret_cast(event)); + break; + case XCB_CREATE_NOTIFY: + handle_create_notify(reinterpret_cast(event)); + break; + case XCB_MAP_REQUEST: + handle_map_request(reinterpret_cast(event)); + break; + case XCB_MAP_NOTIFY: + if (verbose_xwayland_logging_enabled()) + log_debug("XCB_MAP_NOTIFY"); + //(reinterpret_cast(event)); + break; + case XCB_UNMAP_NOTIFY: + handle_unmap_notify(reinterpret_cast(event)); + break; + case XCB_REPARENT_NOTIFY: + if (verbose_xwayland_logging_enabled()) + log_debug("XCB_REPARENT_NOTIFY"); + //(reinterpret_cast(event)); + break; + case XCB_CONFIGURE_REQUEST: + handle_configure_request(reinterpret_cast(event)); + break; + case XCB_CONFIGURE_NOTIFY: + handle_configure_notify(reinterpret_cast(event)); + break; + case XCB_DESTROY_NOTIFY: + handle_destroy_notify(reinterpret_cast(event)); + break; + case XCB_MAPPING_NOTIFY: + if (verbose_xwayland_logging_enabled()) + log_debug("XCB_MAPPING_NOTIFY"); + break; + case XCB_PROPERTY_NOTIFY: + handle_property_notify(reinterpret_cast(event)); + break; + case XCB_CLIENT_MESSAGE: + handle_client_message(reinterpret_cast(event)); + break; + case XCB_FOCUS_IN: + if (verbose_xwayland_logging_enabled()) + log_debug("XCB_FOCUS_IN"); + //(reinterpret_cast(event)); + default: + break; + } +} + void mf::XWaylandWM::handle_property_notify(xcb_property_notify_event_t *event) { if (verbose_xwayland_logging_enabled()) @@ -443,7 +459,14 @@ void mf::XWaylandWM::handle_create_notify(xcb_create_notify_event_t *event) log_warning("border width unsupported (border width %d)", event->border_width); } - surfaces[event->window] = std::make_shared(this, event); + if (!is_ours(event->window)) + { + if (surfaces.find(event->window) != surfaces.end()) + BOOST_THROW_EXCEPTION( + std::runtime_error(get_window_debug_string(event->window) + " created, but already known")); + + surfaces[event->window] = std::make_shared(this, event); + } } void mf::XWaylandWM::handle_motion_notify(xcb_motion_notify_event_t *event) @@ -549,15 +572,6 @@ void mf::XWaylandWM::handle_move_resize(std::shared_ptr surfa surface->move_resize(detail); } -void mf::XWaylandWM::handle_change_state(std::shared_ptr surface, xcb_client_message_event_t *event) -{ - if (!surface || !event) - return; - - if (event->data.data32[0] == 3) - surface->set_state(mir_window_state_minimized); -} - void mf::XWaylandWM::handle_state(std::shared_ptr surface, xcb_client_message_event_t *event) { if (!surface || !event) diff --git a/src/server/frontend_xwayland/xwayland_wm.h b/src/server/frontend_xwayland/xwayland_wm.h index 92c4682717b..184b9b280a3 100644 --- a/src/server/frontend_xwayland/xwayland_wm.h +++ b/src/server/frontend_xwayland/xwayland_wm.h @@ -113,13 +113,13 @@ class XWaylandWM // Event handeling void handle_events(); + void handle_event(xcb_generic_event_t* event); // Events void handle_create_notify(xcb_create_notify_event_t *event); void handle_motion_notify(xcb_motion_notify_event_t *event); void handle_property_notify(xcb_property_notify_event_t *event); void handle_map_request(xcb_map_request_event_t *event); - void handle_change_state(std::shared_ptr surface, xcb_client_message_event_t *event); void handle_state(std::shared_ptr surface, xcb_client_message_event_t *event); void handle_surface_id(std::shared_ptr surface, xcb_client_message_event_t *event); void handle_move_resize(std::shared_ptr surface, xcb_client_message_event_t *event);