Implemented keyboard shortcut inhibit support.
This commit is contained in:
parent
0ef64f8a84
commit
81f1fb934c
@ -273,6 +273,8 @@ static BOOL handle_uwac_events(freerdp* instance, UwacDisplay* display)
|
||||
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;
|
||||
|
||||
|
@ -494,6 +494,16 @@ UWAC_API const char *UwacSeatGetName(const UwacSeat *seat);
|
||||
*/
|
||||
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
|
||||
|
@ -39,6 +39,7 @@ endmacro()
|
||||
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})
|
||||
|
@ -215,21 +215,25 @@ static void registry_handle_global(void* data, struct wl_registry* registry, uin
|
||||
{
|
||||
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);
|
||||
@ -243,7 +247,6 @@ static void registry_handle_global(void* data, struct wl_registry* registry, uin
|
||||
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)
|
||||
{
|
||||
@ -512,6 +515,9 @@ UwacReturnCode UwacCloseDisplay(UwacDisplay** pdisplay)
|
||||
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)
|
||||
|
@ -130,6 +130,7 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, uint
|
||||
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;
|
||||
@ -819,6 +820,7 @@ error_xkb_context:
|
||||
}
|
||||
|
||||
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)
|
||||
@ -873,3 +875,19 @@ const char *UwacSeatGetName(const UwacSeat *seat) {
|
||||
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;
|
||||
}
|
||||
|
@ -28,6 +28,8 @@
|
||||
#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
|
||||
@ -86,6 +88,7 @@ struct uwac_display {
|
||||
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
|
||||
@ -151,6 +154,7 @@ struct uwac_seat {
|
||||
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;
|
||||
|
@ -449,22 +449,22 @@ UwacWindow* UwacCreateWindowShm(UwacDisplay* display, uint32_t width, uint32_t h
|
||||
|
||||
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);
|
||||
|
143
uwac/protocols/keyboard-shortcuts-inhibit-unstable-v1.xml
Normal file
143
uwac/protocols/keyboard-shortcuts-inhibit-unstable-v1.xml
Normal file
@ -0,0 +1,143 @@
|
||||
<?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>
|
156
uwac/protocols/xdg-decoration-unstable-v1.xml
Normal file
156
uwac/protocols/xdg-decoration-unstable-v1.xml
Normal file
@ -0,0 +1,156 @@
|
||||
<?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>
|
Loading…
Reference in New Issue
Block a user