diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index d00524f048..d5ac46e1b0 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -584,15 +584,18 @@ gdk_wayland_device_query_state (GdkDevice *device, GdkModifierType *mask) { GdkWaylandPointerData *pointer; + GList *children; if (window == NULL) - window = GDK_WAYLAND_DISPLAY (gdk_device_get_display (device))->root_window; + children = gdk_wayland_display_get_toplevel_windows (gdk_device_get_display (device)); + else + children = window->children; pointer = GDK_WAYLAND_DEVICE (device)->pointer; if (child_window) /* Set child only if actually a child of the given window, as XIQueryPointer() does */ - *child_window = g_list_find (window->children, pointer->focus) ? pointer->focus : NULL; + *child_window = g_list_find (children, pointer->focus) ? pointer->focus : NULL; if (mask) *mask = device_get_modifiers (device); diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 9cfebacad0..f74dd2ad79 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -600,7 +600,6 @@ _gdk_wayland_display_open (const gchar *display_name) display_wayland = GDK_WAYLAND_DISPLAY (display); display_wayland->wl_display = wl_display; - display_wayland->root_window = _gdk_wayland_display_create_root_window (display, 0, 0); display_wayland->event_source = _gdk_wayland_display_event_source_new (display); init_settings (display); @@ -644,13 +643,18 @@ _gdk_wayland_display_open (const gchar *display_name) return display; } +static void +destroy_toplevel (gpointer data) +{ + _gdk_window_destroy (GDK_WINDOW (data), FALSE); +} + static void gdk_wayland_display_dispose (GObject *object) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (object); - if (display_wayland->root_window) - _gdk_window_destroy (display_wayland->root_window, FALSE); + g_list_free_full (display_wayland->toplevels, destroy_toplevel); if (display_wayland->event_source) { @@ -686,9 +690,6 @@ gdk_wayland_display_finalize (GObject *object) _gdk_wayland_display_finalize_cursors (display_wayland); - if (display_wayland->root_window) - g_object_unref (display_wayland->root_window); - g_free (display_wayland->startup_notification_id); g_free (display_wayland->cursor_theme_name); xkb_context_unref (display_wayland->xkb_context); @@ -1062,6 +1063,12 @@ gdk_wayland_display_init (GdkWaylandDisplay *display) display->monitors = g_ptr_array_new_with_free_func (g_object_unref); } +GList * +gdk_wayland_display_get_toplevel_windows (GdkDisplay *display) +{ + return GDK_WAYLAND_DISPLAY (display)->toplevels; +} + void gdk_wayland_display_set_cursor_theme (GdkDisplay *display, const gchar *name, @@ -1899,6 +1906,14 @@ transform_to_string (int transform) #endif +static void +update_scale (GdkDisplay *display) +{ + g_list_foreach (gdk_wayland_display_get_toplevel_windows (display), + (GFunc)gdk_wayland_window_update_scale, + NULL); +} + static void output_handle_geometry (void *data, struct wl_output *wl_output, @@ -1924,10 +1939,7 @@ output_handle_geometry (void *data, gdk_monitor_set_model (GDK_MONITOR (monitor), model); if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE) - { - GdkDisplay *display = GDK_MONITOR (monitor)->display; - window_update_scale (GDK_WAYLAND_DISPLAY (display)->root_window); - } + update_scale (GDK_MONITOR (monitor)->display); } static void @@ -1947,7 +1959,7 @@ output_handle_done (void *data, gdk_display_monitor_added (display, GDK_MONITOR (monitor)); } - window_update_scale (GDK_WAYLAND_DISPLAY (display)->root_window); + update_scale (display); } static void @@ -1974,7 +1986,7 @@ output_handle_scale (void *data, gdk_monitor_set_size (GDK_MONITOR (monitor), width / scale, height / scale); if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE) - window_update_scale (GDK_WAYLAND_DISPLAY (GDK_MONITOR (monitor)->display)->root_window); + update_scale (GDK_MONITOR (monitor)->display); } static void @@ -2000,7 +2012,7 @@ output_handle_mode (void *data, gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh); if (width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE) - window_update_scale (GDK_WAYLAND_DISPLAY (GDK_MONITOR (monitor)->display)->root_window); + update_scale (GDK_MONITOR (monitor)->display); } static const struct wl_output_listener output_listener = @@ -2093,7 +2105,7 @@ gdk_wayland_display_remove_output (GdkWaylandDisplay *display_wayland, g_object_ref (monitor); g_ptr_array_remove (display_wayland->monitors, monitor); gdk_display_monitor_removed (GDK_DISPLAY (display_wayland), GDK_MONITOR (monitor)); - window_update_scale (display_wayland->root_window); + update_scale (GDK_DISPLAY (display_wayland)); g_object_unref (monitor); } } diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h index ed59818590..c38c810153 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -64,7 +64,7 @@ typedef struct { struct _GdkWaylandDisplay { GdkDisplay parent_instance; - GdkWindow *root_window; + GList *toplevels; GHashTable *settings; GsdXftSettings xft_settings; diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index 223b963b48..98789d6ae3 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -199,6 +199,8 @@ GdkWindow *_gdk_wayland_display_create_root_window (GdkDisplay *display, int width, int height); +GList *gdk_wayland_display_get_toplevel_windows (GdkDisplay *display); + int gdk_wayland_display_get_output_refresh_rate (GdkWaylandDisplay *display_wayland, struct wl_output *output); guint32 gdk_wayland_display_get_output_scale (GdkWaylandDisplay *display_wayland, @@ -265,7 +267,7 @@ void gdk_wayland_window_inhibit_shortcuts (GdkWindow *window, void gdk_wayland_window_restore_shortcuts (GdkWindow *window, GdkSeat *gdk_seat); -void window_update_scale (GdkWindow *window); +void gdk_wayland_window_update_scale (GdkWindow *window); #endif /* __GDK_PRIVATE_WAYLAND_H__ */ diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 03396528ed..235c4e97c5 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -610,7 +610,7 @@ on_frame_clock_after_paint (GdkFrameClock *clock, } void -window_update_scale (GdkWindow *window) +gdk_wayland_window_update_scale (GdkWindow *window) { GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); @@ -638,7 +638,7 @@ window_update_scale (GdkWindow *window) for (c = children; c; c = c->next) { GdkWindow *child = c->data; - window_update_scale (child); + gdk_wayland_window_update_scale (child); } g_list_free (children); } @@ -693,6 +693,9 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display, break; } + if (real_parent == NULL) + display_wayland->toplevels = g_list_prepend (display_wayland->toplevels, window); + gdk_wayland_window_create_surface (window); frame_clock = gdk_window_get_frame_clock (window); @@ -1238,7 +1241,7 @@ surface_enter (void *data, impl->display_server.outputs = g_slist_prepend (impl->display_server.outputs, output); - window_update_scale (window); + gdk_wayland_window_update_scale (window); } static void @@ -1255,7 +1258,7 @@ surface_leave (void *data, impl->display_server.outputs = g_slist_remove (impl->display_server.outputs, output); if (impl->display_server.outputs) - window_update_scale (window); + gdk_wayland_window_update_scale (window); } static const struct wl_surface_listener surface_listener = { @@ -2835,6 +2838,12 @@ gdk_wayland_window_destroy (GdkWindow *window, gdk_wayland_window_hide_surface (window); drop_cairo_surfaces (window); + + if (window->parent == NULL) + { + GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); + display->toplevels = g_list_remove (display->toplevels, window); + } } static void