Hyprland icon indicating copy to clipboard operation
Hyprland copied to clipboard

Layershells cannot steal focus from a window that has captured the mouse

Open outfoxxed opened this issue 1 year ago • 5 comments

Hyprland Version

System/Version info
Hyprland, built from branch HEAD at commit 0871fe738a14dc7183d7d4495123f85a8a4b2dbe dirty (Rewrite the subsurface tree).
Date: Wed Feb 28 13:46:03 2024
Tag: v0.36.0-8-g0871fe73

flags: (if any)


System Information:
System name: Linux
Node name: msi
Release: 6.1.79
Version: #1-NixOS SMP PREEMPT_DYNAMIC Fri Feb 23 08:12:53 UTC 2024


GPU information:


os-release: ANSI_COLOR="1;34"
BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues"
BUILD_ID="24.05.20240224.73de017"
DOCUMENTATION_URL="https://nixos.org/learn.html"
HOME_URL="https://nixos.org/"
ID=nixos
IMAGE_ID=""
IMAGE_VERSION=""
LOGO="nix-snowflake"
NAME=NixOS
PRETTY_NAME="NixOS 24.05 (Uakari)"
SUPPORT_URL="https://nixos.org/community.html"
VERSION="24.05 (Uakari)"
VERSION_CODENAME=uakari
VERSION_ID="24.05"


plugins:
  hy3 by outfoxxed ver 0.1

Bug or Regression?

Bug

Description

When an exiting layershell's keyboard_interactivity is set to exclusive or a new layershell is created with exclusive keyboard_interactivity and a window (usually a game) has captured the mouse, the window retains ownership of the mouse and keyboard. As soon as the window gives it up (opening a game menu) the layershell gets exclusive focus.

How to reproduce

I've prepared a demo that can be used with https://git.outfoxxed.me/outfoxxed/quickshell/commit/5ac04649aabdba2bf0ee67357a3d1065b8b17d97 (this specific commit is guaranteed to work.)

layerbug.qml
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Wayland

ShellRoot {
	PanelWindow {
		id: window

		property var inhibiting: false

		exclusionMode: ExclusionMode.Ignore
		WlrLayershell.layer: Layer.Overlay
		WlrLayershell.keyboardFocus: inhibiting ? KeyboardFocus.Exclusive : KeyboardFocus.None

		anchors {
			top: true
			left: true
			right: true
			bottom: true
		}

		property var maskRegion: Region {
			Region { item: closebutton }
			Region { item: inhibitButton }
			Region { item: hideButton }
		}

		color: "transparent"
		mask: inhibiting ? null : maskRegion

		Rectangle {
			anchors.fill: parent
			color: "#50ffffff"

			Button {
				id: closebutton
				anchors {
					horizontalCenter: parent.horizontalCenter
					top: parent.top
					topMargin: 200
				}

				width: 200
				height: 100
				text: "close"
				onClicked: Qt.quit()
			}

			Button {
				id: inhibitButton

				anchors {
					top: closebutton.bottom
					left: closebutton.left
					right: closebutton.right
				}

				text: window.inhibiting ? "disable inhibitors" : "enable inhibitors"
				enabled: !inhibitTimer.running
				onClicked: {
					if (window.inhibiting) window.inhibiting = false;
					else inhibitTimer.running = true;
				}
			}

			Button {
				id: hideButton

				anchors {
					top: inhibitButton.bottom
					left: inhibitButton.left
					right: inhibitButton.right
				}

				text: "enable inhibitors && hide"

				visible: !window.inhibiting
				onClicked: {
					inhibitTimer.running = true
					window.visible = false
				}
			}

			Timer {
				id: inhibitTimer
				interval: 2000
				onTriggered: {
					window.inhibiting = true;
					window.visible = true;
				}
			}
		}
	}
}

You can build quickshell as a normal cmake project (needs wayland deps + qt6) and run the demo with quickshell --config /path/to/demo.qml.

This is the same demo shown in the attached video. It will open as a layershell on the overlay layer with a click mask over the buttons in the UI. "enable inhibitors" will wait for 2 seconds and then set the keyboard focus from none to exclusive along with disabling the click mask. "enable inhibitors & hide" will do the same thing except it will close the shell and open a new one with exclusive focus after the 2 second period ends.

In both cases the shell will not be able to take focus from the window.

Crash reports, logs, images, videos

https://github.com/hyprwm/Hyprland/assets/83010835/e01caf04-abe8-42c2-8d1a-509fc90b647a

outfoxxed avatar Mar 05 '24 02:03 outfoxxed

patch.txt try

vaxerski avatar Mar 05 '24 14:03 vaxerski

There are some issues with this patch:

  1. if an existing shell changes from none to exclusive the window does not release the mouse
  2. if an existing shell changes from exclusive to none then the shell does not release the keyboard until window focus changes

Newly created shells are able to kick you out of mouse grabs now though.

outfoxxed avatar Mar 06 '24 11:03 outfoxxed

patch.txt try this

vaxerski avatar Mar 09 '24 16:03 vaxerski

#1 is fixed, #2 is not. Additionally it broke making selections in slurp (bugs out all over the place) and I had to click my disable button 3 times (which seems like a similar / the same bug)

outfoxxed avatar Mar 10 '24 09:03 outfoxxed

Note: rolled back to 300d77edd9833db42c999a91271ae23a5be69ef2 so the patch would apply

outfoxxed avatar Mar 10 '24 09:03 outfoxxed

was fixed by #6394

outfoxxed avatar Jun 25 '24 18:06 outfoxxed