diff options
Diffstat (limited to 'intern/ghost')
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWayland.cpp | 69 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWayland.cpp | 12 |
2 files changed, 72 insertions, 9 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 67270d26ed3..528aa6e1884 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -1157,6 +1157,18 @@ static void gwl_registry_entry_update_all(GWL_Display *display, const int interf /** \name Private Utility Functions * \{ */ +static void ghost_wl_display_report_error(struct wl_display *display) +{ + int ecode = wl_display_get_error(display); + GHOST_ASSERT(ecode, "Error not set!"); + if ((ecode == EPIPE || ecode == ECONNRESET)) { + fprintf(stderr, "The Wayland connection broke. Did the Wayland compositor die?\n"); + } + else { + fprintf(stderr, "The Wayland connection experienced a fatal error: %s\n", strerror(ecode)); + } +} + /** * Callback for WAYLAND to run when there is an error. * @@ -1264,6 +1276,12 @@ static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym) GXMAP(gkey, XKB_KEY_XF86AudioStop, GHOST_kKeyMediaStop); GXMAP(gkey, XKB_KEY_XF86AudioPrev, GHOST_kKeyMediaFirst); GXMAP(gkey, XKB_KEY_XF86AudioNext, GHOST_kKeyMediaLast); + + /* Additional keys for non US layouts. */ + + /* Uses the same physical key as #XKB_KEY_KP_Decimal for QWERTZ layout, see: T102287. */ + GXMAP(gkey, XKB_KEY_KP_Separator, GHOST_kKeyNumpadPeriod); + default: /* Rely on #xkb_map_gkey_or_scan_code to report when no key can be found. */ gkey = GHOST_kKeyUnknown; @@ -4013,7 +4031,8 @@ static void gwl_seat_capability_touch_disable(GWL_Seat *seat) } static void seat_handle_capabilities(void *data, - struct wl_seat *wl_seat, + /* Only used in an assert. */ + [[maybe_unused]] struct wl_seat *wl_seat, const uint32_t capabilities) { CLOG_INFO(LOG, @@ -4978,6 +4997,42 @@ static const struct wl_registry_listener registry_listener = { /** \} */ /* -------------------------------------------------------------------- */ +/** \name Listener (Display), #wl_display_listener + * \{ */ + +static CLG_LogRef LOG_WL_DISPLAY = {"ghost.wl.handle.display"}; +#define LOG (&LOG_WL_DISPLAY) + +static void display_handle_error( + void *data, struct wl_display *wl_display, void *object_id, uint32_t code, const char *message) +{ + GWL_Display *display = static_cast<GWL_Display *>(data); + GHOST_ASSERT(display->wl_display == wl_display, "Invalid internal state"); + (void)display; + + /* NOTE: code is #wl_display_error, there isn't a convenient way to convert to an ID. */ + CLOG_INFO(LOG, 2, "error (code=%u, object_id=%p, message=%s)", code, object_id, message); +} + +static void display_handle_delete_id(void *data, struct wl_display *wl_display, uint32_t id) +{ + GWL_Display *display = static_cast<GWL_Display *>(data); + GHOST_ASSERT(display->wl_display == wl_display, "Invalid internal state"); + (void)display; + + CLOG_INFO(LOG, 2, "delete_id (id=%u)", id); +} + +static const struct wl_display_listener display_listener = { + display_handle_error, + display_handle_delete_id, +}; + +#undef LOG + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name GHOST Implementation * * WAYLAND specific implementation of the #GHOST_System interface. @@ -4999,6 +5054,8 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) /* This may be removed later if decorations are required, needed as part of registration. */ display_->xdg_decor = new GWL_XDG_Decor_System; + wl_display_add_listener(display_->wl_display, &display_listener, display_); + /* Register interfaces. */ { display_->registry_skip_update_all = true; @@ -5058,6 +5115,8 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) } } else +#else + (void)background; #endif { GWL_XDG_Decor_System &decor = *display_->xdg_decor; @@ -5105,10 +5164,14 @@ bool GHOST_SystemWayland::processEvents(bool waitForEvent) #endif /* WITH_INPUT_NDOF */ if (waitForEvent) { - wl_display_dispatch(display_->wl_display); + if (wl_display_dispatch(display_->wl_display) == -1) { + ghost_wl_display_report_error(display_->wl_display); + } } else { - wl_display_roundtrip(display_->wl_display); + if (wl_display_roundtrip(display_->wl_display) == -1) { + ghost_wl_display_report_error(display_->wl_display); + } } if (getEventManager()->getNumEvents() > 0) { diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index ad94a02b514..9d62c69edef 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -219,7 +219,7 @@ static void xdg_toplevel_handle_close(void *data, xdg_toplevel * /*xdg_toplevel* static_cast<GWL_Window *>(data)->ghost_window->close(); } -static const xdg_toplevel_listener toplevel_listener = { +static const xdg_toplevel_listener xdg_toplevel_listener = { xdg_toplevel_handle_configure, xdg_toplevel_handle_close, }; @@ -322,7 +322,7 @@ static void xdg_toplevel_decoration_handle_configure( static_cast<GWL_Window *>(data)->xdg_decor->mode = (zxdg_toplevel_decoration_v1_mode)mode; } -static const zxdg_toplevel_decoration_v1_listener toplevel_decoration_v1_listener = { +static const zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_v1_listener = { xdg_toplevel_decoration_handle_configure, }; @@ -418,7 +418,7 @@ static void surface_handle_leave(void *data, } } -static struct wl_surface_listener wl_surface_listener = { +static const struct wl_surface_listener wl_surface_listener = { surface_handle_enter, surface_handle_leave, }; @@ -483,7 +483,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, wl_surface_set_buffer_scale(window_->wl_surface, window_->scale); - wl_surface_add_listener(window_->wl_surface, &wl_surface_listener, this); + wl_surface_add_listener(window_->wl_surface, &wl_surface_listener, window_); window_->egl_window = wl_egl_window_create( window_->wl_surface, int(window_->size[0]), int(window_->size[1])); @@ -537,13 +537,13 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, decor.toplevel_decor = zxdg_decoration_manager_v1_get_toplevel_decoration( system_->xdg_decor_manager(), decor.toplevel); zxdg_toplevel_decoration_v1_add_listener( - decor.toplevel_decor, &toplevel_decoration_v1_listener, window_); + decor.toplevel_decor, &xdg_toplevel_decoration_v1_listener, window_); zxdg_toplevel_decoration_v1_set_mode(decor.toplevel_decor, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); } xdg_surface_add_listener(decor.surface, &xdg_surface_listener, window_); - xdg_toplevel_add_listener(decor.toplevel, &toplevel_listener, window_); + xdg_toplevel_add_listener(decor.toplevel, &xdg_toplevel_listener, window_); if (parentWindow && is_dialog) { WGL_XDG_Decor_Window &decor_parent = |