Compare commits

...

48 Commits

Author SHA1 Message Date
edab8c3a4c Bump version to 3.25.3
Update NEWS.
2017-06-21 21:30:33 +02:00
8153c5b544 compositor: Handle EXIF orientation for backgrounds
Apply the embedded EXIF orientation when the background is loaded.

https://bugzilla.gnome.org/show_bug.cgi?id=783125
2017-06-21 20:23:09 +02:00
a4cef8586c backends/native: Interpret tablet padding as being input-centric
It is possible to interpret the ammount of padding provided to the
*_set_tablet_area functions in two different and incompatible ways. The X11
backend effectively treats them as being input-centric (i.e., the padding
defines the size of the "dead zone" on the tablet) while the native backend
has an output-centric viewpoint (i.e., the padding defines the size of the
"dead zone" on the display) viewpoint. This difference in opinion causes the
cursor offset to change when switching between Xorg and a Wayland sessions.

The calibration utility within g-c-c does its calculations with an input-
centric viewpoint, so this patch modifies the native backend to work
correctly with these values. To change viewpoints, we can simply invert
the scale and negate the offset. It should be noted that this function
also forgot to apply scaling to the offsets (as required by the matrix
transform done by libinput) which would have further compounded the
cursor offset issue under Wayland.

https://bugzilla.gnome.org/show_bug.cgi?id=784009
2017-06-20 23:42:38 +02:00
9b9bb9cf86 backends: Fix output cycling in non display-attached tablets
It would only allow to alternate between the logical monitors, we actually
want to return NULL here so it can cycle to the whole span of monitors.

https://bugzilla.gnome.org/show_bug.cgi?id=782032
2017-06-20 22:02:04 +02:00
dc5b2e396c backends: Fix typo
Instead of checking all MetaMonitors in the monitor manager, we want to
look (as the function name says) in the MetaMonitors contained in the
given logical monitor.

Otherwise, it will return TRUE for every logical monitor, given we are
querying for an existing EDID.

https://bugzilla.gnome.org/show_bug.cgi?id=782032
2017-06-20 22:02:04 +02:00
d23275bc76 backends/x11: Handle left-handed mode on pen/eraser devices correctly
Due to the pen/eraser device separation in X11, CLUTTER_TABLET_DEVICE does
not apply there, this device type is only used in native/evdev. Checking
for CLUTTER_PEN/ERASER_DEVICE makes the left-handed mode correctly applied
on tablets.

https://bugzilla.gnome.org/show_bug.cgi?id=782027
2017-06-20 22:02:04 +02:00
48e820235e backends/x11: Fix c&p issue in tablet area calculation
instead of filling in the last array value, it overwrote the previous one.

https://bugzilla.gnome.org/show_bug.cgi?id=781703
2017-06-20 22:02:04 +02:00
2d3c56b089 Updated Spanish translation 2017-06-19 17:37:23 +02:00
85b2e59e7e Update Arabic translation 2017-06-18 21:28:17 +02:00
e1950ed76f texture-tower: Fix usage of G_*_DECLS
https://bugzilla.gnome.org/show_bug.cgi?id=783505
2017-06-14 11:15:04 +02:00
7938f41c11 monitor: invert logic for 4k TV scaling
For devices connected via HDMI (supposedly TVs) we want have a
scale factor of 1 if we are *below* the smallest 4k resolution
width (not equal or above) and do the scaling factor computation
if we are above the limit. This check was apparently wrongly
ported from gnome-settings-daemon.

Based of a patch by Caolan McNamara <caolanm@redhat.com>.

https://bugzilla.gnome.org/show_bug.cgi?id=777347
2017-06-07 14:03:03 +02:00
9f41bdb086 Update Indonesian translation 2017-06-07 08:01:27 +00:00
8457e2bad6 wayland/pointer: Check for subsurfaces when grabbing
Previously, the function only returned `TRUE` if the given surface was
equal to the given pointer's focused surface. This changes the behaviour
to also return `TRUE` if any of the given surface's subsurfaces are
equal to the pointer's focused surface.

https://bugzilla.gnome.org/show_bug.cgi?id=781811.
2017-06-07 09:47:29 +08:00
4d7329a7e2 window: Include STATE_CHANGED flag when tiling
For size change animations, plugins rely on the size change effect being
followed by size changed signal (or effects being kill altogether).
However unless the move_resize operation included the STATE_CHANGED flag,
the size changed event emitted when the compositor syncs the window
geometry only happens when the operation resulted in an actual change.

To avoid animations getting stuck in that case, make sure to include the
flag when tiling a window.

https://bugzilla.gnome.org/show_bug.cgi?id=783293
2017-06-06 15:35:06 +02:00
b4120a75e0 wayland/pointer: Track lifetime of current surface
Clear the pointer->current when the surface is destroyed.

https://bugzilla.gnome.org/show_bug.cgi?id=783113
2017-06-01 12:46:32 +08:00
b19e4592df wayland/pointer: Use glib signals tracking focus surface
Use the "destroy" MetaWaylandSurface signal instead of the wl_resource
destroy signal for tracking the lifetime of the surface with pointer
focus.

As unsetting the focus may have side effects due to handlers of the
"focus-surface-changed" signal, connect the signal after the default
handler to make sure other clean up facilities have the chance deal with
the surface destruction before we try to unset the focus.

https://bugzilla.gnome.org/show_bug.cgi?id=783113
2017-06-01 12:46:32 +08:00
e9c9ee844c backends/x11: Ensure reply is initialised to NULL 2017-05-31 19:15:39 -04:00
f5f0ff0a2f monitor-manager: Fix crash when UPower is not available
Don't access the upower client if it doesn't exist

https://bugzilla.gnome.org/show_bug.cgi?id=780407
2017-05-31 16:11:24 +02:00
68dacb531b keybindings: handle multiple keycodes for keysym
A single keysym can resolve to multiple keycodes. Instead of only using
the first one and ignoring the others, we store all codes in
MetaResolvedKeyCombo and then handle all of them in keybinding
resolution. If we already have bound a keycode for a keybinding with a
specific keysym then this can get overwritten by a new keybinding with a
different keysym that resolves to the same keycode. Now that we resolve
and bind all keycodes for a keysym this might happen more often; in that
case warn but still overwrite, but only for the first keycode for each
keysym. If a secondary (i.e. all non-first keycodes) is already indexed
we just ignore that; this should resemble the old behavior  where we
only took the first keycode for any keysym as close as possible.

https://bugzilla.gnome.org/show_bug.cgi?id=781223
2017-05-30 15:23:00 +02:00
dd82f4afcd configure: require glib 2.53.2
This is required for the new glib-genmarshal as introduced in
 commit 9131f26cae

https://bugzilla.gnome.org/show_bug.cgi?id=783161
2017-05-28 11:21:42 +10:00
fc010e0edc Update Friulian translation 2017-05-27 20:55:46 +00:00
5132ea64be Use Unicode quotation marks in a translatable string
Also fixes a typo.

See https://developer.gnome.org/hig/stable/typography.html

https://bugzilla.gnome.org/show_bug.cgi?id=772218
2017-05-26 16:15:25 +02:00
82325cbcfd monitor: Don't get the monitor manager from the backend
We will both create and destroy monitors during initialization (when
using the X11 backend), so don't try to access the monitor manager from
the backend, but store a pointer to it instead.

It's stored in MetaMonitor even though only MetaMonitorTiled uses it,
mostly because it makes more sense to store such a pointer there.

https://bugzilla.gnome.org/show_bug.cgi?id=781723
2017-05-26 14:32:43 +08:00
fb5ebffb8d tests/monitor-unit-tests: Check handling of odd tiled monitors
Add tests for handling tiled monitors where the origin tile output is
not the main output.

https://bugzilla.gnome.org/show_bug.cgi?id=781723
2017-05-26 14:32:43 +08:00
94d843b80e tests/monitor-unit-tests: Check meta_monitor_is_active()
https://bugzilla.gnome.org/show_bug.cgi?id=781723
2017-05-26 14:32:43 +08:00
c32e2d17d9 monitor: Handle tiled monitors where (0, 0) is not the main output
In some circumstances, the origin tile (0, 0) is not the one that
should be used to drive the monitor when using a non-tiled mode. Update
MetaMonitorTiled to support this case. It also seems to be so that the
preferred mode might be some low resolution or bogus mode on these
monitors, so also adapt MetaMonitorTiled to manage to ignore the
preferred mode of a tiled monitor if the preferred mode doesn't use
both tiles.

https://bugzilla.gnome.org/show_bug.cgi?id=781723
2017-05-26 14:32:43 +08:00
2b05748d5c monitor: Move get_suggested() behind behind vfunc
Only support suggested monitor positioning if the monitor is non-tiled.
Normally this functionality is used by virtual machines to provide a
hint of how to place the virtual monitors, and they don't tend to use
tiled monitors anyway.

https://bugzilla.gnome.org/show_bug.cgi?id=781723
2017-05-26 14:32:43 +08:00
cd775929bf monitor: Move tiled CRTC mode identification into helper
It'll be used in more places later.

https://bugzilla.gnome.org/show_bug.cgi?id=781723
2017-05-26 14:32:43 +08:00
7303a78b06 monitor: Generate spec struct earlier
By generating the spec struct earlier, code executed later can use the
fields in the spec.

https://bugzilla.gnome.org/show_bug.cgi?id=781723
2017-05-26 14:32:43 +08:00
07b8cc0773 monitor: Fix naming of spec generation function
It was at one point referred to as 'id', but was changed to 'spec', but
the name of this function was not updated.

https://bugzilla.gnome.org/show_bug.cgi?id=781723
2017-05-26 14:32:43 +08:00
1bb0e18042 monitor-manager/xrandr: Allow configuring scales on X11 too
This commit makes it possible to configure logical monitor scale also
when running on top of an X11 server using Xrandr. An extra property
'requires-globla-scale' is added to the D-Bus API is added to instruct
a configuration application to only allow setting a global logical
monitor scale.

This is needed to let gsd-xsettings use the configured state to set a
XSettings state that respects the explicit monitor configuration.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-05-26 14:31:48 +08:00
05bc2e2331 gschema: Add description for "monitor-config-manager"
https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-05-26 14:31:48 +08:00
3b097c7e77 monitor-manager/kms: Move scale calculation to MetaMonitor
The scale calculation doesn't really have anything to do with KMS, and
eventually we'll want to have mutter calculate the monitor scale for
non-KMS backends too, so move the scale calculation to MetaMonitor.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-05-26 14:31:48 +08:00
0bc312a54b monitor-manager/kms: Move global ui scaling setting to MetaSettings
It'll be used elsewhere, so shouldn't be in MetaMonitorManagerKms.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-05-26 14:31:48 +08:00
2718699ccc backend: Move settings into a new MetaSettings object
Introduce MetaSettings and add the settings managed by MetaBackend into
the new object. These settings include: experimental-features and UI
scaling factor.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-05-26 14:31:48 +08:00
be175558c3 backend: Make X11 display opened function explicitly named
It didn't say anything about being the X11 display, so make it say so.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-05-26 14:31:48 +08:00
df39a7d0fd monitor-manager/xrandr: Use xcb API to configure CRTC
Use xcb-randr instead of libXrandr to set the CRTC configuration. This
is needed because data from the reply will later be used.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-05-26 14:31:48 +08:00
43cdf81f6b backend: Make the getter use the cached ui scale
The cached ui scale is kept up to date, so don't recalculate it
everytime meta_backend_get_ui_scaling() is called.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
2017-05-26 14:31:48 +08:00
183f4b0c13 MetaMonitorManager: ignore hotplug_mode_update at startup
hotplug_mode_update is used (mostly by VMs nowadays, and
VMware has implemented it) to inform that modes list (including
the preferred one) might change after an uevent.

However, when using MetaMonitorConfigManager we should
ignore this value at initialization level, or mutter
won't restore the configured values at startup.

https://bugzilla.gnome.org/show_bug.cgi?id=783073
2017-05-25 16:50:29 +08:00
38a772bce7 Bump version to 3.25.2
Update NEWS.
2017-05-24 21:04:07 +02:00
dd451547a5 tests: Fix actor-anchors test
Since commit 5cb5baa7d4, we skip transitions when updating an
actor's scale/position to the existing value. As a result, we
don't get change notification on those properties either - given
that the properties did not actually change, that behavior seems
fine, so just modify the test to not expect a notify signal for
unchanged properties.
2017-05-24 21:04:07 +02:00
270da95cbc window: Notify about size-change when tiling
Call meta_compositor_size_change_window while tiling in order
to emit the size-change signal. Since the untiling action is
considered a unmaximize size change, treat tiling as a maximize
size change for consistency.

https://bugzilla.gnome.org/show_bug.cgi?id=782968
2017-05-24 09:51:29 +02:00
76198e0b3b Implements disable-while-typing in mutter.
Disable-while-typing disables the touchpad while the user is typing.

This patch introduces the necessary backend code to implement the
org.gnome.desktop.peripherals.touchpad.disable-while-typing setting of
gsettings-desktop-schemas which was implemented in commit
4c5b1c1df399d6afaaccb237e299ccd1d5d29ddd and released as part of 3.24.
This is known as dwt in libinput.

This patch has been tested on X11 and Wayland.

https://bugzilla.gnome.org/show_bug.cgi?id=764852
2017-05-24 11:56:54 +08:00
efc190789f backend: Couple of whitespace fixes
https://bugzilla.gnome.org/show_bug.cgi?id=782152
2017-05-24 11:18:56 +08:00
81e99c2680 input-settings: Minor structural cleanup
Let the backend implementations create their own input settings
backend, as is done with other backend specific special purpose
backends. Also use the macro for declaring the GType.

https://bugzilla.gnome.org/show_bug.cgi?id=782152
2017-05-24 11:18:56 +08:00
755755a2f3 backend: Move out some code from post_init()
meta_backend_real_post_init() had some open coded initialization with
some unexpected interdependencies. Split these up and move them to their
own functions in order to make meta_backend_real_post_init() a bit more
readable.

https://bugzilla.gnome.org/show_bug.cgi?id=782152
2017-05-24 11:17:46 +08:00
4b23eb064c clutter: Update pointer position on master clock's update stage
Ensure the pointer position is up-to-date for the pointers inside
the clip area after the stage got actors relayout.

https://bugzilla.gnome.org/show_bug.cgi?id=755164
2017-05-23 16:37:53 +02:00
498200776c wayland: Ensure we repick the pointer on synthesized crossing events
Relayouts in clutter may trigger synthesized crossing events if the
actor below the pointer changes. In that situation we do need to
repick() the MetaWaylandPointer to end up with the right current
wayland surface.

https://bugzilla.gnome.org/show_bug.cgi?id=755164
2017-05-22 17:45:17 +02:00
51 changed files with 2969 additions and 1138 deletions

50
NEWS
View File

