Compare commits
32 Commits
wip/kms-co
...
3.26.2
Author | SHA1 | Date | |
---|---|---|---|
17e5cd8c46 | |||
08e6aaa953 | |||
9187314216 | |||
634f48a1cf | |||
656f64f3a5 | |||
81341ec9a9 | |||
8335a75ae5 | |||
b7fc6480dd | |||
d9ea3ceabe | |||
6ef08c5018 | |||
8c35409eed | |||
f6659928b2 | |||
79fe635f5f | |||
193216c2a7 | |||
6eacf9a398 | |||
297027b8cb | |||
c0dc66e8c0 | |||
b48c349794 | |||
d71b0d3d27 | |||
49ee46d924 | |||
d6e3193c2a | |||
c6c777a604 | |||
bef9829229 | |||
0a3549da06 | |||
65d3e47987 | |||
41f7a5fdf3 | |||
425df31cf9 | |||
8886e1bbdc | |||
7b02e2daf9 | |||
62a772807f | |||
edfd15b32d | |||
5b07a2c0ee |
22
NEWS
22
NEWS
@ -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]
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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,
|
||||
|
@ -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"])
|
||||
|
1663
po/ca@valencia.po
1663
po/ca@valencia.po
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -31,6 +31,8 @@ struct _MetaCompositor
|
||||
|
||||
CoglContext *context;
|
||||
|
||||
MetaWindowActor *top_window_actor;
|
||||
|
||||
/* Used for unredirecting fullscreen windows */
|
||||
guint disable_unredirect_count;
|
||||
MetaWindow *unredirected_window;
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
Reference in New Issue
Block a user