Blender V4.3
GHOST_WindowWayland.cc File Reference
#include "GHOST_WindowWayland.hh"
#include "GHOST_SystemWayland.hh"
#include "GHOST_WaylandUtils.hh"
#include "GHOST_WindowManager.hh"
#include "GHOST_utildefines.hh"
#include "GHOST_Event.hh"
#include "GHOST_ContextNone.hh"
#include <wayland-client-protocol.h>
#include <algorithm>
#include <fractional-scale-v1-client-protocol.h>
#include <viewporter-client-protocol.h>
#include <xdg-activation-v1-client-protocol.h>
#include <xdg-decoration-unstable-v1-client-protocol.h>
#include <xdg-shell-client-protocol.h>
#include <atomic>
#include <cstring>
#include <malloc.h>
#include "CLG_log.h"

Go to the source code of this file.

Classes

struct  GWL_XDG_Decor_Window
 
struct  GWL_WindowScaleParams
 
struct  GWL_WindowCursorCustomShape
 
struct  GWL_WindowFrame
 
struct  GWL_Window
 

Functions

static void gwl_xdg_decor_window_destroy (GWL_XDG_Decor_Window *decor)
 
Rounding Utilities
static void gwl_round_int_by (int *value_p, const int round_value)
 
static void gwl_round_int2_by (int value_p[2], const int round_value)
 
static bool gwl_round_int_test (int value, const int round_value)
 
Window-Viewport/Wayland to/from Scale Conversion
wl_fixed_t gwl_window_scale_wl_fixed_to (const GWL_WindowScaleParams &scale_params, wl_fixed_t value)
 
wl_fixed_t gwl_window_scale_wl_fixed_from (const GWL_WindowScaleParams &scale_params, wl_fixed_t value)
 
int gwl_window_scale_int_to (const GWL_WindowScaleParams &scale_params, int value)
 
int gwl_window_scale_int_from (const GWL_WindowScaleParams &scale_params, int value)
 
Internal #GWL_WindowCursorCustomShape
static void gwl_window_cursor_custom_free (GWL_WindowCursorCustomShape &ccs)
 
static void gwl_window_cursor_custom_clear (GWL_WindowCursorCustomShape &ccs)
 
static void gwl_window_cursor_custom_store (GWL_WindowCursorCustomShape &ccs, const uint8_t *bitmap, const uint8_t *mask, const int32_t size[2], const int32_t hot_spot[2], bool can_invert_color)
 
static GHOST_TSuccess gwl_window_cursor_custom_load (const GWL_WindowCursorCustomShape &ccs, GHOST_SystemWayland *system)
 
static GHOST_TSuccess gwl_window_cursor_shape_refresh (GHOST_TStandardCursor shape, const GWL_WindowCursorCustomShape &ccs, GHOST_SystemWayland *system)
 
Internal #GWL_Window Viewport Setup/Tear-down

A viewport is needed to implement fractional scale, as the outputs scale may change at runtime, support creating & clearing the viewport as needed.

static int gwl_window_fractional_to_viewport (const GWL_WindowFrame &frame, int value)
 
static int gwl_window_fractional_from_viewport (const GWL_WindowFrame &frame, int value)
 
static int gwl_window_fractional_to_viewport_round (const GWL_WindowFrame &frame, int value)
 
static int gwl_window_fractional_from_viewport_round (const GWL_WindowFrame &frame, int value)
 
static bool gwl_window_viewport_set (GWL_Window *win, bool *r_surface_needs_commit, bool *r_surface_needs_buffer_scale)
 
static bool gwl_window_viewport_unset (GWL_Window *win, bool *r_surface_needs_commit, bool *r_surface_needs_buffer_scale)
 
static bool gwl_window_viewport_size_update (GWL_Window *win)
 
Internal #GWL_Window Activation
static void gwl_window_activate (GWL_Window *win)
 
Internal #GWL_Window Pending Actions
static void gwl_window_frame_pending_fractional_scale_set_notest (GWL_Window *win, bool *r_surface_needs_commit, bool *r_surface_needs_buffer_scale)
 
