Request window-relative coordinates in focus tracking
Resolves: #2009350
This commit is contained in:
parent
97040a32ad
commit
af5c85c6c9
148
0001-magnifier-Request-window-relative-coordinates-for-fo.patch
Normal file
148
0001-magnifier-Request-window-relative-coordinates-for-fo.patch
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
From ea7e7acd45e428cc17306de2bf65730c90d7e118 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sebastian Keller <skeller@gnome.org>
|
||||||
|
Date: Mon, 23 May 2022 23:01:23 +0200
|
||||||
|
Subject: [PATCH] magnifier: Request window-relative coordinates for
|
||||||
|
focus/caret events
|
||||||
|
|
||||||
|
Absolute screen coordinates are impossible for Wayland clients to
|
||||||
|
provide, because the clients don't know where the window is positioned.
|
||||||
|
Some clients, such as the ones using GTK 3 were providing window
|
||||||
|
relative coordinates even when screen coordinates were requested,
|
||||||
|
while others, such as GTK 4 clients, were just returning an error for
|
||||||
|
caret events or also window-relative coordinates for focus events.
|
||||||
|
|
||||||
|
So for this to work on Wayland we have to request window-relative
|
||||||
|
coordinates and translate them to the current focus window.
|
||||||
|
|
||||||
|
To ensure the correct coordinates, we have to only consider events
|
||||||
|
coming from the current focus window. All other events are filtered out
|
||||||
|
now. As a side effect this also fixes the magnifier always jumping
|
||||||
|
to a terminal cursor whenever there was some output, even if the window
|
||||||
|
was not focused.
|
||||||
|
|
||||||
|
This also needs some special handling for events coming from the shell
|
||||||
|
itself, which should not be translated to the focus window either. As
|
||||||
|
another side effect this fixes another bug that was caused by these
|
||||||
|
events already including scaling and getting scaled again.
|
||||||
|
|
||||||
|
Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5509
|
||||||
|
Part-of:
|
||||||
|
<https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2301>
|
||||||
|
---
|
||||||
|
js/ui/magnifier.js | 77 +++++++++++++++++++++++++++++++++++++++++-----
|
||||||
|
1 file changed, 70 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/js/ui/magnifier.js b/js/ui/magnifier.js
|
||||||
|
index 4c2e88f1a..9813664be 100644
|
||||||
|
--- a/js/ui/magnifier.js
|
||||||
|
+++ b/js/ui/magnifier.js
|
||||||
|
@@ -789,21 +789,81 @@ var ZoomRegion = class ZoomRegion {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ _convertExtentsToScreenSpace(accessible, extents) {
|
||||||
|
+ const toplevelWindowTypes = new Set([
|
||||||
|
+ Atspi.Role.FRAME,
|
||||||
|
+ Atspi.Role.DIALOG,
|
||||||
|
+ Atspi.Role.WINDOW,
|
||||||
|
+ ]);
|
||||||
|
+
|
||||||
|
+ try {
|
||||||
|
+ let app = null;
|
||||||
|
+ let parentWindow = null;
|
||||||
|
+ let iter = accessible;
|
||||||
|
+ while (iter) {
|
||||||
|
+ if (iter.get_role() === Atspi.Role.APPLICATION) {
|
||||||
|
+ app = iter;
|
||||||
|
+ /* This is the last Accessible we are interested in */
|
||||||
|
+ break;
|
||||||
|
+ } else if (toplevelWindowTypes.has(iter.get_role())) {
|
||||||
|
+ parentWindow = iter;
|
||||||
|
+ }
|
||||||
|
+ iter = iter.get_parent();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* We don't want to translate our own events to the focus window.
|
||||||
|
+ * They are also already scaled by clutter before being sent, so
|
||||||
|
+ * we don't need to do that here either. */
|
||||||
|
+ if (app && app.get_name() === 'gnome-shell')
|
||||||
|
+ return extents;
|
||||||
|
+
|
||||||
|
+ /* Only events from the focused widget of the focused window. Some
|
||||||
|
+ * widgets seem to claim to have focus when the window does not so
|
||||||
|
+ * check both. */
|
||||||
|
+ const windowActive = parentWindow &&
|
||||||
|
+ parentWindow.get_state_set().contains(Atspi.StateType.ACTIVE);
|
||||||
|
+ const accessibleFocused =
|
||||||
|
+ accessible.get_state_set().contains(Atspi.StateType.FOCUSED);
|
||||||
|
+ if (!windowActive || !accessibleFocused)
|
||||||
|
+ return null;
|
||||||
|
+ } catch (e) {
|
||||||
|
+ throw new Error(`Failed to validate parent window: ${e}`);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ const focusWindowRect = global.display.focus_window?.get_frame_rect();
|
||||||
|
+ if (!focusWindowRect)
|
||||||
|
+ return null;
|
||||||
|
+
|
||||||
|
+ const scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||||
|
+ const screenSpaceExtents = new Atspi.Rect({
|
||||||
|
+ x: focusWindowRect.x + (scaleFactor * extents.x),
|
||||||
|
+ y: focusWindowRect.y + (scaleFactor * extents.y),
|
||||||
|
+ width: scaleFactor * extents.width,
|
||||||
|
+ height: scaleFactor * extents.height,
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ return screenSpaceExtents;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
_updateFocus(caller, event) {
|
||||||
|
let component = event.source.get_component_iface();
|
||||||
|
if (!component || event.detail1 != 1)
|
||||||
|
return;
|
||||||
|
let extents;
|
||||||
|
try {
|
||||||
|
- extents = component.get_extents(Atspi.CoordType.SCREEN);
|
||||||
|
+ extents = component.get_extents(Atspi.CoordType.WINDOW);
|
||||||
|
+ extents = this._convertExtentsToScreenSpace(event.source, extents);
|
||||||
|
+ if (!extents)
|
||||||
|
+ return;
|
||||||
|
} catch (e) {
|
||||||
|
log(`Failed to read extents of focused component: ${e.message}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||||
|
- let [xFocus, yFocus] = [(extents.x + (extents.width / 2)) * scaleFactor,
|
||||||
|
- (extents.y + (extents.height / 2)) * scaleFactor];
|
||||||
|
+ const [xFocus, yFocus] = [
|
||||||
|
+ extents.x + (extents.width / 2),
|
||||||
|
+ extents.y + (extents.height / 2),
|
||||||
|
+ ];
|
||||||
|
|
||||||
|
if (this._xFocus !== xFocus || this._yFocus !== yFocus) {
|
||||||
|
[this._xFocus, this._yFocus] = [xFocus, yFocus];
|
||||||
|
@@ -817,14 +877,17 @@ var ZoomRegion = class ZoomRegion {
|
||||||
|
return;
|
||||||
|
let extents;
|
||||||
|
try {
|
||||||
|
- extents = text.get_character_extents(text.get_caret_offset(), 0);
|
||||||
|
+ extents = text.get_character_extents(text.get_caret_offset(),
|
||||||
|
+ Atspi.CoordType.WINDOW);
|
||||||
|
+ extents = this._convertExtentsToScreenSpace(text, extents);
|
||||||
|
+ if (!extents)
|
||||||
|
+ return;
|
||||||
|
} catch (e) {
|
||||||
|
log(`Failed to read extents of text caret: ${e.message}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
||||||
|
- let [xCaret, yCaret] = [extents.x * scaleFactor, extents.y * scaleFactor];
|
||||||
|
+ const [xCaret, yCaret] = [extents.x, extents.y];
|
||||||
|
|
||||||
|
// Ignore event(s) if the caret size is none (0x0). This happens a lot if
|
||||||
|
// the cursor offset can't be translated into a location. This is a work
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Name: gnome-shell
|
Name: gnome-shell
|
||||||
Version: 40.10
|
Version: 40.10
|
||||||
Release: 5%{?dist}
|
Release: 6%{?dist}
|
||||||
Summary: Window management and application launching for GNOME
|
Summary: Window management and application launching for GNOME
|
||||||
|
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
@ -49,6 +49,7 @@ Patch47: 0001-layout-Initialize-regions-unconditionally.patch
|
|||||||
Patch48: 0001-introspect-Allowlist-GNOME-portal.patch
|
Patch48: 0001-introspect-Allowlist-GNOME-portal.patch
|
||||||
Patch49: 0001-introspect-Add-WindowsChanged-signal.patch
|
Patch49: 0001-introspect-Add-WindowsChanged-signal.patch
|
||||||
Patch50: 0001-window-tracker-Emit-tracked-windows-changed-on-title.patch
|
Patch50: 0001-window-tracker-Emit-tracked-windows-changed-on-title.patch
|
||||||
|
Patch51: 0001-magnifier-Request-window-relative-coordinates-for-fo.patch
|
||||||
|
|
||||||
%define eds_version 3.33.1
|
%define eds_version 3.33.1
|
||||||
%define gnome_desktop_version 3.35.91
|
%define gnome_desktop_version 3.35.91
|
||||||
@ -267,6 +268,10 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/evolution-calendar.de
|
|||||||
%{_mandir}/man1/gnome-shell.1*
|
%{_mandir}/man1/gnome-shell.1*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Jan 18 2023 Florian Müllner <fmuellner@redhat.com> - 40.10-6
|
||||||
|
- Request window-relative coordinates in focus tracker
|
||||||
|
Resolves: #2009350
|
||||||
|
|
||||||
* Fri Dec 02 2022 Jonas Ådahl <jadahl@redhat.com> - 40.10-5
|
* Fri Dec 02 2022 Jonas Ådahl <jadahl@redhat.com> - 40.10-5
|
||||||
- Backport 'WindowsChanged' introspect signal
|
- Backport 'WindowsChanged' introspect signal
|
||||||
Related: #2148362
|
Related: #2148362
|
||||||
|
Loading…
Reference in New Issue
Block a user