Wayland GNOME: Fix a small rendering artifact when docking a window at a screen edge or maximizing it

For some reason destroying the shadow surfaces causes mutter to render one of them at its old relative position. So workaround by not destroying the surfaces, modern mutter anyway seems to hide them when the window is docked.

Fixes #7701
This commit is contained in:
Kovid Goyal
2024-08-07 13:34:10 +05:30
parent 75d0dcab8d
commit d7902f6b24
3 changed files with 14 additions and 21 deletions

View File

@@ -132,6 +132,8 @@ Detailed list of changes
- Wayland GNOME: Fix the font size in the OS Window title bar changing with the size of the text in the window (:disc:`7677`) - Wayland GNOME: Fix the font size in the OS Window title bar changing with the size of the text in the window (:disc:`7677`)
- Wayland GNOME: Fix a small rendering artifact when docking a window at a screen edge or maximizing it (:iss:`7701`)
0.35.2 [2024-06-22] 0.35.2 [2024-06-22]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -577,7 +577,6 @@ ensure_csd_resources(_GLFWwindow *window) {
if (!window_is_csd_capable(window)) return false; if (!window_is_csd_capable(window)) return false;
const bool is_focused = window->id == _glfw.focusedWindowId; const bool is_focused = window->id == _glfw.focusedWindowId;
const bool focus_changed = is_focused != decs.for_window_state.focused; const bool focus_changed = is_focused != decs.for_window_state.focused;
const bool needs_shadow = window_needs_shadows(window);
const bool size_changed = ( const bool size_changed = (
decs.for_window_state.width != window->wl.width || decs.for_window_state.width != window->wl.width ||
decs.for_window_state.height != window->wl.height || decs.for_window_state.height != window->wl.height ||
@@ -586,12 +585,11 @@ ensure_csd_resources(_GLFWwindow *window) {
); );
const bool state_changed = decs.for_window_state.toplevel_states != window->wl.current.toplevel_states; const bool state_changed = decs.for_window_state.toplevel_states != window->wl.current.toplevel_states;
const bool needs_update = focus_changed || size_changed || !decs.titlebar.surface || decs.buffer_destroyed || state_changed; const bool needs_update = focus_changed || size_changed || !decs.titlebar.surface || decs.buffer_destroyed || state_changed;
const bool shadow_changed = needs_shadow != decs.for_window_state.needs_shadow; debug("CSD: old.size: %dx%d new.size: %dx%d needs_update: %d size_changed: %d state_changed: %d buffer_destroyed: %d\n",
debug("CSD: old.size: %dx%d new.size: %dx%d needs_update: %d shadow_changed: %d size_changed: %d state_changed: %d buffer_destroyed: %d\n", decs.for_window_state.width, decs.for_window_state.height, window->wl.width, window->wl.height, needs_update,
decs.for_window_state.width, decs.for_window_state.height, window->wl.width, window->wl.height, needs_update, shadow_changed,
size_changed, state_changed, decs.buffer_destroyed); size_changed, state_changed, decs.buffer_destroyed);
if (!needs_update) return false; if (!needs_update) return false;
if (size_changed || decs.buffer_destroyed || shadow_changed) { if (size_changed || decs.buffer_destroyed) {
free_csd_buffers(window); free_csd_buffers(window);
if (!create_shm_buffers(window)) return false; if (!create_shm_buffers(window)) return false;
decs.buffer_destroyed = false; decs.buffer_destroyed = false;
@@ -602,20 +600,14 @@ ensure_csd_resources(_GLFWwindow *window) {
position_csd_surface(&decs.which, x, y); position_csd_surface(&decs.which, x, y);
setup_surface(titlebar, 0, -decs.metrics.visible_titlebar_height); setup_surface(titlebar, 0, -decs.metrics.visible_titlebar_height);
if (needs_shadow) { setup_surface(shadow_top, decs.titlebar.x, decs.titlebar.y - decs.metrics.width);
setup_surface(shadow_top, decs.titlebar.x, decs.titlebar.y - decs.metrics.width); setup_surface(shadow_bottom, decs.titlebar.x, window->wl.height);
setup_surface(shadow_bottom, decs.titlebar.x, window->wl.height); setup_surface(shadow_left, -decs.metrics.width, decs.titlebar.y);
setup_surface(shadow_left, -decs.metrics.width, decs.titlebar.y); setup_surface(shadow_right, window->wl.width, decs.shadow_left.y);
setup_surface(shadow_right, window->wl.width, decs.shadow_left.y); setup_surface(shadow_upper_left, decs.shadow_left.x, decs.shadow_top.y);
setup_surface(shadow_upper_left, decs.shadow_left.x, decs.shadow_top.y); setup_surface(shadow_upper_right, decs.shadow_right.x, decs.shadow_top.y);
setup_surface(shadow_upper_right, decs.shadow_right.x, decs.shadow_top.y); setup_surface(shadow_lower_left, decs.shadow_left.x, decs.shadow_bottom.y);
setup_surface(shadow_lower_left, decs.shadow_left.x, decs.shadow_bottom.y); setup_surface(shadow_lower_right, decs.shadow_right.x, decs.shadow_bottom.y);
setup_surface(shadow_lower_right, decs.shadow_right.x, decs.shadow_bottom.y);
} else {
#define d(which) free_csd_surface(&decs.which);
all_shadow_surfaces(d)
#undef d
}
if (focus_changed || state_changed) update_title_bar(window); if (focus_changed || state_changed) update_title_bar(window);
damage_csd(titlebar, decs.titlebar.buffer.front); damage_csd(titlebar, decs.titlebar.buffer.front);
@@ -629,7 +621,6 @@ ensure_csd_resources(_GLFWwindow *window) {
decs.for_window_state.fscale = _glfwWaylandWindowScale(window); decs.for_window_state.fscale = _glfwWaylandWindowScale(window);
decs.for_window_state.focused = is_focused; decs.for_window_state.focused = is_focused;
decs.for_window_state.toplevel_states = window->wl.current.toplevel_states; decs.for_window_state.toplevel_states = window->wl.current.toplevel_states;
decs.for_window_state.needs_shadow = needs_shadow;
return true; return true;
} }

2
glfw/wl_platform.h vendored
View File

@@ -232,7 +232,7 @@ typedef struct _GLFWwindowWayland
struct { struct {
int width, height; int width, height;
bool focused, needs_shadow; bool focused;
double fscale; double fscale;
WaylandWindowState toplevel_states; WaylandWindowState toplevel_states;
} for_window_state; } for_window_state;