[go: up one dir, main page]

Draft: [GTK4] Port to event controllers

Hello!

This is the result of my initial exploratory work in preparing Inkscape for a future GTK 4 port. This aims to address the changes in the GTK event system, which is currently the largest blocker for GTK4.

Testing is thoroughly appreciated (please read bottom for details).

Thanks to @pbs3141 for code fixes and a lot of the key groundwork for this.

Depends heavily on !4876 (merged). Unfortunately this makes the diff quite unreadable. This comparison provides a better example until that is merged.

Background

GTK provides an abstraction over input devices so they can be accessed in a unified and cross platform way. When input is received from the windowing system, GDK (the ‘GTK Drawing Kit’– the abstraction layer for events, drawing, and windowing) translates these into a series of different event types. If applications want to have complex input handling, they are expected to read the raw input stream and react accordingly.

Under GTK4, this model has changed quite radically. Applications are no longer given access to the raw input system. They are expected to instead use GtkEventController auxiliary objects and attach them to widgets.

  • Each event controller corresponds to a particular kind of input. For example, we have EventControllerKey to handle keyboard events.
  • When events occur, the event controller corresponding to that event is notified and calls the program saying: “this is an event and here is what happens”. It is automatically rate limited and synchronised to GTK’s frame clock.

Rationale (The Inkscape Model)

Now that events are internal to GTK, Inkscape can no longer create and emit events at will. This breaks the fundamental input model that Inkscape’s Canvas uses. There are thus two options for making Inkscape GTK4-compatible:

  1. Make Inkscape canvas items into GTK Widgets (not recommended)
  2. Create a lightweight input abstraction on top of Canvas

In this PR, I've implemented the latter.

Architecture Overview

The proposed architecture in this PR creates a Canvas-specific event system for manipulating objects within the Canvas. Rather than passing GdkEvent objects to tools directly, Inkscape registers numerous Event Controllers on Canvas and when received, 'offers' these to the Canvas for processing. In a sense, the Canvas becomes a black box which is offered events and either consumes or rejects them. Rejected events will continue to propagate through GTK's widget hierarchy, e.g. so accelerators can work but do not interfere with typing.

What this means in practice is that Inkscape’s Canvas can become mostly/fully decoupled from GTK. This makes the Canvas code more resilient to future API/ABI changes, and better follows the design of GTK 4 (which strongly discourages using GdkEvent directly).

The new event types are one-to-one mappings of the current GDK Events – i.e. ‘GdkEventButton’ becomes a new ‘ButtonEvent’ class which preserves all fields currently in use by Inkscape. These events can 'synthesise' fake compatibility events, so Inkscape's (very complex and numerous) tools can be ported over piecemeal rather than in one giant un-review-able PR. My thinking here is to minimise the size of the changes that needs to be done at any one time, making this a lot more manageable.

This PR

This PR implements the first step of this process, which is to do an 'in-place' replacement of widget event signals with event controllers. When the event controllers are invoked, a compatibility GdkEvent is synthesised and fired into the Canvas. The idea is to prove that we can obtain all necessary event details from the event controllers and maintain functionality with no regressions.

  1. Replace event signals with event controllers <-- We are here
  2. Replace internal propagation of events
  3. Port over each individual tool
  4. Remove any direct uses of GdkEvent anywhere in the Canvas

Testing & Feedback

I'd love to hear your feedback on this architecture (what works/doesn't). I'm also looking to make sure there are no regressions with this approach. Trying out this branch and reporting breakages is strongly appreciated.

Known Issues

  • Selection bug while scrolling
  • Cannot press +Q to quit as it is consumed by quick zoom tool
  • Right clicking on the canvas does not work well
  • Motion events are only received while dragging
  • Cannot double click text in text tool
  • Right clicking while dragging cause the canvas to jump
  • Missing GdkWindow for text tool's input method context
Edited by PBS

Merge request reports

Loading