static void gwl_window_frame_pending_fractional_scale_set (GWL_Window *win, bool *r_surface_needs_commit, bool *r_surface_needs_buffer_scale)
 
static void gwl_window_frame_pending_size_set (GWL_Window *win, bool *r_surface_needs_commit, bool *r_surface_needs_resize_for_backend, bool *r_surface_needs_buffer_scale)
 
static void gwl_window_frame_update_from_pending (GWL_Window *win)
 
static void gwl_window_pending_actions_tag (GWL_Window *win, enum eGWL_PendingWindowActions type)
 
static void gwl_window_pending_actions_handle (GWL_Window *win)
 
static void gwl_window_frame_update_from_pending_no_lock (GWL_Window *win)
 
Internal Utilities
static int output_scale_cmp (const GWL_Output *output_a, const GWL_Output *output_b)
 
static int outputs_max_scale_or_default (const std::vector< GWL_Output * > &outputs, const int32_t scale_default, int *r_scale_fractional)
 
static int outputs_uniform_scale_or_default (const std::vector< GWL_Output * > &outputs, const int32_t scale_default, int *r_scale_fractional)
 

Variables

static constexpr size_t base_dpi = 96
 

Internal #GWL_Window

#define PENDING_NUM   (PENDING_WINDOW_CURSOR_SHAPE_REFRESH + 1)
 
enum  eGWL_PendingWindowActions {
  PENDING_WINDOW_FRAME_CONFIGURE = 0 , PENDING_OUTPUT_SCALE_UPDATE , PENDING_OUTPUT_SCALE_UPDATE_DEFERRED , PENDING_WINDOW_SURFACE_COMMIT ,
  PENDING_WINDOW_CURSOR_SHAPE_REFRESH
}
 
static void gwl_window_resize_for_backend (GWL_Window *win, const int32_t size[2])
 
static void gwl_window_title_set (GWL_Window *win, const char *title)
 
static GHOST_TWindowState gwl_window_state_get (const GWL_Window *win)
 
static bool gwl_window_state_set_for_xdg (xdg_toplevel *toplevel, const GHOST_TWindowState state, const GHOST_TWindowState state_current)
 
static bool gwl_window_state_set (GWL_Window *win, const GHOST_TWindowState state)
 

Listener (Surface), #wl_surface_listener

#define LOG   (&LOG_WL_XDG_TOPLEVEL)
 
#define LOG   (&LOG_WL_FRACTIONAL_SCALE)
 
#define LOG   (&LOG_WL_XDG_TOPLEVEL_DECORATION)
 
#define LOG   (&LOG_WL_XDG_SURFACE)
 
#define LOG   (&LOG_WL_SURFACE)
 
static CLG_LogRef LOG_WL_SURFACE = {"ghost.wl.handle.surface"}
 
static const wl_surface_listener wl_surface_listener
 
static void surface_handle_enter (void *data, wl_surface *, wl_output *wl_output)
 
static void surface_handle_leave (void *data, wl_surface *, wl_output *wl_output)
 

Listener (XDG Top Level), #xdg_toplevel_listener

static CLG_LogRef LOG_WL_XDG_TOPLEVEL = {"ghost.wl.handle.xdg_toplevel"}
 
static const xdg_toplevel_listener xdg_toplevel_listener
 
static void xdg_toplevel_handle_configure (void *data, xdg_toplevel *, const int32_t width, const int32_t height, wl_array *states)
 
static void xdg_toplevel_handle_close (void *data, xdg_toplevel *)
 
static void xdg_toplevel_handle_configure_bounds (void *data, xdg_toplevel *, int32_t width, int32_t height)
 
static void xdg_toplevel_handle_wm_capabilities (void *, xdg_toplevel *, wl_array *)
 

Listener (XDG Activation), #xdg_activation_v1_interface

Used by gwl_window_activate.

static const xdg_activation_token_v1_listener xdg_activation_listener
 
static const xdg_activation_token_v1_listener * xdg_activation_listener_get ()
 
static void xdg_activation_handle_done (void *data, xdg_activation_token_v1 *xdg_activation_token_v1, const char *token)
 

