Skip to content

Commit

Permalink
Fix stacking conflict between the main screensaver window and the
Browse files Browse the repository at this point in the history
backup-locker window.

Since Muffin 5.4, the restacking code in cs-gdk-event-filter-x11.c
does not always work properly when either (unredirected) window
is handling an event from the other.

Now, the backup window will be realized but unmapped while the main
window is visible.

ref: linuxmint#424
  • Loading branch information
mtwebster committed Mar 1, 2023
1 parent 5b56154 commit e7e82b0
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 43 deletions.
36 changes: 26 additions & 10 deletions backup-locker/cs-backup-locker.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ activate_backup_window (BackupWindow *window)

g_signal_connect_swapped (window, "grab-broken-event", G_CALLBACK (window_grab_broken), window);

gtk_widget_show (window->info_box);
position_info_box (window);

window->should_grab = TRUE;
Expand Down Expand Up @@ -159,7 +158,6 @@ on_composited_changed (gpointer data)
if (gtk_widget_get_realized (GTK_WIDGET (window)))
{
gtk_widget_hide (GTK_WIDGET (window));
gtk_widget_unrealize (GTK_WIDGET (window));
gtk_widget_realize (GTK_WIDGET (window));

if (window->should_grab)
Expand All @@ -169,8 +167,6 @@ on_composited_changed (gpointer data)
user_time = gdk_x11_display_get_user_time (gtk_widget_get_display (GTK_WIDGET (window)));
gdk_x11_window_set_user_time (gtk_widget_get_window (GTK_WIDGET (window)), user_time);
}

gtk_widget_show (GTK_WIDGET (window));
}

if (window->should_grab)
Expand All @@ -186,21 +182,37 @@ screensaver_window_changed (CsGdkEventFilter *filter,
{
backup_window_ungrab (window);

g_debug ("New screensaver window, hiding ourselves");

gtk_widget_hide (GTK_WIDGET (window));
gtk_widget_realize (GTK_WIDGET (window));

setup_window_monitor (window, xwindow);
}

static void
screensaver_window_unmapped (CsGdkEventFilter *filter,
BackupWindow *window)
{
gtk_window_present (GTK_WINDOW (window));
}

static void
backup_window_realize (GtkWidget *widget)
{
if (GTK_WIDGET_CLASS (backup_window_parent_class)->realize) {
GTK_WIDGET_CLASS (backup_window_parent_class)->realize (widget);
}
g_debug ("Backup window realized");

BackupWindow *window = BACKUP_WINDOW (widget);

cs_screen_set_net_wm_name (gtk_widget_get_window (widget),
"backup-locker");

gdk_window_set_title (gtk_widget_get_window (widget),
"backup-locker");

root_window_size_changed (window->event_filter, (gpointer) widget);

cs_gdk_event_filter_stop (window->event_filter);
Expand Down Expand Up @@ -325,8 +337,6 @@ backup_window_init (BackupWindow *window)
g_signal_connect_swapped (gdk_screen_get_default (), "composited-changed", G_CALLBACK (on_composited_changed), window);

gtk_widget_show_all (box);
gtk_widget_set_no_show_all (box, TRUE);
gtk_widget_hide (box);
window->info_box = box;

g_signal_connect_swapped (window->info_box, "realize", G_CALLBACK (position_info_box), window);
Expand Down Expand Up @@ -381,6 +391,7 @@ backup_window_new (gulong pretty_xid)
window->event_filter = cs_gdk_event_filter_new (GTK_WIDGET (window), pretty_xid);
g_signal_connect (window->event_filter, "xscreen-size", G_CALLBACK (root_window_size_changed), window);
g_signal_connect (window->event_filter, "screensaver-window-changed", G_CALLBACK (screensaver_window_changed), window);
g_signal_connect (window->event_filter, "screensaver-window-unmapped", G_CALLBACK (screensaver_window_unmapped), window);

window->pretty_xid = pretty_xid;

Expand Down Expand Up @@ -446,13 +457,12 @@ screensaver_window_gone (GObject *source,

if (xid == window->pretty_xid)
{
gtk_window_present (GTK_WINDOW (window));
activate_backup_window (window);
}

g_mutex_unlock (&pretty_xid_mutex);
}

g_clear_object (&task_cancellable);
}

static void
Expand All @@ -465,6 +475,12 @@ setup_window_monitor (BackupWindow *window, gulong xid)
g_mutex_lock (&pretty_xid_mutex);
window->pretty_xid = xid;

if (window_monitor_cancellable != NULL)
{
g_cancellable_cancel (window_monitor_cancellable);
g_object_unref (window_monitor_cancellable);
}

window_monitor_cancellable = g_cancellable_new ();
task = g_task_new (NULL, window_monitor_cancellable, screensaver_window_gone, window);

Expand All @@ -485,6 +501,7 @@ sigterm_received (gpointer data)

g_clear_handle_id (&sigterm_src_id, g_source_remove);
g_cancellable_cancel (window_monitor_cancellable);
g_object_unref (window_monitor_cancellable);

gtk_widget_destroy (window);
gtk_main_quit ();
Expand Down Expand Up @@ -553,8 +570,7 @@ main (int argc,
sigterm_src_id = g_unix_signal_add (SIGTERM, (GSourceFunc) sigterm_received, window);
setup_window_monitor (BACKUP_WINDOW (window), xid);

gtk_widget_show (window);

gtk_widget_realize (GTK_WIDGET (window));
gtk_main ();

g_debug ("backup-locker: exit");
Expand Down
60 changes: 27 additions & 33 deletions libcscreensaver/cs-gdk-event-filter-x11.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
enum {
XSCREEN_SIZE,
SCREENSAVER_WINDOW_CHANGED,
SCREENSAVER_WINDOW_UNMAPPED,
LAST_SIGNAL
};

Expand Down Expand Up @@ -133,6 +134,7 @@ restack (CsGdkEventFilter *filter,
g_debug ("New screensaver window found: 0x%lx (replaces 0x%lx)", event_window, filter->pretty_xid);
filter->pretty_xid = event_window;
g_signal_emit (filter, signals[SCREENSAVER_WINDOW_CHANGED], 0, event_window);
return;
}
}

Expand All @@ -149,16 +151,12 @@ restack (CsGdkEventFilter *filter,
}
else
{
g_debug ("BackupWindow received %s from screensaver window (0x%lx), restacking us below it.",
event_type,
event_window);

Window windows[] = {
filter->pretty_xid,
filter->my_xid
};

XRestackWindows (GDK_DISPLAY_XDISPLAY (filter->display), windows, 2);
if (g_strcmp0 (event_type, "UnmapNotify") == 0)
{
g_printerr ("UNMAP\n");
g_signal_emit (filter, signals[SCREENSAVER_WINDOW_UNMAPPED], 0);
return;
}
}
}
else
Expand Down Expand Up @@ -186,6 +184,19 @@ cs_gdk_event_filter_xevent (CsGdkEventFilter *filter,
/* MapNotify is used to tell us when new windows are mapped.
ConfigureNofify is used to tell us when windows are raised. */
switch (ev->xany.type) {
case UnmapNotify:
{
XUnmapEvent *xue = &ev->xunmap;

// Ignore my own events.
if (xue->window == filter->my_xid)
{
break;
}

restack (filter, xue->window, "UnmapNotify");
break;
}
case MapNotify:
{
XMapEvent *xme = &ev->xmap;
Expand Down Expand Up @@ -294,24 +305,6 @@ select_shape_events (CsGdkEventFilter *filter)
#endif
}

static void
disable_unredirection (CsGdkEventFilter *filter)
{
GdkWindow *gdk_window;
guchar _NET_WM_BYPASS_COMPOSITOR_HINT_OFF = 2;

gdk_window = gtk_widget_get_window (filter->managed_window);

gdk_x11_display_error_trap_push (filter->display);

XChangeProperty (GDK_DISPLAY_XDISPLAY (filter->display), GDK_WINDOW_XID (gdk_window),
XInternAtom (GDK_DISPLAY_XDISPLAY (filter->display), "_NET_WM_BYPASS_COMPOSITOR", TRUE),
XA_CARDINAL, 32, PropModeReplace, &_NET_WM_BYPASS_COMPOSITOR_HINT_OFF, 1);
XFlush (GDK_DISPLAY_XDISPLAY (filter->display));

gdk_x11_display_error_trap_pop_ignored (filter->display);
}

static GdkFilterReturn
xevent_filter (GdkXEvent *xevent,
GdkEvent *event,
Expand Down Expand Up @@ -364,6 +357,12 @@ cs_gdk_event_filter_class_init (CsGdkEventFilterClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_ULONG);
signals[SCREENSAVER_WINDOW_UNMAPPED] = g_signal_new ("screensaver-window-unmapped",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
}

static void
Expand All @@ -383,11 +382,6 @@ cs_gdk_event_filter_start (CsGdkEventFilter *filter,
select_popup_events (filter);
select_shape_events (filter);

if (fractional_scaling)
{
disable_unredirection (filter);
}

if (debug)
{
g_log_set_handler ("Cvc", G_LOG_LEVEL_DEBUG,
Expand Down
4 changes: 4 additions & 0 deletions src/stage.py
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,10 @@ def update_geometry(self):
else:
self.rect = status.screen.get_screen_geometry()

scale = status.screen.get_global_scale()
self.rect.width *= scale
self.rect.height *= scale

DEBUG("Stage.update_geometry - new backdrop position: %d, %d new size: %d x %d" % (self.rect.x, self.rect.y, self.rect.width, self.rect.height))

hints = Gdk.Geometry()
Expand Down

0 comments on commit e7e82b0

Please sign in to comment.