wayland: Implement the XDG dialog protocol
This protocol takes over some of our homegrown GTK Shell protocol, allowing to specify hints on surfaces such as dialog modality. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3557>
This commit is contained in:
parent
326e4c15de
commit
69e791cda1
6 changed files with 262 additions and 1 deletions
|
@ -46,7 +46,7 @@ gudev_req = '>= 232'
|
|||
|
||||
# wayland version requirements
|
||||
wayland_server_req = '>= 1.22'
|
||||
wayland_protocols_req = '>= 1.33'
|
||||
wayland_protocols_req = '>= 1.36'
|
||||
|
||||
# native backend version requirements
|
||||
libinput_req = '>= 1.19.0'
|
||||
|
|
|
@ -702,6 +702,8 @@ if have_wayland
|
|||
'wayland/meta-wayland-xdg-foreign-private.h',
|
||||
'wayland/meta-wayland-xdg-shell.c',
|
||||
'wayland/meta-wayland-xdg-shell.h',
|
||||
'wayland/meta-wayland-xdg-dialog.c',
|
||||
'wayland/meta-wayland-xdg-dialog.h',
|
||||
'wayland/meta-window-wayland.c',
|
||||
'wayland/meta-window-wayland.h',
|
||||
]
|
||||
|
@ -1077,6 +1079,7 @@ if have_wayland
|
|||
['text-input', 'unstable', 'v3', ],
|
||||
['viewporter', 'stable', ],
|
||||
['xdg-activation', 'staging', 'v1', ],
|
||||
['xdg-dialog', 'staging', 'v1', ],
|
||||
['xdg-foreign', 'unstable', 'v1', ],
|
||||
['xdg-foreign', 'unstable', 'v2', ],
|
||||
['xdg-output', 'unstable', 'v1', ],
|
||||
|
|
|
@ -57,3 +57,4 @@
|
|||
#define META_WP_SINGLE_PIXEL_BUFFER_V1_VERSION 1
|
||||
#define META_MUTTER_X11_INTEROP_VERSION 1
|
||||
#define META_WP_FRACTIONAL_SCALE_VERSION 1
|
||||
#define META_XDG_DIALOG_VERSION 1
|
||||
|
|
233
src/wayland/meta-wayland-xdg-dialog.c
Normal file
233
src/wayland/meta-wayland-xdg-dialog.c
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* Wayland Support
|
||||
*
|
||||
* Copyright (C) 2024 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "wayland/meta-wayland-xdg-dialog.h"
|
||||
|
||||
#include "core/window-private.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#include "wayland/meta-wayland-xdg-shell.h"
|
||||
#include "wayland/meta-wayland-versions.h"
|
||||
|
||||
#include "xdg-dialog-v1-server-protocol.h"
|
||||
|
||||
static GQuark quark_xdg_dialog_data = 0;
|
||||
|
||||
typedef struct _MetaWaylandXdgDialog
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
MetaWaylandXdgSurface *toplevel;
|
||||
gboolean is_modal;
|
||||
} MetaWaylandXdgDialog;
|
||||
|
||||
struct _MetaWaylandXdgWmDialog
|
||||
{
|
||||
GObject parent;
|
||||
struct wl_list resources;
|
||||
};
|
||||
|
||||
#define META_TYPE_WAYLAND_XDG_WM_DIALOG (meta_wayland_xdg_wm_dialog_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandXdgWmDialog, meta_wayland_xdg_wm_dialog,
|
||||
META, WAYLAND_XDG_WM_DIALOG, GObject)
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandXdgWmDialog, meta_wayland_xdg_wm_dialog, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
xdg_dialog_destructor (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandXdgDialog *xdg_dialog = wl_resource_get_user_data (resource);
|
||||
|
||||
if (xdg_dialog->toplevel)
|
||||
{
|
||||
g_object_steal_qdata (G_OBJECT (xdg_dialog->toplevel),
|
||||
quark_xdg_dialog_data);
|
||||
}
|
||||
|
||||
g_free (xdg_dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_dialog_set_modal (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandXdgDialog *xdg_dialog = wl_resource_get_user_data (resource);
|
||||
MetaWaylandXdgSurface *xdg_surface;
|
||||
|
||||
xdg_surface = xdg_dialog->toplevel;
|
||||
|
||||
if (xdg_surface && !xdg_dialog->is_modal)
|
||||
{
|
||||
MetaWaylandSurfaceRole *surface_role =
|
||||
META_WAYLAND_SURFACE_ROLE (xdg_surface);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *window = meta_wayland_surface_get_window (surface);
|
||||
|
||||
xdg_dialog->is_modal = TRUE;
|
||||
meta_window_set_type (window, META_WINDOW_MODAL_DIALOG);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_dialog_unset_modal (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandXdgDialog *xdg_dialog = wl_resource_get_user_data (resource);
|
||||
MetaWaylandXdgSurface *xdg_surface;
|
||||
|
||||
xdg_surface = xdg_dialog->toplevel;
|
||||
|
||||
if (xdg_surface && xdg_dialog->is_modal)
|
||||
{
|
||||
MetaWaylandSurfaceRole *surface_role =
|
||||
META_WAYLAND_SURFACE_ROLE (xdg_surface);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *window = meta_wayland_surface_get_window (surface);
|
||||
|
||||
xdg_dialog->is_modal = FALSE;
|
||||
meta_window_set_type (window, META_WINDOW_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_dialog_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static const struct xdg_dialog_v1_interface meta_wayland_xdg_dialog_interface = {
|
||||
xdg_dialog_destroy,
|
||||
xdg_dialog_set_modal,
|
||||
xdg_dialog_unset_modal,
|
||||
};
|
||||
|
||||
static void
|
||||
xdg_dialog_toplevel_destroyed (MetaWaylandXdgDialog *xdg_dialog)
|
||||
{
|
||||
xdg_dialog->toplevel = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_wm_dialog_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_wm_dialog_get_xdg_dialog (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id,
|
||||
struct wl_resource *toplevel_resource)
|
||||
{
|
||||
MetaWaylandXdgSurface *xdg_surface = wl_resource_get_user_data (toplevel_resource);
|
||||
MetaWaylandXdgDialog *xdg_dialog;
|
||||
|
||||
xdg_dialog = g_object_get_qdata (G_OBJECT (xdg_surface), quark_xdg_dialog_data);
|
||||
if (xdg_dialog)
|
||||
{
|
||||
wl_resource_post_error (toplevel_resource,
|
||||
XDG_WM_DIALOG_V1_ERROR_ALREADY_USED,
|
||||
"xdg_wm_dialog_v1::get_xdg_dialog already requested");
|
||||
return;
|
||||
}
|
||||
|
||||
xdg_dialog = g_new0 (MetaWaylandXdgDialog, 1);
|
||||
xdg_dialog->toplevel = xdg_surface;
|
||||
xdg_dialog->resource = wl_resource_create (client,
|
||||
&xdg_dialog_v1_interface,
|
||||
wl_resource_get_version (resource),
|
||||
id);
|
||||
wl_resource_set_implementation (xdg_dialog->resource,
|
||||
&meta_wayland_xdg_dialog_interface,
|
||||
xdg_dialog, xdg_dialog_destructor);
|
||||
|
||||
g_object_set_qdata_full (G_OBJECT (xdg_surface),
|
||||
quark_xdg_dialog_data,
|
||||
xdg_dialog,
|
||||
(GDestroyNotify) xdg_dialog_toplevel_destroyed);
|
||||
}
|
||||
|
||||
static const struct xdg_wm_dialog_v1_interface meta_wayland_xdg_wm_dialog_interface = {
|
||||
xdg_wm_dialog_destroy,
|
||||
xdg_wm_dialog_get_xdg_dialog,
|
||||
};
|
||||
|
||||
static void
|
||||
unbind_resource (struct wl_resource *resource)
|
||||
{
|
||||
wl_list_remove (wl_resource_get_link (resource));
|
||||
}
|
||||
|
||||
static void
|
||||
bind_xdg_wm_dialog (struct wl_client *client,
|
||||
void *data,
|
||||
uint32_t version,
|
||||
uint32_t id)
|
||||
{
|
||||
MetaWaylandXdgWmDialog *xdg_wm_dialog = data;
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, &xdg_wm_dialog_v1_interface, version, id);
|
||||
wl_resource_set_implementation (resource, &meta_wayland_xdg_wm_dialog_interface,
|
||||
data, unbind_resource);
|
||||
wl_list_insert (&xdg_wm_dialog->resources, wl_resource_get_link (resource));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_xdg_wm_dialog_init (MetaWaylandXdgWmDialog *xdg_wm_dialog)
|
||||
{
|
||||
wl_list_init (&xdg_wm_dialog->resources);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_xdg_wm_dialog_class_init (MetaWaylandXdgWmDialogClass *klass)
|
||||
{
|
||||
quark_xdg_dialog_data =
|
||||
g_quark_from_static_string ("-meta-wayland-xdg-wm-dialog-surface-data");
|
||||
}
|
||||
|
||||
static MetaWaylandXdgWmDialog *
|
||||
meta_wayland_xdg_wm_dialog_new (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
MetaWaylandXdgWmDialog *xdg_wm_dialog;
|
||||
|
||||
xdg_wm_dialog = g_object_new (META_TYPE_WAYLAND_XDG_WM_DIALOG, NULL);
|
||||
|
||||
if (wl_global_create (compositor->wayland_display,
|
||||
&xdg_wm_dialog_v1_interface,
|
||||
META_XDG_DIALOG_VERSION,
|
||||
xdg_wm_dialog, bind_xdg_wm_dialog) == NULL)
|
||||
g_error ("Failed to register a global xdg-dialog object");
|
||||
|
||||
return xdg_wm_dialog;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_init_xdg_wm_dialog (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
g_object_set_data_full (G_OBJECT (compositor), "-meta-wayland-xdg-wm-dialog",
|
||||
meta_wayland_xdg_wm_dialog_new (compositor),
|
||||
g_object_unref);
|
||||
}
|
22
src/wayland/meta-wayland-xdg-dialog.h
Normal file
22
src/wayland/meta-wayland-xdg-dialog.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "wayland/meta-wayland.h"
|
||||
|
||||
void meta_wayland_init_xdg_wm_dialog (MetaWaylandCompositor *compositor);
|
|
@ -56,6 +56,7 @@
|
|||
#include "wayland/meta-wayland-subsurface.h"
|
||||
#include "wayland/meta-wayland-tablet-manager.h"
|
||||
#include "wayland/meta-wayland-transaction.h"
|
||||
#include "wayland/meta-wayland-xdg-dialog.h"
|
||||
#include "wayland/meta-wayland-xdg-foreign.h"
|
||||
#include "wayland/meta-wayland-linux-drm-syncobj.h"
|
||||
|
||||
|
@ -870,6 +871,7 @@ meta_wayland_compositor_new (MetaContext *context)
|
|||
meta_wayland_transaction_init (compositor);
|
||||
meta_wayland_idle_inhibit_init (compositor);
|
||||
meta_wayland_drm_syncobj_init (compositor);
|
||||
meta_wayland_init_xdg_wm_dialog (compositor);
|
||||
|
||||
#ifdef HAVE_WAYLAND_EGLSTREAM
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue