diff options
| author | Victor Kareh <[email protected]> | 2025-10-02 16:34:25 -0400 |
|---|---|---|
| committer | Luke from DC <[email protected]> | 2025-10-06 21:07:51 +0000 |
| commit | f5c64ffdd4c6f84de21ea9208d5baa14e1649b23 (patch) | |
| tree | 85c0310ec4d61a6afc514cb9ed1b7395bf8f1689 | |
| parent | 0be9e0492c9cfae8ef8552a71f4ba7f3d801f537 (diff) | |
| download | mate-panel-f5c64ffdd4c6f84de21ea9208d5baa14e1649b23.tar.bz2 mate-panel-f5c64ffdd4c6f84de21ea9208d5baa14e1649b23.tar.xz | |
panel-toplevel: Add dynamic HiDPI scale change support
Panels now respond to HiDPI scale factor changes without requiring
a restart. When the monitors-changed signal is received, the panel
updates its scale factor and forces applets to redraw at the new scale.
The temporary size change (to 0 and back) is necessary because applets
don't individually listen to scale change signals.
This eliminates the need for mate-settings-daemon to kill and restart
mate-panel when the scale factor changes.
| -rw-r--r-- | mate-panel/panel-toplevel.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/mate-panel/panel-toplevel.c b/mate-panel/panel-toplevel.c index bbe4980d..3892cfaf 100644 --- a/mate-panel/panel-toplevel.c +++ b/mate-panel/panel-toplevel.c @@ -260,6 +260,7 @@ static void panel_toplevel_update_monitor(PanelToplevel* toplevel); static void panel_toplevel_set_monitor_internal(PanelToplevel* toplevel, int monitor, gboolean force_resize); static void panel_toplevel_drag_threshold_changed (PanelToplevel *toplevel); +static void panel_toplevel_on_monitors_changed (GdkScreen *screen, gpointer user_data); static void update_style_classes (PanelToplevel *toplevel) @@ -3021,6 +3022,11 @@ panel_toplevel_realize (GtkWidget *widget) if (visual == NULL) visual = gdk_screen_get_system_visual (screen); + /* Connect to monitors-changed signal to handle dynamic HiDPI scale changes */ + g_signal_connect (screen, "monitors-changed", + G_CALLBACK (panel_toplevel_on_monitors_changed), + toplevel); + gtk_widget_set_visual (widget, visual); gtk_window_stick (GTK_WINDOW (widget)); gtk_window_set_decorated (GTK_WINDOW (widget), FALSE); @@ -3066,7 +3072,15 @@ static void panel_toplevel_unrealize (GtkWidget *widget) { PanelToplevel *toplevel; + GdkScreen *screen; + toplevel = PANEL_TOPLEVEL (widget); + + screen = gtk_widget_get_screen (widget); + g_signal_handlers_disconnect_by_func (screen, + G_CALLBACK (panel_toplevel_on_monitors_changed), + toplevel); + panel_toplevel_disconnect_timeouts (toplevel); panel_background_unrealized (&toplevel->background); GTK_WIDGET_CLASS (panel_toplevel_parent_class)->unrealize (widget); @@ -4054,6 +4068,63 @@ panel_toplevel_screen_changed (GtkWidget *widget, gtk_widget_queue_resize (widget); } +static gboolean +panel_toplevel_restore_size (gpointer user_data) +{ + PanelToplevel *toplevel = PANEL_TOPLEVEL (user_data); + int original_size; + + /* Restore original size from GSettings */ + if (toplevel->settings) { + original_size = g_settings_get_int (toplevel->settings, "size"); + panel_toplevel_set_size (toplevel, original_size); + } + + return G_SOURCE_REMOVE; +} + +static gboolean +panel_toplevel_update_applets_scale (gpointer user_data) +{ + PanelToplevel *toplevel = PANEL_TOPLEVEL (user_data); + + /* HACK: Trigger all applets to redraw at the new scale by forcing + * a size change to 0 and then back to the configured size on the next + * cycle. This simulates what happens when you manually adjust the + * panel size via gsettings. Otherwise, every single applet would need + * to listen to their own scale change signal. */ + panel_toplevel_set_size (toplevel, 0); + + /* Use timeout to restore size after the resize completes. + * 100ms gives GTK enough time to complete the resize at the new scale. */ + g_timeout_add (100, panel_toplevel_restore_size, toplevel); + + return G_SOURCE_REMOVE; +} + +static void +panel_toplevel_on_monitors_changed (GdkScreen *screen, + gpointer user_data) +{ + PanelToplevel *toplevel = PANEL_TOPLEVEL (user_data); + gint new_scale; + + g_return_if_fail (PANEL_IS_TOPLEVEL (toplevel)); + + /* Update scale factor */ + new_scale = gtk_widget_get_scale_factor (GTK_WIDGET (toplevel)); + if (new_scale != toplevel->priv->scale) { + toplevel->priv->scale = new_scale; + + /* Queue resize to update panel size and layout at new scale first */ + gtk_widget_queue_resize (GTK_WIDGET (toplevel)); + + /* Use timeout to update applets after panel resizes. + * 100ms gives GTK enough time to complete the resize at the new scale. */ + g_timeout_add (100, panel_toplevel_update_applets_scale, toplevel); + } +} + static void panel_toplevel_set_property (GObject *object, guint prop_id, |