Listener (Fractional Scale), #wp_fractional_scale_manager_v1_interface

Used by gwl_window_activate.

static CLG_LogRef LOG_WL_FRACTIONAL_SCALE = {"ghost.wl.handle.fractional_scale"}
 
static const wp_fractional_scale_v1_listener wp_fractional_scale_listener
 
static void wp_fractional_scale_handle_preferred_scale (void *data, wp_fractional_scale_v1 *, uint preferred_scale)
 

Listener (XDG Decoration Listener), #zxdg_toplevel_decoration_v1_listener

static CLG_LogRef LOG_WL_XDG_TOPLEVEL_DECORATION = {"ghost.wl.handle.xdg_toplevel_decoration"}
 
static const zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_v1_listener
 
static void xdg_toplevel_decoration_handle_configure (void *data, zxdg_toplevel_decoration_v1 *, const uint32_t mode)
 

Listener (XDG Surface Handle Configure), #xdg_surface_listener

static CLG_LogRef LOG_WL_XDG_SURFACE = {"ghost.wl.handle.xdg_surface"}
 
static const xdg_surface_listener xdg_surface_listener
 
static void xdg_surface_handle_configure (void *data, xdg_surface *xdg_surface, const uint32_t serial)
 

Macro Definition Documentation

◆ LOG [1/5]

◆ LOG [2/5]

Definition at line 1249 of file GHOST_WindowWayland.cc.

◆ LOG [3/5]

Definition at line 1249 of file GHOST_WindowWayland.cc.

◆ LOG [4/5]

#define LOG   (&LOG_WL_XDG_SURFACE)

Definition at line 1249 of file GHOST_WindowWayland.cc.

◆ LOG [5/5]

#define LOG   (&LOG_WL_SURFACE)

Definition at line 1249 of file GHOST_WindowWayland.cc.

◆ PENDING_NUM

Definition at line 395 of file GHOST_WindowWayland.cc.

Referenced by gwl_window_pending_actions_handle().

Enumeration Type Documentation

◆ eGWL_PendingWindowActions

Enumerator
PENDING_WINDOW_FRAME_CONFIGURE 

The state of the window frame has changed, apply the state from GWL_Window::frame_pending.

PENDING_OUTPUT_SCALE_UPDATE 

The DPI for a monitor has changed or the monitors (outputs) this window is visible on may have changed. Recalculate the windows scale.

PENDING_OUTPUT_SCALE_UPDATE_DEFERRED 

Workaround for a bug/glitch in WLROOTS based compositors (RIVER for e.g.). Deferring the scale update one even-loop cycle resolves a bug where the output enter/exit events cause the surface buffer being an invalid size.

While these kinds of glitches might be ignored in some cases, this caused newly created windows to immediately loose the connection to WAYLAND (crashing from a user perspective).

PENDING_WINDOW_SURFACE_COMMIT 

The surface needs a commit to run. Use this to avoid committing immediately which can cause flickering when other operations have not yet been performed - such as refreshing the window size.

PENDING_WINDOW_CURSOR_SHAPE_REFRESH 

The window has gained focus and the cursor shape needs to be refreshed.

Definition at line 360 of file GHOST_WindowWayland.cc.

Function Documentation

◆ gwl_round_int2_by()

static void gwl_round_int2_by ( int value_p[2],
const int round_value )
static

◆ gwl_round_int_by()

static void gwl_round_int_by ( int * value_p,
const int round_value )
static

Definition at line 197 of file GHOST_WindowWayland.cc.

References GHOST_ASSERT.

Referenced by GHOST_WindowWayland::outputs_changed_update_scale().

◆ gwl_round_int_test()

static bool gwl_round_int_test ( int value,
const int round_value )
static

Return true if the value is already rounded by round_value.

Definition at line 213 of file GHOST_WindowWayland.cc.

Referenced by GHOST_WindowWayland::GHOST_WindowWayland().

◆ gwl_window_activate()

static void gwl_window_activate ( GWL_Window * win)
static

◆ gwl_window_cursor_custom_clear()

static void gwl_window_cursor_custom_clear ( GWL_WindowCursorCustomShape & ccs)
static

