diff --git a/debian/libmuffin0.symbols b/debian/libmuffin0.symbols index b74edf4ed..999b34fad 100644 --- a/debian/libmuffin0.symbols +++ b/debian/libmuffin0.symbols @@ -879,6 +879,7 @@ libmuffin-clutter-0.so.0 libmuffin0 #MINVER# clutter_modifier_type_get_type@Base 5.3.0 clutter_offscreen_effect_create_texture@Base 5.3.0 clutter_offscreen_effect_get_pipeline@Base 6.6.0 + clutter_offscreen_effect_get_pipeline@Base 6.4.1 clutter_offscreen_effect_get_target@Base 5.3.0 clutter_offscreen_effect_get_target_rect@Base 5.3.0 clutter_offscreen_effect_get_target_size@Base 5.3.0 @@ -2670,6 +2671,7 @@ libmuffin.so.0 libmuffin0 #MINVER# meta_window_kill@Base 5.3.0 meta_window_located_on_workspace@Base 5.3.0 meta_window_lower@Base 5.3.0 + meta_window_lower_with_transients@Base 6.4.1 meta_window_make_above@Base 5.3.0 meta_window_make_fullscreen@Base 5.3.0 meta_window_maximize@Base 5.3.0 diff --git a/src/core/window.c b/src/core/window.c index 4395676f5..363177c35 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -5624,6 +5624,62 @@ meta_window_lower (MetaWindow *window) meta_stack_lower (window->display->stack, window); } +static gboolean +lower_window_and_transients (MetaWindow *window, + gpointer user_data) +{ + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + + meta_window_lower (window); + + meta_window_foreach_transient (window, lower_window_and_transients, NULL); + + if (meta_prefs_get_raise_on_click ()) + { + /* Move window to the back of the focusing workspace's MRU list. + * Do extra sanity checks to avoid possible race conditions. + * (Borrowed from window.c.) + */ + if (workspace_manager->active_workspace && + meta_window_located_on_workspace (window, + workspace_manager->active_workspace)) + { + GList *link; + link = g_list_find (workspace_manager->active_workspace->mru_list, + window); + g_assert (link); + + workspace_manager->active_workspace->mru_list = + g_list_remove_link (workspace_manager->active_workspace->mru_list, + link); + g_list_free (link); + + workspace_manager->active_workspace->mru_list = + g_list_append (workspace_manager->active_workspace->mru_list, + window); + } + } + + return FALSE; +} + +void +meta_window_lower_with_transients (MetaWindow *window, + uint32_t timestamp) +{ + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + + lower_window_and_transients (window, NULL); + + /* Rather than try to figure that out whether we just lowered + * the focus window, assume that's always the case. (Typically, + * this will be invoked via keyboard action or by a mouse action; + * in either case the window or a modal child will have been focused.) */ + meta_workspace_focus_default_window (workspace_manager->active_workspace, + NULL, + timestamp); +} + /* * Move window to the requested workspace; append controls whether new WS * should be created if one does not exist. diff --git a/src/meta/window.h b/src/meta/window.h index 1f670d915..252129f6f 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -317,6 +317,10 @@ void meta_window_raise (MetaWindow *window); META_EXPORT void meta_window_lower (MetaWindow *window); +META_EXPORT +void meta_window_lower_with_transients (MetaWindow *window, + uint32_t timestamp); + META_EXPORT const char *meta_window_get_title (MetaWindow *window); diff --git a/src/wayland/meta-wayland-gtk-shell.c b/src/wayland/meta-wayland-gtk-shell.c index 9c5357b91..d4c67547b 100644 --- a/src/wayland/meta-wayland-gtk-shell.c +++ b/src/wayland/meta-wayland-gtk-shell.c @@ -83,6 +83,9 @@ gtk_surface_set_dbus_properties (struct wl_client *client, MetaWaylandSurface *surface = gtk_surface->surface; MetaWindow *window; + if (!surface) + return; + window = meta_wayland_surface_get_window (surface); if (!window) return; @@ -104,6 +107,9 @@ gtk_surface_set_modal (struct wl_client *client, MetaWaylandSurface *surface = gtk_surface->surface; MetaWindow *window; + if (!surface) + return; + window = meta_wayland_surface_get_window (surface); if (!window) return; @@ -123,6 +129,9 @@ gtk_surface_unset_modal (struct wl_client *client, MetaWaylandSurface *surface = gtk_surface->surface; MetaWindow *window; + if (!surface) + return; + window = meta_wayland_surface_get_window (surface); if (!window) return; @@ -143,6 +152,9 @@ gtk_surface_present (struct wl_client *client, MetaWaylandSurface *surface = gtk_surface->surface; MetaWindow *window; + if (!surface) + return; + window = meta_wayland_surface_get_window (surface); if (!window) return; @@ -162,6 +174,9 @@ gtk_surface_request_focus (struct wl_client *client, MetaStartupSequence *sequence = NULL; MetaWindow *window; + if (!surface) + return; + window = meta_wayland_surface_get_window (surface); if (!window) return; @@ -193,19 +208,119 @@ gtk_surface_request_focus (struct wl_client *client, } } +static void +gtk_surface_titlebar_gesture (struct wl_client *client, + struct wl_resource *resource, + uint32_t serial, + struct wl_resource *seat_resource, + uint32_t gesture) +{ + MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = gtk_surface->surface; + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + CDesktopTitlebarAction action = C_DESKTOP_TITLEBAR_ACTION_NONE; + MetaWindow *window; + float x, y; + + if (!surface) + return; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return; + + + + if (!meta_wayland_seat_get_grab_info (seat, surface, serial, FALSE, &x, &y)) + return; + + switch (gesture) + { + case GTK_SURFACE1_GESTURE_DOUBLE_CLICK: + action = meta_prefs_get_action_double_click_titlebar (); + break; + case GTK_SURFACE1_GESTURE_RIGHT_CLICK: + action = meta_prefs_get_action_right_click_titlebar (); + break; + case GTK_SURFACE1_GESTURE_MIDDLE_CLICK: + action = meta_prefs_get_action_middle_click_titlebar (); + break; + default: + wl_resource_post_error (resource, + GTK_SURFACE1_ERROR_INVALID_GESTURE, + "Invalid gesture passed"); + break; + + } + + switch (action) + { + case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE: + if (META_WINDOW_MAXIMIZED (window)) + meta_window_unmaximize (window, META_MAXIMIZE_BOTH); + else + meta_window_maximize (window, META_MAXIMIZE_BOTH); + break; + + case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_HORIZONTALLY: + if (META_WINDOW_MAXIMIZED_HORIZONTALLY (window)) + meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL); + else + meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL); + break; + + case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_VERTICALLY: + if (META_WINDOW_MAXIMIZED_VERTICALLY (window)) + meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL); + else + meta_window_maximize (window, META_MAXIMIZE_VERTICAL); + break; + + case C_DESKTOP_TITLEBAR_ACTION_MINIMIZE: + meta_window_minimize (window); + break; + + case C_DESKTOP_TITLEBAR_ACTION_LOWER: + { + uint32_t timestamp; + + timestamp = meta_display_get_current_time_roundtrip (window->display); + meta_window_lower_with_transients (window, timestamp); + } + break; + + case C_DESKTOP_TITLEBAR_ACTION_MENU: + meta_window_show_menu (window, META_WINDOW_MENU_WM, x, y); + break; + + case C_DESKTOP_TITLEBAR_ACTION_TOGGLE_SHADE: + g_warning ("No shade! The library is closed."); + G_GNUC_FALLTHROUGH; + default: + return; + } +} + +static void +gtk_surface_release (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + static const struct gtk_surface1_interface meta_wayland_gtk_surface_interface = { gtk_surface_set_dbus_properties, gtk_surface_set_modal, gtk_surface_unset_modal, gtk_surface_present, gtk_surface_request_focus, + gtk_surface_release, + gtk_surface_titlebar_gesture }; static void gtk_surface_surface_destroyed (MetaWaylandGtkSurface *gtk_surface) { - wl_resource_set_implementation (gtk_surface->resource, - NULL, NULL, NULL); gtk_surface->surface = NULL; } diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h index 9898d5be1..98465595b 100644 --- a/src/wayland/meta-wayland-versions.h +++ b/src/wayland/meta-wayland-versions.h @@ -43,7 +43,7 @@ #define META_WL_SEAT_VERSION 5 #define META_WL_OUTPUT_VERSION 4 #define META_XSERVER_VERSION 1 -#define META_GTK_SHELL1_VERSION 3 +#define META_GTK_SHELL1_VERSION 6 #define META_WL_SUBCOMPOSITOR_VERSION 1 #define META_ZWP_POINTER_GESTURES_V1_VERSION 1 #define META_ZXDG_EXPORTER_V1_VERSION 1 diff --git a/src/wayland/protocol/gtk-shell.xml b/src/wayland/protocol/gtk-shell.xml index fb91940b3..3629fb41e 100644 --- a/src/wayland/protocol/gtk-shell.xml +++ b/src/wayland/protocol/gtk-shell.xml @@ -1,6 +1,6 @@ - + gtk_shell is a protocol extension providing additional features for clients implementing it. @@ -33,9 +33,11 @@ + + - + @@ -82,6 +84,28 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/x11/meta-x11-window-control.c b/src/x11/meta-x11-window-control.c index aaf3d7fe1..d72427450 100644 --- a/src/x11/meta-x11-window-control.c +++ b/src/x11/meta-x11-window-control.c @@ -61,62 +61,14 @@ meta_x11_wm_queue_frame_resize (MetaX11Display *x11_display, meta_window_frame_size_changed (window); } -static gboolean -lower_window_and_transients (MetaWindow *window, - gpointer data) -{ - MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; - - meta_window_lower (window); - - meta_window_foreach_transient (window, lower_window_and_transients, NULL); - - if (meta_prefs_get_raise_on_click ()) - { - /* Move window to the back of the focusing workspace's MRU list. - * Do extra sanity checks to avoid possible race conditions. - * (Borrowed from window.c.) - */ - if (workspace_manager->active_workspace && - meta_window_located_on_workspace (window, - workspace_manager->active_workspace)) - { - GList* link; - link = g_list_find (workspace_manager->active_workspace->mru_list, - window); - g_assert (link); - - workspace_manager->active_workspace->mru_list = - g_list_remove_link (workspace_manager->active_workspace->mru_list, - link); - g_list_free (link); - - workspace_manager->active_workspace->mru_list = - g_list_append (workspace_manager->active_workspace->mru_list, - window); - } - } - - return FALSE; -} - void meta_x11_wm_user_lower_and_unfocus (MetaX11Display *x11_display, Window frame_xwindow, uint32_t timestamp) { MetaWindow *window = window_from_frame (x11_display, frame_xwindow); - MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; - - lower_window_and_transients (window, NULL); - /* Rather than try to figure that out whether we just lowered - * the focus window, assume that's always the case. (Typically, - * this will be invoked via keyboard action or by a mouse action; - * in either case the window or a modal child will have been focused.) */ - meta_workspace_focus_default_window (workspace_manager->active_workspace, - NULL, - timestamp); + meta_window_lower_with_transients (window, timestamp); } void