diff --git a/0001-magnifier-Request-window-relative-coordinates-for-fo.patch b/0001-magnifier-Request-window-relative-coordinates-for-fo.patch new file mode 100644 index 0000000..0ebffe9 --- /dev/null +++ b/0001-magnifier-Request-window-relative-coordinates-for-fo.patch @@ -0,0 +1,148 @@ +From ea7e7acd45e428cc17306de2bf65730c90d7e118 Mon Sep 17 00:00:00 2001 +From: Sebastian Keller +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: + +--- + 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 + diff --git a/gnome-shell.spec b/gnome-shell.spec index 2d73792..670c143 100644 --- a/gnome-shell.spec +++ b/gnome-shell.spec @@ -2,7 +2,7 @@ Name: gnome-shell Version: 40.10 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Window management and application launching for GNOME License: GPLv2+ @@ -49,6 +49,7 @@ Patch47: 0001-layout-Initialize-regions-unconditionally.patch Patch48: 0001-introspect-Allowlist-GNOME-portal.patch Patch49: 0001-introspect-Add-WindowsChanged-signal.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 gnome_desktop_version 3.35.91 @@ -267,6 +268,10 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/evolution-calendar.de %{_mandir}/man1/gnome-shell.1* %changelog +* Wed Jan 18 2023 Florian Müllner - 40.10-6 +- Request window-relative coordinates in focus tracker + Resolves: #2009350 + * Fri Dec 02 2022 Jonas Ådahl - 40.10-5 - Backport 'WindowsChanged' introspect signal Related: #2148362