Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions debian/libmuffin0.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
56 changes: 56 additions & 0 deletions src/core/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions src/meta/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
119 changes: 117 additions & 2 deletions src/wayland/meta-wayland-gtk-shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion src/wayland/meta-wayland-versions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 26 additions & 2 deletions src/wayland/protocol/gtk-shell.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<protocol name="gtk">

<interface name="gtk_shell1" version="3">
<interface name="gtk_shell1" version="6">
<description summary="gtk specific extensions">
gtk_shell is a protocol extension providing additional features for
clients implementing it.
Expand Down Expand Up @@ -33,9 +33,11 @@
<request name="notify_launch" since="3">
<arg name="startup_id" type="string"/>
</request>

<!-- Version 6 does not add new API, but asserts that surface offsets are implemented -->
</interface>

<interface name="gtk_surface1" version="3">
<interface name="gtk_surface1" version="6">
<request name="set_dbus_properties">
<arg name="application_id" type="string" allow-null="true"/>
<arg name="app_menu_path" type="string" allow-null="true"/>
Expand Down Expand Up @@ -82,6 +84,28 @@
<request name="request_focus" since="3">
<arg name="startup_id" type="string" allow-null="true"/>
</request>

<!-- Version 4 additions -->
<request name="release" type="destructor" since="4"/>

<!-- Version 5 additions -->
<enum name="gesture" since="5">
<entry name="double_click" value="1"/>
<entry name="right_click" value="2"/>
<entry name="middle_click" value="3"/>
</enum>

<enum name="error" since="5">
<entry name="invalid_gesture" value="0"/>
</enum>

<request name="titlebar_gesture" since="5">
<arg name="serial" type="uint"/>
<arg name="seat" type="object" interface="wl_seat"/>
<arg name="gesture" type="uint" enum="gesture"/>
</request>

<!-- Version 6 does not add new API, but asserts that surface offsets are implemented -->
</interface>

</protocol>
50 changes: 1 addition & 49 deletions src/x11/meta-x11-window-control.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading