From daa7f5881476e1b09ee81ec21a4dd40180f69441 Mon Sep 17 00:00:00 2001 From: Victor Kareh Date: Mon, 5 Feb 2018 15:22:57 -0500 Subject: Load xsettings during initialization phase Also set QT_* env variables during init, and restart marco, mate-panel, toggle desktop icons when changing scales --- plugins/xsettings/Makefile.am | 2 + plugins/xsettings/msd-xsettings-manager.c | 127 ++++++++++++++++++++++++++++-- plugins/xsettings/wm-common.c | 108 +++++++++++++++++++++++++ plugins/xsettings/wm-common.h | 15 ++++ 4 files changed, 247 insertions(+), 5 deletions(-) create mode 100644 plugins/xsettings/wm-common.c create mode 100644 plugins/xsettings/wm-common.h (limited to 'plugins') diff --git a/plugins/xsettings/Makefile.am b/plugins/xsettings/Makefile.am index c4d0520..c4b821f 100644 --- a/plugins/xsettings/Makefile.am +++ b/plugins/xsettings/Makefile.am @@ -15,6 +15,8 @@ libxsettings_la_SOURCES = \ xsettings-manager.c \ fontconfig-monitor.h \ fontconfig-monitor.c \ + wm-common.h \ + wm-common.c \ $(NULL) libxsettings_la_CPPFLAGS = \ diff --git a/plugins/xsettings/msd-xsettings-manager.c b/plugins/xsettings/msd-xsettings-manager.c index d12b23e..6d9061b 100644 --- a/plugins/xsettings/msd-xsettings-manager.c +++ b/plugins/xsettings/msd-xsettings-manager.c @@ -43,6 +43,7 @@ #include "msd-xsettings-manager.h" #include "xsettings-manager.h" #include "fontconfig-monitor.h" +#include "wm-common.h" #define MATE_XSETTINGS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MATE_TYPE_XSETTINGS_MANAGER, MateXSettingsManagerPrivate)) @@ -400,8 +401,6 @@ xft_settings_get (MateXSettingsManager *manager, settings->cursor_size = scale * g_settings_get_int (mouse_gsettings, CURSOR_SIZE_KEY); settings->rgba = "rgb"; - manager->priv->window_scale = scale; - if (rgba_order) { int i; gboolean found = FALSE; @@ -463,6 +462,121 @@ xft_settings_get (MateXSettingsManager *manager, g_free (antialiasing); } +/* Set environment variable. + * This should only work during the initialization phase. */ +static gboolean +update_user_env_variable (const gchar *variable, + const gchar *value, + GError **error) +{ + GDBusConnection *connection; + gboolean environment_updated; + GVariant *reply; + GError *bus_error = NULL; + + g_setenv (variable, value, TRUE); + + environment_updated = FALSE; + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error); + + if (connection == NULL) { + return FALSE; + } + + reply = g_dbus_connection_call_sync (connection, + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + "Setenv", + g_variant_new ("(ss)", variable, value), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &bus_error); + + if (bus_error != NULL) { + g_propagate_error (error, bus_error); + } else { + environment_updated = TRUE; + g_variant_unref (reply); + } + + g_clear_object (&connection); + + return environment_updated; +} + +static gboolean +delayed_toggle_bg_draw (gboolean value) +{ + GSettings *settings; + settings = g_settings_new ("org.mate.background"); + g_settings_set_boolean (settings, "show-desktop-icons", value); + return FALSE; +} + +static void +scale_change_workarounds (MateXSettingsManager *manager, int new_scale) +{ + if (manager->priv->window_scale == new_scale) + return; + + GError *error = NULL; + + /* This is only useful during the Initialization phase, so we guard against + * unnecessarily attempting to set it later. */ + if (!manager->priv->window_scale) { + /* Set env variables to properly scale QT applications */ + if (!update_user_env_variable ("QT_AUTO_SCREEN_SCALE_FACTOR", "0", &error)) { + g_warning ("There was a problem when setting QT_AUTO_SCREEN_SCALE_FACTOR=0: %s", error->message); + g_clear_error (&error); + } + if (!update_user_env_variable ("QT_SCALE_FACTOR", new_scale == 2 ? "2" : "1", &error)) { + g_warning ("There was a problem when setting QT_SCALE_FACTOR=%d: %s", new_scale, error->message); + g_clear_error (&error); + } + } else { + /* Restart marco */ + /* FIXME: The ideal scenario would be for marco to respect window scaling and thus + * resize itself. Currently this is not happening, so msd restarts it when the window + * scaling factor changes so that it's visually correct. */ + wm_common_update_window(); + gchar *wm = wm_common_get_current_window_manager (); + if (g_strcmp0 (wm, WM_COMMON_MARCO) == 0) { + const gchar * const marco[] = {"marco", "--replace", NULL}; + if (!g_spawn_async (NULL, marco, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error)) { + g_warning ("There was a problem restarting marco: %s", error->message); + g_clear_error (&error); + } + } + g_free (wm); + + /* Restart mate-panel */ + /* FIXME: The ideal scenario would be for mate-panel to respect window scaling and thus + * resize itself. Currently this is not happening, so msd restarts it when the window + * scaling factor changes so that it's visually correct. */ + const gchar * const mate_panel[] = {"killall", "mate-panel", NULL}; + if (!g_spawn_async (NULL, mate_panel, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error)) { + g_warning ("There was a problem restarting mate-panel: %s", error->message); + g_clear_error (&error); + } + + /* Toggle icons on desktop to fix size */ + /* FIXME: The ideal scenario would be for caja to respect window scaling and thus + * resize itself. Currently this is not happening, so msd restarts it when the window + * scaling factor changes so that it's visually correct. */ + GSettings *desktop_settings; + desktop_settings = g_settings_new ("org.mate.background"); + if (g_settings_get_boolean (desktop_settings, "show-desktop-icons")) { + /* Delay the toggle to allow enough time for the desktop to redraw */ + g_timeout_add_seconds (1, (GSourceFunc) delayed_toggle_bg_draw, (gpointer) FALSE); + g_timeout_add_seconds (2, (GSourceFunc) delayed_toggle_bg_draw, (gpointer) TRUE); + } + } + + /* Store new scale value */ + manager->priv->window_scale = new_scale; +} + static void xft_settings_set_xsettings (MateXSettingsManager *manager, MateXftSettings *settings) @@ -485,6 +599,8 @@ xft_settings_set_xsettings (MateXSettingsManager *manager, xsettings_manager_set_string (manager->priv->managers [i], "Gtk/CursorThemeName", settings->cursor_theme); } mate_settings_profile_end (NULL); + + scale_change_workarounds (manager, settings->window_scale); } static void @@ -581,8 +697,8 @@ update_xft_settings (MateXSettingsManager *manager) } static void -screen_callback (GdkScreen *screen, - MateXSettingsManager *manager) +recalculate_scale_callback (GdkScreen *screen, + MateXSettingsManager *manager) { int i; int new_scale = get_window_scale (manager); @@ -833,7 +949,8 @@ mate_xsettings_manager_start (MateXSettingsManager *manager, /* Detect changes in screen resolution */ screen = gdk_screen_get_default(); - g_signal_connect(screen, "size-changed", G_CALLBACK (screen_callback), manager); + g_signal_connect(screen, "size-changed", G_CALLBACK (recalculate_scale_callback), manager); + g_signal_connect(screen, "monitors-changed", G_CALLBACK (recalculate_scale_callback), manager); manager->priv->gsettings_font = g_settings_new (FONT_RENDER_SCHEMA); g_signal_connect (manager->priv->gsettings_font, "changed", G_CALLBACK (xft_callback), manager); diff --git a/plugins/xsettings/wm-common.c b/plugins/xsettings/wm-common.c new file mode 100644 index 0000000..ccb9629 --- /dev/null +++ b/plugins/xsettings/wm-common.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include +#include +#include "wm-common.h" + +/* Our WM Window */ +static Window wm_window = None; + +static char * +wm_common_get_window_manager_property (Atom atom) +{ + Atom utf8_string, type; + int result; + char *retval; + int format; + gulong nitems; + gulong bytes_after; + gchar *val; + + if (wm_window == None) + return NULL; + + utf8_string = gdk_x11_get_xatom_by_name ("UTF8_STRING"); + + gdk_error_trap_push (); + + val = NULL; + result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), + wm_window, + atom, + 0, G_MAXLONG, + False, utf8_string, + &type, &format, &nitems, + &bytes_after, (guchar **) &val); + + if (gdk_error_trap_pop () || result != Success || + type != utf8_string || format != 8 || nitems == 0 || + !g_utf8_validate (val, nitems, NULL)) + { + retval = NULL; + } + else + { + retval = g_strndup (val, nitems); + } + + if (val) + XFree (val); + + return retval; +} + +char* +wm_common_get_current_window_manager (void) +{ + Atom atom = gdk_x11_get_xatom_by_name ("_NET_WM_NAME"); + char *result; + + result = wm_common_get_window_manager_property (atom); + if (result) + return result; + else + return g_strdup (WM_COMMON_UNKNOWN); +} + +static void +update_wm_window (void) +{ + Window *xwindow; + Atom type; + gint format; + gulong nitems; + gulong bytes_after; + + XGetWindowProperty (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), GDK_ROOT_WINDOW (), + gdk_x11_get_xatom_by_name ("_NET_SUPPORTING_WM_CHECK"), + 0, G_MAXLONG, False, XA_WINDOW, &type, &format, + &nitems, &bytes_after, (guchar **) &xwindow); + + if (type != XA_WINDOW) + { + wm_window = None; + return; + } + + gdk_error_trap_push (); + XSelectInput (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), *xwindow, StructureNotifyMask | PropertyChangeMask); + XSync (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False); + + if (gdk_error_trap_pop ()) + { + XFree (xwindow); + wm_window = None; + return; + } + + wm_window = *xwindow; + XFree (xwindow); +} + +void +wm_common_update_window () +{ + update_wm_window(); +} diff --git a/plugins/xsettings/wm-common.h b/plugins/xsettings/wm-common.h new file mode 100644 index 0000000..379adbf --- /dev/null +++ b/plugins/xsettings/wm-common.h @@ -0,0 +1,15 @@ +#ifndef WM_COMMON_H +#define WM_COMMON_H + +#define WM_COMMON_MARCO "Metacity (Marco)" +#define WM_COMMON_SAWFISH "Sawfish" +#define WM_COMMON_METACITY "Metacity" +#define WM_COMMON_COMPIZ "Compiz" +#define WM_COMMON_COMPIZ_OLD "compiz" +#define WM_COMMON_UNKNOWN "Unknown" + +gchar *wm_common_get_current_window_manager (void); +void wm_common_update_window (void); + +#endif /* WM_COMMON_H */ + -- cgit v1.2.1