Skip to content

Rework surface state and geometry computation

Jonas Ådahl requested to merge jadahl/gtk:wip/surface-state-rework into master

This merge request represents the redesign of the GTK <-> GDK interaction regarding the size of the window, its backing surface, and their state management.

At a high level, backends should

  • Queue state (e.g. maximized) received from the windowing system via gdk_surface_queue_state_change(), which will then be applied early in the frame dispatch cycle. Will likely work fine without.
  • Queue surface size changes received via configure events, and apply them during GdkSurfaceClass::compute_size which is called during the layout clock phase. Will likely work fine without, as long as "gdk_surface_request_layout()" is called so GdkSurface::layout is emitted with the new size.
  • Keep track of shadow size themself internally to push to the windowing system and passed to the popup position computation helper.

The overall plan is to:

  • GTK has async API setting and getting state: gtk_window_maximize(), gtk_window_unmaximize(), GtkWindow::maximized gtk_window_fullscreen(), gtk_window_fullscreen_on_moniton(), gtk_window_unfullscreen(), GtkWindow::fullscreen
  • API functions are asynchronous, but behave differently depending on whether the window has been shown or not
    • If a window isn't yet shown, the corresponding property is immediately set to respect the intended value. When the window is shown, the corresponding backend configuration is created, which may or may not result in the property changing value after showing.
    • If a window isn't yet shown, the property is left untouched, and will not get updated until the backend, if ever, acknowledges the state request
    • Setting a property is the equivalent to calling the corresponding API function, i.e. it will only take immediate effect when not showing.
  • GDK keeps it gdk_toplevel_present() API, but it becomes asynchronous, it has no immediate effect
  • State changes are communicated to GTK before the update clock phase, i.e. during before-paint.
  • A new frame clock phase is added, between update and layout, called compute-size. During this phase, GDK will emit GdkSurface::compute-size, resize the GdkSurface, as well as emit GdkSurface::size-changed.
  • Do the equivalent changes for GdkPopup and GdkDragSurface.

Current state:

  • Make gdk_toplevel_present() async
    • Wayland
    • X11
    • Win32
    • Broadway
    • MacOS X
  • Push state changes to GTK during frame dispatch
    • Wayland
    • X11
    • Win32
    • Broadway
    • MacOS X
  • Compute toplevel size during frame dispatch
    • Wayland
    • X11 Resize is always async, so compute-size happens during present() still
    • Win32
    • Broadway
    • MacOS X
  • Push popup size during frame dispatch
    • Wayland
    • X11
    • Win32
    • Broadway
    • MacOS X
  • Push drag surface size during frame dispatch
    • Wayland
    • X11
    • Win32
    • Broadway
    • MacOS X
  • Add READWRITE properties for maximized and fullscreen to GtkWindow
Edited by Jonas Ådahl

Merge request reports