Compare commits

...

39 Commits

Author SHA1 Message Date
aa45fa1e26 Bump version to 3.24.3
Update NEWS.
2017-06-23 11:38:37 +02:00
19f4342b46 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:34:30 +02:00
5fc6200375 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:44:13 +02:00
8a7b564219 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:03:35 +02:00
48d1bf9ea9 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:03:35 +02:00
02798ceeb6 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:03:35 +02:00
ee07580365 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:03:35 +02:00
e22c75377b 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:58:13 +08:00
0f7c3f3678 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 14:40:04 +08:00
bbed0d8045 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 14:40:04 +08:00
8699aca7d7 backends/x11: Ensure reply is initialised to NULL
https://bugzilla.gnome.org/show_bug.cgi?id=757661
2017-05-31 19:17:17 -04:00
2ec91abf38 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:13:39 +02:00
28b2added7 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:54:38 +08:00
a8ceceed1a window/wayland: Don't try to resize window on tear down
When terminating mutter running as a display server, don't try to resize
maximized windows when unmanaging, as at this point, they will have no
MetaWaylandSurface. Originally this was done instead of setting the
net_wm_state to not mess with future window managers, but when we're a
Wayland compositor, this does not matter.

https://bugzilla.gnome.org/show_bug.cgi?id=782156
2017-05-22 21:14:47 +08:00
7801df7ef6 wayland: place window if maximized before placement
If a client changes the state of a surface to issue a set_maximize, this
causes apply_pending_state() to be called before mutter has placed the
window.

If the monitor on which the window is to be shown initially is different
from the one where the pointer is placed, this causes the effect to be
played at the wrong location before the window eventually reaches its
location on another monitor.

Force the window to be placed prior to change its state to maximized in
xdg-shell so that mutter won't relocate the window afterwards.

This also avoids sending an xdg_toplevel.configure with a size of 0x0
which would cause the client to initially draw its surface with some
arbitrary size.

https://bugzilla.gnome.org/show_bug.cgi?id=782183
https://bugzilla.gnome.org/show_bug.cgi?id=781353
2017-05-22 09:26:08 +02:00
1b4cd1b47d cogl: Use pixel_format_to_gl_with_target in find_best_gl_get_data_format
Fixes cogl_texture_get_data() resorting to the wrong conversions when
extracting the texture data. This notably resulted in RGB/RGBA buffers
copied as-is into BGRA buffers, for instance for the fullscreen animation,
or single-window screenshots of such buffers.

https://bugzilla.gnome.org/show_bug.cgi?id=779234
2017-05-19 11:13:31 +02:00
7f0f880fba wayland: Apply size hints regardless of geometry
Previously we would bail out early in xdg_toplevel_role_commit() if no
geometry change was set, ignoring the possible min/max size hints
changes.

But setting a min/max size hint without changing the geometry is
perfectly valid, so we ought to apply the min/max changes regardless of
a geometry change.

https://bugzilla.gnome.org/show_bug.cgi?id=782213
2017-05-12 17:00:48 +02:00
ca31e4dc14 wayland: Make sure we have a pending geometry
If the client doesn't set a geometry using xdg_shell, we'll compute its
geometry based on its surface and subsurfaces.

Yet, we translate that as a window (re)size only when there is a pending
geometry, that we don't have when we computed the geometry by ourself.

Make sure we set the pending new geometry flag when computing the
geometry when it actually changed.

https://bugzilla.gnome.org/show_bug.cgi?id=782213
2017-05-12 17:00:42 +02:00
dfdc15c72c 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-12 10:11:07 +08:00
3254103d3e 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-12 10:11:07 +08:00
57d07bd38b tests/monitor-unit-tests: Check meta_monitor_is_active()
https://bugzilla.gnome.org/show_bug.cgi?id=781723
2017-05-12 10:11:07 +08:00
a3b4ee5689 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-12 10:11:07 +08:00
d8adfa9a31 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-12 10:11:07 +08:00
a6678a262c 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-12 10:11:07 +08:00
317517fcb5 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-12 10:11:07 +08:00
0f5ac1dc28 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-12 10:11:07 +08:00
01b6e32e87 Bump version to 3.24.2
Update NEWS.
2017-05-11 14:18:18 +02:00
bff311da88 build: Fix non-wayland builds
Add the necessary preprocessor guards that were missed in commits
65e9c89ed9 and 6d64123849 ...

