From e9a714466ae10c3be2875f4777491f845fe6e182 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Tue, 2 Feb 2021 18:38:43 +0100 Subject: [PATCH 01/36] wayland: Split geometry hint sync from shadow sync --- gdk/wayland/gdksurface-wayland.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 124bcdd1b70..f8f63af64f1 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -316,6 +316,7 @@ static void gdk_wayland_surface_configure (GdkSurface *surface); static void maybe_set_gtk_surface_dbus_properties (GdkWaylandSurface *impl); static void maybe_set_gtk_surface_modal (GdkSurface *surface); +static void gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface); static void gdk_wayland_surface_sync_shadow (GdkSurface *surface); static void gdk_wayland_surface_sync_input_region (GdkSurface *surface); static void gdk_wayland_surface_sync_opaque_region (GdkSurface *surface); @@ -933,6 +934,7 @@ gdk_wayland_surface_attach_image (GdkSurface *surface, void gdk_wayland_surface_sync (GdkSurface *surface) { + gdk_wayland_surface_sync_geometry_hints (surface); gdk_wayland_surface_sync_shadow (surface); gdk_wayland_surface_sync_opaque_region (surface); gdk_wayland_surface_sync_input_region (surface); @@ -1193,11 +1195,9 @@ static void gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, GdkSurfaceHints geom_mask); static void -gdk_wayland_surface_sync_shadow (GdkSurface *surface) +gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - GdkWaylandDisplay *display_wayland = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkRectangle geometry; if (!is_realized_shell_surface (impl)) @@ -1207,6 +1207,20 @@ gdk_wayland_surface_sync_shadow (GdkSurface *surface) gdk_wayland_surface_set_geometry_hints (impl, &impl->geometry_hints, impl->geometry_mask); +} + +static void +gdk_wayland_surface_sync_shadow (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + GdkRectangle geometry; + + if (!is_realized_shell_surface (impl)) + return; + + gdk_wayland_surface_get_window_geometry (surface, &geometry); if (gdk_rectangle_equal (&geometry, &impl->last_sent_window_geometry)) return; -- GitLab From 35575fa9d040d1824a6710ecad85f5b8f4ef952a Mon Sep 17 00:00:00 2001 From: David Keijser Date: Sun, 20 Dec 2020 20:29:44 +0100 Subject: [PATCH 02/36] wayland: Split out gdktoplevel-wayland --- gdk/wayland/gdksurface-wayland.c | 2083 ++--------------------------- gdk/wayland/gdksurface-wayland.h | 194 +++ gdk/wayland/gdktoplevel-wayland.c | 1887 ++++++++++++++++++++++++++ gdk/wayland/gdkwayland.h | 1 + gdk/wayland/gdkwaylandsurface.h | 30 - gdk/wayland/gdkwaylandtoplevel.h | 73 + gdk/wayland/meson.build | 1 + 7 files changed, 2247 insertions(+), 2022 deletions(-) create mode 100644 gdk/wayland/gdktoplevel-wayland.c create mode 100644 gdk/wayland/gdkwaylandtoplevel.h diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index f8f63af64f1..fe2e99500b1 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -74,200 +74,9 @@ #define MAX_WL_BUFFER_SIZE (4083) /* 4096 minus header, string argument length and NUL byte */ -typedef enum _PopupState -{ - POPUP_STATE_IDLE, - POPUP_STATE_WAITING_FOR_REPOSITIONED, - POPUP_STATE_WAITING_FOR_CONFIGURE, - POPUP_STATE_WAITING_FOR_FRAME, -} PopupState; - -struct _GdkWaylandSurface -{ - GdkSurface parent_instance; - - struct { - /* The wl_outputs that this surface currently touches */ - GSList *outputs; - - struct wl_surface *wl_surface; - - struct xdg_surface *xdg_surface; - struct xdg_toplevel *xdg_toplevel; - struct xdg_popup *xdg_popup; - - /* Legacy xdg-shell unstable v6 fallback support */ - struct zxdg_surface_v6 *zxdg_surface_v6; - struct zxdg_toplevel_v6 *zxdg_toplevel_v6; - struct zxdg_popup_v6 *zxdg_popup_v6; - - struct gtk_surface1 *gtk_surface; - struct wl_egl_window *egl_window; - struct wl_egl_window *dummy_egl_window; - struct zxdg_exported_v1 *xdg_exported; - struct org_kde_kwin_server_decoration *server_decoration; - } display_server; - - struct wl_event_queue *event_queue; - - EGLSurface egl_surface; - EGLSurface dummy_egl_surface; - - uint32_t reposition_token; - uint32_t received_reposition_token; - - PopupState popup_state; - - unsigned int initial_configure_received : 1; - unsigned int has_uncommitted_ack_configure : 1; - unsigned int mapped : 1; - unsigned int awaiting_frame : 1; - unsigned int awaiting_frame_frozen : 1; - unsigned int is_drag_surface : 1; - - int pending_buffer_offset_x; - int pending_buffer_offset_y; - - char *title; - - struct { - gboolean was_set; - - char *application_id; - char *app_menu_path; - char *menubar_path; - char *window_object_path; - char *application_object_path; - char *unique_bus_name; - } application; - - GdkGeometry geometry_hints; - GdkSurfaceHints geometry_mask; - - GdkSeat *grab_input_seat; - - gint64 pending_frame_counter; - guint32 scale; - - int shadow_left; - int shadow_right; - int shadow_top; - int shadow_bottom; - gboolean shadow_dirty; - - struct wl_output *initial_fullscreen_output; - - cairo_region_t *opaque_region; - gboolean opaque_region_dirty; - - cairo_region_t *input_region; - gboolean input_region_dirty; - - GdkRectangle last_sent_window_geometry; - int last_sent_min_width; - int last_sent_min_height; - int last_sent_max_width; - int last_sent_max_height; - - int saved_width; - int saved_height; - - gulong parent_surface_committed_handler; - - struct { - GdkToplevelLayout *layout; - } toplevel; - - struct { - GdkPopupLayout *layout; - int unconstrained_width; - int unconstrained_height; - } popup; - - struct { - struct { - int width; - int height; - GdkToplevelState state; - gboolean is_resizing; - } toplevel; - - struct { - int x; - int y; - int width; - int height; - uint32_t repositioned_token; - gboolean has_repositioned_token; - } popup; - - gboolean is_initial_configure; - - uint32_t serial; - gboolean is_dirty; - } pending; - - struct { - GdkToplevelState unset_flags; - GdkToplevelState set_flags; - } initial_state; - - struct { - struct { - gboolean should_constrain; - gboolean size_is_fixed; - } toplevel; - struct { - int x; - int y; - } popup; - int configured_width; - int configured_height; - gboolean surface_geometry_dirty; - } next_layout; - - uint32_t last_configure_serial; - - int state_freeze_count; - - struct { - GdkWaylandToplevelExported callback; - gpointer user_data; - GDestroyNotify destroy_func; - } exported; - - struct zxdg_imported_v1 *imported_transient_for; - GHashTable *shortcuts_inhibitors; - - struct zwp_idle_inhibitor_v1 *idle_inhibitor; - size_t idle_inhibitor_refcount; -}; - -typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass; -struct _GdkWaylandSurfaceClass -{ - GdkSurfaceClass parent_class; -}; - G_DEFINE_TYPE (GdkWaylandSurface, gdk_wayland_surface, GDK_TYPE_SURFACE) -struct _GdkWaylandToplevel -{ - GdkWaylandSurface parent_instance; - - GdkWaylandToplevel *transient_for; -}; - -typedef struct -{ - GdkWaylandSurfaceClass parent_class; -} GdkWaylandToplevelClass; - -static void gdk_wayland_toplevel_iface_init (GdkToplevelInterface *iface); -G_DEFINE_TYPE_WITH_CODE (GdkWaylandToplevel, gdk_wayland_toplevel, GDK_TYPE_WAYLAND_SURFACE, - G_IMPLEMENT_INTERFACE (GDK_TYPE_TOPLEVEL, - gdk_wayland_toplevel_iface_init)) struct _GdkWaylandPopup { @@ -313,16 +122,11 @@ static void gdk_wayland_surface_maybe_resize (GdkSurface *surface, static void gdk_wayland_surface_configure (GdkSurface *surface); -static void maybe_set_gtk_surface_dbus_properties (GdkWaylandSurface *impl); -static void maybe_set_gtk_surface_modal (GdkSurface *surface); - static void gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface); static void gdk_wayland_surface_sync_shadow (GdkSurface *surface); static void gdk_wayland_surface_sync_input_region (GdkSurface *surface); static void gdk_wayland_surface_sync_opaque_region (GdkSurface *surface); -static void unset_transient_for_exported (GdkSurface *surface); - static void gdk_wayland_surface_move_resize (GdkSurface *surface, int x, int y, @@ -376,23 +180,6 @@ gdk_wayland_surface_thaw_state (GdkSurface *surface) g_assert (!impl->display_server.xdg_popup); } -static void -_gdk_wayland_surface_save_size (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - if (surface->state & (GDK_TOPLEVEL_STATE_FULLSCREEN | - GDK_TOPLEVEL_STATE_MAXIMIZED | - GDK_TOPLEVEL_STATE_TILED)) - return; - - if (surface->width <= 1 || surface->height <= 1) - return; - - impl->saved_width = surface->width - impl->shadow_left - impl->shadow_right; - impl->saved_height = surface->height - impl->shadow_top - impl->shadow_bottom; -} - static void _gdk_wayland_surface_clear_saved_size (GdkSurface *surface) { @@ -800,8 +587,6 @@ gdk_wayland_surface_update_scale (GdkSurface *surface) } static void gdk_wayland_surface_create_surface (GdkSurface *surface); -static void gdk_wayland_surface_set_title (GdkSurface *surface, - const char *title); GdkSurface * _gdk_wayland_display_create_surface (GdkDisplay *display, @@ -1036,8 +821,6 @@ is_realized_popup (GdkWaylandSurface *impl) impl->display_server.zxdg_popup_v6); } -static void gdk_wayland_surface_show (GdkSurface *surface, - gboolean already_mapped); static void gdk_wayland_surface_hide (GdkSurface *surface); static void @@ -1073,82 +856,7 @@ gdk_wayland_surface_maybe_resize (GdkSurface *surface, gdk_wayland_surface_show (surface, FALSE); } -static void -gdk_wayland_surface_sync_parent (GdkSurface *surface, - GdkSurface *parent) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - GdkWaylandToplevel *toplevel = GDK_WAYLAND_TOPLEVEL (impl); - GdkWaylandDisplay *display_wayland = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - GdkWaylandSurface *impl_parent = NULL; - - g_assert (parent == NULL || - gdk_surface_get_display (surface) == gdk_surface_get_display (parent)); - - if (!is_realized_toplevel (impl)) - return; - - if (toplevel->transient_for) - impl_parent = GDK_WAYLAND_SURFACE (toplevel->transient_for); - else if (parent) - impl_parent = GDK_WAYLAND_SURFACE (parent); - - /* XXX: Is this correct? */ - if (impl_parent && !impl_parent->display_server.wl_surface) - return; - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - { - struct xdg_toplevel *parent_toplevel; - - if (impl_parent) - parent_toplevel = impl_parent->display_server.xdg_toplevel; - else - parent_toplevel = NULL; - - xdg_toplevel_set_parent (impl->display_server.xdg_toplevel, - parent_toplevel); - break; - } - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - { - struct zxdg_toplevel_v6 *parent_toplevel; - - if (impl_parent) - parent_toplevel = impl_parent->display_server.zxdg_toplevel_v6; - else - parent_toplevel = NULL; - - zxdg_toplevel_v6_set_parent (impl->display_server.zxdg_toplevel_v6, - parent_toplevel); - break; - } - default: - g_assert_not_reached (); - } -} - -static void -gdk_wayland_surface_sync_parent_of_imported (GdkWaylandSurface *impl) -{ - if (!impl->display_server.wl_surface) - return; - - if (!impl->imported_transient_for) - return; - - if (!is_realized_toplevel (impl)) - return; - - zxdg_imported_v1_set_parent_of (impl->imported_transient_for, - impl->display_server.wl_surface); -} - -static void +void gdk_wayland_surface_sync_title (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); @@ -1190,10 +898,6 @@ gdk_wayland_surface_get_window_geometry (GdkSurface *surface, }; } -static void gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, - const GdkGeometry *geometry, - GdkSurfaceHints geom_mask); - static void gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface) { @@ -1466,120 +1170,6 @@ configure_toplevel_geometry (GdkSurface *surface) } } -static void -synthesize_initial_surface_state (GdkSurface *surface, - GdkToplevelState unset_flags, - GdkToplevelState set_flags) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - impl->initial_state.unset_flags |= unset_flags; - impl->initial_state.set_flags &= ~unset_flags; - - impl->initial_state.set_flags |= set_flags; - impl->initial_state.unset_flags &= ~set_flags; -} - -static void -gdk_wayland_surface_configure_toplevel (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - GdkWaylandDisplay *display_wayland = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - GdkToplevelState new_state; - int width, height; - gboolean is_resizing; - gboolean fixed_size; - gboolean saved_size; - - new_state = impl->pending.toplevel.state; - impl->pending.toplevel.state = 0; - - is_resizing = impl->pending.toplevel.is_resizing; - impl->pending.toplevel.is_resizing = FALSE; - - fixed_size = - new_state & (GDK_TOPLEVEL_STATE_MAXIMIZED | - GDK_TOPLEVEL_STATE_FULLSCREEN | - GDK_TOPLEVEL_STATE_TILED) || - is_resizing; - - width = impl->pending.toplevel.width; - height = impl->pending.toplevel.height; - - saved_size = (width == 0 && height == 0); - /* According to xdg_shell, an xdg_surface.configure with size 0x0 - * should be interpreted as that it is up to the client to set a - * size. - * - * When transitioning from maximize or fullscreen state, this means - * the client should configure its size back to what it was before - * being maximize or fullscreen. - */ - if (saved_size && !fixed_size) - { - width = impl->saved_width; - height = impl->saved_height; - } - - if (width > 0 && height > 0) - { - if (!saved_size) - { - impl->next_layout.toplevel.should_constrain = TRUE; - - /* Save size for next time we get 0x0 */ - _gdk_wayland_surface_save_size (surface); - } - else if (is_resizing) - { - impl->next_layout.toplevel.should_constrain = TRUE; - } - else - { - impl->next_layout.toplevel.should_constrain = FALSE; - } - - impl->next_layout.toplevel.size_is_fixed = fixed_size; - impl->next_layout.configured_width = width; - impl->next_layout.configured_height = height; - } - else - { - impl->next_layout.toplevel.should_constrain = FALSE; - impl->next_layout.toplevel.size_is_fixed = FALSE; - impl->next_layout.configured_width = 0; - impl->next_layout.configured_height = 0; - } - - impl->next_layout.surface_geometry_dirty = TRUE; - gdk_surface_request_layout (surface); - - GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS, - g_message ("configure, surface %p %dx%d,%s%s%s%s", - surface, width, height, - (new_state & GDK_TOPLEVEL_STATE_FULLSCREEN) ? " fullscreen" : "", - (new_state & GDK_TOPLEVEL_STATE_MAXIMIZED) ? " maximized" : "", - (new_state & GDK_TOPLEVEL_STATE_FOCUSED) ? " focused" : "", - (new_state & GDK_TOPLEVEL_STATE_TILED) ? " tiled" : "")); - - gdk_surface_queue_state_change (surface, ~0 & ~new_state, new_state); - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_surface_ack_configure (impl->display_server.xdg_surface, - impl->pending.serial); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6, - impl->pending.serial); - break; - default: - g_assert_not_reached (); - } -} - static void gdk_wayland_surface_configure_popup (GdkSurface *surface) { @@ -1693,34 +1283,6 @@ gdk_wayland_surface_handle_configure (GdkSurface *surface, gdk_wayland_surface_configure (surface); } -static void -gdk_wayland_surface_handle_configure_toplevel (GdkSurface *surface, - int32_t width, - int32_t height, - GdkToplevelState state) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - impl->pending.toplevel.state |= state; - impl->pending.toplevel.width = width; - impl->pending.toplevel.height = height; -} - -static void -gdk_wayland_surface_handle_close (GdkSurface *surface) -{ - GdkDisplay *display; - GdkEvent *event; - - display = gdk_surface_get_display (surface); - - GDK_DISPLAY_NOTE (display, EVENTS, g_message ("close %p", surface)); - - event = gdk_delete_event_new (surface); - - _gdk_wayland_display_deliver_event (display, event); -} - static void xdg_surface_configure (void *data, struct xdg_surface *xdg_surface, @@ -1782,341 +1344,94 @@ gdk_wayland_surface_create_xdg_surface_resources (GdkSurface *surface) } static void -xdg_toplevel_configure (void *data, - struct xdg_toplevel *xdg_toplevel, - int32_t width, - int32_t height, - struct wl_array *states) +gdk_wayland_surface_handle_configure_popup (GdkSurface *surface, + int32_t x, + int32_t y, + int32_t width, + int32_t height) { - GdkSurface *surface = GDK_SURFACE (data); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - uint32_t *p; - GdkToplevelState pending_state = 0; - - impl->pending.toplevel.is_resizing = FALSE; - - wl_array_for_each (p, states) - { - uint32_t state = *p; - - switch (state) - { - case XDG_TOPLEVEL_STATE_FULLSCREEN: - pending_state |= GDK_TOPLEVEL_STATE_FULLSCREEN; - break; - case XDG_TOPLEVEL_STATE_MAXIMIZED: - pending_state |= GDK_TOPLEVEL_STATE_MAXIMIZED; - break; - case XDG_TOPLEVEL_STATE_ACTIVATED: - pending_state |= GDK_TOPLEVEL_STATE_FOCUSED; - break; - case XDG_TOPLEVEL_STATE_RESIZING: - impl->pending.toplevel.is_resizing = TRUE; - break; - default: - /* Unknown state */ - break; - } - } - gdk_wayland_surface_handle_configure_toplevel (surface, width, height, - pending_state); + impl->pending.popup.x = x; + impl->pending.popup.y = y; + impl->pending.popup.width = width; + impl->pending.popup.height = height; } static void -xdg_toplevel_close (void *data, - struct xdg_toplevel *xdg_toplevel) +xdg_popup_configure (void *data, + struct xdg_popup *xdg_popup, + int32_t x, + int32_t y, + int32_t width, + int32_t height) { GdkSurface *surface = GDK_SURFACE (data); - gdk_wayland_surface_handle_close (surface); + gdk_wayland_surface_handle_configure_popup (surface, x, y, width, height); } -static const struct xdg_toplevel_listener xdg_toplevel_listener = { - xdg_toplevel_configure, - xdg_toplevel_close, -}; - static void -create_xdg_toplevel_resources (GdkSurface *surface) +xdg_popup_done (void *data, + struct xdg_popup *xdg_popup) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkSurface *surface = GDK_SURFACE (data); - impl->display_server.xdg_toplevel = - xdg_surface_get_toplevel (impl->display_server.xdg_surface); - xdg_toplevel_add_listener (impl->display_server.xdg_toplevel, - &xdg_toplevel_listener, - surface); + GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS, g_message ("done %p", surface)); + + gdk_surface_hide (surface); } static void -zxdg_toplevel_v6_configure (void *data, - struct zxdg_toplevel_v6 *xdg_toplevel, - int32_t width, - int32_t height, - struct wl_array *states) +xdg_popup_repositioned (void *data, + struct xdg_popup *xdg_popup, + uint32_t token) { GdkSurface *surface = GDK_SURFACE (data); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - uint32_t *p; - GdkToplevelState pending_state = 0; - impl->pending.toplevel.is_resizing = FALSE; + GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS, + g_message ("repositioned %p", surface)); - wl_array_for_each (p, states) + if (impl->popup_state != POPUP_STATE_WAITING_FOR_REPOSITIONED) { - uint32_t state = *p; - - switch (state) - { - case ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN: - pending_state |= GDK_TOPLEVEL_STATE_FULLSCREEN; - break; - case ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED: - pending_state |= GDK_TOPLEVEL_STATE_MAXIMIZED; - break; - case ZXDG_TOPLEVEL_V6_STATE_ACTIVATED: - pending_state |= GDK_TOPLEVEL_STATE_FOCUSED; - break; - case ZXDG_TOPLEVEL_V6_STATE_RESIZING: - impl->pending.toplevel.is_resizing = TRUE; - break; - default: - /* Unknown state */ - break; - } + g_warning ("Unexpected xdg_popup.repositioned event, probably buggy compositor"); + return; } - gdk_wayland_surface_handle_configure_toplevel (surface, width, height, - pending_state); + impl->pending.popup.repositioned_token = token; + impl->pending.popup.has_repositioned_token = TRUE; } +static const struct xdg_popup_listener xdg_popup_listener = { + xdg_popup_configure, + xdg_popup_done, + xdg_popup_repositioned, +}; + static void -zxdg_toplevel_v6_close (void *data, - struct zxdg_toplevel_v6 *xdg_toplevel) +zxdg_popup_v6_configure (void *data, + struct zxdg_popup_v6 *xdg_popup, + int32_t x, + int32_t y, + int32_t width, + int32_t height) { GdkSurface *surface = GDK_SURFACE (data); - gdk_wayland_surface_handle_close (surface); + gdk_wayland_surface_handle_configure_popup (surface, x, y, width, height); } -static const struct zxdg_toplevel_v6_listener zxdg_toplevel_v6_listener = { - zxdg_toplevel_v6_configure, - zxdg_toplevel_v6_close, -}; - static void -create_zxdg_toplevel_v6_resources (GdkSurface *surface) +zxdg_popup_v6_done (void *data, + struct zxdg_popup_v6 *xdg_popup) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkSurface *surface = GDK_SURFACE (data); + + GDK_NOTE (EVENTS, + g_message ("done %p", surface)); - impl->display_server.zxdg_toplevel_v6 = - zxdg_surface_v6_get_toplevel (impl->display_server.zxdg_surface_v6); - zxdg_toplevel_v6_add_listener (impl->display_server.zxdg_toplevel_v6, - &zxdg_toplevel_v6_listener, - surface); -} - -/** - * gdk_wayland_toplevel_set_application_id: - * @toplevel: (type GdkWaylandToplevel): a `GdkToplevel` - * @application_id: the application id for the @toplevel - * - * Sets the application id on a `GdkToplevel`. - */ -void -gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel, - const char *application_id) -{ - GdkWaylandSurface *impl; - GdkWaylandDisplay *display_wayland; - - g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); - - g_return_if_fail (application_id != NULL); - - if (GDK_SURFACE_DESTROYED (toplevel)) - return; - - impl = GDK_WAYLAND_SURFACE (toplevel); - - if (!is_realized_toplevel (impl)) - return; - - display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel))); - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_app_id (impl->display_server.xdg_toplevel, - application_id); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_app_id (impl->display_server.zxdg_toplevel_v6, - application_id); - break; - default: - g_assert_not_reached (); - } -} - -static void -gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) -{ - GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - const char *app_id; - - gdk_surface_freeze_updates (surface); - gdk_wayland_surface_create_xdg_surface_resources (surface); - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - create_xdg_toplevel_resources (surface); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - create_zxdg_toplevel_v6_resources (surface); - break; - default: - g_assert_not_reached (); - } - - gdk_wayland_surface_sync_parent (surface, NULL); - gdk_wayland_surface_sync_parent_of_imported (impl); - gdk_wayland_surface_sync_title (surface); - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED) - xdg_toplevel_set_maximized (impl->display_server.xdg_toplevel); - if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED) - xdg_toplevel_set_minimized (impl->display_server.xdg_toplevel); - if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) - xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, - impl->initial_fullscreen_output); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED) - zxdg_toplevel_v6_set_maximized (impl->display_server.zxdg_toplevel_v6); - if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED) - zxdg_toplevel_v6_set_minimized (impl->display_server.zxdg_toplevel_v6); - if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) - zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, - impl->initial_fullscreen_output); - break; - default: - g_assert_not_reached (); - } - - impl->initial_fullscreen_output = NULL; - - app_id = impl->application.application_id; - if (app_id == NULL) - app_id = g_get_prgname (); - - if (app_id == NULL) - app_id = "GTK Application"; - - gdk_wayland_toplevel_set_application_id (GDK_TOPLEVEL (impl), app_id); - - maybe_set_gtk_surface_dbus_properties (impl); - maybe_set_gtk_surface_modal (surface); - - gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit"); - wl_surface_commit (impl->display_server.wl_surface); -} - -static void -gdk_wayland_surface_handle_configure_popup (GdkSurface *surface, - int32_t x, - int32_t y, - int32_t width, - int32_t height) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - impl->pending.popup.x = x; - impl->pending.popup.y = y; - impl->pending.popup.width = width; - impl->pending.popup.height = height; -} - -static void -xdg_popup_configure (void *data, - struct xdg_popup *xdg_popup, - int32_t x, - int32_t y, - int32_t width, - int32_t height) -{ - GdkSurface *surface = GDK_SURFACE (data); - - gdk_wayland_surface_handle_configure_popup (surface, x, y, width, height); -} - -static void -xdg_popup_done (void *data, - struct xdg_popup *xdg_popup) -{ - GdkSurface *surface = GDK_SURFACE (data); - - GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS, g_message ("done %p", surface)); - - gdk_surface_hide (surface); -} - -static void -xdg_popup_repositioned (void *data, - struct xdg_popup *xdg_popup, - uint32_t token) -{ - GdkSurface *surface = GDK_SURFACE (data); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS, - g_message ("repositioned %p", surface)); - - if (impl->popup_state != POPUP_STATE_WAITING_FOR_REPOSITIONED) - { - g_warning ("Unexpected xdg_popup.repositioned event, probably buggy compositor"); - return; - } - - impl->pending.popup.repositioned_token = token; - impl->pending.popup.has_repositioned_token = TRUE; -} - -static const struct xdg_popup_listener xdg_popup_listener = { - xdg_popup_configure, - xdg_popup_done, - xdg_popup_repositioned, -}; - -static void -zxdg_popup_v6_configure (void *data, - struct zxdg_popup_v6 *xdg_popup, - int32_t x, - int32_t y, - int32_t width, - int32_t height) -{ - GdkSurface *surface = GDK_SURFACE (data); - - gdk_wayland_surface_handle_configure_popup (surface, x, y, width, height); -} - -static void -zxdg_popup_v6_done (void *data, - struct zxdg_popup_v6 *xdg_popup) -{ - GdkSurface *surface = GDK_SURFACE (data); - - GDK_NOTE (EVENTS, - g_message ("done %p", surface)); - - gdk_surface_hide (surface); + gdk_surface_hide (surface); } static const struct zxdg_popup_v6_listener zxdg_popup_v6_listener = { @@ -2254,81 +1569,6 @@ surface_anchor_to_gravity_legacy (GdkGravity rect_anchor) ZXDG_POSITIONER_V6_GRAVITY_RIGHT); } -void -gdk_wayland_toplevel_announce_csd (GdkToplevel *toplevel) -{ - GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel))); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); - - g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); - - if (!display_wayland->server_decoration_manager) - return; - impl->display_server.server_decoration = - org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager, - impl->display_server.wl_surface); - if (impl->display_server.server_decoration) - org_kde_kwin_server_decoration_request_mode (impl->display_server.server_decoration, - ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT); -} - -void -gdk_wayland_toplevel_announce_ssd (GdkToplevel *toplevel) -{ - GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel))); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); - - g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); - - if (!display_wayland->server_decoration_manager) - return; - impl->display_server.server_decoration = - org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager, - impl->display_server.wl_surface); - if (impl->display_server.server_decoration) - org_kde_kwin_server_decoration_request_mode (impl->display_server.server_decoration, - ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER); -} - -gboolean -gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel) -{ - GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel))); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); - - g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE); - - if (!display_wayland->idle_inhibit_manager) - return FALSE; - - if (!impl->idle_inhibitor) - { - g_assert (impl->idle_inhibitor_refcount == 0); - impl->idle_inhibitor = - zwp_idle_inhibit_manager_v1_create_inhibitor (display_wayland->idle_inhibit_manager, - impl->display_server.wl_surface); - } - ++impl->idle_inhibitor_refcount; - - return TRUE; -} - -void -gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); - - g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); - - g_assert (impl->idle_inhibitor && impl->idle_inhibitor_refcount > 0); - - if (--impl->idle_inhibitor_refcount == 0) - { - zwp_idle_inhibitor_v1_destroy (impl->idle_inhibitor); - impl->idle_inhibitor = NULL; - } -} - static void calculate_popup_rect (GdkSurface *surface, GdkPopupLayout *layout, @@ -2872,7 +2112,7 @@ gdk_wayland_surface_map_toplevel (GdkSurface *surface) impl->mapped = TRUE; } -static void +void gdk_wayland_surface_show (GdkSurface *surface, gboolean already_mapped) { @@ -3464,210 +2704,41 @@ gdk_wayland_surface_destroy (GdkSurface *surface, display->toplevels = g_list_remove (display->toplevels, surface); } -static void -gdk_wayland_surface_focus (GdkSurface *surface, - guint32 timestamp) +void +gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, + const GdkGeometry *geometry, + GdkSurfaceHints geom_mask) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandDisplay *display_wayland; + int min_width, min_height; + int max_width, max_height; - if (!impl->display_server.gtk_surface) + if (GDK_SURFACE_DESTROYED (impl) || + !SURFACE_IS_TOPLEVEL (impl)) return; - if (timestamp == GDK_CURRENT_TIME) - { - GdkWaylandDisplay *display_wayland = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (impl))); - if (display_wayland->startup_notification_id) - { - if (display_wayland->xdg_activation) - { - xdg_activation_v1_activate (display_wayland->xdg_activation, - display_wayland->startup_notification_id, - impl->display_server.wl_surface); - } - else if (display_wayland->gtk_shell_version >= 3) - { - gtk_surface1_request_focus (impl->display_server.gtk_surface, - display_wayland->startup_notification_id); - } + impl->geometry_hints = *geometry; + impl->geometry_mask = geom_mask; - g_clear_pointer (&display_wayland->startup_notification_id, g_free); - } + if (!is_realized_toplevel (impl)) + return; + + if (geom_mask & GDK_HINT_MIN_SIZE) + { + min_width = MAX (0, (geometry->min_width - + (impl->shadow_left + impl->shadow_right))); + min_height = MAX (0, (geometry->min_height - + (impl->shadow_top + impl->shadow_bottom))); } else - gtk_surface1_present (impl->display_server.gtk_surface, timestamp); -} - -static void -gtk_surface_configure (void *data, - struct gtk_surface1 *gtk_surface, - struct wl_array *states) -{ - GdkSurface *surface = GDK_SURFACE (data); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - GdkToplevelState new_state = 0; - uint32_t *p; - - wl_array_for_each (p, states) { - uint32_t state = *p; - - switch (state) - { - case GTK_SURFACE1_STATE_TILED: - new_state |= GDK_TOPLEVEL_STATE_TILED; - break; - - /* Since v2 */ - case GTK_SURFACE1_STATE_TILED_TOP: - new_state |= (GDK_TOPLEVEL_STATE_TILED | GDK_TOPLEVEL_STATE_TOP_TILED); - break; - case GTK_SURFACE1_STATE_TILED_RIGHT: - new_state |= (GDK_TOPLEVEL_STATE_TILED | GDK_TOPLEVEL_STATE_RIGHT_TILED); - break; - case GTK_SURFACE1_STATE_TILED_BOTTOM: - new_state |= (GDK_TOPLEVEL_STATE_TILED | GDK_TOPLEVEL_STATE_BOTTOM_TILED); - break; - case GTK_SURFACE1_STATE_TILED_LEFT: - new_state |= (GDK_TOPLEVEL_STATE_TILED | GDK_TOPLEVEL_STATE_LEFT_TILED); - break; - default: - /* Unknown state */ - break; - } + min_width = 0; + min_height = 0; } - impl->pending.toplevel.state |= new_state; -} - -static void -gtk_surface_configure_edges (void *data, - struct gtk_surface1 *gtk_surface, - struct wl_array *edge_constraints) -{ - GdkSurface *surface = GDK_SURFACE (data); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - GdkToplevelState new_state = 0; - uint32_t *p; - - wl_array_for_each (p, edge_constraints) - { - uint32_t constraint = *p; - - switch (constraint) - { - case GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_TOP: - new_state |= GDK_TOPLEVEL_STATE_TOP_RESIZABLE; - break; - case GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_RIGHT: - new_state |= GDK_TOPLEVEL_STATE_RIGHT_RESIZABLE; - break; - case GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_BOTTOM: - new_state |= GDK_TOPLEVEL_STATE_BOTTOM_RESIZABLE; - break; - case GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_LEFT: - new_state |= GDK_TOPLEVEL_STATE_LEFT_RESIZABLE; - break; - default: - /* Unknown state */ - break; - } - } - - impl->pending.toplevel.state |= new_state; -} - -static const struct gtk_surface1_listener gtk_surface_listener = { - gtk_surface_configure, - gtk_surface_configure_edges -}; - -static void -gdk_wayland_surface_init_gtk_surface (GdkWaylandSurface *impl) -{ - GdkWaylandDisplay *display = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (impl))); - - if (impl->display_server.gtk_surface != NULL) - return; - if (!is_realized_toplevel (impl)) - return; - if (display->gtk_shell == NULL) - return; - - impl->display_server.gtk_surface = - gtk_shell1_get_gtk_surface (display->gtk_shell, - impl->display_server.wl_surface); - wl_proxy_set_queue ((struct wl_proxy *) impl->display_server.gtk_surface, - impl->event_queue); - gdk_wayland_surface_set_geometry_hints (impl, - &impl->geometry_hints, - impl->geometry_mask); - gtk_surface1_add_listener (impl->display_server.gtk_surface, - >k_surface_listener, - impl); -} - -static void -maybe_set_gtk_surface_modal (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - gdk_wayland_surface_init_gtk_surface (impl); - if (impl->display_server.gtk_surface == NULL) - return; - - if (surface->modal_hint) - gtk_surface1_set_modal (impl->display_server.gtk_surface); - else - gtk_surface1_unset_modal (impl->display_server.gtk_surface); - -} - -static void -gdk_wayland_surface_set_modal_hint (GdkSurface *surface, - gboolean modal) -{ - surface->modal_hint = modal; - maybe_set_gtk_surface_modal (surface); -} - -static void -gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, - const GdkGeometry *geometry, - GdkSurfaceHints geom_mask) -{ - GdkWaylandDisplay *display_wayland; - int min_width, min_height; - int max_width, max_height; - - if (GDK_SURFACE_DESTROYED (impl) || - !SURFACE_IS_TOPLEVEL (impl)) - return; - - display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (impl))); - - impl->geometry_hints = *geometry; - impl->geometry_mask = geom_mask; - - if (!is_realized_toplevel (impl)) - return; - - if (geom_mask & GDK_HINT_MIN_SIZE) - { - min_width = MAX (0, (geometry->min_width - - (impl->shadow_left + impl->shadow_right))); - min_height = MAX (0, (geometry->min_height - - (impl->shadow_top + impl->shadow_bottom))); - } - else - { - min_width = 0; - min_height = 0; - } - - if (geom_mask & GDK_HINT_MAX_SIZE) + if (geom_mask & GDK_HINT_MAX_SIZE) { max_width = MAX (0, (geometry->max_width - (impl->shadow_left + impl->shadow_right))); @@ -3710,7 +2781,7 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, impl->last_sent_max_height = max_height; } -static void +void gdk_wayland_surface_set_title (GdkSurface *surface, const char *title) { @@ -3746,391 +2817,6 @@ gdk_wayland_surface_set_title (GdkSurface *surface, gdk_wayland_surface_sync_title (surface); } -static void -gdk_wayland_surface_set_startup_id (GdkSurface *surface, - const char *startup_id) -{ -} - -static gboolean -check_transient_for_loop (GdkWaylandToplevel *toplevel, - GdkWaylandToplevel *parent) -{ - while (parent) - { - if (parent->transient_for == toplevel) - return TRUE; - parent = parent->transient_for; - } - return FALSE; -} - -static void -gdk_wayland_toplevel_set_transient_for (GdkWaylandToplevel *toplevel, - GdkSurface *parent) -{ - g_return_if_fail (!parent || GDK_IS_WAYLAND_TOPLEVEL (parent)); - g_return_if_fail (!parent || - gdk_surface_get_display (GDK_SURFACE (toplevel)) == gdk_surface_get_display (parent)); - - if (parent) - { - GdkWaylandToplevel *parent_toplevel = GDK_WAYLAND_TOPLEVEL (parent); - - if (check_transient_for_loop (toplevel, parent_toplevel)) - { - g_warning ("Setting %p transient for %p would create a loop", - toplevel, parent); - return; - } - } - - unset_transient_for_exported (GDK_SURFACE (toplevel)); - - if (parent) - toplevel->transient_for = GDK_WAYLAND_TOPLEVEL (parent); - else - toplevel->transient_for = NULL; - - gdk_wayland_surface_sync_parent (GDK_SURFACE (toplevel), NULL); -} - -static void -gdk_wayland_surface_minimize (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - GdkWaylandDisplay *display_wayland; - - if (GDK_SURFACE_DESTROYED (surface) || - !SURFACE_IS_TOPLEVEL (surface)) - return; - - if (!is_realized_toplevel (GDK_WAYLAND_SURFACE (surface))) - return; - - /* FIXME: xdg_toplevel does not come with a minimized state that we can - * query or get notified of. This means we cannot implement the full - * GdkSurface API, and our state will not reflect minimization. - */ - display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_minimized (impl->display_server.xdg_toplevel); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_minimized (impl->display_server.zxdg_toplevel_v6); - break; - default: - g_assert_not_reached (); - } -} - -static void -gdk_wayland_surface_maximize (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - if (GDK_SURFACE_DESTROYED (surface)) - return; - - _gdk_wayland_surface_save_size (surface); - - if (is_realized_toplevel (impl)) - { - GdkWaylandDisplay *display_wayland = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_maximized (impl->display_server.xdg_toplevel); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_maximized (impl->display_server.zxdg_toplevel_v6); - break; - default: - g_assert_not_reached (); - } - } - else - { - synthesize_initial_surface_state (surface, 0, GDK_TOPLEVEL_STATE_MAXIMIZED); - } -} - -static void -gdk_wayland_surface_unmaximize (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - if (GDK_SURFACE_DESTROYED (surface)) - return; - - if (is_realized_toplevel (impl)) - { - GdkWaylandDisplay *display_wayland = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_unset_maximized (impl->display_server.xdg_toplevel); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_unset_maximized (impl->display_server.zxdg_toplevel_v6); - break; - default: - g_assert_not_reached (); - } - } - else - { - synthesize_initial_surface_state (surface, GDK_TOPLEVEL_STATE_MAXIMIZED, 0); - } -} - -static void -gdk_wayland_surface_fullscreen_on_monitor (GdkSurface *surface, - GdkMonitor *monitor) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - struct wl_output *output = ((GdkWaylandMonitor *)monitor)->output; - - if (GDK_SURFACE_DESTROYED (surface)) - return; - - _gdk_wayland_surface_save_size (surface); - - if (is_realized_toplevel (impl)) - { - GdkWaylandDisplay *display_wayland = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, - output); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, - output); - break; - default: - g_assert_not_reached (); - } - } - else - { - synthesize_initial_surface_state (surface, 0, GDK_TOPLEVEL_STATE_FULLSCREEN); - impl->initial_fullscreen_output = output; - } -} - -static void -gdk_wayland_surface_fullscreen (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - if (GDK_SURFACE_DESTROYED (surface)) - return; - - impl->initial_fullscreen_output = NULL; - - _gdk_wayland_surface_save_size (surface); - - if (is_realized_toplevel (impl)) - { - GdkWaylandDisplay *display_wayland = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, - NULL); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, - NULL); - break; - default: - g_assert_not_reached (); - } - } - else - { - synthesize_initial_surface_state (surface, 0, GDK_TOPLEVEL_STATE_FULLSCREEN); - } -} - -static void -gdk_wayland_surface_unfullscreen (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - if (GDK_SURFACE_DESTROYED (surface)) - return; - - impl->initial_fullscreen_output = NULL; - - if (is_realized_toplevel (impl)) - { - GdkWaylandDisplay *display_wayland = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_unset_fullscreen (impl->display_server.xdg_toplevel); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_unset_fullscreen (impl->display_server.zxdg_toplevel_v6); - break; - default: - g_assert_not_reached (); - } - } - else - { - synthesize_initial_surface_state (surface, GDK_TOPLEVEL_STATE_FULLSCREEN, 0); - } -} - -static void -gdk_wayland_toplevel_begin_resize (GdkToplevel *toplevel, - GdkSurfaceEdge edge, - GdkDevice *device, - int button, - double x, - double y, - guint32 timestamp) -{ - GdkSurface *surface = GDK_SURFACE (toplevel); - GdkWaylandSurface *impl; - GdkWaylandDisplay *display_wayland; - GdkEventSequence *sequence; - uint32_t resize_edges, serial; - - if (GDK_SURFACE_DESTROYED (surface) || - !SURFACE_IS_TOPLEVEL (surface)) - return; - - switch (edge) - { - case GDK_SURFACE_EDGE_NORTH_WEST: - resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_TOP_LEFT; - break; - - case GDK_SURFACE_EDGE_NORTH: - resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_TOP; - break; - - case GDK_SURFACE_EDGE_NORTH_EAST: - resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_TOP_RIGHT; - break; - - case GDK_SURFACE_EDGE_WEST: - resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_LEFT; - break; - - case GDK_SURFACE_EDGE_EAST: - resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_RIGHT; - break; - - case GDK_SURFACE_EDGE_SOUTH_WEST: - resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_BOTTOM_LEFT; - break; - - case GDK_SURFACE_EDGE_SOUTH: - resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_BOTTOM; - break; - - case GDK_SURFACE_EDGE_SOUTH_EAST: - resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_BOTTOM_RIGHT; - break; - - default: - g_warning ("gdk_toplevel_begin_resize: bad resize edge %d!", edge); - return; - } - - impl = GDK_WAYLAND_SURFACE (surface); - display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - - if (!is_realized_toplevel (impl)) - return; - - serial = _gdk_wayland_seat_get_last_implicit_grab_serial (GDK_WAYLAND_SEAT (gdk_device_get_seat (device)), - &sequence); - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_resize (impl->display_server.xdg_toplevel, - gdk_wayland_device_get_wl_seat (device), - serial, resize_edges); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_resize (impl->display_server.zxdg_toplevel_v6, - gdk_wayland_device_get_wl_seat (device), - serial, resize_edges); - break; - default: - g_assert_not_reached (); - } - - if (sequence) - gdk_wayland_device_unset_touch_grab (device, sequence); -} - -static void -gdk_wayland_toplevel_begin_move (GdkToplevel *toplevel, - GdkDevice *device, - int button, - double x, - double y, - guint32 timestamp) -{ - GdkSurface *surface = GDK_SURFACE (toplevel); - GdkWaylandSurface *impl; - GdkWaylandDisplay *display_wayland; - GdkEventSequence *sequence; - uint32_t serial; - - if (GDK_SURFACE_DESTROYED (surface) || - !SURFACE_IS_TOPLEVEL (surface)) - return; - - impl = GDK_WAYLAND_SURFACE (surface); - display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - - if (!is_realized_toplevel (impl)) - return; - - serial = _gdk_wayland_seat_get_last_implicit_grab_serial (GDK_WAYLAND_SEAT (gdk_device_get_seat (device)), - &sequence); - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_move (impl->display_server.xdg_toplevel, - gdk_wayland_device_get_wl_seat (device), - serial); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_move (impl->display_server.zxdg_toplevel_v6, - gdk_wayland_device_get_wl_seat (device), - serial); - break; - default: - g_assert_not_reached (); - } - - if (sequence) - gdk_wayland_device_unset_touch_grab (device, sequence); -} - static void gdk_wayland_surface_destroy_notify (GdkSurface *surface) { @@ -4168,68 +2854,6 @@ gdk_wayland_surface_set_opaque_region (GdkSurface *surface, impl->opaque_region_dirty = TRUE; } -static gboolean -gdk_wayland_surface_show_window_menu (GdkSurface *surface, - GdkEvent *event) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - GdkWaylandDisplay *display_wayland = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - GdkSeat *seat; - struct wl_seat *wl_seat; - double x, y; - uint32_t serial; - - GdkEventType event_type = gdk_event_get_event_type (event); - switch ((guint) event_type) - { - case GDK_BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - case GDK_TOUCH_BEGIN: - case GDK_TOUCH_END: - break; - default: - return FALSE; - } - - if (!is_realized_toplevel (impl)) - return FALSE; - - seat = gdk_event_get_seat (event); - wl_seat = gdk_wayland_seat_get_wl_seat (seat); - gdk_event_get_position (event, &x, &y); - - serial = _gdk_wayland_seat_get_implicit_grab_serial (seat, event); - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_show_window_menu (impl->display_server.xdg_toplevel, - wl_seat, serial, x, y); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_show_window_menu (impl->display_server.zxdg_toplevel_v6, - wl_seat, serial, x, y); - break; - default: - g_assert_not_reached (); - } - - return TRUE; -} - -static gboolean -gdk_wayland_surface_supports_edge_constraints (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - struct gtk_surface1 *gtk_surface = impl->display_server.gtk_surface; - - if (!gtk_surface) - return FALSE; - - return gtk_surface1_get_version (gtk_surface) >= GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION; -} - static void gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass) { @@ -4352,77 +2976,23 @@ gdk_wayland_surface_get_dummy_egl_surface (GdkSurface *surface, impl = GDK_WAYLAND_SURFACE (surface); if (impl->dummy_egl_surface == NULL) - { - impl->display_server.dummy_egl_window = - wl_egl_window_create (impl->display_server.wl_surface, 1, 1); - - impl->dummy_egl_surface = - eglCreateWindowSurface (display->egl_display, config, impl->display_server.dummy_egl_window, NULL); - } - - return impl->dummy_egl_surface; -} - -struct gtk_surface1 * -gdk_wayland_surface_get_gtk_surface (GdkSurface *surface) -{ - g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); - - return GDK_WAYLAND_SURFACE (surface)->display_server.gtk_surface; -} - -static void -maybe_set_gtk_surface_dbus_properties (GdkWaylandSurface *impl) -{ - if (impl->application.was_set) - return; - - if (impl->application.application_id == NULL && - impl->application.app_menu_path == NULL && - impl->application.menubar_path == NULL && - impl->application.window_object_path == NULL && - impl->application.application_object_path == NULL && - impl->application.unique_bus_name == NULL) - return; + { + impl->display_server.dummy_egl_window = + wl_egl_window_create (impl->display_server.wl_surface, 1, 1); - gdk_wayland_surface_init_gtk_surface (impl); - if (impl->display_server.gtk_surface == NULL) - return; + impl->dummy_egl_surface = + eglCreateWindowSurface (display->egl_display, config, impl->display_server.dummy_egl_window, NULL); + } - gtk_surface1_set_dbus_properties (impl->display_server.gtk_surface, - impl->application.application_id, - impl->application.app_menu_path, - impl->application.menubar_path, - impl->application.window_object_path, - impl->application.application_object_path, - impl->application.unique_bus_name); - impl->application.was_set = TRUE; + return impl->dummy_egl_surface; } -void -gdk_wayland_toplevel_set_dbus_properties (GdkToplevel *toplevel, - const char *application_id, - const char *app_menu_path, - const char *menubar_path, - const char *window_object_path, - const char *application_object_path, - const char *unique_bus_name) +struct gtk_surface1 * +gdk_wayland_surface_get_gtk_surface (GdkSurface *surface) { - GdkWaylandSurface *impl; - - g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); - - impl = GDK_WAYLAND_SURFACE (toplevel); - - impl->application.application_id = g_strdup (application_id); - impl->application.app_menu_path = g_strdup (app_menu_path); - impl->application.menubar_path = g_strdup (menubar_path); - impl->application.window_object_path = g_strdup (window_object_path); - impl->application.application_object_path = - g_strdup (application_object_path); - impl->application.unique_bus_name = g_strdup (unique_bus_name); + g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); - maybe_set_gtk_surface_dbus_properties (impl); + return GDK_WAYLAND_SURFACE (surface)->display_server.gtk_surface; } void @@ -4440,26 +3010,6 @@ _gdk_wayland_surface_offset_next_wl_buffer (GdkSurface *surface, impl->pending_buffer_offset_y = y; } -static void -xdg_exported_handle (void *data, - struct zxdg_exported_v1 *zxdg_exported_v1, - const char *handle) -{ - GdkToplevel *toplevel = data; - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); - - impl->exported.callback (toplevel, handle, impl->exported.user_data); - if (impl->exported.destroy_func) - { - g_clear_pointer (&impl->exported.user_data, - impl->exported.destroy_func); - } -} - -static const struct zxdg_exported_v1_listener xdg_exported_listener = { - xdg_exported_handle -}; - /** * GdkWaylandToplevelExported: * @toplevel: (type GdkWaylandToplevel): the `GdkToplevel` that is exported @@ -4481,105 +3031,7 @@ gdk_wayland_surface_is_exported (GdkWaylandSurface *impl) return !!impl->display_server.xdg_exported; } -/** - * gdk_wayland_toplevel_export_handle: - * @toplevel: (type GdkWaylandToplevel): the `GdkToplevel` to obtain a handle for - * @callback: callback to call with the handle - * @user_data: (closure): user data for @callback - * @destroy_func: destroy notify for @user_data - * - * Asynchronously obtains a handle for a surface that can be passed - * to other processes. - * - * When the handle has been obtained, @callback will be called. - * - * It is an error to call this function on a surface that is already - * exported. - * - * When the handle is no longer needed, [method@GdkWayland.WaylandToplevel.unexport_handle] - * should be called to clean up resources. - * - * The main purpose for obtaining a handle is to mark a surface - * from another surface as transient for this one, see - * [method@GdkWayland.WaylandToplevel.set_transient_for_exported]. - * - * Note that this API depends on an unstable Wayland protocol, - * and thus may require changes in the future. - * - * Return value: %TRUE if the handle has been requested, %FALSE if - * an error occurred. - */ -gboolean -gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel, - GdkWaylandToplevelExported callback, - gpointer user_data, - GDestroyNotify destroy_func) -{ - GdkWaylandSurface *impl; - GdkWaylandDisplay *display_wayland; - GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (toplevel)); - struct zxdg_exported_v1 *xdg_exported; - - g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE); - g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE); - - impl = GDK_WAYLAND_SURFACE (toplevel); - display_wayland = GDK_WAYLAND_DISPLAY (display); - - g_return_val_if_fail (!impl->display_server.xdg_exported, FALSE); - - if (!display_wayland->xdg_exporter) - { - g_warning ("Server is missing xdg_foreign support"); - return FALSE; - } - - xdg_exported = zxdg_exporter_v1_export (display_wayland->xdg_exporter, - impl->display_server.wl_surface); - zxdg_exported_v1_add_listener (xdg_exported, &xdg_exported_listener, impl); - - impl->display_server.xdg_exported = xdg_exported; - impl->exported.callback = callback; - impl->exported.user_data = user_data; - impl->exported.destroy_func = destroy_func; - - return TRUE; -} - -/** - * gdk_wayland_toplevel_unexport_handle: - * @toplevel: (type GdkWaylandToplevel): the `GdkToplevel` to unexport - * - * Destroys the handle that was obtained with - * gdk_wayland_toplevel_export_handle(). - * - * It is an error to call this function on a surface that - * does not have a handle. - * - * Note that this API depends on an unstable Wayland protocol, - * and thus may require changes in the future. - */ void -gdk_wayland_toplevel_unexport_handle (GdkToplevel *toplevel) -{ - GdkWaylandSurface *impl; - - g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); - - impl = GDK_WAYLAND_SURFACE (toplevel); - - g_return_if_fail (impl->display_server.xdg_exported); - - g_clear_pointer (&impl->display_server.xdg_exported, - zxdg_exported_v1_destroy); - if (impl->exported.destroy_func) - { - g_clear_pointer (&impl->exported.user_data, - impl->exported.destroy_func); - } -} - -static void unset_transient_for_exported (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); @@ -4587,70 +3039,7 @@ unset_transient_for_exported (GdkSurface *surface) g_clear_pointer (&impl->imported_transient_for, zxdg_imported_v1_destroy); } -static void -xdg_imported_destroyed (void *data, - struct zxdg_imported_v1 *zxdg_imported_v1) -{ - GdkSurface *surface = data; - - unset_transient_for_exported (surface); -} - -static const struct zxdg_imported_v1_listener xdg_imported_listener = { - xdg_imported_destroyed, -}; - -/** - * gdk_wayland_toplevel_set_transient_for_exported: - * @toplevel: (type GdkWaylandToplevel): the `GdkToplevel` to make as transient - * @parent_handle_str: an exported handle for a surface - * - * Marks @toplevel as transient for the surface to which the given - * @parent_handle_str refers. - * - * Typically, the handle will originate from a - * [method@GdkWayland.WaylandToplevel.export_handle] call in another process. - * - * Note that this API depends on an unstable Wayland protocol, - * and thus may require changes in the future. - * - * Return value: %TRUE if the surface has been marked as transient, - * %FALSE if an error occurred. - */ -gboolean -gdk_wayland_toplevel_set_transient_for_exported (GdkToplevel *toplevel, - const char *parent_handle_str) -{ - GdkWaylandSurface *impl; - GdkWaylandDisplay *display_wayland; - GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (toplevel)); - - g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE); - g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE); - - impl = GDK_WAYLAND_SURFACE (toplevel); - display_wayland = GDK_WAYLAND_DISPLAY (display); - - if (!display_wayland->xdg_importer) - { - g_warning ("Server is missing xdg_foreign support"); - return FALSE; - } - - gdk_wayland_toplevel_set_transient_for (GDK_WAYLAND_TOPLEVEL (impl), NULL); - - impl->imported_transient_for = - zxdg_importer_v1_import (display_wayland->xdg_importer, parent_handle_str); - zxdg_imported_v1_add_listener (impl->imported_transient_for, - &xdg_imported_listener, - toplevel); - - gdk_wayland_surface_sync_parent_of_imported (impl); - - return TRUE; -} - -static struct zwp_keyboard_shortcuts_inhibitor_v1 * +struct zwp_keyboard_shortcuts_inhibitor_v1 * gdk_wayland_surface_get_inhibitor (GdkWaylandSurface *impl, GdkSeat *gdk_seat) { @@ -4835,296 +3224,6 @@ gdk_wayland_popup_iface_init (GdkPopupInterface *iface) iface->get_position_y = gdk_wayland_popup_get_position_y; } -static void -gdk_wayland_toplevel_init (GdkWaylandToplevel *toplevel) -{ -} - -static void -gdk_wayland_toplevel_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GdkSurface *surface = GDK_SURFACE (object); - GdkWaylandToplevel *toplevel = GDK_WAYLAND_TOPLEVEL (surface); - - switch (prop_id) - { - case LAST_PROP + GDK_TOPLEVEL_PROP_TITLE: - gdk_wayland_surface_set_title (surface, g_value_get_string (value)); - g_object_notify_by_pspec (G_OBJECT (surface), pspec); - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_STARTUP_ID: - gdk_wayland_surface_set_startup_id (surface, g_value_get_string (value)); - g_object_notify_by_pspec (G_OBJECT (surface), pspec); - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_TRANSIENT_FOR: - gdk_wayland_toplevel_set_transient_for (toplevel, - g_value_get_object (value)); - g_object_notify_by_pspec (G_OBJECT (surface), pspec); - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL: - gdk_wayland_surface_set_modal_hint (surface, g_value_get_boolean (value)); - g_object_notify_by_pspec (G_OBJECT (surface), pspec); - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST: - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_DECORATED: - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_DELETABLE: - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_FULLSCREEN_MODE: - surface->fullscreen_mode = g_value_get_enum (value); - g_object_notify_by_pspec (G_OBJECT (surface), pspec); - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_SHORTCUTS_INHIBITED: - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdk_wayland_toplevel_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GdkSurface *surface = GDK_SURFACE (object); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - GdkWaylandToplevel *toplevel = GDK_WAYLAND_TOPLEVEL (surface); - - switch (prop_id) - { - case LAST_PROP + GDK_TOPLEVEL_PROP_STATE: - g_value_set_flags (value, surface->state); - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_TITLE: - g_value_set_string (value, impl->title); - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_STARTUP_ID: - g_value_set_string (value, ""); - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_TRANSIENT_FOR: - g_value_set_object (value, toplevel->transient_for); - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL: - g_value_set_boolean (value, surface->modal_hint); - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST: - g_value_set_pointer (value, NULL); - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_DECORATED: - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_DELETABLE: - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_FULLSCREEN_MODE: - g_value_set_enum (value, surface->fullscreen_mode); - break; - - case LAST_PROP + GDK_TOPLEVEL_PROP_SHORTCUTS_INHIBITED: - g_value_set_boolean (value, surface->shortcuts_inhibited); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->get_property = gdk_wayland_toplevel_get_property; - object_class->set_property = gdk_wayland_toplevel_set_property; - - gdk_toplevel_install_properties (object_class, 1); -} - -static void -gdk_wayland_toplevel_present (GdkToplevel *toplevel, - GdkToplevelLayout *layout) -{ - GdkSurface *surface = GDK_SURFACE (toplevel); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - gboolean pending_configure = FALSE; - gboolean maximize; - gboolean fullscreen; - - if (gdk_toplevel_layout_get_maximized (layout, &maximize)) - { - if (maximize) - gdk_wayland_surface_maximize (surface); - else - gdk_wayland_surface_unmaximize (surface); - pending_configure = TRUE; - } - - if (gdk_toplevel_layout_get_fullscreen (layout, &fullscreen)) - { - if (fullscreen) - { - GdkMonitor *monitor; - - monitor = gdk_toplevel_layout_get_fullscreen_monitor (layout); - if (monitor) - gdk_wayland_surface_fullscreen_on_monitor (surface, monitor); - else - gdk_wayland_surface_fullscreen (surface); - } - else - { - gdk_wayland_surface_unfullscreen (surface); - } - pending_configure = TRUE; - } - - g_clear_pointer (&impl->toplevel.layout, gdk_toplevel_layout_unref); - impl->toplevel.layout = gdk_toplevel_layout_copy (layout); - - gdk_wayland_surface_show (surface, FALSE); - - if (!pending_configure) - { - impl->next_layout.surface_geometry_dirty = TRUE; - gdk_surface_request_layout (surface); - } -} - -static gboolean -gdk_wayland_toplevel_minimize (GdkToplevel *toplevel) -{ - gdk_wayland_surface_minimize (GDK_SURFACE (toplevel)); - - return TRUE; -} - -static gboolean -gdk_wayland_toplevel_lower (GdkToplevel *toplevel) -{ - return FALSE; -} - -static void -gdk_wayland_toplevel_focus (GdkToplevel *toplevel, - guint32 timestamp) -{ - gdk_wayland_surface_focus (GDK_SURFACE (toplevel), timestamp); -} - -static gboolean -gdk_wayland_toplevel_show_window_menu (GdkToplevel *toplevel, - GdkEvent *event) -{ - return gdk_wayland_surface_show_window_menu (GDK_SURFACE (toplevel), event); -} - -static gboolean -gdk_wayland_toplevel_supports_edge_constraints (GdkToplevel *toplevel) -{ - return gdk_wayland_surface_supports_edge_constraints (GDK_SURFACE (toplevel)); -} - -static void -inhibitor_active (void *data, - struct zwp_keyboard_shortcuts_inhibitor_v1 *inhibitor) -{ - GdkToplevel *toplevel = GDK_TOPLEVEL (data); - GdkSurface *surface = GDK_SURFACE (toplevel); - - surface->shortcuts_inhibited = TRUE; - g_object_notify (G_OBJECT (toplevel), "shortcuts-inhibited"); -} - -static void -inhibitor_inactive (void *data, - struct zwp_keyboard_shortcuts_inhibitor_v1 *inhibitor) -{ - GdkToplevel *toplevel = GDK_TOPLEVEL (data); - GdkSurface *surface = GDK_SURFACE (toplevel); - - surface->shortcuts_inhibited = FALSE; - g_object_notify (G_OBJECT (toplevel), "shortcuts-inhibited"); -} - -static const struct zwp_keyboard_shortcuts_inhibitor_v1_listener -zwp_keyboard_shortcuts_inhibitor_listener = { - inhibitor_active, - inhibitor_inactive, -}; - -static void -gdk_wayland_toplevel_inhibit_system_shortcuts (GdkToplevel *toplevel, - GdkEvent *event) -{ - struct zwp_keyboard_shortcuts_inhibitor_v1 *inhibitor; - GdkSurface *surface = GDK_SURFACE (toplevel); - GdkWaylandSurface *impl= GDK_WAYLAND_SURFACE (surface); - GdkSeat *gdk_seat; - - if (surface->shortcuts_inhibited) - return; - - gdk_seat = gdk_surface_get_seat_from_event (surface, event); - gdk_wayland_surface_inhibit_shortcuts (surface, gdk_seat); - - inhibitor = gdk_wayland_surface_get_inhibitor (impl, gdk_seat); - if (!inhibitor) - return; - - surface->current_shortcuts_inhibited_seat = gdk_seat; - zwp_keyboard_shortcuts_inhibitor_v1_add_listener - (inhibitor, &zwp_keyboard_shortcuts_inhibitor_listener, toplevel); -} - -static void -gdk_wayland_toplevel_restore_system_shortcuts (GdkToplevel *toplevel) -{ - GdkSurface *surface = GDK_SURFACE (toplevel); - - gdk_wayland_surface_restore_shortcuts (surface, - surface->current_shortcuts_inhibited_seat); - surface->current_shortcuts_inhibited_seat = NULL; - surface->shortcuts_inhibited = FALSE; - g_object_notify (G_OBJECT (toplevel), "shortcuts-inhibited"); -} - -static void -gdk_wayland_toplevel_iface_init (GdkToplevelInterface *iface) -{ - iface->present = gdk_wayland_toplevel_present; - iface->minimize = gdk_wayland_toplevel_minimize; - iface->lower = gdk_wayland_toplevel_lower; - iface->focus = gdk_wayland_toplevel_focus; - iface->show_window_menu = gdk_wayland_toplevel_show_window_menu; - iface->supports_edge_constraints = gdk_wayland_toplevel_supports_edge_constraints; - iface->inhibit_system_shortcuts = gdk_wayland_toplevel_inhibit_system_shortcuts; - iface->restore_system_shortcuts = gdk_wayland_toplevel_restore_system_shortcuts; - iface->begin_resize = gdk_wayland_toplevel_begin_resize; - iface->begin_move = gdk_wayland_toplevel_begin_move; -} - static void gdk_wayland_drag_surface_init (GdkWaylandDragSurface *surface) { diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 8efa4be04df..92f2b5d64d3 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -22,6 +22,183 @@ #include "gdkwaylandsurface.h" +#include "gdkprivate-wayland.h" + +typedef enum _PopupState +{ + POPUP_STATE_IDLE, + POPUP_STATE_WAITING_FOR_REPOSITIONED, + POPUP_STATE_WAITING_FOR_CONFIGURE, + POPUP_STATE_WAITING_FOR_FRAME, +} PopupState; + +struct _GdkWaylandSurface +{ + GdkSurface parent_instance; + + struct { + /* The wl_outputs that this surface currently touches */ + GSList *outputs; + + struct wl_surface *wl_surface; + + struct xdg_surface *xdg_surface; + struct xdg_toplevel *xdg_toplevel; + struct xdg_popup *xdg_popup; + + /* Legacy xdg-shell unstable v6 fallback support */ + struct zxdg_surface_v6 *zxdg_surface_v6; + struct zxdg_toplevel_v6 *zxdg_toplevel_v6; + struct zxdg_popup_v6 *zxdg_popup_v6; + + struct gtk_surface1 *gtk_surface; + struct wl_egl_window *egl_window; + struct wl_egl_window *dummy_egl_window; + struct zxdg_exported_v1 *xdg_exported; + struct org_kde_kwin_server_decoration *server_decoration; + } display_server; + + struct wl_event_queue *event_queue; + + EGLSurface egl_surface; + EGLSurface dummy_egl_surface; + + uint32_t reposition_token; + uint32_t received_reposition_token; + + PopupState popup_state; + + unsigned int initial_configure_received : 1; + unsigned int has_uncommitted_ack_configure : 1; + unsigned int mapped : 1; + unsigned int awaiting_frame : 1; + unsigned int awaiting_frame_frozen : 1; + unsigned int is_drag_surface : 1; + + int pending_buffer_offset_x; + int pending_buffer_offset_y; + + char *title; + + struct { + gboolean was_set; + + char *application_id; + char *app_menu_path; + char *menubar_path; + char *window_object_path; + char *application_object_path; + char *unique_bus_name; + } application; + + GdkGeometry geometry_hints; + GdkSurfaceHints geometry_mask; + + GdkSeat *grab_input_seat; + + gint64 pending_frame_counter; + guint32 scale; + + int shadow_left; + int shadow_right; + int shadow_top; + int shadow_bottom; + gboolean shadow_dirty; + + struct wl_output *initial_fullscreen_output; + + cairo_region_t *opaque_region; + gboolean opaque_region_dirty; + + cairo_region_t *input_region; + gboolean input_region_dirty; + + GdkRectangle last_sent_window_geometry; + int last_sent_min_width; + int last_sent_min_height; + int last_sent_max_width; + int last_sent_max_height; + + int saved_width; + int saved_height; + + gulong parent_surface_committed_handler; + + struct { + GdkToplevelLayout *layout; + } toplevel; + + struct { + GdkPopupLayout *layout; + int unconstrained_width; + int unconstrained_height; + } popup; + + struct { + struct { + int width; + int height; + GdkToplevelState state; + gboolean is_resizing; + } toplevel; + + struct { + int x; + int y; + int width; + int height; + uint32_t repositioned_token; + gboolean has_repositioned_token; + } popup; + + gboolean is_initial_configure; + + uint32_t serial; + gboolean is_dirty; + } pending; + + struct { + GdkToplevelState unset_flags; + GdkToplevelState set_flags; + } initial_state; + + struct { + struct { + gboolean should_constrain; + gboolean size_is_fixed; + } toplevel; + struct { + int x; + int y; + } popup; + int configured_width; + int configured_height; + gboolean surface_geometry_dirty; + } next_layout; + + uint32_t last_configure_serial; + + int state_freeze_count; + + struct { + GdkWaylandToplevelExported callback; + gpointer user_data; + GDestroyNotify destroy_func; + } exported; + + struct zxdg_imported_v1 *imported_transient_for; + GHashTable *shortcuts_inhibitors; + + struct zwp_idle_inhibitor_v1 *idle_inhibitor; + size_t idle_inhibitor_refcount; +}; + +typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass; +struct _GdkWaylandSurfaceClass +{ + GdkSurfaceClass parent_class; +}; + G_BEGIN_DECLS void gdk_wayland_toplevel_set_dbus_properties (GdkToplevel *toplevel, @@ -38,4 +215,21 @@ void gdk_wayland_toplevel_announce_ssd (GdkTopl gboolean gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel); void gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel); +void gdk_wayland_surface_set_title (GdkSurface *surface, + const char *title); +void +gdk_wayland_surface_sync_title (GdkSurface *surface); + +struct zwp_keyboard_shortcuts_inhibitor_v1 * +gdk_wayland_surface_get_inhibitor (GdkWaylandSurface *impl, + GdkSeat *gdk_seat); +void +gdk_wayland_surface_show (GdkSurface *surface, + gboolean already_mapped); + +void unset_transient_for_exported (GdkSurface *surface); +void gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, + const GdkGeometry *geometry, + GdkSurfaceHints geom_mask); + G_END_DECLS diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c new file mode 100644 index 00000000000..a138007d02c --- /dev/null +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -0,0 +1,1887 @@ +/* + * Copyright © 2010 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gdksurface-wayland.h" +#include "gdkwaylandtoplevel.h" + +#include "gdkdeviceprivate.h" +#include "gdkdisplay-wayland.h" +#include "gdkdragsurfaceprivate.h" +#include "gdkframeclockidleprivate.h" +#include "gdkglcontext-wayland.h" +#include "gdkmonitor-wayland.h" +#include "gdkpopupprivate.h" +#include "gdkprivate-wayland.h" +#include "gdkprivate-wayland.h" +#include "gdkseat-wayland.h" +#include "gdksurfaceprivate.h" +#include "gdktoplevelprivate.h" +#include "gdkdevice-wayland-private.h" + +#include + +#include +#include +#include +#include + +#define SURFACE_IS_TOPLEVEL(surface) TRUE + +typedef struct +{ + GdkWaylandSurfaceClass parent_class; +} GdkWaylandToplevelClass; + +struct _GdkWaylandToplevel +{ + GdkWaylandSurface parent_instance; + + GdkWaylandToplevel *transient_for; +}; + +static void gdk_wayland_toplevel_iface_init (GdkToplevelInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GdkWaylandToplevel, gdk_wayland_toplevel, GDK_TYPE_WAYLAND_SURFACE, + G_IMPLEMENT_INTERFACE (GDK_TYPE_TOPLEVEL, + gdk_wayland_toplevel_iface_init)) + +static void maybe_set_gtk_surface_dbus_properties (GdkWaylandSurface *impl); +static void maybe_set_gtk_surface_modal (GdkSurface *surface); + +static gboolean +is_realized_toplevel (GdkWaylandSurface *impl) +{ + return (impl->display_server.xdg_toplevel || + impl->display_server.zxdg_toplevel_v6); +} + +static void +_gdk_wayland_surface_save_size (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + if (surface->state & (GDK_TOPLEVEL_STATE_FULLSCREEN | + GDK_TOPLEVEL_STATE_MAXIMIZED | + GDK_TOPLEVEL_STATE_TILED)) + return; + + if (surface->width <= 1 || surface->height <= 1) + return; + + impl->saved_width = surface->width - impl->shadow_left - impl->shadow_right; + impl->saved_height = surface->height - impl->shadow_top - impl->shadow_bottom; +} + +static void +gdk_wayland_surface_sync_parent (GdkSurface *surface, + GdkSurface *parent) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *toplevel = GDK_WAYLAND_TOPLEVEL (impl); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + GdkWaylandSurface *impl_parent = NULL; + + g_assert (parent == NULL || + gdk_surface_get_display (surface) == gdk_surface_get_display (parent)); + + if (!is_realized_toplevel (impl)) + return; + + if (toplevel->transient_for) + impl_parent = GDK_WAYLAND_SURFACE (toplevel->transient_for); + else if (parent) + impl_parent = GDK_WAYLAND_SURFACE (parent); + + /* XXX: Is this correct? */ + if (impl_parent && !impl_parent->display_server.wl_surface) + return; + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + { + struct xdg_toplevel *parent_toplevel; + + if (impl_parent) + parent_toplevel = impl_parent->display_server.xdg_toplevel; + else + parent_toplevel = NULL; + + xdg_toplevel_set_parent (impl->display_server.xdg_toplevel, + parent_toplevel); + break; + } + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + { + struct zxdg_toplevel_v6 *parent_toplevel; + + if (impl_parent) + parent_toplevel = impl_parent->display_server.zxdg_toplevel_v6; + else + parent_toplevel = NULL; + + zxdg_toplevel_v6_set_parent (impl->display_server.zxdg_toplevel_v6, + parent_toplevel); + break; + } + default: + g_assert_not_reached (); + } +} + +static void +gdk_wayland_surface_sync_parent_of_imported (GdkWaylandSurface *impl) +{ + if (!impl->display_server.wl_surface) + return; + + if (!impl->imported_transient_for) + return; + + if (!is_realized_toplevel (impl)) + return; + + zxdg_imported_v1_set_parent_of (impl->imported_transient_for, + impl->display_server.wl_surface); +} + +static void +synthesize_initial_surface_state (GdkSurface *surface, + GdkToplevelState unset_flags, + GdkToplevelState set_flags) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + impl->initial_state.unset_flags |= unset_flags; + impl->initial_state.set_flags &= ~unset_flags; + + impl->initial_state.set_flags |= set_flags; + impl->initial_state.unset_flags &= ~set_flags; +} + +void +gdk_wayland_surface_configure_toplevel (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + GdkToplevelState new_state; + int width, height; + gboolean is_resizing; + gboolean fixed_size; + gboolean saved_size; + + new_state = impl->pending.toplevel.state; + impl->pending.toplevel.state = 0; + + is_resizing = impl->pending.toplevel.is_resizing; + impl->pending.toplevel.is_resizing = FALSE; + + fixed_size = + new_state & (GDK_TOPLEVEL_STATE_MAXIMIZED | + GDK_TOPLEVEL_STATE_FULLSCREEN | + GDK_TOPLEVEL_STATE_TILED) || + is_resizing; + + width = impl->pending.toplevel.width; + height = impl->pending.toplevel.height; + + saved_size = (width == 0 && height == 0); + /* According to xdg_shell, an xdg_surface.configure with size 0x0 + * should be interpreted as that it is up to the client to set a + * size. + * + * When transitioning from maximize or fullscreen state, this means + * the client should configure its size back to what it was before + * being maximize or fullscreen. + */ + if (saved_size && !fixed_size) + { + width = impl->saved_width; + height = impl->saved_height; + } + + if (width > 0 && height > 0) + { + if (!saved_size) + { + impl->next_layout.toplevel.should_constrain = TRUE; + + /* Save size for next time we get 0x0 */ + _gdk_wayland_surface_save_size (surface); + } + else if (is_resizing) + { + impl->next_layout.toplevel.should_constrain = TRUE; + } + else + { + impl->next_layout.toplevel.should_constrain = FALSE; + } + + impl->next_layout.toplevel.size_is_fixed = fixed_size; + impl->next_layout.configured_width = width; + impl->next_layout.configured_height = height; + } + else + { + impl->next_layout.toplevel.should_constrain = FALSE; + impl->next_layout.toplevel.size_is_fixed = FALSE; + impl->next_layout.configured_width = 0; + impl->next_layout.configured_height = 0; + } + + impl->next_layout.surface_geometry_dirty = TRUE; + gdk_surface_request_layout (surface); + + GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS, + g_message ("configure, surface %p %dx%d,%s%s%s%s", + surface, width, height, + (new_state & GDK_TOPLEVEL_STATE_FULLSCREEN) ? " fullscreen" : "", + (new_state & GDK_TOPLEVEL_STATE_MAXIMIZED) ? " maximized" : "", + (new_state & GDK_TOPLEVEL_STATE_FOCUSED) ? " focused" : "", + (new_state & GDK_TOPLEVEL_STATE_TILED) ? " tiled" : "")); + + gdk_surface_queue_state_change (surface, ~0 & ~new_state, new_state); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_surface_ack_configure (impl->display_server.xdg_surface, + impl->pending.serial); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6, + impl->pending.serial); + break; + default: + g_assert_not_reached (); + } +} + +static void +gdk_wayland_surface_handle_configure_toplevel (GdkSurface *surface, + int32_t width, + int32_t height, + GdkToplevelState state) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + impl->pending.toplevel.state |= state; + impl->pending.toplevel.width = width; + impl->pending.toplevel.height = height; +} + +static void +gdk_wayland_surface_handle_close (GdkSurface *surface) +{ + GdkDisplay *display; + GdkEvent *event; + + display = gdk_surface_get_display (surface); + + GDK_DISPLAY_NOTE (display, EVENTS, g_message ("close %p", surface)); + + event = gdk_delete_event_new (surface); + + _gdk_wayland_display_deliver_event (display, event); +} + + +// DUPLICATED +static void +maybe_notify_mapped (GdkSurface *surface) +{ + if (surface->destroyed) + return; + + if (!GDK_SURFACE_IS_MAPPED (surface)) + gdk_surface_set_is_mapped (surface, TRUE); +} + +// DUPLICATED +static void +gdk_wayland_surface_configure (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + if (!impl->initial_configure_received) + { + gdk_surface_thaw_updates (surface); + impl->initial_configure_received = TRUE; + impl->pending.is_initial_configure = TRUE; + maybe_notify_mapped (surface); + } + + impl->has_uncommitted_ack_configure = TRUE; + + if (is_realized_toplevel (impl)) + gdk_wayland_surface_configure_toplevel (surface); + else + g_warn_if_reached (); + + impl->last_configure_serial = impl->pending.serial; + + memset (&impl->pending, 0, sizeof (impl->pending)); +} + +static void +gdk_wayland_surface_handle_configure (GdkSurface *surface, + uint32_t serial) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + impl->pending.is_dirty = TRUE; + impl->pending.serial = serial; + + if (impl->state_freeze_count > 0) + return; + + gdk_wayland_surface_configure (surface); +} + +static void +xdg_surface_configure (void *data, + struct xdg_surface *xdg_surface, + uint32_t serial) +{ + GdkSurface *surface = GDK_SURFACE (data); + + gdk_wayland_surface_handle_configure (surface, serial); +} + +static const struct xdg_surface_listener xdg_surface_listener = { + xdg_surface_configure, +}; + +static void +zxdg_surface_v6_configure (void *data, + struct zxdg_surface_v6 *xdg_surface, + uint32_t serial) +{ + GdkSurface *surface = GDK_SURFACE (data); + + gdk_wayland_surface_handle_configure (surface, serial); +} + +static const struct zxdg_surface_v6_listener zxdg_surface_v6_listener = { + zxdg_surface_v6_configure, +}; + +// DUPLICATED +static void +gdk_wayland_surface_create_xdg_surface_resources (GdkSurface *surface) +{ + GdkWaylandDisplay *display = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + switch (display->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + impl->display_server.xdg_surface = + xdg_wm_base_get_xdg_surface (display->xdg_wm_base, + impl->display_server.wl_surface); + wl_proxy_set_queue ((struct wl_proxy *) impl->display_server.xdg_surface, + impl->event_queue); + xdg_surface_add_listener (impl->display_server.xdg_surface, + &xdg_surface_listener, + surface); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + impl->display_server.zxdg_surface_v6 = + zxdg_shell_v6_get_xdg_surface (display->zxdg_shell_v6, + impl->display_server.wl_surface); + zxdg_surface_v6_add_listener (impl->display_server.zxdg_surface_v6, + &zxdg_surface_v6_listener, + surface); + break; + default: + g_assert_not_reached (); + } +} + +static void +xdg_toplevel_configure (void *data, + struct xdg_toplevel *xdg_toplevel, + int32_t width, + int32_t height, + struct wl_array *states) +{ + GdkSurface *surface = GDK_SURFACE (data); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + uint32_t *p; + GdkToplevelState pending_state = 0; + + impl->pending.toplevel.is_resizing = FALSE; + + wl_array_for_each (p, states) + { + uint32_t state = *p; + + switch (state) + { + case XDG_TOPLEVEL_STATE_FULLSCREEN: + pending_state |= GDK_TOPLEVEL_STATE_FULLSCREEN; + break; + case XDG_TOPLEVEL_STATE_MAXIMIZED: + pending_state |= GDK_TOPLEVEL_STATE_MAXIMIZED; + break; + case XDG_TOPLEVEL_STATE_ACTIVATED: + pending_state |= GDK_TOPLEVEL_STATE_FOCUSED; + break; + case XDG_TOPLEVEL_STATE_RESIZING: + impl->pending.toplevel.is_resizing = TRUE; + break; + default: + /* Unknown state */ + break; + } + } + + gdk_wayland_surface_handle_configure_toplevel (surface, width, height, + pending_state); +} + +static void +xdg_toplevel_close (void *data, + struct xdg_toplevel *xdg_toplevel) +{ + GdkSurface *surface = GDK_SURFACE (data); + + gdk_wayland_surface_handle_close (surface); +} + +static const struct xdg_toplevel_listener xdg_toplevel_listener = { + xdg_toplevel_configure, + xdg_toplevel_close, +}; + +static void +create_xdg_toplevel_resources (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + impl->display_server.xdg_toplevel = + xdg_surface_get_toplevel (impl->display_server.xdg_surface); + xdg_toplevel_add_listener (impl->display_server.xdg_toplevel, + &xdg_toplevel_listener, + surface); +} + +static void +zxdg_toplevel_v6_configure (void *data, + struct zxdg_toplevel_v6 *xdg_toplevel, + int32_t width, + int32_t height, + struct wl_array *states) +{ + GdkSurface *surface = GDK_SURFACE (data); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + uint32_t *p; + GdkToplevelState pending_state = 0; + + impl->pending.toplevel.is_resizing = FALSE; + + wl_array_for_each (p, states) + { + uint32_t state = *p; + + switch (state) + { + case ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN: + pending_state |= GDK_TOPLEVEL_STATE_FULLSCREEN; + break; + case ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED: + pending_state |= GDK_TOPLEVEL_STATE_MAXIMIZED; + break; + case ZXDG_TOPLEVEL_V6_STATE_ACTIVATED: + pending_state |= GDK_TOPLEVEL_STATE_FOCUSED; + break; + case ZXDG_TOPLEVEL_V6_STATE_RESIZING: + impl->pending.toplevel.is_resizing = TRUE; + break; + default: + /* Unknown state */ + break; + } + } + + gdk_wayland_surface_handle_configure_toplevel (surface, width, height, + pending_state); +} + +static void +zxdg_toplevel_v6_close (void *data, + struct zxdg_toplevel_v6 *xdg_toplevel) +{ + GdkSurface *surface = GDK_SURFACE (data); + + gdk_wayland_surface_handle_close (surface); +} + +static const struct zxdg_toplevel_v6_listener zxdg_toplevel_v6_listener = { + zxdg_toplevel_v6_configure, + zxdg_toplevel_v6_close, +}; + +static void +create_zxdg_toplevel_v6_resources (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + impl->display_server.zxdg_toplevel_v6 = + zxdg_surface_v6_get_toplevel (impl->display_server.zxdg_surface_v6); + zxdg_toplevel_v6_add_listener (impl->display_server.zxdg_toplevel_v6, + &zxdg_toplevel_v6_listener, + surface); +} + +/** + * gdk_wayland_toplevel_set_application_id: + * @toplevel: (type GdkWaylandToplevel): a `GdkToplevel` + * @application_id: the application id for the @toplevel + * + * Sets the application id on a `GdkToplevel`. + */ +void +gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel, + const char *application_id) +{ + GdkWaylandSurface *impl; + GdkWaylandDisplay *display_wayland; + + g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); + + g_return_if_fail (application_id != NULL); + + if (GDK_SURFACE_DESTROYED (toplevel)) + return; + + impl = GDK_WAYLAND_SURFACE (toplevel); + + if (!is_realized_toplevel (impl)) + return; + + display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel))); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_app_id (impl->display_server.xdg_toplevel, + application_id); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_app_id (impl->display_server.zxdg_toplevel_v6, + application_id); + break; + default: + g_assert_not_reached (); + } +} + +void +gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) +{ + GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + const char *app_id; + + gdk_surface_freeze_updates (surface); + gdk_wayland_surface_create_xdg_surface_resources (surface); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + create_xdg_toplevel_resources (surface); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + create_zxdg_toplevel_v6_resources (surface); + break; + default: + g_assert_not_reached (); + } + + gdk_wayland_surface_sync_parent (surface, NULL); + gdk_wayland_surface_sync_parent_of_imported (impl); + gdk_wayland_surface_sync_title (surface); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED) + xdg_toplevel_set_maximized (impl->display_server.xdg_toplevel); + if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED) + xdg_toplevel_set_minimized (impl->display_server.xdg_toplevel); + if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) + xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, + impl->initial_fullscreen_output); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED) + zxdg_toplevel_v6_set_maximized (impl->display_server.zxdg_toplevel_v6); + if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED) + zxdg_toplevel_v6_set_minimized (impl->display_server.zxdg_toplevel_v6); + if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) + zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, + impl->initial_fullscreen_output); + break; + default: + g_assert_not_reached (); + } + + impl->initial_fullscreen_output = NULL; + + app_id = impl->application.application_id; + if (app_id == NULL) + app_id = g_get_prgname (); + + if (app_id == NULL) + app_id = "GTK Application"; + + gdk_wayland_toplevel_set_application_id (GDK_TOPLEVEL (impl), app_id); + + maybe_set_gtk_surface_dbus_properties (impl); + maybe_set_gtk_surface_modal (surface); + + gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit"); + wl_surface_commit (impl->display_server.wl_surface); +} + +void +gdk_wayland_toplevel_announce_csd (GdkToplevel *toplevel) +{ + GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel))); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); + + g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); + + if (!display_wayland->server_decoration_manager) + return; + impl->display_server.server_decoration = + org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager, + impl->display_server.wl_surface); + if (impl->display_server.server_decoration) + org_kde_kwin_server_decoration_request_mode (impl->display_server.server_decoration, + ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT); +} + +void +gdk_wayland_toplevel_announce_ssd (GdkToplevel *toplevel) +{ + GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel))); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); + + g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); + + if (!display_wayland->server_decoration_manager) + return; + impl->display_server.server_decoration = + org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager, + impl->display_server.wl_surface); + if (impl->display_server.server_decoration) + org_kde_kwin_server_decoration_request_mode (impl->display_server.server_decoration, + ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER); +} + + +gboolean +gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel) +{ + GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel))); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); + + g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE); + + if (!display_wayland->idle_inhibit_manager) + return FALSE; + + if (!impl->idle_inhibitor) + { + g_assert (impl->idle_inhibitor_refcount == 0); + impl->idle_inhibitor = + zwp_idle_inhibit_manager_v1_create_inhibitor (display_wayland->idle_inhibit_manager, + impl->display_server.wl_surface); + } + ++impl->idle_inhibitor_refcount; + + return TRUE; +} + +void +gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); + + g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); + + g_assert (impl->idle_inhibitor && impl->idle_inhibitor_refcount > 0); + + if (--impl->idle_inhibitor_refcount == 0) + { + zwp_idle_inhibitor_v1_destroy (impl->idle_inhibitor); + impl->idle_inhibitor = NULL; + } +} + +static void +gdk_wayland_surface_focus (GdkSurface *surface, + guint32 timestamp) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + if (!impl->display_server.gtk_surface) + return; + + if (timestamp == GDK_CURRENT_TIME) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + if (display_wayland->startup_notification_id) + { + if (display_wayland->xdg_activation) + { + xdg_activation_v1_activate (display_wayland->xdg_activation, + display_wayland->startup_notification_id, + impl->display_server.wl_surface); + } + else if (display_wayland->gtk_shell_version >= 3) + { + gtk_surface1_request_focus (impl->display_server.gtk_surface, + display_wayland->startup_notification_id); + } + + g_clear_pointer (&display_wayland->startup_notification_id, g_free); + } + } + else + gtk_surface1_present (impl->display_server.gtk_surface, timestamp); +} + +static void +gtk_surface_configure (void *data, + struct gtk_surface1 *gtk_surface, + struct wl_array *states) +{ + GdkSurface *surface = GDK_SURFACE (data); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkToplevelState new_state = 0; + uint32_t *p; + + wl_array_for_each (p, states) + { + uint32_t state = *p; + + switch (state) + { + case GTK_SURFACE1_STATE_TILED: + new_state |= GDK_TOPLEVEL_STATE_TILED; + break; + + /* Since v2 */ + case GTK_SURFACE1_STATE_TILED_TOP: + new_state |= (GDK_TOPLEVEL_STATE_TILED | GDK_TOPLEVEL_STATE_TOP_TILED); + break; + case GTK_SURFACE1_STATE_TILED_RIGHT: + new_state |= (GDK_TOPLEVEL_STATE_TILED | GDK_TOPLEVEL_STATE_RIGHT_TILED); + break; + case GTK_SURFACE1_STATE_TILED_BOTTOM: + new_state |= (GDK_TOPLEVEL_STATE_TILED | GDK_TOPLEVEL_STATE_BOTTOM_TILED); + break; + case GTK_SURFACE1_STATE_TILED_LEFT: + new_state |= (GDK_TOPLEVEL_STATE_TILED | GDK_TOPLEVEL_STATE_LEFT_TILED); + break; + default: + /* Unknown state */ + break; + } + } + + impl->pending.toplevel.state |= new_state; +} + +static void +gtk_surface_configure_edges (void *data, + struct gtk_surface1 *gtk_surface, + struct wl_array *edge_constraints) +{ + GdkSurface *surface = GDK_SURFACE (data); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkToplevelState new_state = 0; + uint32_t *p; + + wl_array_for_each (p, edge_constraints) + { + uint32_t constraint = *p; + + switch (constraint) + { + case GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_TOP: + new_state |= GDK_TOPLEVEL_STATE_TOP_RESIZABLE; + break; + case GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_RIGHT: + new_state |= GDK_TOPLEVEL_STATE_RIGHT_RESIZABLE; + break; + case GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_BOTTOM: + new_state |= GDK_TOPLEVEL_STATE_BOTTOM_RESIZABLE; + break; + case GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_LEFT: + new_state |= GDK_TOPLEVEL_STATE_LEFT_RESIZABLE; + break; + default: + /* Unknown state */ + break; + } + } + + impl->pending.toplevel.state |= new_state; +} + +static const struct gtk_surface1_listener gtk_surface_listener = { + gtk_surface_configure, + gtk_surface_configure_edges +}; + +static void +gdk_wayland_surface_init_gtk_surface (GdkWaylandSurface *impl) +{ + GdkWaylandDisplay *display = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (impl))); + + if (impl->display_server.gtk_surface != NULL) + return; + if (!is_realized_toplevel (impl)) + return; + if (display->gtk_shell == NULL) + return; + + impl->display_server.gtk_surface = + gtk_shell1_get_gtk_surface (display->gtk_shell, + impl->display_server.wl_surface); + wl_proxy_set_queue ((struct wl_proxy *) impl->display_server.gtk_surface, + impl->event_queue); + gdk_wayland_surface_set_geometry_hints (impl, + &impl->geometry_hints, + impl->geometry_mask); + gtk_surface1_add_listener (impl->display_server.gtk_surface, + >k_surface_listener, + impl); +} + +static void +maybe_set_gtk_surface_modal (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + gdk_wayland_surface_init_gtk_surface (impl); + if (impl->display_server.gtk_surface == NULL) + return; + + if (surface->modal_hint) + gtk_surface1_set_modal (impl->display_server.gtk_surface); + else + gtk_surface1_unset_modal (impl->display_server.gtk_surface); + +} + +static void +gdk_wayland_surface_set_modal_hint (GdkSurface *surface, + gboolean modal) +{ + surface->modal_hint = modal; + maybe_set_gtk_surface_modal (surface); +} + +static void +gdk_wayland_surface_set_startup_id (GdkSurface *surface, + const char *startup_id) +{ +} + +static gboolean +check_transient_for_loop (GdkWaylandToplevel *toplevel, + GdkWaylandToplevel *parent) +{ + while (parent) + { + if (parent->transient_for == toplevel) + return TRUE; + parent = parent->transient_for; + } + return FALSE; +} + +static void +gdk_wayland_toplevel_set_transient_for (GdkWaylandToplevel *toplevel, + GdkSurface *parent) +{ + g_return_if_fail (!parent || GDK_IS_WAYLAND_TOPLEVEL (parent)); + g_return_if_fail (!parent || + gdk_surface_get_display (GDK_SURFACE (toplevel)) == gdk_surface_get_display (parent)); + + if (parent) + { + GdkWaylandToplevel *parent_toplevel = GDK_WAYLAND_TOPLEVEL (parent); + + if (check_transient_for_loop (toplevel, parent_toplevel)) + { + g_warning ("Setting %p transient for %p would create a loop", + toplevel, parent); + return; + } + } + + unset_transient_for_exported (GDK_SURFACE (toplevel)); + + if (parent) + toplevel->transient_for = GDK_WAYLAND_TOPLEVEL (parent); + else + toplevel->transient_for = NULL; + + gdk_wayland_surface_sync_parent (GDK_SURFACE (toplevel), NULL); +} + +static void +gdk_wayland_surface_minimize (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandDisplay *display_wayland; + + if (GDK_SURFACE_DESTROYED (surface) || + !SURFACE_IS_TOPLEVEL (surface)) + return; + + if (!is_realized_toplevel (GDK_WAYLAND_SURFACE (surface))) + return; + + /* FIXME: xdg_toplevel does not come with a minimized state that we can + * query or get notified of. This means we cannot implement the full + * GdkSurface API, and our state will not reflect minimization. + */ + display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_minimized (impl->display_server.xdg_toplevel); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_minimized (impl->display_server.zxdg_toplevel_v6); + break; + default: + g_assert_not_reached (); + } +} + +static void +gdk_wayland_surface_maximize (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + if (GDK_SURFACE_DESTROYED (surface)) + return; + + _gdk_wayland_surface_save_size (surface); + + if (is_realized_toplevel (impl)) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_maximized (impl->display_server.xdg_toplevel); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_maximized (impl->display_server.zxdg_toplevel_v6); + break; + default: + g_assert_not_reached (); + } + } + else + { + synthesize_initial_surface_state (surface, 0, GDK_TOPLEVEL_STATE_MAXIMIZED); + } +} + +static void +gdk_wayland_surface_unmaximize (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + if (GDK_SURFACE_DESTROYED (surface)) + return; + + if (is_realized_toplevel (impl)) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_unset_maximized (impl->display_server.xdg_toplevel); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_unset_maximized (impl->display_server.zxdg_toplevel_v6); + break; + default: + g_assert_not_reached (); + } + } + else + { + synthesize_initial_surface_state (surface, GDK_TOPLEVEL_STATE_MAXIMIZED, 0); + } +} + +static void +gdk_wayland_surface_fullscreen_on_monitor (GdkSurface *surface, + GdkMonitor *monitor) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + struct wl_output *output = ((GdkWaylandMonitor *)monitor)->output; + + if (GDK_SURFACE_DESTROYED (surface)) + return; + + _gdk_wayland_surface_save_size (surface); + + if (is_realized_toplevel (impl)) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, + output); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, + output); + break; + default: + g_assert_not_reached (); + } + } + else + { + synthesize_initial_surface_state (surface, 0, GDK_TOPLEVEL_STATE_FULLSCREEN); + impl->initial_fullscreen_output = output; + } +} + +static void +gdk_wayland_surface_fullscreen (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + if (GDK_SURFACE_DESTROYED (surface)) + return; + + impl->initial_fullscreen_output = NULL; + + _gdk_wayland_surface_save_size (surface); + + if (is_realized_toplevel (impl)) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, + NULL); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, + NULL); + break; + default: + g_assert_not_reached (); + } + } + else + { + synthesize_initial_surface_state (surface, 0, GDK_TOPLEVEL_STATE_FULLSCREEN); + } +} + +static void +gdk_wayland_surface_unfullscreen (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + if (GDK_SURFACE_DESTROYED (surface)) + return; + + impl->initial_fullscreen_output = NULL; + + if (is_realized_toplevel (impl)) + { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_unset_fullscreen (impl->display_server.xdg_toplevel); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_unset_fullscreen (impl->display_server.zxdg_toplevel_v6); + break; + default: + g_assert_not_reached (); + } + } + else + { + synthesize_initial_surface_state (surface, GDK_TOPLEVEL_STATE_FULLSCREEN, 0); + } +} + +static void +gdk_wayland_toplevel_begin_resize (GdkToplevel *toplevel, + GdkSurfaceEdge edge, + GdkDevice *device, + int button, + double x, + double y, + guint32 timestamp) +{ + GdkSurface *surface = GDK_SURFACE (toplevel); + GdkWaylandSurface *impl; + GdkWaylandDisplay *display_wayland; + GdkEventSequence *sequence; + uint32_t resize_edges, serial; + + if (GDK_SURFACE_DESTROYED (surface) || + !SURFACE_IS_TOPLEVEL (surface)) + return; + + switch (edge) + { + case GDK_SURFACE_EDGE_NORTH_WEST: + resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_TOP_LEFT; + break; + + case GDK_SURFACE_EDGE_NORTH: + resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_TOP; + break; + + case GDK_SURFACE_EDGE_NORTH_EAST: + resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_TOP_RIGHT; + break; + + case GDK_SURFACE_EDGE_WEST: + resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_LEFT; + break; + + case GDK_SURFACE_EDGE_EAST: + resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_RIGHT; + break; + + case GDK_SURFACE_EDGE_SOUTH_WEST: + resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_BOTTOM_LEFT; + break; + + case GDK_SURFACE_EDGE_SOUTH: + resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_BOTTOM; + break; + + case GDK_SURFACE_EDGE_SOUTH_EAST: + resize_edges = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_BOTTOM_RIGHT; + break; + + default: + g_warning ("gdk_toplevel_begin_resize: bad resize edge %d!", edge); + return; + } + + impl = GDK_WAYLAND_SURFACE (surface); + display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + if (!is_realized_toplevel (impl)) + return; + + serial = _gdk_wayland_seat_get_last_implicit_grab_serial (GDK_WAYLAND_SEAT (gdk_device_get_seat (device)), + &sequence); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_resize (impl->display_server.xdg_toplevel, + gdk_wayland_device_get_wl_seat (device), + serial, resize_edges); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_resize (impl->display_server.zxdg_toplevel_v6, + gdk_wayland_device_get_wl_seat (device), + serial, resize_edges); + break; + default: + g_assert_not_reached (); + } + + if (sequence) + gdk_wayland_device_unset_touch_grab (device, sequence); +} + +static void +gdk_wayland_toplevel_begin_move (GdkToplevel *toplevel, + GdkDevice *device, + int button, + double x, + double y, + guint32 timestamp) +{ + GdkSurface *surface = GDK_SURFACE (toplevel); + GdkWaylandSurface *impl; + GdkWaylandDisplay *display_wayland; + GdkEventSequence *sequence; + uint32_t serial; + + if (GDK_SURFACE_DESTROYED (surface) || + !SURFACE_IS_TOPLEVEL (surface)) + return; + + impl = GDK_WAYLAND_SURFACE (surface); + display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + if (!is_realized_toplevel (impl)) + return; + + serial = _gdk_wayland_seat_get_last_implicit_grab_serial (GDK_WAYLAND_SEAT (gdk_device_get_seat (device)), + &sequence); + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_move (impl->display_server.xdg_toplevel, + gdk_wayland_device_get_wl_seat (device), + serial); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_move (impl->display_server.zxdg_toplevel_v6, + gdk_wayland_device_get_wl_seat (device), + serial); + break; + default: + g_assert_not_reached (); + } + + if (sequence) + gdk_wayland_device_unset_touch_grab (device, sequence); +} + + +static gboolean +gdk_wayland_surface_show_window_menu (GdkSurface *surface, + GdkEvent *event) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + GdkSeat *seat; + struct wl_seat *wl_seat; + double x, y; + uint32_t serial; + + GdkEventType event_type = gdk_event_get_event_type (event); + switch ((guint) event_type) + { + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + case GDK_TOUCH_BEGIN: + case GDK_TOUCH_END: + break; + default: + return FALSE; + } + + if (!is_realized_toplevel (impl)) + return FALSE; + + seat = gdk_event_get_seat (event); + wl_seat = gdk_wayland_seat_get_wl_seat (seat); + gdk_event_get_position (event, &x, &y); + + serial = _gdk_wayland_seat_get_implicit_grab_serial (seat, event); + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_show_window_menu (impl->display_server.xdg_toplevel, + wl_seat, serial, x, y); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_show_window_menu (impl->display_server.zxdg_toplevel_v6, + wl_seat, serial, x, y); + break; + default: + g_assert_not_reached (); + } + + return TRUE; +} + +static gboolean +gdk_wayland_surface_supports_edge_constraints (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + struct gtk_surface1 *gtk_surface = impl->display_server.gtk_surface; + + if (!gtk_surface) + return FALSE; + + return gtk_surface1_get_version (gtk_surface) >= GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION; +} + +static void +maybe_set_gtk_surface_dbus_properties (GdkWaylandSurface *impl) +{ + if (impl->application.was_set) + return; + + if (impl->application.application_id == NULL && + impl->application.app_menu_path == NULL && + impl->application.menubar_path == NULL && + impl->application.window_object_path == NULL && + impl->application.application_object_path == NULL && + impl->application.unique_bus_name == NULL) + return; + + gdk_wayland_surface_init_gtk_surface (impl); + if (impl->display_server.gtk_surface == NULL) + return; + + gtk_surface1_set_dbus_properties (impl->display_server.gtk_surface, + impl->application.application_id, + impl->application.app_menu_path, + impl->application.menubar_path, + impl->application.window_object_path, + impl->application.application_object_path, + impl->application.unique_bus_name); + impl->application.was_set = TRUE; +} + +void +gdk_wayland_toplevel_set_dbus_properties (GdkToplevel *toplevel, + const char *application_id, + const char *app_menu_path, + const char *menubar_path, + const char *window_object_path, + const char *application_object_path, + const char *unique_bus_name) +{ + GdkWaylandSurface *impl; + + g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); + + impl = GDK_WAYLAND_SURFACE (toplevel); + + impl->application.application_id = g_strdup (application_id); + impl->application.app_menu_path = g_strdup (app_menu_path); + impl->application.menubar_path = g_strdup (menubar_path); + impl->application.window_object_path = g_strdup (window_object_path); + impl->application.application_object_path = + g_strdup (application_object_path); + impl->application.unique_bus_name = g_strdup (unique_bus_name); + + maybe_set_gtk_surface_dbus_properties (impl); +} + +static void +xdg_exported_handle (void *data, + struct zxdg_exported_v1 *zxdg_exported_v1, + const char *handle) +{ + GdkToplevel *toplevel = data; + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); + + impl->exported.callback (toplevel, handle, impl->exported.user_data); + if (impl->exported.destroy_func) + { + g_clear_pointer (&impl->exported.user_data, + impl->exported.destroy_func); + } +} + +static const struct zxdg_exported_v1_listener xdg_exported_listener = { + xdg_exported_handle +}; + +/** + * gdk_wayland_toplevel_export_handle: + * @toplevel: (type GdkWaylandToplevel): the `GdkToplevel` to obtain a handle for + * @callback: callback to call with the handle + * @user_data: (closure): user data for @callback + * @destroy_func: destroy notify for @user_data + * + * Asynchronously obtains a handle for a surface that can be passed + * to other processes. + * + * When the handle has been obtained, @callback will be called. + * + * It is an error to call this function on a surface that is already + * exported. + * + * When the handle is no longer needed, [method@GdkWaylandToplevel.unexport_handle] + * should be called to clean up resources. + * + * The main purpose for obtaining a handle is to mark a surface + * from another surface as transient for this one, see + * [method@GdkWayland.WaylandToplevel.set_transient_for_exported]. + * + * Note that this API depends on an unstable Wayland protocol, + * and thus may require changes in the future. + * + * Return value: %TRUE if the handle has been requested, %FALSE if + * an error occurred. + */ +gboolean +gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel, + GdkWaylandToplevelExported callback, + gpointer user_data, + GDestroyNotify destroy_func) +{ + GdkWaylandSurface *impl; + GdkWaylandDisplay *display_wayland; + GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (toplevel)); + struct zxdg_exported_v1 *xdg_exported; + + g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE); + g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE); + + impl = GDK_WAYLAND_SURFACE (toplevel); + display_wayland = GDK_WAYLAND_DISPLAY (display); + + g_return_val_if_fail (!impl->display_server.xdg_exported, FALSE); + + if (!display_wayland->xdg_exporter) + { + g_warning ("Server is missing xdg_foreign support"); + return FALSE; + } + + xdg_exported = zxdg_exporter_v1_export (display_wayland->xdg_exporter, + impl->display_server.wl_surface); + zxdg_exported_v1_add_listener (xdg_exported, &xdg_exported_listener, impl); + + impl->display_server.xdg_exported = xdg_exported; + impl->exported.callback = callback; + impl->exported.user_data = user_data; + impl->exported.destroy_func = destroy_func; + + return TRUE; +} + +/** + * gdk_wayland_toplevel_unexport_handle: + * @toplevel: (type GdkWaylandToplevel): the `GdkToplevel` to unexport + * + * Destroys the handle that was obtained with + * gdk_wayland_toplevel_export_handle(). + * + * It is an error to call this function on a surface that + * does not have a handle. + * + * Note that this API depends on an unstable Wayland protocol, + * and thus may require changes in the future. + */ +void +gdk_wayland_toplevel_unexport_handle (GdkToplevel *toplevel) +{ + GdkWaylandSurface *impl; + + g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); + + impl = GDK_WAYLAND_SURFACE (toplevel); + + g_return_if_fail (impl->display_server.xdg_exported); + + g_clear_pointer (&impl->display_server.xdg_exported, + zxdg_exported_v1_destroy); + if (impl->exported.destroy_func) + { + g_clear_pointer (&impl->exported.user_data, + impl->exported.destroy_func); + } +} + +static void +xdg_imported_destroyed (void *data, + struct zxdg_imported_v1 *zxdg_imported_v1) +{ + GdkSurface *surface = data; + + unset_transient_for_exported (surface); +} + +static const struct zxdg_imported_v1_listener xdg_imported_listener = { + xdg_imported_destroyed, +}; + +/** + * gdk_wayland_toplevel_set_transient_for_exported: + * @toplevel: (type GdkWaylandToplevel): the `GdkToplevel` to make as transient + * @parent_handle_str: an exported handle for a surface + * + * Marks @toplevel as transient for the surface to which the given + * @parent_handle_str refers. + * + * Typically, the handle will originate + * from a gdk_wayland_toplevel_export_handle() call in another process. + * + * Note that this API depends on an unstable Wayland protocol, + * and thus may require changes in the future. + * + * Return value: %TRUE if the surface has been marked as transient, + * %FALSE if an error occurred. + */ +gboolean +gdk_wayland_toplevel_set_transient_for_exported (GdkToplevel *toplevel, + const char *parent_handle_str) +{ + GdkWaylandSurface *impl; + GdkWaylandDisplay *display_wayland; + GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (toplevel)); + + g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE); + g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE); + + impl = GDK_WAYLAND_SURFACE (toplevel); + display_wayland = GDK_WAYLAND_DISPLAY (display); + + if (!display_wayland->xdg_importer) + { + g_warning ("Server is missing xdg_foreign support"); + return FALSE; + } + + gdk_wayland_toplevel_set_transient_for (GDK_WAYLAND_TOPLEVEL (impl), NULL); + + impl->imported_transient_for = + zxdg_importer_v1_import (display_wayland->xdg_importer, parent_handle_str); + zxdg_imported_v1_add_listener (impl->imported_transient_for, + &xdg_imported_listener, + toplevel); + + gdk_wayland_surface_sync_parent_of_imported (impl); + + return TRUE; +} + +static void +gdk_wayland_toplevel_init (GdkWaylandToplevel *toplevel) +{ +} + +#define LAST_PROP 1 + +static void +gdk_wayland_toplevel_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdkSurface *surface = GDK_SURFACE (object); + GdkWaylandToplevel *toplevel = GDK_WAYLAND_TOPLEVEL (surface); + + switch (prop_id) + { + case LAST_PROP + GDK_TOPLEVEL_PROP_TITLE: + gdk_wayland_surface_set_title (surface, g_value_get_string (value)); + g_object_notify_by_pspec (G_OBJECT (surface), pspec); + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_STARTUP_ID: + gdk_wayland_surface_set_startup_id (surface, g_value_get_string (value)); + g_object_notify_by_pspec (G_OBJECT (surface), pspec); + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_TRANSIENT_FOR: + gdk_wayland_toplevel_set_transient_for (toplevel, + g_value_get_object (value)); + g_object_notify_by_pspec (G_OBJECT (surface), pspec); + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL: + gdk_wayland_surface_set_modal_hint (surface, g_value_get_boolean (value)); + g_object_notify_by_pspec (G_OBJECT (surface), pspec); + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST: + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_DECORATED: + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_DELETABLE: + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_FULLSCREEN_MODE: + surface->fullscreen_mode = g_value_get_enum (value); + g_object_notify_by_pspec (G_OBJECT (surface), pspec); + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_SHORTCUTS_INHIBITED: + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdk_wayland_toplevel_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdkSurface *surface = GDK_SURFACE (object); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *toplevel = GDK_WAYLAND_TOPLEVEL (surface); + + switch (prop_id) + { + case LAST_PROP + GDK_TOPLEVEL_PROP_STATE: + g_value_set_flags (value, surface->state); + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_TITLE: + g_value_set_string (value, impl->title); + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_STARTUP_ID: + g_value_set_string (value, ""); + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_TRANSIENT_FOR: + g_value_set_object (value, toplevel->transient_for); + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL: + g_value_set_boolean (value, surface->modal_hint); + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST: + g_value_set_pointer (value, NULL); + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_DECORATED: + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_DELETABLE: + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_FULLSCREEN_MODE: + g_value_set_enum (value, surface->fullscreen_mode); + break; + + case LAST_PROP + GDK_TOPLEVEL_PROP_SHORTCUTS_INHIBITED: + g_value_set_boolean (value, surface->shortcuts_inhibited); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->get_property = gdk_wayland_toplevel_get_property; + object_class->set_property = gdk_wayland_toplevel_set_property; + + gdk_toplevel_install_properties (object_class, 1); +} + +static void +gdk_wayland_toplevel_present (GdkToplevel *toplevel, + GdkToplevelLayout *layout) +{ + GdkSurface *surface = GDK_SURFACE (toplevel); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + gboolean pending_configure = FALSE; + gboolean maximize; + gboolean fullscreen; + + if (gdk_toplevel_layout_get_maximized (layout, &maximize)) + { + if (maximize) + gdk_wayland_surface_maximize (surface); + else + gdk_wayland_surface_unmaximize (surface); + pending_configure = TRUE; + } + + if (gdk_toplevel_layout_get_fullscreen (layout, &fullscreen)) + { + if (fullscreen) + { + GdkMonitor *monitor; + + monitor = gdk_toplevel_layout_get_fullscreen_monitor (layout); + if (monitor) + gdk_wayland_surface_fullscreen_on_monitor (surface, monitor); + else + gdk_wayland_surface_fullscreen (surface); + } + else + { + gdk_wayland_surface_unfullscreen (surface); + } + pending_configure = TRUE; + } + + g_clear_pointer (&impl->toplevel.layout, gdk_toplevel_layout_unref); + impl->toplevel.layout = gdk_toplevel_layout_copy (layout); + + gdk_wayland_surface_show (surface, FALSE); + + if (!pending_configure) + { + impl->next_layout.surface_geometry_dirty = TRUE; + gdk_surface_request_layout (surface); + } +} + +static gboolean +gdk_wayland_toplevel_minimize (GdkToplevel *toplevel) +{ + gdk_wayland_surface_minimize (GDK_SURFACE (toplevel)); + + return TRUE; +} + +static gboolean +gdk_wayland_toplevel_lower (GdkToplevel *toplevel) +{ + return FALSE; +} + +static void +gdk_wayland_toplevel_focus (GdkToplevel *toplevel, + guint32 timestamp) +{ + gdk_wayland_surface_focus (GDK_SURFACE (toplevel), timestamp); +} + +static gboolean +gdk_wayland_toplevel_show_window_menu (GdkToplevel *toplevel, + GdkEvent *event) +{ + return gdk_wayland_surface_show_window_menu (GDK_SURFACE (toplevel), event); +} + +static gboolean +gdk_wayland_toplevel_supports_edge_constraints (GdkToplevel *toplevel) +{ + return gdk_wayland_surface_supports_edge_constraints (GDK_SURFACE (toplevel)); +} + +static void +inhibitor_active (void *data, + struct zwp_keyboard_shortcuts_inhibitor_v1 *inhibitor) +{ + GdkToplevel *toplevel = GDK_TOPLEVEL (data); + GdkSurface *surface = GDK_SURFACE (toplevel); + + surface->shortcuts_inhibited = TRUE; + g_object_notify (G_OBJECT (toplevel), "shortcuts-inhibited"); +} + +static void +inhibitor_inactive (void *data, + struct zwp_keyboard_shortcuts_inhibitor_v1 *inhibitor) +{ + GdkToplevel *toplevel = GDK_TOPLEVEL (data); + GdkSurface *surface = GDK_SURFACE (toplevel); + + surface->shortcuts_inhibited = FALSE; + g_object_notify (G_OBJECT (toplevel), "shortcuts-inhibited"); +} + +static const struct zwp_keyboard_shortcuts_inhibitor_v1_listener +zwp_keyboard_shortcuts_inhibitor_listener = { + inhibitor_active, + inhibitor_inactive, +}; + +static void +gdk_wayland_toplevel_inhibit_system_shortcuts (GdkToplevel *toplevel, + GdkEvent *event) +{ + struct zwp_keyboard_shortcuts_inhibitor_v1 *inhibitor; + GdkSurface *surface = GDK_SURFACE (toplevel); + GdkWaylandSurface *impl= GDK_WAYLAND_SURFACE (surface); + GdkSeat *gdk_seat; + + if (surface->shortcuts_inhibited) + return; + + gdk_seat = gdk_surface_get_seat_from_event (surface, event); + gdk_wayland_surface_inhibit_shortcuts (surface, gdk_seat); + + inhibitor = gdk_wayland_surface_get_inhibitor (impl, gdk_seat); + if (!inhibitor) + return; + + surface->current_shortcuts_inhibited_seat = gdk_seat; + zwp_keyboard_shortcuts_inhibitor_v1_add_listener + (inhibitor, &zwp_keyboard_shortcuts_inhibitor_listener, toplevel); +} + +static void +gdk_wayland_toplevel_restore_system_shortcuts (GdkToplevel *toplevel) +{ + GdkSurface *surface = GDK_SURFACE (toplevel); + + gdk_wayland_surface_restore_shortcuts (surface, + surface->current_shortcuts_inhibited_seat); + surface->current_shortcuts_inhibited_seat = NULL; + surface->shortcuts_inhibited = FALSE; + g_object_notify (G_OBJECT (toplevel), "shortcuts-inhibited"); +} + +static void +gdk_wayland_toplevel_iface_init (GdkToplevelInterface *iface) +{ + iface->present = gdk_wayland_toplevel_present; + iface->minimize = gdk_wayland_toplevel_minimize; + iface->lower = gdk_wayland_toplevel_lower; + iface->focus = gdk_wayland_toplevel_focus; + iface->show_window_menu = gdk_wayland_toplevel_show_window_menu; + iface->supports_edge_constraints = gdk_wayland_toplevel_supports_edge_constraints; + iface->inhibit_system_shortcuts = gdk_wayland_toplevel_inhibit_system_shortcuts; + iface->restore_system_shortcuts = gdk_wayland_toplevel_restore_system_shortcuts; + iface->begin_resize = gdk_wayland_toplevel_begin_resize; + iface->begin_move = gdk_wayland_toplevel_begin_move; +} diff --git a/gdk/wayland/gdkwayland.h b/gdk/wayland/gdkwayland.h index 4e7981a229a..5fb89e8d0f5 100644 --- a/gdk/wayland/gdkwayland.h +++ b/gdk/wayland/gdkwayland.h @@ -35,6 +35,7 @@ #include #include #include +#include #undef __GDKWAYLAND_H_INSIDE__ diff --git a/gdk/wayland/gdkwaylandsurface.h b/gdk/wayland/gdkwaylandsurface.h index 851a4d5607f..c94a3cbd16c 100644 --- a/gdk/wayland/gdkwaylandsurface.h +++ b/gdk/wayland/gdkwaylandsurface.h @@ -30,11 +30,9 @@ G_BEGIN_DECLS #ifdef GTK_COMPILATION typedef struct _GdkWaylandSurface GdkWaylandSurface; -typedef struct _GdkWaylandToplevel GdkWaylandToplevel; typedef struct _GdkWaylandPopup GdkWaylandPopup; #else typedef GdkSurface GdkWaylandSurface; -typedef GdkToplevel GdkWaylandToplevel; typedef GdkPopup GdkWaylandPopup; #endif @@ -42,10 +40,6 @@ typedef GdkPopup GdkWaylandPopup; #define GDK_WAYLAND_SURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_SURFACE, GdkWaylandSurface)) #define GDK_IS_WAYLAND_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_SURFACE)) -#define GDK_TYPE_WAYLAND_TOPLEVEL (gdk_wayland_toplevel_get_type()) -#define GDK_WAYLAND_TOPLEVEL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_TOPLEVEL, GdkWaylandToplevel)) -#define GDK_IS_WAYLAND_TOPLEVEL(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_TOPLEVEL)) - #define GDK_TYPE_WAYLAND_POPUP (gdk_wayland_popup_get_type()) #define GDK_WAYLAND_POPUP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_POPUP, GdkWaylandPopup)) #define GDK_IS_WAYLAND_POPUP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_POPUP)) @@ -53,36 +47,12 @@ typedef GdkPopup GdkWaylandPopup; GDK_AVAILABLE_IN_ALL GType gdk_wayland_surface_get_type (void); -GDK_AVAILABLE_IN_ALL -GType gdk_wayland_toplevel_get_type (void); - GDK_AVAILABLE_IN_ALL GType gdk_wayland_popup_get_type (void); GDK_AVAILABLE_IN_ALL struct wl_surface *gdk_wayland_surface_get_wl_surface (GdkSurface *surface); -typedef void (*GdkWaylandToplevelExported) (GdkToplevel *toplevel, - const char *handle, - gpointer user_data); - -GDK_AVAILABLE_IN_ALL -gboolean gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel, - GdkWaylandToplevelExported callback, - gpointer user_data, - GDestroyNotify destroy_func); - -GDK_AVAILABLE_IN_ALL -void gdk_wayland_toplevel_unexport_handle (GdkToplevel *toplevel); - -GDK_AVAILABLE_IN_ALL -gboolean gdk_wayland_toplevel_set_transient_for_exported (GdkToplevel *toplevel, - const char *parent_handle_str); - -GDK_AVAILABLE_IN_ALL -void gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel, - const char *application_id); - G_END_DECLS #endif /* __GDK_WAYLAND_SURFACE_H__ */ diff --git a/gdk/wayland/gdkwaylandtoplevel.h b/gdk/wayland/gdkwaylandtoplevel.h new file mode 100644 index 00000000000..492dbcd6070 --- /dev/null +++ b/gdk/wayland/gdkwaylandtoplevel.h @@ -0,0 +1,73 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2013 Jan Arne Petersen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef __GDK_WAYLAND_TOPLEVEL_H__ +#define __GDK_WAYLAND_TOPLEVEL_H__ + +#if !defined (__GDKWAYLAND_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +#include + +G_BEGIN_DECLS + +#ifdef GTK_COMPILATION +typedef struct _GdkWaylandToplevel GdkWaylandToplevel; +#else +typedef GdkToplevel GdkWaylandToplevel; +#endif + +#define GDK_TYPE_WAYLAND_TOPLEVEL (gdk_wayland_toplevel_get_type()) +#define GDK_WAYLAND_TOPLEVEL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_TOPLEVEL, GdkWaylandToplevel)) +#define GDK_IS_WAYLAND_TOPLEVEL(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_TOPLEVEL)) + +GDK_AVAILABLE_IN_ALL +GType gdk_wayland_toplevel_get_type (void); + +typedef void (*GdkWaylandToplevelExported) (GdkToplevel *toplevel, + const char *handle, + gpointer user_data); + +GDK_AVAILABLE_IN_ALL +gboolean gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel, + GdkWaylandToplevelExported callback, + gpointer user_data, + GDestroyNotify destroy_func); + +GDK_AVAILABLE_IN_ALL +void gdk_wayland_toplevel_unexport_handle (GdkToplevel *toplevel); + +GDK_AVAILABLE_IN_ALL +gboolean gdk_wayland_toplevel_set_transient_for_exported (GdkToplevel *toplevel, + const char *parent_handle_str); + +GDK_AVAILABLE_IN_ALL +void gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel, + const char *application_id); + +void +gdk_wayland_surface_configure_toplevel (GdkSurface *surface); + +void +gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface); + +G_END_DECLS + +#endif /* __GDK_WAYLAND_TOPLEVEL_H__ */ diff --git a/gdk/wayland/meson.build b/gdk/wayland/meson.build index 28a00a959b6..5a30e5cd0d7 100644 --- a/gdk/wayland/meson.build +++ b/gdk/wayland/meson.build @@ -17,6 +17,7 @@ gdk_wayland_sources = files([ 'gdkvulkancontext-wayland.c', 'gdksurface-wayland.c', 'wm-button-layout-translation.c', + 'gdktoplevel-wayland.c', ]) gdk_wayland_public_headers = files([ -- GitLab From d35e0ef2e0b21f7c82db0c886d5d982844b79a6b Mon Sep 17 00:00:00 2001 From: David Keijser Date: Sun, 20 Dec 2020 23:26:38 +0100 Subject: [PATCH 03/36] wayland: Get rid of gdk_wayland_surface_create_xdg_toplevel use in gdksurface-wayland --- gdk/wayland/gdksurface-wayland.c | 33 --------------------------- gdk/wayland/gdktoplevel-wayland.c | 37 ++++++++++++++++++++++++++++++- gdk/wayland/gdkwaylandtoplevel.h | 3 --- 3 files changed, 36 insertions(+), 37 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index fe2e99500b1..110dfacbb27 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -2081,37 +2081,6 @@ find_grab_input_seat (GdkSurface *surface, return NULL; } -static gboolean -should_be_mapped (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - /* Don't map crazy temp that GTK uses for internal X11 shenanigans. */ - if (GDK_IS_DRAG_SURFACE (surface) && surface->x < 0 && surface->y < 0) - return FALSE; - - if (impl->is_drag_surface) - return FALSE; - - return TRUE; -} - -static void -gdk_wayland_surface_map_toplevel (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - if (!should_be_mapped (surface)) - return; - - if (impl->mapped) - return; - - gdk_wayland_surface_create_xdg_toplevel (surface); - - impl->mapped = TRUE; -} - void gdk_wayland_surface_show (GdkSurface *surface, gboolean already_mapped) @@ -2120,8 +2089,6 @@ gdk_wayland_surface_show (GdkSurface *surface, if (!impl->display_server.wl_surface) gdk_wayland_surface_create_surface (surface); - - gdk_wayland_surface_map_toplevel (surface); } static void diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index a138007d02c..21221c8c005 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -64,6 +64,9 @@ G_DEFINE_TYPE_WITH_CODE (GdkWaylandToplevel, gdk_wayland_toplevel, GDK_TYPE_WAYL static void maybe_set_gtk_surface_dbus_properties (GdkWaylandSurface *impl); static void maybe_set_gtk_surface_modal (GdkSurface *surface); +static void +gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface); + static gboolean is_realized_toplevel (GdkWaylandSurface *impl) { @@ -598,7 +601,7 @@ gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel, } } -void +static void gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); @@ -1723,6 +1726,37 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class) gdk_toplevel_install_properties (object_class, 1); } +static gboolean +should_be_mapped (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + /* Don't map crazy temp that GTK uses for internal X11 shenanigans. */ + if (GDK_IS_DRAG_SURFACE (surface) && surface->x < 0 && surface->y < 0) + return FALSE; + + if (impl->is_drag_surface) + return FALSE; + + return TRUE; +} + +static void +gdk_wayland_surface_map_toplevel (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + if (!should_be_mapped (surface)) + return; + + if (impl->mapped) + return; + + gdk_wayland_surface_create_xdg_toplevel (surface); + + impl->mapped = TRUE; +} + static void gdk_wayland_toplevel_present (GdkToplevel *toplevel, GdkToplevelLayout *layout) @@ -1765,6 +1799,7 @@ gdk_wayland_toplevel_present (GdkToplevel *toplevel, impl->toplevel.layout = gdk_toplevel_layout_copy (layout); gdk_wayland_surface_show (surface, FALSE); + gdk_wayland_surface_map_toplevel (surface); if (!pending_configure) { diff --git a/gdk/wayland/gdkwaylandtoplevel.h b/gdk/wayland/gdkwaylandtoplevel.h index 492dbcd6070..471d5efc3ef 100644 --- a/gdk/wayland/gdkwaylandtoplevel.h +++ b/gdk/wayland/gdkwaylandtoplevel.h @@ -65,9 +65,6 @@ void gdk_wayland_toplevel_set_application_id (GdkToplevel *t void gdk_wayland_surface_configure_toplevel (GdkSurface *surface); -void -gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface); - G_END_DECLS #endif /* __GDK_WAYLAND_TOPLEVEL_H__ */ -- GitLab From bfe841183dfabb2a0eb1c69dc4a9cf609cc93b1c Mon Sep 17 00:00:00 2001 From: David Keijser Date: Mon, 21 Dec 2020 01:12:30 +0100 Subject: [PATCH 04/36] wayland: Remove reference to gdk_wayland_surface_configure_toplevel in gdksurface-wayland --- gdk/wayland/gdksurface-wayland.c | 2 -- gdk/wayland/gdktoplevel-wayland.c | 4 +++- gdk/wayland/gdkwaylandtoplevel.h | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 110dfacbb27..6844ba165b4 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -1258,8 +1258,6 @@ gdk_wayland_surface_configure (GdkSurface *surface) if (is_realized_popup (impl)) gdk_wayland_surface_configure_popup (surface); - else if (is_realized_toplevel (impl)) - gdk_wayland_surface_configure_toplevel (surface); else g_warn_if_reached (); diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 21221c8c005..36cb3c4ce60 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -66,6 +66,8 @@ static void maybe_set_gtk_surface_modal (GdkSurface *surface); static void gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface); +static void +gdk_wayland_surface_configure_toplevel (GdkSurface *surface); static gboolean is_realized_toplevel (GdkWaylandSurface *impl) @@ -180,7 +182,7 @@ synthesize_initial_surface_state (GdkSurface *surface, impl->initial_state.unset_flags &= ~set_flags; } -void +static void gdk_wayland_surface_configure_toplevel (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); diff --git a/gdk/wayland/gdkwaylandtoplevel.h b/gdk/wayland/gdkwaylandtoplevel.h index 471d5efc3ef..0d0c6a353bb 100644 --- a/gdk/wayland/gdkwaylandtoplevel.h +++ b/gdk/wayland/gdkwaylandtoplevel.h @@ -62,9 +62,6 @@ GDK_AVAILABLE_IN_ALL void gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel, const char *application_id); -void -gdk_wayland_surface_configure_toplevel (GdkSurface *surface); - G_END_DECLS #endif /* __GDK_WAYLAND_TOPLEVEL_H__ */ -- GitLab From 8c0a62b6a8e83566024067cd305da9788d842ce0 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Mon, 21 Dec 2020 00:16:48 +0100 Subject: [PATCH 05/36] wayland: Move sync_geometry_hints to toplevel --- gdk/wayland/gdksurface-wayland.c | 31 +++++++++++------------------ gdk/wayland/gdksurface-wayland.h | 7 +++++++ gdk/wayland/gdktoplevel-wayland.c | 33 +++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 6844ba165b4..ea9bff89143 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -122,7 +122,6 @@ static void gdk_wayland_surface_maybe_resize (GdkSurface *surface, static void gdk_wayland_surface_configure (GdkSurface *surface); -static void gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface); static void gdk_wayland_surface_sync_shadow (GdkSurface *surface); static void gdk_wayland_surface_sync_input_region (GdkSurface *surface); static void gdk_wayland_surface_sync_opaque_region (GdkSurface *surface); @@ -716,15 +715,20 @@ gdk_wayland_surface_attach_image (GdkSurface *surface, } } -void -gdk_wayland_surface_sync (GdkSurface *surface) +static void +gdk_wayland_surface_sync_real (GdkSurface *surface) { - gdk_wayland_surface_sync_geometry_hints (surface); gdk_wayland_surface_sync_shadow (surface); gdk_wayland_surface_sync_opaque_region (surface); gdk_wayland_surface_sync_input_region (surface); } +void +gdk_wayland_surface_sync (GdkSurface *surface) +{ + GDK_WAYLAND_SURFACE_GET_CLASS(surface)->sync(surface); +} + static gboolean gdk_wayland_surface_beep (GdkSurface *surface) { @@ -884,7 +888,7 @@ gdk_wayland_surface_sync_title (GdkSurface *surface) } } -static void +void gdk_wayland_surface_get_window_geometry (GdkSurface *surface, GdkRectangle *geometry) { @@ -898,21 +902,6 @@ gdk_wayland_surface_get_window_geometry (GdkSurface *surface, }; } -static void -gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - GdkRectangle geometry; - - if (!is_realized_shell_surface (impl)) - return; - - gdk_wayland_surface_get_window_geometry (surface, &geometry); - gdk_wayland_surface_set_geometry_hints (impl, - &impl->geometry_hints, - impl->geometry_mask); -} - static void gdk_wayland_surface_sync_shadow (GdkSurface *surface) { @@ -2844,6 +2833,8 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass) impl_class->create_gl_context = gdk_wayland_surface_create_gl_context; impl_class->request_layout = gdk_wayland_surface_request_layout; impl_class->compute_size = gdk_wayland_surface_compute_size; + + klass->sync = gdk_wayland_surface_sync_real; } void diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 92f2b5d64d3..83e15f666da 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -197,8 +197,12 @@ typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass; struct _GdkWaylandSurfaceClass { GdkSurfaceClass parent_class; + void (*sync) (GdkSurface*); }; +#define GDK_WAYLAND_SURFACE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), GDK_TYPE_WAYLAND_SURFACE, GdkWaylandSurfaceClass)) +#define GDK_WAYLAND_SURFACE_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), GDK_TYPE_WAYLAND_SURFACE, GdkWaylandSurfaceClass)) + G_BEGIN_DECLS void gdk_wayland_toplevel_set_dbus_properties (GdkToplevel *toplevel, @@ -231,5 +235,8 @@ void unset_transient_for_exported (GdkSurface *surface); void gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, const GdkGeometry *geometry, GdkSurfaceHints geom_mask); +void +gdk_wayland_surface_get_window_geometry (GdkSurface *surface, + GdkRectangle *geometry); G_END_DECLS diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 36cb3c4ce60..f1e1bbd65e0 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -61,6 +61,7 @@ G_DEFINE_TYPE_WITH_CODE (GdkWaylandToplevel, gdk_wayland_toplevel, GDK_TYPE_WAYL G_IMPLEMENT_INTERFACE (GDK_TYPE_TOPLEVEL, gdk_wayland_toplevel_iface_init)) +static void gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface); static void maybe_set_gtk_surface_dbus_properties (GdkWaylandSurface *impl); static void maybe_set_gtk_surface_modal (GdkSurface *surface); @@ -69,6 +70,13 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface); static void gdk_wayland_surface_configure_toplevel (GdkSurface *surface); +static gboolean +is_realized_shell_surface (GdkWaylandSurface *impl) +{ + return (impl->display_server.xdg_surface || + impl->display_server.zxdg_surface_v6); +} + static gboolean is_realized_toplevel (GdkWaylandSurface *impl) { @@ -93,6 +101,13 @@ _gdk_wayland_surface_save_size (GdkSurface *surface) impl->saved_height = surface->height - impl->shadow_top - impl->shadow_bottom; } +static void +gdk_wayland_toplevel_sync (GdkSurface *surface) +{ + gdk_wayland_surface_sync_geometry_hints (surface); + GDK_WAYLAND_SURFACE_CLASS(gdk_wayland_toplevel_parent_class)->sync(surface); +} + static void gdk_wayland_surface_sync_parent (GdkSurface *surface, GdkSurface *parent) @@ -168,6 +183,21 @@ gdk_wayland_surface_sync_parent_of_imported (GdkWaylandSurface *impl) impl->display_server.wl_surface); } +static void +gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkRectangle geometry; + + if (!is_realized_shell_surface (impl)) + return; + + gdk_wayland_surface_get_window_geometry (surface, &geometry); + gdk_wayland_surface_set_geometry_hints (impl, + &impl->geometry_hints, + impl->geometry_mask); +} + static void synthesize_initial_surface_state (GdkSurface *surface, GdkToplevelState unset_flags, @@ -1721,10 +1751,13 @@ static void gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); + GdkWaylandSurfaceClass *wayland_surface_class = GDK_WAYLAND_SURFACE_CLASS (class); object_class->get_property = gdk_wayland_toplevel_get_property; object_class->set_property = gdk_wayland_toplevel_set_property; + wayland_surface_class->sync = gdk_wayland_toplevel_sync; + gdk_toplevel_install_properties (object_class, 1); } -- GitLab From 81a6ebddf181db0b7cef7863518f496afc976a36 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Mon, 21 Dec 2020 00:33:54 +0100 Subject: [PATCH 06/36] wayland: Move configure_toplevel_geometry to gdktoplevel-wayland * Remove redundant write to surface_geometry_dirty, setting surface_geometry_dirty to TRUE is already implied by gdk_surface_request_layout --- gdk/wayland/gdksurface-wayland.c | 109 ++++------------------------ gdk/wayland/gdksurface-wayland.h | 5 ++ gdk/wayland/gdktoplevel-wayland.c | 115 +++++++++++++++++++++++++++++- 3 files changed, 131 insertions(+), 98 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index ea9bff89143..03536fcdab1 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -141,8 +141,6 @@ static void update_popup_layout_state (GdkSurface *surface, static gboolean gdk_wayland_surface_is_exported (GdkWaylandSurface *impl); -static void configure_toplevel_geometry (GdkSurface *surface); - static void gdk_wayland_surface_init (GdkWaylandSurface *impl) { @@ -191,7 +189,7 @@ _gdk_wayland_surface_clear_saved_size (GdkSurface *surface) impl->saved_height = -1; } -static void +void gdk_wayland_surface_update_size (GdkSurface *surface, int32_t width, int32_t height, @@ -467,6 +465,17 @@ configure_drag_surface_geometry (GdkSurface *surface) impl->scale); } +static void +gdk_wayland_surface_configure_geometry (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + if (GDK_IS_POPUP (impl)) + configure_popup_geometry (surface); + else if (GDK_IS_DRAG_SURFACE (impl)) + configure_drag_surface_geometry (surface); +} + static gboolean gdk_wayland_surface_compute_size (GdkSurface *surface) { @@ -474,13 +483,7 @@ gdk_wayland_surface_compute_size (GdkSurface *surface) if (impl->next_layout.surface_geometry_dirty) { - if (GDK_IS_TOPLEVEL (impl)) - configure_toplevel_geometry (surface); - else if (GDK_IS_POPUP (impl)) - configure_popup_geometry (surface); - else if (GDK_IS_DRAG_SURFACE (impl)) - configure_drag_surface_geometry (surface); - + gdk_wayland_surface_configure_geometry (surface); impl->next_layout.surface_geometry_dirty = FALSE; } @@ -1073,92 +1076,6 @@ gdk_wayland_surface_create_surface (GdkSurface *surface) impl->display_server.wl_surface = wl_surface; } -static void -configure_toplevel_geometry (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - GdkDisplay *display = gdk_surface_get_display (surface); - GdkMonitor *monitor; - GdkRectangle monitor_geometry; - int bounds_width, bounds_height; - GdkToplevelSize size; - GdkToplevelLayout *layout; - GdkGeometry geometry; - GdkSurfaceHints mask; - - monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0); - gdk_monitor_get_geometry (monitor, &monitor_geometry); - g_object_unref (monitor); - bounds_width = monitor_geometry.width; - bounds_height = monitor_geometry.height; - - gdk_toplevel_size_init (&size, bounds_width, bounds_height); - gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size); - g_warn_if_fail (size.width > 0); - g_warn_if_fail (size.height > 0); - - layout = impl->toplevel.layout; - if (gdk_toplevel_layout_get_resizable (layout)) - { - geometry.min_width = size.min_width; - geometry.min_height = size.min_height; - mask = GDK_HINT_MIN_SIZE; - } - else - { - geometry.max_width = geometry.min_width = size.width; - geometry.max_height = geometry.min_height = size.height; - mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE; - } - gdk_wayland_surface_set_geometry_hints (impl, &geometry, mask); - - if (size.shadow.is_valid) - { - impl->shadow_left = size.shadow.left; - impl->shadow_right = size.shadow.right; - impl->shadow_top = size.shadow.top; - impl->shadow_bottom = size.shadow.bottom; - } - - if (impl->next_layout.configured_width > 0 && - impl->next_layout.configured_height > 0) - { - int width, height; - - width = impl->next_layout.configured_width + - impl->shadow_left + impl->shadow_right; - height = impl->next_layout.configured_height + - impl->shadow_top + impl->shadow_bottom; - - if (impl->next_layout.toplevel.should_constrain) - { - gdk_surface_constrain_size (&impl->geometry_hints, - impl->geometry_mask, - width, height, - &width, &height); - } - gdk_wayland_surface_update_size (surface, width, height, impl->scale); - - if (!impl->next_layout.toplevel.size_is_fixed) - { - impl->next_layout.toplevel.should_constrain = FALSE; - impl->next_layout.configured_width = 0; - impl->next_layout.configured_height = 0; - } - } - else - { - int width, height; - - width = size.width; - height = size.height; - gdk_surface_constrain_size (&geometry, mask, - width, height, - &width, &height); - gdk_wayland_surface_update_size (surface, width, height, impl->scale); - } -} - static void gdk_wayland_surface_configure_popup (GdkSurface *surface) { diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 83e15f666da..0459ad648a0 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -238,5 +238,10 @@ void gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, void gdk_wayland_surface_get_window_geometry (GdkSurface *surface, GdkRectangle *geometry); +void +gdk_wayland_surface_update_size (GdkSurface *surface, + int width, + int height, + int scale); G_END_DECLS diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index f1e1bbd65e0..d21bcb1d30a 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -198,6 +198,115 @@ gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface) impl->geometry_mask); } +static void +configure_toplevel_geometry (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkDisplay *display = gdk_surface_get_display (surface); + GdkMonitor *monitor; + GdkRectangle monitor_geometry; + int bounds_width, bounds_height; + GdkToplevelSize size; + GdkToplevelLayout *layout; + GdkGeometry geometry; + GdkSurfaceHints mask; + + monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0); + gdk_monitor_get_geometry (monitor, &monitor_geometry); + g_object_unref (monitor); + bounds_width = monitor_geometry.width; + bounds_height = monitor_geometry.height; + + gdk_toplevel_size_init (&size, bounds_width, bounds_height); + gdk_toplevel_notify_compute_size (GDK_TOPLEVEL (surface), &size); + g_warn_if_fail (size.width > 0); + g_warn_if_fail (size.height > 0); + + layout = impl->toplevel.layout; + if (gdk_toplevel_layout_get_resizable (layout)) + { + geometry.min_width = size.min_width; + geometry.min_height = size.min_height; + mask = GDK_HINT_MIN_SIZE; + } + else + { + geometry.max_width = geometry.min_width = size.width; + geometry.max_height = geometry.min_height = size.height; + mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE; + } + gdk_wayland_surface_set_geometry_hints (impl, &geometry, mask); + + if (size.shadow.is_valid) + { + impl->shadow_left = size.shadow.left; + impl->shadow_right = size.shadow.right; + impl->shadow_top = size.shadow.top; + impl->shadow_bottom = size.shadow.bottom; + } + + if (impl->next_layout.configured_width > 0 && + impl->next_layout.configured_height > 0) + { + int width, height; + + width = impl->next_layout.configured_width + + impl->shadow_left + impl->shadow_right; + height = impl->next_layout.configured_height + + impl->shadow_top + impl->shadow_bottom; + + if (impl->next_layout.toplevel.should_constrain) + { + gdk_surface_constrain_size (&impl->geometry_hints, + impl->geometry_mask, + width, height, + &width, &height); + } + gdk_wayland_surface_update_size (surface, width, height, impl->scale); + + if (!impl->next_layout.toplevel.size_is_fixed) + { + impl->next_layout.toplevel.should_constrain = FALSE; + impl->next_layout.configured_width = 0; + impl->next_layout.configured_height = 0; + } + } + else + { + int width, height; + + width = size.width; + height = size.height; + gdk_surface_constrain_size (&geometry, mask, + width, height, + &width, &height); + gdk_wayland_surface_update_size (surface, width, height, impl->scale); + } +} + + +static gboolean +gdk_wayland_toplevel_compute_size (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + if (impl->next_layout.surface_geometry_dirty) + { + configure_toplevel_geometry (surface); + impl->next_layout.surface_geometry_dirty = FALSE; + } + + return FALSE; +} + +static void +gdk_wayland_toplevel_request_layout (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + impl->next_layout.surface_geometry_dirty = TRUE; +} + static void synthesize_initial_surface_state (GdkSurface *surface, GdkToplevelState unset_flags, @@ -284,7 +393,6 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface) impl->next_layout.configured_height = 0; } - impl->next_layout.surface_geometry_dirty = TRUE; gdk_surface_request_layout (surface); GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS, @@ -1751,11 +1859,15 @@ static void gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); + GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (class); GdkWaylandSurfaceClass *wayland_surface_class = GDK_WAYLAND_SURFACE_CLASS (class); object_class->get_property = gdk_wayland_toplevel_get_property; object_class->set_property = gdk_wayland_toplevel_set_property; + surface_class->request_layout = gdk_wayland_toplevel_request_layout; + surface_class->compute_size = gdk_wayland_toplevel_compute_size; + wayland_surface_class->sync = gdk_wayland_toplevel_sync; gdk_toplevel_install_properties (object_class, 1); @@ -1838,7 +1950,6 @@ gdk_wayland_toplevel_present (GdkToplevel *toplevel, if (!pending_configure) { - impl->next_layout.surface_geometry_dirty = TRUE; gdk_surface_request_layout (surface); } } -- GitLab From 657ae677c3624b053c504b266026d00a12370922 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Mon, 21 Dec 2020 00:41:47 +0100 Subject: [PATCH 07/36] wayland: Move gdk_wayland_surface_set_geometry_hints to gdktoplevel-wayland --- gdk/wayland/gdksurface-wayland.c | 77 ----------------------------- gdk/wayland/gdksurface-wayland.h | 3 -- gdk/wayland/gdktoplevel-wayland.c | 81 +++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 80 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 03536fcdab1..eb728a47bea 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -2575,83 +2575,6 @@ gdk_wayland_surface_destroy (GdkSurface *surface, display->toplevels = g_list_remove (display->toplevels, surface); } -void -gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, - const GdkGeometry *geometry, - GdkSurfaceHints geom_mask) -{ - GdkWaylandDisplay *display_wayland; - int min_width, min_height; - int max_width, max_height; - - if (GDK_SURFACE_DESTROYED (impl) || - !SURFACE_IS_TOPLEVEL (impl)) - return; - - display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (impl))); - - impl->geometry_hints = *geometry; - impl->geometry_mask = geom_mask; - - if (!is_realized_toplevel (impl)) - return; - - if (geom_mask & GDK_HINT_MIN_SIZE) - { - min_width = MAX (0, (geometry->min_width - - (impl->shadow_left + impl->shadow_right))); - min_height = MAX (0, (geometry->min_height - - (impl->shadow_top + impl->shadow_bottom))); - } - else - { - min_width = 0; - min_height = 0; - } - - if (geom_mask & GDK_HINT_MAX_SIZE) - { - max_width = MAX (0, (geometry->max_width - - (impl->shadow_left + impl->shadow_right))); - max_height = MAX (0, (geometry->max_height - - (impl->shadow_top + impl->shadow_bottom))); - } - else - { - max_width = 0; - max_height = 0; - } - - if (impl->last_sent_min_width == min_width && - impl->last_sent_min_height == min_height && - impl->last_sent_max_width == max_width && - impl->last_sent_max_height == max_height) - return; - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_min_size (impl->display_server.xdg_toplevel, - min_width, min_height); - xdg_toplevel_set_max_size (impl->display_server.xdg_toplevel, - max_width, max_height); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_min_size (impl->display_server.zxdg_toplevel_v6, - min_width, min_height); - zxdg_toplevel_v6_set_max_size (impl->display_server.zxdg_toplevel_v6, - max_width, max_height); - break; - default: - g_assert_not_reached (); - } - - impl->last_sent_min_width = min_width; - impl->last_sent_min_height = min_height; - impl->last_sent_max_width = max_width; - impl->last_sent_max_height = max_height; -} - void gdk_wayland_surface_set_title (GdkSurface *surface, const char *title) diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 0459ad648a0..9852ba9cda7 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -232,9 +232,6 @@ gdk_wayland_surface_show (GdkSurface *surface, gboolean already_mapped); void unset_transient_for_exported (GdkSurface *surface); -void gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, - const GdkGeometry *geometry, - GdkSurfaceHints geom_mask); void gdk_wayland_surface_get_window_geometry (GdkSurface *surface, GdkRectangle *geometry); diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index d21bcb1d30a..ecf86c9fbf8 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -183,6 +183,10 @@ gdk_wayland_surface_sync_parent_of_imported (GdkWaylandSurface *impl) impl->display_server.wl_surface); } +static void gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, + const GdkGeometry *geometry, + GdkSurfaceHints geom_mask); + static void gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface) { @@ -1054,6 +1058,83 @@ gdk_wayland_surface_set_modal_hint (GdkSurface *surface, maybe_set_gtk_surface_modal (surface); } +static void +gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, + const GdkGeometry *geometry, + GdkSurfaceHints geom_mask) +{ + GdkWaylandDisplay *display_wayland; + int min_width, min_height; + int max_width, max_height; + + if (GDK_SURFACE_DESTROYED (impl) || + !SURFACE_IS_TOPLEVEL (impl)) + return; + + display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (impl))); + + impl->geometry_hints = *geometry; + impl->geometry_mask = geom_mask; + + if (!is_realized_toplevel (impl)) + return; + + if (geom_mask & GDK_HINT_MIN_SIZE) + { + min_width = MAX (0, (geometry->min_width - + (impl->shadow_left + impl->shadow_right))); + min_height = MAX (0, (geometry->min_height - + (impl->shadow_top + impl->shadow_bottom))); + } + else + { + min_width = 0; + min_height = 0; + } + + if (geom_mask & GDK_HINT_MAX_SIZE) + { + max_width = MAX (0, (geometry->max_width - + (impl->shadow_left + impl->shadow_right))); + max_height = MAX (0, (geometry->max_height - + (impl->shadow_top + impl->shadow_bottom))); + } + else + { + max_width = 0; + max_height = 0; + } + + if (impl->last_sent_min_width == min_width && + impl->last_sent_min_height == min_height && + impl->last_sent_max_width == max_width && + impl->last_sent_max_height == max_height) + return; + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_min_size (impl->display_server.xdg_toplevel, + min_width, min_height); + xdg_toplevel_set_max_size (impl->display_server.xdg_toplevel, + max_width, max_height); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_min_size (impl->display_server.zxdg_toplevel_v6, + min_width, min_height); + zxdg_toplevel_v6_set_max_size (impl->display_server.zxdg_toplevel_v6, + max_width, max_height); + break; + default: + g_assert_not_reached (); + } + + impl->last_sent_min_width = min_width; + impl->last_sent_min_height = min_height; + impl->last_sent_max_width = max_width; + impl->last_sent_max_height = max_height; +} + static void gdk_wayland_surface_set_startup_id (GdkSurface *surface, const char *startup_id) -- GitLab From aaa94718f703fcdc37d08ca36cd8056c70159250 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Mon, 21 Dec 2020 01:30:19 +0100 Subject: [PATCH 08/36] wayland: Move toplevel specifics of gdk_wayland_surface_hide_surface to gdktoplevel-wayland --- gdk/wayland/gdksurface-wayland.c | 16 +++------------- gdk/wayland/gdktoplevel-wayland.c | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index eb728a47bea..9fb82080481 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -2050,12 +2050,7 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) impl->display_server.egl_window = NULL; } - if (impl->display_server.xdg_toplevel) - { - xdg_toplevel_destroy (impl->display_server.xdg_toplevel); - impl->display_server.xdg_toplevel = NULL; - } - else if (impl->display_server.xdg_popup) + if (impl->display_server.xdg_popup) { xdg_popup_destroy (impl->display_server.xdg_popup); impl->display_server.xdg_popup = NULL; @@ -2074,12 +2069,7 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) impl->initial_configure_received = FALSE; } - if (impl->display_server.zxdg_toplevel_v6) - { - zxdg_toplevel_v6_destroy (impl->display_server.zxdg_toplevel_v6); - impl->display_server.zxdg_toplevel_v6 = NULL; - } - else if (impl->display_server.zxdg_popup_v6) + if (impl->display_server.zxdg_popup_v6) { zxdg_popup_v6_destroy (impl->display_server.zxdg_popup_v6); impl->display_server.zxdg_popup_v6 = NULL; @@ -2565,7 +2555,7 @@ gdk_wayland_surface_destroy (GdkSurface *surface, */ g_return_if_fail (!foreign_destroy); - gdk_wayland_surface_hide_surface (surface); + gdk_surface_hide (surface); frame_clock = gdk_surface_get_frame_clock (surface); g_signal_handlers_disconnect_by_func (frame_clock, on_frame_clock_before_paint, surface); diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index ecf86c9fbf8..ebff5da36ea 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -69,6 +69,8 @@ static void gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface); static void gdk_wayland_surface_configure_toplevel (GdkSurface *surface); +static void +gdk_wayland_toplevel_hide (GdkSurface *surface); static gboolean is_realized_shell_surface (GdkWaylandSurface *impl) @@ -1948,6 +1950,7 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class) surface_class->request_layout = gdk_wayland_toplevel_request_layout; surface_class->compute_size = gdk_wayland_toplevel_compute_size; + surface_class->hide = gdk_wayland_toplevel_hide; wayland_surface_class->sync = gdk_wayland_toplevel_sync; @@ -1985,6 +1988,24 @@ gdk_wayland_surface_map_toplevel (GdkSurface *surface) impl->mapped = TRUE; } +static void +gdk_wayland_toplevel_hide (GdkSurface *surface) { + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + GDK_SURFACE_CLASS (gdk_wayland_toplevel_parent_class)->hide (surface); + + if (impl->display_server.xdg_toplevel) + { + xdg_toplevel_destroy (impl->display_server.xdg_toplevel); + impl->display_server.xdg_toplevel = NULL; + } + if (impl->display_server.zxdg_toplevel_v6) + { + zxdg_toplevel_v6_destroy (impl->display_server.zxdg_toplevel_v6); + impl->display_server.zxdg_toplevel_v6 = NULL; + } +} + static void gdk_wayland_toplevel_present (GdkToplevel *toplevel, GdkToplevelLayout *layout) -- GitLab From b5d5da54c57c67126ea4470034074ab174dbdf68 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Mon, 21 Dec 2020 01:03:14 +0100 Subject: [PATCH 09/36] wayland: Move gdk_wayland_toplevel_set_title impl to gdktoplevel-wayland Also move the title property to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.c | 85 ------------------------ gdk/wayland/gdksurface-wayland.h | 7 -- gdk/wayland/gdktoplevel-wayland.c | 103 +++++++++++++++++++++++++++++- 3 files changed, 101 insertions(+), 94 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 9fb82080481..2fdfd2fe087 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -72,8 +72,6 @@ #define SURFACE_IS_TOPLEVEL(surface) TRUE -#define MAX_WL_BUFFER_SIZE (4083) /* 4096 minus header, string argument length and NUL byte */ - G_DEFINE_TYPE (GdkWaylandSurface, gdk_wayland_surface, GDK_TYPE_SURFACE) @@ -226,20 +224,6 @@ gdk_wayland_surface_update_size (GdkSurface *surface, _gdk_surface_update_size (surface); } -static const char * -get_default_title (void) -{ - const char *title; - - title = g_get_application_name (); - if (!title) - title = g_get_prgname (); - if (!title) - title = ""; - - return title; -} - static void fill_presentation_time_from_frame_time (GdkFrameTimings *timings, guint32 frame_time) @@ -669,9 +653,6 @@ _gdk_wayland_display_create_surface (GdkDisplay *display, } } - gdk_wayland_surface_set_title (surface, get_default_title ()); - - gdk_wayland_surface_create_surface (surface); g_signal_connect (frame_clock, "before-paint", G_CALLBACK (on_frame_clock_before_paint), surface); @@ -791,8 +772,6 @@ gdk_wayland_surface_finalize (GObject *object) if (gdk_wayland_surface_is_exported (impl)) gdk_wayland_toplevel_unexport_handle (GDK_TOPLEVEL (impl)); - g_free (impl->title); - g_free (impl->application.application_id); g_free (impl->application.app_menu_path); g_free (impl->application.menubar_path); @@ -863,34 +842,6 @@ gdk_wayland_surface_maybe_resize (GdkSurface *surface, gdk_wayland_surface_show (surface, FALSE); } -void -gdk_wayland_surface_sync_title (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - GdkWaylandDisplay *display_wayland = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - - if (!is_realized_toplevel (impl)) - return; - - if (!impl->title) - return; - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_title (impl->display_server.xdg_toplevel, - impl->title); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_title (impl->display_server.zxdg_toplevel_v6, - impl->title); - break; - default: - g_assert_not_reached (); - } -} - void gdk_wayland_surface_get_window_geometry (GdkSurface *surface, GdkRectangle *geometry) @@ -2565,42 +2516,6 @@ gdk_wayland_surface_destroy (GdkSurface *surface, display->toplevels = g_list_remove (display->toplevels, surface); } -void -gdk_wayland_surface_set_title (GdkSurface *surface, - const char *title) -{ - GdkWaylandSurface *impl; - const char *end; - gsize title_length; - - g_return_if_fail (title != NULL); - - if (GDK_SURFACE_DESTROYED (surface)) - return; - - impl = GDK_WAYLAND_SURFACE (surface); - - if (g_strcmp0 (impl->title, title) == 0) - return; - - g_free (impl->title); - - title_length = MIN (strlen (title), MAX_WL_BUFFER_SIZE); - if (g_utf8_validate (title, title_length, &end)) - { - impl->title = g_malloc (end - title + 1); - memcpy (impl->title, title, end - title); - impl->title[end - title] = '\0'; - } - else - { - impl->title = g_utf8_make_valid (title, title_length); - g_warning ("Invalid utf8 passed to gdk_surface_set_title: '%s'", title); - } - - gdk_wayland_surface_sync_title (surface); -} - static void gdk_wayland_surface_destroy_notify (GdkSurface *surface) { diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 9852ba9cda7..f79d582d7fa 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -78,8 +78,6 @@ struct _GdkWaylandSurface int pending_buffer_offset_x; int pending_buffer_offset_y; - char *title; - struct { gboolean was_set; @@ -219,11 +217,6 @@ void gdk_wayland_toplevel_announce_ssd (GdkTopl gboolean gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel); void gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel); -void gdk_wayland_surface_set_title (GdkSurface *surface, - const char *title); -void -gdk_wayland_surface_sync_title (GdkSurface *surface); - struct zwp_keyboard_shortcuts_inhibitor_v1 * gdk_wayland_surface_get_inhibitor (GdkWaylandSurface *impl, GdkSeat *gdk_seat); diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index ebff5da36ea..3538796b39a 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -43,6 +43,8 @@ #define SURFACE_IS_TOPLEVEL(surface) TRUE +#define MAX_WL_BUFFER_SIZE (4083) /* 4096 minus header, string argument length and NUL byte */ + typedef struct { GdkWaylandSurfaceClass parent_class; @@ -53,6 +55,8 @@ struct _GdkWaylandToplevel GdkWaylandSurface parent_instance; GdkWaylandToplevel *transient_for; + + char *title; }; static void gdk_wayland_toplevel_iface_init (GdkToplevelInterface *iface); @@ -103,6 +107,21 @@ _gdk_wayland_surface_save_size (GdkSurface *surface) impl->saved_height = surface->height - impl->shadow_top - impl->shadow_bottom; } +static const char * +get_default_title (void) +{ + const char *title; + + title = g_get_application_name (); + if (!title) + title = g_get_prgname (); + if (!title) + title = ""; + + return title; +} + + static void gdk_wayland_toplevel_sync (GdkSurface *surface) { @@ -110,6 +129,19 @@ gdk_wayland_toplevel_sync (GdkSurface *surface) GDK_WAYLAND_SURFACE_CLASS(gdk_wayland_toplevel_parent_class)->sync(surface); } +static void +gdk_wayland_toplevel_finalize (GObject *object) +{ + GdkWaylandToplevel *impl; + + g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (object)); + + impl = GDK_WAYLAND_TOPLEVEL (object); + + g_free (impl->title); + G_OBJECT_CLASS(gdk_wayland_toplevel_parent_class)->finalize (object); +} + static void gdk_wayland_surface_sync_parent (GdkSurface *surface, GdkSurface *parent) @@ -185,6 +217,35 @@ gdk_wayland_surface_sync_parent_of_imported (GdkWaylandSurface *impl) impl->display_server.wl_surface); } +static void +gdk_wayland_surface_sync_title (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + + if (!is_realized_toplevel (impl)) + return; + + if (!GDK_WAYLAND_TOPLEVEL (impl)->title) + return; + + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_toplevel_set_title (impl->display_server.xdg_toplevel, + GDK_WAYLAND_TOPLEVEL (impl)->title); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_toplevel_v6_set_title (impl->display_server.zxdg_toplevel_v6, + GDK_WAYLAND_TOPLEVEL (impl)->title); + break; + default: + g_assert_not_reached (); + } +} + + static void gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, const GdkGeometry *geometry, GdkSurfaceHints geom_mask); @@ -1137,6 +1198,42 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, impl->last_sent_max_height = max_height; } +static void +gdk_wayland_toplevel_set_title (GdkSurface *surface, + const char *title) +{ + GdkWaylandToplevel *impl; + const char *end; + gsize title_length; + + g_return_if_fail (title != NULL); + + if (GDK_SURFACE_DESTROYED (surface)) + return; + + impl = GDK_WAYLAND_TOPLEVEL (surface); + + if (g_strcmp0 (impl->title, title) == 0) + return; + + g_free (impl->title); + + title_length = MIN (strlen (title), MAX_WL_BUFFER_SIZE); + if (g_utf8_validate (title, title_length, &end)) + { + impl->title = g_malloc (end - title + 1); + memcpy (impl->title, title, end - title); + impl->title[end - title] = '\0'; + } + else + { + impl->title = g_utf8_make_valid (title, title_length); + g_warning ("Invalid utf8 passed to gdk_surface_set_title: '%s'", title); + } + + gdk_wayland_surface_sync_title (surface); +} + static void gdk_wayland_surface_set_startup_id (GdkSurface *surface, const char *startup_id) @@ -1823,6 +1920,7 @@ gdk_wayland_toplevel_set_transient_for_exported (GdkToplevel *toplevel, static void gdk_wayland_toplevel_init (GdkWaylandToplevel *toplevel) { + gdk_wayland_toplevel_set_title (GDK_SURFACE (toplevel), get_default_title ()); } #define LAST_PROP 1 @@ -1839,7 +1937,7 @@ gdk_wayland_toplevel_set_property (GObject *object, switch (prop_id) { case LAST_PROP + GDK_TOPLEVEL_PROP_TITLE: - gdk_wayland_surface_set_title (surface, g_value_get_string (value)); + gdk_wayland_toplevel_set_title (surface, g_value_get_string (value)); g_object_notify_by_pspec (G_OBJECT (surface), pspec); break; @@ -1899,7 +1997,7 @@ gdk_wayland_toplevel_get_property (GObject *object, break; case LAST_PROP + GDK_TOPLEVEL_PROP_TITLE: - g_value_set_string (value, impl->title); + g_value_set_string (value, GDK_WAYLAND_TOPLEVEL(impl)->title); break; case LAST_PROP + GDK_TOPLEVEL_PROP_STARTUP_ID: @@ -1947,6 +2045,7 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class) object_class->get_property = gdk_wayland_toplevel_get_property; object_class->set_property = gdk_wayland_toplevel_set_property; + object_class->finalize = gdk_wayland_toplevel_finalize; surface_class->request_layout = gdk_wayland_toplevel_request_layout; surface_class->compute_size = gdk_wayland_toplevel_compute_size; -- GitLab From 6e2f12d9da9f27d37e6539405a57536cfc00d292 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Mon, 21 Dec 2020 01:32:53 +0100 Subject: [PATCH 10/36] wayland: Remove final use of is_realized_toplevel from gdksurface-wayland --- gdk/wayland/gdksurface-wayland.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 2fdfd2fe087..a04c15100b0 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -793,12 +793,6 @@ is_realized_shell_surface (GdkWaylandSurface *impl) impl->display_server.zxdg_surface_v6); } -static gboolean -is_realized_toplevel (GdkWaylandSurface *impl) -{ - return (impl->display_server.xdg_toplevel || - impl->display_server.zxdg_toplevel_v6); -} static gboolean is_realized_popup (GdkWaylandSurface *impl) @@ -1813,11 +1807,6 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, if (!is_realized_shell_surface (parent_impl)) return FALSE; - if (is_realized_toplevel (impl)) - { - g_warning ("Can't map popup, already mapped as toplevel"); - return FALSE; - } if (is_realized_popup (impl)) { g_warning ("Can't map popup, already mapped"); -- GitLab From 254cf40ae3c91c6eef3ad36b7d20bda8cae54b26 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Mon, 21 Dec 2020 02:00:00 +0100 Subject: [PATCH 11/36] wayland: Move *_toplevel structs to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.h | 2 - gdk/wayland/gdktoplevel-wayland.c | 224 +++++++++++++++--------------- 2 files changed, 114 insertions(+), 112 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index f79d582d7fa..13a9a4ef65a 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -43,12 +43,10 @@ struct _GdkWaylandSurface struct wl_surface *wl_surface; struct xdg_surface *xdg_surface; - struct xdg_toplevel *xdg_toplevel; struct xdg_popup *xdg_popup; /* Legacy xdg-shell unstable v6 fallback support */ struct zxdg_surface_v6 *zxdg_surface_v6; - struct zxdg_toplevel_v6 *zxdg_toplevel_v6; struct zxdg_popup_v6 *zxdg_popup_v6; struct gtk_surface1 *gtk_surface; diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 3538796b39a..5a101d5e34e 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -56,6 +56,9 @@ struct _GdkWaylandToplevel GdkWaylandToplevel *transient_for; + struct xdg_toplevel *xdg_toplevel; + struct zxdg_toplevel_v6 *zxdg_toplevel_v6; + char *title; }; @@ -84,10 +87,10 @@ is_realized_shell_surface (GdkWaylandSurface *impl) } static gboolean -is_realized_toplevel (GdkWaylandSurface *impl) +is_realized_toplevel (GdkWaylandToplevel *impl) { - return (impl->display_server.xdg_toplevel || - impl->display_server.zxdg_toplevel_v6); + return (impl->xdg_toplevel || + impl->zxdg_toplevel_v6); } static void @@ -146,11 +149,10 @@ static void gdk_wayland_surface_sync_parent (GdkSurface *surface, GdkSurface *parent) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - GdkWaylandToplevel *toplevel = GDK_WAYLAND_TOPLEVEL (impl); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - GdkWaylandSurface *impl_parent = NULL; + GdkWaylandToplevel *impl_parent = NULL; g_assert (parent == NULL || gdk_surface_get_display (surface) == gdk_surface_get_display (parent)); @@ -158,13 +160,13 @@ gdk_wayland_surface_sync_parent (GdkSurface *surface, if (!is_realized_toplevel (impl)) return; - if (toplevel->transient_for) - impl_parent = GDK_WAYLAND_SURFACE (toplevel->transient_for); + if (impl->transient_for) + impl_parent = GDK_WAYLAND_TOPLEVEL (impl->transient_for); else if (parent) - impl_parent = GDK_WAYLAND_SURFACE (parent); + impl_parent = GDK_WAYLAND_TOPLEVEL (parent); /* XXX: Is this correct? */ - if (impl_parent && !impl_parent->display_server.wl_surface) + if (impl_parent && !GDK_WAYLAND_SURFACE(impl_parent)->display_server.wl_surface) return; switch (display_wayland->shell_variant) @@ -174,11 +176,11 @@ gdk_wayland_surface_sync_parent (GdkSurface *surface, struct xdg_toplevel *parent_toplevel; if (impl_parent) - parent_toplevel = impl_parent->display_server.xdg_toplevel; + parent_toplevel = impl_parent->xdg_toplevel; else parent_toplevel = NULL; - xdg_toplevel_set_parent (impl->display_server.xdg_toplevel, + xdg_toplevel_set_parent (impl->xdg_toplevel, parent_toplevel); break; } @@ -188,11 +190,11 @@ gdk_wayland_surface_sync_parent (GdkSurface *surface, struct zxdg_toplevel_v6 *parent_toplevel; if (impl_parent) - parent_toplevel = impl_parent->display_server.zxdg_toplevel_v6; + parent_toplevel = impl_parent->zxdg_toplevel_v6; else parent_toplevel = NULL; - zxdg_toplevel_v6_set_parent (impl->display_server.zxdg_toplevel_v6, + zxdg_toplevel_v6_set_parent (impl->zxdg_toplevel_v6, parent_toplevel); break; } @@ -210,7 +212,7 @@ gdk_wayland_surface_sync_parent_of_imported (GdkWaylandSurface *impl) if (!impl->imported_transient_for) return; - if (!is_realized_toplevel (impl)) + if (!is_realized_toplevel (GDK_WAYLAND_TOPLEVEL(impl))) return; zxdg_imported_v1_set_parent_of (impl->imported_transient_for, @@ -220,25 +222,25 @@ gdk_wayland_surface_sync_parent_of_imported (GdkWaylandSurface *impl) static void gdk_wayland_surface_sync_title (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); if (!is_realized_toplevel (impl)) return; - if (!GDK_WAYLAND_TOPLEVEL (impl)->title) + if (!impl->title) return; switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_title (impl->display_server.xdg_toplevel, - GDK_WAYLAND_TOPLEVEL (impl)->title); + xdg_toplevel_set_title (impl->xdg_toplevel, + impl->title); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_title (impl->display_server.zxdg_toplevel_v6, - GDK_WAYLAND_TOPLEVEL (impl)->title); + zxdg_toplevel_v6_set_title (impl->zxdg_toplevel_v6, + impl->title); break; default: g_assert_not_reached (); @@ -543,7 +545,7 @@ gdk_wayland_surface_configure (GdkSurface *surface) impl->has_uncommitted_ack_configure = TRUE; - if (is_realized_toplevel (impl)) + if (is_realized_toplevel (GDK_WAYLAND_TOPLEVEL(impl))) gdk_wayland_surface_configure_toplevel (surface); else g_warn_if_reached (); @@ -690,9 +692,9 @@ create_xdg_toplevel_resources (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - impl->display_server.xdg_toplevel = + GDK_WAYLAND_TOPLEVEL(impl)->xdg_toplevel = xdg_surface_get_toplevel (impl->display_server.xdg_surface); - xdg_toplevel_add_listener (impl->display_server.xdg_toplevel, + xdg_toplevel_add_listener (GDK_WAYLAND_TOPLEVEL(impl)->xdg_toplevel, &xdg_toplevel_listener, surface); } @@ -758,9 +760,9 @@ create_zxdg_toplevel_v6_resources (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - impl->display_server.zxdg_toplevel_v6 = + GDK_WAYLAND_TOPLEVEL(impl)->zxdg_toplevel_v6 = zxdg_surface_v6_get_toplevel (impl->display_server.zxdg_surface_v6); - zxdg_toplevel_v6_add_listener (impl->display_server.zxdg_toplevel_v6, + zxdg_toplevel_v6_add_listener (GDK_WAYLAND_TOPLEVEL(impl)->zxdg_toplevel_v6, &zxdg_toplevel_v6_listener, surface); } @@ -776,7 +778,7 @@ void gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel, const char *application_id) { - GdkWaylandSurface *impl; + GdkWaylandToplevel *impl; GdkWaylandDisplay *display_wayland; g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); @@ -786,7 +788,7 @@ gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel, if (GDK_SURFACE_DESTROYED (toplevel)) return; - impl = GDK_WAYLAND_SURFACE (toplevel); + impl = GDK_WAYLAND_TOPLEVEL (toplevel); if (!is_realized_toplevel (impl)) return; @@ -796,11 +798,11 @@ gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel, switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_app_id (impl->display_server.xdg_toplevel, + xdg_toplevel_set_app_id (impl->xdg_toplevel, application_id); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_app_id (impl->display_server.zxdg_toplevel_v6, + zxdg_toplevel_v6_set_app_id (impl->zxdg_toplevel_v6, application_id); break; default: @@ -812,7 +814,8 @@ static void gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); + GdkWaylandSurface *wlsurface = GDK_WAYLAND_SURFACE (surface); const char *app_id; gdk_surface_freeze_updates (surface); @@ -831,36 +834,36 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) } gdk_wayland_surface_sync_parent (surface, NULL); - gdk_wayland_surface_sync_parent_of_imported (impl); + gdk_wayland_surface_sync_parent_of_imported (wlsurface); gdk_wayland_surface_sync_title (surface); switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED) - xdg_toplevel_set_maximized (impl->display_server.xdg_toplevel); - if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED) - xdg_toplevel_set_minimized (impl->display_server.xdg_toplevel); - if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) - xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, - impl->initial_fullscreen_output); + if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED) + xdg_toplevel_set_maximized (impl->xdg_toplevel); + if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED) + xdg_toplevel_set_minimized (impl->xdg_toplevel); + if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) + xdg_toplevel_set_fullscreen (impl->xdg_toplevel, + wlsurface->initial_fullscreen_output); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED) - zxdg_toplevel_v6_set_maximized (impl->display_server.zxdg_toplevel_v6); - if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED) - zxdg_toplevel_v6_set_minimized (impl->display_server.zxdg_toplevel_v6); - if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) - zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, - impl->initial_fullscreen_output); + if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED) + zxdg_toplevel_v6_set_maximized (impl->zxdg_toplevel_v6); + if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED) + zxdg_toplevel_v6_set_minimized (impl->zxdg_toplevel_v6); + if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) + zxdg_toplevel_v6_set_fullscreen (impl->zxdg_toplevel_v6, + wlsurface->initial_fullscreen_output); break; default: g_assert_not_reached (); } - impl->initial_fullscreen_output = NULL; + wlsurface->initial_fullscreen_output = NULL; - app_id = impl->application.application_id; + app_id = wlsurface->application.application_id; if (app_id == NULL) app_id = g_get_prgname (); @@ -869,11 +872,11 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) gdk_wayland_toplevel_set_application_id (GDK_TOPLEVEL (impl), app_id); - maybe_set_gtk_surface_dbus_properties (impl); + maybe_set_gtk_surface_dbus_properties (wlsurface); maybe_set_gtk_surface_modal (surface); gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit"); - wl_surface_commit (impl->display_server.wl_surface); + wl_surface_commit (wlsurface->display_server.wl_surface); } void @@ -1079,7 +1082,7 @@ gdk_wayland_surface_init_gtk_surface (GdkWaylandSurface *impl) if (impl->display_server.gtk_surface != NULL) return; - if (!is_realized_toplevel (impl)) + if (!is_realized_toplevel (GDK_WAYLAND_TOPLEVEL(impl))) return; if (display->gtk_shell == NULL) return; @@ -1122,10 +1125,11 @@ gdk_wayland_surface_set_modal_hint (GdkSurface *surface, } static void -gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, +gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *surface, const GdkGeometry *geometry, GdkSurfaceHints geom_mask) { + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL(surface); GdkWaylandDisplay *display_wayland; int min_width, min_height; int max_width, max_height; @@ -1136,8 +1140,8 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (impl))); - impl->geometry_hints = *geometry; - impl->geometry_mask = geom_mask; + surface->geometry_hints = *geometry; + surface->geometry_mask = geom_mask; if (!is_realized_toplevel (impl)) return; @@ -1145,9 +1149,9 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, if (geom_mask & GDK_HINT_MIN_SIZE) { min_width = MAX (0, (geometry->min_width - - (impl->shadow_left + impl->shadow_right))); + (surface->shadow_left + surface->shadow_right))); min_height = MAX (0, (geometry->min_height - - (impl->shadow_top + impl->shadow_bottom))); + (surface->shadow_top + surface->shadow_bottom))); } else { @@ -1158,9 +1162,9 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, if (geom_mask & GDK_HINT_MAX_SIZE) { max_width = MAX (0, (geometry->max_width - - (impl->shadow_left + impl->shadow_right))); + (surface->shadow_left + surface->shadow_right))); max_height = MAX (0, (geometry->max_height - - (impl->shadow_top + impl->shadow_bottom))); + (surface->shadow_top + surface->shadow_bottom))); } else { @@ -1168,34 +1172,34 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, max_height = 0; } - if (impl->last_sent_min_width == min_width && - impl->last_sent_min_height == min_height && - impl->last_sent_max_width == max_width && - impl->last_sent_max_height == max_height) + if (surface->last_sent_min_width == min_width && + surface->last_sent_min_height == min_height && + surface->last_sent_max_width == max_width && + surface->last_sent_max_height == max_height) return; switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_min_size (impl->display_server.xdg_toplevel, + xdg_toplevel_set_min_size (impl->xdg_toplevel, min_width, min_height); - xdg_toplevel_set_max_size (impl->display_server.xdg_toplevel, + xdg_toplevel_set_max_size (impl->xdg_toplevel, max_width, max_height); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_min_size (impl->display_server.zxdg_toplevel_v6, + zxdg_toplevel_v6_set_min_size (impl->zxdg_toplevel_v6, min_width, min_height); - zxdg_toplevel_v6_set_max_size (impl->display_server.zxdg_toplevel_v6, + zxdg_toplevel_v6_set_max_size (impl->zxdg_toplevel_v6, max_width, max_height); break; default: g_assert_not_reached (); } - impl->last_sent_min_width = min_width; - impl->last_sent_min_height = min_height; - impl->last_sent_max_width = max_width; - impl->last_sent_max_height = max_height; + surface->last_sent_min_width = min_width; + surface->last_sent_min_height = min_height; + surface->last_sent_max_width = max_width; + surface->last_sent_max_height = max_height; } static void @@ -1286,14 +1290,14 @@ gdk_wayland_toplevel_set_transient_for (GdkWaylandToplevel *toplevel, static void gdk_wayland_surface_minimize (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); GdkWaylandDisplay *display_wayland; if (GDK_SURFACE_DESTROYED (surface) || !SURFACE_IS_TOPLEVEL (surface)) return; - if (!is_realized_toplevel (GDK_WAYLAND_SURFACE (surface))) + if (!is_realized_toplevel (impl)) return; /* FIXME: xdg_toplevel does not come with a minimized state that we can @@ -1304,10 +1308,10 @@ gdk_wayland_surface_minimize (GdkSurface *surface) switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_minimized (impl->display_server.xdg_toplevel); + xdg_toplevel_set_minimized (impl->xdg_toplevel); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_minimized (impl->display_server.zxdg_toplevel_v6); + zxdg_toplevel_v6_set_minimized (impl->zxdg_toplevel_v6); break; default: g_assert_not_reached (); @@ -1317,7 +1321,7 @@ gdk_wayland_surface_minimize (GdkSurface *surface) static void gdk_wayland_surface_maximize (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); if (GDK_SURFACE_DESTROYED (surface)) return; @@ -1332,10 +1336,10 @@ gdk_wayland_surface_maximize (GdkSurface *surface) switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_maximized (impl->display_server.xdg_toplevel); + xdg_toplevel_set_maximized (impl->xdg_toplevel); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_maximized (impl->display_server.zxdg_toplevel_v6); + zxdg_toplevel_v6_set_maximized (impl->zxdg_toplevel_v6); break; default: g_assert_not_reached (); @@ -1350,7 +1354,7 @@ gdk_wayland_surface_maximize (GdkSurface *surface) static void gdk_wayland_surface_unmaximize (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); if (GDK_SURFACE_DESTROYED (surface)) return; @@ -1363,10 +1367,10 @@ gdk_wayland_surface_unmaximize (GdkSurface *surface) switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_unset_maximized (impl->display_server.xdg_toplevel); + xdg_toplevel_unset_maximized (impl->xdg_toplevel); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_unset_maximized (impl->display_server.zxdg_toplevel_v6); + zxdg_toplevel_v6_unset_maximized (impl->zxdg_toplevel_v6); break; default: g_assert_not_reached (); @@ -1382,7 +1386,7 @@ static void gdk_wayland_surface_fullscreen_on_monitor (GdkSurface *surface, GdkMonitor *monitor) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); struct wl_output *output = ((GdkWaylandMonitor *)monitor)->output; if (GDK_SURFACE_DESTROYED (surface)) @@ -1398,11 +1402,11 @@ gdk_wayland_surface_fullscreen_on_monitor (GdkSurface *surface, switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, + xdg_toplevel_set_fullscreen (impl->xdg_toplevel, output); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, + zxdg_toplevel_v6_set_fullscreen (impl->zxdg_toplevel_v6, output); break; default: @@ -1412,19 +1416,19 @@ gdk_wayland_surface_fullscreen_on_monitor (GdkSurface *surface, else { synthesize_initial_surface_state (surface, 0, GDK_TOPLEVEL_STATE_FULLSCREEN); - impl->initial_fullscreen_output = output; + GDK_WAYLAND_SURFACE(impl)->initial_fullscreen_output = output; } } static void gdk_wayland_surface_fullscreen (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); if (GDK_SURFACE_DESTROYED (surface)) return; - impl->initial_fullscreen_output = NULL; + GDK_WAYLAND_SURFACE(impl)->initial_fullscreen_output = NULL; _gdk_wayland_surface_save_size (surface); @@ -1436,11 +1440,11 @@ gdk_wayland_surface_fullscreen (GdkSurface *surface) switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_set_fullscreen (impl->display_server.xdg_toplevel, + xdg_toplevel_set_fullscreen (impl->xdg_toplevel, NULL); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_set_fullscreen (impl->display_server.zxdg_toplevel_v6, + zxdg_toplevel_v6_set_fullscreen (impl->zxdg_toplevel_v6, NULL); break; default: @@ -1456,12 +1460,12 @@ gdk_wayland_surface_fullscreen (GdkSurface *surface) static void gdk_wayland_surface_unfullscreen (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); if (GDK_SURFACE_DESTROYED (surface)) return; - impl->initial_fullscreen_output = NULL; + GDK_WAYLAND_SURFACE(impl)->initial_fullscreen_output = NULL; if (is_realized_toplevel (impl)) { @@ -1471,10 +1475,10 @@ gdk_wayland_surface_unfullscreen (GdkSurface *surface) switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_unset_fullscreen (impl->display_server.xdg_toplevel); + xdg_toplevel_unset_fullscreen (impl->xdg_toplevel); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_unset_fullscreen (impl->display_server.zxdg_toplevel_v6); + zxdg_toplevel_v6_unset_fullscreen (impl->zxdg_toplevel_v6); break; default: g_assert_not_reached (); @@ -1496,7 +1500,7 @@ gdk_wayland_toplevel_begin_resize (GdkToplevel *toplevel, guint32 timestamp) { GdkSurface *surface = GDK_SURFACE (toplevel); - GdkWaylandSurface *impl; + GdkWaylandToplevel *impl; GdkWaylandDisplay *display_wayland; GdkEventSequence *sequence; uint32_t resize_edges, serial; @@ -1544,7 +1548,7 @@ gdk_wayland_toplevel_begin_resize (GdkToplevel *toplevel, return; } - impl = GDK_WAYLAND_SURFACE (surface); + impl = GDK_WAYLAND_TOPLEVEL (surface); display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); if (!is_realized_toplevel (impl)) @@ -1556,12 +1560,12 @@ gdk_wayland_toplevel_begin_resize (GdkToplevel *toplevel, switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_resize (impl->display_server.xdg_toplevel, + xdg_toplevel_resize (impl->xdg_toplevel, gdk_wayland_device_get_wl_seat (device), serial, resize_edges); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_resize (impl->display_server.zxdg_toplevel_v6, + zxdg_toplevel_v6_resize (impl->zxdg_toplevel_v6, gdk_wayland_device_get_wl_seat (device), serial, resize_edges); break; @@ -1582,7 +1586,7 @@ gdk_wayland_toplevel_begin_move (GdkToplevel *toplevel, guint32 timestamp) { GdkSurface *surface = GDK_SURFACE (toplevel); - GdkWaylandSurface *impl; + GdkWaylandToplevel *impl; GdkWaylandDisplay *display_wayland; GdkEventSequence *sequence; uint32_t serial; @@ -1591,7 +1595,7 @@ gdk_wayland_toplevel_begin_move (GdkToplevel *toplevel, !SURFACE_IS_TOPLEVEL (surface)) return; - impl = GDK_WAYLAND_SURFACE (surface); + impl = GDK_WAYLAND_TOPLEVEL (surface); display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); if (!is_realized_toplevel (impl)) @@ -1602,12 +1606,12 @@ gdk_wayland_toplevel_begin_move (GdkToplevel *toplevel, switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_move (impl->display_server.xdg_toplevel, + xdg_toplevel_move (impl->xdg_toplevel, gdk_wayland_device_get_wl_seat (device), serial); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_move (impl->display_server.zxdg_toplevel_v6, + zxdg_toplevel_v6_move (impl->zxdg_toplevel_v6, gdk_wayland_device_get_wl_seat (device), serial); break; @@ -1624,7 +1628,7 @@ static gboolean gdk_wayland_surface_show_window_menu (GdkSurface *surface, GdkEvent *event) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkSeat *seat; @@ -1656,11 +1660,11 @@ gdk_wayland_surface_show_window_menu (GdkSurface *surface, switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_toplevel_show_window_menu (impl->display_server.xdg_toplevel, + xdg_toplevel_show_window_menu (impl->xdg_toplevel, wl_seat, serial, x, y); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_toplevel_v6_show_window_menu (impl->display_server.zxdg_toplevel_v6, + zxdg_toplevel_v6_show_window_menu (impl->zxdg_toplevel_v6, wl_seat, serial, x, y); break; default: @@ -2089,19 +2093,19 @@ gdk_wayland_surface_map_toplevel (GdkSurface *surface) static void gdk_wayland_toplevel_hide (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); GDK_SURFACE_CLASS (gdk_wayland_toplevel_parent_class)->hide (surface); - if (impl->display_server.xdg_toplevel) + if (impl->xdg_toplevel) { - xdg_toplevel_destroy (impl->display_server.xdg_toplevel); - impl->display_server.xdg_toplevel = NULL; + xdg_toplevel_destroy (impl->xdg_toplevel); + impl->xdg_toplevel = NULL; } - if (impl->display_server.zxdg_toplevel_v6) + if (impl->zxdg_toplevel_v6) { - zxdg_toplevel_v6_destroy (impl->display_server.zxdg_toplevel_v6); - impl->display_server.zxdg_toplevel_v6 = NULL; + zxdg_toplevel_v6_destroy (impl->zxdg_toplevel_v6); + impl->zxdg_toplevel_v6 = NULL; } } -- GitLab From b9d85bd0e174f472a91dcbc875fa82a684e31272 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Mon, 21 Dec 2020 11:23:33 +0100 Subject: [PATCH 12/36] wayland: Move saved width & height to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.c | 15 ------------- gdk/wayland/gdksurface-wayland.h | 3 --- gdk/wayland/gdktoplevel-wayland.c | 35 ++++++++++++++++++++++++------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index a04c15100b0..34958bb97be 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -144,8 +144,6 @@ gdk_wayland_surface_init (GdkWaylandSurface *impl) { impl->scale = 1; impl->initial_fullscreen_output = NULL; - impl->saved_width = -1; - impl->saved_height = -1; impl->shortcuts_inhibitors = g_hash_table_new (NULL, NULL); } @@ -175,18 +173,6 @@ gdk_wayland_surface_thaw_state (GdkSurface *surface) g_assert (!impl->display_server.xdg_popup); } -static void -_gdk_wayland_surface_clear_saved_size (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - if (surface->state & (GDK_TOPLEVEL_STATE_FULLSCREEN | GDK_TOPLEVEL_STATE_MAXIMIZED)) - return; - - impl->saved_width = -1; - impl->saved_height = -1; -} - void gdk_wayland_surface_update_size (GdkSurface *surface, int32_t width, @@ -2087,7 +2073,6 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) impl->last_sent_max_width = 0; impl->last_sent_max_height = 0; - _gdk_wayland_surface_clear_saved_size (surface); impl->mapped = FALSE; } diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 13a9a4ef65a..1827c1ece26 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -115,9 +115,6 @@ struct _GdkWaylandSurface int last_sent_max_width; int last_sent_max_height; - int saved_width; - int saved_height; - gulong parent_surface_committed_handler; struct { diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 5a101d5e34e..d3fbcd354ea 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -60,6 +60,8 @@ struct _GdkWaylandToplevel struct zxdg_toplevel_v6 *zxdg_toplevel_v6; char *title; + int saved_width; + int saved_height; }; static void gdk_wayland_toplevel_iface_init (GdkToplevelInterface *iface); @@ -96,7 +98,8 @@ is_realized_toplevel (GdkWaylandToplevel *impl) static void _gdk_wayland_surface_save_size (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); + GdkWaylandSurface *wlsurface = GDK_WAYLAND_SURFACE (surface); if (surface->state & (GDK_TOPLEVEL_STATE_FULLSCREEN | GDK_TOPLEVEL_STATE_MAXIMIZED | @@ -106,8 +109,20 @@ _gdk_wayland_surface_save_size (GdkSurface *surface) if (surface->width <= 1 || surface->height <= 1) return; - impl->saved_width = surface->width - impl->shadow_left - impl->shadow_right; - impl->saved_height = surface->height - impl->shadow_top - impl->shadow_bottom; + impl->saved_width = surface->width - wlsurface->shadow_left - wlsurface->shadow_right; + impl->saved_height = surface->height - wlsurface->shadow_top - wlsurface->shadow_bottom; +} + +static void +gdk_wayland_surface_clear_saved_size (GdkSurface *surface) +{ + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); + + if (surface->state & (GDK_TOPLEVEL_STATE_FULLSCREEN | GDK_TOPLEVEL_STATE_MAXIMIZED)) + return; + + impl->saved_width = -1; + impl->saved_height = -1; } static const char * @@ -124,7 +139,6 @@ get_default_title (void) return title; } - static void gdk_wayland_toplevel_sync (GdkSurface *surface) { @@ -428,8 +442,8 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface) */ if (saved_size && !fixed_size) { - width = impl->saved_width; - height = impl->saved_height; + width = GDK_WAYLAND_TOPLEVEL(impl)->saved_width; + height = GDK_WAYLAND_TOPLEVEL(impl)->saved_height; } if (width > 0 && height > 0) @@ -1922,9 +1936,12 @@ gdk_wayland_toplevel_set_transient_for_exported (GdkToplevel *toplevel, } static void -gdk_wayland_toplevel_init (GdkWaylandToplevel *toplevel) +gdk_wayland_toplevel_init (GdkWaylandToplevel *impl) { - gdk_wayland_toplevel_set_title (GDK_SURFACE (toplevel), get_default_title ()); + impl->saved_width = -1; + impl->saved_height = -1; + + gdk_wayland_toplevel_set_title (GDK_SURFACE (impl), get_default_title ()); } #define LAST_PROP 1 @@ -2107,6 +2124,8 @@ gdk_wayland_toplevel_hide (GdkSurface *surface) { zxdg_toplevel_v6_destroy (impl->zxdg_toplevel_v6); impl->zxdg_toplevel_v6 = NULL; } + + gdk_wayland_surface_clear_saved_size (surface); } static void -- GitLab From 17b0b8510b6be9e2d50d6e534e5005fa9631d7fd Mon Sep 17 00:00:00 2001 From: David Keijser Date: Mon, 21 Dec 2020 11:40:30 +0100 Subject: [PATCH 13/36] wayland: Move more geometry related properties to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.h | 3 -- gdk/wayland/gdktoplevel-wayland.c | 60 +++++++++++++++++-------------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 1827c1ece26..1748aca4891 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -87,9 +87,6 @@ struct _GdkWaylandSurface char *unique_bus_name; } application; - GdkGeometry geometry_hints; - GdkSurfaceHints geometry_mask; - GdkSeat *grab_input_seat; gint64 pending_frame_counter; diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index d3fbcd354ea..40656a9a569 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -62,6 +62,9 @@ struct _GdkWaylandToplevel char *title; int saved_width; int saved_height; + + GdkGeometry geometry_hints; + GdkSurfaceHints geometry_mask; }; static void gdk_wayland_toplevel_iface_init (GdkToplevelInterface *iface); @@ -269,14 +272,15 @@ static void gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, static void gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); + GdkWaylandSurface *wlsurface = GDK_WAYLAND_SURFACE (surface); GdkRectangle geometry; - if (!is_realized_shell_surface (impl)) + if (!is_realized_shell_surface (wlsurface)) return; gdk_wayland_surface_get_window_geometry (surface, &geometry); - gdk_wayland_surface_set_geometry_hints (impl, + gdk_wayland_surface_set_geometry_hints (wlsurface, &impl->geometry_hints, impl->geometry_mask); } @@ -284,7 +288,8 @@ gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface) static void configure_toplevel_geometry (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); + GdkWaylandSurface *wlsurface = GDK_WAYLAND_SURFACE (surface); GdkDisplay *display = gdk_surface_get_display (surface); GdkMonitor *monitor; GdkRectangle monitor_geometry; @@ -305,7 +310,7 @@ configure_toplevel_geometry (GdkSurface *surface) g_warn_if_fail (size.width > 0); g_warn_if_fail (size.height > 0); - layout = impl->toplevel.layout; + layout = wlsurface->toplevel.layout; if (gdk_toplevel_layout_get_resizable (layout)) { geometry.min_width = size.min_width; @@ -318,40 +323,40 @@ configure_toplevel_geometry (GdkSurface *surface) geometry.max_height = geometry.min_height = size.height; mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE; } - gdk_wayland_surface_set_geometry_hints (impl, &geometry, mask); + gdk_wayland_surface_set_geometry_hints (wlsurface, &geometry, mask); if (size.shadow.is_valid) { - impl->shadow_left = size.shadow.left; - impl->shadow_right = size.shadow.right; - impl->shadow_top = size.shadow.top; - impl->shadow_bottom = size.shadow.bottom; + wlsurface->shadow_left = size.shadow.left; + wlsurface->shadow_right = size.shadow.right; + wlsurface->shadow_top = size.shadow.top; + wlsurface->shadow_bottom = size.shadow.bottom; } - if (impl->next_layout.configured_width > 0 && - impl->next_layout.configured_height > 0) + if (wlsurface->next_layout.configured_width > 0 && + wlsurface->next_layout.configured_height > 0) { int width, height; - width = impl->next_layout.configured_width + - impl->shadow_left + impl->shadow_right; - height = impl->next_layout.configured_height + - impl->shadow_top + impl->shadow_bottom; + width = wlsurface->next_layout.configured_width + + wlsurface->shadow_left + wlsurface->shadow_right; + height = wlsurface->next_layout.configured_height + + wlsurface->shadow_top + wlsurface->shadow_bottom; - if (impl->next_layout.toplevel.should_constrain) + if (wlsurface->next_layout.toplevel.should_constrain) { gdk_surface_constrain_size (&impl->geometry_hints, impl->geometry_mask, width, height, &width, &height); } - gdk_wayland_surface_update_size (surface, width, height, impl->scale); + gdk_wayland_surface_update_size (surface, width, height, wlsurface->scale); - if (!impl->next_layout.toplevel.size_is_fixed) + if (!wlsurface->next_layout.toplevel.size_is_fixed) { - impl->next_layout.toplevel.should_constrain = FALSE; - impl->next_layout.configured_width = 0; - impl->next_layout.configured_height = 0; + wlsurface->next_layout.toplevel.should_constrain = FALSE; + wlsurface->next_layout.configured_width = 0; + wlsurface->next_layout.configured_height = 0; } } else @@ -363,7 +368,7 @@ configure_toplevel_geometry (GdkSurface *surface) gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height); - gdk_wayland_surface_update_size (surface, width, height, impl->scale); + gdk_wayland_surface_update_size (surface, width, height, wlsurface->scale); } } @@ -1091,6 +1096,7 @@ static const struct gtk_surface1_listener gtk_surface_listener = { static void gdk_wayland_surface_init_gtk_surface (GdkWaylandSurface *impl) { + GdkWaylandToplevel *toplevel = GDK_WAYLAND_TOPLEVEL (impl); GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (impl))); @@ -1107,8 +1113,8 @@ gdk_wayland_surface_init_gtk_surface (GdkWaylandSurface *impl) wl_proxy_set_queue ((struct wl_proxy *) impl->display_server.gtk_surface, impl->event_queue); gdk_wayland_surface_set_geometry_hints (impl, - &impl->geometry_hints, - impl->geometry_mask); + &toplevel->geometry_hints, + toplevel->geometry_mask); gtk_surface1_add_listener (impl->display_server.gtk_surface, >k_surface_listener, impl); @@ -1154,8 +1160,8 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *surface, display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (impl))); - surface->geometry_hints = *geometry; - surface->geometry_mask = geom_mask; + impl->geometry_hints = *geometry; + impl->geometry_mask = geom_mask; if (!is_realized_toplevel (impl)) return; -- GitLab From 0e1cc8326278b0daa5669b3d18e085946d1513c5 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Tue, 22 Dec 2020 13:36:48 +0100 Subject: [PATCH 14/36] wayland: Move initial_fullscreen_output to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.c | 1 - gdk/wayland/gdksurface-wayland.h | 2 -- gdk/wayland/gdktoplevel-wayland.c | 15 +++++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 34958bb97be..2f0fd3ce7f9 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -143,7 +143,6 @@ static void gdk_wayland_surface_init (GdkWaylandSurface *impl) { impl->scale = 1; - impl->initial_fullscreen_output = NULL; impl->shortcuts_inhibitors = g_hash_table_new (NULL, NULL); } diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 1748aca4891..99601acd7ad 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -98,8 +98,6 @@ struct _GdkWaylandSurface int shadow_bottom; gboolean shadow_dirty; - struct wl_output *initial_fullscreen_output; - cairo_region_t *opaque_region; gboolean opaque_region_dirty; diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 40656a9a569..16c9fee3351 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -63,6 +63,8 @@ struct _GdkWaylandToplevel int saved_width; int saved_height; + struct wl_output *initial_fullscreen_output; + GdkGeometry geometry_hints; GdkSurfaceHints geometry_mask; }; @@ -865,7 +867,7 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) xdg_toplevel_set_minimized (impl->xdg_toplevel); if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) xdg_toplevel_set_fullscreen (impl->xdg_toplevel, - wlsurface->initial_fullscreen_output); + impl->initial_fullscreen_output); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED) @@ -874,13 +876,13 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) zxdg_toplevel_v6_set_minimized (impl->zxdg_toplevel_v6); if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) zxdg_toplevel_v6_set_fullscreen (impl->zxdg_toplevel_v6, - wlsurface->initial_fullscreen_output); + impl->initial_fullscreen_output); break; default: g_assert_not_reached (); } - wlsurface->initial_fullscreen_output = NULL; + impl->initial_fullscreen_output = NULL; app_id = wlsurface->application.application_id; if (app_id == NULL) @@ -1436,7 +1438,7 @@ gdk_wayland_surface_fullscreen_on_monitor (GdkSurface *surface, else { synthesize_initial_surface_state (surface, 0, GDK_TOPLEVEL_STATE_FULLSCREEN); - GDK_WAYLAND_SURFACE(impl)->initial_fullscreen_output = output; + impl->initial_fullscreen_output = output; } } @@ -1448,7 +1450,7 @@ gdk_wayland_surface_fullscreen (GdkSurface *surface) if (GDK_SURFACE_DESTROYED (surface)) return; - GDK_WAYLAND_SURFACE(impl)->initial_fullscreen_output = NULL; + impl->initial_fullscreen_output = NULL; _gdk_wayland_surface_save_size (surface); @@ -1485,7 +1487,7 @@ gdk_wayland_surface_unfullscreen (GdkSurface *surface) if (GDK_SURFACE_DESTROYED (surface)) return; - GDK_WAYLAND_SURFACE(impl)->initial_fullscreen_output = NULL; + impl->initial_fullscreen_output = NULL; if (is_realized_toplevel (impl)) { @@ -1944,6 +1946,7 @@ gdk_wayland_toplevel_set_transient_for_exported (GdkToplevel *toplevel, static void gdk_wayland_toplevel_init (GdkWaylandToplevel *impl) { + impl->initial_fullscreen_output = NULL; impl->saved_width = -1; impl->saved_height = -1; -- GitLab From 7a792f43378784ab14d5fb1a3e6c9341f9ede671 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Tue, 2 Feb 2021 19:31:12 +0100 Subject: [PATCH 15/36] wayland: Move last sent min/max width/height to toplevel --- gdk/wayland/gdksurface-wayland.c | 4 ---- gdk/wayland/gdksurface-wayland.h | 4 ---- gdk/wayland/gdktoplevel-wayland.c | 26 ++++++++++++++++++-------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 2f0fd3ce7f9..da6ca619ebc 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -2067,10 +2067,6 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) unset_transient_for_exported (surface); impl->last_sent_window_geometry = (GdkRectangle) { 0 }; - impl->last_sent_min_width = 0; - impl->last_sent_min_height = 0; - impl->last_sent_max_width = 0; - impl->last_sent_max_height = 0; impl->mapped = FALSE; } diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 99601acd7ad..288410de7d7 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -105,10 +105,6 @@ struct _GdkWaylandSurface gboolean input_region_dirty; GdkRectangle last_sent_window_geometry; - int last_sent_min_width; - int last_sent_min_height; - int last_sent_max_width; - int last_sent_max_height; gulong parent_surface_committed_handler; diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 16c9fee3351..1e3998286b1 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -65,6 +65,11 @@ struct _GdkWaylandToplevel struct wl_output *initial_fullscreen_output; + int last_sent_min_width; + int last_sent_min_height; + int last_sent_max_width; + int last_sent_max_height; + GdkGeometry geometry_hints; GdkSurfaceHints geometry_mask; }; @@ -1194,10 +1199,10 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *surface, max_height = 0; } - if (surface->last_sent_min_width == min_width && - surface->last_sent_min_height == min_height && - surface->last_sent_max_width == max_width && - surface->last_sent_max_height == max_height) + if (impl->last_sent_min_width == min_width && + impl->last_sent_min_height == min_height && + impl->last_sent_max_width == max_width && + impl->last_sent_max_height == max_height) return; switch (display_wayland->shell_variant) @@ -1218,10 +1223,10 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *surface, g_assert_not_reached (); } - surface->last_sent_min_width = min_width; - surface->last_sent_min_height = min_height; - surface->last_sent_max_width = max_width; - surface->last_sent_max_height = max_height; + impl->last_sent_min_width = min_width; + impl->last_sent_min_height = min_height; + impl->last_sent_max_width = max_width; + impl->last_sent_max_height = max_height; } static void @@ -2135,6 +2140,11 @@ gdk_wayland_toplevel_hide (GdkSurface *surface) { } gdk_wayland_surface_clear_saved_size (surface); + + impl->last_sent_min_width = 0; + impl->last_sent_min_height = 0; + impl->last_sent_max_width = 0; + impl->last_sent_max_height = 0; } static void -- GitLab From 68f4a7a2d690c351e56c8cbef9683155b0ee8779 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Tue, 22 Dec 2020 13:44:55 +0100 Subject: [PATCH 16/36] wayland: Move toplevel.layout to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.c | 1 - gdk/wayland/gdksurface-wayland.h | 4 ---- gdk/wayland/gdktoplevel-wayland.c | 12 ++++++++---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index da6ca619ebc..0e87504ceac 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -2057,7 +2057,6 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) g_slist_free (impl->display_server.outputs); impl->display_server.outputs = NULL; - g_clear_pointer (&impl->toplevel.layout, gdk_toplevel_layout_unref); g_clear_pointer (&impl->popup.layout, gdk_popup_layout_unref); } diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 288410de7d7..56fd128255a 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -108,10 +108,6 @@ struct _GdkWaylandSurface gulong parent_surface_committed_handler; - struct { - GdkToplevelLayout *layout; - } toplevel; - struct { GdkPopupLayout *layout; int unconstrained_width; diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 1e3998286b1..02a16e5d2e8 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -72,6 +72,8 @@ struct _GdkWaylandToplevel GdkGeometry geometry_hints; GdkSurfaceHints geometry_mask; + + GdkToplevelLayout *layout; }; static void gdk_wayland_toplevel_iface_init (GdkToplevelInterface *iface); @@ -317,7 +319,7 @@ configure_toplevel_geometry (GdkSurface *surface) g_warn_if_fail (size.width > 0); g_warn_if_fail (size.height > 0); - layout = wlsurface->toplevel.layout; + layout = impl->layout; if (gdk_toplevel_layout_get_resizable (layout)) { geometry.min_width = size.min_width; @@ -2145,6 +2147,8 @@ gdk_wayland_toplevel_hide (GdkSurface *surface) { impl->last_sent_min_height = 0; impl->last_sent_max_width = 0; impl->last_sent_max_height = 0; + + g_clear_pointer (&impl->layout, gdk_toplevel_layout_unref); } static void @@ -2152,7 +2156,7 @@ gdk_wayland_toplevel_present (GdkToplevel *toplevel, GdkToplevelLayout *layout) { GdkSurface *surface = GDK_SURFACE (toplevel); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); gboolean pending_configure = FALSE; gboolean maximize; gboolean fullscreen; @@ -2185,8 +2189,8 @@ gdk_wayland_toplevel_present (GdkToplevel *toplevel, pending_configure = TRUE; } - g_clear_pointer (&impl->toplevel.layout, gdk_toplevel_layout_unref); - impl->toplevel.layout = gdk_toplevel_layout_copy (layout); + g_clear_pointer (&impl->layout, gdk_toplevel_layout_unref); + impl->layout = gdk_toplevel_layout_copy (layout); gdk_wayland_surface_show (surface, FALSE); gdk_wayland_surface_map_toplevel (surface); -- GitLab From e04f5afc82d48def4e36e5a29ab87d2e5d936ab6 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Tue, 22 Dec 2020 18:19:57 +0100 Subject: [PATCH 17/36] wayland: Move pending.toplevel & next_layout.toplevel to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.h | 11 ---- gdk/wayland/gdktoplevel-wayland.c | 92 +++++++++++++++++-------------- 2 files changed, 52 insertions(+), 51 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 56fd128255a..073c9411bbf 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -115,13 +115,6 @@ struct _GdkWaylandSurface } popup; struct { - struct { - int width; - int height; - GdkToplevelState state; - gboolean is_resizing; - } toplevel; - struct { int x; int y; @@ -143,10 +136,6 @@ struct _GdkWaylandSurface } initial_state; struct { - struct { - gboolean should_constrain; - gboolean size_is_fixed; - } toplevel; struct { int x; int y; diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 02a16e5d2e8..4b7b10256e1 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -74,6 +74,18 @@ struct _GdkWaylandToplevel GdkSurfaceHints geometry_mask; GdkToplevelLayout *layout; + + struct { + int width; + int height; + GdkToplevelState state; + gboolean is_resizing; + } pending; + + struct { + gboolean should_constrain; + gboolean size_is_fixed; + } next_layout; }; static void gdk_wayland_toplevel_iface_init (GdkToplevelInterface *iface); @@ -352,7 +364,7 @@ configure_toplevel_geometry (GdkSurface *surface) height = wlsurface->next_layout.configured_height + wlsurface->shadow_top + wlsurface->shadow_bottom; - if (wlsurface->next_layout.toplevel.should_constrain) + if (impl->next_layout.should_constrain) { gdk_surface_constrain_size (&impl->geometry_hints, impl->geometry_mask, @@ -361,9 +373,9 @@ configure_toplevel_geometry (GdkSurface *surface) } gdk_wayland_surface_update_size (surface, width, height, wlsurface->scale); - if (!wlsurface->next_layout.toplevel.size_is_fixed) + if (!impl->next_layout.size_is_fixed) { - wlsurface->next_layout.toplevel.should_constrain = FALSE; + impl->next_layout.should_constrain = FALSE; wlsurface->next_layout.configured_width = 0; wlsurface->next_layout.configured_height = 0; } @@ -421,7 +433,7 @@ synthesize_initial_surface_state (GdkSurface *surface, static void gdk_wayland_surface_configure_toplevel (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkToplevelState new_state; @@ -430,11 +442,11 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface) gboolean fixed_size; gboolean saved_size; - new_state = impl->pending.toplevel.state; - impl->pending.toplevel.state = 0; + new_state = impl->pending.state; + impl->pending.state = 0; - is_resizing = impl->pending.toplevel.is_resizing; - impl->pending.toplevel.is_resizing = FALSE; + is_resizing = impl->pending.is_resizing; + impl->pending.is_resizing = FALSE; fixed_size = new_state & (GDK_TOPLEVEL_STATE_MAXIMIZED | @@ -442,8 +454,8 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface) GDK_TOPLEVEL_STATE_TILED) || is_resizing; - width = impl->pending.toplevel.width; - height = impl->pending.toplevel.height; + width = impl->pending.width; + height = impl->pending.height; saved_size = (width == 0 && height == 0); /* According to xdg_shell, an xdg_surface.configure with size 0x0 @@ -456,38 +468,38 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface) */ if (saved_size && !fixed_size) { - width = GDK_WAYLAND_TOPLEVEL(impl)->saved_width; - height = GDK_WAYLAND_TOPLEVEL(impl)->saved_height; + width =impl->saved_width; + height =impl->saved_height; } if (width > 0 && height > 0) { if (!saved_size) { - impl->next_layout.toplevel.should_constrain = TRUE; + impl->next_layout.should_constrain = TRUE; /* Save size for next time we get 0x0 */ _gdk_wayland_surface_save_size (surface); } else if (is_resizing) { - impl->next_layout.toplevel.should_constrain = TRUE; + impl->next_layout.should_constrain = TRUE; } else { - impl->next_layout.toplevel.should_constrain = FALSE; + impl->next_layout.should_constrain = FALSE; } - impl->next_layout.toplevel.size_is_fixed = fixed_size; - impl->next_layout.configured_width = width; - impl->next_layout.configured_height = height; + impl->next_layout.size_is_fixed = fixed_size; + GDK_WAYLAND_SURFACE(impl)->next_layout.configured_width = width; + GDK_WAYLAND_SURFACE(impl)->next_layout.configured_height = height; } else { - impl->next_layout.toplevel.should_constrain = FALSE; - impl->next_layout.toplevel.size_is_fixed = FALSE; - impl->next_layout.configured_width = 0; - impl->next_layout.configured_height = 0; + impl->next_layout.should_constrain = FALSE; + impl->next_layout.size_is_fixed = FALSE; + GDK_WAYLAND_SURFACE(impl)->next_layout.configured_width = 0; + GDK_WAYLAND_SURFACE(impl)->next_layout.configured_height = 0; } gdk_surface_request_layout (surface); @@ -505,12 +517,12 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface) switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_surface_ack_configure (impl->display_server.xdg_surface, - impl->pending.serial); + xdg_surface_ack_configure (GDK_WAYLAND_SURFACE(impl)->display_server.xdg_surface, + GDK_WAYLAND_SURFACE(impl)->pending.serial); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6, - impl->pending.serial); + zxdg_surface_v6_ack_configure (GDK_WAYLAND_SURFACE(impl)->display_server.zxdg_surface_v6, + GDK_WAYLAND_SURFACE(impl)->pending.serial); break; default: g_assert_not_reached (); @@ -523,11 +535,11 @@ gdk_wayland_surface_handle_configure_toplevel (GdkSurface *surface, int32_t height, GdkToplevelState state) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); - impl->pending.toplevel.state |= state; - impl->pending.toplevel.width = width; - impl->pending.toplevel.height = height; + impl->pending.state |= state; + impl->pending.width = width; + impl->pending.height = height; } static void @@ -667,11 +679,11 @@ xdg_toplevel_configure (void *data, struct wl_array *states) { GdkSurface *surface = GDK_SURFACE (data); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); uint32_t *p; GdkToplevelState pending_state = 0; - impl->pending.toplevel.is_resizing = FALSE; + impl->pending.is_resizing = FALSE; wl_array_for_each (p, states) { @@ -689,7 +701,7 @@ xdg_toplevel_configure (void *data, pending_state |= GDK_TOPLEVEL_STATE_FOCUSED; break; case XDG_TOPLEVEL_STATE_RESIZING: - impl->pending.toplevel.is_resizing = TRUE; + impl->pending.is_resizing = TRUE; break; default: /* Unknown state */ @@ -735,11 +747,11 @@ zxdg_toplevel_v6_configure (void *data, struct wl_array *states) { GdkSurface *surface = GDK_SURFACE (data); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); uint32_t *p; GdkToplevelState pending_state = 0; - impl->pending.toplevel.is_resizing = FALSE; + impl->pending.is_resizing = FALSE; wl_array_for_each (p, states) { @@ -757,7 +769,7 @@ zxdg_toplevel_v6_configure (void *data, pending_state |= GDK_TOPLEVEL_STATE_FOCUSED; break; case ZXDG_TOPLEVEL_V6_STATE_RESIZING: - impl->pending.toplevel.is_resizing = TRUE; + impl->pending.is_resizing = TRUE; break; default: /* Unknown state */ @@ -1024,7 +1036,7 @@ gtk_surface_configure (void *data, struct wl_array *states) { GdkSurface *surface = GDK_SURFACE (data); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); GdkToplevelState new_state = 0; uint32_t *p; @@ -1057,7 +1069,7 @@ gtk_surface_configure (void *data, } } - impl->pending.toplevel.state |= new_state; + impl->pending.state |= new_state; } static void @@ -1066,7 +1078,7 @@ gtk_surface_configure_edges (void *data, struct wl_array *edge_constraints) { GdkSurface *surface = GDK_SURFACE (data); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); GdkToplevelState new_state = 0; uint32_t *p; @@ -1094,7 +1106,7 @@ gtk_surface_configure_edges (void *data, } } - impl->pending.toplevel.state |= new_state; + impl->pending.state |= new_state; } static const struct gtk_surface1_listener gtk_surface_listener = { -- GitLab From 3e98ef5a2fb27bd2b41bdb84cc290ac76c749f75 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Tue, 22 Dec 2020 18:31:31 +0100 Subject: [PATCH 18/36] wayland: Move exported & xdg_exported to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.c | 25 --------------- gdk/wayland/gdksurface-wayland.h | 7 ----- gdk/wayland/gdktoplevel-wayland.c | 51 +++++++++++++++++++++++++------ 3 files changed, 41 insertions(+), 42 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 0e87504ceac..a608e7cab8e 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -137,7 +137,6 @@ static void update_popup_layout_state (GdkSurface *surface, int height, GdkPopupLayout *layout); -static gboolean gdk_wayland_surface_is_exported (GdkWaylandSurface *impl); static void gdk_wayland_surface_init (GdkWaylandSurface *impl) @@ -754,9 +753,6 @@ gdk_wayland_surface_finalize (GObject *object) impl = GDK_WAYLAND_SURFACE (object); - if (gdk_wayland_surface_is_exported (impl)) - gdk_wayland_toplevel_unexport_handle (GDK_TOPLEVEL (impl)); - g_free (impl->application.application_id); g_free (impl->application.app_menu_path); g_free (impl->application.menubar_path); @@ -2679,27 +2675,6 @@ _gdk_wayland_surface_offset_next_wl_buffer (GdkSurface *surface, impl->pending_buffer_offset_y = y; } -/** - * GdkWaylandToplevelExported: - * @toplevel: (type GdkWaylandToplevel): the `GdkToplevel` that is exported - * @handle: the handle - * @user_data: user data that was passed to [method@GdkWayland.WaylandToplevel.export_handle] - * - * Callback that gets called when the handle for a surface has been - * obtained from the Wayland compositor. - * - * This callback is used in [method@GdkWayland.WaylandToplevel.export_handle]. - * - * The @handle can be passed to other processes, for the purpose of - * marking surfaces as transient for out-of-process surfaces. - */ - -static gboolean -gdk_wayland_surface_is_exported (GdkWaylandSurface *impl) -{ - return !!impl->display_server.xdg_exported; -} - void unset_transient_for_exported (GdkSurface *surface) { diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 073c9411bbf..cb5fa51a196 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -52,7 +52,6 @@ struct _GdkWaylandSurface struct gtk_surface1 *gtk_surface; struct wl_egl_window *egl_window; struct wl_egl_window *dummy_egl_window; - struct zxdg_exported_v1 *xdg_exported; struct org_kde_kwin_server_decoration *server_decoration; } display_server; @@ -149,12 +148,6 @@ struct _GdkWaylandSurface int state_freeze_count; - struct { - GdkWaylandToplevelExported callback; - gpointer user_data; - GDestroyNotify destroy_func; - } exported; - struct zxdg_imported_v1 *imported_transient_for; GHashTable *shortcuts_inhibitors; diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 4b7b10256e1..f3ca17409b9 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -58,6 +58,7 @@ struct _GdkWaylandToplevel struct xdg_toplevel *xdg_toplevel; struct zxdg_toplevel_v6 *zxdg_toplevel_v6; + struct zxdg_exported_v1 *xdg_exported; char *title; int saved_width; @@ -86,6 +87,12 @@ struct _GdkWaylandToplevel gboolean should_constrain; gboolean size_is_fixed; } next_layout; + + struct { + GdkWaylandToplevelExported callback; + gpointer user_data; + GDestroyNotify destroy_func; + } exported; }; static void gdk_wayland_toplevel_iface_init (GdkToplevelInterface *iface); @@ -104,6 +111,7 @@ static void gdk_wayland_surface_configure_toplevel (GdkSurface *surface); static void gdk_wayland_toplevel_hide (GdkSurface *surface); +static gboolean gdk_wayland_surface_is_exported (GdkWaylandToplevel *impl); static gboolean is_realized_shell_surface (GdkWaylandSurface *impl) @@ -179,6 +187,9 @@ gdk_wayland_toplevel_finalize (GObject *object) impl = GDK_WAYLAND_TOPLEVEL (object); + if (gdk_wayland_surface_is_exported (impl)) + gdk_wayland_toplevel_unexport_handle (GDK_TOPLEVEL (impl)); + g_free (impl->title); G_OBJECT_CLASS(gdk_wayland_toplevel_parent_class)->finalize (object); } @@ -1787,7 +1798,7 @@ xdg_exported_handle (void *data, const char *handle) { GdkToplevel *toplevel = data; - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (toplevel); impl->exported.callback (toplevel, handle, impl->exported.user_data); if (impl->exported.destroy_func) @@ -1801,6 +1812,26 @@ static const struct zxdg_exported_v1_listener xdg_exported_listener = { xdg_exported_handle }; +/** + * GdkWaylandToplevelExported: + * @toplevel: (type GdkWaylandToplevel): the `GdkToplevel` that is exported + * @handle: the handle + * @user_data: user data that was passed to [method@GdkWayland.WaylandToplevel.export_handle] + * + * Callback that gets called when the handle for a surface has been + * obtained from the Wayland compositor. + * + * This callback is used in [method@GdkWayland.WaylandToplevel.export_handle]. + * + * The @handle can be passed to other processes, for the purpose of + * marking surfaces as transient for out-of-process surfaces. + */ +static gboolean +gdk_wayland_surface_is_exported (GdkWaylandToplevel *impl) +{ + return !!impl->xdg_exported; +} + /** * gdk_wayland_toplevel_export_handle: * @toplevel: (type GdkWaylandToplevel): the `GdkToplevel` to obtain a handle for @@ -1835,7 +1866,7 @@ gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel, gpointer user_data, GDestroyNotify destroy_func) { - GdkWaylandSurface *impl; + GdkWaylandToplevel *impl; GdkWaylandDisplay *display_wayland; GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (toplevel)); struct zxdg_exported_v1 *xdg_exported; @@ -1843,10 +1874,10 @@ gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel, g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE); g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE); - impl = GDK_WAYLAND_SURFACE (toplevel); + impl = GDK_WAYLAND_TOPLEVEL (toplevel); display_wayland = GDK_WAYLAND_DISPLAY (display); - g_return_val_if_fail (!impl->display_server.xdg_exported, FALSE); + g_return_val_if_fail (!impl->xdg_exported, FALSE); if (!display_wayland->xdg_exporter) { @@ -1855,10 +1886,10 @@ gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel, } xdg_exported = zxdg_exporter_v1_export (display_wayland->xdg_exporter, - impl->display_server.wl_surface); + GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface); zxdg_exported_v1_add_listener (xdg_exported, &xdg_exported_listener, impl); - impl->display_server.xdg_exported = xdg_exported; + impl->xdg_exported = xdg_exported; impl->exported.callback = callback; impl->exported.user_data = user_data; impl->exported.destroy_func = destroy_func; @@ -1882,15 +1913,15 @@ gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel, void gdk_wayland_toplevel_unexport_handle (GdkToplevel *toplevel) { - GdkWaylandSurface *impl; + GdkWaylandToplevel *impl; g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); - impl = GDK_WAYLAND_SURFACE (toplevel); + impl = GDK_WAYLAND_TOPLEVEL (toplevel); - g_return_if_fail (impl->display_server.xdg_exported); + g_return_if_fail (impl->xdg_exported); - g_clear_pointer (&impl->display_server.xdg_exported, + g_clear_pointer (&impl->xdg_exported, zxdg_exported_v1_destroy); if (impl->exported.destroy_func) { -- GitLab From 8f1fb479fcd8a7ef4e78e22b9c8327cbb534ef92 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Tue, 22 Dec 2020 18:39:37 +0100 Subject: [PATCH 19/36] wayland: Move imported_transient_for to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.c | 10 ---------- gdk/wayland/gdksurface-wayland.h | 2 -- gdk/wayland/gdktoplevel-wayland.c | 27 ++++++++++++++++++++------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index a608e7cab8e..ecdd78e97bd 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -2059,8 +2059,6 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) impl->has_uncommitted_ack_configure = FALSE; impl->input_region_dirty = TRUE; - unset_transient_for_exported (surface); - impl->last_sent_window_geometry = (GdkRectangle) { 0 }; impl->mapped = FALSE; @@ -2675,14 +2673,6 @@ _gdk_wayland_surface_offset_next_wl_buffer (GdkSurface *surface, impl->pending_buffer_offset_y = y; } -void -unset_transient_for_exported (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - g_clear_pointer (&impl->imported_transient_for, zxdg_imported_v1_destroy); -} - struct zwp_keyboard_shortcuts_inhibitor_v1 * gdk_wayland_surface_get_inhibitor (GdkWaylandSurface *impl, GdkSeat *gdk_seat) diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index cb5fa51a196..dc2b085b13b 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -148,7 +148,6 @@ struct _GdkWaylandSurface int state_freeze_count; - struct zxdg_imported_v1 *imported_transient_for; GHashTable *shortcuts_inhibitors; struct zwp_idle_inhibitor_v1 *idle_inhibitor; @@ -188,7 +187,6 @@ void gdk_wayland_surface_show (GdkSurface *surface, gboolean already_mapped); -void unset_transient_for_exported (GdkSurface *surface); void gdk_wayland_surface_get_window_geometry (GdkSurface *surface, GdkRectangle *geometry); diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index f3ca17409b9..a9e8a97a923 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -59,6 +59,7 @@ struct _GdkWaylandToplevel struct xdg_toplevel *xdg_toplevel; struct zxdg_toplevel_v6 *zxdg_toplevel_v6; struct zxdg_exported_v1 *xdg_exported; + struct zxdg_imported_v1 *imported_transient_for; char *title; int saved_width; @@ -112,6 +113,7 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface); static void gdk_wayland_toplevel_hide (GdkSurface *surface); static gboolean gdk_wayland_surface_is_exported (GdkWaylandToplevel *impl); +static void unset_transient_for_exported (GdkSurface *surface); static gboolean is_realized_shell_surface (GdkWaylandSurface *impl) @@ -253,19 +255,19 @@ gdk_wayland_surface_sync_parent (GdkSurface *surface, } static void -gdk_wayland_surface_sync_parent_of_imported (GdkWaylandSurface *impl) +gdk_wayland_surface_sync_parent_of_imported (GdkWaylandToplevel *impl) { - if (!impl->display_server.wl_surface) + if (!GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface) return; if (!impl->imported_transient_for) return; - if (!is_realized_toplevel (GDK_WAYLAND_TOPLEVEL(impl))) + if (!is_realized_toplevel (impl)) return; zxdg_imported_v1_set_parent_of (impl->imported_transient_for, - impl->display_server.wl_surface); + GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface); } static void @@ -885,7 +887,7 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) } gdk_wayland_surface_sync_parent (surface, NULL); - gdk_wayland_surface_sync_parent_of_imported (wlsurface); + gdk_wayland_surface_sync_parent_of_imported (impl); gdk_wayland_surface_sync_title (surface); switch (display_wayland->shell_variant) @@ -1930,6 +1932,15 @@ gdk_wayland_toplevel_unexport_handle (GdkToplevel *toplevel) } } +static void +unset_transient_for_exported (GdkSurface *surface) +{ + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); + + g_clear_pointer (&impl->imported_transient_for, zxdg_imported_v1_destroy); +} + + static void xdg_imported_destroyed (void *data, struct zxdg_imported_v1 *zxdg_imported_v1) @@ -1964,14 +1975,14 @@ gboolean gdk_wayland_toplevel_set_transient_for_exported (GdkToplevel *toplevel, const char *parent_handle_str) { - GdkWaylandSurface *impl; + GdkWaylandToplevel *impl; GdkWaylandDisplay *display_wayland; GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (toplevel)); g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE); g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE); - impl = GDK_WAYLAND_SURFACE (toplevel); + impl = GDK_WAYLAND_TOPLEVEL (toplevel); display_wayland = GDK_WAYLAND_DISPLAY (display); if (!display_wayland->xdg_importer) @@ -2192,6 +2203,8 @@ gdk_wayland_toplevel_hide (GdkSurface *surface) { impl->last_sent_max_height = 0; g_clear_pointer (&impl->layout, gdk_toplevel_layout_unref); + + unset_transient_for_exported (surface); } static void -- GitLab From 0aa5264bcfc9f0510c2a83f1ca36a07ce4f66bc4 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Tue, 22 Dec 2020 18:43:19 +0100 Subject: [PATCH 20/36] wayland: Move idle_inhibitor to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.h | 3 --- gdk/wayland/gdktoplevel-wayland.c | 9 ++++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index dc2b085b13b..c1d5eacf019 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -149,9 +149,6 @@ struct _GdkWaylandSurface int state_freeze_count; GHashTable *shortcuts_inhibitors; - - struct zwp_idle_inhibitor_v1 *idle_inhibitor; - size_t idle_inhibitor_refcount; }; typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass; diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index a9e8a97a923..1ef88811730 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -94,6 +94,9 @@ struct _GdkWaylandToplevel gpointer user_data; GDestroyNotify destroy_func; } exported; + + struct zwp_idle_inhibitor_v1 *idle_inhibitor; + size_t idle_inhibitor_refcount; }; static void gdk_wayland_toplevel_iface_init (GdkToplevelInterface *iface); @@ -973,7 +976,7 @@ gboolean gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel))); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (toplevel); g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE); @@ -985,7 +988,7 @@ gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel) g_assert (impl->idle_inhibitor_refcount == 0); impl->idle_inhibitor = zwp_idle_inhibit_manager_v1_create_inhibitor (display_wayland->idle_inhibit_manager, - impl->display_server.wl_surface); + GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface); } ++impl->idle_inhibitor_refcount; @@ -995,7 +998,7 @@ gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel) void gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (toplevel); g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); -- GitLab From 19504e98bce265fbcc15d57e8b04660c25c05873 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Tue, 22 Dec 2020 18:47:39 +0100 Subject: [PATCH 21/36] wayland: Move initial_state to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.h | 5 ----- gdk/wayland/gdktoplevel-wayland.c | 19 ++++++++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index c1d5eacf019..07ef88fafcf 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -129,11 +129,6 @@ struct _GdkWaylandSurface gboolean is_dirty; } pending; - struct { - GdkToplevelState unset_flags; - GdkToplevelState set_flags; - } initial_state; - struct { struct { int x; diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 1ef88811730..bd36273e65e 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -77,6 +77,11 @@ struct _GdkWaylandToplevel GdkToplevelLayout *layout; + struct { + GdkToplevelState unset_flags; + GdkToplevelState set_flags; + } initial_state; + struct { int width; int height; @@ -437,7 +442,7 @@ synthesize_initial_surface_state (GdkSurface *surface, GdkToplevelState unset_flags, GdkToplevelState set_flags) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); impl->initial_state.unset_flags |= unset_flags; impl->initial_state.set_flags &= ~unset_flags; @@ -896,20 +901,20 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED) + if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED) xdg_toplevel_set_maximized (impl->xdg_toplevel); - if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED) + if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED) xdg_toplevel_set_minimized (impl->xdg_toplevel); - if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) + if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) xdg_toplevel_set_fullscreen (impl->xdg_toplevel, impl->initial_fullscreen_output); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED) + if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED) zxdg_toplevel_v6_set_maximized (impl->zxdg_toplevel_v6); - if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED) + if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED) zxdg_toplevel_v6_set_minimized (impl->zxdg_toplevel_v6); - if (wlsurface->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) + if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN) zxdg_toplevel_v6_set_fullscreen (impl->zxdg_toplevel_v6, impl->initial_fullscreen_output); break; -- GitLab From 73f980d68298c83c31ff585496da4e88cb989954 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Tue, 22 Dec 2020 18:51:57 +0100 Subject: [PATCH 22/36] wayland: Move server_decoration to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.h | 1 - gdk/wayland/gdktoplevel-wayland.c | 23 ++++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 07ef88fafcf..63dbce0134d 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -52,7 +52,6 @@ struct _GdkWaylandSurface struct gtk_surface1 *gtk_surface; struct wl_egl_window *egl_window; struct wl_egl_window *dummy_egl_window; - struct org_kde_kwin_server_decoration *server_decoration; } display_server; struct wl_event_queue *event_queue; diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index bd36273e65e..bba92de832c 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -59,6 +59,7 @@ struct _GdkWaylandToplevel struct xdg_toplevel *xdg_toplevel; struct zxdg_toplevel_v6 *zxdg_toplevel_v6; struct zxdg_exported_v1 *xdg_exported; + struct org_kde_kwin_server_decoration *server_decoration; struct zxdg_imported_v1 *imported_transient_for; char *title; @@ -944,17 +945,17 @@ void gdk_wayland_toplevel_announce_csd (GdkToplevel *toplevel) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel))); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (toplevel); g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); if (!display_wayland->server_decoration_manager) return; - impl->display_server.server_decoration = + impl->server_decoration = org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager, - impl->display_server.wl_surface); - if (impl->display_server.server_decoration) - org_kde_kwin_server_decoration_request_mode (impl->display_server.server_decoration, + GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface); + if (impl->server_decoration) + org_kde_kwin_server_decoration_request_mode (impl->server_decoration, ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT); } @@ -962,18 +963,18 @@ void gdk_wayland_toplevel_announce_ssd (GdkToplevel *toplevel) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel))); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (toplevel); g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); if (!display_wayland->server_decoration_manager) return; - impl->display_server.server_decoration = + impl->server_decoration = org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager, - impl->display_server.wl_surface); - if (impl->display_server.server_decoration) - org_kde_kwin_server_decoration_request_mode (impl->display_server.server_decoration, - ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER); + GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface); + if (impl->server_decoration) + org_kde_kwin_server_decoration_request_mode (impl->server_decoration, + ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER); } -- GitLab From 217a9d9c3b4efc50d5f0e2d28953b16b30c8dcfb Mon Sep 17 00:00:00 2001 From: David Keijser Date: Tue, 22 Dec 2020 19:07:20 +0100 Subject: [PATCH 23/36] wayland: Move gtk_surface & application to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.c | 26 -------- gdk/wayland/gdksurface-wayland.h | 12 ---- gdk/wayland/gdktoplevel-wayland.c | 100 +++++++++++++++++++++--------- 3 files changed, 69 insertions(+), 69 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index ecdd78e97bd..3599e2c3d0d 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -753,13 +753,6 @@ gdk_wayland_surface_finalize (GObject *object) impl = GDK_WAYLAND_SURFACE (object); - g_free (impl->application.application_id); - g_free (impl->application.app_menu_path); - g_free (impl->application.menubar_path); - g_free (impl->application.window_object_path); - g_free (impl->application.application_object_path); - g_free (impl->application.unique_bus_name); - g_clear_pointer (&impl->opaque_region, cairo_region_destroy); g_clear_pointer (&impl->input_region, cairo_region_destroy); g_clear_pointer (&impl->shortcuts_inhibitors, g_hash_table_unref); @@ -2036,17 +2029,6 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) impl->popup_state = POPUP_STATE_IDLE; } - if (impl->display_server.gtk_surface) - { - if (display_wayland->gtk_shell_version >= - GTK_SURFACE1_RELEASE_SINCE_VERSION) - gtk_surface1_release (impl->display_server.gtk_surface); - else - gtk_surface1_destroy (impl->display_server.gtk_surface); - impl->display_server.gtk_surface = NULL; - impl->application.was_set = FALSE; - } - wl_surface_destroy (impl->display_server.wl_surface); impl->display_server.wl_surface = NULL; @@ -2650,14 +2632,6 @@ gdk_wayland_surface_get_dummy_egl_surface (GdkSurface *surface, return impl->dummy_egl_surface; } -struct gtk_surface1 * -gdk_wayland_surface_get_gtk_surface (GdkSurface *surface) -{ - g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); - - return GDK_WAYLAND_SURFACE (surface)->display_server.gtk_surface; -} - void _gdk_wayland_surface_offset_next_wl_buffer (GdkSurface *surface, int x, diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 63dbce0134d..f559d3125dd 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -49,7 +49,6 @@ struct _GdkWaylandSurface struct zxdg_surface_v6 *zxdg_surface_v6; struct zxdg_popup_v6 *zxdg_popup_v6; - struct gtk_surface1 *gtk_surface; struct wl_egl_window *egl_window; struct wl_egl_window *dummy_egl_window; } display_server; @@ -74,17 +73,6 @@ struct _GdkWaylandSurface int pending_buffer_offset_x; int pending_buffer_offset_y; - struct { - gboolean was_set; - - char *application_id; - char *app_menu_path; - char *menubar_path; - char *window_object_path; - char *application_object_path; - char *unique_bus_name; - } application; - GdkSeat *grab_input_seat; gint64 pending_frame_counter; diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index bba92de832c..476c1a2fcde 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -60,6 +60,7 @@ struct _GdkWaylandToplevel struct zxdg_toplevel_v6 *zxdg_toplevel_v6; struct zxdg_exported_v1 *xdg_exported; struct org_kde_kwin_server_decoration *server_decoration; + struct gtk_surface1 *gtk_surface; struct zxdg_imported_v1 *imported_transient_for; char *title; @@ -78,6 +79,17 @@ struct _GdkWaylandToplevel GdkToplevelLayout *layout; + struct { + gboolean was_set; + + char *application_id; + char *app_menu_path; + char *menubar_path; + char *window_object_path; + char *application_object_path; + char *unique_bus_name; + } application; + struct { GdkToplevelState unset_flags; GdkToplevelState set_flags; @@ -112,7 +124,7 @@ G_DEFINE_TYPE_WITH_CODE (GdkWaylandToplevel, gdk_wayland_toplevel, GDK_TYPE_WAYL gdk_wayland_toplevel_iface_init)) static void gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface); -static void maybe_set_gtk_surface_dbus_properties (GdkWaylandSurface *impl); +static void maybe_set_gtk_surface_dbus_properties (GdkWaylandToplevel *impl); static void maybe_set_gtk_surface_modal (GdkSurface *surface); static void @@ -202,6 +214,14 @@ gdk_wayland_toplevel_finalize (GObject *object) gdk_wayland_toplevel_unexport_handle (GDK_TOPLEVEL (impl)); g_free (impl->title); + + g_free (impl->application.application_id); + g_free (impl->application.app_menu_path); + g_free (impl->application.menubar_path); + g_free (impl->application.window_object_path); + g_free (impl->application.application_object_path); + g_free (impl->application.unique_bus_name); + G_OBJECT_CLASS(gdk_wayland_toplevel_parent_class)->finalize (object); } @@ -925,7 +945,7 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) impl->initial_fullscreen_output = NULL; - app_id = wlsurface->application.application_id; + app_id = impl->application.application_id; if (app_id == NULL) app_id = g_get_prgname (); @@ -934,7 +954,7 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) gdk_wayland_toplevel_set_application_id (GDK_TOPLEVEL (impl), app_id); - maybe_set_gtk_surface_dbus_properties (wlsurface); + maybe_set_gtk_surface_dbus_properties (impl); maybe_set_gtk_surface_modal (surface); gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit"); @@ -1021,9 +1041,9 @@ static void gdk_wayland_surface_focus (GdkSurface *surface, guint32 timestamp) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); - if (!impl->display_server.gtk_surface) + if (!impl->gtk_surface) return; if (timestamp == GDK_CURRENT_TIME) @@ -1037,11 +1057,11 @@ gdk_wayland_surface_focus (GdkSurface *surface, { xdg_activation_v1_activate (display_wayland->xdg_activation, display_wayland->startup_notification_id, - impl->display_server.wl_surface); + GDK_WAYLAND_SURFACE (impl)->display_server.wl_surface); } else if (display_wayland->gtk_shell_version >= 3) { - gtk_surface1_request_focus (impl->display_server.gtk_surface, + gtk_surface1_request_focus (impl->gtk_surface, display_wayland->startup_notification_id); } @@ -1049,7 +1069,7 @@ gdk_wayland_surface_focus (GdkSurface *surface, } } else - gtk_surface1_present (impl->display_server.gtk_surface, timestamp); + gtk_surface1_present (impl->gtk_surface, timestamp); } static void @@ -1137,28 +1157,27 @@ static const struct gtk_surface1_listener gtk_surface_listener = { }; static void -gdk_wayland_surface_init_gtk_surface (GdkWaylandSurface *impl) +gdk_wayland_surface_init_gtk_surface (GdkWaylandToplevel *impl) { - GdkWaylandToplevel *toplevel = GDK_WAYLAND_TOPLEVEL (impl); GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (impl))); - if (impl->display_server.gtk_surface != NULL) + if (impl->gtk_surface != NULL) return; - if (!is_realized_toplevel (GDK_WAYLAND_TOPLEVEL(impl))) + if (!is_realized_toplevel (impl)) return; if (display->gtk_shell == NULL) return; - impl->display_server.gtk_surface = + impl->gtk_surface = gtk_shell1_get_gtk_surface (display->gtk_shell, - impl->display_server.wl_surface); - wl_proxy_set_queue ((struct wl_proxy *) impl->display_server.gtk_surface, - impl->event_queue); - gdk_wayland_surface_set_geometry_hints (impl, - &toplevel->geometry_hints, - toplevel->geometry_mask); - gtk_surface1_add_listener (impl->display_server.gtk_surface, + GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface); + wl_proxy_set_queue ((struct wl_proxy *) impl->gtk_surface, + GDK_WAYLAND_SURFACE(impl)->event_queue); + gdk_wayland_surface_set_geometry_hints (GDK_WAYLAND_SURFACE(impl), + &impl->geometry_hints, + impl->geometry_mask); + gtk_surface1_add_listener (impl->gtk_surface, >k_surface_listener, impl); } @@ -1166,16 +1185,16 @@ gdk_wayland_surface_init_gtk_surface (GdkWaylandSurface *impl) static void maybe_set_gtk_surface_modal (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); gdk_wayland_surface_init_gtk_surface (impl); - if (impl->display_server.gtk_surface == NULL) + if (impl->gtk_surface == NULL) return; if (surface->modal_hint) - gtk_surface1_set_modal (impl->display_server.gtk_surface); + gtk_surface1_set_modal (impl->gtk_surface); else - gtk_surface1_unset_modal (impl->display_server.gtk_surface); + gtk_surface1_unset_modal (impl->gtk_surface); } @@ -1740,8 +1759,8 @@ gdk_wayland_surface_show_window_menu (GdkSurface *surface, static gboolean gdk_wayland_surface_supports_edge_constraints (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - struct gtk_surface1 *gtk_surface = impl->display_server.gtk_surface; + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); + struct gtk_surface1 *gtk_surface = impl->gtk_surface; if (!gtk_surface) return FALSE; @@ -1749,8 +1768,16 @@ gdk_wayland_surface_supports_edge_constraints (GdkSurface *surface) return gtk_surface1_get_version (gtk_surface) >= GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION; } +struct gtk_surface1 * +gdk_wayland_surface_get_gtk_surface (GdkSurface *surface) +{ + g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (surface), NULL); + + return GDK_WAYLAND_TOPLEVEL (surface)->gtk_surface; +} + static void -maybe_set_gtk_surface_dbus_properties (GdkWaylandSurface *impl) +maybe_set_gtk_surface_dbus_properties (GdkWaylandToplevel *impl) { if (impl->application.was_set) return; @@ -1764,10 +1791,10 @@ maybe_set_gtk_surface_dbus_properties (GdkWaylandSurface *impl) return; gdk_wayland_surface_init_gtk_surface (impl); - if (impl->display_server.gtk_surface == NULL) + if (impl->gtk_surface == NULL) return; - gtk_surface1_set_dbus_properties (impl->display_server.gtk_surface, + gtk_surface1_set_dbus_properties (impl->gtk_surface, impl->application.application_id, impl->application.app_menu_path, impl->application.menubar_path, @@ -1786,11 +1813,11 @@ gdk_wayland_toplevel_set_dbus_properties (GdkToplevel *toplevel, const char *application_object_path, const char *unique_bus_name) { - GdkWaylandSurface *impl; + GdkWaylandToplevel *impl; g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel)); - impl = GDK_WAYLAND_SURFACE (toplevel); + impl = GDK_WAYLAND_TOPLEVEL (toplevel); impl->application.application_id = g_strdup (application_id); impl->application.app_menu_path = g_strdup (app_menu_path); @@ -2189,6 +2216,7 @@ gdk_wayland_surface_map_toplevel (GdkSurface *surface) static void gdk_wayland_toplevel_hide (GdkSurface *surface) { + GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); GDK_SURFACE_CLASS (gdk_wayland_toplevel_parent_class)->hide (surface); @@ -2203,6 +2231,16 @@ gdk_wayland_toplevel_hide (GdkSurface *surface) { zxdg_toplevel_v6_destroy (impl->zxdg_toplevel_v6); impl->zxdg_toplevel_v6 = NULL; } + if (impl->gtk_surface) + { + if (display_wayland->gtk_shell_version >= + GTK_SURFACE1_RELEASE_SINCE_VERSION) + gtk_surface1_release (impl->gtk_surface); + else + gtk_surface1_destroy (impl->gtk_surface); + impl->gtk_surface = NULL; + impl->application.was_set = FALSE; + } gdk_wayland_surface_clear_saved_size (surface); -- GitLab From 51f1fe80423d8e6b448f4c57b103cdb390f9266c Mon Sep 17 00:00:00 2001 From: David Keijser Date: Wed, 23 Dec 2020 18:55:55 +0100 Subject: [PATCH 24/36] wayland: Add private configured_width/height for GdkWaylandToplevel The one in GdkWaylandSurface is only used by drag/popup specific code --- gdk/wayland/gdktoplevel-wayland.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 476c1a2fcde..c04ba80f4e8 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -105,6 +105,8 @@ struct _GdkWaylandToplevel struct { gboolean should_constrain; gboolean size_is_fixed; + int configured_width; + int configured_height; } next_layout; struct { @@ -396,14 +398,14 @@ configure_toplevel_geometry (GdkSurface *surface) wlsurface->shadow_bottom = size.shadow.bottom; } - if (wlsurface->next_layout.configured_width > 0 && - wlsurface->next_layout.configured_height > 0) + if (impl->next_layout.configured_width > 0 && + impl->next_layout.configured_height > 0) { int width, height; - width = wlsurface->next_layout.configured_width + + width = impl->next_layout.configured_width + wlsurface->shadow_left + wlsurface->shadow_right; - height = wlsurface->next_layout.configured_height + + height = impl->next_layout.configured_height + wlsurface->shadow_top + wlsurface->shadow_bottom; if (impl->next_layout.should_constrain) @@ -418,8 +420,8 @@ configure_toplevel_geometry (GdkSurface *surface) if (!impl->next_layout.size_is_fixed) { impl->next_layout.should_constrain = FALSE; - wlsurface->next_layout.configured_width = 0; - wlsurface->next_layout.configured_height = 0; + impl->next_layout.configured_width = 0; + impl->next_layout.configured_height = 0; } } else @@ -533,15 +535,15 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface) } impl->next_layout.size_is_fixed = fixed_size; - GDK_WAYLAND_SURFACE(impl)->next_layout.configured_width = width; - GDK_WAYLAND_SURFACE(impl)->next_layout.configured_height = height; + impl->next_layout.configured_width = width; + impl->next_layout.configured_height = height; } else { impl->next_layout.should_constrain = FALSE; impl->next_layout.size_is_fixed = FALSE; - GDK_WAYLAND_SURFACE(impl)->next_layout.configured_width = 0; - GDK_WAYLAND_SURFACE(impl)->next_layout.configured_height = 0; + impl->next_layout.configured_width = 0; + impl->next_layout.configured_height = 0; } gdk_surface_request_layout (surface); -- GitLab From 1aafc6178b6606ddc872a79e1444d1355ebcd991 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Wed, 23 Dec 2020 19:56:35 +0100 Subject: [PATCH 25/36] wayland: Add private shadow_* properties to GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.c | 14 +++++++--- gdk/wayland/gdksurface-wayland.h | 1 + gdk/wayland/gdktoplevel-wayland.c | 44 ++++++++++++++++++++++--------- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 3599e2c3d0d..efb3aa64b5e 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -810,9 +810,9 @@ gdk_wayland_surface_maybe_resize (GdkSurface *surface, gdk_wayland_surface_show (surface, FALSE); } -void -gdk_wayland_surface_get_window_geometry (GdkSurface *surface, - GdkRectangle *geometry) +static void +gdk_wayland_surface_get_window_geometry_real (GdkSurface *surface, + GdkRectangle *geometry) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); @@ -824,6 +824,13 @@ gdk_wayland_surface_get_window_geometry (GdkSurface *surface, }; } +void +gdk_wayland_surface_get_window_geometry (GdkSurface *surface, + GdkRectangle *geometry) +{ + GDK_WAYLAND_SURFACE_GET_CLASS(surface)->get_window_geometry(surface, geometry); +} + static void gdk_wayland_surface_sync_shadow (GdkSurface *surface) { @@ -2524,6 +2531,7 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass) impl_class->compute_size = gdk_wayland_surface_compute_size; klass->sync = gdk_wayland_surface_sync_real; + klass->get_window_geometry = gdk_wayland_surface_get_window_geometry_real; } void diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index f559d3125dd..8fdfaa8f35d 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -138,6 +138,7 @@ struct _GdkWaylandSurfaceClass { GdkSurfaceClass parent_class; void (*sync) (GdkSurface*); + void (*get_window_geometry) (GdkSurface*, GdkRectangle*); }; #define GDK_WAYLAND_SURFACE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), GDK_TYPE_WAYLAND_SURFACE, GdkWaylandSurfaceClass)) diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index c04ba80f4e8..76b4815a906 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -77,6 +77,11 @@ struct _GdkWaylandToplevel GdkGeometry geometry_hints; GdkSurfaceHints geometry_mask; + int shadow_left; + int shadow_right; + int shadow_top; + int shadow_bottom; + GdkToplevelLayout *layout; struct { @@ -156,7 +161,6 @@ static void _gdk_wayland_surface_save_size (GdkSurface *surface) { GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); - GdkWaylandSurface *wlsurface = GDK_WAYLAND_SURFACE (surface); if (surface->state & (GDK_TOPLEVEL_STATE_FULLSCREEN | GDK_TOPLEVEL_STATE_MAXIMIZED | @@ -166,8 +170,8 @@ _gdk_wayland_surface_save_size (GdkSurface *surface) if (surface->width <= 1 || surface->height <= 1) return; - impl->saved_width = surface->width - wlsurface->shadow_left - wlsurface->shadow_right; - impl->saved_height = surface->height - wlsurface->shadow_top - wlsurface->shadow_bottom; + impl->saved_width = surface->width - impl->shadow_left - impl->shadow_right; + impl->saved_height = surface->height - impl->shadow_top - impl->shadow_bottom; } static void @@ -329,6 +333,19 @@ gdk_wayland_surface_sync_title (GdkSurface *surface) } } +static void +gdk_wayland_toplevel_get_window_geometry (GdkSurface *surface, + GdkRectangle *geometry) +{ + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); + + *geometry = (GdkRectangle) { + .x = impl->shadow_left, + .y = impl->shadow_top, + .width = surface->width - (impl->shadow_left + impl->shadow_right), + .height = surface->height - (impl->shadow_top + impl->shadow_bottom) + }; +} static void gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl, const GdkGeometry *geometry, @@ -392,10 +409,10 @@ configure_toplevel_geometry (GdkSurface *surface) if (size.shadow.is_valid) { - wlsurface->shadow_left = size.shadow.left; - wlsurface->shadow_right = size.shadow.right; - wlsurface->shadow_top = size.shadow.top; - wlsurface->shadow_bottom = size.shadow.bottom; + impl->shadow_left = size.shadow.left; + impl->shadow_right = size.shadow.right; + impl->shadow_top = size.shadow.top; + impl->shadow_bottom = size.shadow.bottom; } if (impl->next_layout.configured_width > 0 && @@ -404,9 +421,9 @@ configure_toplevel_geometry (GdkSurface *surface) int width, height; width = impl->next_layout.configured_width + - wlsurface->shadow_left + wlsurface->shadow_right; + impl->shadow_left + impl->shadow_right; height = impl->next_layout.configured_height + - wlsurface->shadow_top + wlsurface->shadow_bottom; + impl->shadow_top + impl->shadow_bottom; if (impl->next_layout.should_constrain) { @@ -1233,9 +1250,9 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *surface, if (geom_mask & GDK_HINT_MIN_SIZE) { min_width = MAX (0, (geometry->min_width - - (surface->shadow_left + surface->shadow_right))); + (impl->shadow_left + impl->shadow_right))); min_height = MAX (0, (geometry->min_height - - (surface->shadow_top + surface->shadow_bottom))); + (impl->shadow_top + impl->shadow_bottom))); } else { @@ -1246,9 +1263,9 @@ gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *surface, if (geom_mask & GDK_HINT_MAX_SIZE) { max_width = MAX (0, (geometry->max_width - - (surface->shadow_left + surface->shadow_right))); + (impl->shadow_left + impl->shadow_right))); max_height = MAX (0, (geometry->max_height - - (surface->shadow_top + surface->shadow_bottom))); + (impl->shadow_top + impl->shadow_bottom))); } else { @@ -2181,6 +2198,7 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class) surface_class->hide = gdk_wayland_toplevel_hide; wayland_surface_class->sync = gdk_wayland_toplevel_sync; + wayland_surface_class->get_window_geometry = gdk_wayland_toplevel_get_window_geometry; gdk_toplevel_install_properties (object_class, 1); } -- GitLab From 71f4e064bd88427151932f35188f7b851bdc81ad Mon Sep 17 00:00:00 2001 From: David Keijser Date: Wed, 23 Dec 2020 20:22:24 +0100 Subject: [PATCH 26/36] wayland: Remove some duplicated functions from GdkWaylandToplevel --- gdk/wayland/gdksurface-wayland.c | 24 ++++++++++++++----- gdk/wayland/gdksurface-wayland.h | 4 ++++ gdk/wayland/gdktoplevel-wayland.c | 39 +------------------------------ 3 files changed, 23 insertions(+), 44 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index efb3aa64b5e..d4933000fb3 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -118,8 +118,6 @@ static void gdk_wayland_surface_maybe_resize (GdkSurface *surface, int height, int scale); -static void gdk_wayland_surface_configure (GdkSurface *surface); - static void gdk_wayland_surface_sync_shadow (GdkSurface *surface); static void gdk_wayland_surface_sync_input_region (GdkSurface *surface); static void gdk_wayland_surface_sync_opaque_region (GdkSurface *surface); @@ -1074,6 +1072,22 @@ maybe_notify_mapped (GdkSurface *surface) } static void +gdk_wayland_surface_configure_surface_real (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + if (is_realized_popup (impl)) + gdk_wayland_surface_configure_popup (surface); + else + g_warn_if_reached (); +} + +static void +gdk_wayland_surface_configure_surface (GdkSurface *surface) +{ + GDK_WAYLAND_SURFACE_GET_CLASS(surface)->configure_surface(surface); +} + +void gdk_wayland_surface_configure (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); @@ -1088,10 +1102,7 @@ gdk_wayland_surface_configure (GdkSurface *surface) impl->has_uncommitted_ack_configure = TRUE; - if (is_realized_popup (impl)) - gdk_wayland_surface_configure_popup (surface); - else - g_warn_if_reached (); + gdk_wayland_surface_configure_surface (surface); impl->last_configure_serial = impl->pending.serial; @@ -2532,6 +2543,7 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass) klass->sync = gdk_wayland_surface_sync_real; klass->get_window_geometry = gdk_wayland_surface_get_window_geometry_real; + klass->configure_surface = gdk_wayland_surface_configure_surface_real; } void diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 8fdfaa8f35d..1312a76a276 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -139,6 +139,7 @@ struct _GdkWaylandSurfaceClass GdkSurfaceClass parent_class; void (*sync) (GdkSurface*); void (*get_window_geometry) (GdkSurface*, GdkRectangle*); + void (*configure_surface) (GdkSurface*); }; #define GDK_WAYLAND_SURFACE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), GDK_TYPE_WAYLAND_SURFACE, GdkWaylandSurfaceClass)) @@ -176,4 +177,7 @@ gdk_wayland_surface_update_size (GdkSurface *surface, int height, int scale); +void +gdk_wayland_surface_configure (GdkSurface *surface); + G_END_DECLS diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 76b4815a906..6814d2704e4 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -618,44 +618,6 @@ gdk_wayland_surface_handle_close (GdkSurface *surface) _gdk_wayland_display_deliver_event (display, event); } - -// DUPLICATED -static void -maybe_notify_mapped (GdkSurface *surface) -{ - if (surface->destroyed) - return; - - if (!GDK_SURFACE_IS_MAPPED (surface)) - gdk_surface_set_is_mapped (surface, TRUE); -} - -// DUPLICATED -static void -gdk_wayland_surface_configure (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - if (!impl->initial_configure_received) - { - gdk_surface_thaw_updates (surface); - impl->initial_configure_received = TRUE; - impl->pending.is_initial_configure = TRUE; - maybe_notify_mapped (surface); - } - - impl->has_uncommitted_ack_configure = TRUE; - - if (is_realized_toplevel (GDK_WAYLAND_TOPLEVEL(impl))) - gdk_wayland_surface_configure_toplevel (surface); - else - g_warn_if_reached (); - - impl->last_configure_serial = impl->pending.serial; - - memset (&impl->pending, 0, sizeof (impl->pending)); -} - static void gdk_wayland_surface_handle_configure (GdkSurface *surface, uint32_t serial) @@ -2199,6 +2161,7 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class) wayland_surface_class->sync = gdk_wayland_toplevel_sync; wayland_surface_class->get_window_geometry = gdk_wayland_toplevel_get_window_geometry; + wayland_surface_class->configure_surface = gdk_wayland_surface_configure_toplevel; gdk_toplevel_install_properties (object_class, 1); } -- GitLab From dcdf0f45dc6086ed66c0013a8a7584b618aff3d8 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Wed, 23 Dec 2020 23:23:25 +0100 Subject: [PATCH 27/36] wayland: Remove duplicated setup of xdg surface listener --- gdk/wayland/gdksurface-wayland.c | 6 ++- gdk/wayland/gdksurface-wayland.h | 6 +-- gdk/wayland/gdktoplevel-wayland.c | 76 ------------------------------- 3 files changed, 7 insertions(+), 81 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index d4933000fb3..75530866b5b 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -118,6 +118,8 @@ static void gdk_wayland_surface_maybe_resize (GdkSurface *surface, int height, int scale); +static void gdk_wayland_surface_configure (GdkSurface *surface); + static void gdk_wayland_surface_sync_shadow (GdkSurface *surface); static void gdk_wayland_surface_sync_input_region (GdkSurface *surface); static void gdk_wayland_surface_sync_opaque_region (GdkSurface *surface); @@ -1087,7 +1089,7 @@ gdk_wayland_surface_configure_surface (GdkSurface *surface) GDK_WAYLAND_SURFACE_GET_CLASS(surface)->configure_surface(surface); } -void +static void gdk_wayland_surface_configure (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); @@ -1152,7 +1154,7 @@ static const struct zxdg_surface_v6_listener zxdg_surface_v6_listener = { zxdg_surface_v6_configure, }; -static void +void gdk_wayland_surface_create_xdg_surface_resources (GdkSurface *surface) { GdkWaylandDisplay *display = diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 1312a76a276..203335f3758 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -168,6 +168,9 @@ void gdk_wayland_surface_show (GdkSurface *surface, gboolean already_mapped); +void +gdk_wayland_surface_create_xdg_surface_resources (GdkSurface *surface); + void gdk_wayland_surface_get_window_geometry (GdkSurface *surface, GdkRectangle *geometry); @@ -177,7 +180,4 @@ gdk_wayland_surface_update_size (GdkSurface *surface, int height, int scale); -void -gdk_wayland_surface_configure (GdkSurface *surface); - G_END_DECLS diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 6814d2704e4..cbc1f7875bb 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -618,82 +618,6 @@ gdk_wayland_surface_handle_close (GdkSurface *surface) _gdk_wayland_display_deliver_event (display, event); } -static void -gdk_wayland_surface_handle_configure (GdkSurface *surface, - uint32_t serial) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - impl->pending.is_dirty = TRUE; - impl->pending.serial = serial; - - if (impl->state_freeze_count > 0) - return; - - gdk_wayland_surface_configure (surface); -} - -static void -xdg_surface_configure (void *data, - struct xdg_surface *xdg_surface, - uint32_t serial) -{ - GdkSurface *surface = GDK_SURFACE (data); - - gdk_wayland_surface_handle_configure (surface, serial); -} - -static const struct xdg_surface_listener xdg_surface_listener = { - xdg_surface_configure, -}; - -static void -zxdg_surface_v6_configure (void *data, - struct zxdg_surface_v6 *xdg_surface, - uint32_t serial) -{ - GdkSurface *surface = GDK_SURFACE (data); - - gdk_wayland_surface_handle_configure (surface, serial); -} - -static const struct zxdg_surface_v6_listener zxdg_surface_v6_listener = { - zxdg_surface_v6_configure, -}; - -// DUPLICATED -static void -gdk_wayland_surface_create_xdg_surface_resources (GdkSurface *surface) -{ - GdkWaylandDisplay *display = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - switch (display->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - impl->display_server.xdg_surface = - xdg_wm_base_get_xdg_surface (display->xdg_wm_base, - impl->display_server.wl_surface); - wl_proxy_set_queue ((struct wl_proxy *) impl->display_server.xdg_surface, - impl->event_queue); - xdg_surface_add_listener (impl->display_server.xdg_surface, - &xdg_surface_listener, - surface); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - impl->display_server.zxdg_surface_v6 = - zxdg_shell_v6_get_xdg_surface (display->zxdg_shell_v6, - impl->display_server.wl_surface); - zxdg_surface_v6_add_listener (impl->display_server.zxdg_surface_v6, - &zxdg_surface_v6_listener, - surface); - break; - default: - g_assert_not_reached (); - } -} - static void xdg_toplevel_configure (void *data, struct xdg_toplevel *xdg_toplevel, -- GitLab From 38bb266857fddb4ecc7699d94025ec95f4e10799 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Wed, 23 Dec 2020 23:33:11 +0100 Subject: [PATCH 28/36] wayland: Move xdg configure ack to gdk_wayland_surface_configure --- gdk/wayland/gdksurface-wayland.c | 27 ++++++++++++++++----------- gdk/wayland/gdktoplevel-wayland.c | 16 ---------------- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index 75530866b5b..e2d1938053d 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -1009,17 +1009,6 @@ gdk_wayland_surface_configure_popup (GdkSurface *surface) GdkRectangle parent_geometry; int x, y, width, height; - if (impl->display_server.xdg_popup) - { - xdg_surface_ack_configure (impl->display_server.xdg_surface, - impl->pending.serial); - } - else if (impl->display_server.zxdg_popup_v6) - { - zxdg_surface_v6_ack_configure (impl->display_server.zxdg_surface_v6, - impl->pending.serial); - } - if (impl->pending.popup.has_repositioned_token) impl->received_reposition_token = impl->pending.popup.repositioned_token; @@ -1092,6 +1081,8 @@ gdk_wayland_surface_configure_surface (GdkSurface *surface) static void gdk_wayland_surface_configure (GdkSurface *surface) { + GdkWaylandDisplay *display_wayland = + GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); if (!impl->initial_configure_received) @@ -1106,6 +1097,20 @@ gdk_wayland_surface_configure (GdkSurface *surface) gdk_wayland_surface_configure_surface (surface); + switch (display_wayland->shell_variant) + { + case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: + xdg_surface_ack_configure (GDK_WAYLAND_SURFACE(impl)->display_server.xdg_surface, + GDK_WAYLAND_SURFACE(impl)->pending.serial); + break; + case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: + zxdg_surface_v6_ack_configure (GDK_WAYLAND_SURFACE(impl)->display_server.zxdg_surface_v6, + GDK_WAYLAND_SURFACE(impl)->pending.serial); + break; + default: + g_assert_not_reached (); + } + impl->last_configure_serial = impl->pending.serial; memset (&impl->pending, 0, sizeof (impl->pending)); diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index cbc1f7875bb..103621f16ec 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -495,8 +495,6 @@ static void gdk_wayland_surface_configure_toplevel (GdkSurface *surface) { GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); - GdkWaylandDisplay *display_wayland = - GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkToplevelState new_state; int width, height; gboolean is_resizing; @@ -574,20 +572,6 @@ gdk_wayland_surface_configure_toplevel (GdkSurface *surface) (new_state & GDK_TOPLEVEL_STATE_TILED) ? " tiled" : "")); gdk_surface_queue_state_change (surface, ~0 & ~new_state, new_state); - - switch (display_wayland->shell_variant) - { - case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_surface_ack_configure (GDK_WAYLAND_SURFACE(impl)->display_server.xdg_surface, - GDK_WAYLAND_SURFACE(impl)->pending.serial); - break; - case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_surface_v6_ack_configure (GDK_WAYLAND_SURFACE(impl)->display_server.zxdg_surface_v6, - GDK_WAYLAND_SURFACE(impl)->pending.serial); - break; - default: - g_assert_not_reached (); - } } static void -- GitLab From 7ddd396f0b0ef03d558396a066677aec6d8f85c2 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Sat, 26 Dec 2020 12:17:00 +0100 Subject: [PATCH 29/36] wayland: Use gdk_wayland_surface_get_wl_surface in GdkWaylandToplevel --- gdk/wayland/gdktoplevel-wayland.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 103621f16ec..06286100d96 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -252,7 +252,7 @@ gdk_wayland_surface_sync_parent (GdkSurface *surface, impl_parent = GDK_WAYLAND_TOPLEVEL (parent); /* XXX: Is this correct? */ - if (impl_parent && !GDK_WAYLAND_SURFACE(impl_parent)->display_server.wl_surface) + if (impl_parent && !gdk_wayland_surface_get_wl_surface (surface)) return; switch (display_wayland->shell_variant) @@ -292,7 +292,7 @@ gdk_wayland_surface_sync_parent (GdkSurface *surface, static void gdk_wayland_surface_sync_parent_of_imported (GdkWaylandToplevel *impl) { - if (!GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface) + if (!gdk_wayland_surface_get_wl_surface (GDK_SURFACE (impl))) return; if (!impl->imported_transient_for) @@ -302,7 +302,7 @@ gdk_wayland_surface_sync_parent_of_imported (GdkWaylandToplevel *impl) return; zxdg_imported_v1_set_parent_of (impl->imported_transient_for, - GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface); + gdk_wayland_surface_get_wl_surface (GDK_SURFACE(impl))); } static void @@ -786,7 +786,6 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); - GdkWaylandSurface *wlsurface = GDK_WAYLAND_SURFACE (surface); const char *app_id; gdk_surface_freeze_updates (surface); @@ -847,7 +846,7 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface) maybe_set_gtk_surface_modal (surface); gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit"); - wl_surface_commit (wlsurface->display_server.wl_surface); + wl_surface_commit (gdk_wayland_surface_get_wl_surface (surface)); } void @@ -862,7 +861,7 @@ gdk_wayland_toplevel_announce_csd (GdkToplevel *toplevel) return; impl->server_decoration = org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager, - GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface); + gdk_wayland_surface_get_wl_surface (GDK_SURFACE (impl))); if (impl->server_decoration) org_kde_kwin_server_decoration_request_mode (impl->server_decoration, ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT); @@ -880,7 +879,7 @@ gdk_wayland_toplevel_announce_ssd (GdkToplevel *toplevel) return; impl->server_decoration = org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager, - GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface); + gdk_wayland_surface_get_wl_surface (GDK_SURFACE(impl))); if (impl->server_decoration) org_kde_kwin_server_decoration_request_mode (impl->server_decoration, ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER); @@ -903,7 +902,7 @@ gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel) g_assert (impl->idle_inhibitor_refcount == 0); impl->idle_inhibitor = zwp_idle_inhibit_manager_v1_create_inhibitor (display_wayland->idle_inhibit_manager, - GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface); + gdk_wayland_surface_get_wl_surface (GDK_SURFACE (impl))); } ++impl->idle_inhibitor_refcount; @@ -946,7 +945,7 @@ gdk_wayland_surface_focus (GdkSurface *surface, { xdg_activation_v1_activate (display_wayland->xdg_activation, display_wayland->startup_notification_id, - GDK_WAYLAND_SURFACE (impl)->display_server.wl_surface); + gdk_wayland_surface_get_wl_surface (GDK_SURFACE (impl))); } else if (display_wayland->gtk_shell_version >= 3) { @@ -1060,7 +1059,7 @@ gdk_wayland_surface_init_gtk_surface (GdkWaylandToplevel *impl) impl->gtk_surface = gtk_shell1_get_gtk_surface (display->gtk_shell, - GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface); + gdk_wayland_surface_get_wl_surface (GDK_SURFACE (impl))); wl_proxy_set_queue ((struct wl_proxy *) impl->gtk_surface, GDK_WAYLAND_SURFACE(impl)->event_queue); gdk_wayland_surface_set_geometry_hints (GDK_WAYLAND_SURFACE(impl), @@ -1813,7 +1812,7 @@ gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel, } xdg_exported = zxdg_exporter_v1_export (display_wayland->xdg_exporter, - GDK_WAYLAND_SURFACE(impl)->display_server.wl_surface); + gdk_wayland_surface_get_wl_surface (GDK_SURFACE (impl))); zxdg_exported_v1_add_listener (xdg_exported, &xdg_exported_listener, impl); impl->xdg_exported = xdg_exported; -- GitLab From 14e5deafcc59804df69b1c1231697c61e79b064a Mon Sep 17 00:00:00 2001 From: David Keijser Date: Sat, 26 Dec 2020 12:25:13 +0100 Subject: [PATCH 30/36] wayland: Add acccessors for xdg/zxdg surface --- gdk/wayland/gdksurface-wayland.c | 16 ++++++++++++++++ gdk/wayland/gdksurface-wayland.h | 6 ++++++ gdk/wayland/gdktoplevel-wayland.c | 16 ++++------------ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index e2d1938053d..c3740ac9bd1 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -2596,6 +2596,22 @@ gdk_wayland_surface_get_wl_output (GdkSurface *surface) return NULL; } +struct xdg_surface * +gdk_wayland_surface_get_xdg_surface (GdkSurface *surface) +{ + g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); + + return GDK_WAYLAND_SURFACE (surface)->display_server.xdg_surface; +} + +struct zxdg_surface_v6 * +gdk_wayland_surface_get_zxdg_surface_v6 (GdkSurface *surface) +{ + g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); + + return GDK_WAYLAND_SURFACE (surface)->display_server.zxdg_surface_v6; +} + static struct wl_egl_window * gdk_wayland_surface_get_wl_egl_window (GdkSurface *surface) { diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 203335f3758..38a60e5a63f 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -180,4 +180,10 @@ gdk_wayland_surface_update_size (GdkSurface *surface, int height, int scale); +struct xdg_surface * +gdk_wayland_surface_get_xdg_surface (GdkSurface *surface); + +struct zxdg_surface_v6 * +gdk_wayland_surface_get_zxdg_surface_v6 (GdkSurface *surface); + G_END_DECLS diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 06286100d96..9a126dff468 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -143,13 +143,6 @@ gdk_wayland_toplevel_hide (GdkSurface *surface); static gboolean gdk_wayland_surface_is_exported (GdkWaylandToplevel *impl); static void unset_transient_for_exported (GdkSurface *surface); -static gboolean -is_realized_shell_surface (GdkWaylandSurface *impl) -{ - return (impl->display_server.xdg_surface || - impl->display_server.zxdg_surface_v6); -} - static gboolean is_realized_toplevel (GdkWaylandToplevel *impl) { @@ -355,14 +348,13 @@ static void gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface) { GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); - GdkWaylandSurface *wlsurface = GDK_WAYLAND_SURFACE (surface); GdkRectangle geometry; - if (!is_realized_shell_surface (wlsurface)) + if (!is_realized_toplevel (impl)) return; gdk_wayland_surface_get_window_geometry (surface, &geometry); - gdk_wayland_surface_set_geometry_hints (wlsurface, + gdk_wayland_surface_set_geometry_hints (GDK_WAYLAND_SURFACE (surface), &impl->geometry_hints, impl->geometry_mask); } @@ -664,7 +656,7 @@ create_xdg_toplevel_resources (GdkSurface *surface) GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); GDK_WAYLAND_TOPLEVEL(impl)->xdg_toplevel = - xdg_surface_get_toplevel (impl->display_server.xdg_surface); + xdg_surface_get_toplevel (gdk_wayland_surface_get_xdg_surface (surface)); xdg_toplevel_add_listener (GDK_WAYLAND_TOPLEVEL(impl)->xdg_toplevel, &xdg_toplevel_listener, surface); @@ -732,7 +724,7 @@ create_zxdg_toplevel_v6_resources (GdkSurface *surface) GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); GDK_WAYLAND_TOPLEVEL(impl)->zxdg_toplevel_v6 = - zxdg_surface_v6_get_toplevel (impl->display_server.zxdg_surface_v6); + zxdg_surface_v6_get_toplevel (gdk_wayland_surface_get_zxdg_surface_v6 (surface)); zxdg_toplevel_v6_add_listener (GDK_WAYLAND_TOPLEVEL(impl)->zxdg_toplevel_v6, &zxdg_toplevel_v6_listener, surface); -- GitLab From a52a7ff1198c562befc0ec4a877d2e60d66f5feb Mon Sep 17 00:00:00 2001 From: David Keijser Date: Sat, 26 Dec 2020 12:32:51 +0100 Subject: [PATCH 31/36] wayland: Use gdk_surface_get_scale_factor in GdkWaylandToplevel --- gdk/wayland/gdktoplevel-wayland.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 9a126dff468..0a3e682fe4a 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -363,7 +363,6 @@ static void configure_toplevel_geometry (GdkSurface *surface) { GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); - GdkWaylandSurface *wlsurface = GDK_WAYLAND_SURFACE (surface); GdkDisplay *display = gdk_surface_get_display (surface); GdkMonitor *monitor; GdkRectangle monitor_geometry; @@ -397,7 +396,7 @@ configure_toplevel_geometry (GdkSurface *surface) geometry.max_height = geometry.min_height = size.height; mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE; } - gdk_wayland_surface_set_geometry_hints (wlsurface, &geometry, mask); + gdk_wayland_surface_set_geometry_hints (GDK_WAYLAND_SURFACE (impl), &geometry, mask); if (size.shadow.is_valid) { @@ -424,7 +423,7 @@ configure_toplevel_geometry (GdkSurface *surface) width, height, &width, &height); } - gdk_wayland_surface_update_size (surface, width, height, wlsurface->scale); + gdk_wayland_surface_update_size (surface, width, height, gdk_surface_get_scale_factor (surface)); if (!impl->next_layout.size_is_fixed) { @@ -442,7 +441,7 @@ configure_toplevel_geometry (GdkSurface *surface) gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height); - gdk_wayland_surface_update_size (surface, width, height, wlsurface->scale); + gdk_wayland_surface_update_size (surface, width, height, gdk_surface_get_scale_factor (surface)); } } -- GitLab From 06bf1d17681e7c0b0ad2204870618ad3a963f9de Mon Sep 17 00:00:00 2001 From: David Keijser Date: Sat, 16 Jan 2021 15:16:35 +0100 Subject: [PATCH 32/36] wayland: Remove check for drag surface from GdkWaylandToplevel --- gdk/wayland/gdktoplevel-wayland.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 0a3e682fe4a..5a89f443dac 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -2064,29 +2064,11 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class) gdk_toplevel_install_properties (object_class, 1); } -static gboolean -should_be_mapped (GdkSurface *surface) -{ - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - - /* Don't map crazy temp that GTK uses for internal X11 shenanigans. */ - if (GDK_IS_DRAG_SURFACE (surface) && surface->x < 0 && surface->y < 0) - return FALSE; - - if (impl->is_drag_surface) - return FALSE; - - return TRUE; -} - static void gdk_wayland_surface_map_toplevel (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); - if (!should_be_mapped (surface)) - return; - if (impl->mapped) return; -- GitLab From 42b26b2afd530d697d26cffc5906a584dbc352d0 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Sat, 16 Jan 2021 15:20:11 +0100 Subject: [PATCH 33/36] wayland: Create private copy of mapped state for TopLevel Use in gdkwaylandsurface is all related to popup --- gdk/wayland/gdktoplevel-wayland.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 5a89f443dac..2effa79f07a 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -67,6 +67,8 @@ struct _GdkWaylandToplevel int saved_width; int saved_height; + unsigned int mapped : 1; + struct wl_output *initial_fullscreen_output; int last_sent_min_width; @@ -2067,7 +2069,7 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class) static void gdk_wayland_surface_map_toplevel (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); if (impl->mapped) return; @@ -2115,6 +2117,7 @@ gdk_wayland_toplevel_hide (GdkSurface *surface) { g_clear_pointer (&impl->layout, gdk_toplevel_layout_unref); unset_transient_for_exported (surface); + impl->mapped = FALSE; } static void -- GitLab From f32117e7a55267cf4c5442d5c705b6a69c635abf Mon Sep 17 00:00:00 2001 From: David Keijser Date: Sat, 16 Jan 2021 15:24:44 +0100 Subject: [PATCH 34/36] wayland: Add gdk_wayland_surface_get_event_queue --- gdk/wayland/gdksurface-wayland.c | 8 ++++++++ gdk/wayland/gdksurface-wayland.h | 3 +++ gdk/wayland/gdktoplevel-wayland.c | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index c3740ac9bd1..ff97e90f300 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -2612,6 +2612,14 @@ gdk_wayland_surface_get_zxdg_surface_v6 (GdkSurface *surface) return GDK_WAYLAND_SURFACE (surface)->display_server.zxdg_surface_v6; } +struct wl_event_queue * +gdk_wayland_surface_get_event_queue (GdkSurface *surface) +{ + g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); + + return GDK_WAYLAND_SURFACE (surface)->event_queue; +} + static struct wl_egl_window * gdk_wayland_surface_get_wl_egl_window (GdkSurface *surface) { diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 38a60e5a63f..0c73298fa6f 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -186,4 +186,7 @@ gdk_wayland_surface_get_xdg_surface (GdkSurface *surface); struct zxdg_surface_v6 * gdk_wayland_surface_get_zxdg_surface_v6 (GdkSurface *surface); +struct wl_event_queue * +gdk_wayland_surface_get_event_queue (GdkSurface *surface); + G_END_DECLS diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 2effa79f07a..835efeb9e02 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -1054,7 +1054,7 @@ gdk_wayland_surface_init_gtk_surface (GdkWaylandToplevel *impl) gtk_shell1_get_gtk_surface (display->gtk_shell, gdk_wayland_surface_get_wl_surface (GDK_SURFACE (impl))); wl_proxy_set_queue ((struct wl_proxy *) impl->gtk_surface, - GDK_WAYLAND_SURFACE(impl)->event_queue); + gdk_wayland_surface_get_event_queue (GDK_SURFACE (impl))); gdk_wayland_surface_set_geometry_hints (GDK_WAYLAND_SURFACE(impl), &impl->geometry_hints, impl->geometry_mask); -- GitLab From c88559bb74699ba577c94a2b21d3aa8a955ae8fb Mon Sep 17 00:00:00 2001 From: David Keijser Date: Sat, 16 Jan 2021 16:07:20 +0100 Subject: [PATCH 35/36] wayland: Add private copy of surface_geometry_dirty to toplevel --- gdk/wayland/gdktoplevel-wayland.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c index 835efeb9e02..5e43246803f 100644 --- a/gdk/wayland/gdktoplevel-wayland.c +++ b/gdk/wayland/gdktoplevel-wayland.c @@ -112,6 +112,7 @@ struct _GdkWaylandToplevel struct { gboolean should_constrain; gboolean size_is_fixed; + gboolean surface_geometry_dirty; int configured_width; int configured_height; } next_layout; @@ -451,7 +452,7 @@ configure_toplevel_geometry (GdkSurface *surface) static gboolean gdk_wayland_toplevel_compute_size (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); if (impl->next_layout.surface_geometry_dirty) { @@ -465,7 +466,7 @@ gdk_wayland_toplevel_compute_size (GdkSurface *surface) static void gdk_wayland_toplevel_request_layout (GdkSurface *surface) { - GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface); impl->next_layout.surface_geometry_dirty = TRUE; } -- GitLab From 50ae9dd76d7a839af5b7d5b4609aea8c6bd819c9 Mon Sep 17 00:00:00 2001 From: David Keijser Date: Sat, 16 Jan 2021 15:10:33 +0100 Subject: [PATCH 36/36] wayland: Add GdkWaylandSurfacePrivate --- gdk/wayland/gdksurface-wayland.c | 775 ++++++++++++++++++++----------- gdk/wayland/gdksurface-wayland.h | 104 ----- 2 files changed, 493 insertions(+), 386 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index ff97e90f300..7561a158945 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -72,9 +72,116 @@ #define SURFACE_IS_TOPLEVEL(surface) TRUE -G_DEFINE_TYPE (GdkWaylandSurface, gdk_wayland_surface, GDK_TYPE_SURFACE) +typedef enum _PopupState +{ + POPUP_STATE_IDLE, + POPUP_STATE_WAITING_FOR_REPOSITIONED, + POPUP_STATE_WAITING_FOR_CONFIGURE, + POPUP_STATE_WAITING_FOR_FRAME, +} PopupState; + +struct _GdkWaylandSurfacePrivate +{ + struct { + /* The wl_outputs that this surface currently touches */ + GSList *outputs; + + struct wl_surface *wl_surface; + + struct xdg_surface *xdg_surface; + struct xdg_popup *xdg_popup; + + /* Legacy xdg-shell unstable v6 fallback support */ + struct zxdg_surface_v6 *zxdg_surface_v6; + struct zxdg_popup_v6 *zxdg_popup_v6; + + struct wl_egl_window *egl_window; + struct wl_egl_window *dummy_egl_window; + } display_server; + + struct wl_event_queue *event_queue; + + EGLSurface egl_surface; + EGLSurface dummy_egl_surface; + + uint32_t reposition_token; + uint32_t received_reposition_token; + + PopupState popup_state; + + unsigned int initial_configure_received : 1; + unsigned int has_uncommitted_ack_configure : 1; + unsigned int mapped : 1; + unsigned int awaiting_frame : 1; + unsigned int awaiting_frame_frozen : 1; + unsigned int is_drag_surface : 1; + + int pending_buffer_offset_x; + int pending_buffer_offset_y; + + GdkSeat *grab_input_seat; + + gint64 pending_frame_counter; + guint32 scale; + + int shadow_left; + int shadow_right; + int shadow_top; + int shadow_bottom; + gboolean shadow_dirty; + + cairo_region_t *opaque_region; + gboolean opaque_region_dirty; + + cairo_region_t *input_region; + gboolean input_region_dirty; + + GdkRectangle last_sent_window_geometry; + + gulong parent_surface_committed_handler; + + struct { + GdkPopupLayout *layout; + int unconstrained_width; + int unconstrained_height; + } popup; + + struct { + struct { + int x; + int y; + int width; + int height; + uint32_t repositioned_token; + gboolean has_repositioned_token; + } popup; + gboolean is_initial_configure; + + uint32_t serial; + gboolean is_dirty; + } pending; + + struct { + struct { + int x; + int y; + } popup; + int configured_width; + int configured_height; + gboolean surface_geometry_dirty; + } next_layout; + + uint32_t last_configure_serial; + + int state_freeze_count; + + GHashTable *shortcuts_inhibitors; +}; +typedef struct _GdkWaylandSurfacePrivate GdkWaylandSurfacePrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (GdkWaylandSurface, gdk_wayland_surface, GDK_TYPE_SURFACE) struct _GdkWaylandPopup { @@ -141,34 +248,37 @@ static void update_popup_layout_state (GdkSurface *surface, static void gdk_wayland_surface_init (GdkWaylandSurface *impl) { - impl->scale = 1; - impl->shortcuts_inhibitors = g_hash_table_new (NULL, NULL); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); + priv->scale = 1; + priv->shortcuts_inhibitors = g_hash_table_new (NULL, NULL); } static void gdk_wayland_surface_freeze_state (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - impl->state_freeze_count++; + priv->state_freeze_count++; } static void gdk_wayland_surface_thaw_state (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - g_assert (impl->state_freeze_count > 0); + g_assert (priv->state_freeze_count > 0); - impl->state_freeze_count--; + priv->state_freeze_count--; - if (impl->state_freeze_count > 0) + if (priv->state_freeze_count > 0) return; - if (impl->pending.is_dirty) + if (priv->pending.is_dirty) gdk_wayland_surface_configure (surface); - g_assert (!impl->display_server.xdg_popup); + g_assert (!priv->display_server.xdg_popup); } void @@ -178,23 +288,24 @@ gdk_wayland_surface_update_size (GdkSurface *surface, int scale) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); gboolean width_changed, height_changed, scale_changed; width_changed = surface->width != width; height_changed = surface->height != height; - scale_changed = impl->scale != scale; + scale_changed = priv->scale != scale; if (!width_changed && !height_changed && !scale_changed) return; surface->width = width; surface->height = height; - impl->scale = scale; + priv->scale = scale; - if (impl->display_server.egl_window) - wl_egl_window_resize (impl->display_server.egl_window, width * scale, height * scale, 0, 0); - if (impl->display_server.wl_surface) - wl_surface_set_buffer_scale (impl->display_server.wl_surface, scale); + if (priv->display_server.egl_window) + wl_egl_window_resize (priv->display_server.egl_window, width * scale, height * scale, 0, 0); + if (priv->display_server.wl_surface) + wl_surface_set_buffer_scale (priv->display_server.wl_surface, scale); gdk_surface_invalidate_rect (surface, NULL); @@ -283,9 +394,10 @@ static void finish_pending_relayout (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - g_assert (impl->popup_state == POPUP_STATE_WAITING_FOR_FRAME); - impl->popup_state = POPUP_STATE_IDLE; + g_assert (priv->popup_state == POPUP_STATE_WAITING_FOR_FRAME); + priv->popup_state = POPUP_STATE_IDLE; thaw_popup_toplevel_state (surface); } @@ -297,6 +409,7 @@ frame_callback (void *data, { GdkSurface *surface = data; GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkFrameClock *clock = gdk_surface_get_frame_clock (surface); @@ -310,10 +423,10 @@ frame_callback (void *data, if (GDK_SURFACE_DESTROYED (surface)) return; - if (!impl->awaiting_frame) + if (!priv->awaiting_frame) return; - switch (impl->popup_state) + switch (priv->popup_state) { case POPUP_STATE_IDLE: case POPUP_STATE_WAITING_FOR_REPOSITIONED: @@ -326,27 +439,27 @@ frame_callback (void *data, g_assert_not_reached (); } - impl->awaiting_frame = FALSE; - if (impl->awaiting_frame_frozen) + priv->awaiting_frame = FALSE; + if (priv->awaiting_frame_frozen) { - impl->awaiting_frame_frozen = FALSE; + priv->awaiting_frame_frozen = FALSE; gdk_surface_thaw_updates (surface); } - timings = gdk_frame_clock_get_timings (clock, impl->pending_frame_counter); - impl->pending_frame_counter = 0; + timings = gdk_frame_clock_get_timings (clock, priv->pending_frame_counter); + priv->pending_frame_counter = 0; if (timings == NULL) return; timings->refresh_interval = 16667; /* default to 1/60th of a second */ - if (impl->display_server.outputs) + if (priv->display_server.outputs) { /* We pick a random output out of the outputs that the surface touches * The rate here is in milli-hertz */ int refresh_rate = gdk_wayland_display_get_output_refresh_rate (display_wayland, - impl->display_server.outputs->data); + priv->display_server.outputs->data); if (refresh_rate != 0) timings->refresh_interval = G_GINT64_CONSTANT(1000000000) / refresh_rate; } @@ -407,17 +520,18 @@ static void configure_popup_geometry (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); int x, y; int width, height; - x = impl->next_layout.popup.x - impl->shadow_left; - y = impl->next_layout.popup.y - impl->shadow_top; + x = priv->next_layout.popup.x - priv->shadow_left; + y = priv->next_layout.popup.y - priv->shadow_top; width = - impl->next_layout.configured_width + - (impl->shadow_left + impl->shadow_right); + priv->next_layout.configured_width + + (priv->shadow_left + priv->shadow_right); height = - impl->next_layout.configured_height + - (impl->shadow_top + impl->shadow_bottom); + priv->next_layout.configured_height + + (priv->shadow_top + priv->shadow_bottom); gdk_wayland_surface_move_resize (surface, x, y, width, height); } @@ -426,11 +540,12 @@ static void configure_drag_surface_geometry (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); gdk_wayland_surface_update_size (surface, - impl->next_layout.configured_width, - impl->next_layout.configured_height, - impl->scale); + priv->next_layout.configured_width, + priv->next_layout.configured_height, + priv->scale); } static void @@ -448,11 +563,12 @@ static gboolean gdk_wayland_surface_compute_size (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - if (impl->next_layout.surface_geometry_dirty) + if (priv->next_layout.surface_geometry_dirty) { gdk_wayland_surface_configure_geometry (surface); - impl->next_layout.surface_geometry_dirty = FALSE; + priv->next_layout.surface_geometry_dirty = FALSE; } return FALSE; @@ -462,51 +578,56 @@ static void gdk_wayland_surface_request_layout (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - impl->next_layout.surface_geometry_dirty = TRUE; + priv->next_layout.surface_geometry_dirty = TRUE; } void gdk_wayland_surface_request_frame (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); struct wl_callback *callback; GdkFrameClock *clock; - if (impl->awaiting_frame) + if (priv->awaiting_frame) return; clock = gdk_surface_get_frame_clock (surface); - callback = wl_surface_frame (impl->display_server.wl_surface); + callback = wl_surface_frame (priv->display_server.wl_surface); wl_proxy_set_queue ((struct wl_proxy *) callback, NULL); wl_callback_add_listener (callback, &frame_listener, surface); - impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock); - impl->awaiting_frame = TRUE; + priv->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock); + priv->awaiting_frame = TRUE; } gboolean gdk_wayland_surface_has_surface (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - return !!impl->display_server.wl_surface; + return !!priv->display_server.wl_surface; } void gdk_wayland_surface_commit (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - wl_surface_commit (impl->display_server.wl_surface); + wl_surface_commit (priv->display_server.wl_surface); } void gdk_wayland_surface_notify_committed (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - impl->has_uncommitted_ack_configure = FALSE; + priv->has_uncommitted_ack_configure = FALSE; } static void @@ -514,17 +635,18 @@ on_frame_clock_after_paint (GdkFrameClock *clock, GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - if (surface->update_freeze_count == 0 && impl->has_uncommitted_ack_configure) + if (surface->update_freeze_count == 0 && priv->has_uncommitted_ack_configure) { gdk_wayland_surface_commit (surface); gdk_wayland_surface_notify_committed (surface); } - if (impl->awaiting_frame && - impl->pending_frame_counter == gdk_frame_clock_get_frame_counter (clock)) + if (priv->awaiting_frame && + priv->pending_frame_counter == gdk_frame_clock_get_frame_counter (clock)) { - impl->awaiting_frame_frozen = TRUE; + priv->awaiting_frame_frozen = TRUE; gdk_surface_freeze_updates (surface); } } @@ -533,6 +655,7 @@ void gdk_wayland_surface_update_scale (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); guint32 scale; GSList *l; @@ -544,7 +667,7 @@ gdk_wayland_surface_update_scale (GdkSurface *surface) } scale = 1; - for (l = impl->display_server.outputs; l != NULL; l = l->next) + for (l = priv->display_server.outputs; l != NULL; l = l->next) { guint32 output_scale = gdk_wayland_display_get_output_scale (display_wayland, l->data); scale = MAX (scale, output_scale); @@ -607,6 +730,7 @@ _gdk_wayland_display_create_surface (GdkDisplay *display, } impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); if (width > 65535) { @@ -632,7 +756,7 @@ _gdk_wayland_display_create_surface (GdkDisplay *display, GdkMonitor *monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0); if (monitor) { - impl->scale = gdk_monitor_get_scale_factor (monitor); + priv->scale = gdk_monitor_get_scale_factor (monitor); g_object_unref (monitor); } } @@ -653,6 +777,7 @@ gdk_wayland_surface_attach_image (GdkSurface *surface, const cairo_region_t *damage) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GdkWaylandDisplay *display; cairo_rectangle_int_t rect; int i, n; @@ -663,23 +788,23 @@ gdk_wayland_surface_attach_image (GdkSurface *surface, g_assert (_gdk_wayland_is_shm_surface (cairo_surface)); /* Attach this new buffer to the surface */ - wl_surface_attach (impl->display_server.wl_surface, + wl_surface_attach (priv->display_server.wl_surface, _gdk_wayland_shm_surface_get_wl_buffer (cairo_surface), - impl->pending_buffer_offset_x, - impl->pending_buffer_offset_y); - impl->pending_buffer_offset_x = 0; - impl->pending_buffer_offset_y = 0; + priv->pending_buffer_offset_x, + priv->pending_buffer_offset_y); + priv->pending_buffer_offset_x = 0; + priv->pending_buffer_offset_y = 0; /* Only set the buffer scale if supported by the compositor */ display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); if (display->compositor_version >= WL_SURFACE_HAS_BUFFER_SCALE) - wl_surface_set_buffer_scale (impl->display_server.wl_surface, impl->scale); + wl_surface_set_buffer_scale (priv->display_server.wl_surface, priv->scale); n = cairo_region_num_rectangles (damage); for (i = 0; i < n; i++) { cairo_region_get_rectangle (damage, i, &rect); - wl_surface_damage (impl->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height); + wl_surface_damage (priv->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height); } } @@ -711,14 +836,15 @@ gdk_wayland_surface_constructed (GObject *object) { GdkSurface *surface = GDK_SURFACE (object); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); G_OBJECT_CLASS (gdk_wayland_surface_parent_class)->constructed (object); - impl->event_queue = wl_display_create_queue (display_wayland->wl_display); + priv->event_queue = wl_display_create_queue (display_wayland->wl_display); display_wayland->event_queues = g_list_prepend (display_wayland->event_queues, - impl->event_queue); + priv->event_queue); } static void @@ -726,19 +852,22 @@ gdk_wayland_surface_dispose (GObject *object) { GdkSurface *surface = GDK_SURFACE (object); GdkWaylandSurface *impl; + GdkWaylandSurfacePrivate *priv; g_return_if_fail (GDK_IS_WAYLAND_SURFACE (surface)); impl = GDK_WAYLAND_SURFACE (surface); + priv = gdk_wayland_surface_get_instance_private (impl); - if (impl->event_queue) + + if (priv->event_queue) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); display_wayland->event_queues = g_list_remove (display_wayland->event_queues, surface); - g_clear_pointer (&impl->event_queue, wl_event_queue_destroy); + g_clear_pointer (&priv->event_queue, wl_event_queue_destroy); } G_OBJECT_CLASS (gdk_wayland_surface_parent_class)->dispose (object); @@ -748,14 +877,16 @@ static void gdk_wayland_surface_finalize (GObject *object) { GdkWaylandSurface *impl; + GdkWaylandSurfacePrivate *priv; g_return_if_fail (GDK_IS_WAYLAND_SURFACE (object)); impl = GDK_WAYLAND_SURFACE (object); + priv = gdk_wayland_surface_get_instance_private (impl); - g_clear_pointer (&impl->opaque_region, cairo_region_destroy); - g_clear_pointer (&impl->input_region, cairo_region_destroy); - g_clear_pointer (&impl->shortcuts_inhibitors, g_hash_table_unref); + g_clear_pointer (&priv->opaque_region, cairo_region_destroy); + g_clear_pointer (&priv->input_region, cairo_region_destroy); + g_clear_pointer (&priv->shortcuts_inhibitors, g_hash_table_unref); G_OBJECT_CLASS (gdk_wayland_surface_parent_class)->finalize (object); } @@ -763,16 +894,18 @@ gdk_wayland_surface_finalize (GObject *object) static gboolean is_realized_shell_surface (GdkWaylandSurface *impl) { - return (impl->display_server.xdg_surface || - impl->display_server.zxdg_surface_v6); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); + return (priv->display_server.xdg_surface || + priv->display_server.zxdg_surface_v6); } static gboolean is_realized_popup (GdkWaylandSurface *impl) { - return (impl->display_server.xdg_popup || - impl->display_server.zxdg_popup_v6); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); + return (priv->display_server.xdg_popup || + priv->display_server.zxdg_popup_v6); } static void gdk_wayland_surface_hide (GdkSurface *surface); @@ -784,12 +917,13 @@ gdk_wayland_surface_maybe_resize (GdkSurface *surface, int scale) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); gboolean is_xdg_popup; gboolean is_visible; if (surface->width == width && surface->height == height && - impl->scale == scale) + priv->scale == scale) return; /* For xdg_popup using an xdg_positioner, there is a race condition if @@ -801,12 +935,12 @@ gdk_wayland_surface_maybe_resize (GdkSurface *surface, is_xdg_popup = is_realized_popup (impl); is_visible = gdk_surface_get_mapped (surface); - if (is_xdg_popup && is_visible && !impl->initial_configure_received) + if (is_xdg_popup && is_visible && !priv->initial_configure_received) gdk_wayland_surface_hide (surface); gdk_wayland_surface_update_size (surface, width, height, scale); - if (is_xdg_popup && is_visible && !impl->initial_configure_received) + if (is_xdg_popup && is_visible && !priv->initial_configure_received) gdk_wayland_surface_show (surface, FALSE); } @@ -815,12 +949,13 @@ gdk_wayland_surface_get_window_geometry_real (GdkSurface *surface, GdkRectangle *geometry) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); *geometry = (GdkRectangle) { - .x = impl->shadow_left, - .y = impl->shadow_top, - .width = surface->width - (impl->shadow_left + impl->shadow_right), - .height = surface->height - (impl->shadow_top + impl->shadow_bottom) + .x = priv->shadow_left, + .y = priv->shadow_top, + .width = surface->width - (priv->shadow_left + priv->shadow_right), + .height = surface->height - (priv->shadow_top + priv->shadow_bottom) }; } @@ -835,6 +970,7 @@ static void gdk_wayland_surface_sync_shadow (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkRectangle geometry; @@ -844,20 +980,20 @@ gdk_wayland_surface_sync_shadow (GdkSurface *surface) gdk_wayland_surface_get_window_geometry (surface, &geometry); - if (gdk_rectangle_equal (&geometry, &impl->last_sent_window_geometry)) + if (gdk_rectangle_equal (&geometry, &priv->last_sent_window_geometry)) return; switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_surface_set_window_geometry (impl->display_server.xdg_surface, + xdg_surface_set_window_geometry (priv->display_server.xdg_surface, geometry.x, geometry.y, geometry.width, geometry.height); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_surface_v6_set_window_geometry (impl->display_server.zxdg_surface_v6, + zxdg_surface_v6_set_window_geometry (priv->display_server.zxdg_surface_v6, geometry.x, geometry.y, geometry.width, @@ -867,7 +1003,7 @@ gdk_wayland_surface_sync_shadow (GdkSurface *surface) g_assert_not_reached (); } - impl->last_sent_window_geometry = geometry; + priv->last_sent_window_geometry = geometry; } static struct wl_region * @@ -896,48 +1032,50 @@ static void gdk_wayland_surface_sync_opaque_region (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); struct wl_region *wl_region = NULL; - if (!impl->display_server.wl_surface) + if (!priv->display_server.wl_surface) return; - if (!impl->opaque_region_dirty) + if (!priv->opaque_region_dirty) return; - if (impl->opaque_region != NULL) + if (priv->opaque_region != NULL) wl_region = wl_region_from_cairo_region (GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)), - impl->opaque_region); + priv->opaque_region); - wl_surface_set_opaque_region (impl->display_server.wl_surface, wl_region); + wl_surface_set_opaque_region (priv->display_server.wl_surface, wl_region); if (wl_region != NULL) wl_region_destroy (wl_region); - impl->opaque_region_dirty = FALSE; + priv->opaque_region_dirty = FALSE; } static void gdk_wayland_surface_sync_input_region (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); struct wl_region *wl_region = NULL; - if (!impl->display_server.wl_surface) + if (!priv->display_server.wl_surface) return; - if (!impl->input_region_dirty) + if (!priv->input_region_dirty) return; - if (impl->input_region != NULL) + if (priv->input_region != NULL) wl_region = wl_region_from_cairo_region (GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)), - impl->input_region); + priv->input_region); - wl_surface_set_input_region (impl->display_server.wl_surface, wl_region); + wl_surface_set_input_region (priv->display_server.wl_surface, wl_region); if (wl_region != NULL) wl_region_destroy (wl_region); - impl->input_region_dirty = FALSE; + priv->input_region_dirty = FALSE; } static void @@ -947,13 +1085,14 @@ surface_enter (void *data, { GdkSurface *surface = GDK_SURFACE (data); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GdkDisplay *display = gdk_surface_get_display (surface); GdkMonitor *monitor; GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS, g_message ("surface enter, surface %p output %p", surface, output)); - impl->display_server.outputs = g_slist_prepend (impl->display_server.outputs, output); + priv->display_server.outputs = g_slist_prepend (priv->display_server.outputs, output); gdk_wayland_surface_update_scale (surface); @@ -968,15 +1107,16 @@ surface_leave (void *data, { GdkSurface *surface = GDK_SURFACE (data); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GdkDisplay *display = gdk_surface_get_display (surface); GdkMonitor *monitor; GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS, g_message ("surface leave, surface %p output %p", surface, output)); - impl->display_server.outputs = g_slist_remove (impl->display_server.outputs, output); + priv->display_server.outputs = g_slist_remove (priv->display_server.outputs, output); - if (impl->display_server.outputs) + if (priv->display_server.outputs) gdk_wayland_surface_update_scale (surface); monitor = gdk_wayland_display_get_monitor_for_output (display, output); @@ -992,36 +1132,38 @@ static void gdk_wayland_surface_create_surface (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); struct wl_surface *wl_surface; wl_surface = wl_compositor_create_surface (display_wayland->compositor); - wl_proxy_set_queue ((struct wl_proxy *) wl_surface, impl->event_queue); + wl_proxy_set_queue ((struct wl_proxy *) wl_surface, priv->event_queue); wl_surface_add_listener (wl_surface, &surface_listener, surface); - impl->display_server.wl_surface = wl_surface; + priv->display_server.wl_surface = wl_surface; } static void gdk_wayland_surface_configure_popup (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GdkRectangle parent_geometry; int x, y, width, height; - if (impl->pending.popup.has_repositioned_token) - impl->received_reposition_token = impl->pending.popup.repositioned_token; + if (priv->pending.popup.has_repositioned_token) + priv->received_reposition_token = priv->pending.popup.repositioned_token; - switch (impl->popup_state) + switch (priv->popup_state) { case POPUP_STATE_WAITING_FOR_REPOSITIONED: - if (impl->received_reposition_token != impl->reposition_token) + if (priv->received_reposition_token != priv->reposition_token) return; else gdk_surface_thaw_updates (surface); G_GNUC_FALLTHROUGH; case POPUP_STATE_WAITING_FOR_CONFIGURE: - impl->popup_state = POPUP_STATE_WAITING_FOR_FRAME; + priv->popup_state = POPUP_STATE_WAITING_FOR_FRAME; break; case POPUP_STATE_IDLE: case POPUP_STATE_WAITING_FOR_FRAME: @@ -1030,10 +1172,10 @@ gdk_wayland_surface_configure_popup (GdkSurface *surface) g_assert_not_reached (); } - x = impl->pending.popup.x; - y = impl->pending.popup.y; - width = impl->pending.popup.width; - height = impl->pending.popup.height; + x = priv->pending.popup.x; + y = priv->pending.popup.y; + width = priv->pending.popup.width; + height = priv->pending.popup.height; gdk_wayland_surface_get_window_geometry (surface->parent, &parent_geometry); x += parent_geometry.x; @@ -1042,13 +1184,13 @@ gdk_wayland_surface_configure_popup (GdkSurface *surface) update_popup_layout_state (surface, x, y, width, height, - impl->popup.layout); + priv->popup.layout); - impl->next_layout.popup.x = x; - impl->next_layout.popup.y = y; - impl->next_layout.configured_width = width; - impl->next_layout.configured_height = height; - impl->next_layout.surface_geometry_dirty = TRUE; + priv->next_layout.popup.x = x; + priv->next_layout.popup.y = y; + priv->next_layout.configured_width = width; + priv->next_layout.configured_height = height; + priv->next_layout.surface_geometry_dirty = TRUE; gdk_surface_request_layout (surface); } @@ -1084,36 +1226,37 @@ gdk_wayland_surface_configure (GdkSurface *surface) GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - if (!impl->initial_configure_received) + if (!priv->initial_configure_received) { gdk_surface_thaw_updates (surface); - impl->initial_configure_received = TRUE; - impl->pending.is_initial_configure = TRUE; + priv->initial_configure_received = TRUE; + priv->pending.is_initial_configure = TRUE; maybe_notify_mapped (surface); } - impl->has_uncommitted_ack_configure = TRUE; + priv->has_uncommitted_ack_configure = TRUE; gdk_wayland_surface_configure_surface (surface); switch (display_wayland->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_surface_ack_configure (GDK_WAYLAND_SURFACE(impl)->display_server.xdg_surface, - GDK_WAYLAND_SURFACE(impl)->pending.serial); + xdg_surface_ack_configure (priv->display_server.xdg_surface, + priv->pending.serial); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_surface_v6_ack_configure (GDK_WAYLAND_SURFACE(impl)->display_server.zxdg_surface_v6, - GDK_WAYLAND_SURFACE(impl)->pending.serial); + zxdg_surface_v6_ack_configure (priv->display_server.zxdg_surface_v6, + priv->pending.serial); break; default: g_assert_not_reached (); } - impl->last_configure_serial = impl->pending.serial; + priv->last_configure_serial = priv->pending.serial; - memset (&impl->pending, 0, sizeof (impl->pending)); + memset (&priv->pending, 0, sizeof (priv->pending)); } static void @@ -1121,11 +1264,12 @@ gdk_wayland_surface_handle_configure (GdkSurface *surface, uint32_t serial) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - impl->pending.is_dirty = TRUE; - impl->pending.serial = serial; + priv->pending.is_dirty = TRUE; + priv->pending.serial = serial; - if (impl->state_freeze_count > 0) + if (priv->state_freeze_count > 0) return; gdk_wayland_surface_configure (surface); @@ -1165,24 +1309,25 @@ gdk_wayland_surface_create_xdg_surface_resources (GdkSurface *surface) GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); switch (display->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - impl->display_server.xdg_surface = + priv->display_server.xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, - impl->display_server.wl_surface); - wl_proxy_set_queue ((struct wl_proxy *) impl->display_server.xdg_surface, - impl->event_queue); - xdg_surface_add_listener (impl->display_server.xdg_surface, + priv->display_server.wl_surface); + wl_proxy_set_queue ((struct wl_proxy *) priv->display_server.xdg_surface, + priv->event_queue); + xdg_surface_add_listener (priv->display_server.xdg_surface, &xdg_surface_listener, surface); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - impl->display_server.zxdg_surface_v6 = + priv->display_server.zxdg_surface_v6 = zxdg_shell_v6_get_xdg_surface (display->zxdg_shell_v6, - impl->display_server.wl_surface); - zxdg_surface_v6_add_listener (impl->display_server.zxdg_surface_v6, + priv->display_server.wl_surface); + zxdg_surface_v6_add_listener (priv->display_server.zxdg_surface_v6, &zxdg_surface_v6_listener, surface); break; @@ -1199,11 +1344,12 @@ gdk_wayland_surface_handle_configure_popup (GdkSurface *surface, int32_t height) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - impl->pending.popup.x = x; - impl->pending.popup.y = y; - impl->pending.popup.width = width; - impl->pending.popup.height = height; + priv->pending.popup.x = x; + priv->pending.popup.y = y; + priv->pending.popup.width = width; + priv->pending.popup.height = height; } static void @@ -1237,18 +1383,19 @@ xdg_popup_repositioned (void *data, { GdkSurface *surface = GDK_SURFACE (data); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS, g_message ("repositioned %p", surface)); - if (impl->popup_state != POPUP_STATE_WAITING_FOR_REPOSITIONED) + if (priv->popup_state != POPUP_STATE_WAITING_FOR_REPOSITIONED) { g_warning ("Unexpected xdg_popup.repositioned event, probably buggy compositor"); return; } - impl->pending.popup.repositioned_token = token; - impl->pending.popup.has_repositioned_token = TRUE; + priv->pending.popup.repositioned_token = token; + priv->pending.popup.has_repositioned_token = TRUE; } static const struct xdg_popup_listener xdg_popup_listener = { @@ -1423,6 +1570,7 @@ calculate_popup_rect (GdkSurface *surface, GdkRectangle *out_rect) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); int width, height; GdkRectangle anchor_rect; int dx, dy; @@ -1435,8 +1583,8 @@ calculate_popup_rect (GdkSurface *surface, &shadow_top, &shadow_bottom); - width = (impl->popup.unconstrained_width - (shadow_left + shadow_right)); - height = (impl->popup.unconstrained_height - (shadow_top + shadow_bottom)); + width = (priv->popup.unconstrained_width - (shadow_left + shadow_right)); + height = (priv->popup.unconstrained_height - (shadow_top + shadow_bottom)); anchor_rect = *gdk_popup_layout_get_anchor_rect (layout); gdk_popup_layout_get_offset (layout, &dx, &dy); @@ -1622,6 +1770,7 @@ create_dynamic_positioner (GdkSurface *surface, { GdkSurface *parent = surface->parent; GdkWaylandSurface *parent_impl = GDK_WAYLAND_SURFACE (parent); + GdkWaylandSurfacePrivate *parent_priv = gdk_wayland_surface_get_instance_private (parent_impl); GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkRectangle geometry; @@ -1719,7 +1868,7 @@ create_dynamic_positioner (GdkSurface *surface, parent_geometry.width, parent_geometry.height); xdg_positioner_set_parent_configure (positioner, - parent_impl->last_configure_serial); + parent_priv->last_configure_serial); } return positioner; @@ -1797,10 +1946,12 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, { GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GdkWaylandSurface *parent_impl = GDK_WAYLAND_SURFACE (parent); + GdkWaylandSurfacePrivate *parent_priv = gdk_wayland_surface_get_instance_private (parent_impl); gpointer positioner; - if (!impl->display_server.wl_surface) + if (!priv->display_server.wl_surface) return FALSE; if (!is_realized_shell_surface (parent_impl)) @@ -1827,21 +1978,21 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, switch (display->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - impl->display_server.xdg_popup = - xdg_surface_get_popup (impl->display_server.xdg_surface, - parent_impl->display_server.xdg_surface, + priv->display_server.xdg_popup = + xdg_surface_get_popup (priv->display_server.xdg_surface, + parent_priv->display_server.xdg_surface, positioner); - xdg_popup_add_listener (impl->display_server.xdg_popup, + xdg_popup_add_listener (priv->display_server.xdg_popup, &xdg_popup_listener, surface); xdg_positioner_destroy (positioner); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - impl->display_server.zxdg_popup_v6 = - zxdg_surface_v6_get_popup (impl->display_server.zxdg_surface_v6, - parent_impl->display_server.zxdg_surface_v6, + priv->display_server.zxdg_popup_v6 = + zxdg_surface_v6_get_popup (priv->display_server.zxdg_surface_v6, + parent_priv->display_server.zxdg_surface_v6, positioner); - zxdg_popup_v6_add_listener (impl->display_server.zxdg_popup_v6, + zxdg_popup_v6_add_listener (priv->display_server.zxdg_popup_v6, &zxdg_popup_v6_listener, surface); zxdg_positioner_v6_destroy (positioner); @@ -1851,10 +2002,10 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, } gdk_popup_layout_get_shadow_width (layout, - &impl->shadow_left, - &impl->shadow_right, - &impl->shadow_top, - &impl->shadow_bottom); + &priv->shadow_left, + &priv->shadow_right, + &priv->shadow_top, + &priv->shadow_bottom); if (grab_input_seat) { @@ -1867,10 +2018,10 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, switch (display->shell_variant) { case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL: - xdg_popup_grab (impl->display_server.xdg_popup, seat, serial); + xdg_popup_grab (priv->display_server.xdg_popup, seat, serial); break; case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6: - zxdg_popup_v6_grab (impl->display_server.zxdg_popup_v6, seat, serial); + zxdg_popup_v6_grab (priv->display_server.zxdg_popup_v6, seat, serial); break; default: g_assert_not_reached (); @@ -1878,12 +2029,12 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface, } gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit"); - wl_surface_commit (impl->display_server.wl_surface); + wl_surface_commit (priv->display_server.wl_surface); if (GDK_IS_POPUP (surface)) { - g_assert (impl->popup_state == POPUP_STATE_IDLE); - impl->popup_state = POPUP_STATE_WAITING_FOR_CONFIGURE; + g_assert (priv->popup_state == POPUP_STATE_IDLE); + priv->popup_state = POPUP_STATE_WAITING_FOR_CONFIGURE; freeze_popup_toplevel_state (surface); } @@ -1902,21 +2053,24 @@ find_grab_input_seat (GdkSurface *surface, GdkSurface *parent) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GdkWaylandSurface *tmp_impl; + GdkWaylandSurfacePrivate *tmp_priv; /* Use the device that was used for the grab as the device for * the popup surface setup - so this relies on GTK taking the * grab before showing the popup surface. */ - if (impl->grab_input_seat) - return GDK_WAYLAND_SEAT (impl->grab_input_seat); + if (priv->grab_input_seat) + return GDK_WAYLAND_SEAT (priv->grab_input_seat); while (parent) { tmp_impl = GDK_WAYLAND_SURFACE (parent); + tmp_priv = gdk_wayland_surface_get_instance_private (tmp_impl); - if (tmp_impl->grab_input_seat) - return GDK_WAYLAND_SEAT (tmp_impl->grab_input_seat); + if (tmp_priv->grab_input_seat) + return GDK_WAYLAND_SEAT (tmp_priv->grab_input_seat); parent = parent->parent; } @@ -1929,8 +2083,9 @@ gdk_wayland_surface_show (GdkSurface *surface, gboolean already_mapped) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - if (!impl->display_server.wl_surface) + if (!priv->display_server.wl_surface) gdk_wayland_surface_create_surface (surface); } @@ -1960,83 +2115,84 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); unmap_popups_for_surface (surface); - if (impl->display_server.wl_surface) + if (priv->display_server.wl_surface) { - if (impl->dummy_egl_surface) + if (priv->dummy_egl_surface) { - eglDestroySurface (display_wayland->egl_display, impl->dummy_egl_surface); - impl->dummy_egl_surface = NULL; + eglDestroySurface (display_wayland->egl_display, priv->dummy_egl_surface); + priv->dummy_egl_surface = NULL; } - if (impl->display_server.dummy_egl_window) + if (priv->display_server.dummy_egl_window) { - wl_egl_window_destroy (impl->display_server.dummy_egl_window); - impl->display_server.dummy_egl_window = NULL; + wl_egl_window_destroy (priv->display_server.dummy_egl_window); + priv->display_server.dummy_egl_window = NULL; } - if (impl->egl_surface) + if (priv->egl_surface) { - eglDestroySurface (display_wayland->egl_display, impl->egl_surface); - impl->egl_surface = NULL; + eglDestroySurface (display_wayland->egl_display, priv->egl_surface); + priv->egl_surface = NULL; } - if (impl->display_server.egl_window) + if (priv->display_server.egl_window) { - wl_egl_window_destroy (impl->display_server.egl_window); - impl->display_server.egl_window = NULL; + wl_egl_window_destroy (priv->display_server.egl_window); + priv->display_server.egl_window = NULL; } - if (impl->display_server.xdg_popup) + if (priv->display_server.xdg_popup) { - xdg_popup_destroy (impl->display_server.xdg_popup); - impl->display_server.xdg_popup = NULL; + xdg_popup_destroy (priv->display_server.xdg_popup); + priv->display_server.xdg_popup = NULL; display_wayland->current_popups = g_list_remove (display_wayland->current_popups, surface); display_wayland->current_grabbing_popups = g_list_remove (display_wayland->current_grabbing_popups, surface); } - if (impl->display_server.xdg_surface) + if (priv->display_server.xdg_surface) { - xdg_surface_destroy (impl->display_server.xdg_surface); - impl->display_server.xdg_surface = NULL; - if (!impl->initial_configure_received) + xdg_surface_destroy (priv->display_server.xdg_surface); + priv->display_server.xdg_surface = NULL; + if (!priv->initial_configure_received) gdk_surface_thaw_updates (surface); else - impl->initial_configure_received = FALSE; + priv->initial_configure_received = FALSE; } - if (impl->display_server.zxdg_popup_v6) + if (priv->display_server.zxdg_popup_v6) { - zxdg_popup_v6_destroy (impl->display_server.zxdg_popup_v6); - impl->display_server.zxdg_popup_v6 = NULL; + zxdg_popup_v6_destroy (priv->display_server.zxdg_popup_v6); + priv->display_server.zxdg_popup_v6 = NULL; display_wayland->current_popups = g_list_remove (display_wayland->current_popups, surface); display_wayland->current_grabbing_popups = g_list_remove (display_wayland->current_grabbing_popups, surface); } - if (impl->display_server.zxdg_surface_v6) + if (priv->display_server.zxdg_surface_v6) { - zxdg_surface_v6_destroy (impl->display_server.zxdg_surface_v6); - impl->display_server.zxdg_surface_v6 = NULL; - if (!impl->initial_configure_received) + zxdg_surface_v6_destroy (priv->display_server.zxdg_surface_v6); + priv->display_server.zxdg_surface_v6 = NULL; + if (!priv->initial_configure_received) gdk_surface_thaw_updates (surface); else - impl->initial_configure_received = FALSE; + priv->initial_configure_received = FALSE; } - impl->awaiting_frame = FALSE; - if (impl->awaiting_frame_frozen) + priv->awaiting_frame = FALSE; + if (priv->awaiting_frame_frozen) { - impl->awaiting_frame_frozen = FALSE; + priv->awaiting_frame_frozen = FALSE; gdk_surface_thaw_updates (surface); } if (GDK_IS_POPUP (surface)) { - switch (impl->popup_state) + switch (priv->popup_state) { case POPUP_STATE_WAITING_FOR_REPOSITIONED: gdk_surface_thaw_updates (surface); @@ -2051,24 +2207,23 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) g_assert_not_reached (); } - impl->popup_state = POPUP_STATE_IDLE; + priv->popup_state = POPUP_STATE_IDLE; } - wl_surface_destroy (impl->display_server.wl_surface); - impl->display_server.wl_surface = NULL; + wl_surface_destroy (priv->display_server.wl_surface); + priv->display_server.wl_surface = NULL; - g_slist_free (impl->display_server.outputs); - impl->display_server.outputs = NULL; + g_slist_free (priv->display_server.outputs); + priv->display_server.outputs = NULL; - g_clear_pointer (&impl->popup.layout, gdk_popup_layout_unref); + g_clear_pointer (&priv->popup.layout, gdk_popup_layout_unref); } - impl->has_uncommitted_ack_configure = FALSE; - impl->input_region_dirty = TRUE; - - impl->last_sent_window_geometry = (GdkRectangle) { 0 }; + priv->has_uncommitted_ack_configure = FALSE; + priv->input_region_dirty = TRUE; - impl->mapped = FALSE; + priv->last_sent_window_geometry = (GdkRectangle) { 0 }; + priv->mapped = FALSE; } static void @@ -2096,22 +2251,28 @@ gdk_wayland_surface_move_resize (GdkSurface *surface, int height) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); surface->x = x; surface->y = y; - gdk_wayland_surface_maybe_resize (surface, width, height, impl->scale); + gdk_wayland_surface_maybe_resize (surface, width, height, priv->scale); } static gboolean is_fallback_relayout_possible (GdkSurface *surface) { GList *l; + GdkWaylandSurface *impl; + GdkWaylandSurfacePrivate *priv; for (l = surface->children; l; l = l->next) { GdkSurface *child = l->data; - if (GDK_WAYLAND_SURFACE (child)->mapped) + impl = GDK_WAYLAND_SURFACE (child); + priv = gdk_wayland_surface_get_instance_private (impl); + + if (priv->mapped) return FALSE; } @@ -2128,14 +2289,15 @@ queue_relayout_fallback (GdkSurface *surface, GdkPopupLayout *layout) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); if (!is_fallback_relayout_possible (surface)) return; gdk_wayland_surface_hide_surface (surface); gdk_wayland_surface_present_popup (surface, - impl->popup.unconstrained_width, - impl->popup.unconstrained_height, + priv->popup.unconstrained_width, + priv->popup.unconstrained_height, layout); } @@ -2146,19 +2308,20 @@ do_queue_relayout (GdkSurface *surface, GdkPopupLayout *layout) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); struct xdg_positioner *positioner; g_assert (is_realized_popup (impl)); - g_assert (impl->popup_state == POPUP_STATE_IDLE || - impl->popup_state == POPUP_STATE_WAITING_FOR_FRAME); + g_assert (priv->popup_state == POPUP_STATE_IDLE || + priv->popup_state == POPUP_STATE_WAITING_FOR_FRAME); - g_clear_pointer (&impl->popup.layout, gdk_popup_layout_unref); - impl->popup.layout = gdk_popup_layout_copy (layout); - impl->popup.unconstrained_width = width; - impl->popup.unconstrained_height = height; + g_clear_pointer (&priv->popup.layout, gdk_popup_layout_unref); + priv->popup.layout = gdk_popup_layout_copy (layout); + priv->popup.unconstrained_width = width; + priv->popup.unconstrained_height = height; - if (!impl->display_server.xdg_popup || - xdg_popup_get_version (impl->display_server.xdg_popup) < + if (!priv->display_server.xdg_popup || + xdg_popup_get_version (priv->display_server.xdg_popup) < XDG_POPUP_REPOSITION_SINCE_VERSION) { g_warning_once ("Compositor doesn't support moving popups, " @@ -2171,14 +2334,14 @@ do_queue_relayout (GdkSurface *surface, positioner = create_dynamic_positioner (surface, width, height, layout, TRUE); - xdg_popup_reposition (impl->display_server.xdg_popup, + xdg_popup_reposition (priv->display_server.xdg_popup, positioner, - ++impl->reposition_token); + ++priv->reposition_token); xdg_positioner_destroy (positioner); gdk_surface_freeze_updates (surface); - switch (impl->popup_state) + switch (priv->popup_state) { case POPUP_STATE_IDLE: freeze_popup_toplevel_state (surface); @@ -2191,18 +2354,19 @@ do_queue_relayout (GdkSurface *surface, g_assert_not_reached (); } - impl->popup_state = POPUP_STATE_WAITING_FOR_REPOSITIONED; + priv->popup_state = POPUP_STATE_WAITING_FOR_REPOSITIONED; } static gboolean is_relayout_finished (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - if (!impl->initial_configure_received) + if (!priv->initial_configure_received) return FALSE; - if (impl->reposition_token != impl->received_reposition_token) + if (priv->reposition_token != priv->received_reposition_token) return FALSE; return TRUE; @@ -2215,6 +2379,7 @@ gdk_wayland_surface_map_popup (GdkSurface *surface, GdkPopupLayout *layout) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GdkSurface *parent; GdkWaylandSeat *grab_input_seat; @@ -2238,10 +2403,10 @@ gdk_wayland_surface_map_popup (GdkSurface *surface, layout)) return; - impl->popup.layout = gdk_popup_layout_copy (layout); - impl->popup.unconstrained_width = width; - impl->popup.unconstrained_height = height; - impl->mapped = TRUE; + priv->popup.layout = gdk_popup_layout_copy (layout); + priv->popup.unconstrained_width = width; + priv->popup.unconstrained_height = height; + priv->mapped = TRUE; } static void @@ -2251,8 +2416,9 @@ show_popup (GdkSurface *surface, GdkPopupLayout *layout) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - if (!impl->display_server.wl_surface) + if (!priv->display_server.wl_surface) gdk_wayland_surface_create_surface (surface); gdk_wayland_surface_map_popup (surface, width, height, layout); @@ -2282,8 +2448,9 @@ reposition_popup (GdkSurface *surface, GdkPopupLayout *layout) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - switch (impl->popup_state) + switch (priv->popup_state) { case POPUP_STATE_IDLE: case POPUP_STATE_WAITING_FOR_FRAME: @@ -2309,8 +2476,9 @@ gdk_wayland_surface_present_popup (GdkSurface *surface, GdkWaylandSurface *impl; impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - if (!impl->mapped) + if (!priv->mapped) { if (surface->autohide) { @@ -2351,18 +2519,18 @@ gdk_wayland_surface_present_popup (GdkSurface *surface, } else { - if (impl->popup.unconstrained_width == width && - impl->popup.unconstrained_height == height && - gdk_popup_layout_equal (impl->popup.layout, layout)) + if (priv->popup.unconstrained_width == width && + priv->popup.unconstrained_height == height && + gdk_popup_layout_equal (priv->popup.layout, layout)) return TRUE; reposition_popup (surface, width, height, layout); } - while (impl->display_server.xdg_popup && !is_relayout_finished (surface)) - wl_display_dispatch_queue (display_wayland->wl_display, impl->event_queue); + while (priv->display_server.xdg_popup && !is_relayout_finished (surface)) + wl_display_dispatch_queue (display_wayland->wl_display, priv->event_queue); - if (impl->display_server.xdg_popup) + if (priv->display_server.xdg_popup) { gdk_surface_invalidate_rect (surface, NULL); return TRUE; @@ -2449,16 +2617,17 @@ gdk_wayland_surface_set_input_region (GdkSurface *surface, cairo_region_t *input_region) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); if (GDK_SURFACE_DESTROYED (surface)) return; - g_clear_pointer (&impl->input_region, cairo_region_destroy); + g_clear_pointer (&priv->input_region, cairo_region_destroy); if (input_region) - impl->input_region = cairo_region_copy (input_region); + priv->input_region = cairo_region_copy (input_region); - impl->input_region_dirty = TRUE; + priv->input_region_dirty = TRUE; } static void @@ -2501,11 +2670,12 @@ static int gdk_wayland_surface_get_scale_factor (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); if (GDK_SURFACE_DESTROYED (surface)) return 1; - return impl->scale; + return priv->scale; } static void @@ -2513,13 +2683,14 @@ gdk_wayland_surface_set_opaque_region (GdkSurface *surface, cairo_region_t *region) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); if (GDK_SURFACE_DESTROYED (surface)) return; - g_clear_pointer (&impl->opaque_region, cairo_region_destroy); - impl->opaque_region = cairo_region_reference (region); - impl->opaque_region_dirty = TRUE; + g_clear_pointer (&priv->opaque_region, cairo_region_destroy); + priv->opaque_region = cairo_region_reference (region); + priv->opaque_region_dirty = TRUE; } static void @@ -2558,11 +2729,13 @@ _gdk_wayland_surface_set_grab_seat (GdkSurface *surface, GdkSeat *seat) { GdkWaylandSurface *impl; + GdkWaylandSurfacePrivate *priv; g_return_if_fail (surface != NULL); impl = GDK_WAYLAND_SURFACE (surface); - impl->grab_input_seat = seat; + priv = gdk_wayland_surface_get_instance_private (impl); + priv->grab_input_seat = seat; } /** @@ -2576,22 +2749,29 @@ _gdk_wayland_surface_set_grab_seat (GdkSurface *surface, struct wl_surface * gdk_wayland_surface_get_wl_surface (GdkSurface *surface) { + GdkWaylandSurface *impl; + GdkWaylandSurfacePrivate *priv; + g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); - return GDK_WAYLAND_SURFACE (surface)->display_server.wl_surface; + impl = GDK_WAYLAND_SURFACE (surface); + priv = gdk_wayland_surface_get_instance_private (impl); + return priv->display_server.wl_surface; } struct wl_output * gdk_wayland_surface_get_wl_output (GdkSurface *surface) { GdkWaylandSurface *impl; + GdkWaylandSurfacePrivate *priv; g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); impl = GDK_WAYLAND_SURFACE (surface); + priv = gdk_wayland_surface_get_instance_private (impl); /* We pick the head of the list as this is the last entered output */ - if (impl->display_server.outputs) - return (struct wl_output *) impl->display_server.outputs->data; + if (priv->display_server.outputs) + return (struct wl_output *) priv->display_server.outputs->data; return NULL; } @@ -2599,42 +2779,58 @@ gdk_wayland_surface_get_wl_output (GdkSurface *surface) struct xdg_surface * gdk_wayland_surface_get_xdg_surface (GdkSurface *surface) { + GdkWaylandSurface *impl; + GdkWaylandSurfacePrivate *priv; + g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); - return GDK_WAYLAND_SURFACE (surface)->display_server.xdg_surface; + impl = GDK_WAYLAND_SURFACE (surface); + priv = gdk_wayland_surface_get_instance_private (impl); + return priv->display_server.xdg_surface; } struct zxdg_surface_v6 * gdk_wayland_surface_get_zxdg_surface_v6 (GdkSurface *surface) { + GdkWaylandSurface *impl; + GdkWaylandSurfacePrivate *priv; + g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); - return GDK_WAYLAND_SURFACE (surface)->display_server.zxdg_surface_v6; + impl = GDK_WAYLAND_SURFACE (surface); + priv = gdk_wayland_surface_get_instance_private (impl); + return priv->display_server.zxdg_surface_v6; } struct wl_event_queue * gdk_wayland_surface_get_event_queue (GdkSurface *surface) { + GdkWaylandSurface *impl; + GdkWaylandSurfacePrivate *priv; + g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); - return GDK_WAYLAND_SURFACE (surface)->event_queue; + impl = GDK_WAYLAND_SURFACE (surface); + priv = gdk_wayland_surface_get_instance_private (impl); + return priv->event_queue; } static struct wl_egl_window * gdk_wayland_surface_get_wl_egl_window (GdkSurface *surface) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); - if (impl->display_server.egl_window == NULL) + if (priv->display_server.egl_window == NULL) { - impl->display_server.egl_window = - wl_egl_window_create (impl->display_server.wl_surface, - surface->width * impl->scale, - surface->height * impl->scale); - wl_surface_set_buffer_scale (impl->display_server.wl_surface, impl->scale); + priv->display_server.egl_window = + wl_egl_window_create (priv->display_server.wl_surface, + surface->width * priv->scale, + surface->height * priv->scale); + wl_surface_set_buffer_scale (priv->display_server.wl_surface, priv->scale); } - return impl->display_server.egl_window; + return priv->display_server.egl_window; } EGLSurface @@ -2643,21 +2839,23 @@ gdk_wayland_surface_get_egl_surface (GdkSurface *surface, { GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkWaylandSurface *impl; + GdkWaylandSurfacePrivate *priv; struct wl_egl_window *egl_window; g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); impl = GDK_WAYLAND_SURFACE (surface); + priv = gdk_wayland_surface_get_instance_private (impl); - if (impl->egl_surface == NULL) + if (priv->egl_surface == NULL) { egl_window = gdk_wayland_surface_get_wl_egl_window (surface); - impl->egl_surface = + priv->egl_surface = eglCreateWindowSurface (display->egl_display, config, egl_window, NULL); } - return impl->egl_surface; + return priv->egl_surface; } EGLSurface @@ -2666,21 +2864,23 @@ gdk_wayland_surface_get_dummy_egl_surface (GdkSurface *surface, { GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkWaylandSurface *impl; + GdkWaylandSurfacePrivate *priv; g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL); impl = GDK_WAYLAND_SURFACE (surface); + priv = gdk_wayland_surface_get_instance_private (impl); - if (impl->dummy_egl_surface == NULL) + if (priv->dummy_egl_surface == NULL) { - impl->display_server.dummy_egl_window = - wl_egl_window_create (impl->display_server.wl_surface, 1, 1); + priv->display_server.dummy_egl_window = + wl_egl_window_create (priv->display_server.wl_surface, 1, 1); - impl->dummy_egl_surface = - eglCreateWindowSurface (display->egl_display, config, impl->display_server.dummy_egl_window, NULL); + priv->dummy_egl_surface = + eglCreateWindowSurface (display->egl_display, config, priv->display_server.dummy_egl_window, NULL); } - return impl->dummy_egl_surface; + return priv->dummy_egl_surface; } void @@ -2689,20 +2889,23 @@ _gdk_wayland_surface_offset_next_wl_buffer (GdkSurface *surface, int y) { GdkWaylandSurface *impl; + GdkWaylandSurfacePrivate *priv; g_return_if_fail (GDK_IS_WAYLAND_SURFACE (surface)); impl = GDK_WAYLAND_SURFACE (surface); + priv = gdk_wayland_surface_get_instance_private (impl); - impl->pending_buffer_offset_x = x; - impl->pending_buffer_offset_y = y; + priv->pending_buffer_offset_x = x; + priv->pending_buffer_offset_y = y; } struct zwp_keyboard_shortcuts_inhibitor_v1 * gdk_wayland_surface_get_inhibitor (GdkWaylandSurface *impl, GdkSeat *gdk_seat) { - return g_hash_table_lookup (impl->shortcuts_inhibitors, gdk_seat); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); + return g_hash_table_lookup (priv->shortcuts_inhibitors, gdk_seat); } /* @@ -2716,9 +2919,10 @@ void gdk_wayland_surface_inhibit_shortcuts (GdkSurface *surface, GdkSeat *gdk_seat) { - GdkWaylandSurface *impl= GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); - struct wl_surface *wl_surface = impl->display_server.wl_surface; + struct wl_surface *wl_surface = priv->display_server.wl_surface; struct wl_seat *seat = gdk_wayland_seat_get_wl_seat (gdk_seat); struct zwp_keyboard_shortcuts_inhibitor_v1 *inhibitor; @@ -2732,7 +2936,7 @@ gdk_wayland_surface_inhibit_shortcuts (GdkSurface *surface, zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts ( display->keyboard_shortcuts_inhibit, wl_surface, seat); - g_hash_table_insert (impl->shortcuts_inhibitors, gdk_seat, inhibitor); + g_hash_table_insert (priv->shortcuts_inhibitors, gdk_seat, inhibitor); } /* @@ -2748,6 +2952,7 @@ gdk_wayland_surface_restore_shortcuts (GdkSurface *surface, GdkSeat *gdk_seat) { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); struct zwp_keyboard_shortcuts_inhibitor_v1 *inhibitor; inhibitor = gdk_wayland_surface_get_inhibitor (impl, gdk_seat); @@ -2755,19 +2960,24 @@ gdk_wayland_surface_restore_shortcuts (GdkSurface *surface, return; /* Not inhibitted */ zwp_keyboard_shortcuts_inhibitor_v1_destroy (inhibitor); - g_hash_table_remove (impl->shortcuts_inhibitors, gdk_seat); + g_hash_table_remove (priv->shortcuts_inhibitors, gdk_seat); } GdkSurface * create_dnd_surface (GdkDisplay *display) { GdkSurface *surface; + GdkWaylandSurface *impl; + GdkWaylandSurfacePrivate *priv; surface = _gdk_wayland_display_create_surface (display, GDK_SURFACE_TEMP, NULL, 0, 0, 100, 100); - GDK_WAYLAND_SURFACE (surface)->is_drag_surface = TRUE; + impl = GDK_WAYLAND_SURFACE (surface); + priv = gdk_wayland_surface_get_instance_private (impl); + + priv->is_drag_surface = TRUE; return surface; } @@ -2900,12 +3110,13 @@ gdk_wayland_drag_surface_present (GdkDragSurface *drag_surface, { GdkSurface *surface = GDK_SURFACE (drag_surface); GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl); gdk_wayland_surface_show (surface, FALSE); - impl->next_layout.configured_width = width; - impl->next_layout.configured_height = height; - impl->next_layout.surface_geometry_dirty = TRUE; + priv->next_layout.configured_width = width; + priv->next_layout.configured_height = height; + priv->next_layout.surface_geometry_dirty = TRUE; gdk_surface_request_layout (surface); maybe_notify_mapped (surface); diff --git a/gdk/wayland/gdksurface-wayland.h b/gdk/wayland/gdksurface-wayland.h index 0c73298fa6f..b631704032b 100644 --- a/gdk/wayland/gdksurface-wayland.h +++ b/gdk/wayland/gdksurface-wayland.h @@ -24,113 +24,9 @@ #include "gdkprivate-wayland.h" -typedef enum _PopupState -{ - POPUP_STATE_IDLE, - POPUP_STATE_WAITING_FOR_REPOSITIONED, - POPUP_STATE_WAITING_FOR_CONFIGURE, - POPUP_STATE_WAITING_FOR_FRAME, -} PopupState; - struct _GdkWaylandSurface { GdkSurface parent_instance; - - struct { - /* The wl_outputs that this surface currently touches */ - GSList *outputs; - - struct wl_surface *wl_surface; - - struct xdg_surface *xdg_surface; - struct xdg_popup *xdg_popup; - - /* Legacy xdg-shell unstable v6 fallback support */ - struct zxdg_surface_v6 *zxdg_surface_v6; - struct zxdg_popup_v6 *zxdg_popup_v6; - - struct wl_egl_window *egl_window; - struct wl_egl_window *dummy_egl_window; - } display_server; - - struct wl_event_queue *event_queue; - - EGLSurface egl_surface; - EGLSurface dummy_egl_surface; - - uint32_t reposition_token; - uint32_t received_reposition_token; - - PopupState popup_state; - - unsigned int initial_configure_received : 1; - unsigned int has_uncommitted_ack_configure : 1; - unsigned int mapped : 1; - unsigned int awaiting_frame : 1; - unsigned int awaiting_frame_frozen : 1; - unsigned int is_drag_surface : 1; - - int pending_buffer_offset_x; - int pending_buffer_offset_y; - - GdkSeat *grab_input_seat; - - gint64 pending_frame_counter; - guint32 scale; - - int shadow_left; - int shadow_right; - int shadow_top; - int shadow_bottom; - gboolean shadow_dirty; - - cairo_region_t *opaque_region; - gboolean opaque_region_dirty; - - cairo_region_t *input_region; - gboolean input_region_dirty; - - GdkRectangle last_sent_window_geometry; - - gulong parent_surface_committed_handler; - - struct { - GdkPopupLayout *layout; - int unconstrained_width; - int unconstrained_height; - } popup; - - struct { - struct { - int x; - int y; - int width; - int height; - uint32_t repositioned_token; - gboolean has_repositioned_token; - } popup; - - gboolean is_initial_configure; - - uint32_t serial; - gboolean is_dirty; - } pending; - - struct { - struct { - int x; - int y; - } popup; - int configured_width; - int configured_height; - gboolean surface_geometry_dirty; - } next_layout; - - uint32_t last_configure_serial; - - int state_freeze_count; - - GHashTable *shortcuts_inhibitors; }; typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass; -- GitLab