◆ gwl_window_cursor_custom_free()

◆ gwl_window_cursor_custom_load()

◆ gwl_window_cursor_custom_store()

◆ gwl_window_cursor_shape_refresh()

◆ gwl_window_fractional_from_viewport()

static int gwl_window_fractional_from_viewport ( const GWL_WindowFrame & frame,
int value )
static

Scale a value from a Wayland windowing value to the viewport. Scales up or not at all.

Definition at line 681 of file GHOST_WindowWayland.cc.

References FRACTIONAL_DENOMINATOR, GWL_WindowFrame::fractional_scale, and GHOST_ASSERT.

Referenced by GHOST_WindowWayland::wl_fixed_from_window().

◆ gwl_window_fractional_from_viewport_round()

static int gwl_window_fractional_from_viewport_round ( const GWL_WindowFrame & frame,
int value )
static

◆ gwl_window_fractional_to_viewport()

static int gwl_window_fractional_to_viewport ( const GWL_WindowFrame & frame,
int value )
static

Scale a value from a viewport value to Wayland windowing. Scale down or not at all.

Definition at line 671 of file GHOST_WindowWayland.cc.

References FRACTIONAL_DENOMINATOR, GWL_WindowFrame::fractional_scale, and GHOST_ASSERT.

Referenced by GHOST_WindowWayland::getDPIHint(), and GHOST_WindowWayland::wl_fixed_to_window().

◆ gwl_window_fractional_to_viewport_round()

static int gwl_window_fractional_to_viewport_round ( const GWL_WindowFrame & frame,
int value )
static

◆ gwl_window_frame_pending_fractional_scale_set()

static void gwl_window_frame_pending_fractional_scale_set ( GWL_Window * win,
bool * r_surface_needs_commit,
bool * r_surface_needs_buffer_scale )
static

◆ gwl_window_frame_pending_fractional_scale_set_notest()

◆ gwl_window_frame_pending_size_set()

◆ gwl_window_frame_update_from_pending()

static void gwl_window_frame_update_from_pending ( GWL_Window * win)
static

◆ gwl_window_frame_update_from_pending_no_lock()

◆ gwl_window_pending_actions_handle()

◆ gwl_window_pending_actions_tag()

◆ gwl_window_resize_for_backend()

static void gwl_window_resize_for_backend ( GWL_Window * win,
const int32_t size[2] )
static

◆ gwl_window_scale_int_from()

int gwl_window_scale_int_from ( const GWL_WindowScaleParams & scale_params,
int value )

Definition at line 255 of file GHOST_WindowWayland.cc.

References gwl_window_scale_wl_fixed_from().

◆ gwl_window_scale_int_to()

int gwl_window_scale_int_to ( const GWL_WindowScaleParams & scale_params,
int value )

Definition at line 251 of file GHOST_WindowWayland.cc.

References gwl_window_scale_wl_fixed_to().

◆ gwl_window_scale_wl_fixed_from()

wl_fixed_t gwl_window_scale_wl_fixed_from ( const GWL_WindowScaleParams & scale_params,
wl_fixed_t value )

◆ gwl_window_scale_wl_fixed_to()

wl_fixed_t gwl_window_scale_wl_fixed_to ( const GWL_WindowScaleParams & scale_params,
wl_fixed_t value )

◆ gwl_window_state_get()

◆ gwl_window_state_set()

◆ gwl_window_state_set_for_xdg()

static bool gwl_window_state_set_for_xdg ( xdg_toplevel * toplevel,
const GHOST_TWindowState state,
const GHOST_TWindowState state_current )
static
Note
Keep in sync with #gwl_window_state_set_for_libdecor.

Definition at line 605 of file GHOST_WindowWayland.cc.

References GHOST_kWindowStateFullScreen, GHOST_kWindowStateMaximized, GHOST_kWindowStateMinimized, GHOST_kWindowStateNormal, and state.

Referenced by GHOST_WindowWayland::GHOST_WindowWayland(), and gwl_window_state_set().

◆ gwl_window_title_set()

static void gwl_window_title_set ( GWL_Window * win,
const char * title )
static