https://bugzilla.gnome.org/show_bug.cgi?id=780533
2017-05-11 13:45:12 +02:00
6883a1f350 Fix bashism in autogen.sh
https://bugzilla.gnome.org/show_bug.cgi?id=780215
2017-05-11 13:45:12 +02:00
de3a01b5f5 cally: Fix compilation without X11 backend
Commit 0fd9e38175 fixed setting the out parameter for the x coordinate
when using the X11 backend, but broke compilation when the backend is
not available ...
Really fix the issue by running the X11-specific code when the X11
backend is available and in use, and display the one-time warning
otherwise.

https://bugzilla.gnome.org/show_bug.cgi?id=781902
2017-05-11 13:09:30 +02:00
1ab02344a7 xwayland: Use the right atom type for further selection requests to X11
If we translate between text/plain;charset-utf-8 from the wayland side to
UTF8_STRING on the X11 side, we want to continue all further X11 selection
requests using the same translated UTF8_STRING atom than we use in the
first XConvertSelection call.

https://bugzilla.gnome.org/show_bug.cgi?id=782472
2017-05-10 21:06:00 +02:00
90633660c7 Update Catalan translation 2017-05-06 08:33:45 +02:00
0e65bfcd3a clutter: conform/actor-graph: Add missing null-termination
https://bugzilla.gnome.org/show_bug.cgi?id=759085
2017-05-05 09:54:25 -04:00
79cf22324d cally: Fix translation to screen coordinates
Due to an accidental swap of an else statement and a preprocessor #else,
the output x coordinate is currently only set when not using the X11
windowing system, whoops.

https://bugzilla.gnome.org/show_bug.cgi?id=781902
2017-04-28 17:40:06 +02:00
ebfba766d1 window-props: Fix frame update on hide-titlebar-when-maximized changes
Since we started caching frame borders in commit b4036e061, we need to
invalidate the cache for changes of the GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED
property to take effect immediately.

https://bugzilla.gnome.org/show_bug.cgi?id=781862
2017-04-28 17:40:06 +02:00
bb481fafdb wayland/subsurface: Handle clients committing on destroyed subsurface
A client can still commit state to a destroyed subsurface. It wont
update anything on the screen, since the subsurface will not be
visible, but mutter should still handle it and not crash.

https://bugzilla.gnome.org/show_bug.cgi?id=781391
2017-04-21 17:48:06 +08:00
eb394f19d3 build: Require bash for pushd
If using sh, there's no pushd. Make autogen.sh execute with bash instead.

https://bugzilla.gnome.org/show_bug.cgi?id=781242
2017-04-13 10:16:26 +08:00
c6d3113416 Bump version to 3.24.1
Update NEWS.
2017-04-11 01:19:54 +02:00
196e524703 clutter-color: Shut up a compiler warning 2017-04-11 00:55:26 +02:00
31 changed files with 1540 additions and 506 deletions

51
NEWS
View File

