Skip to content

Commit

Permalink
[M110] wayland: restrict fullscreen-only shortcuts inhibition to linu…
Browse files Browse the repository at this point in the history
…x desktop

This implements an alternative behavior for 'keyboard shortcuts
inhibition' feature in ozone/wayland's platform window impl for Linux
Desktop, which restricts the inhibition to fullscreen state, as
currently state in KeyboardLock web specification [1].

Lacros behavior is kept unchanged, which shouldn't be a problem since
Exo supports zcr-keyboard-extension extension which allows unprocessed
keys to be reported by the client to the compositor for further
processing, when shortcuts inhibitor is in place.

[1] https://wicg.github.io/keyboard-lock

R=​hidehiko, tonikitoo@igalia.com

(cherry picked from commit 92f7bfe)

Bug: 1338554
Change-Id: Ic79d5b67b7d765acd3dbcfddbb0e2b0387eb2391
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4179373
Reviewed-by: Antonio Gomes <tonikitoo@igalia.com>
Commit-Queue: Nick Yamane <nickdiego@igalia.com>
Reviewed-by: Hidehiko Abe <hidehiko@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1094796}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4188482
Reviewed-by: Maksim Sisov <msisov@igalia.com>
Commit-Queue: Maksim Sisov <msisov@igalia.com>
Auto-Submit: Nick Yamane <nickdiego@igalia.com>
Cr-Commit-Position: refs/branch-heads/5481@{#640}
Cr-Branched-From: 130f3e4-refs/heads/main@{#1084008}
  • Loading branch information
nickdiego authored and Chromium LUCI CQ committed Jan 25, 2023
1 parent 314cbca commit 10b6376
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 14 deletions.
3 changes: 3 additions & 0 deletions ui/ozone/platform/wayland/host/wayland_connection.h
Expand Up @@ -129,6 +129,9 @@ class WaylandConnection {
}
xdg_wm_base* shell() const { return shell_.get(); }
wp_presentation* presentation() const { return presentation_.get(); }
zcr_keyboard_extension_v1* keyboard_extension_v1() const {
return keyboard_extension_v1_.get();
}
zwp_keyboard_shortcuts_inhibit_manager_v1*
keyboard_shortcuts_inhibit_manager_v1() const {
return keyboard_shortcuts_inhibit_manager_v1_.get();
Expand Down
12 changes: 7 additions & 5 deletions ui/ozone/platform/wayland/host/wayland_surface.cc
Expand Up @@ -723,14 +723,16 @@ void WaylandSurface::ForceImmediateStateApplication() {
apply_state_immediately_ = true;
}

void WaylandSurface::InhibitKeyboardShortcuts() {
if (auto* keyboard_shortcuts_inhibit_manager =
connection_->keyboard_shortcuts_inhibit_manager_v1()) {
void WaylandSurface::SetKeyboardShortcutsInhibition(bool enabled) {
if (!enabled) {
keyboard_shortcuts_inhibitor_.reset();
return;
}
if (auto* manager = connection_->keyboard_shortcuts_inhibit_manager_v1()) {
keyboard_shortcuts_inhibitor_ =
wl::Object<zwp_keyboard_shortcuts_inhibitor_v1>(
zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(
keyboard_shortcuts_inhibit_manager, surface_.get(),
connection_->seat()->wl_object()));
manager, surface_.get(), connection_->seat()->wl_object()));
}
}

Expand Down
7 changes: 4 additions & 3 deletions ui/ozone/platform/wayland/host/wayland_surface.h
Expand Up @@ -215,9 +215,10 @@ class WaylandSurface {
// effect immediately.
void ForceImmediateStateApplication();

// Requests to wayland compositor to send key events even if it matches
// with the compositor's accelerator keys.
void InhibitKeyboardShortcuts();
// Asks the Wayland compositor to enable or disable the keyboard shortcuts
// inhibition for this surface. i.e: to receive key events even if they match
// compositor accelerators, e.g: Alt+Tab, etc.
void SetKeyboardShortcutsInhibition(bool enabled);

private:
FRIEND_TEST_ALL_PREFIXES(WaylandWindowTest,
Expand Down
16 changes: 13 additions & 3 deletions ui/ozone/platform/wayland/host/wayland_toplevel_window.cc
Expand Up @@ -498,9 +498,19 @@ void WaylandToplevelWindow::HandleAuraToplevelConfigure(
// Thus, we must store previous bounds to restore later.
SetOrResetRestoredBounds();

if (old_state != state_ && !did_send_delegate_notification) {
previous_state_ = old_state;
delegate()->OnWindowStateChanged(previous_state_, state_);
if (old_state != state_) {
if (!did_send_delegate_notification) {
previous_state_ = old_state;
delegate()->OnWindowStateChanged(previous_state_, state_);
}

if (keyboard_shortcuts_inhibition_mode() ==
KeyboardShortcutsInhibitionMode::kFullscreenOnly &&
(state_ == PlatformWindowState::kFullScreen ||
old_state == PlatformWindowState::kFullScreen)) {
root_surface()->SetKeyboardShortcutsInhibition(
state_ == PlatformWindowState::kFullScreen);
}
}

if (did_active_change)
Expand Down
41 changes: 38 additions & 3 deletions ui/ozone/platform/wayland/host/wayland_window.cc
Expand Up @@ -643,9 +643,6 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
return false;
}

if (properties.inhibit_keyboard_shortcuts)
root_surface_->InhibitKeyboardShortcuts();

// Update visual size in tests immediately if the test config is set.
// Otherwise, such tests as interactive_ui_tests fail.
if (!update_visual_size_immediately_for_testing_) {
Expand All @@ -661,6 +658,10 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
opacity_ = properties.opacity;
type_ = properties.type;

if (properties.inhibit_keyboard_shortcuts) {
InitKeyboardShortcutsInhibition();
}

connection_->window_manager()->AddWindow(GetWidget(), this);

if (!OnInitialize(std::move(properties)))
Expand All @@ -686,6 +687,40 @@ bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
return true;
}

// When upper layer requests to 'inhibit keyboard shortcuts', two different
// behaviors are currently implemented:
//
// 1. If `zcr_keyboard_extension_v1` extension is available (typically meaning
// it is running under Exo compositor), shortcuts are kept inhibited since the
// window initialization. That is required to keep Lacros behaving just like
// Ash Chrome's classic browser.
//
// 2. Otherwise, keyboard shortcuts will be inhibited only when in fullscreen.
// See KeyboardLock spec for more details: https://wicg.github.io/keyboard-lock
//
// The main technical difference here is that keyboard-extension-v1 extension
// allows ozone/wayland to report back to the Wayland compositor that a given
// key was not processed by the client, giving it a chance of processing global
// shortcuts (even with a shortcuts inhibitor in place), which is not currently
// possible with standard Wayland protocol and extensions.
//
// TODO(crbug.com/1338554): Revisit and update when/if this scenario changes.
void WaylandWindow::InitKeyboardShortcutsInhibition() {
DCHECK_EQ(keyboard_shortcuts_inhibition_mode_,
KeyboardShortcutsInhibitionMode::kDisabled);
if (!connection_->keyboard_extension_v1()) {
// Only set inhibition mode to kFullscreenOnly and defer the actual handling
// to the subsequent shell surface configure events, where window state is
// applied/updated. See WaylandToplevelWindow::HandleAuraToplevelConfigure.
keyboard_shortcuts_inhibition_mode_ =
KeyboardShortcutsInhibitionMode::kFullscreenOnly;
return;
}
keyboard_shortcuts_inhibition_mode_ =
KeyboardShortcutsInhibitionMode::kAlwaysEnabled;
root_surface()->SetKeyboardShortcutsInhibition(/*enabled=*/true);
}

void WaylandWindow::SetWindowGeometry(gfx::Size size_dip) {}

gfx::Vector2d WaylandWindow::GetWindowGeometryOffsetInDIP() const {
Expand Down
17 changes: 17 additions & 0 deletions ui/ozone/platform/wayland/host/wayland_window.h
Expand Up @@ -366,6 +366,12 @@ class WaylandWindow : public PlatformWindow,
bool has_pending_configures() const { return !pending_configures_.empty(); }

protected:
enum class KeyboardShortcutsInhibitionMode {
kDisabled,
kAlwaysEnabled,
kFullscreenOnly
};

WaylandWindow(PlatformWindowDelegate* delegate,
WaylandConnection* connection);

Expand Down Expand Up @@ -401,6 +407,10 @@ class WaylandWindow : public PlatformWindow,

const gfx::Size& restored_size_dip() const { return restored_size_dip_; }

KeyboardShortcutsInhibitionMode keyboard_shortcuts_inhibition_mode() const {
return keyboard_shortcuts_inhibition_mode_;
}

// Configure related:
// Processes the pending bounds in dip.
void ProcessPendingBoundsDip(uint32_t serial);
Expand Down Expand Up @@ -445,6 +455,10 @@ class WaylandWindow : public PlatformWindow,
// Additional initialization of derived classes.
virtual bool OnInitialize(PlatformWindowInitProperties properties) = 0;

// Determines which keyboard shortcuts inhibition mode to be used and perform
// required initialization steps, if any.
void InitKeyboardShortcutsInhibition();

// WaylandWindowDragController might need to take ownership of the wayland
// surface whether the window that originated the DND session gets destroyed
// in the middle of that session (e.g: when it is snapped into a tab strip).
Expand Down Expand Up @@ -564,6 +578,9 @@ class WaylandWindow : public PlatformWindow,

base::OnceClosure drag_loop_quit_closure_;

KeyboardShortcutsInhibitionMode keyboard_shortcuts_inhibition_mode_{
KeyboardShortcutsInhibitionMode::kDisabled};

#if DCHECK_IS_ON()
bool disable_null_target_dcheck_for_test_ = false;
#endif
Expand Down

0 comments on commit 10b6376

Please sign in to comment.