Compare commits

...

32 Commits

Author SHA1 Message Date
17e5cd8c46 Bump version to 3.26.2
Update NEWS.
2017-11-02 16:54:54 +01:00
08e6aaa953 wayland/keyboard: Don't transfer layout group when replacing xkb state
The layout group determines what actual keyboard layout in the keymap
to use when translating modifier state and key codes to key syms.
When changing a keymap to another, the layout groups has no relation to
the layout groups in the old keymap, thus there is no reason to
transfer it to the new state.

This fixes an issue where the xkb state in meta-wayland-keyboard.c got
desynchronized with the xkb state in clutter-device-manager-evdev.c.

https://bugzilla.gnome.org/show_bug.cgi?id=789300
2017-11-02 12:07:56 +08:00
9187314216 monitor-manager-kms: Don't add outputs without modes
There seems to be a kernel race when one disconnects an external
monitor connected to a DisplayPort via a USB-C adapter. The race
results in a connector being reported as connected, but without any
modes supported.

This had the side effect that we tried to set a preferred mode to
the first listed mode, but as no modes were available, we instead tried
to dereference the first element of a NULL array, causing a
segmentation fault.

Mitigate this by skipping adding output if no supported modes are
advertised and the output doesn't support scaling, while moving the
fallback path for calculating a preferred output mode to after possibly
adding the common modes, to avoid the unvolentary NULL dereference.

https://bugzilla.gnome.org/show_bug.cgi?id=789501
2017-10-30 18:50:18 +08:00
634f48a1cf monitor-manager: Don't free old state until logical monitors are replaced
Logical monitors keep pointers around to monitor objects, which themself
keep pointers aronud to outputs, which keeps pointer to modes and CRTCs.
To avoid causing crashes when using the logical monitor API (which
might use monitor APIs etc) between a hot plug and the time the logical
monitors are regenerated (which is done synchronously in the native
backend but asynchronously in the X11 backend), postpone the freeing of
the state that logical monitor references, until the logical monitor
state is regenerated.

On the native backend, this should have no significant effect, as the
logical state is always regenerated immediately after the hardware
state is updated, but on X11, this should fix race conditions when
events being processed between the hot plug and the hot plug result
tries to access the yet to be up to date state.

https://bugzilla.gnome.org/show_bug.cgi?id=786929
2017-10-30 18:49:39 +08:00
656f64f3a5 backends: Unref variants obtained from g_variant_iter_get_next_value()
Those are being leaked.

https://bugzilla.gnome.org/show_bug.cgi?id=789553
2017-10-27 13:21:34 +02:00
81341ec9a9 wayland/surface: Disconnect actor handlers before unassigning role
The handlers depend on a role being assigned. Destroying the window
causes it to become unmapped, which would sometimes trigger one of the
handlers, resulting in an is-assigned assert hitting in one of the
handlers. Avoid this by disconnecting the handlers earlier, so that
there is no risk that any them being triggered before the role is
assigned.

https://bugzilla.gnome.org/show_bug.cgi?id=789552
2017-10-27 18:55:45 +08:00
8335a75ae5 wayland: Allow Xwayland to leave core dumps
For historical Xorg-reasons, Xwayland would disable its own core dumps by
default. This is a problem because Xwayland crashing is the biggest cause of
gnome-shell crashes [1][2], and we still have no idea why due to there being
no dumps from Xwayland. So enable core dumping from Xwayland.

https://bugzilla.gnome.org/show_bug.cgi?id=789086

[1] https://bugs.launchpad.net/bugs/1505409
[2] https://bugs.launchpad.net/bugs/1556601
2017-10-26 20:10:56 -05:00
b7fc6480dd wayland: Update pointer confinement on surface actor relocations
In the unlikely case that a surface is moved by the compositor while
holding a pointer confinement, we also need to update the pointer
position when the surface actor gets moved.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-10-26 13:02:32 +02:00
d9ea3ceabe wayland: Trigger wl_output updates on actor position changes
Both notify::position on the surface actor and position-changed on
MetaWindow are listened to, in order to trigger wl_output updates for
wl_surfaces whenever the surfaces move across them.

Both signals are necessary in order to cater for toplevel and subsurface
relocations (Because it's the parent window actor what changes position
in this last case).

Also, shuffle signal disconnection, so each signal goes away with
the object reference held by MetaWaylandSurface.

https://bugzilla.gnome.org/show_bug.cgi?id=782344
2017-10-26 13:02:32 +02:00
6ef08c5018 backends/native: Fix handling of trackball settings
The org.gnome.desktop.peripherals.trackball.scroll-wheel-emulation-button
setting contains buttons X11-style. Work out the BTN evcode that applies
to it when applying the setting on the libinput device.

https://bugzilla.gnome.org/show_bug.cgi?id=787804
2017-10-26 13:02:32 +02:00
8c35409eed MetaWindowActor: assert that we have plugin manager on simple effect
It looks that there are some extensions that run a Mainloop on startup,
causing to dispatch a clutter paint before the compositor is even available.
In such scenario a MetaWindow could try to start a simple effect
using a compositor plugin which is not there yet.

Then in order to catch these bugs we can now assert that the expected
conditions are valid, so that gnome-shell will provide a dumpstack to
debug the real offending JS code.

https://bugzilla.gnome.org/show_bug.cgi?id=789223
2017-10-24 04:46:37 -05:00
f6659928b2 MetaLogicalMonitor: free the monitors list on finalize
https://bugzilla.gnome.org/show_bug.cgi?id=789227
2017-10-24 03:19:27 -05:00
79fe635f5f Revert "tests: Fix actor-anchors test"
This reverts commit dd451547a5.

since we reverted commit 5cb5baa with commit 193216c
2017-10-21 19:00:46 -04:00
193216c2a7 Revert "ClutterActor: Optimize away idempotent scale/position updates"
This reverts commit 5cb5baa7d4.

There's a cascade of regressions that needs to be sorted out before
relanding this:

https://bugzilla.gnome.org/show_bug.cgi?id=784314
2017-10-19 19:55:49 -05:00
6eacf9a398 compositor: Avoid a crash if the top window actor is finalized
Since we're not holding a reference, the top window actor might be
finalized when we paint resulting in a use after free crash.

https://bugzilla.gnome.org/show_bug.cgi?id=788493
2017-10-19 18:37:59 +02:00
297027b8cb monitor-unit-tests: Check non-first preferred modes
Check that if there are multiple modes with the same ID (resolution,
refresh rate and handled flags) we correctly add the preferred mode to
the list of monitor modes.

https://bugzilla.gnome.org/show_bug.cgi?id=789153
2017-10-19 10:54:28 +08:00
c0dc66e8c0 monitor/normal: Prefer modes with same flags as preferred mode
When generating MetaMonitorMode's, prefer CRTC modes that has the same
set of flags as the preferred mode. This not only is probably a better
set of configurable modes, but it'll guarantee that the preferred mode
is added.

This fixes a crash when the preferred mode was not the first mode with
the same resolution, refresh rate and set of handled modes.

