mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
wayland: No more screen
This gets rid of the GdkWaylandScreen object and all remnants of GdkScreen in the wayland backend.
This commit is contained in:
parent
81cda3dcf7
commit
0f9e9a9ec2
@ -4521,9 +4521,7 @@ pointer_surface_update_scale (GdkDevice *device)
|
||||
scale = 1;
|
||||
for (l = pointer->pointer_surface_outputs; l != NULL; l = l->next)
|
||||
{
|
||||
guint32 output_scale =
|
||||
_gdk_wayland_screen_get_output_scale (display_wayland->screen,
|
||||
l->data);
|
||||
guint32 output_scale = gdk_wayland_display_get_output_scale (display_wayland, l->data);
|
||||
scale = MAX (scale, output_scale);
|
||||
}
|
||||
|
||||
|
@ -33,10 +33,11 @@
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include "gdkwayland.h"
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkscreen.h"
|
||||
#include "gdkmonitor-wayland.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdevicemanager.h"
|
||||
@ -51,6 +52,8 @@
|
||||
#include <wayland/xdg-foreign-unstable-v1-client-protocol.h>
|
||||
#include <wayland/server-decoration-client-protocol.h>
|
||||
|
||||
#include "wm-button-layout-translation.h"
|
||||
|
||||
/**
|
||||
* SECTION:wayland_interaction
|
||||
* @Short_description: Wayland backend-specific functions
|
||||
@ -87,6 +90,7 @@
|
||||
#define MIN_SYSTEM_BELL_DELAY_MS 20
|
||||
|
||||
#define GTK_SHELL1_VERSION 2
|
||||
#define OUTPUT_VERSION_WITH_DONE 2
|
||||
|
||||
static void _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland);
|
||||
|
||||
@ -366,6 +370,14 @@ gdk_wayland_display_prefers_ssd (GdkDisplay *display)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void gdk_wayland_display_set_has_gtk_shell (GdkWaylandDisplay *display_wayland);
|
||||
static void gdk_wayland_display_add_output (GdkWaylandDisplay *display_wayland,
|
||||
guint32 id,
|
||||
struct wl_output *output,
|
||||
guint32 version);
|
||||
static void gdk_wayland_display_remove_output (GdkWaylandDisplay *display_wayland,
|
||||
guint32 id);
|
||||
|
||||
static void
|
||||
gdk_registry_handle_global (void *data,
|
||||
struct wl_registry *registry,
|
||||
@ -404,17 +416,17 @@ gdk_registry_handle_global (void *data,
|
||||
else if (strcmp (interface, "gtk_shell1") == 0)
|
||||
{
|
||||
display_wayland->gtk_shell =
|
||||
wl_registry_bind(display_wayland->wl_registry, id,
|
||||
>k_shell1_interface,
|
||||
MIN (version, GTK_SHELL1_VERSION));
|
||||
_gdk_wayland_screen_set_has_gtk_shell (display_wayland->screen);
|
||||
wl_registry_bind (display_wayland->wl_registry, id,
|
||||
>k_shell1_interface,
|
||||
MIN (version, GTK_SHELL1_VERSION));
|
||||
gdk_wayland_display_set_has_gtk_shell (display_wayland);
|
||||
display_wayland->gtk_shell_version = version;
|
||||
}
|
||||
else if (strcmp (interface, "wl_output") == 0)
|
||||
{
|
||||
output =
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &wl_output_interface, MIN (version, 2));
|
||||
_gdk_wayland_screen_add_output (display_wayland->screen, id, output, MIN (version, 2));
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &wl_output_interface, MIN (version, 2));
|
||||
gdk_wayland_display_add_output (display_wayland, id, output, MIN (version, 2));
|
||||
_gdk_wayland_display_async_roundtrip (display_wayland);
|
||||
}
|
||||
else if (strcmp (interface, "wl_seat") == 0)
|
||||
@ -518,7 +530,7 @@ gdk_registry_handle_global_remove (void *data,
|
||||
|
||||
GDK_NOTE (MISC, g_message ("remove global %u", id));
|
||||
_gdk_wayland_device_manager_remove_seat (display->device_manager, id);
|
||||
_gdk_wayland_screen_remove_output (display_wayland->screen, id);
|
||||
gdk_wayland_display_remove_output (display_wayland, id);
|
||||
|
||||
g_hash_table_remove (display_wayland->known_globals, GUINT_TO_POINTER (id));
|
||||
|
||||
@ -559,6 +571,8 @@ _gdk_wayland_display_prepare_cursor_themes (GdkWaylandDisplay *display_wayland)
|
||||
postpone_on_globals_closure (display_wayland, closure);
|
||||
}
|
||||
|
||||
static void init_settings (GdkDisplay *display);
|
||||
|
||||
GdkDisplay *
|
||||
_gdk_wayland_display_open (const gchar *display_name)
|
||||
{
|
||||
@ -586,9 +600,11 @@ _gdk_wayland_display_open (const gchar *display_name)
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
display_wayland->wl_display = wl_display;
|
||||
display_wayland->screen = _gdk_wayland_screen_new (display);
|
||||
display_wayland->root_window = _gdk_wayland_display_create_root_window (display, 0, 0);
|
||||
display_wayland->event_source = _gdk_wayland_display_event_source_new (display);
|
||||
|
||||
init_settings (display);
|
||||
|
||||
display_wayland->known_globals =
|
||||
g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
|
||||
@ -633,7 +649,8 @@ gdk_wayland_display_dispose (GObject *object)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (object);
|
||||
|
||||
_gdk_screen_close (display_wayland->screen);
|
||||
if (display_wayland->root_window)
|
||||
_gdk_window_destroy (display_wayland->root_window, FALSE);
|
||||
|
||||
if (display_wayland->event_source)
|
||||
{
|
||||
@ -669,7 +686,8 @@ gdk_wayland_display_finalize (GObject *object)
|
||||
|
||||
_gdk_wayland_display_finalize_cursors (display_wayland);
|
||||
|
||||
g_object_unref (display_wayland->screen);
|
||||
if (display_wayland->root_window)
|
||||
g_object_unref (display_wayland->root_window);
|
||||
|
||||
g_free (display_wayland->startup_notification_id);
|
||||
g_free (display_wayland->cursor_theme_name);
|
||||
@ -686,6 +704,8 @@ gdk_wayland_display_finalize (GObject *object)
|
||||
|
||||
g_ptr_array_free (display_wayland->monitors, TRUE);
|
||||
|
||||
g_hash_table_destroy (display_wayland->settings);
|
||||
|
||||
G_OBJECT_CLASS (gdk_wayland_display_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -973,20 +993,16 @@ gdk_wayland_display_get_monitor_at_window (GdkDisplay *display,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_display_get_setting (GdkDisplay *display,
|
||||
const gchar *name,
|
||||
GValue *value)
|
||||
{
|
||||
return gdk_wayland_screen_get_setting (GDK_WAYLAND_DISPLAY (display)->screen, name, value);
|
||||
}
|
||||
|
||||
static GdkWindow *
|
||||
gdk_wayland_display_get_root_window (GdkDisplay *display)
|
||||
{
|
||||
return gdk_wayland_screen_get_root_window (GDK_WAYLAND_DISPLAY (display)->screen);
|
||||
return GDK_WAYLAND_DISPLAY (display)->root_window;
|
||||
}
|
||||
|
||||
static gboolean gdk_wayland_display_get_setting (GdkDisplay *display,
|
||||
const char *name,
|
||||
GValue *value);
|
||||
|
||||
static void
|
||||
gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
|
||||
{
|
||||
@ -1383,3 +1399,739 @@ gdk_wayland_display_get_selection (GdkDisplay *display)
|
||||
|
||||
return display_wayland->selection;
|
||||
}
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GSD_FONT_ANTIALIASING_MODE_NONE,
|
||||
GSD_FONT_ANTIALIASING_MODE_GRAYSCALE,
|
||||
GSD_FONT_ANTIALIASING_MODE_RGBA
|
||||
} GsdFontAntialiasingMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GSD_FONT_HINTING_NONE,
|
||||
GSD_FONT_HINTING_SLIGHT,
|
||||
GSD_FONT_HINTING_MEDIUM,
|
||||
GSD_FONT_HINTING_FULL
|
||||
} GsdFontHinting;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GSD_FONT_RGBA_ORDER_RGBA,
|
||||
GSD_FONT_RGBA_ORDER_RGB,
|
||||
GSD_FONT_RGBA_ORDER_BGR,
|
||||
GSD_FONT_RGBA_ORDER_VRGB,
|
||||
GSD_FONT_RGBA_ORDER_VBGR
|
||||
} GsdFontRgbaOrder;
|
||||
|
||||
static gdouble
|
||||
get_dpi_from_gsettings (GdkWaylandDisplay *display_wayland)
|
||||
{
|
||||
GSettings *settings;
|
||||
gdouble factor;
|
||||
|
||||
settings = g_hash_table_lookup (display_wayland->settings,
|
||||
"org.gnome.desktop.interface");
|
||||
if (settings != NULL)
|
||||
factor = g_settings_get_double (settings, "text-scaling-factor");
|
||||
else
|
||||
factor = 1.0;
|
||||
|
||||
return 96.0 * factor;
|
||||
}
|
||||
|
||||
static void
|
||||
update_xft_settings (GdkDisplay *display)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GSettings *settings;
|
||||
GsdFontAntialiasingMode antialiasing;
|
||||
GsdFontHinting hinting;
|
||||
GsdFontRgbaOrder order;
|
||||
gboolean use_rgba = FALSE;
|
||||
GsdXftSettings xft_settings;
|
||||
|
||||
settings = g_hash_table_lookup (display_wayland->settings,
|
||||
"org.gnome.settings-daemon.plugins.xsettings");
|
||||
|
||||
if (settings)
|
||||
{
|
||||
antialiasing = g_settings_get_enum (settings, "antialiasing");
|
||||
hinting = g_settings_get_enum (settings, "hinting");
|
||||
order = g_settings_get_enum (settings, "rgba-order");
|
||||
}
|
||||
else
|
||||
{
|
||||
antialiasing = GSD_FONT_ANTIALIASING_MODE_GRAYSCALE;
|
||||
hinting = GSD_FONT_HINTING_MEDIUM;
|
||||
order = GSD_FONT_RGBA_ORDER_RGB;
|
||||
}
|
||||
|
||||
xft_settings.hinting = (hinting != GSD_FONT_HINTING_NONE);
|
||||
xft_settings.dpi = get_dpi_from_gsettings (display_wayland) * 1024; /* Xft wants 1/1024ths of an inch */
|
||||
|
||||
switch (hinting)
|
||||
{
|
||||
case GSD_FONT_HINTING_NONE:
|
||||
xft_settings.hintstyle = "hintnone";
|
||||
break;
|
||||
case GSD_FONT_HINTING_SLIGHT:
|
||||
xft_settings.hintstyle = "hintslight";
|
||||
break;
|
||||
case GSD_FONT_HINTING_MEDIUM:
|
||||
xft_settings.hintstyle = "hintmedium";
|
||||
break;
|
||||
case GSD_FONT_HINTING_FULL:
|
||||
default:
|
||||
xft_settings.hintstyle = "hintfull";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (order)
|
||||
{
|
||||
case GSD_FONT_RGBA_ORDER_RGBA:
|
||||
xft_settings.rgba = "rgba";
|
||||
break;
|
||||
default:
|
||||
case GSD_FONT_RGBA_ORDER_RGB:
|
||||
xft_settings.rgba = "rgb";
|
||||
break;
|
||||
case GSD_FONT_RGBA_ORDER_BGR:
|
||||
xft_settings.rgba = "bgr";
|
||||
break;
|
||||
case GSD_FONT_RGBA_ORDER_VRGB:
|
||||
xft_settings.rgba = "vrgb";
|
||||
break;
|
||||
case GSD_FONT_RGBA_ORDER_VBGR:
|
||||
xft_settings.rgba = "vbgr";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (antialiasing)
|
||||
{
|
||||
default:
|
||||
case GSD_FONT_ANTIALIASING_MODE_NONE:
|
||||
xft_settings.antialias = FALSE;
|
||||
break;
|
||||
case GSD_FONT_ANTIALIASING_MODE_GRAYSCALE:
|
||||
xft_settings.antialias = TRUE;
|
||||
break;
|
||||
case GSD_FONT_ANTIALIASING_MODE_RGBA:
|
||||
xft_settings.antialias = TRUE;
|
||||
use_rgba = TRUE;
|
||||
}
|
||||
|
||||
if (!use_rgba)
|
||||
xft_settings.rgba = "none";
|
||||
|
||||
if (display_wayland->xft_settings.antialias != xft_settings.antialias)
|
||||
{
|
||||
display_wayland->xft_settings.antialias = xft_settings.antialias;
|
||||
gdk_display_setting_changed (display, "gtk-xft-antialias");
|
||||
}
|
||||
|
||||
if (display_wayland->xft_settings.hinting != xft_settings.hinting)
|
||||
{
|
||||
display_wayland->xft_settings.hinting = xft_settings.hinting;
|
||||
gdk_display_setting_changed (display, "gtk-xft-hinting");
|
||||
}
|
||||
|
||||
if (display_wayland->xft_settings.hintstyle != xft_settings.hintstyle)
|
||||
{
|
||||
display_wayland->xft_settings.hintstyle = xft_settings.hintstyle;
|
||||
gdk_display_setting_changed (display, "gtk-xft-hintstyle");
|
||||
}
|
||||
|
||||
if (display_wayland->xft_settings.rgba != xft_settings.rgba)
|
||||
{
|
||||
display_wayland->xft_settings.rgba = xft_settings.rgba;
|
||||
gdk_display_setting_changed (display, "gtk-xft-rgba");
|
||||
}
|
||||
|
||||
if (display_wayland->xft_settings.dpi != xft_settings.dpi)
|
||||
{
|
||||
display_wayland->xft_settings.dpi = xft_settings.dpi;
|
||||
gdk_display_setting_changed (display, "gtk-xft-dpi");
|
||||
}
|
||||
}
|
||||
|
||||
#define WM_SETTINGS_SCHEMA "org.gnome.desktop.wm.preferences"
|
||||
#define CLASSIC_WM_SETTINGS_SCHEMA "org.gnome.shell.extensions.classic-overrides"
|
||||
|
||||
typedef struct _TranslationEntry TranslationEntry;
|
||||
struct _TranslationEntry {
|
||||
gboolean valid;
|
||||
const gchar *schema;
|
||||
const gchar *key;
|
||||
const gchar *setting;
|
||||
GType type;
|
||||
union {
|
||||
const gchar *s;
|
||||
gint i;
|
||||
gboolean b;
|
||||
} fallback;
|
||||
};
|
||||
|
||||
static TranslationEntry translations[] = {
|
||||
{ FALSE, "org.gnome.desktop.interface", "gtk-theme", "gtk-theme-name" , G_TYPE_STRING, { .s = "Adwaita" } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "icon-theme", "gtk-icon-theme-name", G_TYPE_STRING, { .s = "gnome" } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "cursor-theme", "gtk-cursor-theme-name", G_TYPE_STRING, { .s = "Adwaita" } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "cursor-size", "gtk-cursor-theme-size", G_TYPE_INT, { .i = 32 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "font-name", "gtk-font-name", G_TYPE_STRING, { .s = "Cantarell 11" } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "cursor-blink", "gtk-cursor-blink", G_TYPE_BOOLEAN, { .b = TRUE } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "cursor-blink-time", "gtk-cursor-blink-time", G_TYPE_INT, { .i = 1200 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "cursor-blink-timeout", "gtk-cursor-blink-timeout", G_TYPE_INT, { .i = 3600 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "gtk-im-module", "gtk-im-module", G_TYPE_STRING, { .s = "simple" } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "enable-animations", "gtk-enable-animations", G_TYPE_BOOLEAN, { .b = TRUE } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "gtk-enable-primary-paste", "gtk-enable-primary-paste", G_TYPE_BOOLEAN, { .b = TRUE } },
|
||||
{ FALSE, "org.gnome.settings-daemon.peripherals.mouse", "double-click", "gtk-double-click-time", G_TYPE_INT, { .i = 400 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.peripherals.mouse", "drag-threshold", "gtk-dnd-drag-threshold", G_TYPE_INT, {.i = 8 } },
|
||||
{ FALSE, "org.gnome.desktop.sound", "theme-name", "gtk-sound-theme-name", G_TYPE_STRING, { .s = "freedesktop" } },
|
||||
{ FALSE, "org.gnome.desktop.sound", "event-sounds", "gtk-enable-event-sounds", G_TYPE_BOOLEAN, { .b = TRUE } },
|
||||
{ FALSE, "org.gnome.desktop.sound", "input-feedback-sounds", "gtk-enable-input-feedback-sounds", G_TYPE_BOOLEAN, { . b = FALSE } },
|
||||
{ FALSE, "org.gnome.desktop.privacy", "recent-files-max-age", "gtk-recent-files-max-age", G_TYPE_INT, { .i = 30 } },
|
||||
{ FALSE, "org.gnome.desktop.privacy", "remember-recent-files", "gtk-recent-files-enabled", G_TYPE_BOOLEAN, { .b = TRUE } },
|
||||
{ FALSE, WM_SETTINGS_SCHEMA, "button-layout", "gtk-decoration-layout", G_TYPE_STRING, { .s = "menu:close" } },
|
||||
{ FALSE, CLASSIC_WM_SETTINGS_SCHEMA, "button-layout", "gtk-decoration-layout", G_TYPE_STRING, { .s = "menu:close" } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "antialiasing", "gtk-xft-antialias", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "hinting", "gtk-xft-hinting", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "hinting", "gtk-xft-hintstyle", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "rgba-order", "gtk-xft-rgba", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "text-scaling-factor", "gtk-xft-dpi" , G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-double-click-titlebar", "gtk-titlebar-double-click", G_TYPE_STRING, { .s = "toggle-maximize" } },
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-middle-click-titlebar", "gtk-titlebar-middle-click", G_TYPE_STRING, { .s = "none" } },
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-right-click-titlebar", "gtk-titlebar-right-click", G_TYPE_STRING, { .s = "menu" } },
|
||||
{ FALSE, "org.gnome.desktop.a11y", "always-show-text-caret", "gtk-keynav-use-caret", G_TYPE_BOOLEAN, { .b = FALSE } }
|
||||
};
|
||||
|
||||
static TranslationEntry *
|
||||
find_translation_entry_by_key (GSettings *settings,
|
||||
const char *key)
|
||||
{
|
||||
guint i;
|
||||
char *schema;
|
||||
|
||||
g_object_get (settings, "schema", &schema, NULL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (translations); i++)
|
||||
{
|
||||
if (g_str_equal (schema, translations[i].schema) &&
|
||||
g_str_equal (key, translations[i].key))
|
||||
{
|
||||
g_free (schema);
|
||||
return &translations[i];
|
||||
}
|
||||
}
|
||||
|
||||
g_free (schema);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static TranslationEntry *
|
||||
find_translation_entry_by_setting (const char *setting)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (translations); i++)
|
||||
{
|
||||
if (g_str_equal (setting, translations[i].setting))
|
||||
return &translations[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
settings_changed (GSettings *settings,
|
||||
const char *key,
|
||||
GdkDisplay *display)
|
||||
{
|
||||
TranslationEntry *entry;
|
||||
|
||||
entry = find_translation_entry_by_key (settings, key);
|
||||
|
||||
if (entry != NULL)
|
||||
{
|
||||
if (entry->type != G_TYPE_NONE)
|
||||
gdk_display_setting_changed (display, entry->setting);
|
||||
else
|
||||
update_xft_settings (display);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_settings (GdkDisplay *display)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GSettingsSchemaSource *source;
|
||||
GSettingsSchema *schema;
|
||||
GSettings *settings;
|
||||
gint i;
|
||||
|
||||
display_wayland->settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
|
||||
|
||||
source = g_settings_schema_source_get_default ();
|
||||
if (source == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (translations); i++)
|
||||
{
|
||||
schema = g_settings_schema_source_lookup (source, translations[i].schema, TRUE);
|
||||
if (!schema)
|
||||
continue;
|
||||
|
||||
if (g_hash_table_lookup (display_wayland->settings, (gpointer)translations[i].schema) == NULL)
|
||||
{
|
||||
settings = g_settings_new_full (schema, NULL, NULL);
|
||||
g_signal_connect (settings, "changed",
|
||||
G_CALLBACK (settings_changed), display);
|
||||
g_hash_table_insert (display_wayland->settings, (gpointer)translations[i].schema, settings);
|
||||
}
|
||||
|
||||
if (g_settings_schema_has_key (schema, translations[i].key))
|
||||
translations[i].valid = TRUE;
|
||||
|
||||
g_settings_schema_unref (schema);
|
||||
}
|
||||
|
||||
update_xft_settings (display);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shell_handle_capabilities (void *data,
|
||||
struct gtk_shell1 *shell,
|
||||
uint32_t capabilities)
|
||||
{
|
||||
GdkDisplay *display = data;
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (data);
|
||||
|
||||
display_wayland->shell_capabilities = capabilities;
|
||||
|
||||
gdk_display_setting_changed (display, "gtk-shell-shows-app-menu");
|
||||
gdk_display_setting_changed (display, "gtk-shell-shows-menubar");
|
||||
gdk_display_setting_changed (display, "gtk-shell-shows-desktop");
|
||||
}
|
||||
|
||||
struct gtk_shell1_listener gdk_display_gtk_shell_listener = {
|
||||
gtk_shell_handle_capabilities
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_wayland_display_set_has_gtk_shell (GdkWaylandDisplay *display_wayland)
|
||||
{
|
||||
gtk_shell1_add_listener (display_wayland->gtk_shell,
|
||||
&gdk_display_gtk_shell_listener,
|
||||
display_wayland);
|
||||
}
|
||||
|
||||
static void
|
||||
set_value_from_entry (GdkDisplay *display,
|
||||
TranslationEntry *entry,
|
||||
GValue *value)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GSettings *settings;
|
||||
|
||||
settings = (GSettings *)g_hash_table_lookup (display_wayland->settings, entry->schema);
|
||||
switch (entry->type)
|
||||
{
|
||||
case G_TYPE_STRING:
|
||||
if (settings && entry->valid)
|
||||
{
|
||||
gchar *s;
|
||||
s = g_settings_get_string (settings, entry->key);
|
||||
g_value_set_string (value, s);
|
||||
g_free (s);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_value_set_static_string (value, entry->fallback.s);
|
||||
}
|
||||
break;
|
||||
case G_TYPE_INT:
|
||||
g_value_set_int (value, settings && entry->valid
|
||||
? g_settings_get_int (settings, entry->key)
|
||||
: entry->fallback.i);
|
||||
break;
|
||||
case G_TYPE_BOOLEAN:
|
||||
g_value_set_boolean (value, settings && entry->valid
|
||||
? g_settings_get_boolean (settings, entry->key)
|
||||
: entry->fallback.b);
|
||||
break;
|
||||
case G_TYPE_NONE:
|
||||
if (g_str_equal (entry->setting, "gtk-xft-antialias"))
|
||||
g_value_set_int (value, display_wayland->xft_settings.antialias);
|
||||
else if (g_str_equal (entry->setting, "gtk-xft-hinting"))
|
||||
g_value_set_int (value, display_wayland->xft_settings.hinting);
|
||||
else if (g_str_equal (entry->setting, "gtk-xft-hintstyle"))
|
||||
g_value_set_static_string (value, display_wayland->xft_settings.hintstyle);
|
||||
else if (g_str_equal (entry->setting, "gtk-xft-rgba"))
|
||||
g_value_set_static_string (value, display_wayland->xft_settings.rgba);
|
||||
else if (g_str_equal (entry->setting, "gtk-xft-dpi"))
|
||||
g_value_set_int (value, display_wayland->xft_settings.dpi);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_decoration_layout_from_entry (GdkDisplay *display,
|
||||
TranslationEntry *entry,
|
||||
GValue *value)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GSettings *settings = NULL;
|
||||
const char *session;
|
||||
|
||||
/* Hack: until we get session-dependent defaults in GSettings,
|
||||
* swap out the usual schema for the "classic" one when
|
||||
* running in classic mode
|
||||
*/
|
||||
session = g_getenv ("XDG_CURRENT_DESKTOP");
|
||||
if (session && strstr (session, "GNOME-Classic"))
|
||||
settings = (GSettings *)g_hash_table_lookup (display_wayland->settings, CLASSIC_WM_SETTINGS_SCHEMA);
|
||||
|
||||
if (settings == NULL)
|
||||
settings = (GSettings *)g_hash_table_lookup (display_wayland->settings, WM_SETTINGS_SCHEMA);
|
||||
|
||||
if (settings)
|
||||
{
|
||||
gchar *s = g_settings_get_string (settings, entry->key);
|
||||
|
||||
translate_wm_button_layout_to_gtk (s);
|
||||
g_value_set_string (value, s);
|
||||
|
||||
g_free (s);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_value_set_static_string (value, entry->fallback.s);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_capability_setting (GdkDisplay *display,
|
||||
GValue *value,
|
||||
enum gtk_shell1_capability test)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
g_value_set_boolean (value, (display_wayland->shell_capabilities & test) == test);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_display_get_setting (GdkDisplay *display,
|
||||
const char *name,
|
||||
GValue *value)
|
||||
{
|
||||
TranslationEntry *entry;
|
||||
|
||||
entry = find_translation_entry_by_setting (name);
|
||||
if (entry != NULL)
|
||||
{
|
||||
if (strcmp (name, "gtk-decoration-layout") == 0)
|
||||
set_decoration_layout_from_entry (display, entry, value);
|
||||
else
|
||||
set_value_from_entry (display, entry, value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (strcmp (name, "gtk-shell-shows-app-menu") == 0)
|
||||
return set_capability_setting (display, value, GTK_SHELL1_CAPABILITY_GLOBAL_APP_MENU);
|
||||
|
||||
if (strcmp (name, "gtk-shell-shows-menubar") == 0)
|
||||
return set_capability_setting (display, value, GTK_SHELL1_CAPABILITY_GLOBAL_MENU_BAR);
|
||||
|
||||
if (strcmp (name, "gtk-shell-shows-desktop") == 0)
|
||||
return set_capability_setting (display, value, GTK_SHELL1_CAPABILITY_DESKTOP_ICONS);
|
||||
|
||||
if (strcmp (name, "gtk-dialogs-use-header") == 0)
|
||||
{
|
||||
g_value_set_boolean (value, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
static const char *
|
||||
subpixel_to_string (int layout)
|
||||
{
|
||||
int i;
|
||||
struct { int layout; const char *name; } layouts[] = {
|
||||
{ WL_OUTPUT_SUBPIXEL_UNKNOWN, "unknown" },
|
||||
{ WL_OUTPUT_SUBPIXEL_NONE, "none" },
|
||||
{ WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB, "rgb" },
|
||||
{ WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR, "bgr" },
|
||||
{ WL_OUTPUT_SUBPIXEL_VERTICAL_RGB, "vrgb" },
|
||||
{ WL_OUTPUT_SUBPIXEL_VERTICAL_BGR, "vbgr" },
|
||||
{ 0xffffffff, NULL }
|
||||
};
|
||||
|
||||
for (i = 0; layouts[i].name; i++)
|
||||
{
|
||||
if (layouts[i].layout == layout)
|
||||
return layouts[i].name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
transform_to_string (int transform)
|
||||
{
|
||||
int i;
|
||||
struct { int transform; const char *name; } transforms[] = {
|
||||
{ WL_OUTPUT_TRANSFORM_NORMAL, "normal" },
|
||||
{ WL_OUTPUT_TRANSFORM_90, "90" },
|
||||
{ WL_OUTPUT_TRANSFORM_180, "180" },
|
||||
{ WL_OUTPUT_TRANSFORM_270, "270" },
|
||||
{ WL_OUTPUT_TRANSFORM_FLIPPED, "flipped" },
|
||||
{ WL_OUTPUT_TRANSFORM_FLIPPED_90, "flipped 90" },
|
||||
{ WL_OUTPUT_TRANSFORM_FLIPPED_180, "flipped 180" },
|
||||
{ WL_OUTPUT_TRANSFORM_FLIPPED_270, "flipped 270" },
|
||||
{ 0xffffffff, NULL }
|
||||
};
|
||||
|
||||
for (i = 0; transforms[i].name; i++)
|
||||
{
|
||||
if (transforms[i].transform == transform)
|
||||
return transforms[i].name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
output_handle_geometry (void *data,
|
||||
struct wl_output *wl_output,
|
||||
int x,
|
||||
int y,
|
||||
int physical_width,
|
||||
int physical_height,
|
||||
int subpixel,
|
||||
const char *make,
|
||||
const char *model,
|
||||
int32_t transform)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle geometry output %d, position %d %d, phys. size %d %d, subpixel layout %s, manufacturer %s, model %s, transform %s",
|
||||
monitor->id, x, y, physical_width, physical_height, subpixel_to_string (subpixel), make, model, transform_to_string (transform)));
|
||||
|
||||
gdk_monitor_set_position (GDK_MONITOR (monitor), x, y);
|
||||
gdk_monitor_set_physical_size (GDK_MONITOR (monitor), physical_width, physical_height);
|
||||
gdk_monitor_set_subpixel_layout (GDK_MONITOR (monitor), subpixel);
|
||||
gdk_monitor_set_manufacturer (GDK_MONITOR (monitor), make);
|
||||
gdk_monitor_set_model (GDK_MONITOR (monitor), model);
|
||||
|
||||
if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
{
|
||||
GdkDisplay *display = GDK_MONITOR (monitor)->display;
|
||||
window_update_scale (GDK_WAYLAND_DISPLAY (display)->root_window);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_done (void *data,
|
||||
struct wl_output *wl_output)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
GdkDisplay *display = gdk_monitor_get_display (GDK_MONITOR (monitor));
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle done output %d", monitor->id));
|
||||
|
||||
if (!monitor->added)
|
||||
{
|
||||
monitor->added = TRUE;
|
||||
g_ptr_array_add (GDK_WAYLAND_DISPLAY (display)->monitors, monitor);
|
||||
gdk_display_monitor_added (display, GDK_MONITOR (monitor));
|
||||
}
|
||||
|
||||
window_update_scale (GDK_WAYLAND_DISPLAY (display)->root_window);
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_scale (void *data,
|
||||
struct wl_output *wl_output,
|
||||
int32_t scale)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
GdkRectangle previous_geometry;
|
||||
int previous_scale;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle scale output %d, scale %d", monitor->id, scale));
|
||||
|
||||
gdk_monitor_get_geometry (GDK_MONITOR (monitor), &previous_geometry);
|
||||
previous_scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
|
||||
width = previous_geometry.width * previous_scale;
|
||||
height = previous_geometry.height * previous_scale;
|
||||
|
||||
gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), scale);
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), width / scale, height / scale);
|
||||
|
||||
if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
window_update_scale (GDK_WAYLAND_DISPLAY (GDK_MONITOR (monitor)->display)->root_window);
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_mode (void *data,
|
||||
struct wl_output *wl_output,
|
||||
uint32_t flags,
|
||||
int width,
|
||||
int height,
|
||||
int refresh)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
int scale;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle mode output %d, size %d %d, rate %d",
|
||||
monitor->id, width, height, refresh));
|
||||
|
||||
if ((flags & WL_OUTPUT_MODE_CURRENT) == 0)
|
||||
return;
|
||||
|
||||
scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), width / scale, height / scale);
|
||||
gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh);
|
||||
|
||||
if (width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
window_update_scale (GDK_WAYLAND_DISPLAY (GDK_MONITOR (monitor)->display)->root_window);
|
||||
}
|
||||
|
||||
static const struct wl_output_listener output_listener =
|
||||
{
|
||||
output_handle_geometry,
|
||||
output_handle_mode,
|
||||
output_handle_done,
|
||||
output_handle_scale,
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_wayland_display_add_output (GdkWaylandDisplay *display_wayland,
|
||||
guint32 id,
|
||||
struct wl_output *output,
|
||||
guint32 version)
|
||||
{
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = g_object_new (GDK_TYPE_WAYLAND_MONITOR,
|
||||
"display", GDK_DISPLAY (display_wayland),
|
||||
NULL);
|
||||
|
||||
monitor->id = id;
|
||||
monitor->output = output;
|
||||
monitor->version = version;
|
||||
|
||||
if (monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
{
|
||||
g_ptr_array_add (display_wayland->monitors, monitor);
|
||||
gdk_display_monitor_added (GDK_DISPLAY (display_wayland), GDK_MONITOR (monitor));
|
||||
}
|
||||
|
||||
wl_output_add_listener (output, &output_listener, monitor);
|
||||
}
|
||||
|
||||
struct wl_output *
|
||||
gdk_wayland_display_get_wl_output (GdkDisplay *display,
|
||||
gint monitor_num)
|
||||
{
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = GDK_WAYLAND_DISPLAY (display)->monitors->pdata[monitor_num];
|
||||
|
||||
return monitor->output;
|
||||
}
|
||||
|
||||
static GdkWaylandMonitor *
|
||||
get_monitor_for_id (GdkWaylandDisplay *display_wayland,
|
||||
guint32 id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < display_wayland->monitors->len; i++)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = display_wayland->monitors->pdata[i];
|
||||
|
||||
if (monitor->id == id)
|
||||
return monitor;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GdkWaylandMonitor *
|
||||
get_monitor_for_output (GdkWaylandDisplay *display_wayland,
|
||||
struct wl_output *output)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < display_wayland->monitors->len; i++)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = display_wayland->monitors->pdata[i];
|
||||
|
||||
if (monitor->output == output)
|
||||
return monitor;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_display_remove_output (GdkWaylandDisplay *display_wayland,
|
||||
guint32 id)
|
||||
{
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = get_monitor_for_id (display_wayland, id);
|
||||
if (monitor != NULL)
|
||||
{
|
||||
g_object_ref (monitor);
|
||||
g_ptr_array_remove (display_wayland->monitors, monitor);
|
||||
gdk_display_monitor_removed (GDK_DISPLAY (display_wayland), GDK_MONITOR (monitor));
|
||||
window_update_scale (gdk_display_get_root_window (GDK_MONITOR (monitor)->display));
|
||||
g_object_unref (monitor);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
gdk_wayland_display_get_output_refresh_rate (GdkWaylandDisplay *display_wayland,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = get_monitor_for_output (display_wayland, output);
|
||||
if (monitor != NULL)
|
||||
return gdk_monitor_get_refresh_rate (GDK_MONITOR (monitor));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
guint32
|
||||
gdk_wayland_display_get_output_scale (GdkWaylandDisplay *display_wayland,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = get_monitor_for_output (display_wayland, output);
|
||||
if (monitor != NULL)
|
||||
return gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -53,10 +53,23 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkWaylandSelection GdkWaylandSelection;
|
||||
|
||||
typedef struct {
|
||||
gboolean antialias;
|
||||
gboolean hinting;
|
||||
gint dpi;
|
||||
const gchar *rgba;
|
||||
const gchar *hintstyle;
|
||||
} GsdXftSettings;
|
||||
|
||||
struct _GdkWaylandDisplay
|
||||
{
|
||||
GdkDisplay parent_instance;
|
||||
GdkScreen *screen;
|
||||
GdkWindow *root_window;
|
||||
|
||||
GHashTable *settings;
|
||||
GsdXftSettings xft_settings;
|
||||
|
||||
guint32 shell_capabilities;
|
||||
|
||||
/* Startup notification */
|
||||
gchar *startup_notification_id;
|
||||
|
@ -206,30 +206,16 @@ GdkAppLaunchContext *_gdk_wayland_display_get_app_launch_context (GdkDisplay *di
|
||||
|
||||
GdkDisplay *_gdk_wayland_display_open (const gchar *display_name);
|
||||
|
||||
GdkWindow *_gdk_wayland_screen_create_root_window (GdkScreen *screen,
|
||||
int width,
|
||||
int height);
|
||||
GdkWindow *_gdk_wayland_display_create_root_window (GdkDisplay *display,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
gboolean gdk_wayland_screen_get_setting (GdkScreen *screen,
|
||||
const gchar *name,
|
||||
GValue *value);
|
||||
GdkWindow *gdk_wayland_screen_get_root_window (GdkScreen *screen);
|
||||
|
||||
GdkScreen *_gdk_wayland_screen_new (GdkDisplay *display);
|
||||
void _gdk_wayland_screen_add_output (GdkScreen *screen,
|
||||
guint32 id,
|
||||
struct wl_output *output,
|
||||
guint32 version);
|
||||
void _gdk_wayland_screen_remove_output (GdkScreen *screen,
|
||||
guint32 id);
|
||||
int _gdk_wayland_screen_get_output_refresh_rate (GdkScreen *screen,
|
||||
struct wl_output *output);
|
||||
guint32 _gdk_wayland_screen_get_output_scale (GdkScreen *screen,
|
||||
struct wl_output *output);
|
||||
struct wl_output *_gdk_wayland_screen_get_wl_output (GdkScreen *screen,
|
||||
gint monitor_num);
|
||||
|
||||
void _gdk_wayland_screen_set_has_gtk_shell (GdkScreen *screen);
|
||||
int gdk_wayland_display_get_output_refresh_rate (GdkWaylandDisplay *display_wayland,
|
||||
struct wl_output *output);
|
||||
guint32 gdk_wayland_display_get_output_scale (GdkWaylandDisplay *display_wayland,
|
||||
struct wl_output *output);
|
||||
struct wl_output *gdk_wayland_display_get_wl_output (GdkDisplay *display,
|
||||
int monitor_num);
|
||||
|
||||
void _gdk_wayland_window_set_grab_seat (GdkWindow *window,
|
||||
GdkSeat *seat);
|
||||
|
@ -1,905 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include "gdkscreenprivate.h"
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkmonitor-wayland.h"
|
||||
#include "gdkwayland.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
|
||||
#include "wm-button-layout-translation.h"
|
||||
|
||||
typedef struct _GdkWaylandScreen GdkWaylandScreen;
|
||||
typedef struct _GdkWaylandScreenClass GdkWaylandScreenClass;
|
||||
|
||||
#define GDK_TYPE_WAYLAND_SCREEN (_gdk_wayland_screen_get_type ())
|
||||
#define GDK_WAYLAND_SCREEN(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_SCREEN, GdkWaylandScreen))
|
||||
#define GDK_WAYLAND_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_SCREEN, GdkWaylandScreenClass))
|
||||
#define GDK_IS_WAYLAND_SCREEN(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_SCREEN))
|
||||
#define GDK_IS_WAYLAND_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WAYLAND_SCREEN))
|
||||
#define GDK_WAYLAND_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_SCREEN, GdkWaylandScreenClass))
|
||||
|
||||
typedef struct {
|
||||
gboolean antialias;
|
||||
gboolean hinting;
|
||||
gint dpi;
|
||||
const gchar *rgba;
|
||||
const gchar *hintstyle;
|
||||
} GsdXftSettings;
|
||||
|
||||
|
||||
struct _GdkWaylandScreen
|
||||
{
|
||||
GdkScreen parent_instance;
|
||||
|
||||
GdkDisplay *display;
|
||||
GdkWindow *root_window;
|
||||
|
||||
GHashTable *settings;
|
||||
GsdXftSettings xft_settings;
|
||||
|
||||
guint32 shell_capabilities;
|
||||
};
|
||||
|
||||
struct _GdkWaylandScreenClass
|
||||
{
|
||||
GdkScreenClass parent_class;
|
||||
};
|
||||
|
||||
#define OUTPUT_VERSION_WITH_DONE 2
|
||||
|
||||
|
||||
GType _gdk_wayland_screen_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
|
||||
|
||||
static void
|
||||
gdk_wayland_screen_dispose (GObject *object)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (object);
|
||||
|
||||
if (screen_wayland->root_window)
|
||||
_gdk_window_destroy (screen_wayland->root_window, FALSE);
|
||||
|
||||
G_OBJECT_CLASS (_gdk_wayland_screen_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_screen_finalize (GObject *object)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (object);
|
||||
|
||||
if (screen_wayland->root_window)
|
||||
g_object_unref (screen_wayland->root_window);
|
||||
|
||||
g_hash_table_destroy (screen_wayland->settings);
|
||||
|
||||
G_OBJECT_CLASS (_gdk_wayland_screen_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static GdkDisplay *
|
||||
gdk_wayland_screen_get_display (GdkScreen *screen)
|
||||
{
|
||||
return GDK_WAYLAND_SCREEN (screen)->display;
|
||||
}
|
||||
|
||||
GdkWindow *
|
||||
gdk_wayland_screen_get_root_window (GdkScreen *screen)
|
||||
{
|
||||
return GDK_WAYLAND_SCREEN (screen)->root_window;
|
||||
}
|
||||
|
||||
static void
|
||||
notify_setting (GdkScreen *screen,
|
||||
const gchar *setting)
|
||||
{
|
||||
gdk_display_setting_changed (gdk_screen_get_display (screen), setting);
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GSD_FONT_ANTIALIASING_MODE_NONE,
|
||||
GSD_FONT_ANTIALIASING_MODE_GRAYSCALE,
|
||||
GSD_FONT_ANTIALIASING_MODE_RGBA
|
||||
} GsdFontAntialiasingMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GSD_FONT_HINTING_NONE,
|
||||
GSD_FONT_HINTING_SLIGHT,
|
||||
GSD_FONT_HINTING_MEDIUM,
|
||||
GSD_FONT_HINTING_FULL
|
||||
} GsdFontHinting;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GSD_FONT_RGBA_ORDER_RGBA,
|
||||
GSD_FONT_RGBA_ORDER_RGB,
|
||||
GSD_FONT_RGBA_ORDER_BGR,
|
||||
GSD_FONT_RGBA_ORDER_VRGB,
|
||||
GSD_FONT_RGBA_ORDER_VBGR
|
||||
} GsdFontRgbaOrder;
|
||||
|
||||
static gdouble
|
||||
get_dpi_from_gsettings (GdkWaylandScreen *screen_wayland)
|
||||
{
|
||||
GSettings *settings;
|
||||
gdouble factor;
|
||||
|
||||
settings = g_hash_table_lookup (screen_wayland->settings,
|
||||
"org.gnome.desktop.interface");
|
||||
if (settings != NULL)
|
||||
factor = g_settings_get_double (settings, "text-scaling-factor");
|
||||
else
|
||||
factor = 1.0;
|
||||
|
||||
return 96.0 * factor;
|
||||
}
|
||||
|
||||
static void
|
||||
update_xft_settings (GdkScreen *screen)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GSettings *settings;
|
||||
GsdFontAntialiasingMode antialiasing;
|
||||
GsdFontHinting hinting;
|
||||
GsdFontRgbaOrder order;
|
||||
gboolean use_rgba = FALSE;
|
||||
GsdXftSettings xft_settings;
|
||||
|
||||
settings = g_hash_table_lookup (screen_wayland->settings, "org.gnome.settings-daemon.plugins.xsettings");
|
||||
|
||||
if (settings)
|
||||
{
|
||||
antialiasing = g_settings_get_enum (settings, "antialiasing");
|
||||
hinting = g_settings_get_enum (settings, "hinting");
|
||||
order = g_settings_get_enum (settings, "rgba-order");
|
||||
}
|
||||
else
|
||||
{
|
||||
antialiasing = GSD_FONT_ANTIALIASING_MODE_GRAYSCALE;
|
||||
hinting = GSD_FONT_HINTING_MEDIUM;
|
||||
order = GSD_FONT_RGBA_ORDER_RGB;
|
||||
}
|
||||
|
||||
xft_settings.hinting = (hinting != GSD_FONT_HINTING_NONE);
|
||||
xft_settings.dpi = get_dpi_from_gsettings (screen_wayland) * 1024; /* Xft wants 1/1024ths of an inch */
|
||||
|
||||
switch (hinting)
|
||||
{
|
||||
case GSD_FONT_HINTING_NONE:
|
||||
xft_settings.hintstyle = "hintnone";
|
||||
break;
|
||||
case GSD_FONT_HINTING_SLIGHT:
|
||||
xft_settings.hintstyle = "hintslight";
|
||||
break;
|
||||
case GSD_FONT_HINTING_MEDIUM:
|
||||
xft_settings.hintstyle = "hintmedium";
|
||||
break;
|
||||
case GSD_FONT_HINTING_FULL:
|
||||
default:
|
||||
xft_settings.hintstyle = "hintfull";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (order)
|
||||
{
|
||||
case GSD_FONT_RGBA_ORDER_RGBA:
|
||||
xft_settings.rgba = "rgba";
|
||||
break;
|
||||
default:
|
||||
case GSD_FONT_RGBA_ORDER_RGB:
|
||||
xft_settings.rgba = "rgb";
|
||||
break;
|
||||
case GSD_FONT_RGBA_ORDER_BGR:
|
||||
xft_settings.rgba = "bgr";
|
||||
break;
|
||||
case GSD_FONT_RGBA_ORDER_VRGB:
|
||||
xft_settings.rgba = "vrgb";
|
||||
break;
|
||||
case GSD_FONT_RGBA_ORDER_VBGR:
|
||||
xft_settings.rgba = "vbgr";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (antialiasing)
|
||||
{
|
||||
default:
|
||||
case GSD_FONT_ANTIALIASING_MODE_NONE:
|
||||
xft_settings.antialias = FALSE;
|
||||
break;
|
||||
case GSD_FONT_ANTIALIASING_MODE_GRAYSCALE:
|
||||
xft_settings.antialias = TRUE;
|
||||
break;
|
||||
case GSD_FONT_ANTIALIASING_MODE_RGBA:
|
||||
xft_settings.antialias = TRUE;
|
||||
use_rgba = TRUE;
|
||||
}
|
||||
|
||||
if (!use_rgba)
|
||||
xft_settings.rgba = "none";
|
||||
|
||||
if (screen_wayland->xft_settings.antialias != xft_settings.antialias)
|
||||
{
|
||||
screen_wayland->xft_settings.antialias = xft_settings.antialias;
|
||||
notify_setting (screen, "gtk-xft-antialias");
|
||||
}
|
||||
|
||||
if (screen_wayland->xft_settings.hinting != xft_settings.hinting)
|
||||
{
|
||||
screen_wayland->xft_settings.hinting = xft_settings.hinting;
|
||||
notify_setting (screen, "gtk-xft-hinting");
|
||||
}
|
||||
|
||||
if (screen_wayland->xft_settings.hintstyle != xft_settings.hintstyle)
|
||||
{
|
||||
screen_wayland->xft_settings.hintstyle = xft_settings.hintstyle;
|
||||
notify_setting (screen, "gtk-xft-hintstyle");
|
||||
}
|
||||
|
||||
if (screen_wayland->xft_settings.rgba != xft_settings.rgba)
|
||||
{
|
||||
screen_wayland->xft_settings.rgba = xft_settings.rgba;
|
||||
notify_setting (screen, "gtk-xft-rgba");
|
||||
}
|
||||
|
||||
if (screen_wayland->xft_settings.dpi != xft_settings.dpi)
|
||||
{
|
||||
screen_wayland->xft_settings.dpi = xft_settings.dpi;
|
||||
notify_setting (screen, "gtk-xft-dpi");
|
||||
}
|
||||
}
|
||||
|
||||
#define WM_SETTINGS_SCHEMA "org.gnome.desktop.wm.preferences"
|
||||
#define CLASSIC_WM_SETTINGS_SCHEMA "org.gnome.shell.extensions.classic-overrides"
|
||||
|
||||
typedef struct _TranslationEntry TranslationEntry;
|
||||
struct _TranslationEntry {
|
||||
gboolean valid;
|
||||
const gchar *schema;
|
||||
const gchar *key;
|
||||
const gchar *setting;
|
||||
GType type;
|
||||
union {
|
||||
const gchar *s;
|
||||
gint i;
|
||||
gboolean b;
|
||||
} fallback;
|
||||
};
|
||||
|
||||
static TranslationEntry translations[] = {
|
||||
{ FALSE, "org.gnome.desktop.interface", "gtk-theme", "gtk-theme-name" , G_TYPE_STRING, { .s = "Adwaita" } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "icon-theme", "gtk-icon-theme-name", G_TYPE_STRING, { .s = "gnome" } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "cursor-theme", "gtk-cursor-theme-name", G_TYPE_STRING, { .s = "Adwaita" } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "cursor-size", "gtk-cursor-theme-size", G_TYPE_INT, { .i = 32 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "font-name", "gtk-font-name", G_TYPE_STRING, { .s = "Cantarell 11" } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "cursor-blink", "gtk-cursor-blink", G_TYPE_BOOLEAN, { .b = TRUE } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "cursor-blink-time", "gtk-cursor-blink-time", G_TYPE_INT, { .i = 1200 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "cursor-blink-timeout", "gtk-cursor-blink-timeout", G_TYPE_INT, { .i = 3600 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "gtk-im-module", "gtk-im-module", G_TYPE_STRING, { .s = "simple" } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "enable-animations", "gtk-enable-animations", G_TYPE_BOOLEAN, { .b = TRUE } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "gtk-enable-primary-paste", "gtk-enable-primary-paste", G_TYPE_BOOLEAN, { .b = TRUE } },
|
||||
{ FALSE, "org.gnome.settings-daemon.peripherals.mouse", "double-click", "gtk-double-click-time", G_TYPE_INT, { .i = 400 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.peripherals.mouse", "drag-threshold", "gtk-dnd-drag-threshold", G_TYPE_INT, {.i = 8 } },
|
||||
{ FALSE, "org.gnome.desktop.sound", "theme-name", "gtk-sound-theme-name", G_TYPE_STRING, { .s = "freedesktop" } },
|
||||
{ FALSE, "org.gnome.desktop.sound", "event-sounds", "gtk-enable-event-sounds", G_TYPE_BOOLEAN, { .b = TRUE } },
|
||||
{ FALSE, "org.gnome.desktop.sound", "input-feedback-sounds", "gtk-enable-input-feedback-sounds", G_TYPE_BOOLEAN, { . b = FALSE } },
|
||||
{ FALSE, "org.gnome.desktop.privacy", "recent-files-max-age", "gtk-recent-files-max-age", G_TYPE_INT, { .i = 30 } },
|
||||
{ FALSE, "org.gnome.desktop.privacy", "remember-recent-files", "gtk-recent-files-enabled", G_TYPE_BOOLEAN, { .b = TRUE } },
|
||||
{ FALSE, WM_SETTINGS_SCHEMA, "button-layout", "gtk-decoration-layout", G_TYPE_STRING, { .s = "menu:close" } },
|
||||
{ FALSE, CLASSIC_WM_SETTINGS_SCHEMA, "button-layout", "gtk-decoration-layout", G_TYPE_STRING, { .s = "menu:close" } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "antialiasing", "gtk-xft-antialias", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "hinting", "gtk-xft-hinting", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "hinting", "gtk-xft-hintstyle", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.settings-daemon.plugins.xsettings", "rgba-order", "gtk-xft-rgba", G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.desktop.interface", "text-scaling-factor", "gtk-xft-dpi" , G_TYPE_NONE, { .i = 0 } },
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-double-click-titlebar", "gtk-titlebar-double-click", G_TYPE_STRING, { .s = "toggle-maximize" } },
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-middle-click-titlebar", "gtk-titlebar-middle-click", G_TYPE_STRING, { .s = "none" } },
|
||||
{ FALSE, "org.gnome.desktop.wm.preferences", "action-right-click-titlebar", "gtk-titlebar-right-click", G_TYPE_STRING, { .s = "menu" } },
|
||||
{ FALSE, "org.gnome.desktop.a11y", "always-show-text-caret", "gtk-keynav-use-caret", G_TYPE_BOOLEAN, { .b = FALSE } }
|
||||
};
|
||||
|
||||
static TranslationEntry *
|
||||
find_translation_entry_by_key (GSettings *settings,
|
||||
const gchar *key)
|
||||
{
|
||||
guint i;
|
||||
gchar *schema;
|
||||
|
||||
g_object_get (settings, "schema", &schema, NULL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (translations); i++)
|
||||
{
|
||||
if (g_str_equal (schema, translations[i].schema) &&
|
||||
g_str_equal (key, translations[i].key))
|
||||
{
|
||||
g_free (schema);
|
||||
return &translations[i];
|
||||
}
|
||||
}
|
||||
|
||||
g_free (schema);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static TranslationEntry *
|
||||
find_translation_entry_by_setting (const gchar *setting)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (translations); i++)
|
||||
{
|
||||
if (g_str_equal (setting, translations[i].setting))
|
||||
return &translations[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
settings_changed (GSettings *settings,
|
||||
const gchar *key,
|
||||
GdkScreen *screen)
|
||||
{
|
||||
TranslationEntry *entry;
|
||||
|
||||
entry = find_translation_entry_by_key (settings, key);
|
||||
|
||||
if (entry != NULL)
|
||||
{
|
||||
if (entry->type != G_TYPE_NONE)
|
||||
notify_setting (screen, entry->setting);
|
||||
else
|
||||
update_xft_settings (screen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_settings (GdkScreen *screen)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GSettingsSchemaSource *source;
|
||||
GSettingsSchema *schema;
|
||||
GSettings *settings;
|
||||
gint i;
|
||||
|
||||
screen_wayland->settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
|
||||
|
||||
source = g_settings_schema_source_get_default ();
|
||||
if (source == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (translations); i++)
|
||||
{
|
||||
schema = g_settings_schema_source_lookup (source, translations[i].schema, TRUE);
|
||||
if (!schema)
|
||||
continue;
|
||||
|
||||
if (g_hash_table_lookup (screen_wayland->settings, (gpointer)translations[i].schema) == NULL)
|
||||
{
|
||||
settings = g_settings_new_full (schema, NULL, NULL);
|
||||
g_signal_connect (settings, "changed",
|
||||
G_CALLBACK (settings_changed), screen);
|
||||
g_hash_table_insert (screen_wayland->settings, (gpointer)translations[i].schema, settings);
|
||||
}
|
||||
|
||||
if (g_settings_schema_has_key (schema, translations[i].key))
|
||||
translations[i].valid = TRUE;
|
||||
|
||||
g_settings_schema_unref (schema);
|
||||
}
|
||||
|
||||
update_xft_settings (screen);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shell_handle_capabilities (void *data,
|
||||
struct gtk_shell1 *shell,
|
||||
uint32_t capabilities)
|
||||
{
|
||||
GdkScreen *screen = data;
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (data);
|
||||
|
||||
screen_wayland->shell_capabilities = capabilities;
|
||||
|
||||
notify_setting (screen, "gtk-shell-shows-app-menu");
|
||||
notify_setting (screen, "gtk-shell-shows-menubar");
|
||||
notify_setting (screen, "gtk-shell-shows-desktop");
|
||||
}
|
||||
|
||||
struct gtk_shell1_listener gdk_screen_gtk_shell_listener = {
|
||||
gtk_shell_handle_capabilities
|
||||
};
|
||||
|
||||
void
|
||||
_gdk_wayland_screen_set_has_gtk_shell (GdkScreen *screen)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland =
|
||||
GDK_WAYLAND_DISPLAY (GDK_WAYLAND_SCREEN (screen)->display);
|
||||
|
||||
gtk_shell1_add_listener (display_wayland->gtk_shell,
|
||||
&gdk_screen_gtk_shell_listener,
|
||||
screen);
|
||||
}
|
||||
|
||||
static void
|
||||
set_value_from_entry (GdkScreen *screen,
|
||||
TranslationEntry *entry,
|
||||
GValue *value)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GSettings *settings;
|
||||
|
||||
settings = (GSettings *)g_hash_table_lookup (screen_wayland->settings, entry->schema);
|
||||
switch (entry->type)
|
||||
{
|
||||
case G_TYPE_STRING:
|
||||
if (settings && entry->valid)
|
||||
{
|
||||
gchar *s;
|
||||
s = g_settings_get_string (settings, entry->key);
|
||||
g_value_set_string (value, s);
|
||||
g_free (s);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_value_set_static_string (value, entry->fallback.s);
|
||||
}
|
||||
break;
|
||||
case G_TYPE_INT:
|
||||
g_value_set_int (value, settings && entry->valid
|
||||
? g_settings_get_int (settings, entry->key)
|
||||
: entry->fallback.i);
|
||||
break;
|
||||
case G_TYPE_BOOLEAN:
|
||||
g_value_set_boolean (value, settings && entry->valid
|
||||
? g_settings_get_boolean (settings, entry->key)
|
||||
: entry->fallback.b);
|
||||
break;
|
||||
case G_TYPE_NONE:
|
||||
if (g_str_equal (entry->setting, "gtk-xft-antialias"))
|
||||
g_value_set_int (value, screen_wayland->xft_settings.antialias);
|
||||
else if (g_str_equal (entry->setting, "gtk-xft-hinting"))
|
||||
g_value_set_int (value, screen_wayland->xft_settings.hinting);
|
||||
else if (g_str_equal (entry->setting, "gtk-xft-hintstyle"))
|
||||
g_value_set_static_string (value, screen_wayland->xft_settings.hintstyle);
|
||||
else if (g_str_equal (entry->setting, "gtk-xft-rgba"))
|
||||
g_value_set_static_string (value, screen_wayland->xft_settings.rgba);
|
||||
else if (g_str_equal (entry->setting, "gtk-xft-dpi"))
|
||||
g_value_set_int (value, screen_wayland->xft_settings.dpi);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_decoration_layout_from_entry (GdkScreen *screen,
|
||||
TranslationEntry *entry,
|
||||
GValue *value)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GSettings *settings = NULL;
|
||||
const char *session;
|
||||
|
||||
/* Hack: until we get session-dependent defaults in GSettings,
|
||||
* swap out the usual schema for the "classic" one when
|
||||
* running in classic mode
|
||||
*/
|
||||
session = g_getenv ("XDG_CURRENT_DESKTOP");
|
||||
if (session && strstr (session, "GNOME-Classic"))
|
||||
settings = (GSettings *)g_hash_table_lookup (screen_wayland->settings, CLASSIC_WM_SETTINGS_SCHEMA);
|
||||
|
||||
if (settings == NULL)
|
||||
settings = (GSettings *)g_hash_table_lookup (screen_wayland->settings, WM_SETTINGS_SCHEMA);
|
||||
|
||||
if (settings)
|
||||
{
|
||||
gchar *s = g_settings_get_string (settings, entry->key);
|
||||
|
||||
translate_wm_button_layout_to_gtk (s);
|
||||
g_value_set_string (value, s);
|
||||
|
||||
g_free (s);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_value_set_static_string (value, entry->fallback.s);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_capability_setting (GdkScreen *screen,
|
||||
GValue *value,
|
||||
enum gtk_shell1_capability test)
|
||||
{
|
||||
GdkWaylandScreen *wayland_screen = GDK_WAYLAND_SCREEN (screen);
|
||||
|
||||
g_value_set_boolean (value, (wayland_screen->shell_capabilities & test) == test);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_wayland_screen_get_setting (GdkScreen *screen,
|
||||
const gchar *name,
|
||||
GValue *value)
|
||||
{
|
||||
TranslationEntry *entry;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
|
||||
|
||||
entry = find_translation_entry_by_setting (name);
|
||||
if (entry != NULL)
|
||||
{
|
||||
if (strcmp (name, "gtk-decoration-layout") == 0)
|
||||
set_decoration_layout_from_entry (screen, entry, value);
|
||||
else
|
||||
set_value_from_entry (screen, entry, value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (strcmp (name, "gtk-shell-shows-app-menu") == 0)
|
||||
return set_capability_setting (screen, value,
|
||||
GTK_SHELL1_CAPABILITY_GLOBAL_APP_MENU);
|
||||
|
||||
if (strcmp (name, "gtk-shell-shows-menubar") == 0)
|
||||
return set_capability_setting (screen, value,
|
||||
GTK_SHELL1_CAPABILITY_GLOBAL_MENU_BAR);
|
||||
|
||||
if (strcmp (name, "gtk-shell-shows-desktop") == 0)
|
||||
return set_capability_setting (screen, value,
|
||||
GTK_SHELL1_CAPABILITY_DESKTOP_ICONS);
|
||||
|
||||
if (strcmp (name, "gtk-dialogs-use-header") == 0)
|
||||
{
|
||||
g_value_set_boolean (value, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GdkScreen *
|
||||
_gdk_wayland_screen_new (GdkDisplay *display)
|
||||
{
|
||||
GdkScreen *screen;
|
||||
GdkWaylandScreen *screen_wayland;
|
||||
|
||||
screen = g_object_new (GDK_TYPE_WAYLAND_SCREEN, NULL);
|
||||
|
||||
screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
screen_wayland->display = display;
|
||||
|
||||
screen_wayland->root_window =
|
||||
_gdk_wayland_screen_create_root_window (screen, 0, 0);
|
||||
|
||||
init_settings (screen);
|
||||
|
||||
return screen;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_wayland_screen_class_init (GdkWaylandScreenClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkScreenClass *screen_class = GDK_SCREEN_CLASS (klass);
|
||||
|
||||
object_class->dispose = gdk_wayland_screen_dispose;
|
||||
object_class->finalize = gdk_wayland_screen_finalize;
|
||||
|
||||
screen_class->get_display = gdk_wayland_screen_get_display;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_wayland_screen_init (GdkWaylandScreen *screen_wayland)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
static const char *
|
||||
subpixel_to_string (int layout)
|
||||
{
|
||||
int i;
|
||||
struct { int layout; const char *name; } layouts[] = {
|
||||
{ WL_OUTPUT_SUBPIXEL_UNKNOWN, "unknown" },
|
||||
{ WL_OUTPUT_SUBPIXEL_NONE, "none" },
|
||||
{ WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB, "rgb" },
|
||||
{ WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR, "bgr" },
|
||||
{ WL_OUTPUT_SUBPIXEL_VERTICAL_RGB, "vrgb" },
|
||||
{ WL_OUTPUT_SUBPIXEL_VERTICAL_BGR, "vbgr" },
|
||||
{ 0xffffffff, NULL }
|
||||
};
|
||||
|
||||
for (i = 0; layouts[i].name; i++)
|
||||
{
|
||||
if (layouts[i].layout == layout)
|
||||
return layouts[i].name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
transform_to_string (int transform)
|
||||
{
|
||||
int i;
|
||||
struct { int transform; const char *name; } transforms[] = {
|
||||
{ WL_OUTPUT_TRANSFORM_NORMAL, "normal" },
|
||||
{ WL_OUTPUT_TRANSFORM_90, "90" },
|
||||
{ WL_OUTPUT_TRANSFORM_180, "180" },
|
||||
{ WL_OUTPUT_TRANSFORM_270, "270" },
|
||||
{ WL_OUTPUT_TRANSFORM_FLIPPED, "flipped" },
|
||||
{ WL_OUTPUT_TRANSFORM_FLIPPED_90, "flipped 90" },
|
||||
{ WL_OUTPUT_TRANSFORM_FLIPPED_180, "flipped 180" },
|
||||
{ WL_OUTPUT_TRANSFORM_FLIPPED_270, "flipped 270" },
|
||||
{ 0xffffffff, NULL }
|
||||
};
|
||||
|
||||
for (i = 0; transforms[i].name; i++)
|
||||
{
|
||||
if (transforms[i].transform == transform)
|
||||
return transforms[i].name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
output_handle_geometry (void *data,
|
||||
struct wl_output *wl_output,
|
||||
int x,
|
||||
int y,
|
||||
int physical_width,
|
||||
int physical_height,
|
||||
int subpixel,
|
||||
const char *make,
|
||||
const char *model,
|
||||
int32_t transform)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle geometry output %d, position %d %d, phys. size %d %d, subpixel layout %s, manufacturer %s, model %s, transform %s",
|
||||
monitor->id, x, y, physical_width, physical_height, subpixel_to_string (subpixel), make, model, transform_to_string (transform)));
|
||||
|
||||
gdk_monitor_set_position (GDK_MONITOR (monitor), x, y);
|
||||
gdk_monitor_set_physical_size (GDK_MONITOR (monitor), physical_width, physical_height);
|
||||
gdk_monitor_set_subpixel_layout (GDK_MONITOR (monitor), subpixel);
|
||||
gdk_monitor_set_manufacturer (GDK_MONITOR (monitor), make);
|
||||
gdk_monitor_set_model (GDK_MONITOR (monitor), model);
|
||||
|
||||
if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
{
|
||||
GdkDisplay *display = GDK_MONITOR (monitor)->display;
|
||||
window_update_scale (gdk_display_get_root_window (display));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_done (void *data,
|
||||
struct wl_output *wl_output)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
GdkDisplay *display = gdk_monitor_get_display (GDK_MONITOR (monitor));
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle done output %d", monitor->id));
|
||||
|
||||
if (!monitor->added)
|
||||
{
|
||||
monitor->added = TRUE;
|
||||
g_ptr_array_add (GDK_WAYLAND_DISPLAY (display)->monitors, monitor);
|
||||
gdk_display_monitor_added (display, GDK_MONITOR (monitor));
|
||||
}
|
||||
|
||||
window_update_scale (gdk_display_get_root_window (display));
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_scale (void *data,
|
||||
struct wl_output *wl_output,
|
||||
int32_t scale)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
GdkRectangle previous_geometry;
|
||||
int previous_scale;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle scale output %d, scale %d", monitor->id, scale));
|
||||
|
||||
gdk_monitor_get_geometry (GDK_MONITOR (monitor), &previous_geometry);
|
||||
previous_scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
|
||||
width = previous_geometry.width * previous_scale;
|
||||
height = previous_geometry.height * previous_scale;
|
||||
|
||||
gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), scale);
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), width / scale, height / scale);
|
||||
|
||||
if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
window_update_scale (gdk_display_get_root_window (GDK_MONITOR (monitor)->display));
|
||||
}
|
||||
|
||||
static void
|
||||
output_handle_mode (void *data,
|
||||
struct wl_output *wl_output,
|
||||
uint32_t flags,
|
||||
int width,
|
||||
int height,
|
||||
int refresh)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
int scale;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle mode output %d, size %d %d, rate %d",
|
||||
monitor->id, width, height, refresh));
|
||||
|
||||
if ((flags & WL_OUTPUT_MODE_CURRENT) == 0)
|
||||
return;
|
||||
|
||||
scale = gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), width / scale, height / scale);
|
||||
gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh);
|
||||
|
||||
if (width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
window_update_scale (gdk_display_get_root_window (GDK_MONITOR (monitor)->display));
|
||||
}
|
||||
|
||||
static const struct wl_output_listener output_listener =
|
||||
{
|
||||
output_handle_geometry,
|
||||
output_handle_mode,
|
||||
output_handle_done,
|
||||
output_handle_scale,
|
||||
};
|
||||
|
||||
void
|
||||
_gdk_wayland_screen_add_output (GdkScreen *screen,
|
||||
guint32 id,
|
||||
struct wl_output *output,
|
||||
guint32 version)
|
||||
{
|
||||
GdkDisplay *display = gdk_screen_get_display (screen);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = g_object_new (GDK_TYPE_WAYLAND_MONITOR,
|
||||
"display", display,
|
||||
NULL);
|
||||
|
||||
monitor->id = id;
|
||||
monitor->output = output;
|
||||
monitor->version = version;
|
||||
|
||||
if (monitor->version < OUTPUT_VERSION_WITH_DONE)
|
||||
{
|
||||
g_ptr_array_add (GDK_WAYLAND_DISPLAY (display)->monitors, monitor);
|
||||
gdk_display_monitor_added (display, GDK_MONITOR (monitor));
|
||||
}
|
||||
|
||||
wl_output_add_listener (output, &output_listener, monitor);
|
||||
}
|
||||
|
||||
struct wl_output *
|
||||
_gdk_wayland_screen_get_wl_output (GdkScreen *screen,
|
||||
gint monitor_num)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (GDK_WAYLAND_SCREEN (screen)->display);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = display_wayland->monitors->pdata[monitor_num];
|
||||
|
||||
return monitor->output;
|
||||
}
|
||||
|
||||
static GdkWaylandMonitor *
|
||||
get_monitor_for_id (GdkWaylandScreen *screen_wayland,
|
||||
guint32 id)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (screen_wayland->display);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < display_wayland->monitors->len; i++)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = display_wayland->monitors->pdata[i];
|
||||
|
||||
if (monitor->id == id)
|
||||
return monitor;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GdkWaylandMonitor *
|
||||
get_monitor_for_output (GdkWaylandScreen *screen_wayland,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (screen_wayland->display);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < display_wayland->monitors->len; i++)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = display_wayland->monitors->pdata[i];
|
||||
|
||||
if (monitor->output == output)
|
||||
return monitor;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_wayland_screen_remove_output (GdkScreen *screen,
|
||||
guint32 id)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (screen_wayland->display);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = get_monitor_for_id (screen_wayland, id);
|
||||
if (monitor != NULL)
|
||||
{
|
||||
g_object_ref (monitor);
|
||||
g_ptr_array_remove (display_wayland->monitors, monitor);
|
||||
gdk_display_monitor_removed (GDK_DISPLAY (display_wayland), GDK_MONITOR (monitor));
|
||||
window_update_scale (gdk_display_get_root_window (GDK_MONITOR (monitor)->display));
|
||||
g_object_unref (monitor);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_gdk_wayland_screen_get_output_refresh_rate (GdkScreen *screen,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = get_monitor_for_output (screen_wayland, output);
|
||||
if (monitor != NULL)
|
||||
return gdk_monitor_get_refresh_rate (GDK_MONITOR (monitor));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
guint32
|
||||
_gdk_wayland_screen_get_output_scale (GdkScreen *screen,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
GdkWaylandMonitor *monitor;
|
||||
|
||||
monitor = get_monitor_for_output (screen_wayland, output);
|
||||
if (monitor != NULL)
|
||||
return gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
|
||||
|
||||
return 0;
|
||||
}
|
@ -348,11 +348,10 @@ gdk_wayland_window_update_size (GdkWindow *window,
|
||||
}
|
||||
|
||||
GdkWindow *
|
||||
_gdk_wayland_screen_create_root_window (GdkScreen *screen,
|
||||
int width,
|
||||
int height)
|
||||
_gdk_wayland_display_create_root_window (GdkDisplay *display,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GdkDisplay *display = gdk_screen_get_display (screen);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GdkWindow *window;
|
||||
GdkWindowImplWayland *impl;
|
||||
@ -385,7 +384,6 @@ _gdk_wayland_screen_create_root_window (GdkScreen *screen,
|
||||
window->height = height;
|
||||
window->viewable = TRUE;
|
||||
|
||||
/* see init_randr_support() in gdkscreen-wayland.c */
|
||||
window->event_mask = GDK_STRUCTURE_MASK;
|
||||
|
||||
return window;
|
||||
@ -518,7 +516,7 @@ frame_callback (void *data,
|
||||
/* We pick a random output out of the outputs that the window touches
|
||||
* The rate here is in milli-hertz */
|
||||
int refresh_rate =
|
||||
_gdk_wayland_screen_get_output_refresh_rate (display_wayland->screen,
|
||||
gdk_wayland_display_get_output_refresh_rate (display_wayland,
|
||||
impl->display_server.outputs->data);
|
||||
if (refresh_rate != 0)
|
||||
timings->refresh_interval = G_GINT64_CONSTANT(1000000000) / refresh_rate;
|
||||
@ -633,8 +631,7 @@ window_update_scale (GdkWindow *window)
|
||||
scale = 1;
|
||||
for (l = impl->display_server.outputs; l != NULL; l = l->next)
|
||||
{
|
||||
guint32 output_scale =
|
||||
_gdk_wayland_screen_get_output_scale (display_wayland->screen, l->data);
|
||||
guint32 output_scale = gdk_wayland_display_get_output_scale (display_wayland, l->data);
|
||||
scale = MAX (scale, output_scale);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ gdk_wayland_sources = files([
|
||||
'gdkglcontext-wayland.c',
|
||||
'gdkkeys-wayland.c',
|
||||
'gdkmonitor-wayland.c',
|
||||
'gdkscreen-wayland.c',
|
||||
'gdkselection-wayland.c',
|
||||
'gdkvulkancontext-wayland.c',
|
||||
'gdkwindow-wayland.c',
|
||||
|
Loading…
Reference in New Issue
Block a user