@ -1,3 +1,54 @@
3.24.3
======
* Fix handling of tiled monitors [Jonas; #781723]
* Fix swapped red and blue channels in CoglTexture data [Carlos; #779234]
* Fix glitches when opening a window maximized [Olivier; #781353, #782183]
* Implement support for disable-while-typing option [Evan; #764852]
* Consider subsurfaces when grabbing [mindtree; #781811]
* 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 [Jonas, Bastien, Ikey, Carlos; #782156, #780407, #757661,
#783113, #781703]
Contributors:
mitchmindtree, Jonas Ådahl, Ikey Doherty, Olivier Fourdan, Carlos Garnacho,
Jason Gerecke, Silvère Latchurié, Bastien Nocera, Evan Welsh
3.24.2
======
* Don't crash when wayland clients commit to destroyed surfaces [Jonas; #781391]
* Fix frame updates on hide-titlebar-when-maximized changes [Florian; #781862]
* Fix accessible screen coordinates on X11 [Florian; #781902]
* Fix copy+paste of UTF8 strings between X11 and wayland [Carlos; #782472]
* Fix non-wayland builds [Chris; #780533]
* Misc. bug fixes [Philip, Matthias, Nigel; #781242, #780215, #759085]
Contributors:
Jonas Ådahl, Philip Chimento, Carlos Garnacho, Matthias Liertzer,
Florian Müllner, Nigel Taylor, Chris Vine
Translations:
Jordi Mas [ca]
3.24.1
======
* Always sync window geometry on state changes [Jonas; #780292]
* Use EGL instead of GLX when drawing using GLES [Jonas; #771636]
* Fix HiDPI detection on vertical monitor layouts [Carlos; #777687]
* Get double-click timing from desktop mouse settings [Armin; #771576]
* Scale relative motion deltas with monitor scale [Jonas, Carlos; #778119]
* Use texture fallback when setting hardware cursor fails [Jente; #770020]
* Fix lock-up when using additional theme variants [Shantanu; #780254]
Contributors:
Jonas Ådahl, Carlos Garnacho, Shantanu Goel, Jente Hidskes, Armin Krezović,
Florian Müllner
Translations:
Yuras Shumovich [be], Yosef Or Boczko [he], Tom Tryfonidis [el]
3.24.0
======

View File

@ -6,7 +6,9 @@ test -z "$srcdir" && srcdir=.
REQUIRED_AUTOMAKE_VERSION=1.11
pushd $srcdir
olddir="$(pwd)"
cd "${srcdir}"
(test -f configure.ac \
&& test -d src) || {
@ -19,8 +21,8 @@ aclocal --install || exit 1
intltoolize --force --copy --automake || exit 1
autoreconf --verbose --force --install || exit 1
popd
cd "${olddir}"
if [ "$NOCONFIGURE" = "" ]; then
$srcdir/configure "$@" || exit 1
"${srcdir}/configure" "$@" || exit 1
fi

View File

@ -781,7 +781,7 @@ _cally_actor_get_top_level_origin (ClutterActor *actor,
"position of the stage");
}
else
#else
#endif
{
static gboolean yet_warned = FALSE;
@ -793,7 +793,6 @@ _cally_actor_get_top_level_origin (ClutterActor *actor,
"atk_component_get_extents() with ATK_XY_SCREEN.");
}
}
#endif
if (xp)
*xp = x;

View File

@ -48,7 +48,7 @@
#include "clutter-debug.h"
/* XXX - keep in sync with the ClutterStaticColor enumeration order */
static const ClutterColor const static_colors[] = {
static const ClutterColor static_colors[] = {
/* CGA/EGA color palette */
{ 0xff, 0xff, 0xff, 0xff }, /* white */
{ 0x00, 0x00, 0x00, 0xff }, /* black */

View File

@ -350,7 +350,8 @@ actor_replace_child (void)
g_assert_cmpstr (clutter_actor_get_name (iter), ==, "qux");
clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
"name", "foo"));
"name", "foo",
NULL));
clutter_actor_replace_child (actor, iter,
g_object_new (CLUTTER_TYPE_ACTOR,

View File

@ -198,6 +198,7 @@ struct _CoglTextureDriver
CoglPixelFormat
(* find_best_gl_get_data_format) (CoglContext *context,
CoglPixelFormat format,
CoglPixelFormat target_format,
GLenum *closest_gl_format,
GLenum *closest_gl_type);
};

View File

@ -1059,6 +1059,7 @@ cogl_texture_get_data (CoglTexture *texture,
closest_format =
ctx->texture_driver->find_best_gl_get_data_format (ctx,
texture_format,
format,
&closest_gl_format,
&closest_gl_type);

View File

@ -533,14 +533,16 @@ static CoglPixelFormat
_cogl_texture_driver_find_best_gl_get_data_format
(CoglContext *context,
CoglPixelFormat format,
CoglPixelFormat target_format,
GLenum *closest_gl_format,
GLenum *closest_gl_type)
{
return context->driver_vtable->pixel_format_to_gl (context,
format,
NULL, /* don't need */
closest_gl_format,
closest_gl_type);
return context->driver_vtable->pixel_format_to_gl_with_target (context,
format,
target_format,
NULL, /* don't need */
closest_gl_format,
closest_gl_type);
}
const CoglTextureDriver

View File

@ -615,6 +615,7 @@ static CoglPixelFormat
_cogl_texture_driver_find_best_gl_get_data_format
(CoglContext *context,
CoglPixelFormat format,
CoglPixelFormat target_format,
GLenum *closest_gl_format,
GLenum *closest_gl_type)
{

View File

@ -2,7 +2,7 @@ AC_PREREQ(2.62)
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [24])
m4_define([mutter_micro_version], [0])
m4_define([mutter_micro_version], [3])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])

882
po/ca.po

File diff suppressed because it is too large Load Diff

View File

@ -65,6 +65,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,7 +120,6 @@ struct _MetaInputSettingsClass
ClutterInputDeviceTool *tool,
GDesktopStylusButtonAction primary,
GDesktopStylusButtonAction secondary);
gboolean (* has_two_finger_scroll) (MetaInputSettings *settings,
ClutterInputDevice *device);
};

View File

@ -448,6 +448,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 +738,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 +1027,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 +1274,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);
@ -1619,7 +1660,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

@ -260,6 +260,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);
}
@ -1667,7 +1670,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);
}

View File

@ -34,6 +34,8 @@ typedef struct _MetaMonitorMode
typedef struct _MetaMonitorPrivate
{
MetaMonitorManager *monitor_manager;
GList *outputs;
GList *modes;
@ -69,6 +71,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;
};
@ -135,7 +141,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);
@ -344,7 +350,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;
@ -354,11 +361,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;
}
@ -384,6 +393,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_init (MetaMonitorNormal *monitor)
{
@ -396,6 +422,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->get_suggested_position = meta_monitor_normal_get_suggested_position;
}
uint32_t
@ -409,16 +436,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
@ -437,7 +456,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);
}
@ -523,15 +542,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);
MetaMonitorMode *mode;
GList *l;
int i;
unsigned int i;
gboolean is_preferred = TRUE;
mode = g_new0 (MetaMonitorMode, 1);
meta_monitor_tiled_calculate_tiled_size (monitor,
@ -542,29 +599,93 @@ 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;
int x;
int y;
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 (mode);
return NULL;
}
calculate_tile_coordinate (monitor, output, &x, &y);
mode->crtc_modes[i] = (MetaMonitorCrtcMode) {
.x = x,
.y = y,
.output = output,
.crtc_mode = preferred_crtc_mode
.crtc_mode = tiled_crtc_mode
};
g_warn_if_fail (mode->spec.refresh_rate == 0.0f ||
(mode->spec.refresh_rate ==
preferred_crtc_mode->refresh_rate));
mode->spec.refresh_rate = refresh_rate;
mode->spec.refresh_rate = preferred_crtc_mode->refresh_rate;
is_preferred = is_preferred && tiled_crtc_mode == output->preferred_mode;
}
*out_is_preferred = is_preferred;
return 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 *
create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
MetaOutput *main_output,
@ -577,12 +698,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 (MetaMonitorMode, 1);
@ -620,42 +736,184 @@ create_untiled_monitor_mode (MetaMonitorTiled *monitor_tiled,
return mode;
}
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);
}
}
@ -671,17 +929,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;
}
@ -725,16 +988,23 @@ 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_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
@ -752,6 +1022,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->get_suggested_position = meta_monitor_tiled_get_suggested_position;
}
static void