◆ gwl_window_viewport_set()

static bool gwl_window_viewport_set ( GWL_Window * win,
bool * r_surface_needs_commit,
bool * r_surface_needs_buffer_scale )
static

◆ gwl_window_viewport_size_update()

◆ gwl_window_viewport_unset()

static bool gwl_window_viewport_unset ( GWL_Window * win,
bool * r_surface_needs_commit,
bool * r_surface_needs_buffer_scale )
static

◆ gwl_xdg_decor_window_destroy()

static void gwl_xdg_decor_window_destroy ( GWL_XDG_Decor_Window * decor)
static

◆ output_scale_cmp()

static int output_scale_cmp ( const GWL_Output * output_a,
const GWL_Output * output_b )
static

Return -1 if output_a has a scale smaller than output_b, 0 when there equal, otherwise 1.

Definition at line 1135 of file GHOST_WindowWayland.cc.

References FRACTIONAL_DENOMINATOR, GWL_Output::has_scale_fractional, GWL_Output::scale, and GWL_Output::scale_fractional.

Referenced by outputs_max_scale_or_default(), and outputs_uniform_scale_or_default().

◆ outputs_max_scale_or_default()

static int outputs_max_scale_or_default ( const std::vector< GWL_Output * > & outputs,
const int32_t scale_default,
int * r_scale_fractional )
static

◆ outputs_uniform_scale_or_default()

static int outputs_uniform_scale_or_default ( const std::vector< GWL_Output * > & outputs,
const int32_t scale_default,
int * r_scale_fractional )
static

◆ surface_handle_enter()

static void surface_handle_enter ( void * data,
wl_surface * ,
wl_output * wl_output )
static

◆ surface_handle_leave()

static void surface_handle_leave ( void * data,
wl_surface * ,
wl_output * wl_output )
static

◆ wp_fractional_scale_handle_preferred_scale()

static void wp_fractional_scale_handle_preferred_scale ( void * data,
wp_fractional_scale_v1 * ,
uint preferred_scale )
static

◆ xdg_activation_handle_done()

static void xdg_activation_handle_done ( void * data,
xdg_activation_token_v1 * xdg_activation_token_v1,
const char * token )
static

◆ xdg_activation_listener_get()

static const xdg_activation_token_v1_listener * xdg_activation_listener_get ( )
static

LIBDECOR support committing a window-configuration in the main-thread that was handled in a non-main-thread.

