diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index 124bcdd1b7031005f51127895e566239e87bdea2..7561a1589457aa063c445331d217cc7d47a0ae4f 100644
--- a/gdk/wayland/gdksurface-wayland.c
+++ b/gdk/wayland/gdksurface-wayland.c
@@ -72,7 +72,6 @@
#define SURFACE_IS_TOPLEVEL(surface) TRUE
-#define MAX_WL_BUFFER_SIZE (4083) /* 4096 minus header, string argument length and NUL byte */
typedef enum _PopupState
{
@@ -82,10 +81,8 @@ typedef enum _PopupState
POPUP_STATE_WAITING_FOR_FRAME,
} PopupState;
-struct _GdkWaylandSurface
+struct _GdkWaylandSurfacePrivate
{
- GdkSurface parent_instance;
-
struct {
/* The wl_outputs that this surface currently touches */
GSList *outputs;
@@ -93,19 +90,14 @@ 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;
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;
@@ -128,22 +120,6 @@ struct _GdkWaylandSurface
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;
@@ -155,8 +131,6 @@ struct _GdkWaylandSurface
int shadow_bottom;
gboolean shadow_dirty;
- struct wl_output *initial_fullscreen_output;
-
cairo_region_t *opaque_region;
gboolean opaque_region_dirty;
@@ -164,20 +138,9 @@ 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;
-
- int saved_width;
- int saved_height;
gulong parent_surface_committed_handler;
- struct {
- GdkToplevelLayout *layout;
- } toplevel;
-
struct {
GdkPopupLayout *layout;
int unconstrained_width;
@@ -185,13 +148,6 @@ struct _GdkWaylandSurface
} popup;
struct {
- struct {
- int width;
- int height;
- GdkToplevelState state;
- gboolean is_resizing;
- } toplevel;
-
struct {
int x;
int y;
@@ -207,16 +163,7 @@ struct _GdkWaylandSurface
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;
@@ -230,44 +177,11 @@ 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;
-
- 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 _GdkWaylandSurfacePrivate GdkWaylandSurfacePrivate;
-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))
+G_DEFINE_TYPE_WITH_PRIVATE (GdkWaylandSurface, gdk_wayland_surface, GDK_TYPE_SURFACE)
struct _GdkWaylandPopup
{
@@ -313,15 +227,10 @@ 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_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,
@@ -335,99 +244,68 @@ static void update_popup_layout_state (GdkSurface *surface,
int height,
GdkPopupLayout *layout);
-static gboolean gdk_wayland_surface_is_exported (GdkWaylandSurface *impl);
-
-static void configure_toplevel_geometry (GdkSurface *surface);
static void
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);
+ 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);
-}
-
-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)
-{
- 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;
+ g_assert (!priv->display_server.xdg_popup);
}
-static void
+void
gdk_wayland_surface_update_size (GdkSurface *surface,
int32_t width,
int32_t height,
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);
@@ -441,20 +319,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)
@@ -530,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);
}
@@ -544,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);
@@ -557,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:
@@ -573,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;
}
@@ -654,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);
}
@@ -673,28 +540,35 @@ 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
+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)
{
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)
{
- 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);
-
- impl->next_layout.surface_geometry_dirty = FALSE;
+ gdk_wayland_surface_configure_geometry (surface);
+ priv->next_layout.surface_geometry_dirty = FALSE;
}
return FALSE;
@@ -704,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
@@ -756,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);
}
}
@@ -775,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;
@@ -786,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);
@@ -799,8 +680,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,
@@ -851,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)
{
@@ -876,14 +756,11 @@ _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);
}
}
- 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);
@@ -900,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;
@@ -910,34 +788,40 @@ 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);
}
}
-void
-gdk_wayland_surface_sync (GdkSurface *surface)
+static void
+gdk_wayland_surface_sync_real (GdkSurface *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)
{
@@ -952,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
@@ -967,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);
@@ -989,26 +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);
- 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);
- 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);
+ 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);
}
@@ -1016,26 +894,20 @@ 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_toplevel (GdkWaylandSurface *impl)
-{
- return (impl->display_server.xdg_toplevel ||
- impl->display_server.zxdg_toplevel_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_show (GdkSurface *surface,
- gboolean already_mapped);
static void gdk_wayland_surface_hide (GdkSurface *surface);
static void
@@ -1045,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
@@ -1062,140 +935,42 @@ 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);
}
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
-gdk_wayland_surface_sync_title (GdkSurface *surface)
+gdk_wayland_surface_get_window_geometry_real (GdkSurface *surface,
+ GdkRectangle *geometry)
{
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;
+ GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl);
- 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 ();
- }
+ *geometry = (GdkRectangle) {
+ .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)
+ };
}
-static void
-gdk_wayland_surface_get_window_geometry (GdkSurface *surface,
+void
+gdk_wayland_surface_get_window_geometry (GdkSurface *surface,
GdkRectangle *geometry)
{
- GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (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)
- };
+ GDK_WAYLAND_SURFACE_GET_CLASS(surface)->get_window_geometry(surface, geometry);
}
-static void gdk_wayland_surface_set_geometry_hints (GdkWaylandSurface *impl,
- const GdkGeometry *geometry,
- GdkSurfaceHints geom_mask);
-
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;
@@ -1204,24 +979,21 @@ gdk_wayland_surface_sync_shadow (GdkSurface *surface)
return;
gdk_wayland_surface_get_window_geometry (surface, &geometry);
- gdk_wayland_surface_set_geometry_hints (impl,
- &impl->geometry_hints,
- impl->geometry_mask);
- 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,
@@ -1231,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 *
@@ -1260,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
@@ -1311,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);
@@ -1332,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);
@@ -1356,247 +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;
-}
-
-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
-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 ();
- }
+ 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->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;
+ 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:
@@ -1605,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;
@@ -1617,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);
}
@@ -1638,73 +1205,74 @@ maybe_notify_mapped (GdkSurface *surface)
}
static void
-gdk_wayland_surface_configure (GdkSurface *surface)
+gdk_wayland_surface_configure_surface_real (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_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 ();
-
- 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)
+gdk_wayland_surface_configure_surface (GdkSurface *surface)
{
- 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);
+ GDK_WAYLAND_SURFACE_GET_CLASS(surface)->configure_surface(surface);
}
static void
-gdk_wayland_surface_handle_configure_toplevel (GdkSurface *surface,
- int32_t width,
- int32_t height,
- GdkToplevelState state)
+gdk_wayland_surface_configure (GdkSurface *surface)
{
- GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (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 (!priv->initial_configure_received)
+ {
+ gdk_surface_thaw_updates (surface);
+ priv->initial_configure_received = TRUE;
+ priv->pending.is_initial_configure = TRUE;
+ maybe_notify_mapped (surface);
+ }
+
+ 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 (priv->display_server.xdg_surface,
+ priv->pending.serial);
+ break;
+ case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
+ zxdg_surface_v6_ack_configure (priv->display_server.zxdg_surface_v6,
+ priv->pending.serial);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
- impl->pending.toplevel.state |= state;
- impl->pending.toplevel.width = width;
- impl->pending.toplevel.height = height;
+ priv->last_configure_serial = priv->pending.serial;
+
+ memset (&priv->pending, 0, sizeof (priv->pending));
}
static void
-gdk_wayland_surface_handle_close (GdkSurface *surface)
+gdk_wayland_surface_handle_configure (GdkSurface *surface,
+ uint32_t serial)
{
- GdkDisplay *display;
- GdkEvent *event;
-
- display = gdk_surface_get_display (surface);
+ GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+ GdkWaylandSurfacePrivate *priv = gdk_wayland_surface_get_instance_private (impl);
- GDK_DISPLAY_NOTE (display, EVENTS, g_message ("close %p", surface));
+ priv->pending.is_dirty = TRUE;
+ priv->pending.serial = serial;
- event = gdk_delete_event_new (surface);
+ if (priv->state_freeze_count > 0)
+ return;
- _gdk_wayland_display_deliver_event (display, event);
+ gdk_wayland_surface_configure (surface);
}
static void
@@ -1735,30 +1303,31 @@ 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 =
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;
@@ -1767,253 +1336,6 @@ 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)
-{
- 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 ();
- }
-}
-
-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,
@@ -2022,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
@@ -2060,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 = {
@@ -2240,87 +1564,13 @@ 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,
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;
@@ -2333,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);
@@ -2520,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;
@@ -2617,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;
@@ -2695,20 +1946,17 @@ 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))
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");
@@ -2730,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);
@@ -2754,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)
{
@@ -2770,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 ();
@@ -2781,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);
}
@@ -2805,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;
}
@@ -2827,47 +2078,15 @@ 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;
-}
-
-static void
+void
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);
-
- gdk_wayland_surface_map_toplevel (surface);
}
static void
@@ -2896,93 +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_toplevel)
+ if (priv->display_server.xdg_popup)
{
- xdg_toplevel_destroy (impl->display_server.xdg_toplevel);
- impl->display_server.xdg_toplevel = NULL;
- }
- else if (impl->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_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 (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);
@@ -2997,43 +2207,23 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
g_assert_not_reached ();
}
- 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;
+ 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->toplevel.layout, gdk_toplevel_layout_unref);
- 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;
+ priv->has_uncommitted_ack_configure = FALSE;
+ priv->input_region_dirty = TRUE;
- 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;
-
- _gdk_wayland_surface_clear_saved_size (surface);
- impl->mapped = FALSE;
+ priv->last_sent_window_geometry = (GdkRectangle) { 0 };
+ priv->mapped = FALSE;
}
static void
@@ -3061,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;
}
@@ -3093,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);
}
@@ -3111,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, "
@@ -3136,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);
@@ -3156,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;
@@ -3180,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;
@@ -3203,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
@@ -3216,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);
@@ -3247,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:
@@ -3274,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)
{
@@ -3316,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;
@@ -3414,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
@@ -3440,7 +2644,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);
@@ -3451,693 +2655,27 @@ gdk_wayland_surface_destroy (GdkSurface *surface,
}
static void
-gdk_wayland_surface_focus (GdkSurface *surface,
- guint32 timestamp)
+gdk_wayland_surface_destroy_notify (GdkSurface *surface)
{
- GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
-
- if (!impl->display_server.gtk_surface)
- return;
-
- if (timestamp == GDK_CURRENT_TIME)
+ if (!GDK_SURFACE_DESTROYED (surface))
{
- GdkWaylandDisplay *display_wayland =
- GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
+ g_warning ("GdkSurface %p unexpectedly destroyed", surface);
+ _gdk_surface_destroy (surface, TRUE);
+ }
- 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_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_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_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)
-{
- if (!GDK_SURFACE_DESTROYED (surface))
- {
- g_warning ("GdkSurface %p unexpectedly destroyed", surface);
- _gdk_surface_destroy (surface, TRUE);
- }
-
- g_object_unref (surface);
-}
+ g_object_unref (surface);
+}
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
@@ -4145,75 +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;
-}
-
-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;
+ g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
+ priv->opaque_region = cairo_region_reference (region);
+ priv->opaque_region_dirty = TRUE;
}
static void
@@ -4241,6 +2718,10 @@ 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;
+ klass->get_window_geometry = gdk_wayland_surface_get_window_geometry_real;
+ klass->configure_surface = gdk_wayland_surface_configure_surface_real;
}
void
@@ -4248,399 +2729,183 @@ _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;
}
/**
* gdk_wayland_surface_get_wl_surface: (skip)
* @surface: (type GdkWaylandSurface): a `GdkSurface`
*
- * Returns the Wayland `wl_surface` of a `GdkSurface`.
- *
- * Returns: (transfer none): a Wayland `wl_surface`
- */
-struct wl_surface *
-gdk_wayland_surface_get_wl_surface (GdkSurface *surface)
-{
- g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
-
- return GDK_WAYLAND_SURFACE (surface)->display_server.wl_surface;
-}
-
-struct wl_output *
-gdk_wayland_surface_get_wl_output (GdkSurface *surface)
-{
- GdkWaylandSurface *impl;
-
- g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
-
- impl = GDK_WAYLAND_SURFACE (surface);
- /* 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;
-
- return NULL;
-}
-
-static struct wl_egl_window *
-gdk_wayland_surface_get_wl_egl_window (GdkSurface *surface)
-{
- GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
-
- if (impl->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);
- }
-
- return impl->display_server.egl_window;
-}
-
-EGLSurface
-gdk_wayland_surface_get_egl_surface (GdkSurface *surface,
- EGLConfig config)
-{
- GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
- GdkWaylandSurface *impl;
- struct wl_egl_window *egl_window;
-
- g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
-
- impl = GDK_WAYLAND_SURFACE (surface);
-
- if (impl->egl_surface == NULL)
- {
- egl_window = gdk_wayland_surface_get_wl_egl_window (surface);
-
- impl->egl_surface =
- eglCreateWindowSurface (display->egl_display, config, egl_window, NULL);
- }
-
- return impl->egl_surface;
-}
-
-EGLSurface
-gdk_wayland_surface_get_dummy_egl_surface (GdkSurface *surface,
- EGLConfig config)
-{
- GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
- GdkWaylandSurface *impl;
-
- g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
-
- 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;
-
- 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);
-}
-
-void
-_gdk_wayland_surface_offset_next_wl_buffer (GdkSurface *surface,
- int x,
- int y)
-{
- GdkWaylandSurface *impl;
-
- g_return_if_fail (GDK_IS_WAYLAND_SURFACE (surface));
-
- impl = GDK_WAYLAND_SURFACE (surface);
-
- impl->pending_buffer_offset_x = x;
- 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
- * @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;
-}
-
-/**
- * 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.
+ * Returns the Wayland `wl_surface` of a `GdkSurface`.
*
- * Return value: %TRUE if the handle has been requested, %FALSE if
- * an error occurred.
+ * Returns: (transfer none): a Wayland `wl_surface`
*/
-gboolean
-gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel,
- GdkWaylandToplevelExported callback,
- gpointer user_data,
- GDestroyNotify destroy_func)
+struct wl_surface *
+gdk_wayland_surface_get_wl_surface (GdkSurface *surface)
{
GdkWaylandSurface *impl;
- GdkWaylandDisplay *display_wayland;
- GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (toplevel));
- struct zxdg_exported_v1 *xdg_exported;
+ GdkWaylandSurfacePrivate *priv;
- g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE);
- g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE);
+ g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
- impl = GDK_WAYLAND_SURFACE (toplevel);
- display_wayland = GDK_WAYLAND_DISPLAY (display);
+ impl = GDK_WAYLAND_SURFACE (surface);
+ priv = gdk_wayland_surface_get_instance_private (impl);
+ return priv->display_server.wl_surface;
+}
- g_return_val_if_fail (!impl->display_server.xdg_exported, FALSE);
+struct wl_output *
+gdk_wayland_surface_get_wl_output (GdkSurface *surface)
+{
+ GdkWaylandSurface *impl;
+ GdkWaylandSurfacePrivate *priv;
- if (!display_wayland->xdg_exporter)
- {
- g_warning ("Server is missing xdg_foreign support");
- return FALSE;
- }
+ g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
- 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 = 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 (priv->display_server.outputs)
+ return (struct wl_output *) priv->display_server.outputs->data;
- impl->display_server.xdg_exported = xdg_exported;
- impl->exported.callback = callback;
- impl->exported.user_data = user_data;
- impl->exported.destroy_func = destroy_func;
+ return NULL;
+}
- return TRUE;
+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);
+
+ impl = GDK_WAYLAND_SURFACE (surface);
+ priv = gdk_wayland_surface_get_instance_private (impl);
+ return priv->display_server.xdg_surface;
}
-/**
- * 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)
+struct zxdg_surface_v6 *
+gdk_wayland_surface_get_zxdg_surface_v6 (GdkSurface *surface)
{
GdkWaylandSurface *impl;
+ GdkWaylandSurfacePrivate *priv;
- g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel));
+ g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
- impl = GDK_WAYLAND_SURFACE (toplevel);
+ impl = GDK_WAYLAND_SURFACE (surface);
+ priv = gdk_wayland_surface_get_instance_private (impl);
+ return priv->display_server.zxdg_surface_v6;
+}
- g_return_if_fail (impl->display_server.xdg_exported);
+struct wl_event_queue *
+gdk_wayland_surface_get_event_queue (GdkSurface *surface)
+{
+ GdkWaylandSurface *impl;
+ GdkWaylandSurfacePrivate *priv;
- 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);
- }
+ g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
+
+ impl = GDK_WAYLAND_SURFACE (surface);
+ priv = gdk_wayland_surface_get_instance_private (impl);
+ return priv->event_queue;
}
-static void
-unset_transient_for_exported (GdkSurface *surface)
+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 (priv->display_server.egl_window == NULL)
+ {
+ 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);
+ }
- g_clear_pointer (&impl->imported_transient_for, zxdg_imported_v1_destroy);
+ return priv->display_server.egl_window;
}
-static void
-xdg_imported_destroyed (void *data,
- struct zxdg_imported_v1 *zxdg_imported_v1)
+EGLSurface
+gdk_wayland_surface_get_egl_surface (GdkSurface *surface,
+ EGLConfig config)
{
- GdkSurface *surface = data;
+ GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
+ GdkWaylandSurface *impl;
+ GdkWaylandSurfacePrivate *priv;
+ struct wl_egl_window *egl_window;
- unset_transient_for_exported (surface);
-}
+ g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
-static const struct zxdg_imported_v1_listener xdg_imported_listener = {
- xdg_imported_destroyed,
-};
+ impl = GDK_WAYLAND_SURFACE (surface);
+ priv = gdk_wayland_surface_get_instance_private (impl);
-/**
- * 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)
+ if (priv->egl_surface == NULL)
+ {
+ egl_window = gdk_wayland_surface_get_wl_egl_window (surface);
+
+ priv->egl_surface =
+ eglCreateWindowSurface (display->egl_display, config, egl_window, NULL);
+ }
+
+ return priv->egl_surface;
+}
+
+EGLSurface
+gdk_wayland_surface_get_dummy_egl_surface (GdkSurface *surface,
+ EGLConfig config)
{
+ GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkWaylandSurface *impl;
- GdkWaylandDisplay *display_wayland;
- GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (toplevel));
+ GdkWaylandSurfacePrivate *priv;
- g_return_val_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel), FALSE);
- g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE);
+ g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
- impl = GDK_WAYLAND_SURFACE (toplevel);
- display_wayland = GDK_WAYLAND_DISPLAY (display);
+ impl = GDK_WAYLAND_SURFACE (surface);
+ priv = gdk_wayland_surface_get_instance_private (impl);
- if (!display_wayland->xdg_importer)
+ if (priv->dummy_egl_surface == NULL)
{
- g_warning ("Server is missing xdg_foreign support");
- return FALSE;
+ priv->display_server.dummy_egl_window =
+ wl_egl_window_create (priv->display_server.wl_surface, 1, 1);
+
+ priv->dummy_egl_surface =
+ eglCreateWindowSurface (display->egl_display, config, priv->display_server.dummy_egl_window, NULL);
}
- gdk_wayland_toplevel_set_transient_for (GDK_WAYLAND_TOPLEVEL (impl), NULL);
+ return priv->dummy_egl_surface;
+}
- 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);
+void
+_gdk_wayland_surface_offset_next_wl_buffer (GdkSurface *surface,
+ int x,
+ int y)
+{
+ GdkWaylandSurface *impl;
+ GdkWaylandSurfacePrivate *priv;
- gdk_wayland_surface_sync_parent_of_imported (impl);
+ g_return_if_fail (GDK_IS_WAYLAND_SURFACE (surface));
- return TRUE;
+ impl = GDK_WAYLAND_SURFACE (surface);
+ priv = gdk_wayland_surface_get_instance_private (impl);
+
+ priv->pending_buffer_offset_x = x;
+ priv->pending_buffer_offset_y = y;
}
-static struct zwp_keyboard_shortcuts_inhibitor_v1 *
+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);
}
/*
@@ -4654,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;
@@ -4670,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);
}
/*
@@ -4686,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);
@@ -4693,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;
}
@@ -4821,296 +3093,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)
{
@@ -5128,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 8efa4be04dfbb9a351e89c5892e9557bf6497364..b631704032ba905d8b8ec2239e13aa6ea5b87577 100644
--- a/gdk/wayland/gdksurface-wayland.h
+++ b/gdk/wayland/gdksurface-wayland.h
@@ -22,6 +22,25 @@
#include "gdkwaylandsurface.h"
+#include "gdkprivate-wayland.h"
+
+struct _GdkWaylandSurface
+{
+ GdkSurface parent_instance;
+};
+
+typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass;
+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))
+#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,
@@ -38,4 +57,32 @@ void gdk_wayland_toplevel_announce_ssd (GdkTopl
gboolean gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel);
void gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel);
+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
+gdk_wayland_surface_create_xdg_surface_resources (GdkSurface *surface);
+
+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);
+
+struct xdg_surface *
+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
new file mode 100644
index 0000000000000000000000000000000000000000..5e43246803fcf5c0ca38f53fda53db72b2fc1d1e
--- /dev/null
+++ b/gdk/wayland/gdktoplevel-wayland.c
@@ -0,0 +1,2285 @@
+/*
+ * 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
+
+#define MAX_WL_BUFFER_SIZE (4083) /* 4096 minus header, string argument length and NUL byte */
+
+typedef struct
+{
+ GdkWaylandSurfaceClass parent_class;
+} GdkWaylandToplevelClass;
+
+struct _GdkWaylandToplevel
+{
+ GdkWaylandSurface parent_instance;
+
+ GdkWaylandToplevel *transient_for;
+
+ 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 gtk_surface1 *gtk_surface;
+ struct zxdg_imported_v1 *imported_transient_for;
+
+ char *title;
+ int saved_width;
+ int saved_height;
+
+ unsigned int mapped : 1;
+
+ 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;
+
+ int shadow_left;
+ int shadow_right;
+ int shadow_top;
+ int shadow_bottom;
+
+ 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;
+ } initial_state;
+
+ struct {
+ int width;
+ int height;
+ GdkToplevelState state;
+ gboolean is_resizing;
+ } pending;
+
+ struct {
+ gboolean should_constrain;
+ gboolean size_is_fixed;
+ gboolean surface_geometry_dirty;
+ int configured_width;
+ int configured_height;
+ } next_layout;
+
+ struct {
+ GdkWaylandToplevelExported callback;
+ 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);
+
+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 gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface);
+static void maybe_set_gtk_surface_dbus_properties (GdkWaylandToplevel *impl);
+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 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_toplevel (GdkWaylandToplevel *impl)
+{
+ return (impl->xdg_toplevel ||
+ impl->zxdg_toplevel_v6);
+}
+
+static void
+_gdk_wayland_surface_save_size (GdkSurface *surface)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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)
+{
+ 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 *
+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)
+{
+ gdk_wayland_surface_sync_geometry_hints (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);
+
+ 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);
+ 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);
+}
+
+static void
+gdk_wayland_surface_sync_parent (GdkSurface *surface,
+ GdkSurface *parent)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface);
+ GdkWaylandDisplay *display_wayland =
+ GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
+ GdkWaylandToplevel *impl_parent = NULL;
+
+ g_assert (parent == NULL ||
+ gdk_surface_get_display (surface) == gdk_surface_get_display (parent));
+
+ if (!is_realized_toplevel (impl))
+ return;
+
+ if (impl->transient_for)
+ impl_parent = GDK_WAYLAND_TOPLEVEL (impl->transient_for);
+ else if (parent)
+ impl_parent = GDK_WAYLAND_TOPLEVEL (parent);
+
+ /* XXX: Is this correct? */
+ if (impl_parent && !gdk_wayland_surface_get_wl_surface (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->xdg_toplevel;
+ else
+ parent_toplevel = NULL;
+
+ xdg_toplevel_set_parent (impl->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->zxdg_toplevel_v6;
+ else
+ parent_toplevel = NULL;
+
+ zxdg_toplevel_v6_set_parent (impl->zxdg_toplevel_v6,
+ parent_toplevel);
+ break;
+ }
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+gdk_wayland_surface_sync_parent_of_imported (GdkWaylandToplevel *impl)
+{
+ if (!gdk_wayland_surface_get_wl_surface (GDK_SURFACE (impl)))
+ return;
+
+ if (!impl->imported_transient_for)
+ return;
+
+ if (!is_realized_toplevel (impl))
+ return;
+
+ zxdg_imported_v1_set_parent_of (impl->imported_transient_for,
+ gdk_wayland_surface_get_wl_surface (GDK_SURFACE(impl)));
+}
+
+static void
+gdk_wayland_surface_sync_title (GdkSurface *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 (!impl->title)
+ return;
+
+ switch (display_wayland->shell_variant)
+ {
+ case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL:
+ xdg_toplevel_set_title (impl->xdg_toplevel,
+ impl->title);
+ break;
+ case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
+ zxdg_toplevel_v6_set_title (impl->zxdg_toplevel_v6,
+ impl->title);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+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,
+ GdkSurfaceHints geom_mask);
+
+static void
+gdk_wayland_surface_sync_geometry_hints (GdkSurface *surface)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface);
+ GdkRectangle geometry;
+
+ if (!is_realized_toplevel (impl))
+ return;
+
+ gdk_wayland_surface_get_window_geometry (surface, &geometry);
+ gdk_wayland_surface_set_geometry_hints (GDK_WAYLAND_SURFACE (surface),
+ &impl->geometry_hints,
+ impl->geometry_mask);
+}
+
+static void
+configure_toplevel_geometry (GdkSurface *surface)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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->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 (GDK_WAYLAND_SURFACE (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.should_constrain)
+ {
+ gdk_surface_constrain_size (&impl->geometry_hints,
+ impl->geometry_mask,
+ width, height,
+ &width, &height);
+ }
+ gdk_wayland_surface_update_size (surface, width, height, gdk_surface_get_scale_factor (surface));
+
+ if (!impl->next_layout.size_is_fixed)
+ {
+ impl->next_layout.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, gdk_surface_get_scale_factor (surface));
+ }
+}
+
+
+static gboolean
+gdk_wayland_toplevel_compute_size (GdkSurface *surface)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface);
+
+ impl->next_layout.surface_geometry_dirty = TRUE;
+}
+
+static void
+synthesize_initial_surface_state (GdkSurface *surface,
+ GdkToplevelState unset_flags,
+ GdkToplevelState set_flags)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface);
+ GdkToplevelState new_state;
+ int width, height;
+ gboolean is_resizing;
+ gboolean fixed_size;
+ gboolean saved_size;
+
+ new_state = impl->pending.state;
+ impl->pending.state = 0;
+
+ is_resizing = impl->pending.is_resizing;
+ impl->pending.is_resizing = FALSE;
+
+ fixed_size =
+ new_state & (GDK_TOPLEVEL_STATE_MAXIMIZED |
+ GDK_TOPLEVEL_STATE_FULLSCREEN |
+ GDK_TOPLEVEL_STATE_TILED) ||
+ is_resizing;
+
+ 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
+ * 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.should_constrain = TRUE;
+
+ /* Save size for next time we get 0x0 */
+ _gdk_wayland_surface_save_size (surface);
+ }
+ else if (is_resizing)
+ {
+ impl->next_layout.should_constrain = TRUE;
+ }
+ else
+ {
+ impl->next_layout.should_constrain = FALSE;
+ }
+
+ impl->next_layout.size_is_fixed = fixed_size;
+ 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;
+ impl->next_layout.configured_width = 0;
+ impl->next_layout.configured_height = 0;
+ }
+
+ 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);
+}
+
+static void
+gdk_wayland_surface_handle_configure_toplevel (GdkSurface *surface,
+ int32_t width,
+ int32_t height,
+ GdkToplevelState state)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface);
+
+ impl->pending.state |= state;
+ impl->pending.width = width;
+ impl->pending.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_toplevel_configure (void *data,
+ struct xdg_toplevel *xdg_toplevel,
+ int32_t width,
+ int32_t height,
+ struct wl_array *states)
+{
+ GdkSurface *surface = GDK_SURFACE (data);
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface);
+ uint32_t *p;
+ GdkToplevelState pending_state = 0;
+
+ impl->pending.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.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);
+
+ GDK_WAYLAND_TOPLEVEL(impl)->xdg_toplevel =
+ 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);
+}
+
+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);
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface);
+ uint32_t *p;
+ GdkToplevelState pending_state = 0;
+
+ impl->pending.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.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);
+
+ GDK_WAYLAND_TOPLEVEL(impl)->zxdg_toplevel_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);
+}
+
+/**
+ * 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)
+{
+ GdkWaylandToplevel *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_TOPLEVEL (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->xdg_toplevel,
+ application_id);
+ break;
+ case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
+ zxdg_toplevel_v6_set_app_id (impl->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));
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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->xdg_toplevel);
+ if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED)
+ xdg_toplevel_set_minimized (impl->xdg_toplevel);
+ 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 (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MAXIMIZED)
+ zxdg_toplevel_v6_set_maximized (impl->zxdg_toplevel_v6);
+ if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_MINIMIZED)
+ zxdg_toplevel_v6_set_minimized (impl->zxdg_toplevel_v6);
+ if (impl->initial_state.set_flags & GDK_TOPLEVEL_STATE_FULLSCREEN)
+ zxdg_toplevel_v6_set_fullscreen (impl->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 (gdk_wayland_surface_get_wl_surface (surface));
+}
+
+void
+gdk_wayland_toplevel_announce_csd (GdkToplevel *toplevel)
+{
+ GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_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->server_decoration =
+ org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager,
+ 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);
+}
+
+void
+gdk_wayland_toplevel_announce_ssd (GdkToplevel *toplevel)
+{
+ GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_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->server_decoration =
+ org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager,
+ 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);
+}
+
+
+gboolean
+gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel)
+{
+ GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (toplevel)));
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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,
+ gdk_wayland_surface_get_wl_surface (GDK_SURFACE (impl)));
+ }
+ ++impl->idle_inhibitor_refcount;
+
+ return TRUE;
+}
+
+void
+gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface);
+
+ if (!impl->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,
+ gdk_wayland_surface_get_wl_surface (GDK_SURFACE (impl)));
+ }
+ else if (display_wayland->gtk_shell_version >= 3)
+ {
+ gtk_surface1_request_focus (impl->gtk_surface,
+ display_wayland->startup_notification_id);
+ }
+
+ g_clear_pointer (&display_wayland->startup_notification_id, g_free);
+ }
+ }
+ else
+ gtk_surface1_present (impl->gtk_surface, timestamp);
+}
+
+static void
+gtk_surface_configure (void *data,
+ struct gtk_surface1 *gtk_surface,
+ struct wl_array *states)
+{
+ GdkSurface *surface = GDK_SURFACE (data);
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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.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);
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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.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 (GdkWaylandToplevel *impl)
+{
+ GdkWaylandDisplay *display =
+ GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (impl)));
+
+ if (impl->gtk_surface != NULL)
+ return;
+ if (!is_realized_toplevel (impl))
+ return;
+ if (display->gtk_shell == NULL)
+ return;
+
+ impl->gtk_surface =
+ 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_get_event_queue (GDK_SURFACE (impl)));
+ 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);
+}
+
+static void
+maybe_set_gtk_surface_modal (GdkSurface *surface)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface);
+
+ gdk_wayland_surface_init_gtk_surface (impl);
+ if (impl->gtk_surface == NULL)
+ return;
+
+ if (surface->modal_hint)
+ gtk_surface1_set_modal (impl->gtk_surface);
+ else
+ gtk_surface1_unset_modal (impl->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 *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;
+
+ 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->xdg_toplevel,
+ min_width, min_height);
+ 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->zxdg_toplevel_v6,
+ min_width, min_height);
+ 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;
+}
+
+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)
+{
+}
+
+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)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface);
+ GdkWaylandDisplay *display_wayland;
+
+ if (GDK_SURFACE_DESTROYED (surface) ||
+ !SURFACE_IS_TOPLEVEL (surface))
+ return;
+
+ if (!is_realized_toplevel (impl))
+ 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->xdg_toplevel);
+ break;
+ case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
+ zxdg_toplevel_v6_set_minimized (impl->zxdg_toplevel_v6);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+gdk_wayland_surface_maximize (GdkSurface *surface)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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->xdg_toplevel);
+ break;
+ case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
+ zxdg_toplevel_v6_set_maximized (impl->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)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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->xdg_toplevel);
+ break;
+ case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
+ zxdg_toplevel_v6_unset_maximized (impl->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)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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->xdg_toplevel,
+ output);
+ break;
+ case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
+ zxdg_toplevel_v6_set_fullscreen (impl->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)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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->xdg_toplevel,
+ NULL);
+ break;
+ case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
+ zxdg_toplevel_v6_set_fullscreen (impl->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)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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->xdg_toplevel);
+ break;
+ case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
+ zxdg_toplevel_v6_unset_fullscreen (impl->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);
+ GdkWaylandToplevel *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_TOPLEVEL (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->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->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);
+ GdkWaylandToplevel *impl;
+ GdkWaylandDisplay *display_wayland;
+ GdkEventSequence *sequence;
+ uint32_t serial;
+
+ if (GDK_SURFACE_DESTROYED (surface) ||
+ !SURFACE_IS_TOPLEVEL (surface))
+ return;
+
+ impl = GDK_WAYLAND_TOPLEVEL (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->xdg_toplevel,
+ gdk_wayland_device_get_wl_seat (device),
+ serial);
+ break;
+ case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
+ zxdg_toplevel_v6_move (impl->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)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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->xdg_toplevel,
+ wl_seat, serial, x, y);
+ break;
+ case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
+ zxdg_toplevel_v6_show_window_menu (impl->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)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface);
+ struct gtk_surface1 *gtk_surface = impl->gtk_surface;
+
+ if (!gtk_surface)
+ return FALSE;
+
+ 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 (GdkWaylandToplevel *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->gtk_surface == NULL)
+ return;
+
+ gtk_surface1_set_dbus_properties (impl->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)
+{
+ GdkWaylandToplevel *impl;
+
+ g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel));
+
+ impl = GDK_WAYLAND_TOPLEVEL (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;
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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
+ * @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
+ * @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)
+{
+ GdkWaylandToplevel *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_TOPLEVEL (toplevel);
+ display_wayland = GDK_WAYLAND_DISPLAY (display);
+
+ g_return_val_if_fail (!impl->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,
+ 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;
+ 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)
+{
+ GdkWaylandToplevel *impl;
+
+ g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (toplevel));
+
+ impl = GDK_WAYLAND_TOPLEVEL (toplevel);
+
+ g_return_if_fail (impl->xdg_exported);
+
+ g_clear_pointer (&impl->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)
+{
+ 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)
+{
+ 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)
+{
+ 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_TOPLEVEL (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 *impl)
+{
+ impl->initial_fullscreen_output = NULL;
+ impl->saved_width = -1;
+ impl->saved_height = -1;
+
+ gdk_wayland_toplevel_set_title (GDK_SURFACE (impl), get_default_title ());
+}
+
+#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_toplevel_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, GDK_WAYLAND_TOPLEVEL(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);
+ 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;
+ 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;
+ 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;
+ wayland_surface_class->configure_surface = gdk_wayland_surface_configure_toplevel;
+
+ gdk_toplevel_install_properties (object_class, 1);
+}
+
+static void
+gdk_wayland_surface_map_toplevel (GdkSurface *surface)
+{
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (surface);
+
+ if (impl->mapped)
+ return;
+
+ gdk_wayland_surface_create_xdg_toplevel (surface);
+
+ impl->mapped = TRUE;
+}
+
+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);
+
+ if (impl->xdg_toplevel)
+ {
+ xdg_toplevel_destroy (impl->xdg_toplevel);
+ impl->xdg_toplevel = NULL;
+ }
+ if (impl->zxdg_toplevel_v6)
+ {
+ 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);
+
+ impl->last_sent_min_width = 0;
+ 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);
+
+ unset_transient_for_exported (surface);
+ impl->mapped = FALSE;
+}
+
+static void
+gdk_wayland_toplevel_present (GdkToplevel *toplevel,
+ GdkToplevelLayout *layout)
+{
+ GdkSurface *surface = GDK_SURFACE (toplevel);
+ GdkWaylandToplevel *impl = GDK_WAYLAND_TOPLEVEL (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->layout, gdk_toplevel_layout_unref);
+ impl->layout = gdk_toplevel_layout_copy (layout);
+
+ gdk_wayland_surface_show (surface, FALSE);
+ gdk_wayland_surface_map_toplevel (surface);
+
+ if (!pending_configure)
+ {
+ 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 4e7981a229acc855bac793bc0c8eb80db51d6422..5fb89e8d0f5ba4baed5dc1abeefcc9a469462cb3 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 851a4d5607fea1cdfde191a7fe7b5c351f8f5d1f..c94a3cbd16cb50e4b786ff2133b5f5f3f1aab2af 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 0000000000000000000000000000000000000000..0d0c6a353bb11736148fb9490eee8408fa1149b2
--- /dev/null
+++ b/gdk/wayland/gdkwaylandtoplevel.h
@@ -0,0 +1,67 @@
+/* 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);
+
+G_END_DECLS
+
+#endif /* __GDK_WAYLAND_TOPLEVEL_H__ */
diff --git a/gdk/wayland/meson.build b/gdk/wayland/meson.build
index 28a00a959b6d252b1078c7bfd1bf2c1146346209..5a30e5cd0d75e920756ac311be9e2526a80f5b1e 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([