[Bf-blender-cvs] [f1646a4d5e8] blender-v3.4-release: GHOST/Wayland: share logic for xdg/libdecor window configuration
Campbell Barton
noreply at git.blender.org
Tue Nov 15 04:50:59 CET 2022
Commit: f1646a4d5e83d6fd0e1ae65ccef762520e81f445
Author: Campbell Barton
Date: Tue Nov 15 14:49:04 2022 +1100
Branches: blender-v3.4-release
https://developer.blender.org/rBf1646a4d5e83d6fd0e1ae65ccef762520e81f445
GHOST/Wayland: share logic for xdg/libdecor window configuration
Split frame & frame_pending structs, making window actions simpler
to reason about.
===================================================================
M intern/ghost/intern/GHOST_WindowWayland.cpp
===================================================================
diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp
index 3445898a6a8..72494c8070f 100644
--- a/intern/ghost/intern/GHOST_WindowWayland.cpp
+++ b/intern/ghost/intern/GHOST_WindowWayland.cpp
@@ -81,6 +81,13 @@ static void gwl_xdg_decor_window_destroy(WGL_XDG_Decor_Window *decor)
/** \name Internal #GWL_Window
* \{ */
+struct GWL_WindowFrame {
+ int32_t size[2] = {0, 0};
+ bool is_maximised = false;
+ bool is_fullscreen = false;
+ bool is_active = false;
+};
+
struct GWL_Window {
GHOST_WindowWayland *ghost_window = nullptr;
GHOST_SystemWayland *ghost_system = nullptr;
@@ -106,16 +113,15 @@ struct GWL_Window {
#endif
WGL_XDG_Decor_Window *xdg_decor = nullptr;
+ /** The current value of frame, copied from `frame_pending` when applying updates. */
+ GWL_WindowFrame frame;
+ GWL_WindowFrame frame_pending;
+
wl_egl_window *egl_window = nullptr;
std::string title;
- bool is_maximised = false;
- bool is_fullscreen = false;
- bool is_active = false;
- bool is_dialog = false;
- int32_t size[2] = {0, 0};
- int32_t size_pending[2] = {0, 0};
+ bool is_dialog = false;
};
static void gwl_window_title_set(GWL_Window *win, const char *title)
@@ -137,10 +143,10 @@ static void gwl_window_title_set(GWL_Window *win, const char *title)
static GHOST_TWindowState gwl_window_state_get(const GWL_Window *win)
{
- if (win->is_fullscreen) {
+ if (win->frame.is_fullscreen) {
return GHOST_kWindowStateFullScreen;
}
- if (win->is_maximised) {
+ if (win->frame.is_maximised) {
return GHOST_kWindowStateMaximized;
}
return GHOST_kWindowStateNormal;
@@ -227,6 +233,59 @@ static bool gwl_window_state_set(GWL_Window *win, const GHOST_TWindowState state
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Internal #GWL_Window Pending Actions
+ * \{ */
+
+static void gwl_window_frame_pending_size_set(GWL_Window *win)
+{
+ if (win->frame_pending.size[0] == 0 || win->frame_pending.size[1] == 0) {
+ return;
+ }
+
+ win->frame.size[0] = win->frame_pending.size[0];
+ win->frame.size[1] = win->frame_pending.size[1];
+
+ wl_egl_window_resize(win->egl_window, UNPACK2(win->frame.size), 0, 0);
+ win->ghost_window->notify_size();
+
+ win->frame_pending.size[0] = 0;
+ win->frame_pending.size[1] = 0;
+}
+
+static void gwl_window_frame_update_from_pending(GWL_Window *win);
+
+/**
+ * Update the window's #GWL_WindowFrame
+ */
+static void gwl_window_frame_update_from_pending(GWL_Window *win)
+{
+ if (win->frame_pending.size[0] != 0 && win->frame_pending.size[1] != 0) {
+ if ((win->frame.size[0] != win->frame_pending.size[0]) ||
+ (win->frame.size[1] != win->frame_pending.size[1])) {
+ gwl_window_frame_pending_size_set(win);
+ }
+ }
+
+ if (win->frame_pending.is_active) {
+ win->ghost_window->activate();
+ }
+ else {
+ win->ghost_window->deactivate();
+ }
+
+ win->frame_pending.size[0] = win->frame.size[0];
+ win->frame_pending.size[1] = win->frame.size[1];
+
+ win->frame = win->frame_pending;
+
+ /* Signal not to apply the scale unless it's configured. */
+ win->frame_pending.size[0] = 0;
+ win->frame_pending.size[1] = 0;
+}
+
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Internal Utilities
* \{ */
@@ -304,24 +363,24 @@ static void xdg_toplevel_handle_configure(void *data,
CLOG_INFO(LOG, 2, "configure (size=[%d, %d])", width, height);
GWL_Window *win = static_cast<GWL_Window *>(data);
- win->size_pending[0] = win->scale * width;
- win->size_pending[1] = win->scale * height;
+ win->frame_pending.size[0] = win->scale * width;
+ win->frame_pending.size[1] = win->scale * height;
- win->is_maximised = false;
- win->is_fullscreen = false;
- win->is_active = false;
+ win->frame_pending.is_maximised = false;
+ win->frame_pending.is_fullscreen = false;
+ win->frame_pending.is_active = false;
enum xdg_toplevel_state *state;
WL_ARRAY_FOR_EACH (state, states) {
switch (*state) {
case XDG_TOPLEVEL_STATE_MAXIMIZED:
- win->is_maximised = true;
+ win->frame_pending.is_maximised = true;
break;
case XDG_TOPLEVEL_STATE_FULLSCREEN:
- win->is_fullscreen = true;
+ win->frame_pending.is_fullscreen = true;
break;
case XDG_TOPLEVEL_STATE_ACTIVATED:
- win->is_active = true;
+ win->frame_pending.is_active = true;
break;
default:
break;
@@ -362,65 +421,49 @@ static void frame_handle_configure(struct libdecor_frame *frame,
{
CLOG_INFO(LOG, 2, "configure");
- GWL_Window *win = static_cast<GWL_Window *>(data);
+ GWL_WindowFrame *frame_pending = &static_cast<GWL_Window *>(data)->frame_pending;
+ /* Set the size. */
int size_next[2];
- enum libdecor_window_state window_state;
- struct libdecor_state *state;
- bool do_redraw = false;
-
- if (!libdecor_configuration_get_content_size(
- configuration, frame, &size_next[0], &size_next[1])) {
- size_next[0] = win->size[0] / win->scale;
- size_next[1] = win->size[1] / win->scale;
- }
-
- const int size_prev[2] = {UNPACK2(win->size)};
- win->size[0] = win->scale * size_next[0];
- win->size[1] = win->scale * size_next[1];
-
- const bool do_resize = (size_prev[0] != win->size[0]) || (size_prev[1] != win->size[1]);
-
- if (do_resize) {
- wl_egl_window_resize(win->egl_window, UNPACK2(win->size), 0, 0);
- win->ghost_window->notify_size();
- }
+ {
+ const int scale = static_cast<GWL_Window *>(data)->scale;
+ if (!libdecor_configuration_get_content_size(
+ configuration, frame, &size_next[0], &size_next[1])) {
+ GWL_Window *win = static_cast<GWL_Window *>(data);
+ size_next[0] = win->frame.size[0] / scale;
+ size_next[1] = win->frame.size[1] / scale;
+ }
- if (!libdecor_configuration_get_window_state(configuration, &window_state)) {
- window_state = LIBDECOR_WINDOW_STATE_NONE;
+ frame_pending->size[0] = scale * size_next[0];
+ frame_pending->size[1] = scale * size_next[1];
}
- win->is_maximised = window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED;
- win->is_fullscreen = window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN;
-
- GHOST_SystemWayland *system = win->ghost_system;
- const bool is_active_prev_ghost = (win->ghost_window ==
- system->getWindowManager()->getActiveWindow());
- win->is_active = window_state & LIBDECOR_WINDOW_STATE_ACTIVE;
- if (is_active_prev_ghost != win->is_active) {
- if (win->is_active) {
- win->ghost_window->activate();
- }
- else {
- win->ghost_window->deactivate();
+ /* Set the state. */
+ {
+ enum libdecor_window_state window_state;
+ if (!libdecor_configuration_get_window_state(configuration, &window_state)) {
+ window_state = LIBDECOR_WINDOW_STATE_NONE;
}
- }
- const bool is_active_prev_decor = win->is_active;
- if (is_active_prev_decor) {
- /* Without this, activating another window doesn't refresh the title-bar as inactive. */
- do_redraw = true;
+ frame_pending->is_maximised = window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED;
+ frame_pending->is_fullscreen = window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN;
+ frame_pending->is_active = window_state & LIBDECOR_WINDOW_STATE_ACTIVE;
}
- state = libdecor_state_new(UNPACK2(size_next));
- libdecor_frame_commit(frame, state, configuration);
- libdecor_state_free(state);
+ /* Commit the changes. */
+ {
+ GWL_Window *win = static_cast<GWL_Window *>(data);
+ struct libdecor_state *state = libdecor_state_new(UNPACK2(size_next));
+ libdecor_frame_commit(frame, state, configuration);
+ libdecor_state_free(state);
- if (do_redraw) {
- win->ghost_window->swapBuffers();
+ win->libdecor->configured = true;
}
- win->libdecor->configured = true;
+ {
+ GWL_Window *win = static_cast<GWL_Window *>(data);
+ gwl_window_frame_update_from_pending(win);
+ }
}
static void frame_handle_close(struct libdecor_frame * /*frame*/, void *data)
@@ -497,29 +540,9 @@ static void xdg_surface_handle_configure(void *data,
CLOG_INFO(LOG, 2, "configure (skipped)");
return;
}
- const bool do_resize = win->size_pending[0] != 0 && win->size_pending[1] != 0;
- CLOG_INFO(LOG, 2, "configure (do_resize=%d)", do_resize);
-
- if (do_resize) {
- win->size[0] = win->size_pending[0];
- win->size[1] = win->size_pending[1];
- wl_egl_window_resize(win->egl_window, UNPACK2(win->size), 0, 0);
- win->size_pending[0] = 0;
- win->size_pending[1] = 0;
- win->ghost_window->notify_size();
- }
+ CLOG_INFO(LOG, 2, "configure");
- GHOST_SystemWayland *system = win->ghost_system;
- const bool is_active_prev_ghost = (win->ghost_window ==
- system->getWindowManager()->getActiveWindow());
- if (is_active_prev_ghost != win->is_active) {
- if (win->is_active) {
- win->ghost_window->activate();
- }
- else {
- win->ghost_window->deactivate();
- }
- }
+ gwl_window_frame_update_from_pending(win);
xdg_surface_ack_configure(xdg_surface, serial);
}
@@ -617,8 +640,8 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
window_->ghost_window = this;
window_->ghost_system = system;
- window_->size[0] = int32_t(width);
- window_->size[1] = int32_t(height);
+ window_->frame.size[0] = int32_t(width);
+ window_->frame.size[1] = int32_t(height);
window_->is_dialog = is_dialog;
@@ -642,7 +665,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
wl_surface_add_listener(window_->wl_surface, &wl_surface_listener, window_);
window_->egl_window = wl_egl_window_create(
- window_->wl_surface, int(window_->size[0]), int(window_->size[1]));
+ window_->wl_surface, int(window_->frame.size[0]), int(window_->frame.size[1]));
/* NOTE: The limit is in points (not pixels) so Hi-DPI will limit to larger number of pixels.
* This has the advantage that the size limit is the same when moving the window between monitors
@@ -812,31 +835,25 @@ void GHOST_WindowWayland::getWindowBounds(GHOST_Rect &b
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list