https://bugzilla.gnome.org/show_bug.cgi?id=789153
2017-10-19 10:54:27 +08:00
b48c349794 monitor-manager/xrandr: Use a single supported scales list for all
Under X11 we can only ever have the same scale configured on all
monitors. In order to use e.g. scale 2 when there is a HiDPI monitor
connected, we must not disallow it because there is a monitor that does
not support scale 2. Thus we must show the same scale for every monitor
and monitor mode, even though it might result in a bad experience.

Do this by iterating through all the monitors adding all supported
scales by the preferred mode, combining all the supported scales. This
supported scales list is then used for all monitor and modes no matter
what.

https://bugzilla.gnome.org/show_bug.cgi?id=788901
2017-10-17 15:31:54 +08:00
d71b0d3d27 compositor: Ignore offscreen windows when unredirecting
When determining whether we should unredirect a window or not, ignore
offscreen windows, and just check the top most visible window.

Previously this was not an issue, but since 'stack-tracker: Keep
override redirect windows on top' we started sorting the UI frames
window, which is an offscreen override redirect window, on top, causing
the unredirect checking code to always check whether to unredirect the
UI frames window. This effectively disabled the compositor bypass
functionality.

https://bugzilla.gnome.org/show_bug.cgi?id=788493
2017-10-17 14:54:54 +08:00
49ee46d924 x11/window: Don't manage InputOnly windows
This was dropped by mistake in commit
f166240225.

https://bugzilla.gnome.org/show_bug.cgi?id=788493
2017-10-17 14:54:53 +08:00
d6e3193c2a workspace: ensure that workarea data is valid when fetching by monitor num
https://bugzilla.gnome.org/show_bug.cgi?id=788860
2017-10-13 01:00:05 -05:00
c6c777a604 backend: move the cursor render update on screen changes here
https://bugzilla.gnome.org/show_bug.cgi?id=788860
2017-10-13 00:59:51 -05:00
bef9829229 monitor-manager: use g_return_val_if_fail if trying to fetch an invalid monitor
https://bugzilla.gnome.org/show_bug.cgi?id=788860
2017-10-13 00:59:33 -05:00
0a3549da06 backends: add 'monitors-updated-internal' signal to only update internal state
Adding an internal signal and use it to update the internal state before
emitting "monitors-changed" which will be repeated by the screen to the world.

https://bugzilla.gnome.org/show_bug.cgi?id=788860
2017-10-13 00:59:14 -05:00
65d3e47987 settings: Get UI scaling factor from primary logical monitor
Don't use MAX(logical monitor scales) to determine the UI scaling
factor, just use the primary logical monitor. That's where the shell UI
will most likely be.

https://bugzilla.gnome.org/show_bug.cgi?id=788820
2017-10-12 17:45:15 +08:00
41f7a5fdf3 x11: Protect XChangeProperty call with error traps
They may happen around the time a window is destroyed, thus could result
on BadWindow X errors.

https://bugzilla.gnome.org/show_bug.cgi?id=788666
2017-10-10 14:09:01 +02:00
425df31cf9 monitor-unit-tests: Check going headless -> headless
https://bugzilla.gnome.org/show_bug.cgi?id=788607
2017-10-08 09:42:56 +08:00
8886e1bbdc window: Handle updating from no to no monitor
When we received two hot plug events that both resulted in headless
configuration, we tried to find a new window monitor given the old.
That resulted in a null pointer dereference; avoid that by only trying
to find the same monitor if there was an old one.

https://bugzilla.gnome.org/show_bug.cgi?id=788607
2017-10-08 09:42:56 +08:00
7b02e2daf9 screen-cast-stream-src: Only clean up pipewire remote/core if they exist
They can could fail to create, so lets deal better with that
possibility.

https://bugzilla.gnome.org/show_bug.cgi?id=788569
2017-10-05 16:16:47 -04:00
62a772807f build: Fetch pipewire micro version
Pipewire doesn't export its version defines, so the API checks added
in commit f0c6c4eb1f effectively disable screencasting, whoops.
Breaking changes like this should disappear once the library stabilizes,
so simply define the version ourselves instead of writing a "proper"
test with AC_COMPILE_IFELSE() ...

https://bugzilla.gnome.org/show_bug.cgi?id=788572
2017-10-05 16:16:47 -04:00
edfd15b32d wayland-dma-buf: Don't send modifiers to old clients
The modifier event was only added in v3 of the client; sending it to
older clients (e.g. GStreamer waylandsink) causes them to disconnect
immediately.

Send the older 'format' event to all clients, and only send the newer
'modifier' event to resource versions 3 or above.

https://bugzilla.gnome.org/show_bug.cgi?id=788558
2017-10-05 13:11:34 -04:00
5b07a2c0ee [l10n] Updated Catalan (Valencian) translation 2017-10-05 14:15:59 +02:00
35 changed files with 1433 additions and 1018 deletions

22
NEWS
View File

