Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cff5ef0ec2 | ||
|
|
d478d8f143 | ||
|
|
7eca43cec9 | ||
|
|
9060190555 | ||
|
|
0de3869656 | ||
|
|
9f13033f15 | ||
|
|
48bf807430 | ||
|
|
c68e43a97f | ||
|
|
cc53d48fa8 | ||
|
|
ca6e799b97 | ||
|
|
0f8e387dc0 | ||
|
|
d62c595e51 | ||
|
|
dd3cf94744 | ||
|
|
eb56e0a3d7 | ||
|
|
8937c32cd5 | ||
|
|
a8a5da768a | ||
|
|
33bfcf56ce | ||
|
|
40cccb58a5 | ||
|
|
eb6c70137b | ||
|
|
df3b412a25 | ||
|
|
cfba0a5dfc | ||
|
|
3561b46fc6 | ||
|
|
8dfb88b669 | ||
|
|
2e3086e2aa | ||
|
|
f424056fea | ||
|
|
cfb7297cf1 | ||
|
|
8769b3d554 | ||
|
|
f8b82c376c | ||
|
|
868e1427a8 | ||
|
|
4aa74af694 | ||
|
|
f3fecd478d | ||
|
|
a5d1f67c34 | ||
|
|
102fa0e373 | ||
|
|
dbca3337b2 | ||
|
|
939f7ce781 | ||
|
|
c6e6ed87c5 | ||
|
|
8188cddcf7 | ||
|
|
9f17c05a15 | ||
|
|
c3455b01af | ||
|
|
d4e8d97e58 | ||
|
|
a86368dcb1 | ||
|
|
a13f906ed1 | ||
|
|
f9e91bf007 | ||
|
|
7c5fe42835 | ||
|
|
e76decbcf2 | ||
|
|
aac5a5dcaf | ||
|
|
9b3186f8a5 |
31
NEWS
31
NEWS
@@ -1,3 +1,34 @@
|
||||
3.17.1
|
||||
======
|
||||
* Add public method to get neighboring monitor [Florian; #633994]
|
||||
* Apply the right settings to the right input devices [Carlos; #747886]
|
||||
* Fix scroll button setting [Ondrej; #747967]
|
||||
* Add support for modal hint on wayland [Jonas; #745720]
|
||||
* Don't reset idle time for non-hardware events [Rui; #748541]
|
||||
* Misc. bug fixes [Ray, Rui; #748380, #748478]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Carlos Garnacho, Ondrej Holy, Rui Matos, Florian Müllner,
|
||||
Jasper St. Pierre, Ray Strode, Tomeu Vizoso
|
||||
|
||||
3.16.1
|
||||
======
|
||||
* Add function to refresh all background instances [Rui; #739178]
|
||||
* Fix swapped scroll methods on wayland [Ondrej; #746870]
|
||||
* Manually activate stage to fix accessibility on wayland [Ray, Rui; #746670]
|
||||
* Center pointer on primary monitor on startup [Carlos; #746896]
|
||||
* wayland: Reword synchronized state application semantics [Jonas; #743617]
|
||||
* Ensure input settings are applied on startup [Rui; #747434]
|
||||
* Misc. bug fixes [Jonas, Giovanni, Calvin, Ray, Rui; #744932, #746509, #746692,
|
||||
#746510, #746545, #747263]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Giovanni Campagna, Carlos Garnacho, Ondrej Holy, Rui Matos,
|
||||
Jasper St. Pierre, Ray Strode, Calvin Walton
|
||||
|
||||
Translations:
|
||||
Khaled Hosny [ar], Marek Černocký [cs]
|
||||
|
||||
3.16.0
|
||||
======
|
||||
* wayland: Don't skip notifying about initial maximized state [Jonas; #745303]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
AC_PREREQ(2.62)
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [16])
|
||||
m4_define([mutter_micro_version], [0])
|
||||
m4_define([mutter_minor_version], [17])
|
||||
m4_define([mutter_micro_version], [1])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@@ -90,6 +90,7 @@ MUTTER_PC_MODULES="
|
||||
xkeyboard-config
|
||||
xkbcommon >= 0.4.3
|
||||
xkbcommon-x11
|
||||
xrender
|
||||
x11-xcb
|
||||
xcb-randr
|
||||
"
|
||||
|
||||
36
po/cs.po
36
po/cs.po
@@ -12,7 +12,7 @@ msgstr ""
|
||||
"Project-Id-Version: mutter\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"product=mutter&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2015-01-06 22:57+0000\n"
|
||||
"POT-Creation-Date: 2015-03-24 23:25+0000\n"
|
||||
"PO-Revision-Date: 2014-09-22 15:01+0200\n"
|
||||
"Last-Translator: Petr Kovar <pknbe@volny.cz>\n"
|
||||
"Language-Team: Czech <gnome-cs-list@gnome.org>\n"
|
||||
@@ -437,22 +437,42 @@ msgstr "Přepnout na VT 6"
|
||||
msgid "Switch to VT 7"
|
||||
msgstr "Přepnout na VT 7"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:351
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
|
||||
msgid "Switch to VT 8"
|
||||
msgstr "Přepnout na VT 8"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
|
||||
msgid "Switch to VT 9"
|
||||
msgstr "Přepnout na VT 9"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
|
||||
msgid "Switch to VT 10"
|
||||
msgstr "Přepnout na VT 10"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
|
||||
msgid "Switch to VT 11"
|
||||
msgstr "Přepnout na VT 11"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
|
||||
msgid "Switch to VT 12"
|
||||
msgstr "Přepnout na VT 12"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:364
|
||||
msgid "Built-in display"
|
||||
msgstr "Vestavěný displej"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:378
|
||||
#: ../src/backends/meta-monitor-manager.c:391
|
||||
msgid "Unknown"
|
||||
msgstr "Neznámý"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:380
|
||||
#: ../src/backends/meta-monitor-manager.c:393
|
||||
msgid "Unknown Display"
|
||||
msgstr "Neznámý displej"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: ../src/backends/meta-monitor-manager.c:388
|
||||
#: ../src/backends/meta-monitor-manager.c:401
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
@@ -495,7 +515,7 @@ msgstr "_Počkat"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Vynutit ukončení"
|
||||
|
||||
#: ../src/core/display.c:561
|
||||
#: ../src/core/display.c:562
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Nelze otevřít displej X Window System „%s“\n"
|
||||
@@ -556,7 +576,7 @@ msgstr "Vypíše verzi"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Zásuvný modul Mutter, který se má použít"
|
||||
|
||||
#: ../src/core/prefs.c:2015
|
||||
#: ../src/core/prefs.c:2004
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Plocha %d"
|
||||
@@ -587,7 +607,7 @@ msgstr ""
|
||||
"Tato okna nepodporují "ukládání aktuálního nastavení" a po vašem "
|
||||
"příštím přihlášení je budete muset spustit ručně."
|
||||
|
||||
#: ../src/x11/window-props.c:558
|
||||
#: ../src/x11/window-props.c:549
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (na %s)"
|
||||
|
||||
@@ -210,10 +210,9 @@ libmutter_la_SOURCES = \
|
||||
meta/theme.h \
|
||||
ui/theme-private.h \
|
||||
ui/ui.c \
|
||||
x11/iconcache.c \
|
||||
x11/iconcache.h \
|
||||
x11/async-getprop.c \
|
||||
x11/async-getprop.h \
|
||||
x11/atomnames.h \
|
||||
x11/events.c \
|
||||
x11/events.h \
|
||||
x11/group-private.h \
|
||||
@@ -221,6 +220,8 @@ libmutter_la_SOURCES = \
|
||||
x11/group-props.h \
|
||||
x11/group.c \
|
||||
meta/group.h \
|
||||
x11/iconcache.c \
|
||||
x11/iconcache.h \
|
||||
x11/session.c \
|
||||
x11/session.h \
|
||||
x11/window-props.c \
|
||||
@@ -265,8 +266,8 @@ libmutter_la_SOURCES += \
|
||||
wayland/meta-wayland-versions.h \
|
||||
wayland/meta-wayland-outputs.c \
|
||||
wayland/meta-wayland-outputs.h \
|
||||
wayland/window-wayland.c \
|
||||
wayland/window-wayland.h \
|
||||
wayland/meta-window-wayland.c \
|
||||
wayland/meta-window-wayland.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
@@ -338,16 +339,10 @@ libmutterinclude_base_headers = \
|
||||
$(libmutterinclude_headers) \
|
||||
$(libmutterinclude_built_headers)
|
||||
|
||||
# Excluded from scanning for introspection but installed
|
||||
# atomnames.h: macros cause problems for scanning process
|
||||
libmutterinclude_extra_headers = \
|
||||
meta/atomnames.h
|
||||
|
||||
libmutterincludedir = $(includedir)/mutter/meta
|
||||
|
||||
libmutterinclude_HEADERS = \
|
||||
$(libmutterinclude_headers) \
|
||||
$(libmutterinclude_extra_headers)
|
||||
$(libmutterinclude_headers)
|
||||
|
||||
nodist_libmutterinclude_HEADERS = \
|
||||
$(libmutterinclude_built_headers)
|
||||
|
||||
@@ -92,12 +92,37 @@ meta_backend_sync_screen_size (MetaBackend *backend)
|
||||
META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
center_pointer (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
MetaMonitorInfo *monitors, *primary;
|
||||
guint n_monitors;
|
||||
|
||||
monitors = meta_monitor_manager_get_monitor_infos (priv->monitor_manager, &n_monitors);
|
||||
primary = &monitors[meta_monitor_manager_get_primary_index (priv->monitor_manager)];
|
||||
meta_backend_warp_pointer (backend,
|
||||
primary->rect.x + primary->rect.width / 2,
|
||||
primary->rect.y + primary->rect.height / 2);
|
||||
}
|
||||
|
||||
static void
|
||||
on_monitors_changed (MetaMonitorManager *monitors,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaBackend *backend = META_BACKEND (user_data);
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
ClutterInputDevice *device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
|
||||
ClutterPoint point;
|
||||
|
||||
meta_backend_sync_screen_size (backend);
|
||||
|
||||
if (clutter_input_device_get_coords (device, NULL, &point))
|
||||
{
|
||||
/* If we're outside all monitors, warp the pointer back inside */
|
||||
if (meta_monitor_manager_get_monitor_at_point (monitors, point.x, point.y) < 0)
|
||||
center_pointer (backend);
|
||||
}
|
||||
}
|
||||
|
||||
static MetaIdleMonitor *
|
||||
@@ -283,6 +308,8 @@ meta_backend_real_post_init (MetaBackend *backend)
|
||||
}
|
||||
|
||||
priv->input_settings = meta_input_settings_create ();
|
||||
|
||||
center_pointer (backend);
|
||||
}
|
||||
|
||||
static MetaCursorRenderer *
|
||||
|
||||
@@ -185,6 +185,7 @@ meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
return FALSE;
|
||||
|
||||
g_clear_pointer (&tracker->xfixes_cursor, meta_cursor_reference_unref);
|
||||
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -209,6 +209,10 @@ update_touchpad_left_handed (MetaInputSettings *input_settings,
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gboolean enabled = FALSE;
|
||||
|
||||
if (device &&
|
||||
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
handedness = g_settings_get_enum (priv->touchpad_settings, "left-handed");
|
||||
@@ -230,7 +234,6 @@ update_touchpad_left_handed (MetaInputSettings *input_settings,
|
||||
|
||||
if (device)
|
||||
{
|
||||
g_assert (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHPAD_DEVICE);
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_left_handed,
|
||||
enabled);
|
||||
@@ -251,13 +254,16 @@ update_mouse_left_handed (MetaInputSettings *input_settings,
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gboolean enabled;
|
||||
|
||||
if (device &&
|
||||
clutter_input_device_get_device_type (device) != CLUTTER_POINTER_DEVICE)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
enabled = g_settings_get_boolean (priv->mouse_settings, "left-handed");
|
||||
|
||||
if (device)
|
||||
{
|
||||
g_assert (clutter_input_device_get_device_type (device) == CLUTTER_POINTER_DEVICE);
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_left_handed,
|
||||
enabled);
|
||||
@@ -279,51 +285,82 @@ update_mouse_left_handed (MetaInputSettings *input_settings,
|
||||
}
|
||||
}
|
||||
|
||||
static GSettings *
|
||||
get_settings_for_device_type (MetaInputSettings *input_settings,
|
||||
ClutterInputDeviceType type)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
switch (type)
|
||||
{
|
||||
case CLUTTER_POINTER_DEVICE:
|
||||
return priv->mouse_settings;
|
||||
case CLUTTER_TOUCHPAD_DEVICE:
|
||||
return priv->touchpad_settings;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_device_speed (MetaInputSettings *input_settings,
|
||||
GSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
ClutterInputDeviceType type)
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
gdouble speed;
|
||||
GSettings *settings;
|
||||
ConfigDoubleFunc func;
|
||||
const gchar *key = "speed";
|
||||
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
speed = g_settings_get_double (settings, "speed");
|
||||
func = META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_speed;
|
||||
|
||||
if (device)
|
||||
settings_device_set_double_setting (input_settings, device,
|
||||
input_settings_class->set_speed,
|
||||
speed);
|
||||
{
|
||||
settings = get_settings_for_device_type (input_settings,
|
||||
clutter_input_device_get_device_type (device));
|
||||
if (!settings)
|
||||
return;
|
||||
|
||||
settings_device_set_double_setting (input_settings, device, func,
|
||||
g_settings_get_double (settings, key));
|
||||
}
|
||||
else
|
||||
settings_set_double_setting (input_settings, type,
|
||||
input_settings_class->set_speed,
|
||||
speed);
|
||||
{
|
||||
settings = get_settings_for_device_type (input_settings, CLUTTER_POINTER_DEVICE);
|
||||
settings_set_double_setting (input_settings, CLUTTER_POINTER_DEVICE, func,
|
||||
g_settings_get_double (settings, key));
|
||||
settings = get_settings_for_device_type (input_settings, CLUTTER_TOUCHPAD_DEVICE);
|
||||
settings_set_double_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, func,
|
||||
g_settings_get_double (settings, key));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_device_natural_scroll (MetaInputSettings *input_settings,
|
||||
GSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
ClutterInputDeviceType type)
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
gboolean enabled;
|
||||
GSettings *settings;
|
||||
ConfigBoolFunc func;
|
||||
const gchar *key = "natural-scroll";
|
||||
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
enabled = g_settings_get_boolean (settings, "natural-scroll");
|
||||
func = META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_invert_scroll;
|
||||
|
||||
if (device)
|
||||
{
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_invert_scroll,
|
||||
enabled);
|
||||
settings = get_settings_for_device_type (input_settings,
|
||||
clutter_input_device_get_device_type (device));
|
||||
if (!settings)
|
||||
return;
|
||||
|
||||
settings_device_set_bool_setting (input_settings, device, func,
|
||||
g_settings_get_boolean (settings, key));
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_set_bool_setting (input_settings, type,
|
||||
input_settings_class->set_invert_scroll,
|
||||
enabled);
|
||||
settings = get_settings_for_device_type (input_settings, CLUTTER_POINTER_DEVICE);
|
||||
settings_set_bool_setting (input_settings, CLUTTER_POINTER_DEVICE, func,
|
||||
g_settings_get_boolean (settings, key));
|
||||
settings = get_settings_for_device_type (input_settings, CLUTTER_TOUCHPAD_DEVICE);
|
||||
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, func,
|
||||
g_settings_get_boolean (settings, key));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,6 +372,10 @@ update_touchpad_tap_enabled (MetaInputSettings *input_settings,
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gboolean enabled;
|
||||
|
||||
if (device &&
|
||||
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-to-click");
|
||||
@@ -361,6 +402,10 @@ update_touchpad_scroll_method (MetaInputSettings *input_settings,
|
||||
GDesktopTouchpadScrollMethod method;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
if (device &&
|
||||
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
method = g_settings_get_enum (priv->touchpad_settings, "scroll-method");
|
||||
@@ -387,6 +432,10 @@ update_touchpad_click_method (MetaInputSettings *input_settings,
|
||||
GDesktopTouchpadScrollMethod method;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
if (device &&
|
||||
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
method = g_settings_get_enum (priv->touchpad_settings, "click-method");
|
||||
@@ -413,6 +462,10 @@ update_touchpad_send_events (MetaInputSettings *input_settings,
|
||||
MetaInputSettingsPrivate *priv;
|
||||
GDesktopDeviceSendEvents mode;
|
||||
|
||||
if (device &&
|
||||
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
mode = g_settings_get_enum (priv->touchpad_settings, "send-events");
|
||||
@@ -455,11 +508,16 @@ update_trackball_scroll_button (MetaInputSettings *input_settings,
|
||||
MetaInputSettingsPrivate *priv;
|
||||
guint button;
|
||||
|
||||
if (device && !device_is_trackball (device))
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
button = g_settings_get_uint (priv->trackball_settings, "scroll-wheel-emulation-button");
|
||||
/* This key is 'i' in the schema but it also specifies a minimum
|
||||
* range of 0 so the cast here is safe. */
|
||||
button = (guint) g_settings_get_int (priv->trackball_settings, "scroll-wheel-emulation-button");
|
||||
|
||||
if (device && device_is_trackball (device))
|
||||
if (device)
|
||||
{
|
||||
input_settings_class->set_scroll_button (input_settings, device, button);
|
||||
}
|
||||
@@ -573,22 +631,18 @@ meta_input_settings_changed_cb (GSettings *settings,
|
||||
if (strcmp (key, "left-handed") == 0)
|
||||
update_mouse_left_handed (input_settings, NULL);
|
||||
else if (strcmp (key, "speed") == 0)
|
||||
update_device_speed (input_settings, settings, NULL,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
update_device_speed (input_settings, NULL);
|
||||
else if (strcmp (key, "natural-scroll") == 0)
|
||||
update_device_natural_scroll (input_settings, settings,
|
||||
NULL, CLUTTER_POINTER_DEVICE);
|
||||
update_device_natural_scroll (input_settings, NULL);
|
||||
}
|
||||
else if (settings == priv->touchpad_settings)
|
||||
{
|
||||
if (strcmp (key, "left-handed") == 0)
|
||||
update_touchpad_left_handed (input_settings, NULL);
|
||||
else if (strcmp (key, "speed") == 0)
|
||||
update_device_speed (input_settings, settings, NULL,
|
||||
CLUTTER_TOUCHPAD_DEVICE);
|
||||
update_device_speed (input_settings, NULL);
|
||||
else if (strcmp (key, "natural-scroll") == 0)
|
||||
update_device_natural_scroll (input_settings, settings,
|
||||
NULL, CLUTTER_TOUCHPAD_DEVICE);
|
||||
update_device_natural_scroll (input_settings, NULL);
|
||||
else if (strcmp (key, "tap-to-click") == 0)
|
||||
update_touchpad_tap_enabled (input_settings, NULL);
|
||||
else if (strcmp (key, "send-events") == 0)
|
||||
@@ -706,45 +760,35 @@ check_add_mappable_device (MetaInputSettings *input_settings,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
apply_device_settings (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
update_mouse_left_handed (input_settings, device);
|
||||
update_device_speed (input_settings, device);
|
||||
update_device_natural_scroll (input_settings, device);
|
||||
|
||||
update_touchpad_left_handed (input_settings, device);
|
||||
update_device_speed (input_settings, device);
|
||||
update_device_natural_scroll (input_settings, device);
|
||||
update_touchpad_tap_enabled (input_settings, device);
|
||||
update_touchpad_send_events (input_settings, device);
|
||||
update_touchpad_scroll_method (input_settings, device);
|
||||
update_touchpad_click_method (input_settings, device);
|
||||
|
||||
update_trackball_scroll_button (input_settings, device);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_device_added (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDevice *device,
|
||||
MetaInputSettings *input_settings)
|
||||
{
|
||||
ClutterInputDeviceType type;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
type = clutter_input_device_get_device_type (device);
|
||||
|
||||
if (type == CLUTTER_POINTER_DEVICE)
|
||||
{
|
||||
update_mouse_left_handed (input_settings, device);
|
||||
update_device_speed (input_settings, priv->mouse_settings, device, type);
|
||||
|
||||
if (device_is_trackball (device))
|
||||
update_trackball_scroll_button (input_settings, device);
|
||||
}
|
||||
else if (type == CLUTTER_TOUCHPAD_DEVICE)
|
||||
{
|
||||
update_touchpad_left_handed (input_settings, device);
|
||||
update_touchpad_tap_enabled (input_settings, device);
|
||||
update_touchpad_scroll_method (input_settings, device);
|
||||
update_touchpad_click_method (input_settings, device);
|
||||
update_touchpad_send_events (input_settings, device);
|
||||
|
||||
update_device_speed (input_settings, priv->touchpad_settings,
|
||||
device, type);
|
||||
update_device_natural_scroll (input_settings, priv->touchpad_settings,
|
||||
device, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
check_add_mappable_device (input_settings, device);
|
||||
}
|
||||
apply_device_settings (input_settings, device);
|
||||
check_add_mappable_device (input_settings, device);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -782,25 +826,9 @@ static void
|
||||
meta_input_settings_constructed (GObject *object)
|
||||
{
|
||||
MetaInputSettings *input_settings = META_INPUT_SETTINGS (object);
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
|
||||
update_mouse_left_handed (input_settings, NULL);
|
||||
|
||||
update_touchpad_left_handed (input_settings, NULL);
|
||||
update_touchpad_tap_enabled (input_settings, NULL);
|
||||
update_touchpad_send_events (input_settings, NULL);
|
||||
|
||||
update_device_natural_scroll (input_settings, priv->touchpad_settings,
|
||||
NULL, CLUTTER_TOUCHPAD_DEVICE);
|
||||
update_device_speed (input_settings, priv->touchpad_settings, NULL,
|
||||
CLUTTER_TOUCHPAD_DEVICE);
|
||||
update_device_speed (input_settings, priv->mouse_settings, NULL,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
|
||||
apply_device_settings (input_settings, NULL);
|
||||
update_keyboard_repeat (input_settings);
|
||||
|
||||
check_mappable_devices (input_settings);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ typedef struct {
|
||||
|
||||
gboolean is_primary;
|
||||
gboolean is_presentation;
|
||||
gboolean is_underscanning;
|
||||
} MetaOutputConfig;
|
||||
|
||||
typedef struct {
|
||||
@@ -82,7 +83,8 @@ struct _MetaMonitorConfig {
|
||||
gboolean current_is_for_laptop_lid;
|
||||
MetaConfiguration *previous;
|
||||
|
||||
GFile *file;
|
||||
GFile *user_file;
|
||||
GFile *system_file;
|
||||
GCancellable *save_cancellable;
|
||||
|
||||
UpClient *up_client;
|
||||
@@ -238,6 +240,7 @@ meta_monitor_config_init (MetaMonitorConfig *self)
|
||||
{
|
||||
const char *filename;
|
||||
char *path;
|
||||
const char * const *system_dirs;
|
||||
|
||||
self->configs = g_hash_table_new_full (config_hash, config_equal, NULL, (GDestroyNotify) config_unref);
|
||||
|
||||
@@ -246,9 +249,17 @@ meta_monitor_config_init (MetaMonitorConfig *self)
|
||||
filename = "monitors.xml";
|
||||
|
||||
path = g_build_filename (g_get_user_config_dir (), filename, NULL);
|
||||
self->file = g_file_new_for_path (path);
|
||||
self->user_file = g_file_new_for_path (path);
|
||||
g_free (path);
|
||||
|
||||
for (system_dirs = g_get_system_config_dirs (); !self->system_file && *system_dirs; system_dirs++)
|
||||
{
|
||||
path = g_build_filename (*system_dirs, filename, NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
self->system_file = g_file_new_for_path (path);
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
self->up_client = up_client_new ();
|
||||
self->lid_is_closed = up_client_get_lid_is_closed (self->up_client);
|
||||
|
||||
@@ -393,7 +404,8 @@ handle_start_element (GMarkupParseContext *context,
|
||||
strcmp (element_name, "reflect_x") == 0 ||
|
||||
strcmp (element_name, "reflect_y") == 0 ||
|
||||
strcmp (element_name, "primary") == 0 ||
|
||||
strcmp (element_name, "presentation") == 0) && parser->unknown_count == 0)
|
||||
strcmp (element_name, "presentation") == 0 ||
|
||||
strcmp (element_name, "underscanning") == 0) && parser->unknown_count == 0)
|
||||
{
|
||||
parser->state = STATE_OUTPUT_FIELD;
|
||||
|
||||
@@ -700,6 +712,8 @@ handle_text (GMarkupParseContext *context,
|
||||
parser->output.is_primary = read_bool (text, text_len, error);
|
||||
else if (strcmp (parser->output_field, "presentation") == 0)
|
||||
parser->output.is_presentation = read_bool (text, text_len, error);
|
||||
else if (strcmp (parser->output_field, "underscanning") == 0)
|
||||
parser->output.is_underscanning = read_bool (text, text_len, error);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
@@ -717,8 +731,8 @@ static const GMarkupParser config_parser = {
|
||||
.text = handle_text,
|
||||
};
|
||||
|
||||
static void
|
||||
meta_monitor_config_load (MetaMonitorConfig *self)
|
||||
static gboolean
|
||||
load_config_file (MetaMonitorConfig *self, GFile *file)
|
||||
{
|
||||
char *contents;
|
||||
gsize size;
|
||||
@@ -736,14 +750,12 @@ meta_monitor_config_load (MetaMonitorConfig *self)
|
||||
*/
|
||||
|
||||
error = NULL;
|
||||
ok = g_file_load_contents (self->file, NULL, &contents, &size, NULL, &error);
|
||||
ok = g_file_load_contents (file, NULL, &contents, &size, NULL, &error);
|
||||
if (!ok)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
meta_warning ("Failed to load stored monitor configuration: %s\n", error->message);
|
||||
|
||||
g_error_free (error);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset (&parser, 0, sizeof (ConfigParser));
|
||||
@@ -772,6 +784,17 @@ meta_monitor_config_load (MetaMonitorConfig *self)
|
||||
|
||||
g_markup_parse_context_free (context);
|
||||
g_free (contents);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_config_load (MetaMonitorConfig *self)
|
||||
{
|
||||
if (self->user_file && load_config_file (self, self->user_file))
|
||||
return;
|
||||
if (self->system_file && load_config_file (self, self->system_file))
|
||||
return;
|
||||
}
|
||||
|
||||
MetaMonitorConfig *
|
||||
@@ -1408,6 +1431,7 @@ init_config_from_output (MetaOutputConfig *config,
|
||||
config->transform = output->crtc->transform;
|
||||
config->is_primary = output->is_primary;
|
||||
config->is_presentation = output->is_presentation;
|
||||
config->is_underscanning = output->is_underscanning;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1598,7 +1622,8 @@ meta_monitor_config_save (MetaMonitorConfig *self)
|
||||
" <reflect_x>%s</reflect_x>\n"
|
||||
" <reflect_y>no</reflect_y>\n"
|
||||
" <primary>%s</primary>\n"
|
||||
" <presentation>%s</presentation>\n",
|
||||
" <presentation>%s</presentation>\n"
|
||||
" <underscanning>%s</underscanning>\n",
|
||||
output->rect.width,
|
||||
output->rect.height,
|
||||
refresh_rate,
|
||||
@@ -1607,7 +1632,8 @@ meta_monitor_config_save (MetaMonitorConfig *self)
|
||||
rotation_map[output->transform & 0x3],
|
||||
output->transform >= META_MONITOR_TRANSFORM_FLIPPED ? "yes" : "no",
|
||||
output->is_primary ? "yes" : "no",
|
||||
output->is_presentation ? "yes" : "no");
|
||||
output->is_presentation ? "yes" : "no",
|
||||
output->is_underscanning ? "yes" : "no");
|
||||
}
|
||||
|
||||
g_string_append (buffer, " </output>\n");
|
||||
@@ -1622,7 +1648,7 @@ meta_monitor_config_save (MetaMonitorConfig *self)
|
||||
closure->config = g_object_ref (self);
|
||||
closure->buffer = buffer;
|
||||
|
||||
g_file_replace_contents_async (self->file,
|
||||
g_file_replace_contents_async (self->user_file,
|
||||
buffer->str, buffer->len,
|
||||
NULL, /* etag */
|
||||
TRUE,
|
||||
@@ -1941,6 +1967,7 @@ meta_monitor_config_assign_crtcs (MetaConfiguration *config,
|
||||
&config->keys[i]);
|
||||
output_info->is_primary = output_config->is_primary;
|
||||
output_info->is_presentation = output_config->is_presentation;
|
||||
output_info->is_underscanning = output_config->is_underscanning;
|
||||
|
||||
g_ptr_array_add (outputs, output_info);
|
||||
}
|
||||
|
||||
@@ -132,6 +132,7 @@ struct _MetaOutput
|
||||
*/
|
||||
gboolean is_primary;
|
||||
gboolean is_presentation;
|
||||
gboolean is_underscanning;
|
||||
|
||||
gpointer driver_private;
|
||||
GDestroyNotify driver_notify;
|
||||
@@ -159,6 +160,9 @@ struct _MetaCRTC
|
||||
gboolean is_dirty;
|
||||
|
||||
MetaCursorReference *cursor;
|
||||
|
||||
gpointer driver_private;
|
||||
GDestroyNotify driver_notify;
|
||||
};
|
||||
|
||||
struct _MetaMonitorMode
|
||||
@@ -224,12 +228,13 @@ struct _MetaCRTCInfo {
|
||||
|
||||
/*
|
||||
* MetaOutputInfo:
|
||||
* this is the same as MetaOutputInfo, but for CRTCs
|
||||
* this is the same as MetaCRTCInfo, but for outputs
|
||||
*/
|
||||
struct _MetaOutputInfo {
|
||||
MetaOutput *output;
|
||||
gboolean is_primary;
|
||||
gboolean is_presentation;
|
||||
gboolean is_underscanning;
|
||||
};
|
||||
|
||||
#define META_TYPE_MONITOR_MANAGER (meta_monitor_manager_get_type ())
|
||||
@@ -370,6 +375,10 @@ gboolean meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *
|
||||
MetaOutput *output,
|
||||
gfloat matrix[6]);
|
||||
|
||||
gint meta_monitor_manager_get_monitor_at_point (MetaMonitorManager *manager,
|
||||
gfloat x,
|
||||
gfloat y);
|
||||
|
||||
/* Returns true if transform causes width and height to be inverted
|
||||
This is true for the odd transforms in the enum */
|
||||
static inline gboolean
|
||||
|
||||
@@ -264,6 +264,21 @@ meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
|
||||
g_free (old_modes);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_free_crtc_array (MetaCRTC *old_crtcs,
|
||||
int n_old_crtcs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_old_crtcs; i++)
|
||||
{
|
||||
if (old_crtcs[i].driver_notify)
|
||||
old_crtcs[i].driver_notify (&old_crtcs[i]);
|
||||
}
|
||||
|
||||
g_free (old_crtcs);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_finalize (GObject *object)
|
||||
{
|
||||
@@ -271,8 +286,8 @@ meta_monitor_manager_finalize (GObject *object)
|
||||
|
||||
meta_monitor_manager_free_output_array (manager->outputs, manager->n_outputs);
|
||||
meta_monitor_manager_free_mode_array (manager->modes, manager->n_modes);
|
||||
meta_monitor_manager_free_crtc_array (manager->crtcs, manager->n_crtcs);
|
||||
g_free (manager->monitor_infos);
|
||||
g_free (manager->crtcs);
|
||||
|
||||
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -520,6 +535,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
g_variant_new_boolean (output->is_presentation));
|
||||
g_variant_builder_add (&properties, "{sv}", "connector-type",
|
||||
g_variant_new_string (get_connector_type_name (output->connector_type)));
|
||||
g_variant_builder_add (&properties, "{sv}", "underscanning",
|
||||
g_variant_new_boolean (output->is_underscanning));
|
||||
|
||||
edid_file = manager_class->get_edid_file (manager, output);
|
||||
if (edid_file)
|
||||
@@ -808,7 +825,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_index, &properties))
|
||||
{
|
||||
MetaOutputInfo *output_info;
|
||||
gboolean primary, presentation;
|
||||
gboolean primary, presentation, underscanning;
|
||||
|
||||
if (output_index >= manager->n_outputs)
|
||||
{
|
||||
@@ -827,6 +844,9 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
if (g_variant_lookup (properties, "presentation", "b", &presentation))
|
||||
output_info->is_presentation = presentation;
|
||||
|
||||
if (g_variant_lookup (properties, "underscanning", "b", &underscanning))
|
||||
output_info->is_underscanning = underscanning;
|
||||
|
||||
g_ptr_array_add (output_infos, output_info);
|
||||
}
|
||||
|
||||
@@ -1194,23 +1214,24 @@ meta_monitor_manager_read_current_config (MetaMonitorManager *manager)
|
||||
MetaOutput *old_outputs;
|
||||
MetaCRTC *old_crtcs;
|
||||
MetaMonitorMode *old_modes;
|
||||
unsigned int n_old_outputs, n_old_modes;
|
||||
unsigned int n_old_outputs, n_old_crtcs, n_old_modes;
|
||||
|
||||
/* Some implementations of read_current use the existing information
|
||||
* we have available, so don't free the old configuration until after
|
||||
* read_current finishes. */
|
||||
old_outputs = manager->outputs;
|
||||
n_old_outputs = manager->n_outputs;
|
||||
old_crtcs = manager->crtcs;
|
||||
n_old_crtcs = manager->n_crtcs;
|
||||
old_modes = manager->modes;
|
||||
n_old_modes = manager->n_modes;
|
||||
old_crtcs = manager->crtcs;
|
||||
|
||||
manager->serial++;
|
||||
META_MONITOR_MANAGER_GET_CLASS (manager)->read_current (manager);
|
||||
|
||||
meta_monitor_manager_free_output_array (old_outputs, n_old_outputs);
|
||||
meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
|
||||
g_free (old_crtcs);
|
||||
meta_monitor_manager_free_crtc_array (old_crtcs, n_old_crtcs);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1368,3 +1389,27 @@ meta_monitor_manager_get_monitor_for_output (MetaMonitorManager *manager,
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
gint
|
||||
meta_monitor_manager_get_monitor_at_point (MetaMonitorManager *manager,
|
||||
gfloat x,
|
||||
gfloat y)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < manager->n_monitor_infos; i++)
|
||||
{
|
||||
MetaMonitorInfo *monitor = &manager->monitor_infos[i];
|
||||
int left, right, top, bottom;
|
||||
|
||||
left = monitor->rect.x;
|
||||
right = left + monitor->rect.width;
|
||||
top = monitor->rect.y;
|
||||
bottom = top + monitor->rect.height;
|
||||
|
||||
if ((x >= left) && (x < right) && (y >= top) && (y < bottom))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ typedef struct {
|
||||
|
||||
struct _MetaStagePrivate {
|
||||
MetaOverlay cursor_overlay;
|
||||
gboolean is_active;
|
||||
};
|
||||
typedef struct _MetaStagePrivate MetaStagePrivate;
|
||||
|
||||
@@ -126,15 +127,41 @@ meta_stage_paint (ClutterActor *actor)
|
||||
meta_overlay_paint (&priv->cursor_overlay);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_activate (ClutterStage *actor)
|
||||
{
|
||||
MetaStage *stage = META_STAGE (actor);
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
|
||||
CLUTTER_STAGE_CLASS (meta_stage_parent_class)->activate (actor);
|
||||
|
||||
priv->is_active = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_deactivate (ClutterStage *actor)
|
||||
{
|
||||
MetaStage *stage = META_STAGE (actor);
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
|
||||
CLUTTER_STAGE_CLASS (meta_stage_parent_class)->deactivate (actor);
|
||||
|
||||
priv->is_active = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_stage_class_init (MetaStageClass *klass)
|
||||
{
|
||||
ClutterStageClass *stage_class = (ClutterStageClass *) klass;
|
||||
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
|
||||
GObjectClass *object_class = (GObjectClass *) klass;
|
||||
|
||||
object_class->finalize = meta_stage_finalize;
|
||||
|
||||
actor_class->paint = meta_stage_paint;
|
||||
|
||||
stage_class->activate = meta_stage_activate;
|
||||
stage_class->deactivate = meta_stage_deactivate;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -195,3 +222,43 @@ meta_stage_set_cursor (MetaStage *stage,
|
||||
meta_overlay_set (&priv->cursor_overlay, texture, rect);
|
||||
queue_redraw_for_overlay (stage, &priv->cursor_overlay);
|
||||
}
|
||||
|
||||
void
|
||||
meta_stage_set_active (MetaStage *stage,
|
||||
gboolean is_active)
|
||||
{
|
||||
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
|
||||
ClutterEvent event = { 0 };
|
||||
|
||||
/* Used by the native backend to inform accessibility technologies
|
||||
* about when the stage loses and gains input focus.
|
||||
*
|
||||
* For the X11 backend, clutter transparently takes care of this
|
||||
* for us.
|
||||
*/
|
||||
|
||||
if (priv->is_active == is_active)
|
||||
return;
|
||||
|
||||
event.type = CLUTTER_STAGE_STATE;
|
||||
clutter_event_set_stage (&event, CLUTTER_STAGE (stage));
|
||||
event.stage_state.changed_mask = CLUTTER_STAGE_STATE_ACTIVATED;
|
||||
|
||||
if (is_active)
|
||||
event.stage_state.new_state = CLUTTER_STAGE_STATE_ACTIVATED;
|
||||
|
||||
/* Emitting this StageState event will result in the stage getting
|
||||
* activated or deactivated (with the activated or deactivated signal
|
||||
* getting emitted from the stage)
|
||||
*
|
||||
* FIXME: This won't update ClutterStage's own notion of its
|
||||
* activeness. For that we would need to somehow trigger a
|
||||
* _clutter_stage_update_state call, which will probably
|
||||
* require new API in clutter. In practice, nothing relies
|
||||
* on the ClutterStage's own notion of activeness when using
|
||||
* the EGL backend.
|
||||
*
|
||||
* See http://bugzilla.gnome.org/746670
|
||||
*/
|
||||
clutter_stage_event (CLUTTER_STAGE (stage), &event);
|
||||
}
|
||||
|
||||
@@ -54,6 +54,9 @@ ClutterActor *meta_stage_new (void);
|
||||
void meta_stage_set_cursor (MetaStage *stage,
|
||||
CoglTexture *texture,
|
||||
MetaRectangle *rect);
|
||||
|
||||
void meta_stage_set_active (MetaStage *stage,
|
||||
gboolean is_active);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* META_STAGE_H */
|
||||
|
||||
@@ -84,31 +84,6 @@ constrain_to_barriers (ClutterInputDevice *device,
|
||||
*
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
check_all_screen_monitors(MetaMonitorInfo *monitors,
|
||||
unsigned n_monitors,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < n_monitors; i++)
|
||||
{
|
||||
MetaMonitorInfo *monitor = &monitors[i];
|
||||
int left, right, top, bottom;
|
||||
|
||||
left = monitor->rect.x;
|
||||
right = left + monitor->rect.width;
|
||||
top = monitor->rect.y;
|
||||
bottom = top + monitor->rect.height;
|
||||
|
||||
if ((x >= left) && (x < right) && (y >= top) && (y < bottom))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
constrain_all_screen_monitors (ClutterInputDevice *device,
|
||||
MetaMonitorInfo *monitors,
|
||||
@@ -162,7 +137,6 @@ pointer_constrain_callback (ClutterInputDevice *device,
|
||||
MetaMonitorManager *monitor_manager;
|
||||
MetaMonitorInfo *monitors;
|
||||
unsigned int n_monitors;
|
||||
gboolean ret;
|
||||
|
||||
/* Constrain to barriers */
|
||||
constrain_to_barriers (device, time, new_x, new_y);
|
||||
@@ -171,57 +145,22 @@ pointer_constrain_callback (ClutterInputDevice *device,
|
||||
monitors = meta_monitor_manager_get_monitor_infos (monitor_manager, &n_monitors);
|
||||
|
||||
/* if we're moving inside a monitor, we're fine */
|
||||
ret = check_all_screen_monitors(monitors, n_monitors, *new_x, *new_y);
|
||||
if (ret == TRUE)
|
||||
if (meta_monitor_manager_get_monitor_at_point (monitor_manager, *new_x, *new_y) >= 0)
|
||||
return;
|
||||
|
||||
/* if we're trying to escape, clamp to the CRTC we're coming from */
|
||||
constrain_all_screen_monitors(device, monitors, n_monitors, new_x, new_y);
|
||||
}
|
||||
|
||||
static void
|
||||
on_monitors_changed (MetaMonitorManager *monitor_manager,
|
||||
MetaBackend *backend)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
ClutterInputDevice *device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
|
||||
MetaMonitorInfo *monitors, *primary;
|
||||
unsigned int n_monitors;
|
||||
ClutterPoint point;
|
||||
|
||||
if (!clutter_input_device_get_coords (device, NULL, &point))
|
||||
return;
|
||||
|
||||
monitors = meta_monitor_manager_get_monitor_infos (monitor_manager, &n_monitors);
|
||||
|
||||
/* if we're inside a monitor, we're fine */
|
||||
if (check_all_screen_monitors (monitors, n_monitors, point.x, point.y))
|
||||
return;
|
||||
|
||||
/* warp the pointer to the primary monitor so it isn't lost */
|
||||
primary = &monitors[meta_monitor_manager_get_primary_index (monitor_manager)];
|
||||
meta_backend_warp_pointer (backend,
|
||||
primary->rect.x + primary->rect.width / 2,
|
||||
primary->rect.y + primary->rect.height / 2);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_native_post_init (MetaBackend *backend)
|
||||
{
|
||||
MetaMonitorManager *monitor_manager;
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
|
||||
META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend);
|
||||
|
||||
clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback,
|
||||
NULL, NULL);
|
||||
|
||||
monitor_manager = meta_backend_get_monitor_manager (backend);
|
||||
g_signal_connect_object (monitor_manager, "monitors-changed",
|
||||
G_CALLBACK (on_monitors_changed), backend, G_CONNECT_AFTER);
|
||||
|
||||
/* make sure the pointer is in the visible area after init */
|
||||
on_monitors_changed (monitor_manager, backend);
|
||||
}
|
||||
|
||||
static MetaIdleMonitor *
|
||||
|
||||
@@ -169,10 +169,10 @@ meta_input_settings_native_set_scroll_method (MetaInputSettings *sett
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_EDGE_SCROLLING:
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_TWO_FINGER_SCROLLING:
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE;
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
|
||||
@@ -57,6 +57,12 @@ typedef struct {
|
||||
uint32_t edid_blob_id;
|
||||
} MetaOutputKms;
|
||||
|
||||
typedef struct {
|
||||
uint32_t underscan_prop_id;
|
||||
uint32_t underscan_hborder_prop_id;
|
||||
uint32_t underscan_vborder_prop_id;
|
||||
} MetaCRTCKms;
|
||||
|
||||
struct _MetaMonitorManagerKms
|
||||
{
|
||||
MetaMonitorManager parent_instance;
|
||||
@@ -137,6 +143,12 @@ meta_monitor_mode_destroy_notify (MetaMonitorMode *output)
|
||||
g_slice_free (drmModeModeInfo, output->driver_private);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_destroy_notify (MetaCRTC *crtc)
|
||||
{
|
||||
g_free (crtc->driver_private);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drm_mode_equal (gconstpointer one,
|
||||
gconstpointer two)
|
||||
@@ -181,29 +193,57 @@ drm_mode_hash (gconstpointer ptr)
|
||||
}
|
||||
|
||||
static void
|
||||
find_properties (MetaMonitorManagerKms *manager_kms,
|
||||
MetaOutputKms *output_kms)
|
||||
find_connector_properties (MetaMonitorManagerKms *manager_kms,
|
||||
MetaOutputKms *output_kms)
|
||||
{
|
||||
drmModePropertyPtr prop;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < output_kms->connector->count_props; i++)
|
||||
{
|
||||
prop = drmModeGetProperty (manager_kms->fd, output_kms->connector->props[i]);
|
||||
drmModePropertyPtr prop = drmModeGetProperty (manager_kms->fd, output_kms->connector->props[i]);
|
||||
if (!prop)
|
||||
continue;
|
||||
|
||||
if ((prop->flags & DRM_MODE_PROP_ENUM) &&
|
||||
strcmp(prop->name, "DPMS") == 0)
|
||||
if ((prop->flags & DRM_MODE_PROP_ENUM) && strcmp (prop->name, "DPMS") == 0)
|
||||
output_kms->dpms_prop_id = prop->prop_id;
|
||||
else if ((prop->flags & DRM_MODE_PROP_BLOB) &&
|
||||
strcmp (prop->name, "EDID") == 0)
|
||||
else if ((prop->flags & DRM_MODE_PROP_BLOB) && strcmp (prop->name, "EDID") == 0)
|
||||
output_kms->edid_blob_id = output_kms->connector->prop_values[i];
|
||||
|
||||
drmModeFreeProperty (prop);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
find_crtc_properties (MetaMonitorManagerKms *manager_kms,
|
||||
MetaCRTC *meta_crtc)
|
||||
{
|
||||
MetaCRTCKms *crtc_kms;
|
||||
drmModeObjectPropertiesPtr props;
|
||||
size_t i;
|
||||
|
||||
crtc_kms = meta_crtc->driver_private;
|
||||
|
||||
props = drmModeObjectGetProperties (manager_kms->fd, meta_crtc->crtc_id, DRM_MODE_OBJECT_CRTC);
|
||||
if (!props)
|
||||
return;
|
||||
|
||||
for (i = 0; i < props->count_props; i++)
|
||||
{
|
||||
drmModePropertyPtr prop = drmModeGetProperty (manager_kms->fd, props->props[i]);
|
||||
if (!prop)
|
||||
continue;
|
||||
|
||||
if ((prop->flags & DRM_MODE_PROP_ENUM) && strcmp (prop->name, "underscan") == 0)
|
||||
crtc_kms->underscan_prop_id = prop->prop_id;
|
||||
else if ((prop->flags & DRM_MODE_PROP_RANGE) && strcmp (prop->name, "underscan hborder") == 0)
|
||||
crtc_kms->underscan_hborder_prop_id = prop->prop_id;
|
||||
else if ((prop->flags & DRM_MODE_PROP_RANGE) && strcmp (prop->name, "underscan vborder") == 0)
|
||||
crtc_kms->underscan_vborder_prop_id = prop->prop_id;
|
||||
|
||||
drmModeFreeProperty (prop);
|
||||
}
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
read_output_edid (MetaMonitorManagerKms *manager_kms,
|
||||
MetaOutput *output)
|
||||
@@ -442,6 +482,10 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
height = MAX (height, meta_crtc->rect.y + meta_crtc->rect.height);
|
||||
}
|
||||
|
||||
meta_crtc->driver_private = g_new0 (MetaCRTCKms, 1);
|
||||
meta_crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify;
|
||||
find_crtc_properties (manager_kms, meta_crtc);
|
||||
|
||||
drmModeFreeCrtc (crtc);
|
||||
}
|
||||
|
||||
@@ -567,7 +611,7 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
meta_output->is_presentation = FALSE;
|
||||
}
|
||||
|
||||
find_properties (manager_kms, output_kms);
|
||||
find_connector_properties (manager_kms, output_kms);
|
||||
|
||||
edid = read_output_edid (manager_kms, meta_output);
|
||||
meta_output_parse_edid (meta_output, edid);
|
||||
@@ -723,8 +767,9 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
|
||||
|
||||
if (output_kms->dpms_prop_id != 0)
|
||||
{
|
||||
int ok = drmModeConnectorSetProperty(manager_kms->fd, meta_output->winsys_id,
|
||||
output_kms->dpms_prop_id, state);
|
||||
int ok = drmModeObjectSetProperty (manager_kms->fd, meta_output->winsys_id,
|
||||
DRM_MODE_OBJECT_CONNECTOR,
|
||||
output_kms->dpms_prop_id, state);
|
||||
|
||||
if (ok < 0)
|
||||
meta_warning ("Failed to set power save mode for output %s: %s\n",
|
||||
@@ -748,6 +793,48 @@ crtc_free (CoglKmsCrtc *crtc)
|
||||
g_slice_free (CoglKmsCrtc, crtc);
|
||||
}
|
||||
|
||||
static void
|
||||
set_underscan (MetaMonitorManagerKms *manager_kms,
|
||||
MetaOutput *output)
|
||||
{
|
||||
if (!output->crtc)
|
||||
return;
|
||||
|
||||
MetaCRTC *crtc = output->crtc;
|
||||
MetaCRTCKms *crtc_kms = crtc->driver_private;
|
||||
if (!crtc_kms->underscan_prop_id)
|
||||
return;
|
||||
|
||||
if (output->is_underscanning)
|
||||
{
|
||||
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
|
||||
DRM_MODE_OBJECT_CRTC,
|
||||
crtc_kms->underscan_prop_id, (uint64_t) 1);
|
||||
|
||||
if (crtc_kms->underscan_hborder_prop_id)
|
||||
{
|
||||
uint64_t value = crtc->current_mode->width * 0.05;
|
||||
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
|
||||
DRM_MODE_OBJECT_CRTC,
|
||||
crtc_kms->underscan_hborder_prop_id, value);
|
||||
}
|
||||
if (crtc_kms->underscan_vborder_prop_id)
|
||||
{
|
||||
uint64_t value = crtc->current_mode->height * 0.05;
|
||||
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
|
||||
DRM_MODE_OBJECT_CRTC,
|
||||
crtc_kms->underscan_vborder_prop_id, value);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
|
||||
DRM_MODE_OBJECT_CRTC,
|
||||
crtc_kms->underscan_prop_id, (uint64_t) 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
MetaCRTCInfo **crtcs,
|
||||
@@ -755,6 +842,7 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
ClutterBackend *backend;
|
||||
CoglContext *cogl_context;
|
||||
CoglDisplay *cogl_display;
|
||||
@@ -900,6 +988,9 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
|
||||
output->is_primary = output_info->is_primary;
|
||||
output->is_presentation = output_info->is_presentation;
|
||||
output->is_underscanning = output_info->is_underscanning;
|
||||
|
||||
set_underscan (manager_kms, output);
|
||||
}
|
||||
|
||||
/* Disable outputs not mentioned in the list */
|
||||
|
||||
@@ -180,7 +180,7 @@ meta_input_settings_x11_set_scroll_button (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
guint button)
|
||||
{
|
||||
change_property (device, "libinput Scroll Method Enabled",
|
||||
change_property (device, "libinput Button Scrolling Button",
|
||||
XA_INTEGER, 32, &button, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -225,6 +225,38 @@ output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
return output_get_boolean_property (manager_xrandr, output, "_MUTTER_PRESENTATION_OUTPUT");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
gboolean value = FALSE;
|
||||
Atom atom, actual_type;
|
||||
int actual_format;
|
||||
unsigned long nitems, bytes_after;
|
||||
unsigned char *buffer;
|
||||
char *str;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "underscan", False);
|
||||
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
atom,
|
||||
0, G_MAXLONG, False, False, XA_ATOM,
|
||||
&actual_type, &actual_format,
|
||||
&nitems, &bytes_after, &buffer);
|
||||
|
||||
if (actual_type != XA_ATOM || actual_format != 32 ||
|
||||
nitems < 1)
|
||||
goto out;
|
||||
|
||||
str = XGetAtomName (manager_xrandr->xdisplay, *(Atom *)buffer);
|
||||
value = !strcmp(str, "on");
|
||||
XFree (str);
|
||||
|
||||
out:
|
||||
XFree (buffer);
|
||||
return value;
|
||||
}
|
||||
|
||||
static int
|
||||
normalize_backlight (MetaOutput *output,
|
||||
int hw_value)
|
||||
@@ -756,6 +788,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
|
||||
meta_output->is_primary = ((XID)meta_output->winsys_id == primary_output);
|
||||
meta_output->is_presentation = output_get_presentation_xrandr (manager_xrandr, meta_output);
|
||||
meta_output->is_underscanning = output_get_underscanning_xrandr (manager_xrandr, meta_output);
|
||||
output_get_backlight_limits_xrandr (manager_xrandr, meta_output);
|
||||
|
||||
if (!(meta_output->backlight_min == 0 && meta_output->backlight_max == 0))
|
||||
@@ -876,6 +909,49 @@ output_set_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
(unsigned char*) &value, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
output_set_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output,
|
||||
gboolean underscanning)
|
||||
{
|
||||
Atom prop, valueatom;
|
||||
const char *value;
|
||||
|
||||
prop = XInternAtom (manager_xrandr->xdisplay, "underscan", False);
|
||||
|
||||
value = underscanning ? "on" : "off";
|
||||
valueatom = XInternAtom (manager_xrandr->xdisplay, value, False);
|
||||
XRRChangeOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
prop,
|
||||
XA_ATOM, 32, PropModeReplace,
|
||||
(unsigned char*) &valueatom, 1);
|
||||
|
||||
/* Configure the border at the same time. Currently, we use a
|
||||
* 5% of the width/height of the mode. In the future, we should
|
||||
* make the border configurable. */
|
||||
if (underscanning)
|
||||
{
|
||||
uint32_t border_value;
|
||||
|
||||
prop = XInternAtom (manager_xrandr->xdisplay, "underscan hborder", False);
|
||||
border_value = output->crtc->current_mode->width * 0.05;
|
||||
XRRChangeOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
prop,
|
||||
XA_INTEGER, 32, PropModeReplace,
|
||||
(unsigned char *) &border_value, 1);
|
||||
|
||||
prop = XInternAtom (manager_xrandr->xdisplay, "underscan vborder", False);
|
||||
border_value = output->crtc->current_mode->height * 0.05;
|
||||
XRRChangeOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
prop,
|
||||
XA_INTEGER, 32, PropModeReplace,
|
||||
(unsigned char *) &border_value, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
MetaCRTCInfo **crtcs,
|
||||
@@ -1071,8 +1147,13 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
output_info->output,
|
||||
output_info->is_presentation);
|
||||
|
||||
output_set_underscanning_xrandr (manager_xrandr,
|
||||
output_info->output,
|
||||
output_info->is_underscanning);
|
||||
|
||||
output->is_primary = output_info->is_primary;
|
||||
output->is_presentation = output_info->is_presentation;
|
||||
output->is_underscanning = output_info->is_underscanning;
|
||||
}
|
||||
|
||||
/* Disable outputs not mentioned in the list */
|
||||
|
||||
@@ -71,6 +71,8 @@ enum
|
||||
|
||||
G_DEFINE_TYPE (MetaBackground, meta_background, G_TYPE_OBJECT)
|
||||
|
||||
static GSList *all_backgrounds = NULL;
|
||||
|
||||
static void
|
||||
free_fbos (MetaBackground *self)
|
||||
{
|
||||
@@ -305,6 +307,8 @@ meta_background_dispose (GObject *object)
|
||||
static void
|
||||
meta_background_finalize (GObject *object)
|
||||
{
|
||||
all_backgrounds = g_slist_remove (all_backgrounds, object);
|
||||
|
||||
G_OBJECT_CLASS (meta_background_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -347,6 +351,7 @@ meta_background_init (MetaBackground *self)
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||
META_TYPE_BACKGROUND,
|
||||
MetaBackgroundPrivate);
|
||||
all_backgrounds = g_slist_prepend (all_backgrounds, self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -913,3 +918,12 @@ meta_background_set_blend (MetaBackground *self,
|
||||
free_wallpaper_texture (self);
|
||||
mark_changed (self);
|
||||
}
|
||||
|
||||
void
|
||||
meta_background_refresh_all (void)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = all_backgrounds; l; l = l->next)
|
||||
mark_changed (l->data);
|
||||
}
|
||||
|
||||
@@ -217,19 +217,6 @@ meta_core_show_window_menu_for_rect (Display *xdisplay,
|
||||
meta_window_show_menu_for_rect (window, menu, rect);
|
||||
}
|
||||
|
||||
const char*
|
||||
meta_core_get_workspace_name_with_index (Display *xdisplay,
|
||||
Window xroot,
|
||||
int index)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaWorkspace *workspace;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
workspace = meta_screen_get_workspace_by_index (display->screen, index);
|
||||
return workspace ? meta_workspace_get_name (workspace) : NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_core_begin_grab_op (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
|
||||
@@ -47,9 +47,6 @@ void meta_core_change_workspace (Display *xdisplay,
|
||||
|
||||
int meta_core_get_frame_workspace (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
|
||||
Window xroot,
|
||||
int index);
|
||||
|
||||
void meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
|
||||
@@ -121,7 +121,7 @@ struct _MetaDisplay
|
||||
* class is constructed.
|
||||
*/
|
||||
#define item(x) Atom atom_##x;
|
||||
#include <meta/atomnames.h>
|
||||
#include <x11/atomnames.h>
|
||||
#undef item
|
||||
|
||||
/* The window and serial of the most recent FocusIn event. */
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <meta/meta-backend.h>
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "backends/meta-stage.h"
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
|
||||
#ifdef HAVE_RANDR
|
||||
@@ -548,7 +549,7 @@ meta_display_open (void)
|
||||
/* A list of all atom names, so that we can intern them in one go. */
|
||||
char *atom_names[] = {
|
||||
#define item(x) #x,
|
||||
#include <meta/atomnames.h>
|
||||
#include <x11/atomnames.h>
|
||||
#undef item
|
||||
};
|
||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||
@@ -609,7 +610,7 @@ meta_display_open (void)
|
||||
{
|
||||
int i = 0;
|
||||
#define item(x) display->atom_##x = atoms[i++];
|
||||
#include <meta/atomnames.h>
|
||||
#include <x11/atomnames.h>
|
||||
#undef item
|
||||
}
|
||||
|
||||
@@ -1411,6 +1412,8 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display)
|
||||
#ifdef HAVE_WAYLAND
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaWindow *focus_window = NULL;
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaStage *stage = META_STAGE (meta_backend_get_stage (backend));
|
||||
|
||||
if (!meta_display_windows_are_interactable (display))
|
||||
focus_window = NULL;
|
||||
@@ -1421,6 +1424,7 @@ meta_display_sync_wayland_input_focus (MetaDisplay *display)
|
||||
else
|
||||
meta_topic (META_DEBUG_FOCUS, "Focus change has no effect, because there is no matching wayland surface");
|
||||
|
||||
meta_stage_set_active (stage, focus_window == NULL);
|
||||
meta_wayland_compositor_set_input_focus (compositor, focus_window);
|
||||
|
||||
meta_wayland_seat_repick (compositor->seat);
|
||||
|
||||
@@ -93,6 +93,15 @@ handle_idletime_for_event (const ClutterEvent *event)
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
if (event->any.flags & CLUTTER_EVENT_FLAG_SYNTHETIC ||
|
||||
event->type == CLUTTER_ENTER ||
|
||||
event->type == CLUTTER_LEAVE ||
|
||||
event->type == CLUTTER_STAGE_STATE ||
|
||||
event->type == CLUTTER_DESTROY_NOTIFY ||
|
||||
event->type == CLUTTER_CLIENT_MESSAGE ||
|
||||
event->type == CLUTTER_DELETE)
|
||||
return;
|
||||
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
|
||||
core_monitor = meta_idle_monitor_get_core ();
|
||||
@@ -192,6 +201,7 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
{
|
||||
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
meta_cursor_tracker_update_position (tracker, event->motion.x, event->motion.y);
|
||||
display->monitor_cache_invalidated = TRUE;
|
||||
}
|
||||
|
||||
handle_idletime_for_event (event);
|
||||
|
||||
@@ -37,7 +37,6 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
{
|
||||
MetaFrame *frame;
|
||||
XSetWindowAttributes attrs;
|
||||
Visual *visual;
|
||||
gulong create_serial;
|
||||
|
||||
if (window->frame)
|
||||
@@ -58,37 +57,14 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
frame->is_flashing = FALSE;
|
||||
frame->borders_cached = FALSE;
|
||||
|
||||
meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
|
||||
window->desc,
|
||||
XVisualIDFromVisual (window->xvisual) ==
|
||||
XVisualIDFromVisual (window->screen->default_xvisual) ?
|
||||
"is" : "is not",
|
||||
window->depth, window->screen->default_depth);
|
||||
meta_verbose ("Frame geometry %d,%d %dx%d\n",
|
||||
frame->rect.x, frame->rect.y,
|
||||
frame->rect.width, frame->rect.height);
|
||||
|
||||
/* Default depth/visual handles clients with weird visuals; they can
|
||||
* always be children of the root depth/visual obviously, but
|
||||
* e.g. DRI games can't be children of a parent that has the same
|
||||
* visual as the client. NULL means default visual.
|
||||
*
|
||||
* We look for an ARGB visual if we can find one, otherwise use
|
||||
* the default of NULL.
|
||||
*/
|
||||
|
||||
/* Special case for depth 32 windows (assumed to be ARGB),
|
||||
* we use the window's visual. Otherwise we just use the system visual.
|
||||
*/
|
||||
if (window->depth == 32)
|
||||
visual = window->xvisual;
|
||||
else
|
||||
visual = NULL;
|
||||
|
||||
frame->ui_frame = meta_ui_create_frame (window->screen->ui,
|
||||
window->display->xdisplay,
|
||||
frame->window,
|
||||
visual,
|
||||
window->xvisual,
|
||||
frame->rect.x,
|
||||
frame->rect.y,
|
||||
frame->rect.width,
|
||||
|
||||
@@ -2113,12 +2113,6 @@ meta_prefs_add_keybinding (const char *name,
|
||||
pref->combos = NULL;
|
||||
pref->builtin = (flags & META_KEY_BINDING_BUILTIN) != 0;
|
||||
|
||||
strokes = g_settings_get_strv (settings, name);
|
||||
update_binding (pref, strokes);
|
||||
g_strfreev (strokes);
|
||||
|
||||
g_hash_table_insert (key_bindings, g_strdup (name), pref);
|
||||
|
||||
if (pref->builtin)
|
||||
{
|
||||
if (g_object_get_data (G_OBJECT (settings), "changed-signal") == NULL)
|
||||
@@ -2140,6 +2134,12 @@ meta_prefs_add_keybinding (const char *name,
|
||||
queue_changed (META_PREF_KEYBINDINGS);
|
||||
}
|
||||
|
||||
strokes = g_settings_get_strv (settings, name);
|
||||
update_binding (pref, strokes);
|
||||
g_strfreev (strokes);
|
||||
|
||||
g_hash_table_insert (key_bindings, g_strdup (name), pref);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,14 +41,6 @@
|
||||
typedef void (* MetaScreenWindowFunc) (MetaWindow *window,
|
||||
gpointer user_data);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_SCREEN_UP,
|
||||
META_SCREEN_DOWN,
|
||||
META_SCREEN_LEFT,
|
||||
META_SCREEN_RIGHT
|
||||
} MetaScreenDirection;
|
||||
|
||||
#define META_WIREFRAME_XOR_LINE_WIDTH 2
|
||||
|
||||
struct _MetaScreen
|
||||
|
||||
@@ -294,7 +294,7 @@ set_supported_hint (MetaScreen *screen)
|
||||
Atom atoms[] = {
|
||||
#define EWMH_ATOMS_ONLY
|
||||
#define item(x) screen->display->atom_##x,
|
||||
#include <meta/atomnames.h>
|
||||
#include <x11/atomnames.h>
|
||||
#undef item
|
||||
#undef EWMH_ATOMS_ONLY
|
||||
|
||||
@@ -1490,6 +1490,16 @@ meta_screen_get_monitor_neighbor (MetaScreen *screen,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
meta_screen_get_monitor_neighbor_index (MetaScreen *screen,
|
||||
int which_monitor,
|
||||
MetaScreenDirection direction)
|
||||
{
|
||||
const MetaMonitorInfo *monitor;
|
||||
monitor = meta_screen_get_monitor_neighbor (screen, which_monitor, direction);
|
||||
return monitor ? monitor->number : -1;
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_get_natural_monitor_list (MetaScreen *screen,
|
||||
int** monitors_list,
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
#include "x11/xprops.h"
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "wayland/window-wayland.h"
|
||||
#include "wayland/meta-window-wayland.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ struct _MetaBackground
|
||||
MetaBackgroundPrivate *priv;
|
||||
};
|
||||
|
||||
void meta_background_refresh_all (void);
|
||||
|
||||
GType meta_background_get_type (void);
|
||||
|
||||
MetaBackground *meta_background_new (MetaScreen *screen);
|
||||
|
||||
@@ -66,6 +66,21 @@ int meta_screen_get_active_workspace_index (MetaScreen *screen);
|
||||
|
||||
MetaWorkspace * meta_screen_get_active_workspace (MetaScreen *screen);
|
||||
|
||||
/**
|
||||
* MetaScreenDirection:
|
||||
* @META_SCREEN_UP: up
|
||||
* @META_SCREEN_DOWN: down
|
||||
* @META_SCREEN_LEFT: left
|
||||
* @META_SCREEN_RIGHT: right
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
META_SCREEN_UP,
|
||||
META_SCREEN_DOWN,
|
||||
META_SCREEN_LEFT,
|
||||
META_SCREEN_RIGHT
|
||||
} MetaScreenDirection;
|
||||
|
||||
int meta_screen_get_n_monitors (MetaScreen *screen);
|
||||
int meta_screen_get_primary_monitor (MetaScreen *screen);
|
||||
int meta_screen_get_current_monitor (MetaScreen *screen);
|
||||
@@ -82,6 +97,10 @@ gboolean meta_screen_get_monitor_in_fullscreen (MetaScreen *screen,
|
||||
int meta_screen_get_monitor_index_for_rect (MetaScreen *screen,
|
||||
MetaRectangle *rect);
|
||||
|
||||
int meta_screen_get_monitor_neighbor_index (MetaScreen *screen,
|
||||
int which_monitor,
|
||||
MetaScreenDirection dir);
|
||||
|
||||
void meta_screen_focus_default_window (MetaScreen *screen,
|
||||
guint32 timestamp);
|
||||
|
||||
|
||||
@@ -411,6 +411,11 @@ meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info)
|
||||
void
|
||||
meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
g_signal_handlers_disconnect_by_func (backend, on_keymap_changed, keyboard);
|
||||
g_signal_handlers_disconnect_by_func (backend, on_keymap_layout_group_changed, keyboard);
|
||||
|
||||
meta_wayland_keyboard_set_focus (keyboard, NULL);
|
||||
meta_wayland_xkb_info_destroy (&keyboard->xkb_info);
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
int display_index;
|
||||
char *lockfile;
|
||||
char *lock_file;
|
||||
int abstract_fd;
|
||||
int unix_fd;
|
||||
pid_t pid;
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "display-private.h"
|
||||
#include "window-private.h"
|
||||
#include "window-wayland.h"
|
||||
#include "meta-window-wayland.h"
|
||||
|
||||
#include "compositor/region-utils.h"
|
||||
|
||||
@@ -121,24 +121,30 @@ static void
|
||||
surface_process_damage (MetaWaylandSurface *surface,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
unsigned int buffer_width;
|
||||
unsigned int buffer_height;
|
||||
cairo_rectangle_int_t surface_rect;
|
||||
cairo_region_t *scaled_region;
|
||||
cairo_rectangle_int_t buffer_rect;
|
||||
int i, n_rectangles;
|
||||
|
||||
if (!surface->buffer)
|
||||
return;
|
||||
|
||||
buffer_rect.x = 0;
|
||||
buffer_rect.y = 0;
|
||||
buffer_rect.width = cogl_texture_get_width (surface->buffer->texture);
|
||||
buffer_rect.height = cogl_texture_get_height (surface->buffer->texture);
|
||||
/* Intersect the damage region with the surface region before scaling in
|
||||
* order to avoid integer overflow when scaling a damage region is too large
|
||||
* (for example INT32_MAX which mesa passes). */
|
||||
buffer_width = cogl_texture_get_width (surface->buffer->texture);
|
||||
buffer_height = cogl_texture_get_height (surface->buffer->texture);
|
||||
surface_rect = (cairo_rectangle_int_t) {
|
||||
.width = buffer_width / surface->scale,
|
||||
.height = buffer_height / surface->scale,
|
||||
};
|
||||
cairo_region_intersect_rectangle (region, &surface_rect);
|
||||
|
||||
/* The damage region must be in the same coordinate space as the buffer,
|
||||
* i.e. scaled with surface->scale. */
|
||||
scaled_region = meta_region_scale (region, surface->scale);
|
||||
|
||||
cairo_region_intersect_rectangle (scaled_region, &buffer_rect);
|
||||
|
||||
/* First update the buffer. */
|
||||
meta_wayland_buffer_process_damage (surface->buffer, scaled_region);
|
||||
|
||||
@@ -209,19 +215,52 @@ calculate_surface_window_geometry (MetaWaylandSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_window (MetaWaylandSurface *surface)
|
||||
{
|
||||
if (surface->window)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
guint32 timestamp = meta_display_get_current_time_roundtrip (display);
|
||||
|
||||
meta_window_unmanage (surface->window, timestamp);
|
||||
}
|
||||
|
||||
g_assert (surface->window == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
toplevel_surface_commit (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWindow *window = surface->window;
|
||||
|
||||
/* Sanity check. */
|
||||
if (surface->buffer == NULL)
|
||||
if (surface->role == META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE)
|
||||
{
|
||||
wl_resource_post_error (surface->resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"Cannot commit a NULL buffer to an xdg_surface");
|
||||
return;
|
||||
/* For wl_shell, it's equivalent to an unmap. Semantics
|
||||
* are poorly defined, so we can choose some that are
|
||||
* convenient for us. */
|
||||
if (surface->buffer && !window)
|
||||
{
|
||||
window = meta_window_wayland_new (meta_get_display (), surface);
|
||||
meta_wayland_surface_set_window (surface, window);
|
||||
}
|
||||
else if (surface->buffer == NULL && window)
|
||||
{
|
||||
destroy_window (surface);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (surface->buffer == NULL)
|
||||
{
|
||||
/* XDG surfaces can't commit NULL buffers */
|
||||
wl_resource_post_error (surface->resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"Cannot commit a NULL buffer to an xdg_surface");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* We resize X based surfaces according to X events */
|
||||
@@ -355,33 +394,95 @@ subsurface_surface_commit (MetaWaylandSurface *surface,
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
subsurface_parent_surface_committed (MetaWaylandSurface *surface);
|
||||
|
||||
static void
|
||||
parent_surface_committed (gpointer data, gpointer user_data)
|
||||
/* A non-subsurface is always desynchronized.
|
||||
*
|
||||
* A subsurface is effectively synchronized if either its parent is
|
||||
* synchronized or itself is in synchronized mode. */
|
||||
static gboolean
|
||||
is_surface_effectively_synchronized (MetaWaylandSurface *surface)
|
||||
{
|
||||
subsurface_parent_surface_committed (data);
|
||||
if (surface->wl_subsurface == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (surface->sub.synchronous)
|
||||
return TRUE;
|
||||
else
|
||||
return is_surface_effectively_synchronized (surface->sub.parent);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
commit_pending_state (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
apply_pending_state (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending);
|
||||
|
||||
static void
|
||||
parent_surface_state_applied (gpointer data, gpointer user_data)
|
||||
{
|
||||
MetaWaylandSurface *surface = data;
|
||||
|
||||
if (surface->sub.pending_pos)
|
||||
{
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor),
|
||||
surface->sub.pending_x,
|
||||
surface->sub.pending_y);
|
||||
surface->sub.pending_pos = FALSE;
|
||||
}
|
||||
|
||||
if (surface->sub.pending_placement_ops)
|
||||
{
|
||||
GSList *it;
|
||||
for (it = surface->sub.pending_placement_ops; it; it = it->next)
|
||||
{
|
||||
MetaWaylandSubsurfacePlacementOp *op = it->data;
|
||||
ClutterActor *surface_actor;
|
||||
ClutterActor *parent_actor;
|
||||
ClutterActor *sibling_actor;
|
||||
|
||||
if (!op->sibling)
|
||||
{
|
||||
g_slice_free (MetaWaylandSubsurfacePlacementOp, op);
|
||||
continue;
|
||||
}
|
||||
|
||||
surface_actor = CLUTTER_ACTOR (surface->surface_actor);
|
||||
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->sub.parent));
|
||||
sibling_actor = CLUTTER_ACTOR (op->sibling->surface_actor);
|
||||
|
||||
switch (op->placement)
|
||||
{
|
||||
case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
|
||||
clutter_actor_set_child_above_sibling (parent_actor,
|
||||
surface_actor,
|
||||
sibling_actor);
|
||||
break;
|
||||
case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
|
||||
clutter_actor_set_child_below_sibling (parent_actor,
|
||||
surface_actor,
|
||||
sibling_actor);
|
||||
break;
|
||||
}
|
||||
|
||||
wl_list_remove (&op->sibling_destroy_listener.link);
|
||||
g_slice_free (MetaWaylandSubsurfacePlacementOp, op);
|
||||
}
|
||||
|
||||
g_slist_free (surface->sub.pending_placement_ops);
|
||||
surface->sub.pending_placement_ops = NULL;
|
||||
}
|
||||
|
||||
if (is_surface_effectively_synchronized (surface))
|
||||
apply_pending_state (surface, &surface->sub.pending);
|
||||
}
|
||||
|
||||
static void
|
||||
apply_pending_state (MetaWaylandSurface *surface,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = surface->compositor;
|
||||
|
||||
/* If this surface is a subsurface in in synchronous mode, commit
|
||||
* has a special-case and should not apply the pending state immediately.
|
||||
*
|
||||
* Instead, we move it to another pending state, which will be
|
||||
* actually committed when the parent commits.
|
||||
*/
|
||||
if (surface->sub.synchronous)
|
||||
{
|
||||
move_pending_state (pending, &surface->sub.pending);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pending->newly_attached)
|
||||
{
|
||||
surface_set_buffer (surface, pending->buffer);
|
||||
@@ -432,15 +533,26 @@ commit_pending_state (MetaWaylandSurface *surface,
|
||||
else if (surface->wl_subsurface)
|
||||
subsurface_surface_commit (surface, pending);
|
||||
|
||||
g_list_foreach (surface->subsurfaces, parent_surface_committed, NULL);
|
||||
|
||||
pending_state_reset (pending);
|
||||
|
||||
g_list_foreach (surface->subsurfaces, parent_surface_state_applied, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_commit (MetaWaylandSurface *surface)
|
||||
{
|
||||
commit_pending_state (surface, &surface->pending);
|
||||
/*
|
||||
* If this is a sub-surface and it is in effective synchronous mode, only
|
||||
* cache the pending surface state until either one of the following two
|
||||
* scenarios happens:
|
||||
* 1) Its parent surface gets its state applied.
|
||||
* 2) Its mode changes from synchronized to desynchronized and its parent
|
||||
* surface is in effective desynchronized mode.
|
||||
*/
|
||||
if (is_surface_effectively_synchronized (surface))
|
||||
move_pending_state (&surface->pending, &surface->sub.pending);
|
||||
else
|
||||
apply_pending_state (surface, &surface->pending);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -644,20 +756,6 @@ meta_wayland_surface_set_window (MetaWaylandSurface *surface,
|
||||
sync_reactive (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_window (MetaWaylandSurface *surface)
|
||||
{
|
||||
if (surface->window)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
guint32 timestamp = meta_display_get_current_time_roundtrip (display);
|
||||
|
||||
meta_window_unmanage (surface->window, timestamp);
|
||||
}
|
||||
|
||||
g_assert (surface->window == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
wl_surface_destructor (struct wl_resource *resource)
|
||||
{
|
||||
@@ -1427,7 +1525,6 @@ wl_shell_get_shell_surface (struct wl_client *client,
|
||||
struct wl_resource *surface_resource)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||
MetaWindow *window;
|
||||
|
||||
if (surface->wl_shell_surface != NULL)
|
||||
{
|
||||
@@ -1445,9 +1542,6 @@ wl_shell_get_shell_surface (struct wl_client *client,
|
||||
|
||||
surface->wl_shell_surface = wl_resource_create (client, &wl_shell_surface_interface, wl_resource_get_version (resource), id);
|
||||
wl_resource_set_implementation (surface->wl_shell_surface, &meta_wayland_wl_shell_surface_interface, surface, wl_shell_surface_destructor);
|
||||
|
||||
window = meta_window_wayland_new (meta_get_display (), surface);
|
||||
meta_wayland_surface_set_window (surface, window);
|
||||
}
|
||||
|
||||
static const struct wl_shell_interface meta_wayland_wl_shell_interface = {
|
||||
@@ -1475,14 +1569,14 @@ gtk_surface_destructor (struct wl_resource *resource)
|
||||
}
|
||||
|
||||
static void
|
||||
set_dbus_properties (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
const char *application_id,
|
||||
const char *app_menu_path,
|
||||
const char *menubar_path,
|
||||
const char *window_object_path,
|
||||
const char *application_object_path,
|
||||
const char *unique_bus_name)
|
||||
gtk_surface_set_dbus_properties (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
const char *application_id,
|
||||
const char *app_menu_path,
|
||||
const char *menubar_path,
|
||||
const char *window_object_path,
|
||||
const char *application_object_path,
|
||||
const char *unique_bus_name)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
|
||||
@@ -1502,8 +1596,36 @@ set_dbus_properties (struct wl_client *client,
|
||||
window_object_path);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_surface_set_modal (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
|
||||
if (surface->is_modal)
|
||||
return;
|
||||
|
||||
surface->is_modal = TRUE;
|
||||
meta_window_set_type (surface->window, META_WINDOW_MODAL_DIALOG);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_surface_unset_modal (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
|
||||
if (!surface->is_modal)
|
||||
return;
|
||||
|
||||
surface->is_modal = FALSE;
|
||||
meta_window_set_type (surface->window, META_WINDOW_NORMAL);
|
||||
}
|
||||
|
||||
static const struct gtk_surface_interface meta_wayland_gtk_surface_interface = {
|
||||
set_dbus_properties
|
||||
gtk_surface_set_dbus_properties,
|
||||
gtk_surface_set_modal,
|
||||
gtk_surface_unset_modal,
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -1540,6 +1662,17 @@ bind_gtk_shell (struct wl_client *client,
|
||||
uint32_t capabilities = 0;
|
||||
|
||||
resource = wl_resource_create (client, >k_shell_interface, version, id);
|
||||
|
||||
if (version != META_GTK_SHELL_VERSION)
|
||||
{
|
||||
wl_resource_post_error (resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"Incompatible gtk-shell version "
|
||||
"(supported version: %d)",
|
||||
META_GTK_SHELL_VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource_set_implementation (resource, &meta_wayland_gtk_shell_interface, data, NULL);
|
||||
|
||||
if (!meta_prefs_get_show_fallback_app_menu ())
|
||||
@@ -1548,59 +1681,6 @@ bind_gtk_shell (struct wl_client *client,
|
||||
gtk_shell_send_capabilities (resource, capabilities);
|
||||
}
|
||||
|
||||
static void
|
||||
subsurface_parent_surface_committed (MetaWaylandSurface *surface)
|
||||
{
|
||||
if (surface->sub.pending_pos)
|
||||
{
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor),
|
||||
surface->sub.pending_x,
|
||||
surface->sub.pending_y);
|
||||
surface->sub.pending_pos = FALSE;
|
||||
}
|
||||
|
||||
if (surface->sub.pending_placement_ops)
|
||||
{
|
||||
GSList *it;
|
||||
for (it = surface->sub.pending_placement_ops; it; it = it->next)
|
||||
{
|
||||
MetaWaylandSubsurfacePlacementOp *op = it->data;
|
||||
ClutterActor *surface_actor;
|
||||
ClutterActor *parent_actor;
|
||||
ClutterActor *sibling_actor;
|
||||
|
||||
if (!op->sibling)
|
||||
{
|
||||
g_slice_free (MetaWaylandSubsurfacePlacementOp, op);
|
||||
continue;
|
||||
}
|
||||
|
||||
surface_actor = CLUTTER_ACTOR (surface->surface_actor);
|
||||
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->sub.parent));
|
||||
sibling_actor = CLUTTER_ACTOR (op->sibling->surface_actor);
|
||||
|
||||
switch (op->placement)
|
||||
{
|
||||
case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
|
||||
clutter_actor_set_child_above_sibling (parent_actor, surface_actor, sibling_actor);
|
||||
break;
|
||||
case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
|
||||
clutter_actor_set_child_below_sibling (parent_actor, surface_actor, sibling_actor);
|
||||
break;
|
||||
}
|
||||
|
||||
wl_list_remove (&op->sibling_destroy_listener.link);
|
||||
g_slice_free (MetaWaylandSubsurfacePlacementOp, op);
|
||||
}
|
||||
|
||||
g_slist_free (surface->sub.pending_placement_ops);
|
||||
surface->sub.pending_placement_ops = NULL;
|
||||
}
|
||||
|
||||
if (surface->sub.synchronous)
|
||||
commit_pending_state (surface, &surface->sub.pending);
|
||||
}
|
||||
|
||||
static void
|
||||
unparent_actor (MetaWaylandSurface *surface)
|
||||
{
|
||||
@@ -1745,11 +1825,13 @@ wl_subsurface_set_desync (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
gboolean was_effectively_synchronized;
|
||||
|
||||
if (surface->sub.synchronous)
|
||||
subsurface_parent_surface_committed (surface);
|
||||
|
||||
was_effectively_synchronized = is_surface_effectively_synchronized (surface);
|
||||
surface->sub.synchronous = FALSE;
|
||||
if (was_effectively_synchronized &&
|
||||
!is_surface_effectively_synchronized (surface))
|
||||
apply_pending_state (surface, &surface->sub.pending);
|
||||
}
|
||||
|
||||
static const struct wl_subsurface_interface meta_wayland_wl_subsurface_interface = {
|
||||
|
||||
@@ -101,6 +101,7 @@ struct _MetaWaylandSurface
|
||||
struct wl_resource *xdg_shell_resource;
|
||||
MetaWaylandSerial acked_configure_serial;
|
||||
gboolean has_set_geometry;
|
||||
gboolean is_modal;
|
||||
|
||||
/* xdg_popup */
|
||||
struct {
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#define META_WL_SEAT_VERSION 4
|
||||
#define META_WL_OUTPUT_VERSION 2
|
||||
#define META_XSERVER_VERSION 1
|
||||
#define META_GTK_SHELL_VERSION 1
|
||||
#define META_GTK_SHELL_VERSION 2
|
||||
#define META_WL_SUBCOMPOSITOR_VERSION 1
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "window-wayland.h"
|
||||
#include "meta-window-wayland.h"
|
||||
|
||||
#include <meta/errors.h>
|
||||
#include "window-private.h"
|
||||
@@ -182,7 +182,7 @@ try_display (int display,
|
||||
|
||||
if (kill (other, 0) < 0 && errno == ESRCH)
|
||||
{
|
||||
/* Process is dead. Try unlinking the lockfile and trying again. */
|
||||
/* Process is dead. Try unlinking the lock file and trying again. */
|
||||
if (unlink (filename) < 0)
|
||||
{
|
||||
g_warning ("failed to unlink stale lock file %s: %m", filename);
|
||||
@@ -221,21 +221,23 @@ try_display (int display,
|
||||
}
|
||||
|
||||
static char *
|
||||
create_lockfile (int display, int *display_out)
|
||||
create_lock_file (int display, int *display_out)
|
||||
{
|
||||
char *filename;
|
||||
int fd;
|
||||
|
||||
char pid[11];
|
||||
int size;
|
||||
int number_of_tries = 0;
|
||||
|
||||
while (!try_display (display, &filename, &fd))
|
||||
{
|
||||
display++;
|
||||
number_of_tries++;
|
||||
|
||||
/* If display is above 50, then something's wrong. Just
|
||||
/* If we can't get a display after 50 times, then something's wrong. Just
|
||||
* abort in this case. */
|
||||
if (display > 50)
|
||||
if (number_of_tries >= 50)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -322,11 +324,13 @@ bind_to_unix_socket (int display)
|
||||
}
|
||||
|
||||
static void
|
||||
xserver_died (GPid pid,
|
||||
gint status,
|
||||
gpointer user_data)
|
||||
xserver_died (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (!WIFEXITED (status))
|
||||
GSubprocess *proc = G_SUBPROCESS (source);
|
||||
|
||||
if (!g_subprocess_get_successful (proc))
|
||||
g_error ("X Wayland crashed; aborting");
|
||||
else
|
||||
{
|
||||
@@ -350,7 +354,7 @@ static gboolean
|
||||
choose_xdisplay (MetaXWaylandManager *manager)
|
||||
{
|
||||
int display = 0;
|
||||
char *lockfile = NULL;
|
||||
char *lock_file = NULL;
|
||||
|
||||
/* Hack to keep the unused Xwayland instance on
|
||||
* the login screen from taking the prime :0 display
|
||||
@@ -361,8 +365,8 @@ choose_xdisplay (MetaXWaylandManager *manager)
|
||||
|
||||
do
|
||||
{
|
||||
lockfile = create_lockfile (display, &display);
|
||||
if (!lockfile)
|
||||
lock_file = create_lock_file (display, &display);
|
||||
if (!lock_file)
|
||||
{
|
||||
g_warning ("Failed to create an X lock file");
|
||||
return FALSE;
|
||||
@@ -371,7 +375,7 @@ choose_xdisplay (MetaXWaylandManager *manager)
|
||||
manager->abstract_fd = bind_to_abstract_socket (display);
|
||||
if (manager->abstract_fd < 0)
|
||||
{
|
||||
unlink (lockfile);
|
||||
unlink (lock_file);
|
||||
|
||||
if (errno == EADDRINUSE)
|
||||
{
|
||||
@@ -385,7 +389,7 @@ choose_xdisplay (MetaXWaylandManager *manager)
|
||||
manager->unix_fd = bind_to_unix_socket (display);
|
||||
if (manager->abstract_fd < 0)
|
||||
{
|
||||
unlink (lockfile);
|
||||
unlink (lock_file);
|
||||
close (manager->abstract_fd);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -396,7 +400,7 @@ choose_xdisplay (MetaXWaylandManager *manager)
|
||||
|
||||
manager->display_index = display;
|
||||
manager->display_name = g_strdup_printf (":%d", manager->display_index);
|
||||
manager->lockfile = lockfile;
|
||||
manager->lock_file = lock_file;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -434,75 +438,60 @@ meta_xwayland_start (MetaXWaylandManager *manager,
|
||||
{
|
||||
int xwayland_client_fd[2];
|
||||
int displayfd[2];
|
||||
int fd;
|
||||
gboolean started = FALSE;
|
||||
g_autoptr(GSubprocessLauncher) launcher = NULL;
|
||||
GSubprocessFlags flags;
|
||||
GSubprocess *proc;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!choose_xdisplay (manager))
|
||||
return FALSE;
|
||||
goto out;
|
||||
|
||||
/* We want xwayland to be a wayland client so we make a socketpair to setup a
|
||||
* wayland protocol connection. */
|
||||
if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, xwayland_client_fd) < 0)
|
||||
{
|
||||
g_warning ("xwayland_client_fd socketpair failed\n");
|
||||
unlink (manager->lockfile);
|
||||
return 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, displayfd) < 0)
|
||||
{
|
||||
g_warning ("displayfd socketpair failed\n");
|
||||
unlink (manager->lockfile);
|
||||
return 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
manager->pid = fork ();
|
||||
if (manager->pid == 0)
|
||||
/* xwayland, please. */
|
||||
flags = G_SUBPROCESS_FLAGS_NONE;
|
||||
|
||||
if (getenv ("XWAYLAND_STFU"))
|
||||
{
|
||||
char socket_fd[8], unix_fd[8], abstract_fd[8], displayfd_fd[8];
|
||||
|
||||
/* We passed SOCK_CLOEXEC, so dup the FD so it isn't
|
||||
* closed on exec.. */
|
||||
fd = dup (xwayland_client_fd[1]);
|
||||
snprintf (socket_fd, sizeof (socket_fd), "%d", fd);
|
||||
setenv ("WAYLAND_SOCKET", socket_fd, TRUE);
|
||||
|
||||
fd = dup (manager->abstract_fd);
|
||||
snprintf (abstract_fd, sizeof (abstract_fd), "%d", fd);
|
||||
|
||||
fd = dup (manager->unix_fd);
|
||||
snprintf (unix_fd, sizeof (unix_fd), "%d", fd);
|
||||
|
||||
fd = dup (displayfd[1]);
|
||||
snprintf (displayfd_fd, sizeof (displayfd_fd), "%d", fd);
|
||||
|
||||
/* xwayland, please. */
|
||||
if (getenv ("XWAYLAND_STFU"))
|
||||
{
|
||||
int dev_null;
|
||||
dev_null = open ("/dev/null", O_WRONLY);
|
||||
|
||||
dup2 (dev_null, STDOUT_FILENO);
|
||||
dup2 (dev_null, STDERR_FILENO);
|
||||
}
|
||||
|
||||
if (execl (XWAYLAND_PATH, XWAYLAND_PATH,
|
||||
manager->display_name,
|
||||
"-rootless",
|
||||
"-noreset",
|
||||
"-listen", abstract_fd,
|
||||
"-listen", unix_fd,
|
||||
"-displayfd", displayfd_fd,
|
||||
NULL) < 0)
|
||||
{
|
||||
g_error ("Failed to spawn XWayland: %m");
|
||||
}
|
||||
flags |= G_SUBPROCESS_FLAGS_STDOUT_SILENCE;
|
||||
flags |= G_SUBPROCESS_FLAGS_STDERR_SILENCE;
|
||||
}
|
||||
else if (manager->pid == -1)
|
||||
|
||||
launcher = g_subprocess_launcher_new (flags);
|
||||
|
||||
g_subprocess_launcher_take_fd (launcher, xwayland_client_fd[1], 3);
|
||||
g_subprocess_launcher_take_fd (launcher, manager->abstract_fd, 4);
|
||||
g_subprocess_launcher_take_fd (launcher, manager->unix_fd, 5);
|
||||
g_subprocess_launcher_take_fd (launcher, displayfd[1], 6);
|
||||
|
||||
g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
|
||||
proc = g_subprocess_launcher_spawn (launcher, &error,
|
||||
XWAYLAND_PATH, manager->display_name,
|
||||
"-rootless", "-noreset",
|
||||
"-listen", "4",
|
||||
"-listen", "5",
|
||||
"-displayfd", "6",
|
||||
NULL);
|
||||
if (!proc)
|
||||
{
|
||||
g_error ("Failed to fork: %m");
|
||||
g_error ("Failed to spawn Xwayland: %s", error->message);
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_child_watch_add (manager->pid, xserver_died, NULL);
|
||||
g_subprocess_wait_async (proc, NULL, xserver_died, NULL);
|
||||
g_unix_fd_add (displayfd[0], G_IO_IN, on_displayfd_ready, manager);
|
||||
manager->client = wl_client_create (wl_display, xwayland_client_fd[0]);
|
||||
|
||||
@@ -512,7 +501,15 @@ meta_xwayland_start (MetaXWaylandManager *manager,
|
||||
manager->init_loop = g_main_loop_new (NULL, FALSE);
|
||||
g_main_loop_run (manager->init_loop);
|
||||
|
||||
return TRUE;
|
||||
started = TRUE;
|
||||
|
||||
out:
|
||||
if (!started)
|
||||
{
|
||||
unlink (manager->lock_file);
|
||||
g_clear_pointer (&manager->lock_file, g_free);
|
||||
}
|
||||
return started;
|
||||
}
|
||||
|
||||
/* To be called right after connecting */
|
||||
@@ -532,10 +529,13 @@ meta_xwayland_stop (MetaXWaylandManager *manager)
|
||||
{
|
||||
char path[256];
|
||||
|
||||
snprintf (path, sizeof path, "/tmp/.X%d-lock", manager->display_index);
|
||||
unlink (path);
|
||||
snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->display_index);
|
||||
unlink (path);
|
||||
|
||||
unlink (manager->lockfile);
|
||||
g_clear_pointer (&manager->display_name, g_free);
|
||||
if (manager->lock_file)
|
||||
{
|
||||
unlink (manager->lock_file);
|
||||
g_clear_pointer (&manager->lock_file, g_free);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
<protocol name="gtk">
|
||||
|
||||
<interface name="gtk_shell" version="1">
|
||||
<interface name="gtk_shell" version="2">
|
||||
<description summary="gtk specific extensions">
|
||||
gtk_shell is a protocol extension providing additional features for
|
||||
clients implementing it. It is not backward compatible, and a client must
|
||||
always only bind to the specific version it implements. If a client binds
|
||||
to a version different from the version the server provides, an error will
|
||||
be raised.
|
||||
</description>
|
||||
|
||||
<enum name="capability">
|
||||
<entry name="global_app_menu" value="1"/>
|
||||
<entry name="global_menu_bar" value="2"/>
|
||||
<entry name="desktop_icons" value="3"/>
|
||||
</enum>
|
||||
|
||||
<event name="capabilities">
|
||||
@@ -16,7 +25,7 @@
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="gtk_surface" version="1">
|
||||
<interface name="gtk_surface" version="2">
|
||||
<request name="set_dbus_properties">
|
||||
<arg name="application_id" type="string" allow-null="true"/>
|
||||
<arg name="app_menu_path" type="string" allow-null="true"/>
|
||||
@@ -25,6 +34,9 @@
|
||||
<arg name="application_object_path" type="string" allow-null="true"/>
|
||||
<arg name="unique_bus_name" type="string" allow-null="true"/>
|
||||
</request>
|
||||
|
||||
<request name="set_modal"/>
|
||||
<request name="unset_modal"/>
|
||||
</interface>
|
||||
|
||||
</protocol>
|
||||
|
||||
Reference in New Issue
Block a user