From b3cffb85f39183a83a99e7517191e46bcd744749 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 9 Oct 2013 16:55:55 -0400 Subject: [PATCH] wayland: Support always-on-top / sticky windows Use the new gtk-shell APIs available in mutter to add support for this. https://bugzilla.gnome.org/show_bug.cgi?id=710056 --- gdk/wayland/gdkdisplay-wayland.c | 2 +- gdk/wayland/gdkwindow-wayland.c | 12 ++++++++++- gdk/wayland/protocol/gtk-shell.xml | 32 +++++++++++++++++++++++++--- gtk/gtkwindow.c | 34 +++++++++++++++--------------- 4 files changed, 58 insertions(+), 22 deletions(-) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 71debb944a..f90db8ff48 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -169,7 +169,7 @@ gdk_registry_handle_global(void *data, struct wl_registry *registry, uint32_t id wl_registry_bind(display_wayland->wl_registry, id, &wl_shell_interface, 1); } else if (strcmp(interface, "gtk_shell") == 0) { display_wayland->gtk_shell = - wl_registry_bind(display_wayland->wl_registry, id, >k_shell_interface, 1); + wl_registry_bind(display_wayland->wl_registry, id, >k_shell_interface, 2); _gdk_wayland_screen_set_has_gtk_shell (display_wayland->screen); /* We need another roundtrip to receive the shell capabilities */ wait_for_roundtrip(display_wayland); diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 70abf77da5..e9f2d3bf8a 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -1647,15 +1647,23 @@ gdk_wayland_window_deiconify (GdkWindow *window) static void gdk_wayland_window_stick (GdkWindow *window) { + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + if (GDK_WINDOW_DESTROYED (window)) return; + + gtk_surface_set_on_all_workspaces (impl->gtk_surface, TRUE); } static void gdk_wayland_window_unstick (GdkWindow *window) { + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + if (GDK_WINDOW_DESTROYED (window)) return; + + gtk_surface_set_on_all_workspaces (impl->gtk_surface, FALSE); } static void @@ -1769,10 +1777,12 @@ static void gdk_wayland_window_set_keep_above (GdkWindow *window, gboolean setting) { - g_return_if_fail (GDK_IS_WINDOW (window)); + GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); if (GDK_WINDOW_DESTROYED (window)) return; + + gtk_surface_set_always_on_top (impl->gtk_surface, setting); } static void diff --git a/gdk/wayland/protocol/gtk-shell.xml b/gdk/wayland/protocol/gtk-shell.xml index a4e25653f1..4407cb8981 100644 --- a/gdk/wayland/protocol/gtk-shell.xml +++ b/gdk/wayland/protocol/gtk-shell.xml @@ -1,11 +1,11 @@ - + - + @@ -16,7 +16,7 @@ - + @@ -25,6 +25,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 32f5eeedff..fd690d6314 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -8119,7 +8119,6 @@ ontop_window_clicked (GtkMenuItem *menuitem, gtk_window_set_keep_above (window, !window->priv->above_initially); } -#ifdef GDK_WINDOWING_X11 static void stick_window_clicked (GtkMenuItem *menuitem, gpointer user_data) @@ -8138,6 +8137,7 @@ unstick_window_clicked (GtkMenuItem *menuitem, gtk_window_unstick (window); } +#ifdef GDK_WINDOWING_X11 static void workspace_change_clicked (GtkMenuItem *menuitem, gpointer user_data) @@ -8205,25 +8205,25 @@ gtk_window_do_popup (GtkWindow *window, G_CALLBACK (ontop_window_clicked), window); gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem); + menuitem = gtk_check_menu_item_new_with_label (_("Always on Visible Workspace")); + gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (menuitem), TRUE); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), priv->stick_initially); + gtk_widget_show (menuitem); + g_signal_connect (G_OBJECT (menuitem), "activate", + G_CALLBACK (stick_window_clicked), window); + gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem); + + menuitem = gtk_check_menu_item_new_with_label (_("Only on This Workspace")); + gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (menuitem), TRUE); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), !priv->stick_initially); + gtk_widget_show (menuitem); + g_signal_connect (G_OBJECT (menuitem), "activate", + G_CALLBACK (unstick_window_clicked), window); + gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem); + #ifdef GDK_WINDOWING_X11 if (GDK_IS_X11_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window)))) { - menuitem = gtk_check_menu_item_new_with_label (_("Always on Visible Workspace")); - gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (menuitem), TRUE); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), priv->stick_initially); - gtk_widget_show (menuitem); - g_signal_connect (G_OBJECT (menuitem), "activate", - G_CALLBACK (stick_window_clicked), window); - gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem); - - menuitem = gtk_check_menu_item_new_with_label (_("Only on This Workspace")); - gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (menuitem), TRUE); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), !priv->stick_initially); - gtk_widget_show (menuitem); - g_signal_connect (G_OBJECT (menuitem), "activate", - G_CALLBACK (unstick_window_clicked), window); - gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem); - if (!priv->stick_initially) { guint32 n_desktops, desktop;