@ -1,3 +1,25 @@
3.26.2
======
* Work with clients that require older linux_dmabuf protocol [Daniel; #788558]
* Prevent crash when closing maximized windows [Jonni; #788666]
* Use the correct monitor for HiDPI scaling of shell chrome [Jonas; #788820]
* Fix unredirection of fullscreen windows [Rui, Jonas; #788493]
* Fix list of supported monitor scales on X11 [Jonas; #788901]
* Fix handling of trackball settings on wayland [Carlos; #787804]
* Enable XWayland core dumps [Daniel; #789086]
* Fixes of misc. multi-monitor regressions and crashes [Jonas, Marco; #788607,
#788860, #789153, #786929, #789501]
* Misc. bug fixes [Florian, Jonas, Michael, Marco, Carlos; #788572, #788569,
#784314, #789227, #789223, #782344, #789552, #789553, #789300]
Contributors:
Jonas Ådahl, Jeremy Bicha, Michael Catanzaro, Carlos Garnacho, Rui Matos,
Florian Müllner, Daniel Stone, Marco Trevisan, Daniel van Vugt,
Jonni Westphalen
Translations:
Xavi Ivars [ca@valencia]
3.26.1
======
* Fix crash when respawning shortcut inhibitor dialog [Olivier; #787568]

View File

@ -4828,8 +4828,7 @@ clutter_actor_set_scale_factor (ClutterActor *self,
g_assert (pspec != NULL);
g_assert (scale_p != NULL);
if (*scale_p != factor)
_clutter_actor_create_transition (self, pspec, *scale_p, factor);
_clutter_actor_create_transition (self, pspec, *scale_p, factor);
}
static inline void
@ -10264,10 +10263,9 @@ clutter_actor_set_position (ClutterActor *self,
cur_position.x = clutter_actor_get_x (self);
cur_position.y = clutter_actor_get_y (self);
if (!clutter_point_equals (&cur_position, &new_position))
_clutter_actor_create_transition (self, obj_props[PROP_POSITION],
&cur_position,
&new_position);
_clutter_actor_create_transition (self, obj_props[PROP_POSITION],
&cur_position,
&new_position);
}
/**

View File

@ -407,7 +407,8 @@ 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_CENTER_X | NOTIFY_SCALE_CENTER_Y
assert_notifications (NOTIFY_SCALE_X | NOTIFY_SCALE_Y
| 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], [26])
m4_define([mutter_micro_version], [1])
m4_define([mutter_micro_version], [2])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
@ -245,6 +245,10 @@ AC_ARG_ENABLE(remote-desktop,
)
AS_IF([test "$enable_remote_desktop" = "yes"], [
MUTTER_PC_MODULES="$MUTTER_PC_MODULES libpipewire-0.1 >= 0.1.4"
PKG_CHECK_EXISTS([libpipewire-0.1], [
pw_micro=`$PKG_CONFIG --modversion libpipewire-0.1 | cut -d. -f3`
AC_DEFINE_UNQUOTED([PIPEWIRE_VERSION_MICRO],[$pw_micro], [Pipewire micro version used])
])
AC_DEFINE([HAVE_REMOTE_DESKTOP],[1], [Defined if screen cast and remote desktop support is enabled])
])
AM_CONDITIONAL([HAVE_REMOTE_DESKTOP],[test "$enable_remote_desktop" = "yes"])

File diff suppressed because it is too large Load Diff

View File

@ -197,7 +197,7 @@ meta_backend_monitors_changed (MetaBackend *backend)
}
}
meta_settings_update_ui_scaling_factor (priv->settings);
meta_cursor_renderer_force_update (priv->cursor_renderer);
}
void

View File

@ -1617,7 +1617,7 @@ meta_input_settings_init (MetaInputSettings *settings)
g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) device_mapping_info_free);
priv->monitor_manager = g_object_ref (meta_monitor_manager_get ());
g_signal_connect (priv->monitor_manager, "monitors-changed",
g_signal_connect (priv->monitor_manager, "monitors-changed-internal",
G_CALLBACK (monitors_changed_cb), settings);
#ifdef HAVE_LIBWACOM

View File

@ -204,9 +204,22 @@ meta_logical_monitor_init (MetaLogicalMonitor *logical_monitor)
{
}
static void
meta_logical_monitor_finalize (GObject *object)
{
MetaLogicalMonitor *logical_monitor = META_LOGICAL_MONITOR (object);
g_list_free (logical_monitor->monitors);
G_OBJECT_CLASS (meta_logical_monitor_parent_class)->finalize (object);
}
static void
meta_logical_monitor_class_init (MetaLogicalMonitorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_logical_monitor_finalize;
}
gboolean

View File

@ -328,6 +328,19 @@ struct _MetaMonitorManager
GList *monitors;
struct {
MetaOutput *outputs;
unsigned int n_outputs;
MetaCrtcMode *modes;
unsigned int n_modes;
MetaCrtc *crtcs;
unsigned int n_crtcs;
GList *monitors;
} pending_cleanup;
GList *logical_monitors;
MetaLogicalMonitor *primary_logical_monitor;

View File

@ -46,6 +46,7 @@
#define DEFAULT_DISPLAY_CONFIGURATION_TIMEOUT 20
enum {
MONITORS_CHANGED_INTERNAL,
CONFIRM_DISPLAY_CHANGE,
SIGNALS_LAST
};
@ -75,6 +76,9 @@ static gboolean
meta_monitor_manager_is_config_complete (MetaMonitorManager *manager,
MetaMonitorsConfig *config);
static void
cleanup_pending_cleanup_state (MetaMonitorManager *manager);
static void
meta_monitor_manager_init (MetaMonitorManager *manager)
{
@ -801,6 +805,8 @@ meta_monitor_manager_finalize (GObject *object)
meta_monitor_manager_free_crtc_array (manager->crtcs, manager->n_crtcs);
g_list_free_full (manager->logical_monitors, g_object_unref);
cleanup_pending_cleanup_state (manager);
g_signal_handler_disconnect (meta_get_backend (),
manager->experimental_features_changed_handler_id);
@ -851,6 +857,14 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
klass->read_edid = meta_monitor_manager_real_read_edid;
klass->is_lid_closed = meta_monitor_manager_real_is_lid_closed;
signals[MONITORS_CHANGED_INTERNAL] =
g_signal_new ("monitors-changed-internal",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
signals[CONFIRM_DISPLAY_CHANGE] =
g_signal_new ("confirm-display-change",
G_TYPE_FROM_CLASS (object_class),
@ -1769,6 +1783,8 @@ create_logical_monitor_config_from_variant (MetaMonitorManager *manager
monitor_config =
create_monitor_config_from_variant (manager,
monitor_config_variant, error);
g_variant_unref (monitor_config_variant);
if (!monitor_config)
goto err;
@ -1919,6 +1935,8 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet
logical_monitor_config_variant,
layout_mode,
&error);
g_variant_unref (logical_monitor_config_variant);
if (!logical_monitor_config)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
@ -2264,7 +2282,7 @@ MetaLogicalMonitor *
meta_monitor_manager_get_logical_monitor_from_number (MetaMonitorManager *manager,
int number)
{
g_assert ((unsigned int) number < g_list_length (manager->logical_monitors));
g_return_val_if_fail ((unsigned int) number < g_list_length (manager->logical_monitors), NULL);
return g_list_nth (manager->logical_monitors, number)->data;
}
@ -2469,16 +2487,10 @@ meta_monitor_manager_get_screen_size (MetaMonitorManager *manager,
}
static void
rebuild_monitors (MetaMonitorManager *manager)
generate_monitors (MetaMonitorManager *manager)
{
unsigned int i;
if (manager->monitors)
{
g_list_free_full (manager->monitors, g_object_unref);
manager->monitors = NULL;
}
for (i = 0; i < manager->n_outputs; i++)
{
MetaOutput *output = &manager->outputs[i];
@ -2538,6 +2550,37 @@ meta_monitor_manager_is_transform_handled (MetaMonitorManager *manager,
return manager_class->is_transform_handled (manager, crtc, transform);
}
static void
cleanup_pending_cleanup_state (MetaMonitorManager *manager)
{
if (manager->pending_cleanup.monitors)
{
g_list_free_full (manager->pending_cleanup.monitors, g_object_unref);
manager->pending_cleanup.monitors = NULL;
}
if (manager->pending_cleanup.outputs)
{
meta_monitor_manager_free_output_array (manager->pending_cleanup.outputs,
manager->pending_cleanup.n_outputs);
manager->pending_cleanup.outputs = NULL;
manager->pending_cleanup.n_outputs = 0;
}
if (manager->pending_cleanup.modes)
{
meta_monitor_manager_free_mode_array (manager->pending_cleanup.modes,
manager->pending_cleanup.n_modes);
manager->pending_cleanup.modes = NULL;
manager->pending_cleanup.n_modes = 0;
}
if (manager->pending_cleanup.crtcs)
{
meta_monitor_manager_free_crtc_array (manager->pending_cleanup.crtcs,
manager->pending_cleanup.n_crtcs);
manager->pending_cleanup.crtcs = NULL;
manager->pending_cleanup.n_crtcs = 0;
}
}
void
meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
{
@ -2559,11 +2602,46 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
manager->serial++;
META_MONITOR_MANAGER_GET_CLASS (manager)->read_current (manager);
rebuild_monitors (manager);
/*
* We must delay cleaning up the old hardware state, because the current
* logical state, when running on top of X11/Xrandr, may still be based on it
* for some time. The logical state may not be updated immediately, in case
* it is reconfigured, but after getting the response from a logical state
* configuration request to the X server. To be able to handle events and
* other things needing the logical state between the request and the
* response, the hardware state the logical state points to must be kept
* alive.
*
* If there is already a hardware state pending cleaning up, it means that
* the current logical state is still using that hardware state, so we can
* destroy the just replaced state immedietaley.
*/
if (manager->pending_cleanup.outputs ||
manager->pending_cleanup.crtcs ||
manager->pending_cleanup.monitors)
{
if (manager->monitors)
{
g_list_free_full (manager->monitors, g_object_unref);
manager->monitors = NULL;
}
meta_monitor_manager_free_output_array (old_outputs, n_old_outputs);
meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
meta_monitor_manager_free_crtc_array (old_crtcs, n_old_crtcs);
}
else
{
manager->pending_cleanup.outputs = old_outputs;
manager->pending_cleanup.n_outputs = n_old_outputs;
manager->pending_cleanup.modes = old_modes;
manager->pending_cleanup.n_modes = n_old_modes;
manager->pending_cleanup.crtcs = old_crtcs;
manager->pending_cleanup.n_crtcs = n_old_crtcs;
manager->pending_cleanup.monitors = manager->monitors;
manager->monitors = NULL;
}
meta_monitor_manager_free_output_array (old_outputs, n_old_outputs);
meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
meta_monitor_manager_free_crtc_array (old_crtcs, n_old_crtcs);
generate_monitors (manager);
}
static void
@ -2574,6 +2652,8 @@ meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager)
manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN;
meta_backend_monitors_changed (backend);
g_signal_emit (manager, signals[MONITORS_CHANGED_INTERNAL], 0);
g_signal_emit_by_name (manager, "monitors-changed");
}
@ -2653,6 +2733,8 @@ meta_monitor_manager_rebuild (MetaMonitorManager *manager,
meta_monitor_manager_notify_monitors_changed (manager);
g_list_free_full (old_logical_monitors, g_object_unref);
cleanup_pending_cleanup_state (manager);
}
static void
@ -2695,6 +2777,8 @@ meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager,
meta_monitor_manager_notify_monitors_changed (manager);
g_list_free_full (old_logical_monitors, g_object_unref);
cleanup_pending_cleanup_state (manager);
}
void

View File

@ -34,8 +34,6 @@
#define MINIMUM_LOGICAL_HEIGHT 600
#define MAXIMUM_REFRESH_RATE_DIFF 0.001
#define HANDLED_CRTC_MODE_FLAGS (META_CRTC_MODE_FLAG_INTERLACE)
typedef struct _MetaMonitorMode
{
char *id;
@ -394,16 +392,22 @@ generate_mode_id (MetaMonitorModeSpec *monitor_mode_spec)
static gboolean
meta_monitor_add_mode (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode)
MetaMonitorMode *monitor_mode,
gboolean replace)
{
MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
MetaMonitorMode *existing_mode;
if (g_hash_table_lookup (priv->mode_ids,
meta_monitor_mode_get_id (monitor_mode)))
existing_mode = g_hash_table_lookup (priv->mode_ids,
meta_monitor_mode_get_id (monitor_mode));
if (existing_mode && !replace)
return FALSE;
if (existing_mode)
priv->modes = g_list_remove (priv->modes, existing_mode);
priv->modes = g_list_append (priv->modes, monitor_mode);
g_hash_table_insert (priv->mode_ids, monitor_mode->id, monitor_mode);
g_hash_table_replace (priv->mode_ids, monitor_mode->id, monitor_mode);
return TRUE;
}
@ -415,13 +419,17 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
MetaOutput *output;
MetaCrtcModeFlag preferred_mode_flags;
unsigned int i;
output = meta_monitor_get_main_output (monitor);
preferred_mode_flags = output->preferred_mode->flags;
for (i = 0; i < output->n_modes; i++)
{
MetaCrtcMode *crtc_mode = output->modes[i];
MetaMonitorMode *mode;
gboolean replace;
mode = g_new0 (MetaMonitorMode, 1);
mode->spec = (MetaMonitorModeSpec) {
@ -437,13 +445,26 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
.crtc_mode = crtc_mode
};
/*
* We don't distinguish between all available mode flags, just the ones
* that are configurable. We still need to pick some mode though, so
* prefer ones that has the same set of flags as the preferred mode;
* otherwise take the first one in the list. This guarantees that the
* preferred mode is always added.
*/
replace = crtc_mode->flags == preferred_mode_flags;
if (!meta_monitor_add_mode (monitor, mode, replace))
{
g_assert (crtc_mode != output->preferred_mode);
meta_monitor_mode_free (mode);
continue;
}
if (crtc_mode == output->preferred_mode)
monitor_priv->preferred_mode = mode;
if (output->crtc && crtc_mode == output->crtc->current_mode)
monitor_priv->current_mode = mode;
if (!meta_monitor_add_mode (monitor, mode))
meta_monitor_mode_free (mode);
}
}
@ -825,7 +846,7 @@ generate_tiled_monitor_modes (MetaMonitorTiled *monitor_tiled)
tiled_modes = g_list_remove_link (tiled_modes, l);
if (!meta_monitor_add_mode (monitor, mode))
if (!meta_monitor_add_mode (monitor, mode, FALSE))
{
meta_monitor_mode_free (mode);
continue;
@ -967,7 +988,7 @@ generate_untiled_monitor_modes (MetaMonitorTiled *monitor_tiled)
if (!mode)
continue;
if (!meta_monitor_add_mode (monitor, mode))
if (!meta_monitor_add_mode (monitor, mode, FALSE))
{
meta_monitor_mode_free (mode);
continue;

View File

@ -48,6 +48,8 @@ typedef struct _MetaMonitorCrtcMode
MetaCrtcMode *crtc_mode;
} MetaMonitorCrtcMode;
#define HANDLED_CRTC_MODE_FLAGS (META_CRTC_MODE_FLAG_INTERLACE)
typedef gboolean (* MetaMonitorModeFunc) (MetaMonitor *monitor,
MetaMonitorMode *mode,
MetaMonitorCrtcMode *monitor_crtc_mode,

View File

@ -130,7 +130,7 @@ meta_screen_cast_monitor_stream_new (GDBusConnection *connection,
monitor_stream->stage = stage;
g_signal_connect_object (monitor_manager, "monitors-changed",
g_signal_connect_object (monitor_manager, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed),
monitor_stream, 0);

View File

@ -593,8 +593,8 @@ meta_screen_cast_stream_src_finalize (GObject *object)
meta_screen_cast_stream_src_disable (src);
g_clear_pointer (&priv->pipewire_stream, (GDestroyNotify) pw_stream_destroy);
pw_remote_destroy (priv->pipewire_remote);
pw_core_destroy (priv->pipewire_core);
g_clear_pointer (&priv->pipewire_remote, (GDestroyNotify) pw_remote_destroy);
g_clear_pointer (&priv->pipewire_core, (GDestroyNotify) pw_core_destroy);
g_source_destroy (&priv->pipewire_source->base);
G_OBJECT_CLASS (meta_screen_cast_stream_src_parent_class)->finalize (object);

View File

@ -67,23 +67,14 @@ calculate_ui_scaling_factor (MetaSettings *settings)
{
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (settings->backend);
GList *logical_monitors;
GList *l;
float max_scale = 1.0;
MetaLogicalMonitor *primary_logical_monitor;
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
primary_logical_monitor =
meta_monitor_manager_get_primary_logical_monitor (monitor_manager);
if (!primary_logical_monitor)
return 1;
max_scale = MAX (meta_logical_monitor_get_scale (logical_monitor),
max_scale);
}
g_warn_if_fail (fmodf (max_scale, 1.0) == 0.0);
return (int) max_scale;
return (int) meta_logical_monitor_get_scale (primary_logical_monitor);
}
static gboolean
@ -352,11 +343,25 @@ meta_settings_init (MetaSettings *settings)
update_experimental_features (settings);
}
static void
on_monitors_changed (MetaMonitorManager *monitor_manager,
MetaSettings *settings)
{
meta_settings_update_ui_scaling_factor (settings);
}
void
meta_settings_post_init (MetaSettings *settings)
{
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (settings->backend);
update_ui_scaling_factor (settings);
update_font_dpi (settings);
g_signal_connect_object (monitor_manager, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed),
settings, G_CONNECT_AFTER);
}
static void

View File

@ -850,7 +850,7 @@ meta_cursor_renderer_native_init (MetaCursorRendererNative *native)
MetaMonitorManager *monitors;
monitors = meta_monitor_manager_get ();
g_signal_connect_object (monitors, "monitors-changed",
g_signal_connect_object (monitors, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed), native, 0);
priv->hw_state_invalidated = TRUE;

View File

@ -245,16 +245,33 @@ meta_input_settings_native_set_scroll_button (MetaInputSettings *settings,
guint button)
{
struct libinput_device *libinput_device;
enum libinput_config_scroll_method method;
guint evcode;
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
if (!libinput_device)
return;
if (!device_set_scroll_method (libinput_device,
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN))
if (button == 0)
{
method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
evcode = 0;
}
else
{
/* Compensate for X11 scroll buttons */
if (button > 7)
button -= 4;
/* Button is 1-indexed */
evcode = (BTN_LEFT - 1) + button;
method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
}
if (!device_set_scroll_method (libinput_device, method))
return;
libinput_device_config_scroll_set_button (libinput_device, button);
libinput_device_config_scroll_set_button (libinput_device, evcode);
}
static void

View File

@ -692,7 +692,7 @@ init_crtc (MetaCrtc *crtc,
crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify;
}
static void
static gboolean
init_output (MetaOutput *output,
MetaMonitorManager *manager,
drmModeConnector *connector,
@ -746,9 +746,6 @@ init_output (MetaOutput *output,
output->preferred_mode = output->modes[i];
}
if (!output->preferred_mode)
output->preferred_mode = output->modes[0];
output_kms->connector = connector;
find_connector_properties (manager_kms, output_kms);
@ -759,6 +756,15 @@ init_output (MetaOutput *output,
if (output_kms->has_scaling)
add_common_modes (manager, output);
if (!output->modes)
{
meta_monitor_manager_clear_output (output);
return FALSE;
}
if (!output->preferred_mode)
output->preferred_mode = output->modes[0];
qsort (output->modes, output->n_modes, sizeof (MetaCrtcMode *), compare_modes);
output_kms->n_encoders = connector->count_encoders;
@ -865,6 +871,8 @@ init_output (MetaOutput *output,
output->backlight_min = 0;
output->backlight_max = 0;
output->backlight = -1;
return TRUE;
}
static void
@ -1091,8 +1099,8 @@ init_outputs (MetaMonitorManager *manager,
old_output = find_output_by_id (old_outputs, n_old_outputs,
connector->connector_id);
init_output (output, manager, connector, old_output);
n_actual_outputs++;
if (init_output (output, manager, connector, old_output))
n_actual_outputs++;
}
}

View File

@ -454,7 +454,7 @@ meta_backend_x11_post_init (MetaBackend *backend)
META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend);
monitor_manager = meta_backend_get_monitor_manager (backend);
g_signal_connect (monitor_manager, "monitors-changed",
g_signal_connect (monitor_manager, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed), backend);
}

View File

@ -71,6 +71,9 @@ struct _MetaMonitorManagerXrandr
int max_screen_width;
int max_screen_height;
float *supported_scales;
int n_supported_scales;
};
struct _MetaMonitorManagerXrandrClass
@ -1481,6 +1484,17 @@ meta_monitor_manager_xrandr_ensure_initial_config (MetaMonitorManager *manager)
meta_monitor_manager_update_logical_state_derived (manager, config);
}
static void
meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *manager,
MetaMonitorsConfig *config)
{
MetaMonitorManagerXrandr *manager_xrandr =
META_MONITOR_MANAGER_XRANDR (manager);
g_clear_pointer (&manager_xrandr->supported_scales, g_free);
meta_monitor_manager_rebuild_derived (manager, config);
}
static gboolean
meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *manager,
MetaMonitorsConfig *config,
@ -1492,7 +1506,7 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *mana
if (!config)
{
meta_monitor_manager_rebuild_derived (manager, NULL);
meta_monitor_manager_xrandr_rebuild_derived (manager, NULL);
return TRUE;
}
@ -1526,7 +1540,7 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *mana
}
else
{
meta_monitor_manager_rebuild_derived (manager, config);
meta_monitor_manager_xrandr_rebuild_derived (manager, config);
}
}
@ -1782,6 +1796,76 @@ meta_monitor_manager_xrandr_calculate_monitor_mode_scale (MetaMonitorManager *ma
return meta_monitor_calculate_mode_scale (monitor, monitor_mode);
}
static void
add_supported_scale (GArray *supported_scales,
float scale)
{
unsigned int i;
for (i = 0; i < supported_scales->len; i++)
{
float supported_scale = g_array_index (supported_scales, float, i);
if (scale == supported_scale)
return;
}
g_array_append_val (supported_scales, scale);
}
static int
compare_scales (gconstpointer a,
gconstpointer b)
{
float f = *(float *) a - *(float *) b;
if (f < 0)
return -1;
if (f > 0)
return 1;
return 0;
}
static void
ensure_supported_monitor_scales (MetaMonitorManager *manager)
{
MetaMonitorManagerXrandr *manager_xrandr =
META_MONITOR_MANAGER_XRANDR (manager);
MetaMonitorScalesConstraint constraints;
GList *l;
GArray *supported_scales;
if (manager_xrandr->supported_scales)
return;
constraints = META_MONITOR_SCALES_CONSTRAINT_NO_FRAC;
supported_scales = g_array_new (FALSE, FALSE, sizeof (float));
for (l = manager->monitors; l; l = l->next)
{
MetaMonitor *monitor = l->data;
MetaMonitorMode *monitor_mode;
float *monitor_scales;
int n_monitor_scales;
int i;
monitor_mode = meta_monitor_get_preferred_mode (monitor);
monitor_scales =
meta_monitor_calculate_supported_scales (monitor,
monitor_mode,
constraints,
&n_monitor_scales);
for (i = 0; i < n_monitor_scales; i++)
add_supported_scale (supported_scales, monitor_scales[i]);
g_array_sort (supported_scales, compare_scales);
}
manager_xrandr->supported_scales = (float *) supported_scales->data;
manager_xrandr->n_supported_scales = supported_scales->len;
g_array_free (supported_scales, FALSE);
}
static float *
meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager *manager,
MetaLogicalMonitorLayoutMode layout_mode,
@ -1789,12 +1873,14 @@ meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager
MetaMonitorMode *monitor_mode,
int *n_supported_scales)
{
MetaMonitorScalesConstraint constraints;
MetaMonitorManagerXrandr *manager_xrandr =
META_MONITOR_MANAGER_XRANDR (manager);
constraints = META_MONITOR_SCALES_CONSTRAINT_NO_FRAC;
return meta_monitor_calculate_supported_scales (monitor, monitor_mode,
constraints,
n_supported_scales);
ensure_supported_monitor_scales (manager);
*n_supported_scales = manager_xrandr->n_supported_scales;
return g_memdup (manager_xrandr->supported_scales,
manager_xrandr->n_supported_scales * sizeof (float));
}
static MetaMonitorManagerCapability
@ -1874,6 +1960,7 @@ meta_monitor_manager_xrandr_finalize (GObject *object)
manager_xrandr->resources = NULL;
g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms);
g_free (manager_xrandr->supported_scales);
G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object);
}
@ -1949,7 +2036,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
config = NULL;
}
meta_monitor_manager_rebuild_derived (manager, config);
meta_monitor_manager_xrandr_rebuild_derived (manager, config);
}
return TRUE;

