diff --git a/src/Makefile.am b/src/Makefile.am index 10c288db3..736fff16c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -73,6 +73,8 @@ mutter_built_sources += \ xdg-foreign-unstable-v1-server-protocol.h \ linux-dmabuf-unstable-v1-protocol.c \ linux-dmabuf-unstable-v1-server-protocol.h \ + keyboard-shortcuts-inhibit-unstable-v1-protocol.c \ + keyboard-shortcuts-inhibit-unstable-v1-server-protocol.h \ $(NULL) endif @@ -388,6 +390,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES += \ wayland/meta-wayland-wl-shell.h \ wayland/meta-wayland-gtk-shell.c \ wayland/meta-wayland-gtk-shell.h \ + wayland/meta-wayland-inhibit-shortcuts.c \ + wayland/meta-wayland-inhibit-shortcuts.h \ $(NULL) endif @@ -650,3 +654,7 @@ endef $(AM_V_GEN)$(WAYLAND_SCANNER) code $< $@ %-server-protocol.h : $(srcdir)/wayland/protocol/%.xml $(AM_V_GEN)$(WAYLAND_SCANNER) server-header $< $@ +keyboard-shortcuts-inhibit-unstable-v1-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@ +keyboard-shortcuts-inhibit-unstable-v1-server-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml + $(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@ diff --git a/src/wayland/meta-wayland-inhibit-shortcuts.c b/src/wayland/meta-wayland-inhibit-shortcuts.c new file mode 100644 index 000000000..e4b72643d --- /dev/null +++ b/src/wayland/meta-wayland-inhibit-shortcuts.c @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2017 Red Hat + * + * 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. + * + * Written by: + * Olivier Fourdan + */ + +#include "config.h" + +#include + +#include "keyboard-shortcuts-inhibit-unstable-v1-server-protocol.h" +#include "wayland/meta-wayland-private.h" +#include "wayland/meta-wayland-versions.h" +#include "wayland/meta-wayland-inhibit-shortcuts.h" + +struct _MetaWaylandKeyboardShotscutsInhibit +{ + MetaWaylandSurface *surface; + MetaWaylandSeat *seat; + gulong inhibit_shortcut_handler; + gulong restore_shortcut_handler; + gulong surface_destroyed_handler; + struct wl_resource *resource; +}; + +static void +zwp_keyboard_shortcuts_inhibit_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + MetaWaylandKeyboardShotscutsInhibit *shortcut_inhibit; + + shortcut_inhibit = wl_resource_get_user_data (resource); + if (shortcut_inhibit->surface) + { + g_signal_handler_disconnect (shortcut_inhibit->surface, + shortcut_inhibit->surface_destroyed_handler); + + g_signal_handler_disconnect (shortcut_inhibit->surface, + shortcut_inhibit->inhibit_shortcut_handler); + + g_signal_handler_disconnect (shortcut_inhibit->surface, + shortcut_inhibit->restore_shortcut_handler); + + meta_wayland_surface_restore_shortcuts (shortcut_inhibit->surface, + shortcut_inhibit->seat); + } + g_free (shortcut_inhibit); + wl_resource_destroy (resource); +} + +static const struct zwp_keyboard_shortcuts_inhibit_manager_v1_interface + meta_keyboard_shortcuts_inhibit_interface = { + zwp_keyboard_shortcuts_inhibit_destroy, + }; + +static void +surface_destroyed_cb (MetaWaylandSurface *surface, + MetaWaylandKeyboardShotscutsInhibit *shortcut_inhibit) +{ + shortcut_inhibit->surface = NULL; + shortcut_inhibit->seat = NULL; +} + +static void +shortcuts_inhibited_cb (MetaWaylandSurface *surface, + MetaWaylandKeyboardShotscutsInhibit *shortcut_inhibit) +{ + MetaWaylandKeyboard *keyboard = shortcut_inhibit->seat->keyboard; + + /* Send active event only if the surface has keyboard focus */ + if (keyboard->focus_surface == surface) + zwp_keyboard_shortcuts_inhibitor_v1_send_active (shortcut_inhibit->resource); +} + +static void +shortcuts_restored_cb (MetaWaylandSurface *surface, + gpointer user_data) +{ + MetaWaylandKeyboardShotscutsInhibit *shortcut_inhibit = user_data; + + zwp_keyboard_shortcuts_inhibitor_v1_send_inactive (shortcut_inhibit->resource); +} + +static void +zwp_keyboard_shortcuts_inhibit_manager_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +zwp_keyboard_shortcuts_inhibit_manager_inhibit_shortcuts (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource, + struct wl_resource *seat_resource) +{ + MetaWaylandKeyboardShotscutsInhibit *shortcut_inhibit; + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); + struct wl_resource *keyboard_shortcuts_inhibit_resource; + + keyboard_shortcuts_inhibit_resource = + wl_resource_create (client, + &zwp_keyboard_shortcuts_inhibitor_v1_interface, + META_ZWP_KEYBOARD_SHORTCUTS_INHIBIT_V1_VERSION, + id); + + shortcut_inhibit = g_new0 (MetaWaylandKeyboardShotscutsInhibit, 1); + shortcut_inhibit->surface = surface; + shortcut_inhibit->seat = seat; + shortcut_inhibit->resource = keyboard_shortcuts_inhibit_resource; + + shortcut_inhibit->inhibit_shortcut_handler = + g_signal_connect (surface, "shortcuts-inhibited", + G_CALLBACK (shortcuts_inhibited_cb), + shortcut_inhibit); + shortcut_inhibit->restore_shortcut_handler = + g_signal_connect (surface, "shortcuts-restored", + G_CALLBACK (shortcuts_restored_cb), + shortcut_inhibit); + + shortcut_inhibit->surface_destroyed_handler = + g_signal_connect (surface, "destroy", + G_CALLBACK (surface_destroyed_cb), + shortcut_inhibit); + + meta_wayland_surface_inhibit_shortcuts (surface, seat); + + wl_resource_set_implementation (keyboard_shortcuts_inhibit_resource, + &meta_keyboard_shortcuts_inhibit_interface, + shortcut_inhibit, + NULL); +} + +static const struct zwp_keyboard_shortcuts_inhibit_manager_v1_interface + meta_keyboard_shortcuts_inhibit_manager_interface = { + zwp_keyboard_shortcuts_inhibit_manager_destroy, + zwp_keyboard_shortcuts_inhibit_manager_inhibit_shortcuts, + }; + +static void +bind_keyboard_shortcuts_inhibit (struct wl_client *client, + void *data, + uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create (client, + &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, + META_ZWP_KEYBOARD_SHORTCUTS_INHIBIT_V1_VERSION, + id); + + wl_resource_set_implementation (resource, + &meta_keyboard_shortcuts_inhibit_manager_interface, + NULL, NULL); +} + +gboolean +meta_wayland_keyboard_shortcuts_inhibit_init (MetaWaylandCompositor *compositor) +{ + return (wl_global_create (compositor->wayland_display, + &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, + META_ZWP_KEYBOARD_SHORTCUTS_INHIBIT_V1_VERSION, + NULL, + bind_keyboard_shortcuts_inhibit) != NULL); +} diff --git a/src/wayland/meta-wayland-inhibit-shortcuts.h b/src/wayland/meta-wayland-inhibit-shortcuts.h new file mode 100644 index 000000000..fdd35dd06 --- /dev/null +++ b/src/wayland/meta-wayland-inhibit-shortcuts.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2017 Red Hat + * + * 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. + * + * Written by: + * Olivier Fourdan + */ + +#ifndef META_WAYLAND_INHIBIT_SHORTCUTS_H +#define META_WAYLAND_INHIBIT_SHORTCUTS_H + +#include +#include "wayland/meta-wayland-types.h" +#include "meta/window.h" + +#define META_TYPE_WAYLAND_KEYBOARD_SHORTCUTS_INHIBIT (meta_wayland_keyboard_shortcuts_inhibit_resource_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandKeyboardShotscutsInhibit, + meta_wayland_keyboard_shortcuts_inhibit_resource, + META, WAYLAND_KEYBOARD_SHORTCUTS_INHIBIT, + GObject); + +gboolean meta_wayland_keyboard_shortcuts_inhibit_init (MetaWaylandCompositor *compositor); + +#endif /* META_WAYLAND_INHIBIT_SHORTCUTS_H */ diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h index cbd794a04..65496b4d6 100644 --- a/src/wayland/meta-wayland-versions.h +++ b/src/wayland/meta-wayland-versions.h @@ -48,5 +48,6 @@ #define META_ZXDG_EXPORTER_V1_VERSION 1 #define META_ZXDG_IMPORTER_V1_VERSION 1 #define META_ZWP_LINUX_DMABUF_V1_VERSION 3 +#define META_ZWP_KEYBOARD_SHORTCUTS_INHIBIT_V1_VERSION 1 #endif diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c index d89cac540..e25739100 100644 --- a/src/wayland/meta-wayland.c +++ b/src/wayland/meta-wayland.c @@ -42,6 +42,7 @@ #include "meta-wayland-tablet-manager.h" #include "meta-wayland-xdg-foreign.h" #include "meta-wayland-dma-buf.h" +#include "meta-wayland-inhibit-shortcuts.h" static MetaWaylandCompositor _meta_wayland_compositor; static char *_display_name_override; @@ -357,6 +358,7 @@ meta_wayland_init (void) meta_wayland_pointer_constraints_init (compositor); meta_wayland_xdg_foreign_init (compositor); meta_wayland_dma_buf_init (compositor); + meta_wayland_keyboard_shortcuts_inhibit_init (compositor); if (!meta_xwayland_start (&compositor->xwayland_manager, compositor->wayland_display)) g_error ("Failed to start X Wayland");