break;
case UWAC_EVENT_KEYBOARD_ENTER:
+ if (instance->context->settings->GrabKeyboard)
+ UwacSeatInhibitShortcuts(event.keyboard_enter_leave.seat, true);
if (!wlf_keyboard_enter(instance, &event.keyboard_enter_leave))
return FALSE;
*/
UWAC_API UwacSeatId UwacSeatGetId(const UwacSeat *seat);
+/**
+ * Inhibits or restores keyboard shortcuts.
+ *
+ * @param seat The UwacSeat to inhibit the shortcuts for
+ * @param inhibit Inhibit or restore keyboard shortcuts
+ *
+ * @return UWAC_SUCCESS or an appropriate error code.
+ */
+UWAC_API UwacReturnCode UwacSeatInhibitShortcuts(UwacSeat* seat, bool inhibit);
+
#ifdef __cplusplus
}
#endif
generate_protocol_file(xdg-shell)
generate_protocol_file(ivi-application)
generate_protocol_file(fullscreen-shell-unstable-v1)
+generate_protocol_file(keyboard-shortcuts-inhibit-unstable-v1)
if(FREEBSD)
include_directories(${EPOLLSHIM_INCLUDE_DIR})
{
d->xdg_base = wl_registry_bind(registry, id, &xdg_wm_base_interface, 1);
xdg_wm_base_add_listener(d->xdg_base, &xdg_wm_base_listener, d);
-#if BUILD_IVI
}
+ else if (strcmp(interface, "zwp_keyboard_shortcuts_inhibit_manager_v1") == 0)
+ {
+ d->keyboard_inhibit_manager = wl_registry_bind(registry, id, &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1);
+ }
+#if BUILD_IVI
else if (strcmp(interface, "ivi_application") == 0)
{
d->ivi_application = wl_registry_bind(registry, id, &ivi_application_interface, 1);
+ }
#endif
#if BUILD_FULLSCREEN_SHELL
- }
else if (strcmp(interface, "zwp_fullscreen_shell_v1") == 0)
{
d->fullscreen_shell = wl_registry_bind(registry, id, &zwp_fullscreen_shell_v1_interface, 1);
zwp_fullscreen_shell_v1_add_listener(d->fullscreen_shell, &fullscreen_shell_listener, d);
+ }
#endif
#if 0
- }
else if (strcmp(interface, "text_cursor_position") == 0)
{
d->text_cursor_position = wl_registry_bind(registry, id, &text_cursor_position_interface, 1);
{
d->subcompositor = wl_registry_bind(registry, id, &wl_subcompositor_interface, 1);
#endif
- }
}
static void registry_handle_global_remove(void* data, struct wl_registry* registry, uint32_t name)
if (display->compositor)
wl_compositor_destroy(display->compositor);
+ if (display->keyboard_inhibit_manager)
+ zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(display->keyboard_inhibit_manager);
+
#ifdef BUILD_FULLSCREEN_SHELL
if (display->fullscreen_shell)
return;
event->window = input->keyboard_focus = (UwacWindow *)wl_surface_get_user_data(surface);
+ event->seat = input;
/* look for keys that have been released */
found = false;
}
void UwacSeatDestroy(UwacSeat *s) {
+ UwacSeatInhibitShortcuts(s, false);
if (s->seat) {
#ifdef WL_SEAT_RELEASE_SINCE_VERSION
if (s->seat_version >= WL_SEAT_RELEASE_SINCE_VERSION)
UwacSeatId UwacSeatGetId(const UwacSeat *seat) {
return seat->seat_id;
}
+
+UwacReturnCode UwacSeatInhibitShortcuts(UwacSeat* s, bool inhibit)
+{
+ if (!s)
+ return UWAC_ERROR_CLOSED;
+
+ if (s->keyboard_inhibitor)
+ zwp_keyboard_shortcuts_inhibitor_v1_destroy(s->keyboard_inhibitor);
+ if (inhibit && s->display && s->display->keyboard_inhibit_manager)
+ s->keyboard_inhibitor = zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(s->display->keyboard_inhibit_manager,
+ s->keyboard_focus->surface, s->seat);
+
+ if (!s->keyboard_inhibitor)
+ return UWAC_ERROR_INTERNAL;
+ return UWAC_SUCCESS;
+}
#include <stdbool.h>
#include <wayland-client.h>
#include "xdg-shell-client-protocol.h"
+#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h"
+
#ifdef BUILD_IVI
#include "ivi-application-client-protocol.h"
#endif
struct wl_shell *shell;
struct xdg_toplevel *xdg_toplevel;
struct xdg_wm_base *xdg_base;
+ struct zwp_keyboard_shortcuts_inhibit_manager_v1 *keyboard_inhibit_manager;
#ifdef BUILD_IVI
struct ivi_application *ivi_application;
#endif
struct wl_keyboard *keyboard;
struct wl_touch *touch;
struct xkb_context *xkb_context;
+ struct zwp_keyboard_shortcuts_inhibitor_v1 *keyboard_inhibitor;
struct {
struct xkb_keymap *keymap;
assert(w->xdg_surface);
xdg_toplevel_add_listener(w->xdg_toplevel, &xdg_toplevel_listener, w);
-#if BUILD_IVI
}
+#if BUILD_IVI
else if (display->ivi_application)
{
w->ivi_surface = ivi_application_surface_create(display->ivi_application, 1, w->surface);
assert(w->ivi_surface);
ivi_surface_add_listener(w->ivi_surface, &ivi_surface_listener, w);
+ }
#endif
#if BUILD_FULLSCREEN_SHELL
- }
else if (display->fullscreen_shell)
{
zwp_fullscreen_shell_v1_present_surface(display->fullscreen_shell, w->surface,
ZWP_FULLSCREEN_SHELL_V1_PRESENT_METHOD_CENTER, NULL);
-#endif
}
+#endif
else
{
w->shell_surface = wl_shell_get_shell_surface(display->shell, w->surface);
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="keyboard_shortcuts_inhibit_unstable_v1">
+
+ <copyright>
+ Copyright © 2017 Red Hat Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice (including the next
+ paragraph) shall be included in all copies or substantial portions of the
+ Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ </copyright>
+
+ <description summary="Protocol for inhibiting the compositor keyboard shortcuts">
+ This protocol specifies a way for a client to request the compositor
+ to ignore its own keyboard shortcuts for a given seat, so that all
+ key events from that seat get forwarded to a surface.
+
+ Warning! The protocol described in this file is experimental and
+ backward incompatible changes may be made. Backward compatible
+ changes may be added together with the corresponding interface
+ version bump.
+ Backward incompatible changes are done by bumping the version
+ number in the protocol and interface names and resetting the
+ interface version. Once the protocol is to be declared stable,
+ the 'z' prefix and the version number in the protocol and
+ interface names are removed and the interface version number is
+ reset.
+ </description>
+
+ <interface name="zwp_keyboard_shortcuts_inhibit_manager_v1" version="1">
+ <description summary="context object for keyboard grab_manager">
+ A global interface used for inhibiting the compositor keyboard shortcuts.
+ </description>
+
+ <request name="destroy" type="destructor">
+ <description summary="destroy the keyboard shortcuts inhibitor object">
+ Destroy the keyboard shortcuts inhibitor manager.
+ </description>
+ </request>
+
+ <request name="inhibit_shortcuts">
+ <description summary="create a new keyboard shortcuts inhibitor object">
+ Create a new keyboard shortcuts inhibitor object associated with
+ the given surface for the given seat.
+
+ If shortcuts are already inhibited for the specified seat and surface,
+ a protocol error "already_inhibited" is raised by the compositor.
+ </description>
+ <arg name="id" type="new_id" interface="zwp_keyboard_shortcuts_inhibitor_v1"/>
+ <arg name="surface" type="object" interface="wl_surface"
+ summary="the surface that inhibits the keyboard shortcuts behavior"/>
+ <arg name="seat" type="object" interface="wl_seat"
+ summary="the wl_seat for which keyboard shortcuts should be disabled"/>
+ </request>
+
+ <enum name="error">
+ <entry name="already_inhibited"
+ value="0"
+ summary="the shortcuts are already inhibited for this surface"/>
+ </enum>
+ </interface>
+
+ <interface name="zwp_keyboard_shortcuts_inhibitor_v1" version="1">
+ <description summary="context object for keyboard shortcuts inhibitor">
+ A keyboard shortcuts inhibitor instructs the compositor to ignore
+ its own keyboard shortcuts when the associated surface has keyboard
+ focus. As a result, when the surface has keyboard focus on the given
+ seat, it will receive all key events originating from the specified
+ seat, even those which would normally be caught by the compositor for
+ its own shortcuts.
+
+ The Wayland compositor is however under no obligation to disable
+ all of its shortcuts, and may keep some special key combo for its own
+ use, including but not limited to one allowing the user to forcibly
+ restore normal keyboard events routing in the case of an unwilling
+ client. The compositor may also use the same key combo to reactivate
+ an existing shortcut inhibitor that was previously deactivated on
+ user request.
+
+ When the compositor restores its own keyboard shortcuts, an
+ "inactive" event is emitted to notify the client that the keyboard
+ shortcuts inhibitor is not effectively active for the surface and
+ seat any more, and the client should not expect to receive all
+ keyboard events.
+
+ When the keyboard shortcuts inhibitor is inactive, the client has
+ no way to forcibly reactivate the keyboard shortcuts inhibitor.
+
+ The user can chose to re-enable a previously deactivated keyboard
+ shortcuts inhibitor using any mechanism the compositor may offer,
+ in which case the compositor will send an "active" event to notify
+ the client.
+
+ If the surface is destroyed, unmapped, or loses the seat's keyboard
+ focus, the keyboard shortcuts inhibitor becomes irrelevant and the
+ compositor will restore its own keyboard shortcuts but no "inactive"
+ event is emitted in this case.
+ </description>
+
+ <request name="destroy" type="destructor">
+ <description summary="destroy the keyboard shortcuts inhibitor object">
+ Remove the keyboard shortcuts inhibitor from the associated wl_surface.
+ </description>
+ </request>
+
+ <event name="active">
+ <description summary="shortcuts are inhibited">
+ This event indicates that the shortcut inhibitor is active.
+
+ The compositor sends this event every time compositor shortcuts
+ are inhibited on behalf of the surface. When active, the client
+ may receive input events normally reserved by the compositor
+ (see zwp_keyboard_shortcuts_inhibitor_v1).
+
+ This occurs typically when the initial request "inhibit_shortcuts"
+ first becomes active or when the user instructs the compositor to
+ re-enable and existing shortcuts inhibitor using any mechanism
+ offered by the compositor.
+ </description>
+ </event>
+
+ <event name="inactive">
+ <description summary="shortcuts are restored">
+ This event indicates that the shortcuts inhibitor is inactive,
+ normal shortcuts processing is restored by the compositor.
+ </description>
+ </event>
+ </interface>
+</protocol>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="xdg_decoration_unstable_v1">
+ <copyright>
+ Copyright © 2018 Simon Ser
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice (including the next
+ paragraph) shall be included in all copies or substantial portions of the
+ Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ </copyright>
+
+ <interface name="zxdg_decoration_manager_v1" version="1">
+ <description summary="window decoration manager">
+ This interface allows a compositor to announce support for server-side
+ decorations.
+
+ A window decoration is a set of window controls as deemed appropriate by
+ the party managing them, such as user interface components used to move,
+ resize and change a window's state.
+
+ A client can use this protocol to request being decorated by a supporting
+ compositor.
+
+ If compositor and client do not negotiate the use of a server-side
+ decoration using this protocol, clients continue to self-decorate as they
+ see fit.
+
+ Warning! The protocol described in this file is experimental and
+ backward incompatible changes may be made. Backward compatible changes
+ may be added together with the corresponding interface version bump.
+ Backward incompatible changes are done by bumping the version number in
+ the protocol and interface names and resetting the interface version.
+ Once the protocol is to be declared stable, the 'z' prefix and the
+ version number in the protocol and interface names are removed and the
+ interface version number is reset.
+ </description>
+
+ <request name="destroy" type="destructor">
+ <description summary="destroy the decoration manager object">
+ Destroy the decoration manager. This doesn't destroy objects created
+ with the manager.
+ </description>
+ </request>
+
+ <request name="get_toplevel_decoration">
+ <description summary="create a new toplevel decoration object">
+ Create a new decoration object associated with the given toplevel.
+
+ Creating an xdg_toplevel_decoration from an xdg_toplevel which has a
+ buffer attached or committed is a client error, and any attempts by a
+ client to attach or manipulate a buffer prior to the first
+ xdg_toplevel_decoration.configure event must also be treated as
+ errors.
+ </description>
+ <arg name="id" type="new_id" interface="zxdg_toplevel_decoration_v1"/>
+ <arg name="toplevel" type="object" interface="xdg_toplevel"/>
+ </request>
+ </interface>
+
+ <interface name="zxdg_toplevel_decoration_v1" version="1">
+ <description summary="decoration object for a toplevel surface">
+ The decoration object allows the compositor to toggle server-side window
+ decorations for a toplevel surface. The client can request to switch to
+ another mode.
+
+ The xdg_toplevel_decoration object must be destroyed before its
+ xdg_toplevel.
+ </description>
+
+ <enum name="error">
+ <entry name="unconfigured_buffer" value="0"
+ summary="xdg_toplevel has a buffer attached before configure"/>
+ <entry name="already_constructed" value="1"
+ summary="xdg_toplevel already has a decoration object"/>
+ <entry name="orphaned" value="2"
+ summary="xdg_toplevel destroyed before the decoration object"/>
+ </enum>
+
+ <request name="destroy" type="destructor">
+ <description summary="destroy the decoration object">
+ Switch back to a mode without any server-side decorations at the next
+ commit.
+ </description>
+ </request>
+
+ <enum name="mode">
+ <description summary="window decoration modes">
+ These values describe window decoration modes.
+ </description>
+ <entry name="client_side" value="1"
+ summary="no server-side window decoration"/>
+ <entry name="server_side" value="2"
+ summary="server-side window decoration"/>
+ </enum>
+
+ <request name="set_mode">
+ <description summary="set the decoration mode">
+ Set the toplevel surface decoration mode. This informs the compositor
+ that the client prefers the provided decoration mode.
+
+ After requesting a decoration mode, the compositor will respond by
+ emitting a xdg_surface.configure event. The client should then update
+ its content, drawing it without decorations if the received mode is
+ server-side decorations. The client must also acknowledge the configure
+ when committing the new content (see xdg_surface.ack_configure).
+
+ The compositor can decide not to use the client's mode and enforce a
+ different mode instead.
+
+ Clients whose decoration mode depend on the xdg_toplevel state may send
+ a set_mode request in response to a xdg_surface.configure event and wait
+ for the next xdg_surface.configure event to prevent unwanted state.
+ Such clients are responsible for preventing configure loops and must
+ make sure not to send multiple successive set_mode requests with the
+ same decoration mode.
+ </description>
+ <arg name="mode" type="uint" enum="mode" summary="the decoration mode"/>
+ </request>
+
+ <request name="unset_mode">
+ <description summary="unset the decoration mode">
+ Unset the toplevel surface decoration mode. This informs the compositor
+ that the client doesn't prefer a particular decoration mode.
+
+ This request has the same semantics as set_mode.
+ </description>
+ </request>
+
+ <event name="configure">
+ <description summary="suggest a surface change">
+ The configure event asks the client to change its decoration mode. The
+ configured state should not be applied immediately. Clients must send an
+ ack_configure in response to this event. See xdg_surface.configure and
+ xdg_surface.ack_configure for details.
+
+ A configure event can be sent at any time. The specified mode must be
+ obeyed by the client.
+ </description>
+ <arg name="mode" type="uint" enum="mode" summary="the decoration mode"/>
+ </event>
+ </interface>
+</protocol>