View File

@ -31,6 +31,8 @@ struct _MetaCompositor
CoglContext *context;
MetaWindowActor *top_window_actor;
/* Used for unredirecting fullscreen windows */
guint disable_unredirect_count;
MetaWindow *unredirected_window;

View File

@ -671,6 +671,9 @@ meta_compositor_remove_window (MetaCompositor *compositor,
if (compositor->unredirected_window == window)
set_unredirected_window (compositor, NULL);
if (compositor->top_window_actor == window_actor)
compositor->top_window_actor = NULL;
meta_window_actor_destroy (window_actor);
}
@ -923,6 +926,32 @@ sync_actor_stacking (MetaCompositor *compositor)
g_list_free (backgrounds);
}
/*
* Find the top most window that is visible on the screen. The intention of
* this is to avoid offscreen windows that isn't actually part of the visible
* desktop (such as the UI frames override redirect window).
*/
static MetaWindowActor *
get_top_visible_window_actor (MetaCompositor *compositor)
{
GList *l;
for (l = g_list_last (compositor->windows); l; l = l->prev)
{
MetaWindowActor *window_actor = l->data;
MetaWindow *window = meta_window_actor_get_meta_window (window_actor);
MetaRectangle buffer_rect;
meta_window_get_buffer_rect (window, &buffer_rect);
if (meta_rectangle_overlap (&compositor->display->screen->rect,
&buffer_rect))
return window_actor;
}
return NULL;
}
void
meta_compositor_sync_stack (MetaCompositor *compositor,
GList *stack)
@ -1009,6 +1038,8 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
}
sync_actor_stacking (compositor);
compositor->top_window_actor = get_top_visible_window_actor (compositor);
}
void
@ -1065,19 +1096,26 @@ static gboolean
meta_pre_paint_func (gpointer data)
{
GList *l;
MetaWindowActor *top_window;
MetaWindowActor *top_window_actor;
MetaCompositor *compositor = data;
if (compositor->windows == NULL)
return TRUE;
top_window = g_list_last (compositor->windows)->data;
if (meta_window_actor_should_unredirect (top_window) &&
top_window_actor = compositor->top_window_actor;
if (top_window_actor &&
meta_window_actor_should_unredirect (top_window_actor) &&
compositor->disable_unredirect_count == 0)
set_unredirected_window (compositor, meta_window_actor_get_meta_window (top_window));
{
MetaWindow *top_window;
top_window = meta_window_actor_get_meta_window (top_window_actor);
set_unredirected_window (compositor, top_window);
}
else
set_unredirected_window (compositor, NULL);
{
set_unredirected_window (compositor, NULL);
}
for (l = compositor->windows; l; l = l->next)
meta_window_actor_pre_paint (l->data);

View File

@ -1069,6 +1069,8 @@ start_simple_effect (MetaWindowActor *self,
gint *counter = NULL;
gboolean use_freeze_thaw = FALSE;
g_assert (compositor->plugin_mgr != NULL);
switch (event)
{
case META_PLUGIN_NONE:

View File

@ -73,8 +73,10 @@ static void prefs_changed_callback (MetaPreference pref,
static void set_desktop_geometry_hint (MetaScreen *screen);
static void set_desktop_viewport_hint (MetaScreen *screen);
static void on_monitors_changed (MetaMonitorManager *manager,
MetaScreen *screen);
static void on_monitors_changed_internal (MetaMonitorManager *manager,
MetaScreen *screen);
static void on_monitors_changed (MetaMonitorManager *manager,
MetaScreen *screen);
enum
{
@ -710,6 +712,8 @@ meta_screen_new (MetaDisplay *display,
screen->rect.x = screen->rect.y = 0;
manager = meta_monitor_manager_get ();
g_signal_connect (manager, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed_internal), screen);
g_signal_connect (manager, "monitors-changed",
G_CALLBACK (on_monitors_changed), screen);
@ -2266,12 +2270,9 @@ meta_screen_resize_func (MetaWindow *window,
}
static void
on_monitors_changed (MetaMonitorManager *manager,
MetaScreen *screen)
on_monitors_changed_internal (MetaMonitorManager *manager,
MetaScreen *screen)
{
MetaBackend *backend;
MetaCursorRenderer *cursor_renderer;
meta_monitor_manager_get_screen_size (manager,
&screen->rect.width,
&screen->rect.height);
@ -2302,11 +2303,13 @@ on_monitors_changed (MetaMonitorManager *manager,
meta_screen_foreach_window (screen, META_LIST_DEFAULT, meta_screen_resize_func, 0);
meta_screen_queue_check_fullscreen (screen);
}
backend = meta_get_backend ();
cursor_renderer = meta_backend_get_cursor_renderer (backend);
meta_cursor_renderer_force_update (cursor_renderer);
static void
on_monitors_changed (MetaMonitorManager *manager,
MetaScreen *screen)
{
/* Inform the external world about what has happened */
g_signal_emit (screen, screen_signals[MONITORS_CHANGED], 0);
}

View File

@ -3793,7 +3793,7 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
new = find_monitor_by_winsys_id (window, window->preferred_output_winsys_id);
/* Otherwise, try to find the old output on a new monitor */
if (!new)
if (old && !new)
new = find_monitor_by_winsys_id (window, old->winsys_id);
/* Fall back to primary if everything else failed */

View File

@ -1099,13 +1099,16 @@ meta_workspace_get_work_area_for_monitor (MetaWorkspace *workspace,
MetaLogicalMonitor *logical_monitor;
MetaWorkspaceLogicalMonitorData *data;
ensure_work_areas_validated (workspace);
logical_monitor =
meta_monitor_manager_get_logical_monitor_from_number (monitor_manager,
which_monitor);
g_return_if_fail (logical_monitor != NULL);
ensure_work_areas_validated (workspace);
data = meta_workspace_get_logical_monitor_data (workspace, logical_monitor);
g_return_if_fail (data != NULL);
*area = data->logical_monitor_work_area;
}

View File

@ -419,7 +419,7 @@ check_monitor_mode (MetaMonitor *monitor,
flags = meta_monitor_mode_get_flags (mode);
g_assert_cmpfloat (refresh_rate, ==, crtc_mode->refresh_rate);
g_assert_cmpint (flags, ==, crtc_mode->flags);
g_assert_cmpint (flags, ==, (crtc_mode->flags & HANDLED_CRTC_MODE_FLAGS));
}
data->expect_crtc_mode_iter++;
@ -2631,6 +2631,13 @@ meta_test_monitor_no_outputs (void)
emulate_hotplug (test_setup);
check_monitor_configuration (&test_case);
/* Also check that we handle going headless -> headless */
test_setup = create_monitor_test_setup (&test_case,
MONITOR_TEST_FLAG_NO_STORED);
emulate_hotplug (test_setup);
check_monitor_configuration (&test_case);
}
static void
@ -2723,6 +2730,101 @@ meta_test_monitor_underscanning_config (void)
check_monitor_configuration (&test_case);
}
static void
meta_test_monitor_preferred_non_first_mode (void)
{
MonitorTestCase test_case = {
.setup = {
.modes = {
{
.width = 800,
.height = 600,
.refresh_rate = 60.0,
.flags = META_CRTC_MODE_FLAG_NHSYNC,
},
{
.width = 800,
.height = 600,
.refresh_rate = 60.0,
.flags = META_CRTC_MODE_FLAG_PHSYNC,
},
},
.n_modes = 2,
.outputs = {
{
.crtc = -1,
.modes = { 0, 1 },
.n_modes = 2,
.preferred_mode = 1,
.possible_crtcs = { 0 },
.n_possible_crtcs = 1,
.width_mm = 222,
.height_mm = 125
}
},
.n_outputs = 1,
.crtcs = {
{
.current_mode = -1
}
},
.n_crtcs = 1
},
.expect = {
.monitors = {
{
.outputs = { 0 },
.n_outputs = 1,
.modes = {
{
.width = 800,
.height = 600,
.refresh_rate = 60.0,
.crtc_modes = {
{
.output = 0,
.crtc_mode = 1
}
}
},
},
.n_modes = 1,
.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 = 800, .height = 600 },
.scale = 1
},
},
.n_logical_monitors = 1,
.primary_logical_monitor = 0,
.n_outputs = 1,
.crtcs = {
{
.current_mode = 1,
}
},
.n_crtcs = 1,
.screen_width = 800,
.screen_height = 600,
}
};
MetaMonitorTestSetup *test_setup;
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_custom_vertical_config (void)
{
@ -5310,6 +5412,8 @@ init_monitor_tests (void)
meta_test_monitor_no_outputs);
add_monitor_test ("/backends/monitor/underscanning-config",
meta_test_monitor_underscanning_config);
add_monitor_test ("/backends/monitor/preferred-non-first-mode",
meta_test_monitor_preferred_non_first_mode);
add_monitor_test ("/backends/monitor/custom/vertical-config",
meta_test_monitor_custom_vertical_config);

View File

@ -671,6 +671,21 @@ surface_actor_allocation_notify (MetaSurfaceActorWayland *surface_actor,
meta_pointer_confinement_wayland_maybe_warp (self);
}
static void
surface_actor_position_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaPointerConfinementWayland *self)
{
meta_pointer_confinement_wayland_maybe_warp (self);
}
static void
window_position_changed (MetaWindow *window,
MetaPointerConfinementWayland *self)
{
meta_pointer_confinement_wayland_maybe_warp (self);
}
MetaPointerConstraint *
meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint)
{
@ -689,6 +704,19 @@ meta_pointer_confinement_wayland_new (MetaWaylandPointerConstraint *constraint)
G_CALLBACK (surface_actor_allocation_notify),
confinement,
0);
g_signal_connect_object (surface->surface_actor,
"notify::position",
G_CALLBACK (surface_actor_position_notify),
confinement,
0);
if (surface->window)
{
g_signal_connect_object (surface->window,
"position-changed",
G_CALLBACK (window_position_changed),
confinement,
0);
}
return META_POINTER_CONSTRAINT (confinement);
}

View File

@ -473,12 +473,19 @@ send_modifiers (struct wl_resource *resource,
gboolean ret;
int i;
zwp_linux_dmabuf_v1_send_format (resource, format);
/* The modifier event was only added in v3; v1 and v2 only have the format
* event. */
if (wl_resource_get_version (resource) < ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION)
return;
/* First query the number of available modifiers, then allocate an array,
* then fill the array. */
ret = meta_egl_query_dma_buf_modifiers (egl, egl_display, format, 0, NULL,
NULL, &num_modifiers, NULL);
if (!ret || num_modifiers == 0)
return;
return;
modifiers = g_new0 (uint64_t, num_modifiers);
ret = meta_egl_query_dma_buf_modifiers (egl, egl_display, format,

View File

@ -478,23 +478,24 @@ static void
meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard)
{
MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
xkb_mod_mask_t latched, locked, group;
xkb_mod_mask_t latched, locked;
/* Preserve latched/locked modifiers state */
if (xkb_info->state)
{
latched = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LATCHED);
locked = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LOCKED);
group = xkb_state_serialize_layout (xkb_info->state, XKB_STATE_LAYOUT_EFFECTIVE);
xkb_state_unref (xkb_info->state);
}
else
latched = locked = group = 0;
{
latched = locked = 0;
}
xkb_info->state = xkb_state_new (xkb_info->keymap);
if (latched || locked || group)
xkb_state_update_mask (xkb_info->state, 0, latched, locked, 0, 0, group);
if (latched || locked)
xkb_state_update_mask (xkb_info->state, 0, latched, locked, 0, 0, 0);
}
static void

View File

@ -422,7 +422,7 @@ meta_wayland_outputs_init (MetaWaylandCompositor *compositor)
MetaMonitorManager *monitors;
monitors = meta_monitor_manager_get ();
g_signal_connect (monitors, "monitors-changed",
g_signal_connect (monitors, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed), compositor);
compositor->outputs = g_hash_table_new_full (NULL, NULL, NULL, wayland_output_destroy_notify);

View File

@ -50,11 +50,12 @@ typedef struct
char *lock_file;
int abstract_fd;
int unix_fd;
pid_t pid;
struct wl_client *client;
struct wl_resource *xserver_resource;
char *display_name;
GCancellable *xserver_died_cancellable;
GSubprocess *proc;
GMainLoop *init_loop;
MetaXWaylandSelection *selection_data;

View File

@ -182,6 +182,13 @@ static void
surface_actor_allocation_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaWaylandSurface *surface);
static void
surface_actor_position_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaWaylandSurface *surface);
static void
window_position_changed (MetaWindow *window,
MetaWaylandSurface *surface);
static void
unset_param_value (GParameter *param)
@ -422,13 +429,6 @@ meta_wayland_surface_destroy_window (MetaWaylandSurface *surface)
MetaDisplay *display = meta_get_display ();
guint32 timestamp = meta_display_get_current_time_roundtrip (display);
g_signal_handlers_disconnect_by_func (surface->surface_actor,
surface_actor_mapped_notify,
surface);
g_signal_handlers_disconnect_by_func (surface->surface_actor,
surface_actor_allocation_notify,
surface);
meta_window_unmanage (surface->window, timestamp);
}
@ -1272,18 +1272,47 @@ meta_wayland_surface_update_outputs (MetaWaylandSurface *surface)
surface);
}
static void
meta_wayland_surface_update_outputs_recursively (MetaWaylandSurface *surface)
{
GList *l;
meta_wayland_surface_update_outputs (surface);
for (l = surface->subsurfaces; l != NULL; l = l->next)
meta_wayland_surface_update_outputs_recursively (l->data);
}
void
meta_wayland_surface_set_window (MetaWaylandSurface *surface,
MetaWindow *window)
{
gboolean was_unmapped = surface->window && !window;
if (surface->window == window)
return;
if (surface->window)
{
g_signal_handlers_disconnect_by_func (surface->window,
window_position_changed,
surface);
}
surface->window = window;
sync_reactive (surface);
sync_drag_dest_funcs (surface);
if (was_unmapped)
g_signal_emit (surface, surface_signals[SURFACE_UNMAPPED], 0);
if (window)
{
g_signal_connect_object (window,
"position-changed",
G_CALLBACK (window_position_changed),
surface, 0);
}
}
static void
@ -1295,6 +1324,16 @@ wl_surface_destructor (struct wl_resource *resource)
g_signal_emit (surface, surface_signals[SURFACE_DESTROY], 0);
g_signal_handlers_disconnect_by_func (surface->surface_actor,
surface_actor_mapped_notify,
surface);
g_signal_handlers_disconnect_by_func (surface->surface_actor,
surface_actor_allocation_notify,
surface);
g_signal_handlers_disconnect_by_func (surface->surface_actor,
surface_actor_position_notify,
surface);
g_clear_object (&surface->role);
/* If we still have a window at the time of destruction, that means that
@ -1348,7 +1387,7 @@ surface_actor_mapped_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaWaylandSurface *surface)
{
meta_wayland_surface_update_outputs (surface);
meta_wayland_surface_update_outputs_recursively (surface);
}
static void
@ -1356,7 +1395,22 @@ surface_actor_allocation_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaWaylandSurface *surface)
{
meta_wayland_surface_update_outputs (surface);
meta_wayland_surface_update_outputs_recursively (surface);
}
static void
surface_actor_position_notify (MetaSurfaceActorWayland *surface_actor,
GParamSpec *pspec,
MetaWaylandSurface *surface)
{
meta_wayland_surface_update_outputs_recursively (surface);
}
static void
window_position_changed (MetaWindow *window,
MetaWaylandSurface *surface)
{
meta_wayland_surface_update_outputs_recursively (surface);
}
MetaWaylandSurface *
@ -1381,6 +1435,10 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
"notify::allocation",
G_CALLBACK (surface_actor_allocation_notify),
surface, 0);
g_signal_connect_object (surface->surface_actor,
"notify::position",
G_CALLBACK (surface_actor_position_notify),
surface, 0);
g_signal_connect_object (surface->surface_actor,
"notify::mapped",
G_CALLBACK (surface_actor_mapped_notify),

View File

@ -392,8 +392,15 @@ xserver_died (GObject *source,
gpointer user_data)
{
GSubprocess *proc = G_SUBPROCESS (source);
GError *error = NULL;
if (!g_subprocess_get_successful (proc))
if (!g_subprocess_wait_finish (proc, result, &error))
{
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
g_error ("Failed to finish waiting for Xwayland: %s", error->message);
g_clear_error (&error);
}
else if (!g_subprocess_get_successful (proc))
g_error ("X Wayland crashed; aborting");
else
{
@ -508,7 +515,6 @@ meta_xwayland_start (MetaXWaylandManager *manager,
gboolean started = FALSE;
g_autoptr(GSubprocessLauncher) launcher = NULL;
GSubprocessFlags flags;
GSubprocess *proc;
GError *error = NULL;
if (!choose_xdisplay (manager))
@ -545,20 +551,31 @@ meta_xwayland_start (MetaXWaylandManager *manager,
g_subprocess_launcher_take_fd (launcher, displayfd[1], 6);
g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
proc = g_subprocess_launcher_spawn (launcher, &error,
XWAYLAND_PATH, manager->display_name,
"-rootless", "-noreset",
"-listen", "4",
"-listen", "5",
"-displayfd", "6",
NULL);
if (!proc)
/* Use the -terminate parameter to ensure that Xwayland exits cleanly
* after the last client disconnects. Fortunately that includes the window
* manager so it won't exit prematurely either. This ensures that Xwayland
* won't try to reconnect and crash, leaving uninteresting core dumps. We do
* want core dumps from Xwayland but only if a real bug occurs...
*/
manager->proc = g_subprocess_launcher_spawn (launcher, &error,
XWAYLAND_PATH, manager->display_name,
"-rootless",
"-terminate",
"-core",
"-listen", "4",
"-listen", "5",
"-displayfd", "6",
NULL);
if (!manager->proc)
{
g_error ("Failed to spawn Xwayland: %s", error->message);
goto out;
}
g_subprocess_wait_async (proc, NULL, xserver_died, NULL);
manager->xserver_died_cancellable = g_cancellable_new ();
g_subprocess_wait_async (manager->proc, manager->xserver_died_cancellable,
xserver_died, NULL);
g_unix_fd_add (displayfd[0], G_IO_IN, on_displayfd_ready, manager);
manager->client = wl_client_create (wl_display, xwayland_client_fd[0]);
@ -598,7 +615,10 @@ meta_xwayland_stop (MetaXWaylandManager *manager)
{
char path[256];
g_cancellable_cancel (manager->xserver_died_cancellable);
meta_xwayland_shutdown_selection ();
g_clear_object (&manager->proc);
g_clear_object (&manager->xserver_died_cancellable);
snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->display_index);
unlink (path);

View File

@ -920,11 +920,13 @@ update_gtk_edge_constraints (MetaWindow *window)
meta_verbose ("Setting _GTK_EDGE_CONSTRAINTS to %lu\n", data[0]);
meta_error_trap_push (window->display);
XChangeProperty (window->display->xdisplay,
window->xwindow,
window->display->atom__GTK_EDGE_CONSTRAINTS,
XA_CARDINAL, 32, PropModeReplace,
(guchar*) data, 1);
meta_error_trap_pop (window->display);
}
static gboolean
@ -3037,6 +3039,12 @@ meta_window_x11_new (MetaDisplay *display,
goto error;
}
if (attrs.class == InputOnly)
{
meta_verbose ("Not managing InputOnly windows\n");
goto error;
}
if (is_our_xwindow (display, screen, xwindow, &attrs))
{
meta_verbose ("Not managing our own windows\n");