Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
outfoxxed opened this issue Mar 5, 2024 · 6 comments
Closed
Labels
bug Something isn't working stale Not much going on

Comments

@outfoxxed
Copy link
Member

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

output.mp4
@outfoxxed outfoxxed added the bug Something isn't working label Mar 5, 2024
@outfoxxed outfoxxed changed the title Leyershells cannot steal focus from a window that has captured the mouse Layershells cannot steal focus from a window that has captured the mouse Mar 5, 2024
@vaxerski
Copy link
Member

vaxerski commented Mar 5, 2024

patch.txt
try

@outfoxxed
Copy link
Member Author

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.

@vaxerski
Copy link
Member

vaxerski commented Mar 9, 2024

patch.txt
try this

@outfoxxed
Copy link
Member Author

#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
Copy link
Member Author

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

@outfoxxed
Copy link
Member Author

was fixed by #6394

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working stale Not much going on
Projects
None yet
Development

No branches or pull requests

2 participants