This is needed for proper order of operations as the commit needs to occur after the buffer is resized (something that can't be done from a non-main thread). Without this, the window-frame can get out of sync with its contents and resizing is slow.

Eventually LIBDECOR should support copying & freeing a configuration, even when it does, older versions of the library will to be supported and the workaround will need to be kept. See: https://gitlab.freedesktop.org/libdecor/libdecor/-/issues/64 Queue configuration calls until a valid window frame size is available. This is needed because LIBDECOR has an issue where windows initialized with a zero size don't have a usable title bar. see #117583.

Definition at line 1371 of file GHOST_WindowWayland.cc.

References xdg_activation_listener.

Referenced by gwl_window_activate().

◆ xdg_surface_handle_configure()

◆ xdg_toplevel_decoration_handle_configure()

static void xdg_toplevel_decoration_handle_configure ( void * data,
zxdg_toplevel_decoration_v1 * ,
const uint32_t mode )
static

◆ xdg_toplevel_handle_close()

static void xdg_toplevel_handle_close ( void * data,
xdg_toplevel *  )
static

◆ xdg_toplevel_handle_configure()

◆ xdg_toplevel_handle_configure_bounds()

static void xdg_toplevel_handle_configure_bounds ( void * data,
xdg_toplevel * ,
int32_t width,
int32_t height )
static

◆ xdg_toplevel_handle_wm_capabilities()

static void xdg_toplevel_handle_wm_capabilities ( void * ,
xdg_toplevel * ,
wl_array *  )
static

Definition at line 1324 of file GHOST_WindowWayland.cc.

References CLOG_INFO, and LOG.

Variable Documentation

◆ base_dpi

size_t base_dpi = 96
staticconstexpr

Definition at line 99 of file GHOST_WindowWayland.cc.

Referenced by GHOST_WindowWayland::getDPIHint().

◆ LOG_WL_FRACTIONAL_SCALE

CLG_LogRef LOG_WL_FRACTIONAL_SCALE = {"ghost.wl.handle.fractional_scale"}
static

Definition at line 1384 of file GHOST_WindowWayland.cc.

◆ LOG_WL_SURFACE

CLG_LogRef LOG_WL_SURFACE = {"ghost.wl.handle.surface"}
static

Definition at line 1673 of file GHOST_WindowWayland.cc.

◆ LOG_WL_XDG_SURFACE

CLG_LogRef LOG_WL_XDG_SURFACE = {"ghost.wl.handle.xdg_surface"}
static

Definition at line 1625 of file GHOST_WindowWayland.cc.

◆ LOG_WL_XDG_TOPLEVEL

CLG_LogRef LOG_WL_XDG_TOPLEVEL = {"ghost.wl.handle.xdg_toplevel"}
static

Definition at line 1248 of file GHOST_WindowWayland.cc.

◆ LOG_WL_XDG_TOPLEVEL_DECORATION

CLG_LogRef LOG_WL_XDG_TOPLEVEL_DECORATION = {"ghost.wl.handle.xdg_toplevel_decoration"}
static

Definition at line 1600 of file GHOST_WindowWayland.cc.

◆ wl_surface_listener

const wl_surface_listener wl_surface_listener
static
Initial value:
= {
}
static void surface_handle_leave(void *data, wl_surface *, wl_output *wl_output)
static void surface_handle_enter(void *data, wl_surface *, wl_output *wl_output)

Definition at line 1726 of file GHOST_WindowWayland.cc.

Referenced by GHOST_WindowWayland::GHOST_WindowWayland().

◆ wp_fractional_scale_listener

const wp_fractional_scale_v1_listener wp_fractional_scale_listener
static
Initial value:
= {
}
static void wp_fractional_scale_handle_preferred_scale(void *data, wp_fractional_scale_v1 *, uint preferred_scale)

Definition at line 1406 of file GHOST_WindowWayland.cc.

Referenced by GHOST_WindowWayland::GHOST_WindowWayland().

◆ xdg_activation_listener

const xdg_activation_token_v1_listener xdg_activation_listener
static
Initial value:
= {
}
static void xdg_activation_handle_done(void *data, xdg_activation_token_v1 *xdg_activation_token_v1, const char *token)

Definition at line 1367 of file GHOST_WindowWayland.cc.

Referenced by xdg_activation_listener_get().

◆ xdg_surface_listener

const xdg_surface_listener xdg_surface_listener
static
Initial value:
= {
}
static void xdg_surface_handle_configure(void *data, xdg_surface *xdg_surface, const uint32_t serial)

Definition at line 1661 of file GHOST_WindowWayland.cc.

Referenced by GHOST_WindowWayland::GHOST_WindowWayland().

◆ xdg_toplevel_decoration_v1_listener

const zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_v1_listener
static
Initial value:
= {
}
static void xdg_toplevel_decoration_handle_configure(void *data, zxdg_toplevel_decoration_v1 *, const uint32_t mode)

Definition at line 1613 of file GHOST_WindowWayland.cc.

Referenced by GHOST_WindowWayland::GHOST_WindowWayland().

◆ xdg_toplevel_listener

const xdg_toplevel_listener xdg_toplevel_listener
static
Initial value:
= {
}
static void xdg_toplevel_handle_configure(void *data, xdg_toplevel *, const int32_t width, const int32_t height, wl_array *states)
static void xdg_toplevel_handle_configure_bounds(void *data, xdg_toplevel *, int32_t width, int32_t height)
static void xdg_toplevel_handle_wm_capabilities(void *, xdg_toplevel *, wl_array *)
static void xdg_toplevel_handle_close(void *data, xdg_toplevel *)

Definition at line 1334 of file GHOST_WindowWayland.cc.

Referenced by GHOST_WindowWayland::GHOST_WindowWayland().