@ -1,3 +1,53 @@
3.25.3
======
* Ignore hotplug-mode-update value on startup [Marco; #783073]
* Implement configurable monitor scales on X11 [Jonas; #777732]
* Fix handling of tiled monitors [Jonas; #781723]
* Handle multiple keycodes for keysym [Christian; #781223]
* Consider subsurfaces when grabbing [mindtree; #781811]
* Fix logic for HiPDPI scaling of TV outputs [Christian; #777347]
* Fix handling of left-handed mode on pen/eraser devices [Carlos; #782027]
* Fix output cycling in non-display-attached tablets [Carlos; #782032]
* Fix wacom cursor offset on wayland [Jason; #784009]
* Handle EXIF orientation of backgrounds [Silvère; #783125]
* Misc. bug fixes [Piotr, Tim, Bastien, Jonas, Florian, Benoit, Carlos; #772218,
#783161, #780407, #783113, #783293, #783505, #781703]
Contributors:
mitchmindtree, Jonas Ådahl, Ikey Doherty, Piotr Drąg, Carlos Garnacho,
Jason Gerecke, Benoit Gschwind, Christian Kellner, Silvère Latchurié,
Tim Lunn, Florian Müllner, Bastien Nocera, Marco Trevisan (Treviño)
Translations:
Fabio Tomat [fur], Kukuh Syafaat [id], Khaled Hosny [ar],
Daniel Mustieles [es]
3.25.2
======
* Fix frame updates on hide-titlebar-when-maximized changes [Florian; #781862]
* Fix accessible screen coordinates on X11 [Florian; #781902]
* Use less CPU when rendering fast-updating windows [Carlos, Emmanuele; #782344]
* Compute geometry of clients that don't set one explicitly [Olivier; #782213]
* Fix copy+paste of UTF8 strings between X11 and wayland [Carlos; #782472]
* Fix non-wayland builds [Chris; #780533]
* Add plugin vfunc to implement a custom force-quit dialog [Carlos; #711619]
* Fix swapped red and blue channels in CoglTexture data [Carlos; #779234
* Fix build where libtool's link_all_deplibs defaults to 'no' [Marco; #782821]
* Fix glitches when opening a window maximized [Olivier; #781353, #782183]
* Fix wrong cursor after window underneath the pointer changed [Carlos; #755164]
* Implement support for disable-while-typing option [Evan; #764852]
* Emit size-change signal when tiling [Alessandro; #782968]
* Misc. bug fixes [Nigel, Matthias, Jonas; #759085, #780215, #782156, #782152]
Contributors:
Jonas Ådahl, Emmanuele Bassi, Alessandro Bono, Olivier Fourdan,
Carlos Garnacho, Matthias Liertzer, Florian Müllner, Nigel Taylor,
Marco Trevisan (Treviño), Chris Vine, Evan Welsh
Translations:
Fabio Tomat [fur], Jordi Mas [ca], Mario Blättermann [de],
Emin Tufan Çetin [tr], Balázs Úr [hu]
3.25.1
======
* Always sync window geometry on state changes [Jonas; #780292]

View File

@ -161,6 +161,7 @@ struct _ClutterStagePrivate
guint accept_focus : 1;
guint motion_events_enabled : 1;
guint has_custom_perspective : 1;
guint stage_was_relayout : 1;
};
enum
@ -1059,6 +1060,7 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
if (!CLUTTER_ACTOR_IN_RELAYOUT (stage))
{
priv->relayout_pending = FALSE;
priv->stage_was_relayout = TRUE;
CLUTTER_NOTE (ACTOR, "Recomputing layout");
@ -1129,6 +1131,58 @@ clutter_stage_do_redraw (ClutterStage *stage)
stage);
}
static GSList *
_clutter_stage_check_updated_pointers (ClutterStage *stage)
{
ClutterStagePrivate *priv = stage->priv;
ClutterDeviceManager *device_manager;
GSList *updating = NULL;
const GSList *devices;
cairo_rectangle_int_t clip;
ClutterPoint point;
gboolean has_clip;
has_clip = _clutter_stage_window_get_redraw_clip_bounds (priv->impl, &clip);
device_manager = clutter_device_manager_get_default ();
devices = clutter_device_manager_peek_devices (device_manager);
for (; devices != NULL; devices = devices->next)
{
ClutterInputDevice *dev = devices->data;
if (clutter_input_device_get_device_mode (dev) !=
CLUTTER_INPUT_MODE_MASTER)
continue;
switch (clutter_input_device_get_device_type (dev))
{
case CLUTTER_POINTER_DEVICE:
case CLUTTER_TABLET_DEVICE:
case CLUTTER_PEN_DEVICE:
case CLUTTER_ERASER_DEVICE:
case CLUTTER_CURSOR_DEVICE:
if (!clutter_input_device_get_coords (dev, NULL, &point))
continue;
if (!has_clip ||
(point.x >= clip.x && point.x < clip.x + clip.width &&
point.y >= clip.y && point.y < clip.y + clip.height))
updating = g_slist_prepend (updating, dev);
break;
default:
/* Any other devices don't need checking, either because they
* don't have x/y coordinates, or because they're implicitly
* grabbed on an actor by default as it's the case of
* touch(screens).
*/
break;
}
}
return updating;
}
/**
* _clutter_stage_do_update:
* @stage: A #ClutterStage
@ -1141,6 +1195,10 @@ gboolean
_clutter_stage_do_update (ClutterStage *stage)
{
ClutterStagePrivate *priv = stage->priv;
gboolean stage_was_relayout = priv->stage_was_relayout;
GSList *pointers = NULL;
priv->stage_was_relayout = FALSE;
/* if the stage is being destroyed, or if the destruction already
* happened and we don't have an StageWindow any more, then we
@ -1161,6 +1219,9 @@ _clutter_stage_do_update (ClutterStage *stage)
if (!priv->redraw_pending)
return FALSE;
if (stage_was_relayout)
pointers = _clutter_stage_check_updated_pointers (stage);
clutter_stage_maybe_finish_queue_redraws (stage);
clutter_stage_do_redraw (stage);
@ -1178,6 +1239,12 @@ _clutter_stage_do_update (ClutterStage *stage)
}
#endif /* CLUTTER_ENABLE_DEBUG */
while (pointers)
{
_clutter_input_device_update (pointers->data, NULL, TRUE);
pointers = g_slist_delete_link (pointers, pointers);
}
return TRUE;
}

View File

@ -110,7 +110,7 @@ LT_LIB_M
AC_HEADER_STDC
# required versions for dependencies
m4_define([glib_req_version], [2.44.0])
m4_define([glib_req_version], [2.53.2])
m4_define([cogl_req_version], [1.21.2])
m4_define([json_glib_req_version], [0.12.0])
m4_define([atk_req_version], [2.5.3])

View File

@ -407,8 +407,7 @@ test_scale_center (TestState *state)
g_assert (scale_x == 4.0);
g_assert (scale_y == 2.0);
g_assert (gravity == CLUTTER_GRAVITY_NONE);
assert_notifications (NOTIFY_SCALE_X | NOTIFY_SCALE_Y
| NOTIFY_SCALE_CENTER_X | NOTIFY_SCALE_CENTER_Y
assert_notifications (NOTIFY_SCALE_CENTER_X | NOTIFY_SCALE_CENTER_Y
| NOTIFY_SCALE_GRAVITY);
assert_coords (state, 100 + 10 - 10 * 4, 200 + 20 - 20 * 2,
100 + 10 + (RECT_WIDTH - 10) * 4,

View File

@ -2,7 +2,7 @@ AC_PREREQ(2.62)
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [25])
m4_define([mutter_micro_version], [1])
m4_define([mutter_micro_version], [3])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
@ -72,7 +72,7 @@ AC_HEADER_STDC
PKG_PROG_PKG_CONFIG([0.21])
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
AM_PATH_GLIB_2_0([2.49.0])
AM_PATH_GLIB_2_0([2.53.2])
CANBERRA_GTK=libcanberra-gtk3
CANBERRA_GTK_VERSION=0.26

View File

@ -114,12 +114,22 @@
Currently possible keywords:
• “monitor-config-manager” — use the new monitor configuration
system, aimed to replace the old one.
This enables a higher level configuration
API to be used by configuration
applications, as well as the ability to
configure per logical monitor scale.
• “scale-monitor-framebuffer” — makes mutter default to layout logical
monitors in a logical pixel coordinate
space, while scaling monitor
framebuffers instead of window content,
to manage HiDPI monitors. Does not
require a restart.
Also enabling “monitor-config-manager”
is required for this feature to be
enabled.
</description>
</key>

411
po/ar.po
View File

@ -4,14 +4,15 @@
# Arafat Medini <lumina@silverpen.de>, 2003.
# Abdulaziz Al-Arfaj <alarfaj0@yahoo.com>, 2004.
# Djihed Afifi <djihed@gmail.com>, 2006.
# Khaled Hosny <khaledhosny@eglug.org>, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015.
# Khaled Hosny <khaledhosny@eglug.org>, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2017.
# Anas Afif Emad <anas.e87@gmail.com>, 2008.
msgid ""
msgstr ""
"Project-Id-Version: metacity.HEAD\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-03-23 21:38+0200\n"
"PO-Revision-Date: 2015-03-23 21:45+0200\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter&"
"keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2017-06-18 21:26+0200\n"
"PO-Revision-Date: 2017-06-18 21:27+0200\n"
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
"Language-Team: Arabic <doc@arabeyes.org>\n"
"Language: ar\n"
@ -20,524 +21,568 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"X-Generator: Virtaal 0.7.1\n"
"X-Generator: Virtaal 1.0.0-beta1\n"
"X-Project-Style: gnome\n"
#: ../data/50-mutter-navigation.xml.in.h:1
#: data/50-mutter-navigation.xml:6
msgid "Navigation"
msgstr "الإبحار"
#: ../data/50-mutter-navigation.xml.in.h:2
#: data/50-mutter-navigation.xml:9
msgid "Move window to workspace 1"
msgstr "انقل النافذة إلى مساحة العمل 1"
#: ../data/50-mutter-navigation.xml.in.h:3
#: data/50-mutter-navigation.xml:12
msgid "Move window to workspace 2"
msgstr "انقل النافذة إلى مساحة العمل 2"
#: ../data/50-mutter-navigation.xml.in.h:4
#: data/50-mutter-navigation.xml:15
msgid "Move window to workspace 3"
msgstr "انقل النافذة إلى مساحة العمل 3"
#: ../data/50-mutter-navigation.xml.in.h:5
#: data/50-mutter-navigation.xml:18
msgid "Move window to workspace 4"
msgstr "انقل النافذة إلى مساحة العمل 4"
#: ../data/50-mutter-navigation.xml.in.h:6
#: data/50-mutter-navigation.xml:21
msgid "Move window to last workspace"
msgstr "انقل النافذة إلى مساحة العمل الأخيرة"
#: ../data/50-mutter-navigation.xml.in.h:7
#: data/50-mutter-navigation.xml:24
msgid "Move window one workspace to the left"
msgstr "انقل النافذة مساحة عمل واحدة إلى اليسار"
#: ../data/50-mutter-navigation.xml.in.h:8
#: data/50-mutter-navigation.xml:27
msgid "Move window one workspace to the right"
msgstr "انقل النافذة مساحة عمل واحدة إلى اليمين"
#: ../data/50-mutter-navigation.xml.in.h:9
#: data/50-mutter-navigation.xml:30
msgid "Move window one workspace up"
msgstr "انقل النافذة مساحة عمل واحدة إلى الأعلى"
#: ../data/50-mutter-navigation.xml.in.h:10
#: data/50-mutter-navigation.xml:33
msgid "Move window one workspace down"
msgstr "انقل النافذة مساحة عمل واحدة إلى الأسفل"
#: ../data/50-mutter-navigation.xml.in.h:11
#: data/50-mutter-navigation.xml:36
msgid "Move window one monitor to the left"
msgstr "انقل النافذة شاشة واحدة إلى اليسار"
#: ../data/50-mutter-navigation.xml.in.h:12
#: data/50-mutter-navigation.xml:39
msgid "Move window one monitor to the right"
msgstr "انقل النافذة شاشة واحدة إلى اليمين"
#: ../data/50-mutter-navigation.xml.in.h:13
#: data/50-mutter-navigation.xml:42
msgid "Move window one monitor up"
msgstr "انقل النافذة شاشة واحدة إلى الأعلى"
#: ../data/50-mutter-navigation.xml.in.h:14
#: data/50-mutter-navigation.xml:45
msgid "Move window one monitor down"
msgstr "انقل النافذة شاشة واحدة إلى الأسفل"
#: ../data/50-mutter-navigation.xml.in.h:15
#: data/50-mutter-navigation.xml:49
msgid "Switch applications"
msgstr "تنقل بين التطبيقات"
#: ../data/50-mutter-navigation.xml.in.h:16
#: data/50-mutter-navigation.xml:54
msgid "Switch to previous application"
msgstr "انتقل إلى التطبيق السابق"
#: ../data/50-mutter-navigation.xml.in.h:17
#: data/50-mutter-navigation.xml:58
msgid "Switch windows"
msgstr "تنقل بين النوافذ"
#: ../data/50-mutter-navigation.xml.in.h:18
#: data/50-mutter-navigation.xml:63
msgid "Switch to previous window"
msgstr "انتقل إلى النافذة السابقة"
#: ../data/50-mutter-navigation.xml.in.h:19
#: data/50-mutter-navigation.xml:67
msgid "Switch windows of an application"
msgstr "تنقل بين نوافذ التطبيق"
#: ../data/50-mutter-navigation.xml.in.h:20
#: data/50-mutter-navigation.xml:72
msgid "Switch to previous window of an application"
msgstr "انتقل إلى نافذة التطبيق السابقة"
#: ../data/50-mutter-navigation.xml.in.h:21
#: data/50-mutter-navigation.xml:76
msgid "Switch system controls"
msgstr "تنقل بين تحكمات النظام"
#: ../data/50-mutter-navigation.xml.in.h:22
#: data/50-mutter-navigation.xml:81
msgid "Switch to previous system control"
msgstr "انتقل إلى تحكم النظام السابق"
#: ../data/50-mutter-navigation.xml.in.h:23
#: data/50-mutter-navigation.xml:85
msgid "Switch windows directly"
msgstr "تنقل مباشرة بين النوافذ"
#: ../data/50-mutter-navigation.xml.in.h:24
#: data/50-mutter-navigation.xml:90
msgid "Switch directly to previous window"
msgstr "انتقل مباشرة إلى النافذة السابقة"
#: ../data/50-mutter-navigation.xml.in.h:25
#: data/50-mutter-navigation.xml:94
msgid "Switch windows of an app directly"
msgstr "تنقل مباشرة بين نوافذ التطبيق"
#: ../data/50-mutter-navigation.xml.in.h:26
#: data/50-mutter-navigation.xml:99
msgid "Switch directly to previous window of an app"
msgstr "انتقل مباشرة إلى نافذة التطبيق السابقة"
#: ../data/50-mutter-navigation.xml.in.h:27
#: data/50-mutter-navigation.xml:103
msgid "Switch system controls directly"
msgstr "تنقل مباشرة بين تحكمات النظام"
#: ../data/50-mutter-navigation.xml.in.h:28
#: data/50-mutter-navigation.xml:108
msgid "Switch directly to previous system control"
msgstr "انتقل مباشرة إلى تحكم النظام السابق"
#: ../data/50-mutter-navigation.xml.in.h:29
#: data/50-mutter-navigation.xml:111
msgid "Hide all normal windows"
msgstr "أخفِ كل النوافذ العادية"
#: ../data/50-mutter-navigation.xml.in.h:30
#: data/50-mutter-navigation.xml:114
msgid "Switch to workspace 1"
msgstr "انتقل إلى مساحة العمل 1"
#: ../data/50-mutter-navigation.xml.in.h:31
#: data/50-mutter-navigation.xml:117
msgid "Switch to workspace 2"
msgstr "انتقل إلى مساحة العمل 2"
#: ../data/50-mutter-navigation.xml.in.h:32
#: data/50-mutter-navigation.xml:120
msgid "Switch to workspace 3"
msgstr "انتقل إلى مساحة العمل 3"
#: ../data/50-mutter-navigation.xml.in.h:33
#: data/50-mutter-navigation.xml:123
msgid "Switch to workspace 4"
msgstr "انتقل إلى مساحة العمل 4"
#: ../data/50-mutter-navigation.xml.in.h:34
#: data/50-mutter-navigation.xml:126
msgid "Switch to last workspace"
msgstr "انتقل إلى مساحة العمل الأخيرة"
#: ../data/50-mutter-navigation.xml.in.h:35
#: data/50-mutter-navigation.xml:129
msgid "Move to workspace left"
msgstr "انقل لمساحة العمل على اليسار"
#: ../data/50-mutter-navigation.xml.in.h:36
#: data/50-mutter-navigation.xml:132
msgid "Move to workspace right"
msgstr "انقل لمساحة العمل على اليمين"
#: ../data/50-mutter-navigation.xml.in.h:37
#: data/50-mutter-navigation.xml:135
msgid "Move to workspace above"
msgstr "انقل لمساحة العمل أعلى"
#: ../data/50-mutter-navigation.xml.in.h:38
#: data/50-mutter-navigation.xml:138
msgid "Move to workspace below"
msgstr "انقل لمساحة العمل أسفل"
#: ../data/50-mutter-system.xml.in.h:1
#: data/50-mutter-system.xml:6
msgid "System"
msgstr "النظام"
#: ../data/50-mutter-system.xml.in.h:2
#: data/50-mutter-system.xml:8
msgid "Show the run command prompt"
msgstr "أظهر محث تشغيل أمر"
#: ../data/50-mutter-system.xml.in.h:3
#: data/50-mutter-system.xml:10
msgid "Show the activities overview"
msgstr "أظهر نظرة عامة على الأنشطة"
#: ../data/50-mutter-windows.xml.in.h:1
#: data/50-mutter-windows.xml:6
msgid "Windows"
msgstr "النوافذ"
#: ../data/50-mutter-windows.xml.in.h:2
#: data/50-mutter-windows.xml:8
msgid "Activate the window menu"
msgstr "فعّل قائمة النافذة"
#: ../data/50-mutter-windows.xml.in.h:3
#: data/50-mutter-windows.xml:10
msgid "Toggle fullscreen mode"
msgstr "بدّل نمط ملء الشاشة"
#: ../data/50-mutter-windows.xml.in.h:4
#: data/50-mutter-windows.xml:12
msgid "Toggle maximization state"
msgstr "بدّل حالة التكبير"
#: ../data/50-mutter-windows.xml.in.h:5
#: data/50-mutter-windows.xml:14
msgid "Maximize window"
msgstr "كبّر النّافذة"
#: ../data/50-mutter-windows.xml.in.h:6
#: data/50-mutter-windows.xml:16
msgid "Restore window"
msgstr "استعد النّافذة"
#: ../data/50-mutter-windows.xml.in.h:7
#: data/50-mutter-windows.xml:18
msgid "Toggle shaded state"
msgstr "بدّل حالة الإخفاء"
#: ../data/50-mutter-windows.xml.in.h:8
#: data/50-mutter-windows.xml:20
msgid "Close window"
msgstr "أغلق النّافذة"
#: ../data/50-mutter-windows.xml.in.h:9
#: data/50-mutter-windows.xml:22
msgid "Hide window"
msgstr "أخفِ النّافذة"
#: ../data/50-mutter-windows.xml.in.h:10
#: data/50-mutter-windows.xml:24
msgid "Move window"
msgstr "انقل النّافذة"
#: ../data/50-mutter-windows.xml.in.h:11
#: data/50-mutter-windows.xml:26
msgid "Resize window"
msgstr "حجّم النّافذة"
#: ../data/50-mutter-windows.xml.in.h:12
#: data/50-mutter-windows.xml:29
msgid "Toggle window on all workspaces or one"
msgstr "بدّل حالة ظهور النافذة على جميع مساحات العمل أو واحدة منها"
#: ../data/50-mutter-windows.xml.in.h:13
#: data/50-mutter-windows.xml:31
msgid "Raise window if covered, otherwise lower it"
msgstr "ارفع النافذة إذا كانت أخرى تغطيها، أو أخفضها في ما عدا ذلك"
#: ../data/50-mutter-windows.xml.in.h:14
#: data/50-mutter-windows.xml:33
msgid "Raise window above other windows"
msgstr "ارفع النافذة فوق النوافذ الأخرى"
#: ../data/50-mutter-windows.xml.in.h:15
#: data/50-mutter-windows.xml:35
msgid "Lower window below other windows"
msgstr "اخفض النافذة تحت النوافذ الأخرى"
#: ../data/50-mutter-windows.xml.in.h:16
#: data/50-mutter-windows.xml:37
msgid "Maximize window vertically"
msgstr "كبّر النافذة رأسيا"
#: ../data/50-mutter-windows.xml.in.h:17
#: data/50-mutter-windows.xml:39
msgid "Maximize window horizontally"
msgstr "كبّر النافذة أفقيا"
#: ../data/50-mutter-windows.xml.in.h:18
#: data/50-mutter-windows.xml:43
msgid "View split on left"
msgstr "المنظور مقسوم على اليمين"
#: ../data/50-mutter-windows.xml.in.h:19
#: data/50-mutter-windows.xml:47
msgid "View split on right"
msgstr "المنظور مقسوم على اليسار"
#: ../data/mutter.desktop.in.h:1
#: data/mutter.desktop.in:4
msgid "Mutter"
msgstr "مَتَر"
#: ../data/org.gnome.mutter.gschema.xml.in.h:1
#: data/org.gnome.mutter.gschema.xml.in:7
msgid "Modifier to use for extended window management operations"
msgstr "المغير الذي سيُستعمل لتمديد عمليات إدارة النوافذ "
#: ../data/org.gnome.mutter.gschema.xml.in.h:2
#: data/org.gnome.mutter.gschema.xml.in:8
msgid ""
"This key will initiate the \"overlay\", which is a combination window "
"overview and application launching system. The default is intended to be the "
"\"Windows key\" on PC hardware. It's expected that this binding either the "
"default or set to the empty string."
"This key will initiate the overlay, which is a combination window overview "
"and application launching system. The default is intended to be the “Windows "
"key on PC hardware. Its expected that this binding either the default or "
"set to the empty string."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:3
#: data/org.gnome.mutter.gschema.xml.in:20
msgid "Attach modal dialogs"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:4
#: data/org.gnome.mutter.gschema.xml.in:21
msgid ""
"When true, instead of having independent titlebars, modal dialogs appear "
"attached to the titlebar of the parent window and are moved together with "
"the parent window."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:5
#: data/org.gnome.mutter.gschema.xml.in:30
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:6
#: data/org.gnome.mutter.gschema.xml.in:31
msgid ""
"If enabled, dropping windows on vertical screen edges maximizes them "
"vertically and resizes them horizontally to cover half of the available "
"area. Dropping windows on the top screen edge maximizes them completely."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:7
#: data/org.gnome.mutter.gschema.xml.in:40
msgid "Workspaces are managed dynamically"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:8
#: data/org.gnome.mutter.gschema.xml.in:41
msgid ""
"Determines whether workspaces are managed dynamically or whether there's a "
"Determines whether workspaces are managed dynamically or whether theres a "
"static number of workspaces (determined by the num-workspaces key in org."
"gnome.desktop.wm.preferences)."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:9
#: data/org.gnome.mutter.gschema.xml.in:50
msgid "Workspaces only on primary"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:10
#: data/org.gnome.mutter.gschema.xml.in:51
msgid ""
"Determines whether workspace switching should happen for windows on all "
"monitors or only for windows on the primary monitor."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:11
#: data/org.gnome.mutter.gschema.xml.in:59
msgid "No tab popup"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:12
#: data/org.gnome.mutter.gschema.xml.in:60
msgid ""
"Determines whether the use of popup and highlight frame should be disabled "
"for window cycling."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:13
#: data/org.gnome.mutter.gschema.xml.in:68
msgid "Delay focus changes until the pointer stops moving"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:14
#: data/org.gnome.mutter.gschema.xml.in:69
msgid ""
"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
"the focus will not be changed immediately when entering a window, but only "
"after the pointer stops moving."
"If set to true, and the focus mode is either sloppy or mouse then the "
"focus will not be changed immediately when entering a window, but only after "
"the pointer stops moving."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:15
#: data/org.gnome.mutter.gschema.xml.in:79
msgid "Draggable border width"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:16
#: data/org.gnome.mutter.gschema.xml.in:80
msgid ""
"The amount of total draggable borders. If the theme's visible borders are "
"The amount of total draggable borders. If the themes visible borders are "
"not enough, invisible borders will be added to meet this value."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:17
#: data/org.gnome.mutter.gschema.xml.in:89
msgid "Auto maximize nearly monitor sized windows"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:18
#: data/org.gnome.mutter.gschema.xml.in:90
msgid ""
"If enabled, new windows that are initially the size of the monitor "
"automatically get maximized."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:19
#: data/org.gnome.mutter.gschema.xml.in:98
msgid "Place new windows in the center"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:20
#: data/org.gnome.mutter.gschema.xml.in:99
msgid ""
"When true, the new windows will always be put in the center of the active "
"screen of the monitor."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:21
#: data/org.gnome.mutter.gschema.xml.in:107
msgid "Enable experimental features"
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:108
msgid ""
"To enable experimental features, add the feature keyword to the list. "
"Whether the feature requires restarting the compositor depends on the given "
"feature. Any experimental feature is not required to still be available, or "
"configurable. Dont expect adding anything in this setting to be future "
"proof. Currently possible keywords: • “monitor-config-manager” — use the new "
"monitor configuration system, aimed to replace the old one. This enables a "
"higher level configuration API to be used by configuration applications, as "
"well as the ability to configure per logical monitor scale. • “scale-monitor-"
"framebuffer” — makes mutter default to layout logical monitors in a logical "
"pixel coordinate space, while scaling monitor framebuffers instead of window "
"content, to manage HiDPI monitors. Does not require a restart. Also enabling "
"“monitor-config-manager” is required for this feature to be enabled."
msgstr ""
#: data/org.gnome.mutter.gschema.xml.in:151
msgid "Select window from tab popup"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:22
#: data/org.gnome.mutter.gschema.xml.in:156
msgid "Cancel tab popup"
msgstr ""
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1
#: data/org.gnome.mutter.wayland.gschema.xml.in:6
#, fuzzy
msgid "Switch to VT 1"
msgstr "انتقل إلى مساحة العمل 1"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2
#: data/org.gnome.mutter.wayland.gschema.xml.in:10
#, fuzzy
msgid "Switch to VT 2"
msgstr "انتقل إلى مساحة العمل 2"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3
#: data/org.gnome.mutter.wayland.gschema.xml.in:14
#, fuzzy
msgid "Switch to VT 3"
msgstr "انتقل إلى مساحة العمل 3"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4
#: data/org.gnome.mutter.wayland.gschema.xml.in:18
#, fuzzy
msgid "Switch to VT 4"
msgstr "انتقل إلى مساحة العمل 4"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5
#: data/org.gnome.mutter.wayland.gschema.xml.in:22
#, fuzzy
msgid "Switch to VT 5"
msgstr "انتقل إلى مساحة العمل 5"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6
#: data/org.gnome.mutter.wayland.gschema.xml.in:26
#, fuzzy
msgid "Switch to VT 6"
msgstr "انتقل إلى مساحة العمل 6"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7
#: data/org.gnome.mutter.wayland.gschema.xml.in:30
#, fuzzy
msgid "Switch to VT 7"
msgstr "انتقل إلى مساحة العمل 7"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
#: data/org.gnome.mutter.wayland.gschema.xml.in:34
#, fuzzy
msgid "Switch to VT 8"
msgstr "انتقل إلى مساحة العمل 8"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
#: data/org.gnome.mutter.wayland.gschema.xml.in:38
#, fuzzy
msgid "Switch to VT 9"
msgstr "انتقل إلى مساحة العمل 9"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
#: data/org.gnome.mutter.wayland.gschema.xml.in:42
#, fuzzy
msgid "Switch to VT 10"
msgstr "انتقل إلى مساحة العمل 10"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
#: data/org.gnome.mutter.wayland.gschema.xml.in:46
#, fuzzy
msgid "Switch to VT 11"
msgstr "انتقل إلى مساحة العمل 11"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
#: data/org.gnome.mutter.wayland.gschema.xml.in:50
#, fuzzy
msgid "Switch to VT 12"
msgstr "انتقل إلى مساحة العمل 12"
#: ../src/backends/meta-monitor-manager.c:364
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:1866
#, c-format
msgid "Mode Switch (Group %d)"
msgstr ""
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:1888
msgid "Switch monitor"
msgstr "غيّر الشاشة"
#: src/backends/meta-input-settings.c:1890
msgid "Show on-screen help"
msgstr ""
#: src/backends/meta-monitor-manager.c:879
msgid "Built-in display"
msgstr "شاشة مدمجة"
#: ../src/backends/meta-monitor-manager.c:391
#: src/backends/meta-monitor-manager.c:902
msgid "Unknown"
msgstr "غير معروفة"
#: ../src/backends/meta-monitor-manager.c:393
#: src/backends/meta-monitor-manager.c:904
msgid "Unknown Display"
msgstr "شاشة غير معروفة"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: ../src/backends/meta-monitor-manager.c:401
#: src/backends/meta-monitor-manager.c:912
#, c-format
msgid "%s %s"
msgstr "%s %s"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: ../src/compositor/compositor.c:456
#, c-format
#: src/compositor/compositor.c:476
#, fuzzy, c-format
msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
"\"."
"Another compositing manager is already running on screen %i on display “%s”."
msgstr "يعمل مدير مزج آخر على الشاشة %i والعرض \"%s\"."
#: ../src/core/bell.c:185
#: src/core/bell.c:194
msgid "Bell event"
msgstr "حدث جرس"
#: ../src/core/delete.c:127
#: src/core/display.c:608
#, fuzzy, c-format
msgid "Failed to open X Window System display “%s”\n"
msgstr "فشل فتح عرض نظام نوافذ إكس '%s'\n"
#: src/core/main.c:189
msgid "Disable connection to session manager"
msgstr "عطّل الاتصال بمدير الجلسة"
#: src/core/main.c:195
msgid "Replace the running window manager"
msgstr "استبدل بمدير النوافذ الذي يعمل"
#: src/core/main.c:201
msgid "Specify session management ID"
msgstr "حدّد رقم هويّة إدارة الجلسة"
#: src/core/main.c:206
msgid "X Display to use"
msgstr "معراض س الذي سيستعمل"
#: src/core/main.c:212
msgid "Initialize session from savefile"
msgstr "ابدأ الجلسة من ملف محفوظ"
#: src/core/main.c:218
msgid "Make X calls synchronous"
msgstr "اجعل نداءات س متزامنة"
#: src/core/main.c:225
msgid "Run as a wayland compositor"
msgstr ""
#: src/core/main.c:231
msgid "Run as a nested compositor"
msgstr ""
#: src/core/main.c:239
msgid "Run as a full display server, rather than nested"
msgstr ""
#. Translators: %s is a window title
#: src/core/meta-close-dialog-default.c:147
#, c-format
msgid "“%s” is not responding."
msgstr "”‏%s“ لا يستجيب."
#: ../src/core/delete.c:129
#: src/core/meta-close-dialog-default.c:149
msgid "Application is not responding."
msgstr "لا يستجيب التطبيق"
#: ../src/core/delete.c:134
#: src/core/meta-close-dialog-default.c:154
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr "ربما ترغب في الانتظار قليلا ليُكمِل أو إجبار التطبيق على الإنهاء كُلّية."
#: ../src/core/delete.c:141
msgid "_Wait"
msgstr "ا_نتظر"
#: ../src/core/delete.c:141
#: src/core/meta-close-dialog-default.c:161
msgid "_Force Quit"
msgstr "أ_جبر الإنهاء"
#: ../src/core/display.c:562
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "فشل فتح عرض نظام نوافذ إكس '%s'\n"
#: src/core/meta-close-dialog-default.c:161
msgid "_Wait"
msgstr "ا_نتظر"
#: ../src/core/main.c:176
msgid "Disable connection to session manager"
msgstr "عطّل الاتصال بمدير الجلسة"
#: ../src/core/main.c:182
msgid "Replace the running window manager"
msgstr "استبدل بمدير النوافذ الذي يعمل"
#: ../src/core/main.c:188
msgid "Specify session management ID"
msgstr "حدّد رقم هويّة إدارة الجلسة"
#: ../src/core/main.c:193
msgid "X Display to use"
msgstr "معراض س الذي سيستعمل"
#: ../src/core/main.c:199
msgid "Initialize session from savefile"
msgstr "ابدأ الجلسة من ملف محفوظ"
#: ../src/core/main.c:205
msgid "Make X calls synchronous"
msgstr "اجعل نداءات س متزامنة"
#: ../src/core/main.c:212
msgid "Run as a wayland compositor"
msgstr ""
#: ../src/core/main.c:220
msgid "Run as a full display server, rather than nested"
msgstr ""
#: ../src/core/mutter.c:39
#, c-format
#: src/core/mutter.c:39
#, fuzzy, c-format
msgid ""
"mutter %s\n"
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
"This is free software; see the source for copying conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A "
"PARTICULAR PURPOSE.\n"
@ -547,46 +592,52 @@ msgstr ""
"هذا برنامج حر، راجع المصدر لشروط النسخ.\n"
"لا يوجد أي ضمان: و لا حتى ضمان قابلية التسويق أو المناسبة لأي هدف.\n"
#: ../src/core/mutter.c:53
#: src/core/mutter.c:53
msgid "Print version"
msgstr "اطبع الإصدارة"
#: ../src/core/mutter.c:59
#: src/core/mutter.c:59
msgid "Mutter plugin to use"
msgstr "ملحق مَتَر الذي سيُستخدم"
#: ../src/core/prefs.c:2004
#: src/core/prefs.c:1997
#, c-format
msgid "Workspace %d"
msgstr "مساحة العمل %d"
#: ../src/core/screen.c:525
#, c-format
#: src/core/screen.c:580
#, fuzzy, c-format
msgid ""
"Display \"%s\" already has a window manager; try using the --replace option "
"to replace the current window manager."
"Display “%s” already has a window manager; try using the --replace option to "
"replace the current window manager."
msgstr ""
"الشاشة \"%s\" لها مدير نوافذ بالفعل، حاول استعمال خيار التبديل --replace "
"لتحُلّ محلّ مدير النوافذ الحالي."
#: ../src/core/screen.c:607
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
#: src/core/screen.c:665
#, fuzzy, c-format
msgid "Screen %d on display %s is invalid\n"
msgstr "الشاشة %d على العرض '%s' غير صحيحة\n"
#: ../src/core/util.c:118
#: src/core/util.c:120
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "جُمِّع مَتَر دون دعم للنمط المطنب\n"
#: ../src/x11/session.c:1815
#: src/wayland/meta-wayland-tablet-pad.c:563
#, c-format
msgid "Mode Switch: Mode %d"
msgstr ""
#: src/x11/session.c:1815
#, fuzzy
msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
"be restarted manually next time you log in."
"These windows do not support save current setup and will have to be "
"restarted manually next time you log in."
msgstr ""
"هذه النوافذ لا تدعم &quot;احفظ الضبط الحالي&quot; يجب إعادة تشغيلها يدويا "
"عند الولوج المرة القادمة."
#: ../src/x11/window-props.c:549
#: src/x11/window-props.c:559
#, c-format
msgid "%s (on %s)"
msgstr "%s (على %s)"

137
po/es.po
View File

@ -12,10 +12,10 @@
msgid ""
msgstr ""
"Project-Id-Version: mutter.master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2017-02-16 01:44+0000\n"
"PO-Revision-Date: 2017-02-17 11:38+0100\n"
"POT-Creation-Date: 2017-06-01 06:38+0000\n"
"PO-Revision-Date: 2017-06-19 13:47+0200\n"
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
"Language-Team: es <gnome-es-list@gnome.org>\n"
"Language: es\n"
@ -275,11 +275,6 @@ msgstr ""
"Modificador que usar para extender las operaciones de gestión sobre ventanas"
#: data/org.gnome.mutter.gschema.xml.in:8
#| msgid ""
#| "This key will initiate the \"overlay\", which is a combination window "
#| "overview and application launching system. The default is intended to be "
#| "the \"Windows key\" on PC hardware. It's expected that this binding "
#| "either the default or set to the empty string."
msgid ""
"This key will initiate the “overlay”, which is a combination window overview "
"and application launching system. The default is intended to be the “Windows "
@ -328,10 +323,6 @@ msgid "Workspaces are managed dynamically"
msgstr "Las áreas de trabajo se gestionan dinámicamente"
#: data/org.gnome.mutter.gschema.xml.in:41
#| msgid ""
#| "Determines whether workspaces are managed dynamically or whether there's "
#| "a static number of workspaces (determined by the num-workspaces key in "
#| "org.gnome.desktop.wm.preferences)."
msgid ""
"Determines whether workspaces are managed dynamically or whether theres a "
"static number of workspaces (determined by the num-workspaces key in org."
@ -370,10 +361,6 @@ msgid "Delay focus changes until the pointer stops moving"
msgstr "Retrasar el cambio de foco hasta detener el puntero"
#: data/org.gnome.mutter.gschema.xml.in:69
#| msgid ""
#| "If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
#| "the focus will not be changed immediately when entering a window, but "
#| "only after the pointer stops moving."
msgid ""
"If set to true, and the focus mode is either “sloppy” or “mouse” then the "
"focus will not be changed immediately when entering a window, but only after "
@ -388,9 +375,6 @@ msgid "Draggable border width"
msgstr "Anchura arrastrable del borde"
#: data/org.gnome.mutter.gschema.xml.in:80
#| msgid ""
#| "The amount of total draggable borders. If the theme's visible borders are "
#| "not enough, invisible borders will be added to meet this value."
msgid ""
"The amount of total draggable borders. If the themes visible borders are "
"not enough, invisible borders will be added to meet this value."
@ -425,11 +409,36 @@ msgstr ""
"Cuando es cierto, las ventanas nuevas se colocarán siempre en el centro de "
"la pantalla activa del monitor."
#: data/org.gnome.mutter.gschema.xml.in:120
#: data/org.gnome.mutter.gschema.xml.in:107
msgid "Enable experimental features"
msgstr "Activar las características experimentales"
#: data/org.gnome.mutter.gschema.xml.in:108
#, fuzzy
msgid ""
"To enable experimental features, add the feature keyword to the list. "
"Whether the feature requires restarting the compositor depends on the given "
"feature. Any experimental feature is not required to still be available, or "
"configurable. Dont expect adding anything in this setting to be future "
"proof. Currently possible keywords: • “monitor-config-manager” — use the new "
"monitor configuration system, aimed to replace the old one. This enables a "
"higher level configuration API to be used by configuration applications, as "
"well as the ability to configure per logical monitor scale. • “scale-monitor-"
"framebuffer” — makes mutter default to layout logical monitors in a logical "
"pixel coordinate space, while scaling monitor framebuffers instead of window "
"content, to manage HiDPI monitors. Does not require a restart. Also enabling "
"“monitor-config-manager” is required for this feature to be enabled."
msgstr ""
"Para activar las características experimentales, añada la palabra clave de "
"la característica a la lista. Depende de la característica que se deba "
"reiniciar o no el compositor. Cualquier característica experimental puede no "
"estar disponible o ser configurable. "
#: data/org.gnome.mutter.gschema.xml.in:151
msgid "Select window from tab popup"
msgstr "Seleccionar ventana de la pestaña emergente"
#: data/org.gnome.mutter.gschema.xml.in:125
#: data/org.gnome.mutter.gschema.xml.in:156
msgid "Cancel tab popup"
msgstr "Cancelar pestaña emergente"
@ -484,50 +493,46 @@ msgstr "Cambiar al VT 12"
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:1759
#: src/backends/meta-input-settings.c:1866
#, c-format
#| msgid "Mode Switch: Mode %d"
msgid "Mode Switch (Group %d)"
msgstr "Cambiar modo (grupo %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:1781
#: src/backends/meta-input-settings.c:1888
msgid "Switch monitor"
msgstr "Cambiar monitor"
#: src/backends/meta-input-settings.c:1783
#: src/backends/meta-input-settings.c:1890
msgid "Show on-screen help"
msgstr "Mostrar la ayuda en pantalla"
#: src/backends/meta-monitor-manager.c:675
#: src/backends/meta-monitor-manager.c:879
msgid "Built-in display"
msgstr "Pantalla integrada"
#: src/backends/meta-monitor-manager.c:698
#: src/backends/meta-monitor-manager.c:902
msgid "Unknown"
msgstr "Desconocida"
#: src/backends/meta-monitor-manager.c:700
#: src/backends/meta-monitor-manager.c:904
msgid "Unknown Display"
msgstr "Pantalla desconocida"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: src/backends/meta-monitor-manager.c:708
#: src/backends/meta-monitor-manager.c:912
#, c-format
msgid "%s %s"
msgstr "%s %s"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: src/compositor/compositor.c:471
#: src/compositor/compositor.c:476
#, c-format
#| msgid ""
#| "Another compositing manager is already running on screen %i on display "
#| "\"%s\"."
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
msgstr ""
@ -538,35 +543,8 @@ msgstr ""
msgid "Bell event"
msgstr "Evento de campana"
#. Translators: %s is a window title
#: src/core/delete.c:127
#, c-format
msgid "“%s” is not responding."
msgstr "«%s» no está respondiendo."
#: src/core/delete.c:129
msgid "Application is not responding."
msgstr "La aplicación no está respondiendo."
#: src/core/delete.c:134
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
"Puede elegir esperar un rato para ver si continua o forzar la aplicación "
"para cerrarla completamente."
#: src/core/delete.c:141
msgid "_Force Quit"
msgstr "_Forzar la salida"
#: src/core/delete.c:141
msgid "_Wait"
msgstr "_Esperar"
#: src/core/display.c:608
#, c-format
#| msgid "Failed to open X Window System display '%s'\n"
msgid "Failed to open X Window System display “%s”\n"
msgstr "Ocurrió un error al abrir la pantalla de X Window System «%s»\n"
@ -606,14 +584,34 @@ msgstr "Ejecutar como compositor anidado"
msgid "Run as a full display server, rather than nested"
msgstr "Ejecutar como servidor completo, en lugar de anidado"
#. Translators: %s is a window title
#: src/core/meta-close-dialog-default.c:147
#, c-format
msgid "“%s” is not responding."
msgstr "«%s» no está respondiendo."
#: src/core/meta-close-dialog-default.c:149
msgid "Application is not responding."
msgstr "La aplicación no está respondiendo."
#: src/core/meta-close-dialog-default.c:154
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
"Puede elegir esperar un rato para ver si continua o forzar la aplicación "
"para cerrarla completamente."
#: src/core/meta-close-dialog-default.c:161
msgid "_Force Quit"
msgstr "_Forzar la salida"
#: src/core/meta-close-dialog-default.c:161
msgid "_Wait"
msgstr "_Esperar"
#: src/core/mutter.c:39
#, c-format
#| msgid ""
#| "mutter %s\n"
#| "Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
#| "This is free software; see the source for copying conditions.\n"
#| "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A "
#| "PARTICULAR PURPOSE.\n"
msgid ""
"mutter %s\n"
"Copyright © 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
@ -643,9 +641,6 @@ msgstr "Área de trabajo %d"
#: src/core/screen.c:580
#, c-format
#| msgid ""
#| "Display \"%s\" already has a window manager; try using the --replace "
#| "option to replace the current window manager."
msgid ""
"Display “%s” already has a window manager; try using the --replace option to "
"replace the current window manager."
@ -655,7 +650,6 @@ msgstr ""
#: src/core/screen.c:665
#, c-format
#| msgid "Screen %d on display '%s' is invalid\n"
msgid "Screen %d on display “%s” is invalid\n"
msgstr "La ventana %d en la pantalla «%s» no es válida\n"
@ -669,9 +663,6 @@ msgid "Mode Switch: Mode %d"
msgstr "Cambiar modo: modo %d"
#: src/x11/session.c:1815
#| msgid ""
#| "These windows do not support &quot;save current setup&quot; and will have "
#| "to be restarted manually next time you log in."
msgid ""
"These windows do not support “save current setup” and will have to be "
"restarted manually next time you log in."

102
po/fur.po
View File

@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: mutter master\n"
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2017-04-21 21:33+0000\n"
"PO-Revision-Date: 2017-04-30 15:41+0200\n"
"POT-Creation-Date: 2017-05-26 14:16+0000\n"
"PO-Revision-Date: 2017-05-27 22:55+0200\n"
"Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n"
"Language-Team: Friulian <fur@li.org>\n"
"Language: fur\n"
@ -405,10 +405,14 @@ msgid ""
"Whether the feature requires restarting the compositor depends on the given "
"feature. Any experimental feature is not required to still be available, or "
"configurable. Dont expect adding anything in this setting to be future "
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
"mutter default to layout logical monitors in a logical pixel coordinate "
"space, while scaling monitor framebuffers instead of window content, to "
"manage HiDPI monitors. Does not require a restart."
"proof. Currently possible keywords: • “monitor-config-manager” — use the new "
"monitor configuration system, aimed to replace the old one. This enables a "
"higher level configuration API to be used by configuration applications, as "
"well as the ability to configure per logical monitor scale. • “scale-monitor-"
"framebuffer” — makes mutter default to layout logical monitors in a logical "
"pixel coordinate space, while scaling monitor framebuffers instead of window "
"content, to manage HiDPI monitors. Does not require a restart. Also enabling "
"“monitor-config-manager” is required for this feature to be enabled."
msgstr ""
"Par abilitâ lis funzionalitâts sperimentâls, zonte la peraule clâf de "
"funzionalitât ae liste. Il fat che la funzionalitât e vedi bisugne di tornâ "
@ -416,16 +420,22 @@ msgstr ""
"funzionalitât sperimentâl no je necessarie che e sedi disponibile o "
"configurabile. No sta spietâti di zontâ alc in cheste impostazion e pensâ "
"che e duredi tal timp. Atualmentri lis peraulis clâf pussibilis a son: • "
"“scale-monitor-framebuffer” — al rint come predefinît par mutter la "
"disposizion dai visôrs logjics intun spazi logjic di coordenadis dai pixel, "
"intant i framebuffer dai visôrs par scjalâ, invezit dal contignût dal "
"barcon, a gjestissin i visôrs HiDPI. Nol covente tornâ a inviâ."
"“monitor-config-manager” — al dopre il gnûf sisteme di configurazion dal "
"visôr, fat par sostituî chel vecjo. Chest al abilite une API di nivel "
"superiôr che e pues jessi doprade di aplicazions di configurazion, cussì "
"come la capacitât di configurâ par scjale di monitor logjic. • “scale-"
"monitor-framebuffer” — al rint come predefinît par mutter la disposizion dai "
"visôrs logjics intun spazi logjic di coordenadis dai pixel, intant i "
"framebuffer dai visôrs par scjalâ, invezit dal contignût dal barcon, a "
"gjestissin i visôrs HiDPI. Nol covente tornâ a inviâ. In plui al è necessari "
"abilitâ “monitor-config-manager” par fâ in mût che cheste funzionalitât e "
"sedi abilitade."
#: data/org.gnome.mutter.gschema.xml.in:141
#: data/org.gnome.mutter.gschema.xml.in:151
msgid "Select window from tab popup"
msgstr "Selezione barcon dal tab popup"
#: data/org.gnome.mutter.gschema.xml.in:146
#: data/org.gnome.mutter.gschema.xml.in:156
msgid "Cancel tab popup"
msgstr "Anule tab popup"
@ -480,7 +490,7 @@ msgstr "Passe al VT 12"
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:1848
#: src/backends/meta-input-settings.c:1866
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Cambie mût (Grup %d)"
@ -488,37 +498,37 @@ msgstr "Cambie mût (Grup %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:1870
#: src/backends/meta-input-settings.c:1888
msgid "Switch monitor"
msgstr "Cambie visôr"
#: src/backends/meta-input-settings.c:1872
#: src/backends/meta-input-settings.c:1890
msgid "Show on-screen help"
msgstr "Mostre jutori a schermi"
#: src/backends/meta-monitor-manager.c:783
#: src/backends/meta-monitor-manager.c:876
msgid "Built-in display"
msgstr "Display integrât"
#: src/backends/meta-monitor-manager.c:806
#: src/backends/meta-monitor-manager.c:899
msgid "Unknown"
msgstr "No cognossût"
#: src/backends/meta-monitor-manager.c:808
#: src/backends/meta-monitor-manager.c:901
msgid "Unknown Display"
msgstr "Display no cognossût"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: src/backends/meta-monitor-manager.c:816
#: src/backends/meta-monitor-manager.c:909
#, c-format
msgid "%s %s"
msgstr "%s %s"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: src/compositor/compositor.c:474
#: src/compositor/compositor.c:476
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
@ -530,32 +540,6 @@ msgstr ""
msgid "Bell event"
msgstr "Event cjampane"
#. Translators: %s is a window title
#: src/core/delete.c:127
#, c-format
msgid "“%s” is not responding."
msgstr "“%s” nol rispuint."
#: src/core/delete.c:129
msgid "Application is not responding."
msgstr "La aplicazion no rispuint."
#: src/core/delete.c:134
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
"Al è pussibil sielzi di spietâ un pôc lassant che la aplicazion e continui o "
"sfuarçâ la aplicazion par sierâle dal dut."
#: src/core/delete.c:141
msgid "_Force Quit"
msgstr "Sfuarce _Jessude"
#: src/core/delete.c:141
msgid "_Wait"
msgstr "_Spiete"
#: src/core/display.c:608
#, c-format
msgid "Failed to open X Window System display “%s”\n"
@ -597,6 +581,32 @@ msgstr "Eseguìs come compositor nidiât"
msgid "Run as a full display server, rather than nested"
msgstr "Eseguìs come servidôr display complet, invezit che nidiât"
#. Translators: %s is a window title
#: src/core/meta-close-dialog-default.c:147
#, c-format
msgid "“%s” is not responding."
msgstr "“%s” nol rispuint."
#: src/core/meta-close-dialog-default.c:149
msgid "Application is not responding."
msgstr "La aplicazion no rispuint."
#: src/core/meta-close-dialog-default.c:154
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
"Al è pussibil sielzi di spietâ un pôc lassant che la aplicazion e continui o "
"sfuarçâ la aplicazion par sierâle dal dut."
#: src/core/meta-close-dialog-default.c:161
msgid "_Force Quit"
msgstr "Sfuarce _Jessude"
#: src/core/meta-close-dialog-default.c:161
msgid "_Wait"
msgstr "_Spiete"
#: src/core/mutter.c:39
#, c-format
msgid ""

105
po/id.po
View File

@ -11,15 +11,15 @@ msgstr ""
"Project-Id-Version: mutter master\n"
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2017-04-21 21:33+0000\n"
"PO-Revision-Date: 2017-04-23 14:39+0700\n"
"Last-Translator: Kukuh Syafaat <syafaatkukuh@gmail.com>\n"
"POT-Creation-Date: 2017-05-31 14:13+0000\n"
"PO-Revision-Date: 2017-06-07 15:00+0700\n"
"Last-Translator: Andika Triwidada <andika@gmail.com>\n"
"Language-Team: Indonesian <gnome-l10n-id@googlegroups.com>\n"
"Language: id\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.11\n"
"X-Generator: Poedit 1.6.10\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: data/50-mutter-navigation.xml:6
@ -408,26 +408,35 @@ msgid ""
"Whether the feature requires restarting the compositor depends on the given "
"feature. Any experimental feature is not required to still be available, or "
"configurable. Dont expect adding anything in this setting to be future "
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
"mutter default to layout logical monitors in a logical pixel coordinate "
"space, while scaling monitor framebuffers instead of window content, to "
"manage HiDPI monitors. Does not require a restart."
"proof. Currently possible keywords: • “monitor-config-manager” — use the new "
"monitor configuration system, aimed to replace the old one. This enables a "
"higher level configuration API to be used by configuration applications, as "
"well as the ability to configure per logical monitor scale. • “scale-monitor-"
"framebuffer” — makes mutter default to layout logical monitors in a logical "
"pixel coordinate space, while scaling monitor framebuffers instead of window "
"content, to manage HiDPI monitors. Does not require a restart. Also enabling "
"“monitor-config-manager” is required for this feature to be enabled."
msgstr ""
"Untuk mengaktifkan fitur eksperimental, tambahkan kata kunci fitur ke dalam "
"daftar. Apakah fitur memerlukan nyala ulang kompositor tergantung pada fitur "
"yang diberikan. Setiap fitur eksperimental tidak diharuskan tetap tersedia, "
"atau dapat dikonfigurasi. Jangan berharap menambahkan apapun dalam "
"pengaturan ini sebagai bukti di masa depan. Saat ini kata kunci yang "
"mungkin: • \"scale-monitor-framebuffer\" — membuat mutter bawaan ke tata "
"letak monitor logikal dalam ruang koordinat pixel logikal, sementara skala "
"monitor framebuffer bukan konten jendela, untuk mengatur monitor HiDPI. "
"Tidak perlu nyala ulang."
"pengaturan ini kebal perubahan di masa depan. Saat ini kata kunci yang "
"mungkin: • \"monitor-config-manager\" — gunakan sistem konfigurasi monitor "
"baru, yang ditujukan untuk mengganti yang lama. Hal ini memungkinkan tingkat "
"konfigurasi API yang lebih tinggi untuk digunakan oleh aplikasi konfigurasi, "
"serta kemampuan untuk mengkonfigurasi per skala monitor logikal. • “scale-"
"monitor-framebuffer” — membuat bawaan mutter untuk tata letak monitor "
"logikal dalam ruang koordinat pixel logikal, sambil menskalakan framebuffer "
"monitor alih-alih konten jendela, untuk mengelola monitor HiDPI. Tidak perlu "
"mulai ulang. Juga mengaktifkan “monitor-config-manager” diperlukan agar "
"fitur ini diaktifkan."
#: data/org.gnome.mutter.gschema.xml.in:141
#: data/org.gnome.mutter.gschema.xml.in:151
msgid "Select window from tab popup"
msgstr "Pilih jendela dari popup tab"
#: data/org.gnome.mutter.gschema.xml.in:146
#: data/org.gnome.mutter.gschema.xml.in:156
msgid "Cancel tab popup"
msgstr "Batalkan popup tab"
@ -482,7 +491,7 @@ msgstr "Bertukar ke VT 12"
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:1848
#: src/backends/meta-input-settings.c:1866
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Tukar Mode: (Grup %d)"
@ -490,37 +499,37 @@ msgstr "Tukar Mode: (Grup %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:1870
#: src/backends/meta-input-settings.c:1888
msgid "Switch monitor"
msgstr "Berpindah monitor"
#: src/backends/meta-input-settings.c:1872
#: src/backends/meta-input-settings.c:1890
msgid "Show on-screen help"
msgstr "Tampilkan bantuan pada layar"
#: src/backends/meta-monitor-manager.c:783
#: src/backends/meta-monitor-manager.c:879
msgid "Built-in display"
msgstr "Tampilan bawaan"
#: src/backends/meta-monitor-manager.c:806
#: src/backends/meta-monitor-manager.c:902
msgid "Unknown"
msgstr "Tak Dikenal"
#: src/backends/meta-monitor-manager.c:808
#: src/backends/meta-monitor-manager.c:904
msgid "Unknown Display"
msgstr "Tampilan Tak Dikenal"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: src/backends/meta-monitor-manager.c:816
#: src/backends/meta-monitor-manager.c:912
#, c-format
msgid "%s %s"
msgstr "%s %s"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: src/compositor/compositor.c:474
#: src/compositor/compositor.c:476
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
@ -531,31 +540,6 @@ msgstr ""
msgid "Bell event"
msgstr "Bel peristiwa"
#. Translators: %s is a window title
#: src/core/delete.c:127
#, c-format
msgid "“%s” is not responding."
msgstr "\"%s\" tak merespon."
#: src/core/delete.c:129
msgid "Application is not responding."
msgstr "Aplikasi tak merespon."
#: src/core/delete.c:134
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
"Anda bisa memilih untuk menunggu sebentar atau memaksa aplikasi keluar."
#: src/core/delete.c:141
msgid "_Force Quit"
msgstr "_Matikan Paksa"
#: src/core/delete.c:141
msgid "_Wait"
msgstr "_Tunggu"
#: src/core/display.c:608
#, c-format
msgid "Failed to open X Window System display “%s”\n"
@ -597,6 +581,31 @@ msgstr "Jalankan sebagai kompositor bersarang"
msgid "Run as a full display server, rather than nested"
msgstr "Jalankan sebagai server tampilan penuh, ketimbang tampilan bersarang"
#. Translators: %s is a window title
#: src/core/meta-close-dialog-default.c:147
#, c-format
msgid "“%s” is not responding."
msgstr "\"%s\" tak merespon."
#: src/core/meta-close-dialog-default.c:149
msgid "Application is not responding."
msgstr "Aplikasi tak merespon."
#: src/core/meta-close-dialog-default.c:154
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
"Anda bisa memilih untuk menunggu sebentar atau memaksa aplikasi keluar."
#: src/core/meta-close-dialog-default.c:161
msgid "_Force Quit"
msgstr "_Matikan Paksa"
#: src/core/meta-close-dialog-default.c:161
msgid "_Wait"
msgstr "_Tunggu"
#: src/core/mutter.c:39
#, c-format
msgid ""

View File

@ -82,6 +82,7 @@ wayland_protocols = \
libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
backends/meta-backend.c \
meta/meta-backend.h \
meta/meta-settings.h \
backends/meta-backend-private.h \
backends/meta-barrier.c \
backends/meta-barrier-private.h \
@ -119,6 +120,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
backends/meta-monitor-manager-dummy.h \
backends/meta-pointer-constraint.c \
backends/meta-pointer-constraint.h \
backends/meta-settings.c \
backends/meta-settings-private.h \
backends/meta-stage.h \
backends/meta-stage.c \
backends/meta-renderer.c \
@ -445,6 +448,7 @@ libmutterinclude_headers = \
meta/meta-idle-monitor.h \
meta/meta-plugin.h \
meta/meta-monitor-manager.h \
meta/meta-settings.h \
meta/meta-shaped-texture.h \
meta/meta-shadow-factory.h \
meta/meta-window-actor.h \

View File

@ -38,6 +38,7 @@
#include "backends/meta-egl.h"
#include "backends/meta-pointer-constraint.h"
#include "backends/meta-renderer.h"
#include "backends/meta-settings-private.h"
#include "core/util-private.h"
#define DEFAULT_XKB_RULES_FILE "evdev"
@ -59,6 +60,7 @@ struct _MetaBackendClass
MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend);
MetaCursorRenderer * (* create_cursor_renderer) (MetaBackend *backend);
MetaRenderer * (* create_renderer) (MetaBackend *backend);
MetaInputSettings * (* create_input_settings) (MetaBackend *backend);
gboolean (* grab_device) (MetaBackend *backend,
int device_id,
@ -97,16 +99,9 @@ struct _MetaBackendClass
};
typedef enum _MetaExperimentalFeature
{
META_EXPERIMENTAL_FEATURE_NONE = 0,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER = (1 << 1)
} MetaExperimentalFeature;
void meta_init_backend (GType backend_gtype);
void meta_backend_display_opened (MetaBackend *backend);
void meta_backend_x11_display_opened (MetaBackend *backend);
ClutterBackend * meta_backend_get_clutter_backend (MetaBackend *backend);
@ -121,6 +116,7 @@ MetaCursorTracker * meta_backend_get_cursor_tracker (MetaBackend *backend);
MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend);
MetaRenderer * meta_backend_get_renderer (MetaBackend *backend);
MetaEgl * meta_backend_get_egl (MetaBackend *backend);
MetaSettings * meta_backend_get_settings (MetaBackend *backend);
gboolean meta_backend_grab_device (MetaBackend *backend,
int device_id,
@ -155,16 +151,6 @@ ClutterBackend * meta_backend_get_clutter_backend (MetaBackend *backend);
void meta_backend_monitors_changed (MetaBackend *backend);
gboolean meta_backend_is_experimental_feature_enabled (MetaBackend *backend,
MetaExperimentalFeature feature);
MetaExperimentalFeature meta_backend_get_experimental_features (MetaBackend *backend);
void meta_backend_override_experimental_features (MetaBackend *backend);
void meta_backend_enable_experimental_feature (MetaBackend *backend,
MetaExperimentalFeature feature);
gboolean meta_is_stage_views_enabled (void);
gboolean meta_is_stage_views_scaled (void);

View File

@ -43,15 +43,16 @@
#include "backends/meta-idle-monitor-private.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor-manager-dummy.h"
#include "ui/theme-private.h"
#include "backends/meta-settings-private.h"
#define META_IDLE_MONITOR_CORE_DEVICE 0
enum
{
KEYMAP_CHANGED,
KEYMAP_LAYOUT_GROUP_CHANGED,
LAST_DEVICE_CHANGED,
EXPERIMENTAL_FEATURES_CHANGED,
UI_SCALING_FACTOR_CHANGED,
X11_DISPLAY_OPENED,
N_SIGNALS
};
@ -83,10 +84,7 @@ struct _MetaBackendPrivate
MetaInputSettings *input_settings;
MetaRenderer *renderer;
MetaEgl *egl;
GSettings *mutter_settings;
MetaExperimentalFeature experimental_features;
gboolean experimental_features_overridden;
MetaSettings *settings;
ClutterBackend *clutter_backend;
ClutterActor *stage;
@ -99,8 +97,6 @@ struct _MetaBackendPrivate
MetaPointerConstraint *client_pointer_constraint;
MetaDnd *dnd;
int ui_scaling_factor;
};
typedef struct _MetaBackendPrivate MetaBackendPrivate;
@ -126,6 +122,8 @@ meta_backend_finalize (GObject *object)
g_hash_table_destroy (priv->device_monitors);
g_clear_object (&priv->settings);
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
}
@ -155,28 +153,10 @@ center_pointer (MetaBackend *backend)
primary->rect.y + primary->rect.height / 2);
}
static gboolean
meta_backend_update_ui_scaling_factor (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
int ui_scaling_factor;
ui_scaling_factor = meta_backend_get_ui_scaling_factor (backend);
if (ui_scaling_factor != priv->ui_scaling_factor)
{
priv->ui_scaling_factor = ui_scaling_factor;
return TRUE;
}
else
{
return FALSE;
}
}
void
meta_backend_monitors_changed (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
@ -194,8 +174,7 @@ meta_backend_monitors_changed (MetaBackend *backend)
center_pointer (backend);
}
if (meta_backend_update_ui_scaling_factor (backend))
meta_backend_notify_ui_scaling_factor_changed (backend);
meta_settings_update_ui_scaling_factor (priv->settings);
}
void
@ -245,6 +224,16 @@ destroy_device_monitor (MetaBackend *backend,
g_hash_table_remove (priv->device_monitors, &device_id);
}
static void
meta_backend_monitor_device (MetaBackend *backend,
ClutterInputDevice *device)
{
int device_id;
device_id = clutter_input_device_get_device_id (device);
create_device_monitor (backend, device_id);
}
static void
on_device_added (ClutterDeviceManager *device_manager,
ClutterInputDevice *device,
@ -352,10 +341,56 @@ create_monitor_manager (MetaBackend *backend)
return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend);
}
static void
create_device_monitors (MetaBackend *backend,
ClutterDeviceManager *device_manager)
{
const GSList *devices;
const GSList *l;
create_device_monitor (backend, META_IDLE_MONITOR_CORE_DEVICE);
devices = clutter_device_manager_peek_devices (device_manager);
for (l = devices; l; l = l->next)
{
ClutterInputDevice *device = l->data;
meta_backend_monitor_device (backend, device);
}
}
static void
set_initial_pointer_visibility (MetaBackend *backend,
ClutterDeviceManager *device_manager)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
const GSList *devices;
const GSList *l;
gboolean has_touchscreen = FALSE;
devices = clutter_device_manager_peek_devices (device_manager);
for (l = devices; l; l = l->next)
{
ClutterInputDevice *device = l->data;
has_touchscreen |= device_is_slave_touchscreen (device);
}
meta_cursor_tracker_set_pointer_visible (priv->cursor_tracker,
!has_touchscreen);
}
static MetaInputSettings *
meta_backend_create_input_settings (MetaBackend *backend)
{
return META_BACKEND_GET_CLASS (backend)->create_input_settings (backend);
}
static void
meta_backend_real_post_init (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
ClutterDeviceManager *device_manager = clutter_device_manager_get_default ();
priv->stage = meta_stage_new ();
clutter_actor_realize (priv->stage);
@ -365,45 +400,22 @@ meta_backend_real_post_init (MetaBackend *backend)
meta_backend_sync_screen_size (backend);
meta_backend_update_ui_scaling_factor (backend);
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
priv->device_monitors =
g_hash_table_new_full (g_int_hash, g_int_equal,
NULL, (GDestroyNotify) g_object_unref);
{
MetaCursorTracker *cursor_tracker;
ClutterDeviceManager *manager;
gboolean has_touchscreen = FALSE;
GSList *devices, *l;
create_device_monitors (backend, device_manager);
/* Create the core device monitor. */
create_device_monitor (backend, 0);
g_signal_connect_object (device_manager, "device-added",
G_CALLBACK (on_device_added), backend, 0);
g_signal_connect_object (device_manager, "device-removed",
G_CALLBACK (on_device_removed), backend, 0);
manager = clutter_device_manager_get_default ();
g_signal_connect_object (manager, "device-added",
G_CALLBACK (on_device_added), backend, 0);
g_signal_connect_object (manager, "device-removed",
G_CALLBACK (on_device_removed), backend, 0);
set_initial_pointer_visibility (backend, device_manager);
devices = clutter_device_manager_list_devices (manager);
for (l = devices; l != NULL; l = l->next)
{
ClutterInputDevice *device = l->data;
on_device_added (manager, device, backend);
has_touchscreen |= device_is_slave_touchscreen (device);
}
cursor_tracker = priv->cursor_tracker;
meta_cursor_tracker_set_pointer_visible (cursor_tracker, !has_touchscreen);
g_slist_free (devices);
}
priv->input_settings = meta_input_settings_create ();
priv->input_settings = meta_backend_create_input_settings (backend);
center_pointer (backend);
}
@ -449,105 +461,6 @@ meta_backend_real_get_relative_motion_deltas (MetaBackend *backend,
return FALSE;
}
static gboolean
experimental_features_handler (GVariant *features_variant,
gpointer *result,
gpointer data)
{
MetaBackend *backend = data;
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
GVariantIter features_iter;
char *feature;
MetaExperimentalFeature features = META_EXPERIMENTAL_FEATURE_NONE;
if (priv->experimental_features_overridden)
{
*result = GINT_TO_POINTER (FALSE);
return TRUE;
}
g_variant_iter_init (&features_iter, features_variant);
while (g_variant_iter_loop (&features_iter, "s", &feature))
{
/* So far no experimental features defined. */
if (g_str_equal (feature, "scale-monitor-framebuffer"))
features |= META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER;
else if (g_str_equal (feature, "monitor-config-manager"))
features |= META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER;
else
g_info ("Unknown experimental feature '%s'\n", feature);
}
if (features != priv->experimental_features)
{
priv->experimental_features = features;
*result = GINT_TO_POINTER (TRUE);
}
else
{
*result = GINT_TO_POINTER (FALSE);
}
return TRUE;
}
static gboolean
update_experimental_features (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
return GPOINTER_TO_INT (g_settings_get_mapped (priv->mutter_settings,
"experimental-features",
experimental_features_handler,
backend));
}
static void
mutter_settings_changed (GSettings *settings,
gchar *key,
MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
MetaExperimentalFeature old_experimental_features;
gboolean changed;
if (!g_str_equal (key, "experimental-features"))
return;
old_experimental_features = priv->experimental_features;
changed = update_experimental_features (backend);
if (changed)
g_signal_emit (backend, signals[EXPERIMENTAL_FEATURES_CHANGED], 0,
(unsigned int) old_experimental_features);
}
gboolean
meta_backend_is_experimental_feature_enabled (MetaBackend *backend,
MetaExperimentalFeature feature)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
return !!(priv->experimental_features & feature);
}
void
meta_backend_override_experimental_features (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
priv->experimental_features = META_EXPERIMENTAL_FEATURE_NONE;
priv->experimental_features_overridden = TRUE;
}
void
meta_backend_enable_experimental_feature (MetaBackend *backend,
MetaExperimentalFeature feature)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
priv->experimental_features |= feature;
}
static void
meta_backend_class_init (MetaBackendClass *klass)
{
@ -584,15 +497,8 @@ meta_backend_class_init (MetaBackendClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_INT);
signals[EXPERIMENTAL_FEATURES_CHANGED] =
g_signal_new ("experimental-features-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_UINT);
signals[UI_SCALING_FACTOR_CHANGED] =
g_signal_new ("ui-scaling-factor-changed",
signals[X11_DISPLAY_OPENED] =
g_signal_new ("x11-display-opened",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
@ -611,11 +517,7 @@ meta_backend_initable_init (GInitable *initable,
MetaBackend *backend = META_BACKEND (initable);
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
priv->mutter_settings = g_settings_new ("org.gnome.mutter");
g_signal_connect (priv->mutter_settings, "changed",
G_CALLBACK (mutter_settings_changed),
backend);
update_experimental_features (backend);
priv->settings = meta_settings_new (backend);
priv->egl = g_object_new (META_TYPE_EGL, NULL);
@ -650,7 +552,11 @@ meta_backend_init (MetaBackend *backend)
static void
meta_backend_post_init (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
META_BACKEND_GET_CLASS (backend)->post_init (backend);
meta_settings_post_init (priv->settings);
}
/**
@ -698,7 +604,8 @@ meta_backend_get_cursor_renderer (MetaBackend *backend)
/**
* meta_backend_get_renderer: (skip)
*/
MetaRenderer * meta_backend_get_renderer (MetaBackend *backend)
MetaRenderer *
meta_backend_get_renderer (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
@ -708,13 +615,25 @@ MetaRenderer * meta_backend_get_renderer (MetaBackend *backend)
/**
* meta_backend_get_egl: (skip)
*/
MetaEgl * meta_backend_get_egl (MetaBackend *backend)
MetaEgl *
meta_backend_get_egl (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
return priv->egl;
}
/**
* meta_backend_get_settings: (skip)
*/
MetaSettings *
meta_backend_get_settings (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
return priv->settings;
}
/**
* meta_backend_grab_device: (skip)
*/
@ -1010,27 +929,10 @@ meta_clutter_init (void)
meta_backend_post_init (_backend);
}
static void
xft_dpi_changed (GtkSettings *settings,
GParamSpec *pspec,
MetaBackend *backend)
{
meta_backend_update_ui_scaling_factor (backend);
meta_backend_notify_ui_scaling_factor_changed (backend);
}
void
meta_backend_display_opened (MetaBackend *backend)
meta_backend_x11_display_opened (MetaBackend *backend)
{
/*
* gdk-window-scaling-factor is not exported to gtk-settings
* because it is handled inside gdk, so we use gtk-xft-dpi instead
* which also changes when the scale factor changes.
*
* TODO: Don't rely on GtkSettings for this
*/
g_signal_connect (gtk_settings_get_default (), "notify::gtk-xft-dpi",
G_CALLBACK (xft_dpi_changed), backend);
g_signal_emit (backend, signals[X11_DISPLAY_OPENED], 0);
}
gboolean
@ -1095,46 +997,3 @@ meta_backend_notify_keymap_layout_group_changed (MetaBackend *backend,
g_signal_emit (backend, signals[KEYMAP_LAYOUT_GROUP_CHANGED], 0,
locked_group);
}
static int
calculate_ui_scaling_factor (MetaBackend *backend)
{
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
GList *logical_monitors;
GList *l;
int max_scale = 1;
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
max_scale = MAX (logical_monitor->scale, max_scale);
}
return max_scale;
}
int
meta_backend_get_ui_scaling_factor (MetaBackend *backend)
{
if (meta_is_stage_views_scaled ())
{
return 1;
}
else
{
if (meta_is_monitor_config_manager_enabled ())
return calculate_ui_scaling_factor (backend);
else
return meta_theme_get_window_scaling_factor ();
}
}
void
meta_backend_notify_ui_scaling_factor_changed (MetaBackend *backend)
{
g_signal_emit (backend, signals[UI_SCALING_FACTOR_CHANGED], 0);
}

View File

@ -31,20 +31,9 @@
#include <libwacom/libwacom.h>
#endif
#define META_TYPE_INPUT_SETTINGS (meta_input_settings_get_type ())
#define META_INPUT_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_INPUT_SETTINGS, MetaInputSettings))
#define META_INPUT_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_INPUT_SETTINGS, MetaInputSettingsClass))
#define META_IS_INPUT_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_INPUT_SETTINGS))
#define META_IS_INPUT_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_INPUT_SETTINGS))
#define META_INPUT_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_INPUT_SETTINGS, MetaInputSettingsClass))
typedef struct _MetaInputSettings MetaInputSettings;
typedef struct _MetaInputSettingsClass MetaInputSettingsClass;
struct _MetaInputSettings
{
GObject parent_instance;
};
#define META_TYPE_INPUT_SETTINGS (meta_input_settings_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaInputSettings, meta_input_settings,
META, INPUT_SETTINGS, GObject)
struct _MetaInputSettingsClass
{
@ -65,6 +54,9 @@ struct _MetaInputSettingsClass
void (* set_tap_enabled) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled);
void (* set_disable_while_typing) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled);
void (* set_invert_scroll) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean inverted);
@ -117,15 +109,10 @@ struct _MetaInputSettingsClass
ClutterInputDeviceTool *tool,
GDesktopStylusButtonAction primary,
GDesktopStylusButtonAction secondary);
gboolean (* has_two_finger_scroll) (MetaInputSettings *settings,
ClutterInputDevice *device);
};
GType meta_input_settings_get_type (void) G_GNUC_CONST;
MetaInputSettings * meta_input_settings_create (void);
GSettings * meta_input_settings_get_tablet_settings (MetaInputSettings *settings,
ClutterInputDevice *device);
MetaLogicalMonitor * meta_input_settings_get_tablet_logical_monitor (MetaInputSettings *settings,

View File

@ -33,12 +33,6 @@
#include "meta-input-settings-private.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor.h"
#include "x11/meta-input-settings-x11.h"
#ifdef HAVE_NATIVE_BACKEND
#include "native/meta-backend-native.h"
#include "native/meta-input-settings-native.h"
#endif
#include <glib/gi18n-lib.h>
#include <meta/util.h>
@ -448,6 +442,44 @@ update_device_natural_scroll (MetaInputSettings *input_settings,
}
}
static void
update_touchpad_disable_while_typing (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
GSettings *settings;
MetaInputSettingsClass *input_settings_class;
MetaInputSettingsPrivate *priv;
gboolean enabled;
const gchar *key = "disable-while-typing";
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, key);
if (device)
{
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,
input_settings_class->set_disable_while_typing,
enabled);
}
else
{
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
input_settings_class->set_disable_while_typing,
enabled);
}
}
static void
update_touchpad_tap_enabled (MetaInputSettings *input_settings,
ClutterInputDevice *device)
@ -700,7 +732,7 @@ logical_monitor_has_monitor (MetaMonitorManager *monitor_manager,
GList *monitors;
GList *l;
monitors = meta_monitor_manager_get_monitors (monitor_manager);
monitors = meta_logical_monitor_get_monitors (logical_monitor);
for (l = monitors; l; l = l->next)
{
MetaMonitor *monitor = l->data;
@ -989,6 +1021,8 @@ meta_input_settings_changed_cb (GSettings *settings,
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, "disable-while-typing") == 0)
update_touchpad_disable_while_typing (input_settings, NULL);
else if (strcmp (key, "send-events") == 0)
update_touchpad_send_events (input_settings, NULL);
else if (strcmp (key, "edge-scrolling-enabled") == 0)
@ -1234,6 +1268,7 @@ apply_device_settings (MetaInputSettings *input_settings,
update_touchpad_left_handed (input_settings, device);
update_touchpad_tap_enabled (input_settings, device);
update_touchpad_disable_while_typing (input_settings, device);
update_touchpad_send_events (input_settings, device);
update_touchpad_two_finger_scroll (input_settings, device);
update_touchpad_edge_scroll (input_settings, device);
@ -1478,23 +1513,6 @@ meta_input_settings_init (MetaInputSettings *settings)
priv->two_finger_devices = g_hash_table_new (NULL, NULL);
}
MetaInputSettings *
meta_input_settings_create (void)
{
#ifdef HAVE_NATIVE_BACKEND
MetaBackend *backend;
backend = meta_get_backend ();
if (META_IS_BACKEND_NATIVE (backend))
return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, NULL);
#endif
if (!meta_is_wayland_compositor ())
return g_object_new (META_TYPE_INPUT_SETTINGS_X11, NULL);
return NULL;
}
GSettings *
meta_input_settings_get_tablet_settings (MetaInputSettings *settings,
ClutterInputDevice *device)
@ -1619,7 +1637,7 @@ cycle_logical_monitors (MetaInputSettings *settings,
if (l->next)
*next_logical_monitor = l->next->data;
else
*next_logical_monitor = logical_monitors->data;
*next_logical_monitor = NULL;
}
return TRUE;

View File

@ -107,21 +107,15 @@ MetaLogicalMonitor *
meta_logical_monitor_new_derived (MetaMonitorManager *monitor_manager,
MetaMonitor *monitor,
MetaRectangle *layout,
int scale,
int monitor_number)
{
MetaLogicalMonitor *logical_monitor;
MetaOutput *main_output;
MetaMonitorMode *monitor_mode;
int scale;
MetaMonitorTransform transform;
logical_monitor = g_object_new (META_TYPE_LOGICAL_MONITOR, NULL);
monitor_mode = meta_monitor_get_current_mode (monitor);
scale = meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager,
monitor,
monitor_mode);
transform = derive_monitor_transform (monitor);
main_output = meta_monitor_get_main_output (monitor);

View File

@ -68,6 +68,7 @@ MetaLogicalMonitor * meta_logical_monitor_new (MetaMonitorManager *monitor
MetaLogicalMonitor * meta_logical_monitor_new_derived (MetaMonitorManager *monitor_manager,
MetaMonitor *monitor,
MetaRectangle *layout,
int scale,
int monitor_number);
void meta_logical_monitor_add_monitor (MetaLogicalMonitor *logical_monitor,

View File

@ -483,6 +483,7 @@ create_preferred_logical_monitor_config (MetaMonitorManager *monitor_ma
MetaMonitor *monitor,
int x,
int y,
MetaLogicalMonitorConfig *primary_logical_monitor_config,
MetaLogicalMonitorLayoutMode layout_mode)
{
MetaMonitorMode *mode;
@ -493,9 +494,15 @@ create_preferred_logical_monitor_config (MetaMonitorManager *monitor_ma
mode = meta_monitor_get_preferred_mode (monitor);
meta_monitor_mode_get_resolution (mode, &width, &height);
scale = meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager,
monitor,
mode);
if ((meta_monitor_manager_get_capabilities (monitor_manager) &
META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED) &&
primary_logical_monitor_config)
scale = primary_logical_monitor_config->scale;
else
scale = meta_monitor_manager_calculate_monitor_mode_scale (monitor_manager,
monitor,
mode);
switch (layout_mode)
{
@ -546,6 +553,7 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana
create_preferred_logical_monitor_config (monitor_manager,
primary_monitor,
0, 0,
NULL,
layout_mode);
primary_logical_monitor_config->is_primary = TRUE;
logical_monitor_configs = g_list_append (NULL,
@ -569,6 +577,7 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana
create_preferred_logical_monitor_config (monitor_manager,
monitor,
x, 0,
primary_logical_monitor_config,
layout_mode);
logical_monitor_configs = g_list_append (logical_monitor_configs,
logical_monitor_config);
@ -598,6 +607,7 @@ meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_ma
create_preferred_logical_monitor_config (monitor_manager,
primary_monitor,
0, 0,
NULL,
layout_mode);
primary_logical_monitor_config->is_primary = TRUE;
logical_monitor_configs = g_list_append (NULL,
@ -615,6 +625,7 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
MetaLogicalMonitorLayoutMode layout_mode;
GList *logical_monitor_configs;
GList *region;
int x, y;
GList *monitors;
GList *l;
@ -622,16 +633,30 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
if (!primary_monitor)
return NULL;
if (!meta_monitor_get_suggested_position (primary_monitor, &x, &y))
return NULL;
layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
logical_monitor_configs = NULL;
region = NULL;
primary_logical_monitor_config =
create_preferred_logical_monitor_config (monitor_manager,
primary_monitor,
x, y,
NULL,
layout_mode);
primary_logical_monitor_config->is_primary = TRUE;
logical_monitor_configs = g_list_append (NULL,
primary_logical_monitor_config);
region = g_list_prepend (NULL, &primary_logical_monitor_config->layout);
monitors = meta_monitor_manager_get_monitors (monitor_manager);
for (l = monitors; l; l = l->next)
{
MetaMonitor *monitor = l->data;
MetaLogicalMonitorConfig *logical_monitor_config;
int x, y;
if (monitor == primary_monitor)
continue;
if (!meta_monitor_get_suggested_position (monitor, &x, &y))
continue;
@ -640,6 +665,7 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
create_preferred_logical_monitor_config (monitor_manager,
monitor,
x, y,
primary_logical_monitor_config,
layout_mode);
logical_monitor_configs = g_list_append (logical_monitor_configs,
logical_monitor_config);
@ -655,9 +681,6 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
}
region = g_list_prepend (region, &logical_monitor_config->layout);
if (monitor == primary_monitor)
primary_logical_monitor_config = logical_monitor_config;
}
g_list_free (region);
@ -665,12 +688,6 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
if (!logical_monitor_configs)
return NULL;
if (!primary_logical_monitor_config)
primary_logical_monitor_config =
g_list_first (logical_monitor_configs)->data;
primary_logical_monitor_config->is_primary = TRUE;
return meta_monitors_config_new (logical_monitor_configs, layout_mode);
}
@ -1024,12 +1041,14 @@ has_adjecent_neighbour (MetaMonitorsConfig *config,
gboolean
meta_verify_monitors_config (MetaMonitorsConfig *config,
MetaMonitorManager *monitor_manager,
GError **error)
{
int min_x, min_y;
gboolean has_primary;
GList *region;
GList *l;
gboolean global_scale_required;
if (!config->logical_monitor_configs)
{
@ -1038,6 +1057,10 @@ meta_verify_monitors_config (MetaMonitorsConfig *config,
return FALSE;
}
global_scale_required =
!!(meta_monitor_manager_get_capabilities (monitor_manager) &
META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED);
min_x = INT_MAX;
min_y = INT_MAX;
region = NULL;
@ -1046,6 +1069,21 @@ meta_verify_monitors_config (MetaMonitorsConfig *config,
{
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
if (global_scale_required)
{
MetaLogicalMonitorConfig *prev_logical_monitor_config =
l->prev ? l->prev->data : NULL;
if (prev_logical_monitor_config &&
(prev_logical_monitor_config->scale !=
logical_monitor_config->scale))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Logical monitor scales must be identical");
return FALSE;
}
}
if (meta_rectangle_overlaps_with_region (region,
&logical_monitor_config->layout))
{

View File

@ -120,6 +120,7 @@ gboolean meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logica
GError **error);
gboolean meta_verify_monitors_config (MetaMonitorsConfig *config,
MetaMonitorManager *monitor_manager,
GError **error);
#endif /* META_MONITOR_CONFIG_MANAGER_H */

View File

@ -640,7 +640,8 @@ handle_end_element (GMarkupParseContext *context,
parser->current_logical_monitor_configs = NULL;
if (!meta_verify_monitors_config (config, error))
if (!meta_verify_monitors_config (config, store->monitor_manager,
error))
{
g_object_unref (config);
return;

View File

@ -357,9 +357,16 @@ meta_monitor_manager_dummy_ensure_initial_config (MetaMonitorManager *manager)
config = meta_monitor_manager_ensure_configured (manager);
if (meta_is_monitor_config_manager_enabled ())
meta_monitor_manager_update_logical_state (manager, config);
{
meta_monitor_manager_update_logical_state (manager, config);
}
else
meta_monitor_manager_update_logical_state_derived (manager);
{
MetaMonitorManagerDeriveFlag flags =
META_MONITOR_MANAGER_DERIVE_FLAG_NONE;
meta_monitor_manager_update_logical_state_derived (manager, flags);
}
}
static void
@ -565,11 +572,14 @@ meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager,
MetaOutputInfo **outputs,
unsigned int n_outputs)
{
MetaMonitorManagerDeriveFlag flags =
META_MONITOR_MANAGER_DERIVE_FLAG_NONE;
apply_crtc_assignments (manager, crtcs, n_crtcs, outputs, n_outputs);
legacy_calculate_screen_size (manager);
meta_monitor_manager_rebuild_derived (manager);
meta_monitor_manager_rebuild_derived (manager, flags);
}
static gboolean
@ -609,22 +619,25 @@ static gboolean
is_monitor_framebuffers_scaled (void)
{
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
return meta_backend_is_experimental_feature_enabled (
backend,
return meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
}
static MetaMonitorManagerCapability
meta_monitor_manager_dummy_get_capabilities (MetaMonitorManager *manager)
{
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
MetaMonitorManagerCapability capabilities =
META_MONITOR_MANAGER_CAPABILITY_NONE;
capabilities |= META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
if (meta_backend_is_experimental_feature_enabled (
meta_get_backend (),
if (meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER))
capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE;

View File

@ -72,7 +72,8 @@ typedef enum _MetaMonitorManagerCapability
{
META_MONITOR_MANAGER_CAPABILITY_NONE = 0,
META_MONITOR_MANAGER_CAPABILITY_MIRRORING = (1 << 0),
META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE = (1 << 1)
META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE = (1 << 1),
META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED = (1 << 2)
} MetaMonitorManagerCapability;
/* Equivalent to the 'method' enum in org.gnome.Mutter.DisplayConfig */
@ -90,6 +91,12 @@ typedef enum _MetaLogicalMonitorLayoutMode
META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL = 2
} MetaLogicalMonitorLayoutMode;
typedef enum _MetaMonitorManagerDeriveFlag
{
META_MONITOR_MANAGER_DERIVE_FLAG_NONE = 0,
META_MONITOR_MANAGER_DERIVE_FLAG_CONFIGURED_SCALE = (1 << 0)
} MetaMonitorManagerDeriveFlag;
typedef enum
{
META_MONITOR_TRANSFORM_NORMAL,
@ -404,7 +411,8 @@ gboolean meta_is_monitor_config_manager_enabled (void);
void meta_monitor_manager_rebuild (MetaMonitorManager *manager,
MetaMonitorsConfig *config);
void meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager);
void meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager,
MetaMonitorManagerDeriveFlag flags);
int meta_monitor_manager_get_num_logical_monitors (MetaMonitorManager *manager);
@ -487,7 +495,8 @@ MetaMonitorsConfig * meta_monitor_manager_ensure_configured (MetaMonitorManager
void meta_monitor_manager_update_logical_state (MetaMonitorManager *manager,
MetaMonitorsConfig *config);
void meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager);
void meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager,
MetaMonitorManagerDeriveFlag flags);
gboolean meta_monitor_manager_is_lid_closed (MetaMonitorManager *manager);
@ -499,6 +508,9 @@ int meta_monitor_manager_calculate_monitor_mode_scale (MetaMonito
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode);
MetaMonitorManagerCapability
meta_monitor_manager_get_capabilities (MetaMonitorManager *manager);
gboolean meta_monitor_manager_get_max_screen_size (MetaMonitorManager *manager,
int *max_width,
int *max_height);

View File

@ -77,8 +77,11 @@ meta_monitor_manager_init (MetaMonitorManager *manager)
gboolean
meta_is_monitor_config_manager_enabled (void)
{
return meta_backend_is_experimental_feature_enabled (
meta_get_backend (),
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
return meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER);
}
@ -181,16 +184,95 @@ derive_monitor_layout (MetaMonitor *monitor,
meta_monitor_derive_dimensions (monitor, &layout->width, &layout->height);
}
static int
derive_configured_global_scale (MetaMonitorManager *manager)
{
MetaMonitorsConfig *config;
MetaLogicalMonitorConfig *logical_monitor_config;
config = meta_monitor_config_manager_get_current (manager->config_manager);
if (!config)
return 1;
logical_monitor_config = config->logical_monitor_configs->data;
return logical_monitor_config->scale;
}
static int
calculate_monitor_scale (MetaMonitorManager *manager,
MetaMonitor *monitor)
{
MetaMonitorMode *monitor_mode;
monitor_mode = meta_monitor_get_current_mode (monitor);
return meta_monitor_manager_calculate_monitor_mode_scale (manager,
monitor,
monitor_mode);
}
static int
derive_calculated_global_scale (MetaMonitorManager *manager)
{
MetaMonitor *primary_monitor;
primary_monitor = meta_monitor_manager_get_primary_monitor (manager);
if (!primary_monitor)
return 1;
return calculate_monitor_scale (manager, primary_monitor);
}
static int
derive_scale_from_config (MetaMonitorManager *manager,
MetaRectangle *layout)
{
MetaMonitorsConfig *config;
GList *l;
config = meta_monitor_config_manager_get_current (manager->config_manager);
for (l = config->logical_monitor_configs; l; l = l->next)
{
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
if (meta_rectangle_equal (layout, &logical_monitor_config->layout))
return logical_monitor_config->scale;
}
g_warning ("Missing logical monitor, using scale 1");
return 1;
}
static void
meta_monitor_manager_rebuild_logical_monitors_derived (MetaMonitorManager *manager)
meta_monitor_manager_rebuild_logical_monitors_derived (MetaMonitorManager *manager,
MetaMonitorManagerDeriveFlag flags)
{
GList *logical_monitors = NULL;
GList *l;
int monitor_number;
MetaLogicalMonitor *primary_logical_monitor = NULL;
gboolean use_configured_scale;
gboolean use_global_scale;
int global_scale = 0;
MetaMonitorManagerCapability capabilities;
monitor_number = 0;
capabilities = meta_monitor_manager_get_capabilities (manager);
use_global_scale =
!!(capabilities & META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED);
use_configured_scale =
!!(flags & META_MONITOR_MANAGER_DERIVE_FLAG_CONFIGURED_SCALE);
if (use_global_scale)
{
if (use_configured_scale)
global_scale = derive_configured_global_scale (manager);
else
global_scale = derive_calculated_global_scale (manager);
}
for (l = manager->monitors; l; l = l->next)
{
MetaMonitor *monitor = l->data;
@ -209,9 +291,21 @@ meta_monitor_manager_rebuild_logical_monitors_derived (MetaMonitorManager *manag
}
else
{
int scale;
if (use_global_scale)
scale = global_scale;
else if (use_configured_scale)
scale = derive_scale_from_config (manager, &layout);
else
scale = calculate_monitor_scale (manager, monitor);
g_assert (scale > 0);
logical_monitor = meta_logical_monitor_new_derived (manager,
monitor,
&layout,
scale,
monitor_number);
logical_monitors = g_list_append (logical_monitors, logical_monitor);
monitor_number++;
@ -281,6 +375,9 @@ lid_is_closed_changed (UpClient *client,
static gboolean
meta_monitor_manager_real_is_lid_closed (MetaMonitorManager *manager)
{
if (!manager->up_client)
return FALSE;
return up_client_get_lid_is_closed (manager->up_client);
}
@ -320,7 +417,7 @@ meta_monitor_manager_get_supported_scales (MetaMonitorManager *manager,
manager_class->get_supported_scales (manager, scales, n_scales);
}
static MetaMonitorManagerCapability
MetaMonitorManagerCapability
meta_monitor_manager_get_capabilities (MetaMonitorManager *manager)
{
MetaMonitorManagerClass *manager_class =
@ -392,7 +489,8 @@ meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager)
static gboolean
should_use_stored_config (MetaMonitorManager *manager)
{
return !meta_monitor_manager_has_hotplug_mode_update (manager);
return (manager->in_init ||
!meta_monitor_manager_has_hotplug_mode_update (manager));
}
static void
@ -520,7 +618,7 @@ done:
}
static void
experimental_features_changed (MetaBackend *backend,
experimental_features_changed (MetaSettings *settings,
MetaExperimentalFeature old_experimental_features,
MetaMonitorManager *manager)
{
@ -530,7 +628,6 @@ experimental_features_changed (MetaBackend *backend,
gboolean is_config_manager_enabled;
gboolean is_stage_views_scaled;
gboolean should_reconfigure = FALSE;
int ui_scaling_factor;
is_config_manager_enabled = meta_is_monitor_config_manager_enabled ();
was_config_manager_enabled =
@ -544,21 +641,18 @@ experimental_features_changed (MetaBackend *backend,
!!(old_experimental_features &
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
is_stage_views_scaled =
meta_backend_is_experimental_feature_enabled (
backend,
meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
if (is_config_manager_enabled != was_config_manager_enabled ||
is_stage_views_scaled != was_stage_views_scaled)
should_reconfigure = TRUE;
ui_scaling_factor = meta_backend_get_ui_scaling_factor (backend);
if (should_reconfigure)
meta_monitor_manager_on_hotplug (manager);
if (ui_scaling_factor != meta_backend_get_ui_scaling_factor (backend))
meta_backend_notify_ui_scaling_factor_changed (backend);
meta_settings_update_ui_scaling_factor (settings);
}
static void
@ -568,9 +662,11 @@ meta_monitor_manager_constructed (GObject *object)
MetaDBusDisplayConfig *skeleton = META_DBUS_DISPLAY_CONFIG (manager);
MetaMonitorManagerClass *manager_class =
META_MONITOR_MANAGER_GET_CLASS (manager);
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
manager->experimental_features_changed_handler_id =
g_signal_connect (meta_get_backend (),
g_signal_connect (settings,
"experimental-features-changed",
G_CALLBACK (experimental_features_changed),
manager);
@ -1561,6 +1657,13 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
g_variant_new_boolean (TRUE));
}
if (capabilities & META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED)
{
g_variant_builder_add (&properties_builder, "{sv}",
"global-scale-required",
g_variant_new_boolean (TRUE));
}
if (meta_monitor_manager_get_max_screen_size (manager,
&max_screen_width,
&max_screen_height))
@ -1995,7 +2098,7 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet
}
config = meta_monitors_config_new (logical_monitor_configs, layout_mode);
if (!meta_verify_monitors_config (config, &error))
if (!meta_verify_monitors_config (config, manager, &error))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_INVALID_ARGS,
@ -2558,7 +2661,7 @@ rebuild_monitors (MetaMonitorManager *manager)
{
MetaMonitorNormal *monitor_normal;
monitor_normal = meta_monitor_normal_new (output);
monitor_normal = meta_monitor_normal_new (manager, output);
manager->monitors = g_list_append (manager->monitors,
monitor_normal);
}
@ -2727,15 +2830,17 @@ meta_monitor_manager_update_monitor_modes_derived (MetaMonitorManager *manager)
}
void
meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager)
meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager,
MetaMonitorManagerDeriveFlag flags)
{
manager->layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
meta_monitor_manager_rebuild_logical_monitors_derived (manager);
meta_monitor_manager_rebuild_logical_monitors_derived (manager, flags);
}
void
meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager)
meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager,
MetaMonitorManagerDeriveFlag flags)
{
GList *old_logical_monitors;
@ -2746,7 +2851,7 @@ meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager)
old_logical_monitors = manager->logical_monitors;
meta_monitor_manager_update_logical_state_derived (manager);
meta_monitor_manager_update_logical_state_derived (manager, flags);
meta_monitor_manager_notify_monitors_changed (manager);

View File

@ -25,6 +25,7 @@
#include "backends/meta-backend-private.h"
#include "backends/meta-monitor-manager-private.h"
#include "backends/meta-settings-private.h"
typedef struct _MetaMonitorMode
{
@ -41,6 +42,8 @@ typedef struct _MetaMonitorModeTiled
typedef struct _MetaMonitorPrivate
{
MetaMonitorManager *monitor_manager;
GList *outputs;
GList *modes;
@ -76,6 +79,10 @@ struct _MetaMonitorTiled
uint32_t tile_group_id;
/* The tile (0, 0) output. */
MetaOutput *origin_output;
/* The output enabled even when a non-tiled mode is used. */
MetaOutput *main_output;
};
@ -142,7 +149,7 @@ meta_monitor_spec_free (MetaMonitorSpec *monitor_spec)
}
static void
meta_monitor_generate_id (MetaMonitor *monitor)
meta_monitor_generate_spec (MetaMonitor *monitor)
{
MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
MetaOutput *output = meta_monitor_get_main_output (monitor);
@ -377,7 +384,8 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
}
MetaMonitorNormal *
meta_monitor_normal_new (MetaOutput *output)
meta_monitor_normal_new (MetaMonitorManager *monitor_manager,
MetaOutput *output)
{
MetaMonitorNormal *monitor_normal;
MetaMonitor *monitor;
@ -387,11 +395,13 @@ meta_monitor_normal_new (MetaOutput *output)
monitor = META_MONITOR (monitor_normal);
monitor_priv = meta_monitor_get_instance_private (monitor);
monitor_priv->monitor_manager = monitor_manager;
monitor_priv->outputs = g_list_append (NULL, output);
monitor_priv->winsys_id = output->winsys_id;
meta_monitor_generate_spec (monitor);
meta_monitor_normal_generate_modes (monitor_normal);
meta_monitor_generate_id (monitor);
return monitor_normal;
}
@ -417,6 +427,23 @@ meta_monitor_normal_derive_dimensions (MetaMonitor *monitor,
*height = output->crtc->rect.height;
}
static gboolean
meta_monitor_normal_get_suggested_position (MetaMonitor *monitor,
int *x,
int *y)
{
MetaOutput *output;
output = meta_monitor_get_main_output (monitor);
if (output->suggested_x < 0 && output->suggested_y < 0)
return FALSE;
*x = output->suggested_x;
*y = output->suggested_y;
return TRUE;
}
static void
meta_monitor_normal_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
@ -442,6 +469,7 @@ meta_monitor_normal_class_init (MetaMonitorNormalClass *klass)
monitor_class->get_main_output = meta_monitor_normal_get_main_output;
monitor_class->derive_dimensions = meta_monitor_normal_derive_dimensions;
monitor_class->calculate_crtc_pos = meta_monitor_normal_calculate_crtc_pos;
monitor_class->get_suggested_position = meta_monitor_normal_get_suggested_position;
}
uint32_t
@ -455,16 +483,8 @@ meta_monitor_get_suggested_position (MetaMonitor *monitor,
int *x,
int *y)
{
MetaOutput *main_output;
main_output = meta_monitor_get_main_output (monitor);
if (main_output->suggested_x < 0 && main_output->suggested_y < 0)
return FALSE;
*x = main_output->suggested_x;
*y = main_output->suggested_y;
return TRUE;
return META_MONITOR_GET_CLASS (monitor)->get_suggested_position (monitor,
x, y);
}
static void
@ -483,7 +503,7 @@ add_tiled_monitor_outputs (MetaMonitorManager *monitor_manager,
continue;
g_warn_if_fail (output->subpixel_order ==
monitor_tiled->main_output->subpixel_order);
monitor_tiled->origin_output->subpixel_order);
monitor_priv->outputs = g_list_append (monitor_priv->outputs, output);
}
@ -603,15 +623,53 @@ is_monitor_mode_assigned (MetaMonitor *monitor,
return TRUE;
}
static gboolean
is_crtc_mode_tiled (MetaOutput *output,
MetaCrtcMode *crtc_mode)
{
return (crtc_mode->width == (int) output->tile_info.tile_w &&
crtc_mode->height == (int) output->tile_info.tile_h);
}
static MetaCrtcMode *
find_tiled_crtc_mode (MetaOutput *output,
float refresh_rate)
{
MetaCrtcMode *crtc_mode;
unsigned int i;
crtc_mode = output->preferred_mode;
if (is_crtc_mode_tiled (output, crtc_mode))
return crtc_mode;
for (i = 0; i < output->n_modes; i++)
{
crtc_mode = output->modes[i];
if (!is_crtc_mode_tiled (output, crtc_mode))
continue;
if (crtc_mode->refresh_rate != refresh_rate)
continue;
return crtc_mode;
}
return NULL;
}
static MetaMonitorMode *
create_tiled_monitor_mode (MetaMonitorTiled *monitor_tiled)
create_tiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
float refresh_rate,
gboolean *out_is_preferred)
{
MetaMonitor *monitor = META_MONITOR (monitor_tiled);
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
MetaMonitorModeTiled *mode;
GList *l;
int i;
unsigned int i;
gboolean is_preferred = TRUE;
mode = g_new0 (MetaMonitorModeTiled, 1);
mode->is_tiled = TRUE;
@ -623,21 +681,85 @@ create_tiled_monitor_mode (MetaMonitorTiled *monitor_tiled)
for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++)
{
MetaOutput *output = l->data;
MetaCrtcMode *preferred_crtc_mode = output->preferred_mode;
MetaCrtcMode *tiled_crtc_mode;
tiled_crtc_mode = find_tiled_crtc_mode (output, refresh_rate);
if (!tiled_crtc_mode)
{
g_warning ("No tiled mode with refresh rate %f on %s",
refresh_rate, output->name);
meta_monitor_mode_free ((MetaMonitorMode *) mode);
return NULL;
}
mode->parent.crtc_modes[i] = (MetaMonitorCrtcMode) {
.output = output,
.crtc_mode = preferred_crtc_mode
.crtc_mode = tiled_crtc_mode
};
g_warn_if_fail (mode->parent.spec.refresh_rate == 0.0f ||
(mode->parent.spec.refresh_rate ==
preferred_crtc_mode->refresh_rate));
mode->parent.spec.refresh_rate = refresh_rate;
mode->parent.spec.refresh_rate = preferred_crtc_mode->refresh_rate;
is_preferred = is_preferred && tiled_crtc_mode == output->preferred_mode;
}
return &mode->parent;
*out_is_preferred = is_preferred;
return (MetaMonitorMode *) mode;
}
static void
generate_tiled_monitor_modes (MetaMonitorTiled *monitor_tiled)
{
MetaMonitor *monitor = META_MONITOR (monitor_tiled);
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
MetaOutput *main_output;
GList *tiled_modes = NULL;
unsigned int i;
main_output = meta_monitor_get_main_output (META_MONITOR (monitor_tiled));
for (i = 0; i < main_output->n_modes; i++)
{
MetaCrtcMode *crtc_mode = main_output->modes[i];
MetaMonitorMode *mode;
gboolean is_preferred;
if (!is_crtc_mode_tiled (main_output, crtc_mode))
continue;
mode = create_tiled_monitor_mode (monitor_tiled, crtc_mode->refresh_rate,
&is_preferred);
if (!mode)
continue;
tiled_modes = g_list_append (tiled_modes, mode);
if (is_monitor_mode_assigned (monitor, mode))
monitor_priv->current_mode = mode;
if (is_preferred)
monitor_priv->preferred_mode = mode;
}
if (!monitor_priv->preferred_mode)
{
MetaMonitorMode *best_mode = NULL;
GList *l;
for (l = tiled_modes; l; l = l->next)
{
MetaMonitorMode *mode = l->data;
if (!best_mode ||
mode->spec.refresh_rate > best_mode->spec.refresh_rate)
best_mode = mode;
}
monitor_priv->preferred_mode = best_mode;
}
monitor_priv->modes = g_list_concat (monitor_priv->modes, tiled_modes);
}
static MetaMonitorMode *
@ -652,12 +774,7 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
GList *l;
int i;
/*
* Assume modes with a resolution identical to the tile sizes are tiled
* modes.
*/
if (crtc_mode->width == (int) main_output->tile_info.tile_w &&
crtc_mode->height == (int) main_output->tile_info.tile_h)
if (is_crtc_mode_tiled (main_output, crtc_mode))
return NULL;
mode = g_new0 (MetaMonitorModeTiled, 1);
@ -694,42 +811,184 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
return &mode->parent;
}
static int
count_untiled_crtc_modes (MetaOutput *output)
{
int count;
unsigned int i;
count = 0;
for (i = 0; i < output->n_modes; i++)
{
MetaCrtcMode *crtc_mode = output->modes[i];
if (!is_crtc_mode_tiled (output, crtc_mode))
count++;
}
return count;
}
static MetaOutput *
find_untiled_output (MetaMonitorTiled *monitor_tiled)
{
MetaMonitor *monitor = META_MONITOR (monitor_tiled);
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
MetaOutput *best_output;
int best_untiled_crtc_mode_count;
GList *l;
best_output = monitor_tiled->origin_output;
best_untiled_crtc_mode_count =
count_untiled_crtc_modes (monitor_tiled->origin_output);
for (l = monitor_priv->outputs; l; l = l->next)
{
MetaOutput *output = l->data;
int untiled_crtc_mode_count;
if (output == monitor_tiled->origin_output)
continue;
untiled_crtc_mode_count = count_untiled_crtc_modes (output);
if (untiled_crtc_mode_count > best_untiled_crtc_mode_count)
{
best_untiled_crtc_mode_count = untiled_crtc_mode_count;
best_output = output;
}
}
return best_output;
}
static void
generate_untiled_monitor_modes (MetaMonitorTiled *monitor_tiled)
{
MetaMonitor *monitor = META_MONITOR (monitor_tiled);
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
MetaOutput *main_output;
unsigned int i;
main_output = meta_monitor_get_main_output (monitor);
for (i = 0; i < main_output->n_modes; i++)
{
MetaCrtcMode *crtc_mode = main_output->modes[i];
MetaMonitorMode *mode;
mode = create_untiled_monitor_mode (monitor_tiled,
main_output,
crtc_mode);
if (!mode)
continue;
monitor_priv->modes = g_list_append (monitor_priv->modes, mode);
if (is_monitor_mode_assigned (monitor, mode))
{
g_assert (!monitor_priv->current_mode);
monitor_priv->current_mode = mode;
}
if (!monitor_priv->preferred_mode &&
crtc_mode == main_output->preferred_mode)
monitor_priv->preferred_mode = mode;
}
}
static MetaMonitorMode *
find_best_mode (MetaMonitor *monitor)
{
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
MetaMonitorMode *best_mode = NULL;
GList *l;
for (l = monitor_priv->modes; l; l = l->next)
{
MetaMonitorMode *mode = l->data;
int area, best_area;
if (!best_mode)
{
best_mode = mode;
continue;
}
area = mode->spec.width * mode->spec.height;
best_area = best_mode->spec.width * best_mode->spec.height;
if (area > best_area)
{
best_mode = mode;
continue;
}
if (mode->spec.refresh_rate > best_mode->spec.refresh_rate)
{
best_mode = mode;
continue;
}
}
return best_mode;
}
static void
meta_monitor_tiled_generate_modes (MetaMonitorTiled *monitor_tiled)
{
MetaMonitor *monitor = META_MONITOR (monitor_tiled);
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
MetaMonitorMode *mode;
MetaOutput *main_output;
unsigned int i;
mode = create_tiled_monitor_mode (monitor_tiled);
monitor_priv->modes = g_list_append (monitor_priv->modes, mode);
/*
* Tiled monitors may look a bit different from each other, depending on the
* monitor itself, the driver, etc.
*
* On some, the tiled modes will be the preferred CRTC modes, and running
* untiled is done by only enabling (0, 0) tile. In this case, things are
* pretty straight forward.
*
* Other times a monitor may have some bogus mode preferred on the main tile,
* and an untiled mode preferred on the non-main tile, and there seems to be
* no guarantee that the (0, 0) tile is the one that should drive the
* non-tiled mode.
*
* To handle both these cases, the following hueristics are implemented:
*
* 1) Find all the tiled CRTC modes of the (0, 0) tile, and create tiled
* monitor modes for all tiles based on these.
* 2) If there is any tiled monitor mode combination where all CRTC modes
* are the preferred ones, that one is marked as preferred.
* 3) If there is no preferred mode determined so far, assume the tiled
* monitor mode with the highest refresh rate is preferred.
* 4) Find the tile with highest number of untiled CRTC modes available,
* assume this is the one driving the monitor in untiled mode, and
* create monitor modes for all untiled CRTC modes of that tile. If
* there is still no preferred mode, set any untiled mode as preferred
* if the CRTC mode is marked as such.
* 5) If at this point there is still no preferred mode, just pick the one
* with the highest number of pixels and highest refresh rate.
*
* Note that this ignores the preference if the preference is a non-tiled
* mode. This seems to be the case on some systems, where the user tends to
* manually set up the tiled mode anyway.
*/
monitor_priv->preferred_mode = mode;
generate_tiled_monitor_modes (monitor_tiled);
if (is_monitor_mode_assigned (monitor, mode))
monitor_priv->current_mode = mode;
if (!monitor_priv->preferred_mode)
g_warning ("Tiled monitor on %s didn't have any tiled modes",
monitor_priv->spec->connector);
main_output = meta_monitor_get_main_output (monitor);
for (i = 0; i < main_output->n_modes; i++)
generate_untiled_monitor_modes (monitor_tiled);
if (!monitor_priv->preferred_mode)
{
MetaCrtcMode *crtc_mode = main_output->modes[i];
mode = create_untiled_monitor_mode (monitor_tiled,
main_output,
crtc_mode);
if (mode)
{
monitor_priv->modes = g_list_append (monitor_priv->modes, mode);
if (is_monitor_mode_assigned (monitor, mode))
{
g_assert (!monitor_priv->current_mode);
monitor_priv->current_mode = mode;
}
}
g_warning ("Tiled monitor on %s didn't have a valid preferred mode",
monitor_priv->spec->connector);
monitor_priv->preferred_mode = find_best_mode (monitor);
}
}
@ -745,17 +1004,22 @@ meta_monitor_tiled_new (MetaMonitorManager *monitor_manager,
monitor = META_MONITOR (monitor_tiled);
monitor_priv = meta_monitor_get_instance_private (monitor);
monitor_priv->monitor_manager = monitor_manager;
monitor_tiled->tile_group_id = output->tile_info.group_id;
monitor_priv->winsys_id = output->winsys_id;
monitor_tiled->main_output = output;
monitor_tiled->origin_output = output;
add_tiled_monitor_outputs (monitor_manager, monitor_tiled);
monitor_tiled->main_output = find_untiled_output (monitor_tiled);
meta_monitor_generate_spec (monitor);
meta_monitor_manager_tiled_monitor_added (monitor_manager,
META_MONITOR (monitor_tiled));
meta_monitor_tiled_generate_modes (monitor_tiled);
meta_monitor_generate_id (monitor);
return monitor_tiled;
}
@ -799,6 +1063,14 @@ meta_monitor_tiled_derive_dimensions (MetaMonitor *monitor,
*out_height = max_y - min_y;
}
static gboolean
meta_monitor_tiled_get_suggested_position (MetaMonitor *monitor,
int *x,
int *y)
{
return FALSE;
}
static void
meta_monitor_tiled_calculate_crtc_pos (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
@ -824,13 +1096,12 @@ meta_monitor_tiled_calculate_crtc_pos (MetaMonitor *monitor,
static void
meta_monitor_tiled_finalize (GObject *object)
{
MetaMonitorTiled *monitor_tiled = META_MONITOR_TILED (object);
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaMonitor *monitor = META_MONITOR (object);
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
meta_monitor_manager_tiled_monitor_removed (monitor_manager,
META_MONITOR (monitor_tiled));
meta_monitor_manager_tiled_monitor_removed (monitor_priv->monitor_manager,
monitor);
}
static void
@ -849,6 +1120,7 @@ meta_monitor_tiled_class_init (MetaMonitorTiledClass *klass)
monitor_class->get_main_output = meta_monitor_tiled_get_main_output;
monitor_class->derive_dimensions = meta_monitor_tiled_derive_dimensions;
monitor_class->calculate_crtc_pos = meta_monitor_tiled_calculate_crtc_pos;
monitor_class->get_suggested_position = meta_monitor_tiled_get_suggested_position;
}
static void
@ -976,6 +1248,94 @@ meta_monitor_calculate_crtc_pos (MetaMonitor *monitor,
out_y);
}
/* The minimum resolution at which we turn on a window-scale of 2 */
#define HIDPI_LIMIT 192
/*
* The minimum screen height at which we turn on a window-scale of 2;
* below this there just isn't enough vertical real estate for GNOME
* apps to work, and it's better to just be tiny
*/
#define HIDPI_MIN_HEIGHT 1200
/* From http://en.wikipedia.org/wiki/4K_resolution#Resolutions_of_common_formats */
#define SMALLEST_4K_WIDTH 3656
static int
calculate_scale (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
int resolution_width, resolution_height;
int width_mm, height_mm;
int scale;
scale = 1;
meta_monitor_mode_get_resolution (monitor_mode,
&resolution_width,
&resolution_height);
if (resolution_height < HIDPI_MIN_HEIGHT)
goto out;
/* 4K TV */
switch (meta_monitor_get_connector_type (monitor))
{
case META_CONNECTOR_TYPE_HDMIA:
case META_CONNECTOR_TYPE_HDMIB:
if (resolution_width < SMALLEST_4K_WIDTH)
goto out;
break;
default:
break;
}
meta_monitor_get_physical_dimensions (monitor, &width_mm, &height_mm);
/*
* Somebody encoded the aspect ratio (16/9 or 16/10) instead of the physical
* size.
*/
if ((width_mm == 160 && height_mm == 90) ||
(width_mm == 160 && height_mm == 100) ||
(width_mm == 16 && height_mm == 9) ||
(width_mm == 16 && height_mm == 10))
goto out;
if (width_mm > 0 && height_mm > 0)
{
double dpi_x, dpi_y;
dpi_x = (double) resolution_width / (width_mm / 25.4);
dpi_y = (double) resolution_height / (height_mm / 25.4);
/*
* We don't completely trust these values so both must be high, and never
* pick higher ratio than 2 automatically.
*/
if (dpi_x > HIDPI_LIMIT && dpi_y > HIDPI_LIMIT)
scale = 2;
}
out:
return scale;
}
int
meta_monitor_calculate_mode_scale (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
int global_scaling_factor;
if (meta_settings_get_global_scaling_factor (settings,
&global_scaling_factor))
return global_scaling_factor;
return calculate_scale (monitor, monitor_mode);
}
MetaMonitorModeSpec *
meta_monitor_mode_get_spec (MetaMonitorMode *monitor_mode)
{

View File

@ -70,6 +70,9 @@ struct _MetaMonitorClass
MetaMonitorTransform crtc_transform,
int *out_x,
int *out_y);
gboolean (* get_suggested_position) (MetaMonitor *monitor,
int *width,
int *height);
};
#define META_TYPE_MONITOR_NORMAL (meta_monitor_normal_get_type ())
@ -85,7 +88,8 @@ G_DECLARE_FINAL_TYPE (MetaMonitorTiled, meta_monitor_tiled,
MetaMonitorTiled * meta_monitor_tiled_new (MetaMonitorManager *monitor_manager,
MetaOutput *main_output);
MetaMonitorNormal * meta_monitor_normal_new (MetaOutput *output);
MetaMonitorNormal * meta_monitor_normal_new (MetaMonitorManager *monitor_manager,
MetaOutput *output);
MetaMonitorSpec * meta_monitor_get_spec (MetaMonitor *monitor);
@ -156,6 +160,9 @@ void meta_monitor_calculate_crtc_pos (MetaMonitor *monitor,
int *out_x,
int *out_y);
int meta_monitor_calculate_mode_scale (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode);
MetaMonitorModeSpec * meta_monitor_mode_get_spec (MetaMonitorMode *monitor_mode);
void meta_monitor_mode_get_resolution (MetaMonitorMode *monitor_mode,

View File

@ -0,0 +1,60 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2017 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_SETTINGS_PRIVATE_H
#define META_SETTINGS_PRIVATE_H
#include <glib-object.h>
#include "meta/meta-settings.h"
#include "meta/types.h"
typedef enum _MetaExperimentalFeature
{
META_EXPERIMENTAL_FEATURE_NONE = 0,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER = (1 << 1)
} MetaExperimentalFeature;
#define META_TYPE_SETTINGS (meta_settings_get_type ())
G_DECLARE_FINAL_TYPE (MetaSettings, meta_settings,
META, SETTINGS, GObject)
MetaSettings * meta_settings_new (MetaBackend *backend);
void meta_settings_post_init (MetaSettings *settings);
void meta_settings_update_ui_scaling_factor (MetaSettings *settings);
gboolean meta_settings_get_global_scaling_factor (MetaSettings *settings,
int *scaing_factor);
gboolean meta_settings_is_experimental_feature_enabled (MetaSettings *settings,
MetaExperimentalFeature feature);
MetaExperimentalFeature meta_settings_get_experimental_features (MetaSettings *settings);
void meta_settings_override_experimental_features (MetaSettings *settings);
void meta_settings_enable_experimental_feature (MetaSettings *settings,
MetaExperimentalFeature feature);
#endif /* META_SETTINGS_PRIVATE_H */

View File

@ -0,0 +1,384 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2017 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "config.h"
#include "backends/meta-settings-private.h"
#include <gio/gio.h>
#include "backends/meta-backend-private.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor-manager-private.h"
#include "ui/theme-private.h"
enum
{
UI_SCALING_FACTOR_CHANGED,
GLOBAL_SCALING_FACTOR_CHANGED,
EXPERIMENTAL_FEATURES_CHANGED,
N_SIGNALS
};
static guint signals[N_SIGNALS];
struct _MetaSettings
{
GObject parent;
MetaBackend *backend;
GSettings *interface_settings;
GSettings *mutter_settings;
int ui_scaling_factor;
int global_scaling_factor;
MetaExperimentalFeature experimental_features;
gboolean experimental_features_overridden;
};
G_DEFINE_TYPE (MetaSettings, meta_settings, G_TYPE_OBJECT)
static int
calculate_ui_scaling_factor (MetaSettings *settings)
{
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (settings->backend);
GList *logical_monitors;
GList *l;
int max_scale = 1;
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
max_scale = MAX (meta_logical_monitor_get_scale (logical_monitor),
max_scale);
}
return max_scale;
}
static int
get_xsettings_scaling_factor (void)
{
GdkScreen *screen;
GValue value = G_VALUE_INIT;
g_value_init (&value, G_TYPE_INT);
screen = gdk_screen_get_default ();
if (gdk_screen_get_setting (screen, "gdk-window-scaling-factor", &value))
return g_value_get_int (&value);
else
return 1;
}
static gboolean
update_ui_scaling_factor (MetaSettings *settings)
{
int ui_scaling_factor;
if (meta_is_stage_views_scaled ())
{
ui_scaling_factor = 1;
}
else
{
if (meta_is_monitor_config_manager_enabled ())
ui_scaling_factor = calculate_ui_scaling_factor (settings);
else
ui_scaling_factor = get_xsettings_scaling_factor ();
}
if (settings->ui_scaling_factor != ui_scaling_factor)
{
settings->ui_scaling_factor = ui_scaling_factor;
return TRUE;
}
else
{
return FALSE;
}
}
static void
xft_dpi_changed (GtkSettings *gtk_settings,
GParamSpec *pspec,
MetaSettings *settings)
{
/* This only matters when we rely on XSettings. */
if (meta_is_monitor_config_manager_enabled ())
return;
meta_settings_update_ui_scaling_factor (settings);
}
static void
x11_display_opened (MetaBackend *backend,
MetaSettings *settings)
{
/*
* gdk-window-scaling-factor is not exported to gtk-settings
* because it is handled inside gdk, so we use gtk-xft-dpi instead
* which also changes when the scale factor changes.
*
* TODO: Only rely on our own configured scale when we only have
* MetaMonitorConfigManager.
*/
g_signal_connect (gtk_settings_get_default (), "notify::gtk-xft-dpi",
G_CALLBACK (xft_dpi_changed), settings);
}
void
meta_settings_update_ui_scaling_factor (MetaSettings *settings)
{
if (update_ui_scaling_factor (settings))
g_signal_emit (settings, signals[UI_SCALING_FACTOR_CHANGED], 0);
}
int
meta_settings_get_ui_scaling_factor (MetaSettings *settings)
{
g_assert (settings->ui_scaling_factor != 0);
return settings->ui_scaling_factor;
}
static gboolean
update_global_scaling_factor (MetaSettings *settings)
{
int global_scaling_factor;
global_scaling_factor =
(int) g_settings_get_uint (settings->interface_settings,
"scaling-factor");
if (settings->global_scaling_factor != global_scaling_factor)
{
settings->global_scaling_factor = global_scaling_factor;
return TRUE;
}
else
{
return FALSE;
}
}
gboolean
meta_settings_get_global_scaling_factor (MetaSettings *settings,
int *out_scaling_factor)
{
if (settings->global_scaling_factor == 0)
return FALSE;
*out_scaling_factor = settings->global_scaling_factor;
return TRUE;
}
static void
interface_settings_changed (GSettings *interface_settings,
const char *key,
MetaSettings *settings)
{
if (g_str_equal (key, "scaling-factor"))
{
if (update_global_scaling_factor (settings))
g_signal_emit (settings, signals[GLOBAL_SCALING_FACTOR_CHANGED], 0);
}
}
gboolean
meta_settings_is_experimental_feature_enabled (MetaSettings *settings,
MetaExperimentalFeature feature)
{
return !!(settings->experimental_features & feature);
}
void
meta_settings_override_experimental_features (MetaSettings *settings)
{
settings->experimental_features = META_EXPERIMENTAL_FEATURE_NONE;
settings->experimental_features_overridden = TRUE;
}
void
meta_settings_enable_experimental_feature (MetaSettings *settings,
MetaExperimentalFeature feature)
{
g_assert (settings->experimental_features_overridden);
settings->experimental_features |= feature;
}
static gboolean
experimental_features_handler (GVariant *features_variant,
gpointer *result,
gpointer data)
{
MetaSettings *settings = data;
GVariantIter features_iter;
char *feature;
MetaExperimentalFeature features = META_EXPERIMENTAL_FEATURE_NONE;
if (settings->experimental_features_overridden)
{
*result = GINT_TO_POINTER (FALSE);
return TRUE;
}
g_variant_iter_init (&features_iter, features_variant);
while (g_variant_iter_loop (&features_iter, "s", &feature))
{
/* So far no experimental features defined. */
if (g_str_equal (feature, "scale-monitor-framebuffer"))
features |= META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER;
else if (g_str_equal (feature, "monitor-config-manager"))
features |= META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER;
else
g_info ("Unknown experimental feature '%s'\n", feature);
}
if (features != settings->experimental_features)
{
settings->experimental_features = features;
*result = GINT_TO_POINTER (TRUE);
}
else
{
*result = GINT_TO_POINTER (FALSE);
}
return TRUE;
}
static gboolean
update_experimental_features (MetaSettings *settings)
{
return GPOINTER_TO_INT (g_settings_get_mapped (settings->mutter_settings,
"experimental-features",
experimental_features_handler,
settings));
}
static void
mutter_settings_changed (GSettings *mutter_settings,
gchar *key,
MetaSettings *settings)
{
MetaExperimentalFeature old_experimental_features;
if (!g_str_equal (key, "experimental-features"))
return;
old_experimental_features = settings->experimental_features;
if (update_experimental_features (settings))
g_signal_emit (settings, signals[EXPERIMENTAL_FEATURES_CHANGED], 0,
(unsigned int) old_experimental_features);
}
MetaSettings *
meta_settings_new (MetaBackend *backend)
{
MetaSettings *settings;
settings = g_object_new (META_TYPE_SETTINGS, NULL);
settings->backend = backend;
g_signal_connect (backend, "x11-display-opened",
G_CALLBACK (x11_display_opened),
settings);
return settings;
}
static void
meta_settings_dispose (GObject *object)
{
MetaSettings *settings = META_SETTINGS (object);
g_clear_object (&settings->mutter_settings);
g_clear_object (&settings->interface_settings);
G_OBJECT_CLASS (meta_settings_parent_class)->dispose (object);
}
static void
meta_settings_init (MetaSettings *settings)
{
settings->interface_settings = g_settings_new ("org.gnome.desktop.interface");
g_signal_connect (settings->interface_settings, "changed",
G_CALLBACK (interface_settings_changed),
settings);
settings->mutter_settings = g_settings_new ("org.gnome.mutter");
g_signal_connect (settings->mutter_settings, "changed",
G_CALLBACK (mutter_settings_changed),
settings);
/* Chain up inter-dependent settings. */
g_signal_connect (settings, "global-scaling-factor-changed",
G_CALLBACK (meta_settings_update_ui_scaling_factor), NULL);
update_global_scaling_factor (settings);
update_experimental_features (settings);
}
void
meta_settings_post_init (MetaSettings *settings)
{
update_ui_scaling_factor (settings);
}
static void
meta_settings_class_init (MetaSettingsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = meta_settings_dispose;
signals[UI_SCALING_FACTOR_CHANGED] =
g_signal_new ("ui-scaling-factor-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
signals[GLOBAL_SCALING_FACTOR_CHANGED] =
g_signal_new ("global-scaling-factor-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
signals[EXPERIMENTAL_FEATURES_CHANGED] =
g_signal_new ("experimental-features-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_UINT);
}

View File

@ -45,6 +45,7 @@
#include "backends/meta-pointer-constraint.h"
#include "backends/meta-stage.h"
#include "backends/native/meta-clutter-backend-native.h"
#include "backends/native/meta-input-settings-native.h"
#include "backends/native/meta-renderer-native.h"
#include "backends/native/meta-stage-native.h"
@ -431,6 +432,12 @@ meta_backend_native_create_renderer (MetaBackend *backend)
return META_RENDERER (renderer_native);
}
static MetaInputSettings *
meta_backend_native_create_input_settings (MetaBackend *backend)
{
return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, NULL);
}
static void
meta_backend_native_warp_pointer (MetaBackend *backend,
int x,
@ -561,6 +568,7 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager;
backend_class->create_cursor_renderer = meta_backend_native_create_cursor_renderer;
backend_class->create_renderer = meta_backend_native_create_renderer;
backend_class->create_input_settings = meta_backend_native_create_input_settings;
backend_class->warp_pointer = meta_backend_native_warp_pointer;

View File

@ -121,6 +121,25 @@ meta_input_settings_native_set_tap_enabled (MetaInputSettings *settings,
LIBINPUT_CONFIG_TAP_DISABLED);
}
static void
meta_input_settings_native_set_disable_while_typing (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled)
{
struct libinput_device *libinput_device;
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
if (!libinput_device)
return;
if (libinput_device_config_dwt_is_available (libinput_device))
libinput_device_config_dwt_set_enabled (libinput_device,
enabled ?
LIBINPUT_CONFIG_DWT_ENABLED :
LIBINPUT_CONFIG_DWT_DISABLED);
}
static void
meta_input_settings_native_set_invert_scroll (MetaInputSettings *settings,
ClutterInputDevice *device,
@ -432,8 +451,18 @@ meta_input_settings_native_set_tablet_area (MetaInputSettings *settings,
gdouble padding_bottom)
{
struct libinput_device *libinput_device;
gfloat matrix[6] = { 1. - (padding_left + padding_right), 0., padding_left,
0., 1. - (padding_top + padding_bottom), padding_top };
gfloat scale_x;
gfloat scale_y;
gfloat offset_x;
gfloat offset_y;
scale_x = 1. / (1. - (padding_left + padding_right));
scale_y = 1. / (1. - (padding_top + padding_bottom));
offset_x = -padding_left * scale_x;
offset_y = -padding_top * scale_y;
gfloat matrix[6] = { scale_x, 0., offset_x,
0., scale_y, offset_y };
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
if (!libinput_device ||
@ -507,6 +536,7 @@ meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
input_settings_class->set_scroll_button = meta_input_settings_native_set_scroll_button;
input_settings_class->set_click_method = meta_input_settings_native_set_click_method;
input_settings_class->set_keyboard_repeat = meta_input_settings_native_set_keyboard_repeat;
input_settings_class->set_disable_while_typing = meta_input_settings_native_set_disable_while_typing;
input_settings_class->set_tablet_mapping = meta_input_settings_native_set_tablet_mapping;
input_settings_class->set_tablet_keep_aspect = meta_input_settings_native_set_tablet_keep_aspect;

View File

@ -115,8 +115,6 @@ struct _MetaMonitorManagerKms
GUdevClient *udev;
guint uevent_handler_id;
GSettings *desktop_settings;
gboolean page_flips_not_supported;
int max_buffer_width;
@ -1261,9 +1259,16 @@ meta_monitor_manager_kms_ensure_initial_config (MetaMonitorManager *manager)
config = meta_monitor_manager_ensure_configured (manager);
if (meta_is_monitor_config_manager_enabled ())
meta_monitor_manager_update_logical_state (manager, config);
{
meta_monitor_manager_update_logical_state (manager, config);
}
else
meta_monitor_manager_update_logical_state_derived (manager);
{
MetaMonitorManagerDeriveFlag flags =
META_MONITOR_MANAGER_DERIVE_FLAG_NONE;
meta_monitor_manager_update_logical_state_derived (manager, flags);
}
}
static void
@ -1494,10 +1499,13 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
MetaOutputInfo **outputs,
unsigned int n_outputs)
{
MetaMonitorManagerDeriveFlag flags =
META_MONITOR_MANAGER_DERIVE_FLAG_NONE;
apply_crtc_assignments (manager, crtcs, n_crtcs, outputs, n_outputs);
legacy_calculate_screen_size (manager);
meta_monitor_manager_rebuild_derived (manager);
meta_monitor_manager_rebuild_derived (manager, flags);
}
static void
@ -1639,8 +1647,6 @@ meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
G_IO_IN | G_IO_ERR);
manager_kms->source->manager_kms = manager_kms;
g_source_attach (source, NULL);
manager_kms->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
}
static void
@ -1832,91 +1838,12 @@ meta_monitor_manager_kms_is_transform_handled (MetaMonitorManager *manager,
return FALSE;
}
/* The minimum resolution at which we turn on a window-scale of 2 */
#define HIDPI_LIMIT 192
/* The minimum screen height at which we turn on a window-scale of 2;
* below this there just isn't enough vertical real estate for GNOME
* apps to work, and it's better to just be tiny */
#define HIDPI_MIN_HEIGHT 1200
/* From http://en.wikipedia.org/wiki/4K_resolution#Resolutions_of_common_formats */
#define SMALLEST_4K_WIDTH 3656
static int
compute_scale (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
int resolution_width, resolution_height;
int width_mm, height_mm;
int scale;
scale = 1;
meta_monitor_mode_get_resolution (monitor_mode,
&resolution_width,
&resolution_height);
if (resolution_height < HIDPI_MIN_HEIGHT)
goto out;
/* 4K TV */
switch (meta_monitor_get_connector_type (monitor))
{
case META_CONNECTOR_TYPE_HDMIA:
case META_CONNECTOR_TYPE_HDMIB:
if (resolution_width >= SMALLEST_4K_WIDTH)
goto out;
break;
default:
break;
}
meta_monitor_get_physical_dimensions (monitor, &width_mm, &height_mm);
/*
* Somebody encoded the aspect ratio (16/9 or 16/10) instead of the physical
* size.
*/
if ((width_mm == 160 && height_mm == 90) ||
(width_mm == 160 && height_mm == 100) ||
(width_mm == 16 && height_mm == 9) ||
(width_mm == 16 && height_mm == 10))
goto out;
if (width_mm > 0 && height_mm > 0)
{
double dpi_x, dpi_y;
dpi_x = (double) resolution_width / (width_mm / 25.4);
dpi_y = (double) resolution_height / (height_mm / 25.4);
/*
* We don't completely trust these values so both must be high, and never
* pick higher ratio than 2 automatically.
*/
if (dpi_x > HIDPI_LIMIT && dpi_y > HIDPI_LIMIT)
scale = 2;
}
out:
return scale;
}
static int
meta_monitor_manager_kms_calculate_monitor_mode_scale (MetaMonitorManager *manager,
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
int global_scale;
global_scale = g_settings_get_uint (manager_kms->desktop_settings,
"scaling-factor");
if (global_scale > 0)
return global_scale;
else
return compute_scale (monitor, monitor_mode);
return meta_monitor_calculate_mode_scale (monitor, monitor_mode);
}
static void
@ -1932,13 +1859,14 @@ static MetaMonitorManagerCapability
meta_monitor_manager_kms_get_capabilities (MetaMonitorManager *manager)
{
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
MetaRenderer *renderer = meta_backend_get_renderer (backend);
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
MetaMonitorManagerCapability capabilities =
META_MONITOR_MANAGER_CAPABILITY_NONE;
if (meta_backend_is_experimental_feature_enabled (
backend,
if (meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER))
capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE;
@ -1975,11 +1903,14 @@ meta_monitor_manager_kms_get_max_screen_size (MetaMonitorManager *manager,
static MetaLogicalMonitorLayoutMode
meta_monitor_manager_kms_get_default_layout_mode (MetaMonitorManager *manager)
{
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
if (!meta_is_stage_views_enabled ())
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
if (meta_backend_is_experimental_feature_enabled (
meta_get_backend (),
if (meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER))
return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
else
@ -1992,7 +1923,6 @@ meta_monitor_manager_kms_dispose (GObject *object)
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object);
g_clear_object (&manager_kms->udev);
g_clear_object (&manager_kms->desktop_settings);
G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->dispose (object);
}

View File

@ -28,6 +28,7 @@
#include "backends/meta-backend-private.h"
#include "backends/x11/meta-cursor-renderer-x11.h"
#include "backends/x11/meta-input-settings-x11.h"
#include "backends/x11/meta-monitor-manager-xrandr.h"
#include "backends/x11/cm/meta-renderer-x11-cm.h"
@ -108,6 +109,12 @@ meta_backend_x11_cm_create_cursor_renderer (MetaBackend *backend)
return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
}
static MetaInputSettings *
meta_backend_x11_cm_create_input_settings (MetaBackend *backend)
{
return g_object_new (META_TYPE_INPUT_SETTINGS_X11, NULL);
}
static void
meta_backend_x11_cm_update_screen_size (MetaBackend *backend,
int width,
@ -390,6 +397,7 @@ meta_backend_x11_cm_class_init (MetaBackendX11CmClass *klass)
backend_class->create_renderer = meta_backend_x11_cm_create_renderer;
backend_class->create_monitor_manager = meta_backend_x11_cm_create_monitor_manager;
backend_class->create_cursor_renderer = meta_backend_x11_cm_create_cursor_renderer;
backend_class->create_input_settings = meta_backend_x11_cm_create_input_settings;
backend_class->update_screen_size = meta_backend_x11_cm_update_screen_size;
backend_class->select_stage_events = meta_backend_x11_cm_select_stage_events;
backend_class->lock_layout_group = meta_backend_x11_cm_lock_layout_group;

View File

@ -189,9 +189,14 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled)
{
ClutterInputDeviceType device_type;
guchar value;
if (clutter_input_device_get_device_type (device) == CLUTTER_TABLET_DEVICE)
device_type = clutter_input_device_get_device_type (device);
if (device_type == CLUTTER_TABLET_DEVICE ||
device_type == CLUTTER_PEN_DEVICE ||
device_type == CLUTTER_ERASER_DEVICE)
{
value = enabled ? 3 : 0;
change_property (device, "Wacom Rotation",
@ -205,6 +210,17 @@ meta_input_settings_x11_set_left_handed (MetaInputSettings *settings,
}
}
static void
meta_input_settings_x11_set_disable_while_typing (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled)
{
guchar value = (enabled) ? 1 : 0;
change_property (device, "libinput Disable While Typing Enabled",
XA_INTEGER, 8, &value, 1);
}
static void
meta_input_settings_x11_set_tap_enabled (MetaInputSettings *settings,
ClutterInputDevice *device,
@ -598,7 +614,7 @@ meta_input_settings_x11_set_tablet_area (MetaInputSettings *settings,
area[0] = width * padding_left;
area[1] = height * padding_top;
area[2] = width - (width * padding_right);
area[2] = height - (height * padding_bottom);
area[3] = height - (height * padding_bottom);
update_tablet_area (settings, device, area);
}
@ -744,6 +760,7 @@ meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
input_settings_class->set_speed = meta_input_settings_x11_set_speed;
input_settings_class->set_left_handed = meta_input_settings_x11_set_left_handed;
input_settings_class->set_tap_enabled = meta_input_settings_x11_set_tap_enabled;
input_settings_class->set_disable_while_typing = meta_input_settings_x11_set_disable_while_typing;
input_settings_class->set_invert_scroll = meta_input_settings_x11_set_invert_scroll;
input_settings_class->set_edge_scroll = meta_input_settings_x11_set_edge_scroll;
input_settings_class->set_two_finger_scroll = meta_input_settings_x11_set_two_finger_scroll;

View File

@ -33,8 +33,10 @@
#include <clutter/clutter.h>
#include <X11/Xatom.h>
#include <X11/Xlibint.h>
#include <X11/extensions/Xrandr.h>
#include <X11/extensions/dpms.h>
#include <X11/extensions/extutil.h>
#include <X11/Xlib-xcb.h>
#include <xcb/randr.h>
@ -53,7 +55,7 @@
#define DPI_FALLBACK 96.0
static float supported_scales_xrandr[] = {
1.0
1.0, 2.0
};
struct _MetaMonitorManagerXrandr
@ -66,6 +68,8 @@ struct _MetaMonitorManagerXrandr
int rr_error_base;
gboolean has_randr15;
xcb_timestamp_t last_xrandr_set_timestamp;
#ifdef HAVE_XRANDR15
GHashTable *tiled_monitor_atoms;
#endif /* HAVE_XRANDR15 */
@ -355,7 +359,7 @@ output_get_backlight_limits_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
{
Atom atom;
xcb_connection_t *xcb_conn;
g_autofree xcb_randr_query_output_property_reply_t *reply;
g_autofree xcb_randr_query_output_property_reply_t *reply = NULL;
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
@ -978,27 +982,27 @@ meta_monitor_manager_xrandr_set_power_save_mode (MetaMonitorManager *manager,
DPMSSetTimeouts (manager_xrandr->xdisplay, 0, 0, 0);
}
static Rotation
static xcb_randr_rotation_t
meta_monitor_transform_to_xrandr (MetaMonitorTransform transform)
{
switch (transform)
{
case META_MONITOR_TRANSFORM_NORMAL:
return RR_Rotate_0;
return XCB_RANDR_ROTATION_ROTATE_0;
case META_MONITOR_TRANSFORM_90:
return RR_Rotate_90;
return XCB_RANDR_ROTATION_ROTATE_90;
case META_MONITOR_TRANSFORM_180:
return RR_Rotate_180;
return XCB_RANDR_ROTATION_ROTATE_180;
case META_MONITOR_TRANSFORM_270:
return RR_Rotate_270;
return XCB_RANDR_ROTATION_ROTATE_270;
case META_MONITOR_TRANSFORM_FLIPPED:
return RR_Reflect_X | RR_Rotate_0;
return XCB_RANDR_ROTATION_REFLECT_X | XCB_RANDR_ROTATION_ROTATE_0;
case META_MONITOR_TRANSFORM_FLIPPED_90:
return RR_Reflect_X | RR_Rotate_90;
return XCB_RANDR_ROTATION_REFLECT_X | XCB_RANDR_ROTATION_ROTATE_90;
case META_MONITOR_TRANSFORM_FLIPPED_180:
return RR_Reflect_X | RR_Rotate_180;
return XCB_RANDR_ROTATION_REFLECT_X | XCB_RANDR_ROTATION_ROTATE_180;
case META_MONITOR_TRANSFORM_FLIPPED_270:
return RR_Reflect_X | RR_Rotate_270;
return XCB_RANDR_ROTATION_REFLECT_X | XCB_RANDR_ROTATION_ROTATE_270;
}
g_assert_not_reached ();
@ -1067,8 +1071,180 @@ output_set_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
}
}
static gboolean
xrandr_set_crtc_config (MetaMonitorManagerXrandr *manager_xrandr,
gboolean save_timestamp,
xcb_randr_crtc_t crtc,
xcb_timestamp_t timestamp,
int x,
int y,
xcb_randr_mode_t mode,
xcb_randr_rotation_t rotation,
xcb_randr_output_t *outputs,
int n_outputs)
{
xcb_connection_t *xcb_conn;
xcb_timestamp_t config_timestamp;
xcb_randr_set_crtc_config_cookie_t cookie;
xcb_randr_set_crtc_config_reply_t *reply;
xcb_generic_error_t *xcb_error = NULL;
xcb_conn = XGetXCBConnection (manager_xrandr->xdisplay);
config_timestamp = manager_xrandr->resources->configTimestamp;
cookie = xcb_randr_set_crtc_config (xcb_conn,
crtc,
timestamp,
config_timestamp,
x, y,
mode,
rotation,
n_outputs,
outputs);
reply = xcb_randr_set_crtc_config_reply (xcb_conn,
cookie,
&xcb_error);
if (xcb_error || !reply)
{
free (xcb_error);
free (reply);
return FALSE;
}
if (save_timestamp)
manager_xrandr->last_xrandr_set_timestamp = reply->timestamp;
free (reply);
return TRUE;
}
static gboolean
is_crtc_assignment_changed (MetaCrtc *crtc,
MetaCrtcInfo **crtc_infos,
unsigned int n_crtc_infos)
{
unsigned int i;
for (i = 0; i < n_crtc_infos; i++)
{
MetaCrtcInfo *crtc_info = crtc_infos[i];
unsigned int j;
if (crtc_info->crtc != crtc)
continue;
if (crtc->current_mode != crtc_info->mode)
return TRUE;
if (crtc->rect.x != crtc_info->x)
return TRUE;
if (crtc->rect.y != crtc_info->y)
return TRUE;
if (crtc->transform != crtc_info->transform)
return TRUE;
for (j = 0; j < crtc_info->outputs->len; j++)
{
MetaOutput *output = ((MetaOutput**) crtc_info->outputs->pdata)[j];
if (output->crtc != crtc)
return TRUE;
}
return FALSE;
}
return crtc->current_mode != NULL;
}
static gboolean
is_output_assignment_changed (MetaOutput *output,
MetaCrtcInfo **crtc_infos,
unsigned int n_crtc_infos,
MetaOutputInfo **output_infos,
unsigned int n_output_infos)
{
gboolean output_is_found = FALSE;
unsigned int i;
for (i = 0; i < n_output_infos; i++)
{
MetaOutputInfo *output_info = output_infos[i];
if (output_info->output != output)
continue;
if (output->is_primary != output_info->is_primary)
return TRUE;
if (output->is_presentation != output_info->is_presentation)
return TRUE;
if (output->is_underscanning != output_info->is_underscanning)
return TRUE;
output_is_found = TRUE;
}
if (!output_is_found)
return output->crtc != NULL;
for (i = 0; i < n_crtc_infos; i++)
{
MetaCrtcInfo *crtc_info = crtc_infos[i];
unsigned int j;
for (j = 0; j < crtc_info->outputs->len; j++)
{
MetaOutput *crtc_info_output =
((MetaOutput**) crtc_info->outputs->pdata)[j];
if (crtc_info_output == output &&
crtc_info->crtc == output->crtc)
return FALSE;
}
}
return TRUE;
}
static gboolean
is_assignments_changed (MetaMonitorManager *manager,
MetaCrtcInfo **crtc_infos,
unsigned int n_crtc_infos,
MetaOutputInfo **output_infos,
unsigned int n_output_infos)
{
unsigned int i;
for (i = 0; i < manager->n_crtcs; i++)
{
MetaCrtc *crtc = &manager->crtcs[i];
if (is_crtc_assignment_changed (crtc, crtc_infos, n_crtc_infos))
return TRUE;
}
for (i = 0; i < manager->n_outputs; i++)
{
MetaOutput *output = &manager->outputs[i];
if (is_output_assignment_changed (output,
crtc_infos,
n_crtc_infos,
output_infos,
n_output_infos))
return TRUE;
}
return FALSE;
}
static void
apply_crtc_assignments (MetaMonitorManager *manager,
gboolean save_timestamp,
MetaCrtcInfo **crtcs,
unsigned int n_crtcs,
MetaOutputInfo **outputs,
@ -1117,14 +1293,13 @@ apply_crtc_assignments (MetaMonitorManager *manager,
crtc->rect.x + crtc->rect.width > width ||
crtc->rect.y + crtc->rect.height > height)
{
XRRSetCrtcConfig (manager_xrandr->xdisplay,
manager_xrandr->resources,
(XID)crtc->crtc_id,
CurrentTime,
0, 0,
None,
RR_Rotate_0,
NULL, 0);
xrandr_set_crtc_config (manager_xrandr,
save_timestamp,
(xcb_randr_crtc_t) crtc->crtc_id,
XCB_CURRENT_TIME,
0, 0, XCB_NONE,
XCB_RANDR_ROTATION_ROTATE_0,
NULL, 0);
crtc->rect.x = 0;
crtc->rect.y = 0;
@ -1147,14 +1322,13 @@ apply_crtc_assignments (MetaMonitorManager *manager,
if (crtc->current_mode == NULL)
continue;
XRRSetCrtcConfig (manager_xrandr->xdisplay,
manager_xrandr->resources,
(XID)crtc->crtc_id,
CurrentTime,
0, 0,
None,
RR_Rotate_0,
NULL, 0);
xrandr_set_crtc_config (manager_xrandr,
save_timestamp,
(xcb_randr_crtc_t) crtc->crtc_id,
XCB_CURRENT_TIME,
0, 0, XCB_NONE,
XCB_RANDR_ROTATION_ROTATE_0,
NULL, 0);
crtc->rect.x = 0;
crtc->rect.y = 0;
@ -1183,14 +1357,14 @@ apply_crtc_assignments (MetaMonitorManager *manager,
if (crtc_info->mode != NULL)
{
MetaCrtcMode *mode;
g_autofree XID *output_ids = NULL;
g_autofree xcb_randr_output_t *output_ids = NULL;
unsigned int j, n_output_ids;
Status ok;
xcb_randr_rotation_t rotation;
mode = crtc_info->mode;
n_output_ids = crtc_info->outputs->len;
output_ids = g_new (XID, n_output_ids);
output_ids = g_new (xcb_randr_output_t, n_output_ids);
for (j = 0; j < n_output_ids; j++)
{
@ -1204,16 +1378,15 @@ apply_crtc_assignments (MetaMonitorManager *manager,
output_ids[j] = output->winsys_id;
}
ok = XRRSetCrtcConfig (manager_xrandr->xdisplay,
manager_xrandr->resources,
(XID)crtc->crtc_id,
CurrentTime,
crtc_info->x, crtc_info->y,
(XID)mode->mode_id,
meta_monitor_transform_to_xrandr (crtc_info->transform),
output_ids, n_output_ids);
if (ok != Success)
rotation = meta_monitor_transform_to_xrandr (crtc_info->transform);
if (!xrandr_set_crtc_config (manager_xrandr,
save_timestamp,
(xcb_randr_crtc_t) crtc->crtc_id,
XCB_CURRENT_TIME,
crtc_info->x, crtc_info->y,
(xcb_randr_mode_t) mode->mode_id,
rotation,
output_ids, n_output_ids))
{
meta_warning ("Configuring CRTC %d with mode %d (%d x %d @ %f) at position %d, %d and transform %u failed\n",
(unsigned)(crtc->crtc_id), (unsigned)(mode->mode_id),
@ -1290,6 +1463,9 @@ apply_crtc_assignments (MetaMonitorManager *manager,
static void
meta_monitor_manager_xrandr_ensure_initial_config (MetaMonitorManager *manager)
{
MetaMonitorManagerDeriveFlag flags =
META_MONITOR_MANAGER_DERIVE_FLAG_NONE;
meta_monitor_manager_ensure_configured (manager);
/*
@ -1299,7 +1475,10 @@ meta_monitor_manager_xrandr_ensure_initial_config (MetaMonitorManager *manager)
*/
meta_monitor_manager_read_current_state (manager);
meta_monitor_manager_update_logical_state_derived (manager);
if (meta_is_monitor_config_manager_enabled ())
flags |= META_MONITOR_MANAGER_DERIVE_FLAG_CONFIGURED_SCALE;
meta_monitor_manager_update_logical_state_derived (manager, flags);
}
static gboolean
@ -1313,7 +1492,10 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *mana
if (!config)
{
meta_monitor_manager_rebuild_derived (manager);
MetaMonitorManagerDeriveFlag flags =
META_MONITOR_MANAGER_DERIVE_FLAG_NONE;
meta_monitor_manager_rebuild_derived (manager, flags);
return TRUE;
}
@ -1324,11 +1506,35 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *mana
if (method != META_MONITORS_CONFIG_METHOD_VERIFY)
{
apply_crtc_assignments (manager,
(MetaCrtcInfo **) crtc_infos->pdata,
crtc_infos->len,
(MetaOutputInfo **) output_infos->pdata,
output_infos->len);
/*
* If the assignment has not changed, we won't get any notification about
* any new configuration from the X server; but we still need to update
* our own configuration, as something not applicable in Xrandr might
* have changed locally, such as the logical monitors scale. This means we
* must check that our new assignment actually changes anything, otherwise
* just update the logical state.
*/
if (is_assignments_changed (manager,
(MetaCrtcInfo **) crtc_infos->pdata,
crtc_infos->len,
(MetaOutputInfo **) output_infos->pdata,
output_infos->len))
{
apply_crtc_assignments (manager,
TRUE,
(MetaCrtcInfo **) crtc_infos->pdata,
crtc_infos->len,
(MetaOutputInfo **) output_infos->pdata,
output_infos->len);
}
else
{
MetaMonitorManagerDeriveFlag flags;
flags = (META_MONITOR_MANAGER_DERIVE_FLAG_NONE |
META_MONITOR_MANAGER_DERIVE_FLAG_CONFIGURED_SCALE);
meta_monitor_manager_rebuild_derived (manager, flags);
}
}
g_ptr_array_free (crtc_infos, TRUE);
@ -1344,7 +1550,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
MetaOutputInfo **outputs,
unsigned int n_outputs)
{
apply_crtc_assignments (manager, crtcs, n_crtcs, outputs, n_outputs);
apply_crtc_assignments (manager, FALSE, crtcs, n_crtcs, outputs, n_outputs);
}
static void
@ -1590,8 +1796,7 @@ meta_monitor_manager_xrandr_calculate_monitor_mode_scale (MetaMonitorManager *ma
MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
{
/* X11 does not support anything other than scale 1. */
return 1;
return meta_monitor_calculate_mode_scale (monitor, monitor_mode);
}
static void
@ -1606,7 +1811,8 @@ meta_monitor_manager_xrandr_get_supported_scales (MetaMonitorManager *manager,
static MetaMonitorManagerCapability
meta_monitor_manager_xrandr_get_capabilities (MetaMonitorManager *manager)
{
return META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
return (META_MONITOR_MANAGER_CAPABILITY_MIRRORING |
META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED);
}
static gboolean
@ -1626,11 +1832,7 @@ meta_monitor_manager_xrandr_get_max_screen_size (MetaMonitorManager *manager,
static MetaLogicalMonitorLayoutMode
meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager)
{
/*
* Under X11, we still use the 'logical' layout mode, but it is
* eqivalent to 'physical' as the scale is always 1.
*/
return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
}
static void
@ -1724,7 +1926,8 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
XEvent *event)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
gboolean hotplug;
gboolean is_hotplug;
gboolean is_our_configuration;
if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
return FALSE;
@ -1733,16 +1936,24 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
meta_monitor_manager_read_current_state (manager);
hotplug = manager_xrandr->resources->timestamp < manager_xrandr->resources->configTimestamp;
if (hotplug)
is_hotplug = (manager_xrandr->resources->timestamp <
manager_xrandr->resources->configTimestamp);
is_our_configuration = (manager_xrandr->resources->timestamp ==
manager_xrandr->last_xrandr_set_timestamp);
if (is_hotplug)
{
/* This is a hotplug event, so go ahead and build a new configuration. */
meta_monitor_manager_on_hotplug (manager);
}
else
{
/* Something else changed -- tell the world about it. */
meta_monitor_manager_rebuild_derived (manager);
MetaMonitorManagerDeriveFlag flags =
META_MONITOR_MANAGER_DERIVE_FLAG_NONE;
if (is_our_configuration)
flags |= META_MONITOR_MANAGER_DERIVE_FLAG_CONFIGURED_SCALE;
meta_monitor_manager_rebuild_derived (manager, flags);
}
return TRUE;

View File

@ -49,6 +49,12 @@ meta_backend_x11_nested_create_cursor_renderer (MetaBackend *backend)
return g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED, NULL);
}
static MetaInputSettings *
meta_backend_x11_nested_create_input_settings (MetaBackend *backend)
{
return NULL;
}
static void
meta_backend_x11_nested_update_screen_size (MetaBackend *backend,
int width,
@ -177,6 +183,7 @@ meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass)
backend_class->create_renderer = meta_backend_x11_nested_create_renderer;
backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager;
backend_class->create_cursor_renderer = meta_backend_x11_nested_create_cursor_renderer;
backend_class->create_input_settings = meta_backend_x11_nested_create_input_settings;
backend_class->update_screen_size = meta_backend_x11_nested_update_screen_size;
backend_class->select_stage_events = meta_backend_x11_nested_select_stage_events;
backend_class->lock_layout_group = meta_backend_x11_nested_lock_layout_group;

View File

@ -155,7 +155,7 @@ file_loaded (GObject *source_object,
CoglError *catch_error = NULL;
GTask *task;
CoglTexture *texture;
GdkPixbuf *pixbuf;
GdkPixbuf *pixbuf, *rotated;
int width, height, row_stride;
guchar *pixels;
gboolean has_alpha;
@ -173,6 +173,13 @@ file_loaded (GObject *source_object,
goto out;
}
rotated = gdk_pixbuf_apply_embedded_orientation (pixbuf);
if (rotated != NULL)
{
g_object_unref (pixbuf);
pixbuf = rotated;
}
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
row_stride = gdk_pixbuf_get_rowstride (pixbuf);

View File

@ -62,6 +62,6 @@ void meta_texture_tower_update_area (MetaTextureTower *tower,
int height);
CoglTexture *meta_texture_tower_get_paint_texture (MetaTextureTower *tower);
G_BEGIN_DECLS
G_END_DECLS
#endif /* __META_TEXTURE_TOWER_H__ */

View File

@ -963,7 +963,7 @@ meta_display_open (void)
meta_screen_init_workspaces (screen);
meta_backend_display_opened (meta_get_backend ());
meta_backend_x11_display_opened (meta_get_backend ());
enable_compositor (display);

View File

@ -44,7 +44,8 @@ struct _MetaKeyHandler
};
typedef struct _MetaResolvedKeyCombo {
xkb_keycode_t keycode;
xkb_keycode_t *keycodes;
int len;
xkb_mod_mask_t mask;
} MetaResolvedKeyCombo;
@ -102,7 +103,7 @@ typedef struct
MetaKeyCombo overlay_key_combo;
MetaResolvedKeyCombo overlay_resolved_key_combo;
gboolean overlay_key_only_pressed;
MetaResolvedKeyCombo *iso_next_group_combos;
MetaResolvedKeyCombo iso_next_group_combo[2];
int n_iso_next_group_combos;
xkb_level_index_t keymap_num_levels;

View File

@ -64,16 +64,63 @@ static gboolean add_builtin_keybinding (MetaDisplay *display,
MetaKeyHandlerFunc handler,
int handler_arg);
static void
resolved_key_combo_reset (MetaResolvedKeyCombo *resolved_combo)
{
g_free (resolved_combo->keycodes);
resolved_combo->len = 0;
resolved_combo->keycodes = NULL;
}
static void
resolved_key_combo_copy (MetaResolvedKeyCombo *from,
MetaResolvedKeyCombo *to)
{
to->len = from->len;
to->keycodes = g_memdup (from->keycodes,
from->len * sizeof (xkb_keycode_t));
}
static gboolean
resolved_key_combo_has_keycode (MetaResolvedKeyCombo *resolved_combo,
int keycode)
{
int i;
for (i = 0; i < resolved_combo->len; i++)
if ((int) resolved_combo->keycodes[i] == keycode)
return TRUE;
return FALSE;
}
static gboolean
resolved_key_combo_intersect (MetaResolvedKeyCombo *a,
MetaResolvedKeyCombo *b)
{
int i;
for (i = 0; i < a->len; i++)
if (resolved_key_combo_has_keycode (b, a->keycodes[i]))
return TRUE;
return FALSE;
}
static void
meta_key_binding_free (MetaKeyBinding *binding)
{
resolved_key_combo_reset (&binding->resolved_combo);
g_slice_free (MetaKeyBinding, binding);
}
static MetaKeyBinding *
meta_key_binding_copy (MetaKeyBinding *binding)
{
return g_slice_dup (MetaKeyBinding, binding);
MetaKeyBinding *clone = g_slice_dup (MetaKeyBinding, binding);
resolved_key_combo_copy (&binding->resolved_combo,
&clone->resolved_combo);
return clone;
}
G_DEFINE_BOXED_TYPE(MetaKeyBinding,
@ -163,7 +210,8 @@ meta_key_grab_free (MetaKeyGrab *grab)
}
static guint32
key_combo_key (MetaResolvedKeyCombo *resolved_combo)
key_combo_key (MetaResolvedKeyCombo *resolved_combo,
int i)
{
/* On X, keycodes are only 8 bits while libxkbcommon supports 32 bit
keycodes, but since we're using the same XKB keymaps that X uses,
@ -173,7 +221,7 @@ key_combo_key (MetaResolvedKeyCombo *resolved_combo)
can use a 32 bit integer to safely concatenate both keycode and
mask and thus making it easy to use them as an index in a
GHashTable. */
guint32 key = resolved_combo->keycode & 0xffff;
guint32 key = resolved_combo->keycodes[i] & 0xffff;
return (key << 16) | (resolved_combo->mask & 0xffff);
}
@ -274,21 +322,34 @@ get_keycodes_for_keysym_iter (struct xkb_keymap *keymap,
xkb_level_index_t level = search_data->level;
if (is_keycode_for_keysym (keymap, layout, level, keycode, keysym))
g_array_append_val (keycodes, keycode);
{
guint i;
gboolean missing = TRUE;
/* duplicate keycode detection */
for (i = 0; i < keycodes->len; i++)
if (g_array_index (keycodes, xkb_keysym_t, i) == keycode)
{
missing = FALSE;
break;
}
if (missing)
g_array_append_val (keycodes, keycode);
}
}
/* Original code from gdk_x11_keymap_get_entries_for_keyval() in
* gdkkeys-x11.c */
static int
static void
get_keycodes_for_keysym (MetaKeyBindingManager *keys,
int keysym,
int **keycodes)
MetaResolvedKeyCombo *resolved_combo)
{
GArray *retval;
int n_keycodes;
int keycode;
retval = g_array_new (FALSE, FALSE, sizeof (int));
retval = g_array_new (FALSE, FALSE, sizeof (xkb_keysym_t));
/* Special-case: Fake mutter keysym */
if (keysym == META_KEY_ABOVE_TAB)
@ -313,28 +374,8 @@ get_keycodes_for_keysym (MetaKeyBindingManager *keys,
}
out:
n_keycodes = retval->len;
*keycodes = (int*) g_array_free (retval, n_keycodes == 0 ? TRUE : FALSE);
return n_keycodes;
}
static guint
get_first_keycode_for_keysym (MetaKeyBindingManager *keys,
guint keysym)
{
int *keycodes;
int n_keycodes;
int keycode;
n_keycodes = get_keycodes_for_keysym (keys, keysym, &keycodes);
if (n_keycodes > 0)
keycode = keycodes[0];
else
keycode = 0;
g_free (keycodes);
return keycode;
resolved_combo->len = retval->len;
resolved_combo->keycodes = (xkb_keycode_t *) g_array_free (retval, retval->len == 0 ? TRUE : FALSE);
}
static void
@ -367,20 +408,23 @@ static void
reload_iso_next_group_combos (MetaKeyBindingManager *keys)
{
const char *iso_next_group_option;
MetaResolvedKeyCombo *combos;
int *keycodes;
int n_keycodes;
int n_combos;
int i;
g_clear_pointer (&keys->iso_next_group_combos, g_free);
for (i = 0; i < keys->n_iso_next_group_combos; i++)
resolved_key_combo_reset (&keys->iso_next_group_combo[i]);
keys->n_iso_next_group_combos = 0;
iso_next_group_option = meta_prefs_get_iso_next_group_option ();
if (iso_next_group_option == NULL)
return;
n_keycodes = get_keycodes_for_keysym (keys, XKB_KEY_ISO_Next_Group, &keycodes);
get_keycodes_for_keysym (keys, XKB_KEY_ISO_Next_Group, keys->iso_next_group_combo);
if (keys->iso_next_group_combo[0].len == 0)
return;
keys->n_iso_next_group_combos = 1;
if (g_str_equal (iso_next_group_option, "toggle") ||
g_str_equal (iso_next_group_option, "lalt_toggle") ||
@ -394,94 +438,53 @@ reload_iso_next_group_combos (MetaKeyBindingManager *keys)
g_str_equal (iso_next_group_option, "menu_toggle") ||
g_str_equal (iso_next_group_option, "caps_toggle"))
{
n_combos = n_keycodes;
combos = g_new (MetaResolvedKeyCombo, n_combos);
for (i = 0; i < n_keycodes; ++i)
{
combos[i].keycode = keycodes[i];
combos[i].mask = 0;
}
keys->iso_next_group_combo[0].mask = 0;
}
else if (g_str_equal (iso_next_group_option, "shift_caps_toggle") ||
g_str_equal (iso_next_group_option, "shifts_toggle"))
{
n_combos = n_keycodes;
combos = g_new (MetaResolvedKeyCombo, n_combos);
for (i = 0; i < n_keycodes; ++i)
{
combos[i].keycode = keycodes[i];
combos[i].mask = ShiftMask;
}
keys->iso_next_group_combo[0].mask = ShiftMask;
}
else if (g_str_equal (iso_next_group_option, "alt_caps_toggle") ||
g_str_equal (iso_next_group_option, "alt_space_toggle"))
{
n_combos = n_keycodes;
combos = g_new (MetaResolvedKeyCombo, n_combos);
for (i = 0; i < n_keycodes; ++i)
{
combos[i].keycode = keycodes[i];
combos[i].mask = Mod1Mask;
}
keys->iso_next_group_combo[0].mask = Mod1Mask;
}
else if (g_str_equal (iso_next_group_option, "ctrl_shift_toggle") ||
g_str_equal (iso_next_group_option, "lctrl_lshift_toggle") ||
g_str_equal (iso_next_group_option, "rctrl_rshift_toggle"))
{
n_combos = n_keycodes * 2;
combos = g_new (MetaResolvedKeyCombo, n_combos);
resolved_key_combo_copy (&keys->iso_next_group_combo[0],
&keys->iso_next_group_combo[1]);
for (i = 0; i < n_keycodes; ++i)
{
combos[i].keycode = keycodes[i];
combos[i].mask = ShiftMask;
combos[i + n_keycodes].keycode = keycodes[i];
combos[i + n_keycodes].mask = ControlMask;
}
keys->iso_next_group_combo[0].mask = ShiftMask;
keys->iso_next_group_combo[1].mask = ControlMask;
keys->n_iso_next_group_combos = 2;
}
else if (g_str_equal (iso_next_group_option, "ctrl_alt_toggle"))
{
n_combos = n_keycodes * 2;
combos = g_new (MetaResolvedKeyCombo, n_combos);
resolved_key_combo_copy (&keys->iso_next_group_combo[0],
&keys->iso_next_group_combo[1]);
for (i = 0; i < n_keycodes; ++i)
{
combos[i].keycode = keycodes[i];
combos[i].mask = Mod1Mask;
combos[i + n_keycodes].keycode = keycodes[i];
combos[i + n_keycodes].mask = ControlMask;
}
keys->iso_next_group_combo[0].mask = Mod1Mask;
keys->iso_next_group_combo[1].mask = ControlMask;
keys->n_iso_next_group_combos = 2;
}
else if (g_str_equal (iso_next_group_option, "alt_shift_toggle") ||
g_str_equal (iso_next_group_option, "lalt_lshift_toggle"))
{
n_combos = n_keycodes * 2;
combos = g_new (MetaResolvedKeyCombo, n_combos);
resolved_key_combo_copy (&keys->iso_next_group_combo[0],
&keys->iso_next_group_combo[1]);
for (i = 0; i < n_keycodes; ++i)
{
combos[i].keycode = keycodes[i];
combos[i].mask = Mod1Mask;
combos[i + n_keycodes].keycode = keycodes[i];
combos[i + n_keycodes].mask = ShiftMask;
}
keys->iso_next_group_combo[0].mask = Mod1Mask;
keys->iso_next_group_combo[1].mask = ShiftMask;
keys->n_iso_next_group_combos = 2;
}
else
{
n_combos = 0;
combos = NULL;
resolved_key_combo_reset (keys->iso_next_group_combo);
keys->n_iso_next_group_combos = 0;
}
g_free (keycodes);
keys->n_iso_next_group_combos = n_combos;
keys->iso_next_group_combos = combos;
}
static void
@ -517,11 +520,35 @@ static void
index_binding (MetaKeyBindingManager *keys,
MetaKeyBinding *binding)
{
guint32 index_key;
int i;
index_key = key_combo_key (&binding->resolved_combo);
g_hash_table_replace (keys->key_bindings_index,
GINT_TO_POINTER (index_key), binding);
for (i = 0; i < binding->resolved_combo.len; i++)
{
MetaKeyBinding *existing;
guint32 index_key;
index_key = key_combo_key (&binding->resolved_combo, i);
existing = g_hash_table_lookup (keys->key_bindings_index,
GINT_TO_POINTER (index_key));
if (existing != NULL)
{
/* Overwrite already indexed keycodes only for the first
* keycode, i.e. we give those primary keycodes precedence
* over non-first ones. */
if (i > 0)
continue;
meta_warning ("Overwriting existing binding of keysym %x"
" with keysym %x (keycode %x).\n",
binding->combo.keysym,
existing->combo.keysym,
binding->resolved_combo.keycodes[i]);
}
g_hash_table_replace (keys->key_bindings_index,
GINT_TO_POINTER (index_key), binding);
}
}
static void
@ -529,10 +556,19 @@ resolve_key_combo (MetaKeyBindingManager *keys,
MetaKeyCombo *combo,
MetaResolvedKeyCombo *resolved_combo)
{
resolved_key_combo_reset (resolved_combo);
if (combo->keysym != 0)
resolved_combo->keycode = get_first_keycode_for_keysym (keys, combo->keysym);
else
resolved_combo->keycode = combo->keycode;
{
get_keycodes_for_keysym (keys, combo->keysym, resolved_combo);
}
else if (combo->keycode != 0)
{
resolved_combo->keycodes = g_new0 (xkb_keycode_t, 1);
resolved_combo->keycodes[0] = combo->keycode;
resolved_combo->len = 1;
}
devirtualize_modifiers (keys, combo->modifiers, &resolved_combo->mask);
}
@ -691,9 +727,22 @@ static MetaKeyBinding *
get_keybinding (MetaKeyBindingManager *keys,
MetaResolvedKeyCombo *resolved_combo)
{
guint32 key;
key = key_combo_key (resolved_combo);
return g_hash_table_lookup (keys->key_bindings_index, GINT_TO_POINTER (key));
MetaKeyBinding *binding = NULL;
int i;
for (i = 0; i < resolved_combo->len; i++)
{
guint32 key;
key = key_combo_key (resolved_combo, i);
binding = g_hash_table_lookup (keys->key_bindings_index,
GINT_TO_POINTER (key));
if (binding != NULL)
break;
}
return binding;
}
static guint
@ -823,7 +872,8 @@ get_keybinding_action (MetaKeyBindingManager *keys,
* of mutter keybindings while holding a grab, the overlay-key-only-pressed
* tracking is left to the plugin here.
*/
if (resolved_combo->keycode == (unsigned int)keys->overlay_resolved_key_combo.keycode)
if (resolved_key_combo_intersect (resolved_combo,
&keys->overlay_resolved_key_combo))
return META_KEYBINDING_ACTION_OVERLAY_KEY;
binding = get_keybinding (keys, resolved_combo);
@ -841,14 +891,11 @@ get_keybinding_action (MetaKeyBindingManager *keys,
}
}
static void
resolved_combo_from_event_params (MetaResolvedKeyCombo *resolved_combo,
MetaKeyBindingManager *keys,
unsigned int keycode,
unsigned long mask)
static xkb_mod_mask_t
mask_from_event_params (MetaKeyBindingManager *keys,
unsigned long mask)
{
resolved_combo->keycode = keycode;
resolved_combo->mask = mask & 0xff & ~keys->ignored_modifier_mask;
return mask & 0xff & ~keys->ignored_modifier_mask;
}
/**
@ -871,8 +918,10 @@ meta_display_get_keybinding_action (MetaDisplay *display,
unsigned long mask)
{
MetaKeyBindingManager *keys = &display->key_binding_manager;
MetaResolvedKeyCombo resolved_combo;
resolved_combo_from_event_params (&resolved_combo, keys, keycode, mask);
xkb_keycode_t code = (xkb_keycode_t) keycode;
MetaResolvedKeyCombo resolved_combo = { &code, 1 };
resolved_combo.mask = mask_from_event_params (keys, mask);
return get_keybinding_action (keys, &resolved_combo);
}
@ -1165,30 +1214,36 @@ meta_change_keygrab (MetaKeyBindingManager *keys,
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
GArray *mods;
int i;
/* Grab keycode/modmask, together with
* all combinations of ignored modifiers.
* X provides no better way to do this.
*/
meta_topic (META_DEBUG_KEYBINDINGS,
"%s keybinding keycode %d mask 0x%x on 0x%lx\n",
grab ? "Grabbing" : "Ungrabbing",
resolved_combo->keycode, resolved_combo->mask, xwindow);
mods = calc_grab_modifiers (keys, resolved_combo->mask);
if (grab)
XIGrabKeycode (xdisplay,
META_VIRTUAL_CORE_KEYBOARD_ID,
resolved_combo->keycode, xwindow,
XIGrabModeSync, XIGrabModeAsync,
False, &mask, mods->len, (XIGrabModifiers *)mods->data);
else
XIUngrabKeycode (xdisplay,
META_VIRTUAL_CORE_KEYBOARD_ID,
resolved_combo->keycode, xwindow,
mods->len, (XIGrabModifiers *)mods->data);
for (i = 0; i < resolved_combo->len; i++)
{
xkb_keycode_t keycode = resolved_combo->keycodes[i];
meta_topic (META_DEBUG_KEYBINDINGS,
"%s keybinding keycode %d mask 0x%x on 0x%lx\n",
grab ? "Grabbing" : "Ungrabbing",
keycode, resolved_combo->mask, xwindow);
if (grab)
XIGrabKeycode (xdisplay,
META_VIRTUAL_CORE_KEYBOARD_ID,
keycode, xwindow,
XIGrabModeSync, XIGrabModeAsync,
False, &mask, mods->len, (XIGrabModifiers *)mods->data);
else
XIUngrabKeycode (xdisplay,
META_VIRTUAL_CORE_KEYBOARD_ID,
keycode, xwindow,
mods->len, (XIGrabModifiers *)mods->data);
}
g_array_free (mods, TRUE);
}
@ -1213,7 +1268,7 @@ change_keygrab_foreach (gpointer key,
if (data->only_per_window != binding_is_per_window)
return;
if (binding->resolved_combo.keycode == 0)
if (binding->resolved_combo.len == 0)
return;
meta_change_keygrab (data->keys, data->xwindow, data->grab, &binding->resolved_combo);
@ -1241,21 +1296,13 @@ meta_screen_change_keygrabs (MetaScreen *screen,
{
MetaDisplay *display = screen->display;
MetaKeyBindingManager *keys = &display->key_binding_manager;
int i;
if (keys->overlay_resolved_key_combo.keycode != 0)
if (keys->overlay_resolved_key_combo.len != 0)
meta_change_keygrab (keys, screen->xroot, grab, &keys->overlay_resolved_key_combo);
if (keys->iso_next_group_combos)
{
int i = 0;
while (i < keys->n_iso_next_group_combos)
{
if (keys->iso_next_group_combos[i].keycode != 0)
meta_change_keygrab (keys, screen->xroot, grab, &keys->iso_next_group_combos[i]);
++i;
}
}
for (i = 0; i < keys->n_iso_next_group_combos; i++)
meta_change_keygrab (keys, screen->xroot, grab, &keys->iso_next_group_combo[i]);
change_binding_keygrabs (keys, screen->xroot, FALSE, grab);
}
@ -1367,7 +1414,7 @@ meta_display_grab_accelerator (MetaDisplay *display,
MetaKeyBinding *binding;
MetaKeyGrab *grab;
MetaKeyCombo combo = { 0 };
MetaResolvedKeyCombo resolved_combo = { 0 };
MetaResolvedKeyCombo resolved_combo = { NULL, 0 };
if (!meta_parse_accelerator (accelerator, &combo))
{
@ -1380,11 +1427,14 @@ meta_display_grab_accelerator (MetaDisplay *display,
resolve_key_combo (keys, &combo, &resolved_combo);
if (resolved_combo.keycode == 0)
if (resolved_combo.len == 0)
return META_KEYBINDING_ACTION_NONE;
if (get_keybinding (keys, &resolved_combo))
return META_KEYBINDING_ACTION_NONE;
{
resolved_key_combo_reset (&resolved_combo);
return META_KEYBINDING_ACTION_NONE;
}
meta_change_keygrab (keys, display->screen->xroot, TRUE, &resolved_combo);
@ -1415,7 +1465,7 @@ meta_display_ungrab_accelerator (MetaDisplay *display,
MetaKeyBinding *binding;
MetaKeyGrab *grab;
char *key;
MetaResolvedKeyCombo resolved_combo;
MetaResolvedKeyCombo resolved_combo = { NULL, 0 };
g_return_val_if_fail (action != META_KEYBINDING_ACTION_NONE, FALSE);
@ -1428,18 +1478,22 @@ meta_display_ungrab_accelerator (MetaDisplay *display,
binding = get_keybinding (keys, &resolved_combo);
if (binding)
{
guint32 index_key;
int i;
meta_change_keygrab (keys, display->screen->xroot, FALSE, &binding->resolved_combo);
index_key = key_combo_key (&binding->resolved_combo);
g_hash_table_remove (keys->key_bindings_index, GINT_TO_POINTER (index_key));
for (i = 0; i < binding->resolved_combo.len; i++)
{
guint32 index_key = key_combo_key (&binding->resolved_combo, i);
g_hash_table_remove (keys->key_bindings_index, GINT_TO_POINTER (index_key));
}
g_hash_table_remove (keys->key_bindings, binding);
}
g_hash_table_remove (external_grabs, key);
g_free (key);
resolved_key_combo_reset (&resolved_combo);
return TRUE;
}
@ -1645,16 +1699,15 @@ process_event (MetaDisplay *display,
ClutterKeyEvent *event)
{
MetaKeyBindingManager *keys = &display->key_binding_manager;
MetaResolvedKeyCombo resolved_combo;
xkb_keycode_t keycode = (xkb_keycode_t) event->hardware_keycode;
MetaResolvedKeyCombo resolved_combo = { &keycode, 1 };
MetaKeyBinding *binding;
/* we used to have release-based bindings but no longer. */
if (event->type == CLUTTER_KEY_RELEASE)
return FALSE;
resolved_combo_from_event_params (&resolved_combo, keys,
event->hardware_keycode,
event->modifier_state);
resolved_combo.mask = mask_from_event_params (keys, event->modifier_state);
binding = get_keybinding (keys, &resolved_combo);
@ -1708,7 +1761,8 @@ process_overlay_key (MetaDisplay *display,
if (keys->overlay_key_only_pressed)
{
if (event->hardware_keycode != (int)keys->overlay_resolved_key_combo.keycode)
if (! resolved_key_combo_has_keycode (&keys->overlay_resolved_key_combo,
event->hardware_keycode))
{
keys->overlay_key_only_pressed = FALSE;
@ -1790,7 +1844,8 @@ process_overlay_key (MetaDisplay *display,
return TRUE;
}
else if (event->type == CLUTTER_KEY_PRESS &&
event->hardware_keycode == (int)keys->overlay_resolved_key_combo.keycode)
resolved_key_combo_has_keycode (&keys->overlay_resolved_key_combo,
event->hardware_keycode))
{
keys->overlay_key_only_pressed = TRUE;
/* We keep the keyboard frozen - this allows us to use ReplayKeyboard
@ -1813,30 +1868,31 @@ process_iso_next_group (MetaDisplay *display,
{
MetaKeyBindingManager *keys = &display->key_binding_manager;
gboolean activate;
MetaResolvedKeyCombo resolved_combo;
int i;
xkb_keycode_t keycode = (xkb_keycode_t) event->hardware_keycode;
xkb_mod_mask_t mask;
int i, j;
if (event->type == CLUTTER_KEY_RELEASE)
return FALSE;
activate = FALSE;
resolved_combo_from_event_params (&resolved_combo, keys,
event->hardware_keycode,
event->modifier_state);
mask = mask_from_event_params (keys, event->modifier_state);
for (i = 0; i < keys->n_iso_next_group_combos; ++i)
{
if (resolved_combo.keycode == keys->iso_next_group_combos[i].keycode &&
resolved_combo.mask == keys->iso_next_group_combos[i].mask)
for (j = 0; j < keys->iso_next_group_combo[i].len; ++j)
{
/* If the signal handler returns TRUE the keyboard will
remain frozen. It's the signal handler's responsibility
to unfreeze it. */
if (!meta_display_modifiers_accelerator_activate (display))
meta_display_unfreeze_keyboard (display, event->time);
activate = TRUE;
break;
if (keycode == keys->iso_next_group_combo[i].keycodes[j] &&
mask == keys->iso_next_group_combo[i].mask)
{
/* If the signal handler returns TRUE the keyboard will
remain frozen. It's the signal handler's responsibility
to unfreeze it. */
if (!meta_display_modifiers_accelerator_activate (display))
meta_display_unfreeze_keyboard (display, event->time);
activate = TRUE;
break;
}
}
}

View File

@ -2890,6 +2890,7 @@ void
meta_window_tile (MetaWindow *window)
{
MetaMaximizeFlags directions;
MetaRectangle old_frame_rect, old_buffer_rect;
/* Don't do anything if no tiling is requested */
if (window->tile_mode == META_TILE_NONE)
@ -2903,7 +2904,19 @@ meta_window_tile (MetaWindow *window)
meta_window_maximize_internal (window, directions, NULL);
meta_screen_update_tile_preview (window->screen, FALSE);
meta_window_move_resize_now (window);
meta_window_get_frame_rect (window, &old_frame_rect);
meta_window_get_buffer_rect (window, &old_buffer_rect);
meta_compositor_size_change_window (window->display->compositor, window,
META_SIZE_CHANGE_MAXIMIZE,
&old_frame_rect, &old_buffer_rect);
meta_window_move_resize_internal (window,
(META_MOVE_RESIZE_MOVE_ACTION |
META_MOVE_RESIZE_RESIZE_ACTION |
META_MOVE_RESIZE_STATE_CHANGED),
NorthWestGravity,
window->unconstrained_rect);
if (window->frame)
meta_frame_queue_draw (window->frame);

View File

@ -51,8 +51,11 @@ void meta_backend_set_numlock (MetaBackend *backend,
int meta_backend_get_ui_scaling_factor (MetaBackend *backend);
ClutterActor *meta_backend_get_stage (MetaBackend *backend);
MetaDnd *meta_backend_get_dnd (MetaBackend *backend);
MetaSettings *meta_backend_get_settings (MetaBackend *backend);
void meta_clutter_init (void);
#endif /* META_BACKEND_H */

29
src/meta/meta-settings.h Normal file
View File

@ -0,0 +1,29 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2017 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_SETTINGS_H
#define META_SETTINGS_H
#include "meta/types.h"
int meta_settings_get_ui_scaling_factor (MetaSettings *settings);
#endif /* META_SETTINGS_H */

View File

@ -40,5 +40,6 @@ typedef struct _MetaKeyBinding MetaKeyBinding;
typedef struct _MetaCursorTracker MetaCursorTracker;
typedef struct _MetaDnd MetaDnd;
typedef struct _MetaSettings MetaSettings;
#endif

View File

@ -401,6 +401,10 @@
* "supports-changing-layout-mode" (b): True if the layout mode can be
changed. Absence of this means the
layout mode cannot be changed.
* "global-scale-required" (b): True if all the logical monitors must
always use the same scale. Absence of
this means logical monitor scales can
differ.
-->
<method name="GetCurrentState">
<arg name="serial" direction="out" type="u" />

View File

@ -123,9 +123,16 @@ meta_monitor_manager_test_ensure_initial_config (MetaMonitorManager *manager)
config = meta_monitor_manager_ensure_configured (manager);
if (meta_is_monitor_config_manager_enabled ())
meta_monitor_manager_update_logical_state (manager, config);
{
meta_monitor_manager_update_logical_state (manager, config);
}
else
meta_monitor_manager_update_logical_state_derived (manager);
{
MetaMonitorManagerDeriveFlag flags =
META_MONITOR_MANAGER_DERIVE_FLAG_NONE;
meta_monitor_manager_update_logical_state_derived (manager, flags);
}
}
static void
@ -279,9 +286,16 @@ meta_monitor_manager_test_apply_monitors_config (MetaMonitorManager *manage
manager->screen_height = 1;
if (meta_is_stage_views_enabled ())
meta_monitor_manager_rebuild (manager, NULL);
{
meta_monitor_manager_rebuild (manager, NULL);
}
else
meta_monitor_manager_rebuild_derived (manager);
{
MetaMonitorManagerDeriveFlag flags =
META_MONITOR_MANAGER_DERIVE_FLAG_CONFIGURED_SCALE;
meta_monitor_manager_rebuild_derived (manager, flags);
}
return TRUE;
}
@ -311,9 +325,16 @@ meta_monitor_manager_test_apply_monitors_config (MetaMonitorManager *manage
update_screen_size (manager, config);
if (meta_is_stage_views_enabled ())
meta_monitor_manager_rebuild (manager, config);
{
meta_monitor_manager_rebuild (manager, config);
}
else
meta_monitor_manager_rebuild_derived (manager);
{
MetaMonitorManagerDeriveFlag flags =
META_MONITOR_MANAGER_DERIVE_FLAG_CONFIGURED_SCALE;
meta_monitor_manager_rebuild_derived (manager, flags);
}
return TRUE;
}
@ -343,9 +364,12 @@ meta_monitor_manager_test_apply_configuration (MetaMonitorManager *manager,
MetaOutputInfo **outputs,
unsigned int n_outputs)
{
MetaMonitorManagerDeriveFlag flags =
META_MONITOR_MANAGER_DERIVE_FLAG_NONE;
apply_crtc_assignments (manager, crtcs, n_crtcs, outputs, n_outputs);
legacy_calculate_screen_size (manager);
meta_monitor_manager_rebuild_derived (manager);
meta_monitor_manager_rebuild_derived (manager, flags);
}
static void
@ -403,9 +427,10 @@ static gboolean
is_monitor_framebuffer_scaled (void)
{
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
return meta_backend_is_experimental_feature_enabled (
backend,
return meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
}

View File

@ -0,0 +1,22 @@
<monitors version="2">
<configuration>
<logicalmonitor>
<x>0</x>
<y>0</y>
<primary>yes</primary>
<monitor>
<monitorspec>
<connector>DP-2</connector>
<vendor>MetaProduct's Inc.</vendor>
<product>MetaMonitor</product>
<serial>0x123456</serial>
</monitorspec>
<mode>
<width>800</width>
<height>600</height>
<rate>60</rate>
</mode>
</monitor>
</logicalmonitor>
</configuration>
</monitors>

View File

@ -640,6 +640,10 @@ check_monitor_configuration (MonitorTestCase *test_case)
expected_current_mode_index)->data;
g_assert (current_mode == expected_current_mode);
if (current_mode)
g_assert (meta_monitor_is_active (monitor));
else
g_assert (!meta_monitor_is_active (monitor));
if (current_mode)
{
@ -1339,6 +1343,182 @@ meta_test_monitor_tiled_linear_config (void)
check_monitor_configuration (&test_case);
}
static void
meta_test_monitor_tiled_non_preferred_linear_config (void)
{
MonitorTestCase test_case = {
.setup = {
.modes = {
{
.width = 640,
.height = 480,
.refresh_rate = 60.0
},
{
.width = 800,
.height = 600,
.refresh_rate = 60.0
},
{
.width = 512,
.height = 768,
.refresh_rate = 120.0
},
{
.width = 1024,
.height = 768,
.refresh_rate = 60.0
},
},
.n_modes = 4,
.outputs = {
{
.crtc = -1,
.modes = { 0, 2 },
.n_modes = 2,
.preferred_mode = 1,
.possible_crtcs = { 0 },
.n_possible_crtcs = 1,
.width_mm = 222,
.height_mm = 125,
.tile_info = {
.group_id = 1,
.max_h_tiles = 2,
.max_v_tiles = 1,
.loc_h_tile = 0,
.loc_v_tile = 0,
.tile_w = 512,
.tile_h = 768
}
},
{
.crtc = -1,
.modes = { 1, 2, 3 },
.n_modes = 3,
.preferred_mode = 0,
.possible_crtcs = { 1 },
.n_possible_crtcs = 1,
.width_mm = 222,
.height_mm = 125,
.tile_info = {
.group_id = 1,
.max_h_tiles = 2,
.max_v_tiles = 1,
.loc_h_tile = 1,
.loc_v_tile = 0,
.tile_w = 512,
.tile_h = 768
}
}
},
.n_outputs = 2,
.crtcs = {
{
.current_mode = -1
},
{
.current_mode = -1
}
},
.n_crtcs = 2
},
.expect = {
.monitors = {
{
.outputs = { 0, 1 },
.n_outputs = 2,
.modes = {
{
.width = 1024,
.height = 768,
.crtc_modes = {
{
.output = 0,
.crtc_mode = 2
},
{
.output = 1,
.crtc_mode = 2,
}
}
},
{
.width = 800,
.height = 600,
.crtc_modes = {
{
.output = 0,
.crtc_mode = -1
},
{
.output = 1,
.crtc_mode = 1,
}
}
},
{
.width = 1024,
.height = 768,
.crtc_modes = {
{
.output = 0,
.crtc_mode = -1
},
{
.output = 1,
.crtc_mode = 3,
}
}
},
},
.n_modes = 3,
.current_mode = 0,
.width_mm = 222,
.height_mm = 125,
}
},
.n_monitors = 1,
.logical_monitors = {
{
.monitors = { 0 },
.n_monitors = 1,
.layout = { .x = 0, .y = 0, .width = 1024, .height = 768 },
.scale = 1
},
},
.n_logical_monitors = 1,
.primary_logical_monitor = 0,
.n_outputs = 2,
.crtcs = {
{
.current_mode = 2,
},
{
.current_mode = 2,
.x = 512
}
},
.n_crtcs = 2,
.n_tiled_monitors = 1,
.screen_width = 1024,
.screen_height = 768,
}
};
MetaMonitorTestSetup *test_setup;
if (!is_using_monitor_config_manager ())
{
g_test_skip ("Only the new monitor config manager handles this case.");
return;
}
test_setup = create_monitor_test_setup (&test_case,
MONITOR_TEST_FLAG_NO_STORED);
emulate_hotplug (test_setup);
check_monitor_configuration (&test_case);
}
static void
meta_test_monitor_hidpi_linear_config (void)
{
@ -3132,6 +3312,183 @@ meta_test_monitor_custom_tiled_custom_resolution_config (void)
check_monitor_configuration (&test_case);
}
static void
meta_test_monitor_custom_tiled_non_preferred_config (void)
{
MonitorTestCase test_case = {
.setup = {
.modes = {
{
.width = 640,
.height = 480,
.refresh_rate = 60.0
},
{
.width = 800,
.height = 600,
.refresh_rate = 60.0
},
{
.width = 512,
.height = 768,
.refresh_rate = 120.0
},
{
.width = 1024,
.height = 768,
.refresh_rate = 60.0
},
},
.n_modes = 4,
.outputs = {
{
.crtc = -1,
.modes = { 0, 2 },
.n_modes = 2,
.preferred_mode = 1,
.possible_crtcs = { 0 },
.n_possible_crtcs = 1,
.width_mm = 222,
.height_mm = 125,
.tile_info = {
.group_id = 1,
.max_h_tiles = 2,
.max_v_tiles = 1,
.loc_h_tile = 0,
.loc_v_tile = 0,
.tile_w = 512,
.tile_h = 768
}
},
{
.crtc = -1,
.modes = { 1, 2, 3 },
.n_modes = 3,
.preferred_mode = 0,
.possible_crtcs = { 1 },
.n_possible_crtcs = 1,
.width_mm = 222,
.height_mm = 125,
.tile_info = {
.group_id = 1,
.max_h_tiles = 2,
.max_v_tiles = 1,
.loc_h_tile = 1,
.loc_v_tile = 0,
.tile_w = 512,
.tile_h = 768
}
}
},
.n_outputs = 2,
.crtcs = {
{
.current_mode = -1
},
{
.current_mode = -1
}
},
.n_crtcs = 2
},
.expect = {
.monitors = {
{
.outputs = { 0, 1 },
.n_outputs = 2,
.modes = {
{
.width = 1024,
.height = 768,
.crtc_modes = {
{
.output = 0,
.crtc_mode = 2
},
{
.output = 1,
.crtc_mode = 2,
}
}
},
{
.width = 800,
.height = 600,
.crtc_modes = {
{
.output = 0,
.crtc_mode = -1
},
{
.output = 1,
.crtc_mode = 1,
}
}
},
{
.width = 1024,
.height = 768,
.crtc_modes = {
{
.output = 0,
.crtc_mode = -1
},
{
.output = 1,
.crtc_mode = 3,
}
}
},
},
.n_modes = 3,
.current_mode = 1,
.width_mm = 222,
.height_mm = 125,
}
},
.n_monitors = 1,
.logical_monitors = {
{
.monitors = { 0 },
.n_monitors = 1,
.layout = { .x = 0, .y = 0, .width = 800, .height = 600 },
.scale = 1
},
},
.n_logical_monitors = 1,
.primary_logical_monitor = 0,
.n_outputs = 2,
.crtcs = {
{
.current_mode = -1,
},
{
.current_mode = 1,
}
},
.n_crtcs = 2,
.n_tiled_monitors = 1,
.screen_width = 800,
.screen_height = 600,
}
};
MetaMonitorTestSetup *test_setup;
if (!is_using_monitor_config_manager ())
{
g_test_skip ("Only the new monitor config manager handles this case.");
return;
}
test_setup = create_monitor_test_setup (&test_case,
MONITOR_TEST_FLAG_NONE);
set_custom_monitor_config ("non-preferred-tiled-custom-resolution.xml");
emulate_hotplug (test_setup);
check_monitor_configuration (&test_case);
}
static void
meta_test_monitor_custom_mirrored_config (void)
{
@ -3904,6 +4261,8 @@ init_monitor_tests (void)
meta_test_monitor_preferred_linear_config);
g_test_add_func ("/backends/monitor/tiled-linear-config",
meta_test_monitor_tiled_linear_config);
g_test_add_func ("/backends/monitor/tiled-non-preferred-linear-config",
meta_test_monitor_tiled_non_preferred_linear_config);
g_test_add_func ("/backends/monitor/hidpi-linear-config",
meta_test_monitor_hidpi_linear_config);
g_test_add_func ("/backends/monitor/suggested-config",
@ -3933,6 +4292,8 @@ init_monitor_tests (void)
meta_test_monitor_custom_tiled_config);
g_test_add_func ("/backends/monitor/custom/tiled-custom-resolution-config",
meta_test_monitor_custom_tiled_custom_resolution_config);
g_test_add_func ("/backends/monitor/custom/tiled-non-preferred-config",
meta_test_monitor_custom_tiled_non_preferred_config);
g_test_add_func ("/backends/monitor/custom/mirrored-config",
meta_test_monitor_custom_mirrored_config);
g_test_add_func ("/backends/monitor/custom/first-rotated-config",

View File

@ -215,17 +215,18 @@ static gboolean
run_tests (gpointer data)
{
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
gboolean ret;
meta_backend_override_experimental_features (backend);
meta_settings_override_experimental_features (settings);
if (g_strcmp0 (g_getenv ("MUTTER_USE_CONFIG_MANAGER"), "1") == 0)
{
meta_backend_enable_experimental_feature (
backend,
meta_settings_enable_experimental_feature (
settings,
META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER);
meta_backend_enable_experimental_feature (
backend,
meta_settings_enable_experimental_feature (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
}

View File

@ -86,6 +86,10 @@ static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE (MetaWaylandPointer, meta_wayland_pointer,
META_TYPE_WAYLAND_INPUT_DEVICE)
static void
meta_wayland_pointer_set_current (MetaWaylandPointer *pointer,
MetaWaylandSurface *surface);
static void
meta_wayland_pointer_reset_grab (MetaWaylandPointer *pointer);
@ -246,14 +250,6 @@ sync_focus_surface (MetaWaylandPointer *pointer)
}
static void
pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
{
MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_surface_listener);
meta_wayland_pointer_set_focus (pointer, NULL);
}
static void
meta_wayland_pointer_send_frame (MetaWaylandPointer *pointer,
struct wl_resource *resource)
@ -488,8 +484,6 @@ meta_wayland_pointer_enable (MetaWaylandPointer *pointer)
g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) meta_wayland_pointer_client_free);
pointer->focus_surface_listener.notify = pointer_handle_focus_surface_destroy;
pointer->cursor_surface = NULL;
manager = clutter_device_manager_get_default ();
@ -520,6 +514,7 @@ meta_wayland_pointer_disable (MetaWaylandPointer *pointer)
meta_wayland_pointer_cancel_grab (pointer);
meta_wayland_pointer_reset_grab (pointer);
meta_wayland_pointer_set_focus (pointer, NULL);
meta_wayland_pointer_set_current (pointer, NULL);
g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref);
pointer->cursor_surface = NULL;
@ -547,11 +542,40 @@ count_buttons (const ClutterEvent *event)
return count;
}
static void
current_surface_destroyed (MetaWaylandSurface *surface,
MetaWaylandPointer *pointer)
{
meta_wayland_pointer_set_current (pointer, NULL);
}
static void
meta_wayland_pointer_set_current (MetaWaylandPointer *pointer,
MetaWaylandSurface *surface)
{
if (pointer->current)
{
g_signal_handler_disconnect (pointer->current,
pointer->current_surface_destroyed_handler_id);
pointer->current = NULL;
}
if (surface)
{
pointer->current = surface;
pointer->current_surface_destroyed_handler_id =
g_signal_connect (surface, "destroy",
G_CALLBACK (current_surface_destroyed),
pointer);
}
}
static void
repick_for_event (MetaWaylandPointer *pointer,
const ClutterEvent *for_event)
{
ClutterActor *actor;
MetaWaylandSurface *surface;
if (for_event)
actor = clutter_event_get_source (for_event);
@ -559,10 +583,18 @@ repick_for_event (MetaWaylandPointer *pointer,
actor = clutter_input_device_get_pointer_actor (pointer->device);
if (META_IS_SURFACE_ACTOR_WAYLAND (actor))
pointer->current =
meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor));
{
MetaSurfaceActorWayland *actor_wayland =
META_SURFACE_ACTOR_WAYLAND (actor);
surface = meta_surface_actor_wayland_get_surface (actor_wayland);
}
else
pointer->current = NULL;
{
surface = NULL;
}
meta_wayland_pointer_set_current (pointer, surface);
sync_focus_surface (pointer);
meta_wayland_pointer_update_cursor_surface (pointer);
@ -815,6 +847,13 @@ meta_wayland_pointer_broadcast_leave (MetaWaylandPointer *pointer,
meta_wayland_pointer_broadcast_frame (pointer);
}
static void
focus_surface_destroyed (MetaWaylandSurface *surface,
MetaWaylandPointer *pointer)
{
meta_wayland_pointer_set_focus (pointer, NULL);
}
void
meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
MetaWaylandSurface *surface)
@ -838,7 +877,9 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
pointer->focus_client = NULL;
}
wl_list_remove (&pointer->focus_surface_listener.link);
g_signal_handler_disconnect (pointer->focus_surface,
pointer->focus_surface_destroyed_handler_id);
pointer->focus_surface_destroyed_handler_id = 0;
pointer->focus_surface = NULL;
}
@ -848,8 +889,11 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
ClutterPoint pos;
pointer->focus_surface = surface;
wl_resource_add_destroy_listener (pointer->focus_surface->resource,
&pointer->focus_surface_listener);
pointer->focus_surface_destroyed_handler_id =
g_signal_connect_after (pointer->focus_surface, "destroy",
G_CALLBACK (focus_surface_destroyed),
pointer);
clutter_input_device_get_coords (pointer->device, NULL, &pos);
@ -1118,13 +1162,33 @@ meta_wayland_pointer_create_new_resource (MetaWaylandPointer *pointer,
}
}
static gboolean
pointer_can_grab_surface (MetaWaylandPointer *pointer,
MetaWaylandSurface *surface)
{
GList *l;
if (pointer->focus_surface == surface)
return TRUE;
for (l = surface->subsurfaces; l; l = l->next)
{
MetaWaylandSurface *subsurface = l->data;
if (pointer_can_grab_surface (pointer, subsurface))
return TRUE;
}
return FALSE;
}
gboolean
meta_wayland_pointer_can_grab_surface (MetaWaylandPointer *pointer,
MetaWaylandSurface *surface,
uint32_t serial)
{
return (pointer->grab_serial == serial &&
pointer->focus_surface == surface);
pointer_can_grab_surface (pointer, surface));
}
gboolean

View File

@ -71,7 +71,7 @@ struct _MetaWaylandPointer
GHashTable *pointer_clients;
MetaWaylandSurface *focus_surface;
struct wl_listener focus_surface_listener;
gulong focus_surface_destroyed_handler_id;
guint32 focus_serial;
guint32 click_serial;
@ -87,6 +87,7 @@ struct _MetaWaylandPointer
ClutterInputDevice *device;
MetaWaylandSurface *current;
gulong current_surface_destroyed_handler_id;
guint32 button_count;
};

View File

@ -264,6 +264,18 @@ meta_wayland_seat_free (MetaWaylandSeat *seat)
g_slice_free (MetaWaylandSeat, seat);
}
static gboolean
event_is_synthesized_crossing (const ClutterEvent *event)
{
ClutterInputDevice *device;
if (event->type != CLUTTER_ENTER && event->type != CLUTTER_LEAVE)
return FALSE;
device = clutter_event_get_source_device (event);
return clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER;
}
static gboolean
event_from_supported_hardware_device (MetaWaylandSeat *seat,
const ClutterEvent *event)
@ -310,7 +322,8 @@ void
meta_wayland_seat_update (MetaWaylandSeat *seat,
const ClutterEvent *event)
{
if (!event_from_supported_hardware_device (seat, event))
if (!event_from_supported_hardware_device (seat, event) &&
!event_is_synthesized_crossing (event))
return;
switch (event->type)
@ -319,6 +332,8 @@ meta_wayland_seat_update (MetaWaylandSeat *seat,
case CLUTTER_BUTTON_PRESS:
case CLUTTER_BUTTON_RELEASE:
case CLUTTER_SCROLL:
case CLUTTER_ENTER:
case CLUTTER_LEAVE:
if (meta_wayland_seat_has_pointer (seat))
meta_wayland_pointer_update (seat->pointer, event);
break;