View File

@ -68,6 +68,9 @@ struct _MetaMonitorClass
void (* derive_dimensions) (MetaMonitor *monitor,
int *width,
int *height);
gboolean (* get_suggested_position) (MetaMonitor *monitor,
int *width,
int *height);
};
#define META_TYPE_MONITOR_NORMAL (meta_monitor_normal_get_type ())
@ -83,7 +86,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);

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

@ -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

@ -348,7 +348,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);

View File

@ -388,7 +388,9 @@ meta_begin_modal_for_plugin (MetaCompositor *compositor,
meta_display_sync_wayland_input_focus (display);
meta_display_cancel_touch (display);
#ifdef HAVE_WAYLAND
meta_dnd_wayland_handle_begin_modal (compositor);
#endif
}
return TRUE;

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

@ -443,11 +443,13 @@ calculate_compositor_configuration (MetaCompositorType *compositor_type,
#endif /* HAVE_WAYLAND */
*compositor_type = META_COMPOSITOR_TYPE_X11;
#ifdef HAVE_WAYLAND
if (opt_nested)
{
*backend_gtype = META_TYPE_BACKEND_X11_NESTED;
return;
}
#endif /* HAVE_WAYLAND */
#ifdef HAVE_NATIVE_BACKEND
if (opt_display_server)

View File

@ -2957,7 +2957,11 @@ unmaximize_window_before_freeing (MetaWindow *window)
window->rect = window->saved_rect;
set_net_wm_state (window);
}
else if (window->screen->closing) /* See bug #358042 */
else if (window->screen->closing /* See bug #358042 */
#ifdef HAVE_WAYLAND
&& !meta_is_wayland_compositor ()
#endif
)
{
/* Do NOT update net_wm_state: this screen is closing,
* it likely will be managed by another window manager

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

@ -337,17 +337,29 @@ check_monitor_mode (MetaMonitor *monitor,
CheckMonitorModeData *data = user_data;
MetaMonitorManager *monitor_manager = data->monitor_manager;
MetaOutput *output;
int crtc_mode_index;
MetaCrtcMode *crtc_mode;
output = output_from_winsys_id (monitor_manager,
data->expect_crtc_mode_iter->output);
crtc_mode = &monitor_manager->modes[data->expect_crtc_mode_iter->crtc_mode];
crtc_mode_index = data->expect_crtc_mode_iter->crtc_mode;
if (crtc_mode_index == -1)
crtc_mode = NULL;
else
crtc_mode = &monitor_manager->modes[crtc_mode_index];
g_assert (monitor_crtc_mode->output == output);
g_assert (monitor_crtc_mode->crtc_mode == crtc_mode);
g_assert_cmpint (monitor_crtc_mode->x, ==, data->expect_crtc_mode_iter->x);
g_assert_cmpint (monitor_crtc_mode->y, ==, data->expect_crtc_mode_iter->y);
if (crtc_mode)
{
g_assert_cmpint (monitor_crtc_mode->x,
==,
data->expect_crtc_mode_iter->x);
g_assert_cmpint (monitor_crtc_mode->y,
==,
data->expect_crtc_mode_iter->y);
}
data->expect_crtc_mode_iter++;
@ -368,8 +380,11 @@ check_current_monitor_mode (MetaMonitor *monitor,
output = output_from_winsys_id (monitor_manager,
data->expect_crtc_mode_iter->output);
g_assert_nonnull (output->crtc);
g_assert (monitor_crtc_mode->crtc_mode == output->crtc->current_mode);
if (data->expect_crtc_mode_iter->crtc_mode != -1)
{
g_assert_nonnull (output->crtc);
g_assert (monitor_crtc_mode->crtc_mode == output->crtc->current_mode);
}
data->expect_crtc_mode_iter++;
@ -459,7 +474,8 @@ check_logical_monitor (MonitorTestCase *test_case,
primary_output = output;
}
g_assert (output->crtc->logical_monitor == logical_monitor);
g_assert (!output->crtc ||
output->crtc->logical_monitor == logical_monitor);
g_assert_cmpint (logical_monitor->is_presentation,
==,
output->is_presentation);
@ -583,6 +599,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)
{
@ -1237,6 +1257,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,
.x = 512
}
}
},
{
.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,
}
},
.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)
{
@ -2612,6 +2808,184 @@ meta_test_monitor_custom_underscanning_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,
.x = 512
}
}
},
{
.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 ("tiled-custom-resolution.xml");
emulate_hotplug (test_setup);
check_monitor_configuration (&test_case);
}
void
init_monitor_tests (void)
{
@ -2631,6 +3005,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",
@ -2654,4 +3030,6 @@ init_monitor_tests (void)
meta_test_monitor_custom_primary_config);
g_test_add_func ("/backends/monitor/custom/underscanning-config",
meta_test_monitor_custom_underscanning_config);
g_test_add_func ("/backends/monitor/custom/tiled-non-preferred-config",
meta_test_monitor_custom_tiled_non_preferred_config);
}

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

@ -615,7 +615,7 @@ subsurface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role)
meta_wayland_surface_role_get_surface (surface_role);
MetaWaylandSurface *parent = surface->sub.parent;
if (parent->role)
if (parent && parent->role)
return meta_wayland_surface_role_get_toplevel (parent->role);
else
return NULL;

View File

@ -348,6 +348,7 @@ xdg_toplevel_set_maximized (struct wl_client *client,
{
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
meta_window_force_placement (surface->window);
meta_window_maximize (surface->window, META_MAXIMIZE_BOTH);
}
@ -624,20 +625,18 @@ xdg_toplevel_role_commit (MetaWaylandSurfaceRole *surface_role,
if (!window)
return;
if (!pending->has_new_geometry)
if (pending->has_new_geometry)
{
if (pending->dx != 0 || pending->dx != 0)
{
g_warning ("XXX: Attach-initiated move without a new geometry. This is unimplemented right now.");
}
return;
window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface);
meta_window_wayland_move_resize (window,
&xdg_surface_priv->acked_configure_serial,
window_geometry,
pending->dx, pending->dy);
}
else if (pending->dx != 0 || pending->dx != 0)
{
g_warning ("XXX: Attach-initiated move without a new geometry. This is unimplemented right now.");
}
window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface);
meta_window_wayland_move_resize (window,
&xdg_surface_priv->acked_configure_serial,
window_geometry,
pending->dx, pending->dy);
/* When we get to this point, we ought to have valid size hints */
if (pending->has_new_min_size || pending->has_new_max_size)
@ -1272,11 +1271,19 @@ xdg_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
}
else if (!priv->has_set_geometry)
{
MetaRectangle new_geometry = { 0 };
/* If the surface has never set any geometry, calculate
* a default one unioning the surface and all subsurfaces together. */
meta_wayland_surface_calculate_window_geometry (surface,
&priv->geometry,
&new_geometry,
0, 0);
if (!meta_rectangle_equal (&new_geometry, &priv->geometry))
{
pending->has_new_geometry = TRUE;
priv->geometry = new_geometry;
}
}
}

View File

@ -829,7 +829,7 @@ meta_x11_source_send (MetaWaylandDataSource *source,
/* Takes ownership of fd */
selection->x11_selection =
x11_selection_data_new (compositor->xwayland_manager.selection_data,
fd, mime_type);
fd, gdk_x11_get_xatom_name (type_atom));
XConvertSelection (xdisplay,
selection->selection_atom, type_atom,

View File

@ -1721,6 +1721,7 @@ reload_gtk_hide_titlebar_when_maximized (MetaWindow *window,
if (META_WINDOW_MAXIMIZED (window))
{
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
meta_window_frame_size_changed (window);
if (window->frame)
meta_frame_update_style (window->frame);