Skip to content

Commit

Permalink
appearance in wayland: Support changing theme, icon theme, and fonts
Browse files Browse the repository at this point in the history
*If we are in a wayland session, write the gtk theme and icon theme to both org.mate and org.gnome
*This changes wayland and xwayland themes simultaniously

*Under wayland, set the application and document fonts for both MATE and GNOME
*Otherwise some applications will ignore font changes set from the appearance capplet

*Only load GNOME interface  gsettings when running under wayland

*fail gracefully if the gnome interface schema is not present
    *Do not depend on it but use it if it is present to allow setting themes in compositors such as wayfire that use the GNOME gsettings values
  • Loading branch information
lukefromdc committed May 26, 2024
1 parent cf67b6a commit 1e8c08e
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 6 deletions.
62 changes: 57 additions & 5 deletions capplets/appearance/appearance-font.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,20 +421,40 @@ dpi_from_pixels_and_mm (int pixels, int mm)
}

static double
get_dpi_from_x_server (void)
get_dpi_from_x_server_or_monitor (void)
{
GdkScreen *screen;
GdkDisplay *display;
double dpi;

screen = gdk_screen_get_default ();
display = gdk_display_get_default();

if (screen) {
double width_dpi, height_dpi;

Screen *xscreen = gdk_x11_screen_get_xscreen (screen);
if (GDK_IS_X11_DISPLAY (display))
{
Screen *xscreen = gdk_x11_screen_get_xscreen (screen);

width_dpi = dpi_from_pixels_and_mm (WidthOfScreen (xscreen), WidthMMOfScreen (xscreen));
height_dpi = dpi_from_pixels_and_mm (HeightOfScreen (xscreen), HeightMMOfScreen (xscreen));
width_dpi = dpi_from_pixels_and_mm (WidthOfScreen (xscreen), WidthMMOfScreen (xscreen));
height_dpi = dpi_from_pixels_and_mm (HeightOfScreen (xscreen), HeightMMOfScreen (xscreen));
}
else
{
GdkMonitor *monitor;
GdkRectangle geometry = {0};

/*FIXME: we have to use the main monitor for this
*which may not always be the leftmost monitor
*Separate per-monitor settings for this would be ideal
*/
monitor = gdk_display_get_monitor (display, 0);
gdk_monitor_get_geometry (monitor, &geometry);

width_dpi = dpi_from_pixels_and_mm (geometry.width, gdk_monitor_get_width_mm(monitor));
height_dpi = dpi_from_pixels_and_mm (geometry.height, gdk_monitor_get_height_mm(monitor));
}

if (width_dpi < DPI_LOW_REASONABLE_VALUE || width_dpi > DPI_HIGH_REASONABLE_VALUE ||
height_dpi < DPI_LOW_REASONABLE_VALUE || height_dpi > DPI_HIGH_REASONABLE_VALUE)
Expand Down Expand Up @@ -465,7 +485,7 @@ dpi_load (GSettings *settings,
dpi = g_settings_get_double (settings, FONT_DPI_KEY);

if (dpi == 0)
dpi = get_dpi_from_x_server ();
dpi = get_dpi_from_x_server_or_monitor ();

dpi *= (double)scale;
dpi = CLAMP(dpi, DPI_LOW_REASONABLE_VALUE, DPI_HIGH_REASONABLE_VALUE);
Expand Down Expand Up @@ -781,6 +801,38 @@ void font_init(AppearanceData* data)
G_CALLBACK (marco_changed),
data);

/*In a wayland session we must manage MATE font settings for xwayland
*and also manage GNOME font settings for native wayland applications
*so if not running under x11, set the GNOME interface keys too
*Ignore this if for any reason the GNOME schema was not found,
*As we can only set this for compositors using either the MATE or the GNOME gsettings
*/
if (data->interface_gnome_settings)
{
widget = appearance_capplet_get_widget(data, "application_font");
g_settings_bind (data->interface_gnome_settings,
GTK_FONT_KEY,
G_OBJECT (widget),
"font-name",
G_SETTINGS_BIND_DEFAULT);

widget = appearance_capplet_get_widget (data, "document_font");
g_settings_bind (data->interface_gnome_settings,
DOCUMENT_FONT_KEY,
G_OBJECT (widget),
"font-name",
G_SETTINGS_BIND_DEFAULT);

/* The monospace font seems to apply properly if and only if set only for MATE
widget = appearance_capplet_get_widget (data, "monospace_font");
g_settings_bind (data->interface_gnome_settings,
MONOSPACE_FONT_KEY,
G_OBJECT (widget),
"font-name",
G_SETTINGS_BIND_DEFAULT);
*/
}

g_signal_connect (appearance_capplet_get_widget (data, "add_new_font"), "clicked", G_CALLBACK (cb_add_new_font), data);

marco_titlebar_load_sensitivity(data);
Expand Down
16 changes: 16 additions & 0 deletions capplets/appearance/appearance-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "theme-thumbnail.h"
#include "activate-settings-daemon.h"
#include "capplet-util.h"
#include <gdk/gdkx.h>

static AppearanceData *
init_appearance_data (int *argc, char ***argv, GOptionContext *context)
Expand All @@ -56,6 +57,21 @@ init_appearance_data (int *argc, char ***argv, GOptionContext *context)

data->filechooser_settings = g_settings_new (FILECHOOSER_SCHEMA);
data->interface_settings = g_settings_new (INTERFACE_SCHEMA);

data->interface_gnome_settings = NULL;
/*Load the gnome interface schema if we are running under wayland and it is present*/
if (!(GDK_IS_X11_DISPLAY (gdk_display_get_default())))
{
GSettingsSchemaSource *source = g_settings_schema_source_get_default ();

if (source)
{
GSettingsSchema *schema = g_settings_schema_source_lookup (source, INTERFACE_GNOME_SCHEMA, TRUE);

if (schema)
data->interface_gnome_settings = g_settings_new_full (schema, NULL, NULL);
}
}
data->marco_settings = g_settings_new (MARCO_SCHEMA);
data->mouse_settings = g_settings_new (MOUSE_SCHEMA);
data->font_settings = g_settings_new (FONT_RENDER_SCHEMA);
Expand Down
5 changes: 5 additions & 0 deletions capplets/appearance/appearance.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#define GTK_THEME_KEY "gtk-theme"
#define ICON_THEME_KEY "icon-theme"
#define INTERFACE_SCHEMA "org.mate.interface"
#define INTERFACE_GNOME_SCHEMA "org.gnome.desktop.interface"
#define MENU_ICONS_KEY "menus-have-icons"
#define MONOSPACE_FONT_KEY "monospace-font-name"
#define TOOLBAR_STYLE_KEY "toolbar-style"
Expand Down Expand Up @@ -92,6 +93,10 @@ typedef struct {
GSettings* caja_settings;
GSettings* filechooser_settings;
GSettings* interface_settings;
/*We have to accomodate wayland theme setting here
*whether we are using it or not
*/
GSettings* interface_gnome_settings;
GSettings* marco_settings;
GSettings* mouse_settings;
GSettings* font_settings;
Expand Down
33 changes: 33 additions & 0 deletions capplets/common/mate-theme-apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
#include <libmate-desktop/mate-gsettings.h>
#include "mate-theme-apply.h"
#include "gtkrc-utils.h"
#include <gdk/gdkx.h>

#define INTERFACE_SCHEMA "org.mate.interface"
#define INTERFACE_GNOME_SCHEMA "org.gnome.desktop.interface"
#define GTK_THEME_KEY "gtk-theme"
#define COLOR_SCHEME_KEY "gtk-color-scheme"
#define ICON_THEME_KEY "icon-theme"
Expand All @@ -48,12 +50,27 @@ void
mate_meta_theme_set (MateThemeMetaInfo *meta_theme_info)
{
GSettings *interface_settings;
GSettings *interface_gnome_settings = NULL;
GSettings *marco_settings;
GSettings *mouse_settings;
GSettings *notification_settings = NULL;
gchar *old_key;
gint old_key_int;

/*Load the gnome interface schema if we are running under wayland and it is present*/
if (!(GDK_IS_X11_DISPLAY (gdk_display_get_default())))
{
GSettingsSchemaSource *source = g_settings_schema_source_get_default ();

if (source)
{
GSettingsSchema *schema = g_settings_schema_source_lookup (source, INTERFACE_GNOME_SCHEMA, TRUE);

if (schema)
interface_gnome_settings = g_settings_new_full (schema, NULL, NULL);
}
}

interface_settings = g_settings_new (INTERFACE_SCHEMA);
marco_settings = g_settings_new (MARCO_SCHEMA);
mouse_settings = g_settings_new (MOUSE_SCHEMA);
Expand All @@ -68,6 +85,11 @@ mate_meta_theme_set (MateThemeMetaInfo *meta_theme_info)
if (compare (old_key, meta_theme_info->gtk_theme_name))
{
g_settings_set_string (interface_settings, GTK_THEME_KEY, meta_theme_info->gtk_theme_name);

if (interface_gnome_settings)
g_settings_set_string (interface_gnome_settings,
GTK_THEME_KEY, meta_theme_info->gtk_theme_name);

}
g_free (old_key);

Expand Down Expand Up @@ -97,12 +119,17 @@ mate_meta_theme_set (MateThemeMetaInfo *meta_theme_info)

/* Set the wm key */
g_settings_set_string (marco_settings, MARCO_THEME_KEY, meta_theme_info->marco_theme_name);
/*To also control decoration theme in wayland we need a decorator that uses marco themes
*and queries gsettings to determine which theme to use to this is a TODO */

/* set the icon theme */
old_key = g_settings_get_string (interface_settings, ICON_THEME_KEY);
if (compare (old_key, meta_theme_info->icon_theme_name))
{
g_settings_set_string (interface_settings, ICON_THEME_KEY, meta_theme_info->icon_theme_name);
if (interface_gnome_settings)
g_settings_set_string (interface_gnome_settings,
ICON_THEME_KEY, meta_theme_info->icon_theme_name);
}
g_free (old_key);

Expand All @@ -125,6 +152,12 @@ mate_meta_theme_set (MateThemeMetaInfo *meta_theme_info)
if (compare (old_key, meta_theme_info->cursor_theme_name))
{
g_settings_set_string (mouse_settings, CURSOR_THEME_KEY, meta_theme_info->cursor_theme_name);
if (interface_gnome_settings)
{
/*Note that this key is in a different place in GNOME than it is in MATE*/
g_settings_set_string (interface_gnome_settings,
CURSOR_THEME_KEY, meta_theme_info->cursor_theme_name);
}
}

old_key_int = g_settings_get_int (mouse_settings, CURSOR_SIZE_KEY);
Expand Down
27 changes: 26 additions & 1 deletion capplets/common/wm-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ wm_common_get_window_manager_property (Atom atom)
if (wm_window == None)
return NULL;

display = gdk_display_get_default ();
if (!(GDK_IS_X11_DISPLAY (display)))
return NULL;

utf8_string = gdk_x11_get_xatom_by_name ("UTF8_STRING");

display = gdk_display_get_default ();
gdk_x11_display_error_trap_push (display);

val = NULL;
Expand Down Expand Up @@ -64,6 +67,9 @@ wm_common_get_window_manager_property (Atom atom)
char*
wm_common_get_current_window_manager (void)
{
if (!(GDK_IS_X11_DISPLAY (gdk_display_get_default())))
return g_strdup (WM_COMMON_UNKNOWN);

Atom atom = gdk_x11_get_xatom_by_name ("_NET_WM_NAME");
char *result;

Expand All @@ -77,6 +83,15 @@ wm_common_get_current_window_manager (void)
char**
wm_common_get_current_keybindings (void)
{

if (!(GDK_IS_X11_DISPLAY (gdk_display_get_default())))
{
/*This should never reached in wayland as compositors control
*and limit keybindings
*/
return NULL;
}

Atom keybindings_atom = gdk_x11_get_xatom_by_name ("_MATE_WM_KEYBINDINGS");
char *keybindings = wm_common_get_window_manager_property (keybindings_atom);
char **results;
Expand Down Expand Up @@ -115,6 +130,10 @@ update_wm_window (void)
gulong bytes_after;

display = gdk_display_get_default ();

if (!(GDK_IS_X11_DISPLAY (display)))
return;

XGetWindowProperty (GDK_DISPLAY_XDISPLAY(display), GDK_ROOT_WINDOW (),
gdk_x11_get_xatom_by_name ("_NET_SUPPORTING_WM_CHECK"),
0, G_MAXLONG, False, XA_WINDOW, &type, &format,
Expand Down Expand Up @@ -146,6 +165,9 @@ wm_window_event_filter (GdkXEvent *xev,
GdkEvent *event,
gpointer data)
{
if (!(GDK_IS_X11_DISPLAY (gdk_display_get_default())))
return GDK_FILTER_CONTINUE;

WMCallbackData *ncb_data = (WMCallbackData*) data;
XEvent *xevent = (XEvent *)xev;

Expand All @@ -172,6 +194,9 @@ wm_common_register_window_manager_change (GFunc func,
{
WMCallbackData *ncb_data;

if (!(GDK_IS_X11_DISPLAY (gdk_display_get_default())))
return;

ncb_data = g_new0 (WMCallbackData, 1);

ncb_data->func = func;
Expand Down

0 comments on commit 1e8c08e

Please sign in to comment.