Skip to content
  1. Mar 29, 2024
  2. Mar 26, 2024
    • Samuel Thibault's avatar
      Merge branch 'michaelweghorn/take_workspace_and_window_size_into_account' into 'master' · aee8caee
      Samuel Thibault authored
      Some WinManager refactoring, take workspace into account for "Inspect under mouse"
      
      See merge request !55
      aee8caee
    • Michael Weghorn's avatar
      Only consider windows in current workspace for "Inspect under mouse" · fa99d675
      Michael Weghorn authored
      When using the "Inspect under mouse" feature, only consider those
      windows as candidates that are on the current workspace/virtual
      desktop.
      
      It's possible that another window on a different virtual desktop
      has a higher stacking index but is not even currently visible,
      and an object in that window could previously be identified as
      the alleged object under the mouse pointer if the window was at
      the corresponding coordinates on the other workspace/virtual desktop,
      instead of determining the actual window under the mouse on the current
      workspace/virtual desktop.
      
      This was observed with both, the Wnck-based `WindowManager`
      in a Plasma 5 X11 session on Debian testing, and with the
      KWin-based `KWinWindowManager` (enabled via
      `export ACCERCISER_WINDOW_MANAGER=kwin`) in a Plasma 5 Wayland
      session on Debian testing.
      
      To avoid that, only take into account those windows that are on the
      current workspace, using the `on_current_workspace` member
      of the...
      fa99d675
    • Michael Weghorn's avatar
      WindowInfo: Add info whether on current workspace · 6dba1ce5
      Michael Weghorn authored
      Add an `on_current_workspace` member to the
      `WindowInfo` class that describes whether the
      window is on the current workspace/virtual desktop
      or not.
      
      Retrieve the corresponding info from Wnck
      for `WindowManager` and via the KWin API
      for `KWinWindowManager`.
      
      The `Wnck.Screen.get_active_workspace` [1] and
      `Window.html#Wnck.Window.get_workspace` [2] docs
      both metion cases where the returned workspace
      can be `None`, so treat the window as on the current
      workspace in that case to be safe, e.g. cover this
      case mentioned in Window.get_workspace doc [2]:
      
      > Gets the current workspace self is on. If the window is pinned (on all
      > workspaces), or not on any workspaces, None may be returned.
      
      In the Plasma 5 script, just integers are available,
      and only a single desktop number is returned for the
      desktop the window is on.
      (Since it's possible to set a window on an arbitrary
      set of virtual desktops, this does not guarantee the
      correct result when manually setting a w...
      6dba1ce5
    • Michael Weghorn's avatar
      Unify WindowManager implementations further, consider size · 8d9cc454
      Michael Weghorn authored
      Rework window info handling in `WindowManager` and its
      `KWinWindowManager` subclass a bit:
      
      1) Merge the logic from `KWinWindowManager#_getKWinWindowData` and
      `KWinWindowManager#getWindowInfo` (that returns info about a single
      window for a given accessible toplevel)
      to override the base class's `getWindowInfos` (introduced
      in a previous commit, returns infos for all system windows)
      instead and drop the `KWinWindowManager#getWindowInfo` override,
      so that the base class implementation is used, which was
      prepared for that in the previous commit.
      
      This means that the logic to distinguish between
      two windows that have the same name by also taking
      into account the corresponding sizes, originally introduced
      for the Wnck-based implementation in
      
          commit 0860b06a
          Author: Michael Weghorn <m.weghorn@posteo.de>
          Date:   Thu Dec 21 16:51:04 2023 +0100
      
              node: More reliably detect the right gtk4 window
      
      now also applies for the KWin implementation.
      
      In a test on Debian testing with Plasma 5 Wayland with
      `export ACCERCISER_WINDOW_MANAGER=kwin` and gtk4-demo
      or two instances of the qtbase standarddialogs sample app
      running, with both windows having different sizes,
      the correct one is highlighted for each one of them now
      when selecting one of its objects in the a11y treeview in
      Accerciser, while that was not the case yet without
      this change in place.
      (In a Plasma X11 session, this still doesn't work;
      likely there's a mismatch between the sizes reported by
      KWin and via AT-SPI.)
      
      2) Merge the logic to sort windows by stacking index
      from `KWinWindowManager#getWindowOrder` into
      `KWinWindowManager#getWindowOrder`, replacing the
      previous Wnck-specific implementation in the former.
      
      This makes use of the `stacking_index` member
      added to the `WindowInfo` class in the previous
      commit.
      
      Related issue: #41
      8d9cc454
    • Michael Weghorn's avatar
      WindowInfo: Add stacking order · 6a265ebe
      Michael Weghorn authored
      Add `stacking_index` as a new member to the
      `WindowInfo` class. This is used to distinguish
      which of the windows is further up on the windows
      stack. A lower stacking index means that the window
      is lower in the stack.
      
      The KWin implementation already retrieves the info
      via the KWin script.
      
      For the Wnck implementation, use `Wnck.Screen.get_windows_stacked`
      in `WindowManager#getWindowInfos` as well and just increase the
      index for each window.
      
      This will allow to unify `WindowManager#getWindowOrder`
      and the implementation in the `KWinWindowManager` subclass
      in an upcoming commit.
      
      Related issue: #41
      6a265ebe
    • Michael Weghorn's avatar
      win manager: Refactor window info retrieval · c899a411
      Michael Weghorn authored
      Refactor the handling to get a `WindowInfo` (i.e.
      corresponding information on the system/Wnck window)
      for a given accessible toplevel for the Wnck-based
      implementation in the `WindowManager` class:
      
      Introduce a new method `WindowManager#getWindowInfos`
      that returns a list of `WindowInfo`, containing infos
      for all system windows. Use that to implement
      `WindowManager#getWindowInfo` rather than dealing
      with the Wnck.window class in that method.
      
      This limits the use of Wnck-specific classes
      to the new `WindowManager#getWindowInfos` method
      and prepares for reuse of `WindowManager#getWindowInfo`
      for deriving classes to avoid code duplication.
      
      Related issue: #41
      c899a411
    • Michael Weghorn's avatar
      win manager: Add more infos to WindowInfo · 16c92019
      Michael Weghorn authored
      Add members for window title, width and height
      to the WindowInfo class and pass these for the
      Wnck and KWin implementations.
      
      Related issue: #41
      16c92019
  3. Mar 23, 2024
  4. Mar 22, 2024
    • Michael Weghorn's avatar
      KWin: Use 'console.info' instead of 'print' in KWin script · d059f5e6
      Michael Weghorn authored
      In a newly set up Fedora RawHide VM with Plasma 6, the KWin
      scripts were not generating any output in the
      journal. Therefore, retrieving the information from there
      would fail and highlighting the currently selected object
      or inspecting the object under the mouse pointer wouldn't
      work there with Accerciser's KWinWindowManager in a Wayland
      session, enabled via env variable
      `ACCERCISER_WINDOW_MANAGER=kwin`.
      
      Switch from using `print()` to `console.info()`, which
      makes this work there as well without having to adjust any
      configuration, while still working in
      both setups I was testing this in previously (Debian testing
      with Plasma 5, KDE Neon dev unstable with Plasma 6).
      
      Thanks to reddit user "RealFenlair" who mentioned this
      in a reddit post! [1]
      
      [1] https://www.reddit.com/r/kde/comments/15jm7me/comment/jv9u0ex/
      
      Related issue: #41
      d059f5e6
    • Michael Weghorn's avatar
      quick_select: Prevent accessing unassigned variable · eaf81189
      Michael Weghorn authored
      Assign a default value of `None` to `inner_container`,
      as it can otherwise happen that this the variable is
      accessed further below without having been assigned.
      
      This was breaking the "Inspect under mouse" feature
      with the `KWinWindowManager` on Wayland, where an
      exception would be triggered in a call to this
      method from `QuickSelect#_inspectUnderMouse`
      for one of the frames of the "plasmashell" app:
      
          Traceback (most recent call last):
            File "/usr/lib/python3/dist-packages/pyatspi/registry.py", line 209, in eventWrapper
              return callback(event)
                     ^^^^^^^^^^^^^^^
            File "/home/michi/temp/accerciser/lib/python3/dist-packages/accerciser/hotkey_manager.py", line 73, in _accEventKeyPressed
              handled = self.hotkeyPress(event.hw_code, event.modifiers)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            File "/home/michi/temp/accerciser/lib/python3/dist-packages/accerciser/hotkey_manager.py", line 99, in hotkeyPress
              callback()
            File "/home/michi/temp/accerciser/share/accerciser/plugins/quick_select.py", line 103, in _inspectUnderMouse
              acc = self._getComponentAtCoords(frame, x, y)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            File "/home/michi/temp/accerciser/share/accerciser/plugins/quick_select.py", line 199, in _getComponentAtCoords
              if inner_container == parent:
                 ^^^^^^^^^^^^^^^
          UnboundLocalError: cannot access local variable 'inner_container' where it is not associated with a value
      
      With this fix in place, the "Inspect under mouse"
      feature works now to select the object under mouse
      for example with the qtbase standarddialogs example
      in a Plasma Wayland session on Debian testing when
      enabling the use of the `KWinWindowManager` via
      environment variable
      `ACCERCISER_WINDOW_MANAGER=kwin`.
      
      Related issue: #41
      eaf81189
    • Michael Weghorn's avatar
      KWinWindowManager: Get window stacking order from KWin · 55106f15
      Michael Weghorn authored
      Override `WindowManager#getWindowOrder` in
      `KWinWindowManager` and use the stacking order information
      from KWin.
      
      Extend the KWin script that retrieves information
      for all windows to include the stacking order
      and build the list from that information.
      (Higher `stackingOrder` means that the window
      is further up.)
      
      This helps getting rid of another case that was relying on
      Wnck, with the latter not working on Wayland.
      
      In a quick test, "Inspect under mouse" was generally working
      as expected with
      `export ACCERCISER_WINDOW_MANAGER=kwin`
      in a KDE Plasma X11 session on Debian testing,
      using gtk4-demo and the qtbase standarddialogs example
      applications for testing.
      (Position for the qtbase standarddialogs example is slightly
      off, but that's unrelated to this commit.)
      
      Due to another issue that will be fixed separately in an
      upcoming commit, the same use case does not yet work in a KDE
      Plasma Wayland session.
      
      Related issue: #41
      55106f15
    • Michael Weghorn's avatar
      Move retrieval of window stacking order to WindowManager · 61200e63
      Michael Weghorn authored
      Move the existing logic to get a bottom-to-top sorted list
      of windows (by their names) to a new method in `WindowManager`,
      `WindowManager#getWindowOrder`.
      
      This can be overriden by derived classes that don't
      need to rely on Wnck.
      61200e63
    • Michael Weghorn's avatar
      KWinWindowManager: Get mouse position via KWin API · 4b955bfd
      Michael Weghorn authored
      Override `WindowManager#getMousePosition` in
      `KWinWindowManager` and use a script to retrieve the
      mouse position via the KWin scripting API [1].
      
      Other than the `WindowManager#getMousePosition`
      implementation, this also gives the correct result
      on Wayland.
      
      [1] https://develop.kde.org/docs/plasma/kwin/api/
      
      Related issue: #41
      4b955bfd
    • Michael Weghorn's avatar
      KWinWindowManager: Extract helper method to run script · 344d8c33
      Michael Weghorn authored
      This will be reused in an upcoming commit.
      344d8c33
    • Michael Weghorn's avatar
      Move mouse position retrieval to WindowManager · 797447f9
      Michael Weghorn authored
      Move existing code to retrieve the current
      mouse/pointer position to the `WindowManager`
      class, in order to allow overriding the default
      implementation in subclasses.
      797447f9
    • Michael Weghorn's avatar
      KWinWindowManager: Don't fail on win title containing quotes · a4df2d24
      Michael Weghorn authored
      When a window title was containing quotes, this would
      previously break the processing in KWinWindowManager,
      as these were not properly escaped in the JavaScript KWin script,
      then resulting in errors when parsing on the Python side.
      
      For example, Firefox with a browser tab with an HTML file like
      
          <!DOCTYPE html>
          <html>
            <head>
              <title>Title with &quot;Quotes&quot; that break things - and &apos;single quotes&apos; also </title>
            </head>
            <body>
            </body>
          </html>
      
      would have such a window title, resulting in an array entry like this:
      
          {
          "caption": "Title with "Quotes" that break things - and 'single quotes' also — Mozilla Firefox",
          "bufferGeometry.x": 0,
          "bufferGeometry.y": 0,
          "bufferGeometry.width": 1920,
          "bufferGeometry.height": 1044},
      
      and parsing that would then fail with an exception like
      
          WARNING:root:exception in getWindowInfo: Expecting ',' delimiter: line 51 column 25 (char 1252)
      
      Drop the custom building of the JSON string altogether and rather build
      a JSON object and let `JSON.stringify` take care of converting that to
      a string, including all necessary escaping.
      
      This gives an entry like this in the resulting JSON string:
      
          {'caption': 'Title with "Quotes" that break things - and \'single quotes\' also — Mozilla Firefox', 'bufferGeometry.x': 0, 'bufferGeometry.y': 0, 'bufferGeometry.width': 1920, 'bufferGeometry.height': 1044},
      
      and makes parsing and highlighting the proper object work as expected.
      
      Related issue: #41
      a4df2d24
  5. Mar 21, 2024
  6. Mar 20, 2024
  7. Mar 19, 2024
    • Michael Weghorn's avatar
      KWinWindowManager: Support KWin 6 as well · 0f1feb49
      Michael Weghorn authored
      The KWinWindowManager introduced in the previous
      commit works fine on KWin 5.
      
      This commit takes into account changes introduced
      in Plasma 6/KWin 6 and makes this work in a test
      in a KDE Plasma Neon dev unstable VM as well.
      
      1) The path for the Kwin script's DBus objects changed.
      
      2) The `Workspace.clientList` method of the KWin API
      was renamed to `Workspace.windowList` in KWin 6
      in commit [1]
      
          commit ceac574a688569d2fc03d4718804f828a3918aed
          Author: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
          Date:   Wed Aug 23 11:42:26 2023 +0300
      
              scripting: Rename Workspace.clientList
      
      Therefore, rename the existing KWin script to contain
      the version number 5 in it's name and add an adjusted
      version to use for KWin 6 that uses the new method
      name.
      
      In order to decide what version of KWin to support,
      evaluate the `KDE_SESSION_VERSION` environment variable
      that KDE Plasma sets, assuming that KDE Plasma and
      KWin have the same version number (or requiring to
      manually set the variable in addition when starting
      Accerciser with `ACCERCISER_WINDOW_MANAGER=kwin`).
      
      [1] https://invent.kde.org/plasma/kwin/-/commit/ceac574a688569d2fc03d4718804f828a3918aed
      0f1feb49
    • Michael Weghorn's avatar
      Add a window manager that retrieves screen coords from KWin · 6526519b
      Michael Weghorn authored
      Add a `KWinWindowManager` that can be used to retrieve
      window positions using the KWin window manager/Wayland
      compositor that is used on KDE Plasma by default.
      
      In order to do that, a JavaScript KWin script is used
      that retrieves the global/screen positions of windows
      using KWin's scripting API [1].
      The script can be loaded and run via DBus.
      (python3-dbus is used for this, added as a new dependency.)
      
      Unfortunately, the script output is currently not
      available via DBus, which seems to be a KDE bug,
      see [2] [3] [4].
      
      As a workaround, retrieve the script output
      from the journal using `journalctl` instead, see
      also the discussion in [4].
      
      For now, the Wnck-based window manager (that doesn't
      work on Wayland with native Wayland apps, see
      issue #41) remains the default.
      Use of the KWin window manager can explicitly
      be enabled by setting the environment variable
      `ACCERCISER_WINDOW_MANAGER=kwin`.
      
      (Adding some heuristics to choose a WindowManager
      might m...
      6526519b
  8. Mar 18, 2024
    • Michael Weghorn's avatar
      Add helper function to get window manager · f39cfade
      Michael Weghorn authored
      Rather than instantiating one explicitly where
      needed, add a `get_window_manager` helper function
      to the window_manager module that creates and returns one.
      
      This is in preparation of supporting alternative
      implementations.
      f39cfade
    • Michael Weghorn's avatar
      win manager: Extract helper method to get system win infos · 96d5182a
      Michael Weghorn authored
      Introduce a new `WindowInfo` class to represent relevant
      information on a system window (currently only x and y position).
      
      Extract a helper method `WindowManager#getWindowInfo` that
      retrieves the window info using the current Wnck-based
      implementation.
      
      This is in preparation of implementing alternative ways
      of retrieving that information.
      96d5182a
  9. Mar 15, 2024
  10. Mar 13, 2024