mirror of
https://github.com/brl/mutter.git
synced 2024-11-24 00:50:42 -05:00
7ff52b6128
The window functions "work" regardless of whether the client allows the behavior or not. That is, it's up to the caller to not call maximize and friends when the action isn't allowed. Add appropriate checks, which should make the titlebar_gesture() behavior identical to titlebar actions for server-side decorations. https://gitlab.gnome.org/GNOME/mutter/-/issues/2139 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2281>
669 lines
20 KiB
C
669 lines
20 KiB
C
/*
|
|
* Wayland Support
|
|
*
|
|
* Copyright (C) 2012,2013 Intel Corporation
|
|
* 2013-2016 Red Hat, Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program 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
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
* 02111-1307, USA.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "wayland/meta-wayland-gtk-shell.h"
|
|
|
|
#include "core/bell.h"
|
|
#include "core/window-private.h"
|
|
#include "wayland/meta-wayland-private.h"
|
|
#include "wayland/meta-wayland-surface.h"
|
|
#include "wayland/meta-wayland-versions.h"
|
|
#include "wayland/meta-window-wayland.h"
|
|
|
|
#include "gtk-shell-server-protocol.h"
|
|
|
|
static GQuark quark_gtk_surface_data = 0;
|
|
|
|
typedef struct _MetaWaylandGtkSurface
|
|
{
|
|
struct wl_resource *resource;
|
|
MetaWaylandSurface *surface;
|
|
gboolean is_modal;
|
|
gulong configure_handler_id;
|
|
} MetaWaylandGtkSurface;
|
|
|
|
struct _MetaWaylandGtkShell
|
|
{
|
|
GObject parent;
|
|
|
|
GList *shell_resources;
|
|
uint32_t capabilities;
|
|
};
|
|
|
|
G_DEFINE_TYPE (MetaWaylandGtkShell, meta_wayland_gtk_shell, G_TYPE_OBJECT)
|
|
|
|
static void
|
|
gtk_surface_destructor (struct wl_resource *resource)
|
|
{
|
|
MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource);
|
|
|
|
if (gtk_surface->surface)
|
|
{
|
|
g_object_steal_qdata (G_OBJECT (gtk_surface->surface),
|
|
quark_gtk_surface_data);
|
|
g_clear_signal_handler (>k_surface->configure_handler_id,
|
|
gtk_surface->surface);
|
|
}
|
|
|
|
g_free (gtk_surface);
|
|
}
|
|
|
|
static void
|
|
gtk_surface_set_dbus_properties (struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
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)
|
|
{
|
|
MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource);
|
|
MetaWaylandSurface *surface = gtk_surface->surface;
|
|
MetaWindow *window;
|
|
|
|
if (!surface)
|
|
return;
|
|
|
|
window = meta_wayland_surface_get_window (surface);
|
|
if (!window)
|
|
return;
|
|
|
|
meta_window_set_gtk_dbus_properties (window,
|
|
application_id,
|
|
unique_bus_name,
|
|
app_menu_path,
|
|
menubar_path,
|
|
application_object_path,
|
|
window_object_path);
|
|
}
|
|
|
|
static void
|
|
gtk_surface_set_modal (struct wl_client *client,
|
|
struct wl_resource *resource)
|
|
{
|
|
MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource);
|
|
MetaWaylandSurface *surface = gtk_surface->surface;
|
|
MetaWindow *window;
|
|
|
|
if (!surface)
|
|
return;
|
|
|
|
window = meta_wayland_surface_get_window (surface);
|
|
if (!window)
|
|
return;
|
|
|
|
if (gtk_surface->is_modal)
|
|
return;
|
|
|
|
gtk_surface->is_modal = TRUE;
|
|
meta_window_set_type (window, META_WINDOW_MODAL_DIALOG);
|
|
}
|
|
|
|
static void
|
|
gtk_surface_unset_modal (struct wl_client *client,
|
|
struct wl_resource *resource)
|
|
{
|
|
MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource);
|
|
MetaWaylandSurface *surface = gtk_surface->surface;
|
|
MetaWindow *window;
|
|
|
|
if (!surface)
|
|
return;
|
|
|
|
window = meta_wayland_surface_get_window (surface);
|
|
if (!window)
|
|
return;
|
|
|
|
if (!gtk_surface->is_modal)
|
|
return;
|
|
|
|
gtk_surface->is_modal = FALSE;
|
|
meta_window_set_type (window, META_WINDOW_NORMAL);
|
|
}
|
|
|
|
static void
|
|
gtk_surface_present (struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
uint32_t timestamp)
|
|
{
|
|
MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource);
|
|
MetaWaylandSurface *surface = gtk_surface->surface;
|
|
MetaWindow *window;
|
|
|
|
if (!surface)
|
|
return;
|
|
|
|
window = meta_wayland_surface_get_window (surface);
|
|
if (!window)
|
|
return;
|
|
|
|
meta_window_activate_full (window, timestamp,
|
|
META_CLIENT_TYPE_APPLICATION, NULL);
|
|
}
|
|
|
|
static void
|
|
gtk_surface_request_focus (struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
const char *startup_id)
|
|
{
|
|
MetaWaylandGtkSurface *gtk_surface = wl_resource_get_user_data (resource);
|
|
MetaWaylandSurface *surface = gtk_surface->surface;
|
|
MetaDisplay *display = meta_get_display ();
|
|
MetaStartupSequence *sequence = NULL;
|
|
MetaWindow *window;
|
|
|
|
if (!surface)
|
|
return;
|
|
|
|
window = meta_wayland_surface_get_window (surface);
|
|
if (!window)
|
|
return;
|
|
|
|
if (startup_id)
|
|
sequence = meta_startup_notification_lookup_sequence (display->startup_notification,
|
|
startup_id);
|
|
|
|
if (sequence)
|
|
{
|
|
uint32_t timestamp;
|
|
int32_t workspace_idx;
|
|
|
|
workspace_idx = meta_startup_sequence_get_workspace (sequence);
|
|
timestamp = meta_startup_sequence_get_timestamp (sequence);
|
|
|
|
meta_startup_sequence_complete (sequence);
|
|
meta_startup_notification_remove_sequence (display->startup_notification,
|
|
sequence);
|
|
if (workspace_idx >= 0)
|
|
meta_window_change_workspace_by_index (window, workspace_idx, TRUE);
|
|
|
|
meta_window_activate_full (window, timestamp,
|
|
META_CLIENT_TYPE_APPLICATION, NULL);
|
|
}
|
|
else
|
|
{
|
|
meta_window_set_demands_attention (window);
|
|
}
|
|
}
|
|
|
|
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);
|
|
GDesktopTitlebarAction action = G_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 G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE:
|
|
if (!window->has_maximize_func)
|
|
break;
|
|
|
|
if (META_WINDOW_MAXIMIZED (window))
|
|
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
|
|
else
|
|
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
|
break;
|
|
|
|
case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_HORIZONTALLY:
|
|
if (!window->has_maximize_func)
|
|
break;
|
|
|
|
if (META_WINDOW_MAXIMIZED_HORIZONTALLY (window))
|
|
meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL);
|
|
else
|
|
meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL);
|
|
break;
|
|
|
|
case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE_VERTICALLY:
|
|
if (!window->has_maximize_func)
|
|
break;
|
|
|
|
if (META_WINDOW_MAXIMIZED_VERTICALLY (window))
|
|
meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL);
|
|
else
|
|
meta_window_maximize (window, META_MAXIMIZE_VERTICAL);
|
|
break;
|
|
|
|
case G_DESKTOP_TITLEBAR_ACTION_MINIMIZE:
|
|
if (!window->has_minimize_func)
|
|
break;
|
|
|
|
meta_window_minimize (window);
|
|
break;
|
|
|
|
case G_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 G_DESKTOP_TITLEBAR_ACTION_MENU:
|
|
meta_window_show_menu (window, META_WINDOW_MENU_WM, x, y);
|
|
break;
|
|
|
|
case G_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)
|
|
{
|
|
gtk_surface->surface = NULL;
|
|
}
|
|
|
|
static void
|
|
fill_edge_states (struct wl_array *states,
|
|
MetaWindow *window)
|
|
{
|
|
uint32_t *s;
|
|
|
|
if (window->edge_constraints.top != META_EDGE_CONSTRAINT_MONITOR)
|
|
{
|
|
s = wl_array_add (states, sizeof *s);
|
|
*s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_TOP;
|
|
}
|
|
|
|
if (window->edge_constraints.right != META_EDGE_CONSTRAINT_MONITOR)
|
|
{
|
|
s = wl_array_add (states, sizeof *s);
|
|
*s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_RIGHT;
|
|
}
|
|
|
|
if (window->edge_constraints.bottom != META_EDGE_CONSTRAINT_MONITOR)
|
|
{
|
|
s = wl_array_add (states, sizeof *s);
|
|
*s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_BOTTOM;
|
|
}
|
|
|
|
if (window->edge_constraints.left != META_EDGE_CONSTRAINT_MONITOR)
|
|
{
|
|
s = wl_array_add (states, sizeof *s);
|
|
*s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_LEFT;
|
|
}
|
|
}
|
|
|
|
static void
|
|
send_configure_edges (MetaWaylandGtkSurface *gtk_surface,
|
|
MetaWindow *window)
|
|
{
|
|
struct wl_array edge_states;
|
|
|
|
wl_array_init (&edge_states);
|
|
fill_edge_states (&edge_states, window);
|
|
|
|
gtk_surface1_send_configure_edges (gtk_surface->resource, &edge_states);
|
|
|
|
wl_array_release (&edge_states);
|
|
}
|
|
|
|
static void
|
|
add_state_value (struct wl_array *states,
|
|
enum gtk_surface1_state state)
|
|
{
|
|
uint32_t *s;
|
|
|
|
s = wl_array_add (states, sizeof *s);
|
|
*s = state;
|
|
}
|
|
|
|
static void
|
|
fill_states (struct wl_array *states,
|
|
MetaWindow *window,
|
|
struct wl_resource *resource)
|
|
{
|
|
int version;
|
|
|
|
version = wl_resource_get_version (resource);
|
|
|
|
if (version < GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION &&
|
|
(window->tile_mode == META_TILE_LEFT ||
|
|
window->tile_mode == META_TILE_RIGHT))
|
|
add_state_value (states, GTK_SURFACE1_STATE_TILED);
|
|
|
|
if (version >= GTK_SURFACE1_STATE_TILED_TOP_SINCE_VERSION &&
|
|
window->edge_constraints.top != META_EDGE_CONSTRAINT_NONE)
|
|
add_state_value (states, GTK_SURFACE1_STATE_TILED_TOP);
|
|
|
|
if (version >= GTK_SURFACE1_STATE_TILED_RIGHT_SINCE_VERSION &&
|
|
window->edge_constraints.right != META_EDGE_CONSTRAINT_NONE)
|
|
add_state_value (states, GTK_SURFACE1_STATE_TILED_RIGHT);
|
|
|
|
if (version >= GTK_SURFACE1_STATE_TILED_BOTTOM_SINCE_VERSION &&
|
|
window->edge_constraints.bottom != META_EDGE_CONSTRAINT_NONE)
|
|
add_state_value (states, GTK_SURFACE1_STATE_TILED_BOTTOM);
|
|
|
|
if (version >= GTK_SURFACE1_STATE_TILED_LEFT_SINCE_VERSION &&
|
|
window->edge_constraints.left != META_EDGE_CONSTRAINT_NONE)
|
|
add_state_value (states, GTK_SURFACE1_STATE_TILED_LEFT);
|
|
}
|
|
|
|
static void
|
|
send_configure (MetaWaylandGtkSurface *gtk_surface,
|
|
MetaWindow *window)
|
|
{
|
|
struct wl_array states;
|
|
|
|
wl_array_init (&states);
|
|
fill_states (&states, window, gtk_surface->resource);
|
|
|
|
gtk_surface1_send_configure (gtk_surface->resource, &states);
|
|
|
|
wl_array_release (&states);
|
|
}
|
|
|
|
static void
|
|
on_configure (MetaWaylandSurface *surface,
|
|
MetaWaylandGtkSurface *gtk_surface)
|
|
{
|
|
MetaWindow *window;
|
|
|
|
window = meta_wayland_surface_get_window (surface);
|
|
send_configure (gtk_surface, window);
|
|
|
|
if (wl_resource_get_version (gtk_surface->resource) >=
|
|
GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION)
|
|
send_configure_edges (gtk_surface, window);
|
|
}
|
|
|
|
static void
|
|
gtk_shell_get_gtk_surface (struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
guint32 id,
|
|
struct wl_resource *surface_resource)
|
|
{
|
|
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
|
MetaWaylandGtkSurface *gtk_surface;
|
|
|
|
gtk_surface = g_object_get_qdata (G_OBJECT (surface), quark_gtk_surface_data);
|
|
if (gtk_surface)
|
|
{
|
|
wl_resource_post_error (surface_resource,
|
|
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
|
"gtk_shell::get_gtk_surface already requested");
|
|
return;
|
|
}
|
|
|
|
gtk_surface = g_new0 (MetaWaylandGtkSurface, 1);
|
|
gtk_surface->surface = surface;
|
|
gtk_surface->resource = wl_resource_create (client,
|
|
>k_surface1_interface,
|
|
wl_resource_get_version (resource),
|
|
id);
|
|
wl_resource_set_implementation (gtk_surface->resource,
|
|
&meta_wayland_gtk_surface_interface,
|
|
gtk_surface, gtk_surface_destructor);
|
|
|
|
gtk_surface->configure_handler_id = g_signal_connect (surface,
|
|
"configure",
|
|
G_CALLBACK (on_configure),
|
|
gtk_surface);
|
|
|
|
g_object_set_qdata_full (G_OBJECT (surface),
|
|
quark_gtk_surface_data,
|
|
gtk_surface,
|
|
(GDestroyNotify) gtk_surface_surface_destroyed);
|
|
}
|
|
|
|
static void
|
|
gtk_shell_set_startup_id (struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
const char *startup_id)
|
|
{
|
|
MetaStartupSequence *sequence;
|
|
MetaDisplay *display;
|
|
|
|
display = meta_get_display ();
|
|
|
|
sequence = meta_startup_notification_lookup_sequence (display->startup_notification,
|
|
startup_id);
|
|
if (sequence)
|
|
meta_startup_sequence_complete (sequence);
|
|
}
|
|
|
|
static void
|
|
gtk_shell_system_bell (struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
struct wl_resource *gtk_surface_resource)
|
|
{
|
|
MetaDisplay *display = meta_get_display ();
|
|
|
|
if (gtk_surface_resource)
|
|
{
|
|
MetaWaylandGtkSurface *gtk_surface =
|
|
wl_resource_get_user_data (gtk_surface_resource);
|
|
MetaWaylandSurface *surface = gtk_surface->surface;
|
|
MetaWindow *window;
|
|
|
|
window = meta_wayland_surface_get_window (surface);
|
|
if (!window)
|
|
return;
|
|
|
|
meta_bell_notify (display, window);
|
|
}
|
|
else
|
|
{
|
|
meta_bell_notify (display, NULL);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gtk_shell_notify_launch (struct wl_client *client,
|
|
struct wl_resource *resource,
|
|
const char *startup_id)
|
|
{
|
|
MetaDisplay *display = meta_get_display ();
|
|
MetaStartupSequence *sequence;
|
|
uint32_t timestamp;
|
|
|
|
sequence = meta_startup_notification_lookup_sequence (display->startup_notification,
|
|
startup_id);
|
|
if (sequence)
|
|
{
|
|
g_warning ("Naughty client notified launch with duplicate startup_id '%s'",
|
|
startup_id);
|
|
return;
|
|
}
|
|
|
|
timestamp = meta_display_get_current_time_roundtrip (display);
|
|
sequence = g_object_new (META_TYPE_STARTUP_SEQUENCE,
|
|
"id", startup_id,
|
|
"timestamp", timestamp,
|
|
NULL);
|
|
|
|
meta_startup_notification_add_sequence (display->startup_notification,
|
|
sequence);
|
|
g_object_unref (sequence);
|
|
}
|
|
|
|
static const struct gtk_shell1_interface meta_wayland_gtk_shell_interface = {
|
|
gtk_shell_get_gtk_surface,
|
|
gtk_shell_set_startup_id,
|
|
gtk_shell_system_bell,
|
|
gtk_shell_notify_launch,
|
|
};
|
|
|
|
static void
|
|
gtk_shell_destructor (struct wl_resource *resource)
|
|
{
|
|
MetaWaylandGtkShell *gtk_shell = wl_resource_get_user_data (resource);
|
|
|
|
gtk_shell->shell_resources = g_list_remove (gtk_shell->shell_resources,
|
|
resource);
|
|
}
|
|
|
|
static void
|
|
bind_gtk_shell (struct wl_client *client,
|
|
void *data,
|
|
guint32 version,
|
|
guint32 id)
|
|
{
|
|
MetaWaylandGtkShell *gtk_shell = data;
|
|
struct wl_resource *resource;
|
|
|
|
resource = wl_resource_create (client, >k_shell1_interface, version, id);
|
|
wl_resource_set_implementation (resource, &meta_wayland_gtk_shell_interface,
|
|
data, gtk_shell_destructor);
|
|
|
|
gtk_shell->shell_resources = g_list_prepend (gtk_shell->shell_resources,
|
|
resource);
|
|
|
|
gtk_shell1_send_capabilities (resource, gtk_shell->capabilities);
|
|
}
|
|
|
|
static void
|
|
meta_wayland_gtk_shell_init (MetaWaylandGtkShell *gtk_shell)
|
|
{
|
|
}
|
|
|
|
static void
|
|
meta_wayland_gtk_shell_class_init (MetaWaylandGtkShellClass *klass)
|
|
{
|
|
quark_gtk_surface_data =
|
|
g_quark_from_static_string ("-meta-wayland-gtk-shell-surface-data");
|
|
}
|
|
|
|
static uint32_t
|
|
calculate_capabilities (void)
|
|
{
|
|
uint32_t capabilities = 0;
|
|
|
|
if (!meta_prefs_get_show_fallback_app_menu ())
|
|
capabilities = GTK_SHELL1_CAPABILITY_GLOBAL_APP_MENU;
|
|
|
|
return capabilities;
|
|
}
|
|
|
|
static void
|
|
prefs_changed (MetaPreference pref,
|
|
gpointer user_data)
|
|
{
|
|
MetaWaylandGtkShell *gtk_shell = user_data;
|
|
uint32_t new_capabilities;
|
|
GList *l;
|
|
|
|
if (pref != META_PREF_BUTTON_LAYOUT)
|
|
return;
|
|
|
|
new_capabilities = calculate_capabilities ();
|
|
if (gtk_shell->capabilities == new_capabilities)
|
|
return;
|
|
gtk_shell->capabilities = new_capabilities;
|
|
|
|
for (l = gtk_shell->shell_resources; l; l = l->next)
|
|
{
|
|
struct wl_resource *resource = l->data;
|
|
|
|
gtk_shell1_send_capabilities (resource, gtk_shell->capabilities);
|
|
}
|
|
}
|
|
|
|
static MetaWaylandGtkShell *
|
|
meta_wayland_gtk_shell_new (MetaWaylandCompositor *compositor)
|
|
{
|
|
MetaWaylandGtkShell *gtk_shell;
|
|
|
|
gtk_shell = g_object_new (META_TYPE_WAYLAND_GTK_SHELL, NULL);
|
|
|
|
if (wl_global_create (compositor->wayland_display,
|
|
>k_shell1_interface,
|
|
META_GTK_SHELL1_VERSION,
|
|
gtk_shell, bind_gtk_shell) == NULL)
|
|
g_error ("Failed to register a global gtk-shell object");
|
|
|
|
gtk_shell->capabilities = calculate_capabilities ();
|
|
|
|
meta_prefs_add_listener (prefs_changed, gtk_shell);
|
|
|
|
return gtk_shell;
|
|
}
|
|
|
|
void
|
|
meta_wayland_init_gtk_shell (MetaWaylandCompositor *compositor)
|
|
{
|
|
g_object_set_data_full (G_OBJECT (compositor), "-meta-wayland-gtk-shell",
|
|
meta_wayland_gtk_shell_new (compositor),
|
|
g_object_unref);
|
|
}
|