Compare commits

...

22 Commits

Author SHA1 Message Date
Florian Müllner
34f5bdeea3 Bump version to 3.28.3
Update NEWS.
2018-07-18 23:12:51 +02:00
Jonas Ådahl
ca71b0eb1a monitor-manager: Add back warning messages
For some reason "backends: Remove X11 idle-monitor backend" removed
unrelated warning messages for when generated monitor configurations
that should work didn't, which also made the unit tests fail.

This commit adds them back, which also makes the tests pass again.


(cherry picked from commit d9c18fd5bb)
2018-07-18 20:21:12 +00:00
Jonas Ådahl
ca4209d88a screen-cast-src: Allow negotiating the framerate
The framerate for screen cast sources was set to variable within 1 FPS
and the framerate of the monitor being screen casted. This meant that if
the sink didn't match the framerate (e.g. had a lower max framerate),
the formats would not match and a stream would not be established.

Allow letting the sink clamp the framerate range by setting it as
'unset', allowing it to be negotiated.
2018-07-13 14:39:43 +02:00
Olivier Fourdan
3288edf677 contraints: Do not constrain modals without parent
xdg-foreign clears the `transient_for` of a modal dialog when its
imported parent is destroyed, which would later cause a crash in
`constrain_modal_dialog()` because the transient `NULL`.

So in case a modal dialog has no parent, do not try to constrain it
against its parent.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/174
(cherry picked from commit 912a6f5e3f)
2018-07-10 17:03:20 +02:00
Jonas Ådahl
fe1616668e backends: Add logical monitor -> monitor -> output -> crtc ref chain
Make it so that each logical monitor has a reference to all the
monitors that are assigned to it.

All monitors has a reference to each output that belongs to it.

Each output has a reference to any CRTC it has been assigned.

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


(cherry picked from commit 768ec15ea0)
2018-06-28 11:52:10 +00:00
Jonas Ådahl
7d01aec48d backends: Move MetaOutput::crtc field into private struct
No functional changes. This is only done so that changes to reference
counting can done more reliably.

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


(cherry picked from commit 1200182d70)
2018-06-28 11:50:37 +00:00
Marco Trevisan (Treviño)
a41d84db00 renderer-native: Don't crash if the FB surface can't be locked
(cherry picked from commit 0332b7394e)
2018-05-29 22:14:31 +00:00
Marco Trevisan (Treviño)
e73b321c2e device-manager-evdev: Add main seat to seats by default
Treat the main seat as other seats, so we don't have to handle it differently
in specific places. This was already the case before when a real device
was plugged before the startup, but not applied when hotplugging a device.


(cherry picked from commit 15f41c9f68)
2018-05-29 10:48:56 +00:00
Marco Trevisan (Treviño)
b6dc2052c3 device-manager-evdev: Free the main seat on finalize
(cherry picked from commit 2a38601b42)
2018-05-29 10:47:20 +00:00
Marco Trevisan (Treviño)
72965aaaf0 device-manager-evdev: Set and unset the stage for the main seat too
When no input devices are available on startup the device manager might be fast
enough to be constructed so that no default stage is set yet, and thus when
main seat virtual devices are created they won't have a proper stage set.
If then we plug a real device, the events that an input manager could generate
won't be associated to any stage and thus won't be processed.

We need then ensure that when we update the stage for the device manager we
(un)associate it also to the main seat devices.


(cherry picked from commit d7bdc1591f)
2018-05-29 10:46:03 +00:00
Marco Trevisan (Treviño)
2a6782dc10 clutter-device-evdev: Get devices from main seat if no real seat is set
In devices such as ARM boards there could be no input devices connected on
startup, leading to a crash when we try to process artificial events that
could be queued (as gnome-shell does when syncing pointer).

Those events still should refer to a device and, in case we don't have one
provided by libinput we should still return the core devices defined in the
main seat.


(cherry picked from commit 3e85ac8131)
2018-05-29 10:43:41 +00:00
Marco Trevisan (Treviño)
5142c8c7e7 clutter-seat-evdev: Add function to get device by id
(cherry picked from commit 5f83d9a5c8)
2018-05-29 10:43:17 +00:00
Changwoo Ryu
abc7ad8e9f wayland: Don't reset input focus on text commit
Preedit text can be active even after text commit. Resetting the input
focus will lead to unintended commit of the preedit text.

https://gitlab.gnome.org/GNOME/mutter/issues/152

Closes: #152
2018-05-26 15:26:09 +02:00
Olivier Fourdan
1a3f9a3323 frames: Allow for unknown mouse buttons
Commit 47131b1d ("frames: Handle touch events") introduced an assert to
make sure that all mouse button actions are handled in mutter.

However, mice can have a more than 5 buttons, so simply ignore the
"other" actions instead of aborting.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/160
(cherry picked from commit 473bf38753)
2018-05-25 11:35:45 +02:00
Olivier Fourdan
235c35182b wayland: update enter/leave output after effects
Compositor effects change the actor size and position, which can lead to
inconsistent output enter/leave notifications, leaving clients' surfaces
without any output set.

Update output enter/leave notifications after all compositor effects are
completed so that we give clients accurate output location.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/104
(cherry picked from commit 17a745bf81)
2018-05-22 13:01:13 +02:00
Olivier Fourdan
e4661d7870 window-actor: add new signal "effects-completed"
When using plugins, the effects will affect the MetaWindowActor size
and position.

Add a new signal "effects-completed" wired to the corresponding
MetaWindowActor which is emitted when all effects are completed so that
derived objects can be notified when all effects are completed and use
the actual size and position.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/104
(cherry picked from commit 85bbd82ae8)
2018-05-22 13:01:05 +02:00
Georges Basile Stavracas Neto
9d4c7e4e75 wayland: Compare geometries after chaining up
After 20176d03, the Wayland backend only synchronizes with the
compositor after a geometry was set, and it was different from
the current geometry.

That commit was mistakenly comparing the geometry before chaining
up, which would yield a false negative on the case where the
client didn't call set_geometry() before commit().

Fix that by caching the old geometry locally, chain up (and thus
apply the new geometry rectangle), then comparing the old and
current geometry rectangles.

Fixes https://gitlab.gnome.org/GNOME/mutter/issues/150


(cherry picked from commit cf734999fb)
2018-05-18 13:53:20 +00:00
Carlos Garnacho
47131b1dad frames: Handle touch events
This is just done on wayland as it'll break horribly on X11, we let
this happen through pointer emulated events in XISelectEvents evmask
instead.

Some things had to be made slightly more generic to accomodate touch
events. The MetaFrames shall lock onto a single touch at a time, we
don't allow crazy stuff like multi-window drag nor multi-edge resizes.

https://bugzilla.gnome.org/show_bug.cgi?id=770185
2018-05-15 16:07:07 +01:00
Carlos Garnacho
51c0130645 frames: Make 1st button/motion handlers take generic events
This will ease handling of touch events through these same handlers.

https://bugzilla.gnome.org/show_bug.cgi?id=770185
2018-05-15 16:06:59 +01:00
Olivier Fourdan
2dd9fc17c1 clutter/evdev: Don't ignore CAPS lock as modifier
Mark CAPS lock as a modifier (as it should) so that when using XKB
options to change the default behaviour of CAPS lock, the new assigned
key can by used as a sticky key as well.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/112
(cherry picked from commit 6df2b7af55)
2018-05-15 10:26:29 +02:00
Olivier Fourdan
c7a38c3139 clutter/evdev: ignore injected events from IM
Input method can inject key events, which leads to multiple reported key
press/release events for a single user action.

Ignore those events as this confuses keyboard accessibility.

(cherry picked from commit c01b099dbd)
2018-05-15 10:25:51 +02:00
Olivier Fourdan
7d52be0229 wayland: Use cursor position in logical monitor
When using two monitors size by side with different scales, once the
cursor moves from one output to another one, its size changes based on
the scale of the given output.

Changing the size of the cursor can cause the cursor area to change
output again if the hotspot is not exactly at the top left corner of the
area, causing the texture of the cursor to change, which will trigger
another output change, so on and so forth causing continuous surface
enter/leave event which flood the clients and eventually kill them.

Change the logic to use only the actual cursor position to determine if
its on the given logical monitor, so that it remains immune to scale
changes induced by output scale differences.

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/83
(cherry picked from commit 67917db45f)
2018-05-14 16:08:16 +02:00
36 changed files with 540 additions and 207 deletions

13
NEWS
View File

@@ -1,3 +1,16 @@
3.28.3
======
* Handle touch events on server-side titlebars [Carlos; #770185]
* Fix crash with unhandled mouse buttons on titlebars [Olivier; #160]
* Fix Korean Hangul support on wayland [Changwoo; #152]
* Fix crash when taking up from suspend [Jonas; #786929]
* Fix crash with parent-less modal dialogs [Olivier; #174]
* Misc. bug fixes [Olivier, Georges; #83, #112, #150, #104,
Contributors:
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Georges Basile Stavracas Neto,
Changwoo Ryu, Marco Trevisan (Treviño)
3.28.2
======
* Take inhibitors into account for monitoring idle [Bastien; #705942]

View File

@@ -793,10 +793,12 @@ evdev_add_device (ClutterDeviceManagerEvdev *manager_evdev,
if (priv->main_seat->libinput_seat == NULL)
seat = priv->main_seat;
else
seat = clutter_seat_evdev_new (manager_evdev);
{
seat = clutter_seat_evdev_new (manager_evdev);
priv->seats = g_slist_append (priv->seats, seat);
}
clutter_seat_evdev_set_libinput_seat (seat, libinput_seat);
priv->seats = g_slist_append (priv->seats, seat);
}
device = _clutter_input_device_evdev_new (manager, seat, libinput_device);
@@ -919,7 +921,6 @@ clutter_device_manager_evdev_get_device (ClutterDeviceManager *manager,
ClutterDeviceManagerEvdev *manager_evdev;
ClutterDeviceManagerEvdevPrivate *priv;
GSList *l;
GSList *device_it;
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager);
priv = manager_evdev->priv;
@@ -927,14 +928,10 @@ clutter_device_manager_evdev_get_device (ClutterDeviceManager *manager,
for (l = priv->seats; l; l = l->next)
{
ClutterSeatEvdev *seat = l->data;
ClutterInputDevice *device = clutter_seat_evdev_get_device (seat, id);
for (device_it = seat->devices; device_it; device_it = device_it->next)
{
ClutterInputDevice *device = device_it->data;
if (clutter_input_device_get_device_id (device) == id)
return device;
}
if (device)
return device;
}
return NULL;
@@ -1967,6 +1964,7 @@ clutter_device_manager_evdev_constructed (GObject *gobject)
xkb_context_unref (ctx);
priv->main_seat = clutter_seat_evdev_new (manager_evdev);
priv->seats = g_slist_append (priv->seats, priv->main_seat);
dispatch_libinput (manager_evdev);

View File

@@ -433,6 +433,8 @@ key_event_is_modifier (ClutterEvent *event)
case XKB_KEY_Super_R:
case XKB_KEY_Hyper_L:
case XKB_KEY_Hyper_R:
case XKB_KEY_Caps_Lock:
case XKB_KEY_Shift_Lock:
return TRUE;
default:
return FALSE;
@@ -584,6 +586,12 @@ handle_stickykeys_press (ClutterEvent *event,
}
depressed_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED);
/* Ignore the lock modifier mask, that one cannot be sticky, yet the
* CAPS_LOCK key itself counts as a modifier as it might be remapped
* to some other modifier which can be sticky.
*/
depressed_mods &= ~CLUTTER_LOCK_MASK;
new_latched_mask = device->stickykeys_latched_mask;
new_locked_mask = device->stickykeys_locked_mask;
@@ -1122,6 +1130,10 @@ clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent *e
{
ClutterInputDeviceEvdev *device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device);
/* Ignore key events injected from IM */
if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD)
goto emit_event;
if (!device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)
goto emit_event;

View File

@@ -858,6 +858,24 @@ clutter_seat_evdev_free (ClutterSeatEvdev *seat)
g_free (seat);
}
ClutterInputDevice *
clutter_seat_evdev_get_device (ClutterSeatEvdev *seat,
gint id)
{
ClutterInputDevice *device;
GSList *l;
for (l = seat->devices; l; l = l->next)
{
device = l->data;
if (clutter_input_device_get_device_id (device) == id)
return device;
}
return NULL;
}
void
clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat,
ClutterStage *stage)

View File

@@ -139,6 +139,9 @@ void clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
void clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat);
ClutterInputDevice * clutter_seat_evdev_get_device (ClutterSeatEvdev *seat,
gint id);
ClutterTouchState * clutter_seat_evdev_acquire_touch_state (ClutterSeatEvdev *seat,
int device_slot);

View File

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

View File

@@ -264,6 +264,18 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
update_cursor (renderer, priv->displayed_cursor);
}
ClutterPoint
meta_cursor_renderer_get_position (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv =
meta_cursor_renderer_get_instance_private (renderer);
return (ClutterPoint) {
.x = priv->current_x,
.y = priv->current_y
};
}
MetaCursorSprite *
meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
{

View File

@@ -62,6 +62,7 @@ void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
float x,
float y);
ClutterPoint meta_cursor_renderer_get_position (MetaCursorRenderer *renderer);
void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer);
MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);

View File

@@ -100,11 +100,12 @@ static MetaMonitorTransform
derive_monitor_transform (MetaMonitor *monitor)
{
MetaOutput *main_output;
MetaMonitorTransform transform;
main_output = meta_monitor_get_main_output (monitor);
transform = meta_output_get_assigned_crtc (main_output)->transform;
return meta_monitor_crtc_to_logical_transform (monitor,
main_output->crtc->transform);
return meta_monitor_crtc_to_logical_transform (monitor, transform);
}
MetaLogicalMonitor *
@@ -145,7 +146,7 @@ meta_logical_monitor_add_monitor (MetaLogicalMonitor *logical_monitor,
is_presentation = logical_monitor->is_presentation;
logical_monitor->monitors = g_list_append (logical_monitor->monitors,
monitor);
g_object_ref (monitor));
for (l = logical_monitor->monitors; l; l = l->next)
{
@@ -157,10 +158,12 @@ meta_logical_monitor_add_monitor (MetaLogicalMonitor *logical_monitor,
for (l_output = outputs; l_output; l_output = l_output->next)
{
MetaOutput *output = l_output->data;
MetaCrtc *crtc;
is_presentation = is_presentation && output->is_presentation;
if (output->crtc)
output->crtc->logical_monitor = logical_monitor;
crtc = meta_output_get_assigned_crtc (output);
if (crtc)
crtc->logical_monitor = logical_monitor;
}
}
@@ -220,7 +223,7 @@ foreach_crtc (MetaMonitor *monitor,
ForeachCrtcData *data = user_data;
data->func (data->logical_monitor,
monitor_crtc_mode->output->crtc,
meta_output_get_assigned_crtc (monitor_crtc_mode->output),
data->user_data);
return TRUE;
@@ -254,13 +257,17 @@ meta_logical_monitor_init (MetaLogicalMonitor *logical_monitor)
}
static void
meta_logical_monitor_finalize (GObject *object)
meta_logical_monitor_dispose (GObject *object)
{
MetaLogicalMonitor *logical_monitor = META_LOGICAL_MONITOR (object);
g_list_free (logical_monitor->monitors);
if (logical_monitor->monitors)
{
g_list_free_full (logical_monitor->monitors, g_object_unref);
logical_monitor->monitors = NULL;
}
G_OBJECT_CLASS (meta_logical_monitor_parent_class)->finalize (object);
G_OBJECT_CLASS (meta_logical_monitor_parent_class)->dispose (object);
}
static void
@@ -268,7 +275,7 @@ meta_logical_monitor_class_init (MetaLogicalMonitorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_logical_monitor_finalize;
object_class->dispose = meta_logical_monitor_dispose;
}
gboolean

View File

@@ -486,7 +486,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
output->is_dirty = TRUE;
output->crtc = crtc;
meta_output_assign_crtc (output, crtc);
}
}
}
@@ -531,7 +531,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
continue;
}
output->crtc = NULL;
meta_output_unassign_crtc (output);
output->is_primary = FALSE;
}
}

View File

@@ -585,6 +585,8 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
&error))
{
g_clear_object (&config);
g_warning ("Failed to use linear monitor configuration: %s",
error->message);
g_clear_error (&error);
}
else
@@ -602,6 +604,8 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
&error))
{
g_clear_object (&config);
g_warning ("Failed to use fallback monitor configuration: %s",
error->message);
g_clear_error (&error);
}
else
@@ -1041,6 +1045,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
GVariantBuilder crtcs, modes, clones, properties;
GBytes *edid;
char *edid_file;
MetaCrtc *crtc;
int crtc_index;
g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
@@ -1134,8 +1139,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
output->tile_info.tile_h));
}
crtc_index = output->crtc ? g_list_index (combined_crtcs, output->crtc)
: -1;
crtc = meta_output_get_assigned_crtc (output);
crtc_index = crtc ? g_list_index (combined_crtcs, crtc) : -1;
g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
i, /* ID */
(gint64)output->winsys_id,
@@ -2903,11 +2908,7 @@ meta_monitor_manager_get_monitor_for_connector (MetaMonitorManager *manager,
if (meta_monitor_is_active (monitor) &&
g_str_equal (connector, meta_monitor_get_connector (monitor)))
{
MetaOutput *main_output = meta_monitor_get_main_output (monitor);
return main_output->crtc->logical_monitor->number;
}
return meta_monitor_get_logical_monitor (monitor)->number;
}
return -1;

View File

@@ -204,10 +204,12 @@ gboolean
meta_monitor_is_active (MetaMonitor *monitor)
{
MetaOutput *output;
MetaCrtc *crtc;
output = meta_monitor_get_main_output (monitor);
crtc = meta_output_get_assigned_crtc (output);
return output->crtc && output->crtc->current_mode;
return crtc && crtc->current_mode;
}
gboolean
@@ -385,6 +387,21 @@ meta_monitor_crtc_to_logical_transform (MetaMonitor *monitor,
return new_transform;
}
static void
meta_monitor_dispose (GObject *object)
{
MetaMonitor *monitor = META_MONITOR (object);
MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
if (priv->outputs)
{
g_list_free_full (priv->outputs, g_object_unref);
priv->outputs = NULL;
}
G_OBJECT_CLASS (meta_monitor_parent_class)->dispose (object);
}
static void
meta_monitor_finalize (GObject *object)
{
@@ -393,7 +410,6 @@ meta_monitor_finalize (GObject *object)
g_hash_table_destroy (priv->mode_ids);
g_list_free_full (priv->modes, (GDestroyNotify) meta_monitor_mode_free);
g_clear_pointer (&priv->outputs, g_list_free);
meta_monitor_spec_free (priv->spec);
G_OBJECT_CLASS (meta_monitor_parent_class)->finalize (object);
@@ -412,6 +428,7 @@ meta_monitor_class_init (MetaMonitorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = meta_monitor_dispose;
object_class->finalize = meta_monitor_finalize;
}
@@ -493,6 +510,7 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
for (i = 0; i < output->n_modes; i++)
{
MetaCrtcMode *crtc_mode = output->modes[i];
MetaCrtc *crtc;
MetaMonitorMode *mode;
gboolean replace;
@@ -526,7 +544,9 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
if (crtc_mode == output->preferred_mode)
monitor_priv->preferred_mode = mode;
if (output->crtc && crtc_mode == output->crtc->current_mode)
crtc = meta_output_get_assigned_crtc (output);
if (crtc && crtc_mode == crtc->current_mode)
monitor_priv->current_mode = mode;
}
}
@@ -545,7 +565,7 @@ meta_monitor_normal_new (MetaGpu *gpu,
monitor_priv->gpu = gpu;
monitor_priv->outputs = g_list_append (NULL, output);
monitor_priv->outputs = g_list_append (NULL, g_object_ref (output));
monitor_priv->winsys_id = output->winsys_id;
meta_monitor_generate_spec (monitor);
@@ -568,13 +588,15 @@ meta_monitor_normal_derive_layout (MetaMonitor *monitor,
MetaRectangle *layout)
{
MetaOutput *output;
MetaCrtc *crtc;
output = meta_monitor_get_main_output (monitor);
crtc = meta_output_get_assigned_crtc (output);
*layout = (MetaRectangle) {
.x = output->crtc->rect.x,
.y = output->crtc->rect.y,
.width = output->crtc->rect.width,
.height = output->crtc->rect.height
.x = crtc->rect.x,
.y = crtc->rect.y,
.width = crtc->rect.width,
.height = crtc->rect.height
};
}
@@ -658,7 +680,8 @@ add_tiled_monitor_outputs (MetaGpu *gpu,
g_warn_if_fail (output->subpixel_order ==
monitor_tiled->origin_output->subpixel_order);
monitor_priv->outputs = g_list_append (monitor_priv->outputs, output);
monitor_priv->outputs = g_list_append (monitor_priv->outputs,
g_object_ref (output));
}
}
@@ -764,12 +787,13 @@ is_monitor_mode_assigned (MetaMonitor *monitor,
{
MetaOutput *output = l->data;
MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i];
MetaCrtc *crtc;
crtc = meta_output_get_assigned_crtc (output);
if (monitor_crtc_mode->crtc_mode &&
(!output->crtc ||
output->crtc->current_mode != monitor_crtc_mode->crtc_mode))
(!crtc || crtc->current_mode != monitor_crtc_mode->crtc_mode))
return FALSE;
else if (!monitor_crtc_mode->crtc_mode && output->crtc)
else if (!monitor_crtc_mode->crtc_mode && crtc)
return FALSE;
}
@@ -1217,14 +1241,16 @@ meta_monitor_tiled_derive_layout (MetaMonitor *monitor,
for (l = monitor_priv->outputs; l; l = l->next)
{
MetaOutput *output = l->data;
MetaCrtc *crtc;
if (!output->crtc)
crtc = meta_output_get_assigned_crtc (output);
if (!crtc)
continue;
min_x = MIN (output->crtc->rect.x, min_x);
min_y = MIN (output->crtc->rect.y, min_y);
max_x = MAX (output->crtc->rect.x + output->crtc->rect.width, max_x);
max_y = MAX (output->crtc->rect.y + output->crtc->rect.height, max_y);
min_x = MIN (crtc->rect.x, min_x);
min_y = MIN (crtc->rect.y, min_y);
max_x = MAX (crtc->rect.x + crtc->rect.width, max_x);
max_y = MAX (crtc->rect.y + crtc->rect.height, max_y);
}
*layout = (MetaRectangle) {
@@ -1318,10 +1344,14 @@ meta_monitor_get_spec (MetaMonitor *monitor)
MetaLogicalMonitor *
meta_monitor_get_logical_monitor (MetaMonitor *monitor)
{
MetaOutput *output = meta_monitor_get_main_output (monitor);
MetaOutput *output;
MetaCrtc *crtc;
if (output->crtc)
return output->crtc->logical_monitor;
output = meta_monitor_get_main_output (monitor);
crtc = meta_output_get_assigned_crtc (output);
if (crtc)
return crtc->logical_monitor;
else
return NULL;
}

View File

@@ -21,7 +21,13 @@
#include "backends/meta-output.h"
G_DEFINE_TYPE (MetaOutput, meta_output, G_TYPE_OBJECT)
typedef struct _MetaOutputPrivate
{
/* The CRTC driving this output, NULL if the output is not enabled */
MetaCrtc *crtc;
} MetaOutputPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaOutput, meta_output, G_TYPE_OBJECT)
MetaGpu *
meta_output_get_gpu (MetaOutput *output)
@@ -29,6 +35,44 @@ meta_output_get_gpu (MetaOutput *output)
return output->gpu;
}
void
meta_output_assign_crtc (MetaOutput *output,
MetaCrtc *crtc)
{
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
g_assert (crtc);
g_set_object (&priv->crtc, crtc);
}
void
meta_output_unassign_crtc (MetaOutput *output)
{
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
g_clear_object (&priv->crtc);
}
MetaCrtc *
meta_output_get_assigned_crtc (MetaOutput *output)
{
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
return priv->crtc;
}
static void
meta_output_dispose (GObject *object)
{
MetaOutput *output = META_OUTPUT (object);
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
g_clear_object (&priv->crtc);
G_OBJECT_CLASS (meta_output_parent_class)->dispose (object);
}
static void
meta_output_finalize (GObject *object)
{
@@ -58,5 +102,6 @@ meta_output_class_init (MetaOutputClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = meta_output_dispose;
object_class->finalize = meta_output_finalize;
}

View File

@@ -64,9 +64,6 @@ struct _MetaOutput
MetaGpu *gpu;
/* The CRTC driving this output, NULL if the output is not enabled */
MetaCrtc *crtc;
/* The low-level ID of this output, used to apply back configuration */
glong winsys_id;
char *name;
@@ -122,4 +119,11 @@ G_DECLARE_FINAL_TYPE (MetaOutput, meta_output, META, OUTPUT, GObject)
MetaGpu * meta_output_get_gpu (MetaOutput *output);
void meta_output_assign_crtc (MetaOutput *output,
MetaCrtc *crtc);
void meta_output_unassign_crtc (MetaOutput *output);
MetaCrtc * meta_output_get_assigned_crtc (MetaOutput *output);
#endif /* META_OUTPUT_H */

View File

@@ -360,9 +360,9 @@ create_pipewire_stream (MetaScreenCastStreamSrc *src,
":", spa_type->format_video.format, "I", spa_type->video_format.BGRx,
":", spa_type->format_video.size, "R", &SPA_RECTANGLE (width, height),
":", spa_type->format_video.framerate, "F", &SPA_FRACTION (0, 1),
":", spa_type->format_video.max_framerate, "Fr", &max_framerate,
PROP_RANGE (&min_framerate,
&max_framerate));
":", spa_type->format_video.max_framerate, "Fru", &max_framerate,
PROP_RANGE (&min_framerate,
&max_framerate));
pw_stream_add_listener (pipewire_stream,
&priv->pipewire_stream_listener,

View File

@@ -291,6 +291,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
data->in_cursor_renderer_native;
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
MetaCrtc *crtc;
MetaMonitorTransform transform;
ClutterRect scaled_crtc_rect;
float scale;
@@ -330,6 +331,8 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
},
};
crtc = meta_output_get_assigned_crtc (monitor_crtc_mode->output);
if (priv->has_hw_cursor &&
clutter_rect_intersection (&scaled_crtc_rect,
&data->in_local_cursor_rect,
@@ -340,7 +343,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
float crtc_cursor_x, crtc_cursor_y;
set_crtc_cursor (data->in_cursor_renderer_native,
monitor_crtc_mode->output->crtc,
crtc,
data->in_cursor_sprite);
gpu_kms = META_GPU_KMS (meta_monitor_get_gpu (monitor));
@@ -350,7 +353,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
crtc_cursor_y = (data->in_local_cursor_rect.origin.y -
scaled_crtc_rect.origin.y) * scale;
drmModeMoveCursor (kms_fd,
monitor_crtc_mode->output->crtc->crtc_id,
crtc->crtc_id,
roundf (crtc_cursor_x),
roundf (crtc_cursor_y));
@@ -358,8 +361,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
}
else
{
set_crtc_cursor (data->in_cursor_renderer_native,
monitor_crtc_mode->output->crtc, NULL);
set_crtc_cursor (data->in_cursor_renderer_native, crtc, NULL);
}
return TRUE;

View File

@@ -105,8 +105,10 @@ get_crtc_drm_connectors (MetaGpu *gpu,
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
{
MetaOutput *output = l->data;
MetaCrtc *assigned_crtc;
if (output->crtc == crtc)
assigned_crtc = meta_output_get_assigned_crtc (output);
if (assigned_crtc == crtc)
g_array_append_val (connectors_array, output->winsys_id);
}
@@ -186,8 +188,10 @@ meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
{
MetaOutput *output = l->data;
MetaCrtc *assigned_crtc;
if (output->crtc == crtc)
assigned_crtc = meta_output_get_assigned_crtc (output);
if (assigned_crtc == crtc)
{
connected_crtc_found = TRUE;
break;

View File

@@ -188,7 +188,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
MetaOutput *output = g_ptr_array_index (crtc_info->outputs, j);
output->is_dirty = TRUE;
output->crtc = crtc;
meta_output_assign_crtc (output, crtc);
}
}
@@ -249,7 +249,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
continue;
}
output->crtc = NULL;
meta_output_unassign_crtc (output);
output->is_primary = FALSE;
}
}

View File

@@ -64,11 +64,13 @@ typedef struct _MetaOutputKms
void
meta_output_kms_set_underscan (MetaOutput *output)
{
if (!output->crtc)
MetaCrtc *crtc;
crtc = meta_output_get_assigned_crtc (output);
if (!crtc)
return;
meta_crtc_kms_set_underscan (output->crtc,
output->is_underscanning);
meta_crtc_kms_set_underscan (crtc, output->is_underscanning);
}
void
@@ -600,14 +602,14 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
if (crtc->crtc_id == output_kms->current_encoder->crtc_id)
{
output->crtc = crtc;
meta_output_assign_crtc (output, crtc);
break;
}
}
}
else
{
output->crtc = NULL;
meta_output_unassign_crtc (output);
}
if (old_output)

View File

@@ -1601,6 +1601,12 @@ gbm_get_next_fb_id (MetaGpuKms *gpu_kms,
/* Now we need to set the CRTC to whatever is the front buffer */
next_bo = gbm_surface_lock_front_buffer (gbm_surface);
if (!next_bo)
{
g_error ("Impossible to lock surface front buffer: %m");
return FALSE;
}
for (i = 0; i < gbm_bo_get_plane_count (next_bo); i++)
{
strides[i] = gbm_bo_get_stride_for_plane (next_bo, i);
@@ -2083,6 +2089,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
EGLDisplay egl_display = renderer_gpu_data->egl_display;
MetaMonitor *monitor;
MetaOutput *output;
MetaCrtc *crtc;
EGLConfig egl_config;
EGLStreamKHR egl_stream;
EGLSurface egl_surface;
@@ -2106,6 +2113,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
output = meta_monitor_get_main_output (monitor);
crtc = meta_output_get_assigned_crtc (output);
/*
* An "logical_monitor" may have multiple outputs/crtcs in case its tiled,
@@ -2113,7 +2121,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
* lets pass the first one.
*/
output_attribs[0] = EGL_DRM_CRTC_EXT;
output_attribs[1] = output->crtc->crtc_id;
output_attribs[1] = crtc->crtc_id;
output_attribs[2] = EGL_NONE;
if (!meta_egl_get_output_layers (egl, egl_display,
@@ -2711,12 +2719,10 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
{
MetaMonitor *main_monitor;
MetaOutput *main_output;
MetaMonitorTransform crtc_transform;
MetaCrtc *crtc;
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
main_output = meta_monitor_get_main_output (main_monitor);
crtc_transform =
meta_monitor_logical_to_crtc_transform (main_monitor,
logical_monitor->transform);
crtc = meta_output_get_assigned_crtc (main_output);
/*
* Pick any monitor and output and check; all CRTCs of a logical monitor will
@@ -2724,11 +2730,11 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
*/
if (meta_monitor_manager_is_transform_handled (monitor_manager,
main_output->crtc,
crtc_transform))
crtc,
crtc->transform))
return META_MONITOR_TRANSFORM_NORMAL;
else
return crtc_transform;
return crtc->transform;
}
static MetaRendererView *

View File

@@ -225,8 +225,10 @@ is_crtc_assignment_changed (MetaCrtc *crtc,
for (j = 0; j < crtc_info->outputs->len; j++)
{
MetaOutput *output = ((MetaOutput**) crtc_info->outputs->pdata)[j];
MetaCrtc *assigned_crtc;
if (output->crtc != crtc)
assigned_crtc = meta_output_get_assigned_crtc (output);
if (assigned_crtc != crtc)
return TRUE;
}
@@ -243,6 +245,7 @@ is_output_assignment_changed (MetaOutput *output,
MetaOutputInfo **output_infos,
unsigned int n_output_infos)
{
MetaCrtc *assigned_crtc;
gboolean output_is_found = FALSE;
unsigned int i;
@@ -265,8 +268,10 @@ is_output_assignment_changed (MetaOutput *output,
output_is_found = TRUE;
}
assigned_crtc = meta_output_get_assigned_crtc (output);
if (!output_is_found)
return output->crtc != NULL;
return assigned_crtc != NULL;
for (i = 0; i < n_crtc_infos; i++)
{
@@ -279,7 +284,7 @@ is_output_assignment_changed (MetaOutput *output,
((MetaOutput**) crtc_info->outputs->pdata)[j];
if (crtc_info_output == output &&
crtc_info->crtc == output->crtc)
crtc_info->crtc == assigned_crtc)
return FALSE;
}
}
@@ -455,7 +460,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
output->is_dirty = TRUE;
output->crtc = crtc;
meta_output_assign_crtc (output, crtc);
output_ids[j] = output->winsys_id;
}
@@ -521,7 +526,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
continue;
}
output->crtc = NULL;
meta_output_unassign_crtc (output);
output->is_primary = FALSE;
}

View File

@@ -97,10 +97,13 @@ output_set_underscanning_xrandr (MetaOutput *output,
* make the border configurable. */
if (underscanning)
{
MetaCrtc *crtc;
uint32_t border_value;
crtc = meta_output_get_assigned_crtc (output);
prop = XInternAtom (xdisplay, "underscan hborder", False);
border_value = output->crtc->current_mode->width * 0.05;
border_value = crtc->current_mode->width * 0.05;
xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
(XID) output->winsys_id,
@@ -109,7 +112,7 @@ output_set_underscanning_xrandr (MetaOutput *output,
1, &border_value);
prop = XInternAtom (xdisplay, "underscan vborder", False);
border_value = output->crtc->current_mode->height * 0.05;
border_value = crtc->current_mode->height * 0.05;
xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
(XID) output->winsys_id,
@@ -737,14 +740,14 @@ output_get_crtcs (MetaOutput *output,
}
output->n_possible_crtcs = n_actual_crtcs;
output->crtc = NULL;
meta_output_unassign_crtc (output);
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
{
MetaCrtc *crtc = l->data;
if ((XID) crtc->crtc_id == xrandr_output->crtc)
{
output->crtc = crtc;
meta_output_assign_crtc (output, crtc);
break;
}
}

View File

@@ -113,7 +113,7 @@ draw_crtc (MetaMonitor *monitor,
CoglTexture *texture = data->texture;
MetaLogicalMonitor *logical_monitor = data->logical_monitor;
MetaOutput *output = monitor_crtc_mode->output;
MetaCrtc *crtc = output->crtc;
MetaCrtc *crtc;
MetaRendererView *renderer_view = META_RENDERER_VIEW (data->view);
MetaMonitorTransform view_transform;
MetaMonitorTransform layout_transform = META_MONITOR_TRANSFORM_NORMAL;
@@ -129,6 +129,8 @@ draw_crtc (MetaMonitor *monitor,
texture_width = cogl_texture_get_width (texture);
texture_height = cogl_texture_get_height (texture);
crtc = meta_output_get_assigned_crtc (output);
clutter_stage_view_get_layout (data->view, &view_layout);
sample_x = crtc->rect.x - view_layout.x;
sample_y = crtc->rect.y - view_layout.y;

View File

@@ -50,24 +50,22 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
{
MetaMonitor *main_monitor;
MetaOutput *main_output;
MetaMonitorTransform crtc_transform;
MetaCrtc *crtc;
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
main_output = meta_monitor_get_main_output (main_monitor);
crtc_transform =
meta_monitor_logical_to_crtc_transform (main_monitor,
logical_monitor->transform);
crtc = meta_output_get_assigned_crtc (main_output);
/*
* Pick any monitor and output and check; all CRTCs of a logical monitor will
* always have the same transform assigned to them.
*/
if (meta_monitor_manager_is_transform_handled (monitor_manager,
main_output->crtc,
crtc_transform))
crtc,
crtc->transform))
return META_MONITOR_TRANSFORM_NORMAL;
else
return crtc_transform;
return crtc->transform;
}
static MetaRendererView *

View File

@@ -58,5 +58,6 @@ void meta_window_actor_effect_completed (MetaWindowActor *actor,
MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self);
void meta_window_actor_update_surface (MetaWindowActor *self);
MetaWindowActor *meta_window_actor_from_window (MetaWindow *window);
#endif /* META_WINDOW_ACTOR_PRIVATE_H */

View File

@@ -142,6 +142,8 @@ struct _FrameData
enum
{
FIRST_FRAME,
EFFECTS_COMPLETED,
LAST_SIGNAL
};
@@ -238,6 +240,21 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
NULL, NULL, NULL,
G_TYPE_NONE, 0);
/**
* MetaWindowActor::effects-completed:
* @actor: the #MetaWindowActor instance
*
* The ::effects-completed signal will be emitted once all pending compositor
* effects are completed.
*/
signals[EFFECTS_COMPLETED] =
g_signal_new ("effects-completed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
pspec = g_param_spec_object ("meta-window",
"MetaWindow",
"The displayed MetaWindow",
@@ -1131,6 +1148,7 @@ meta_window_actor_after_effects (MetaWindowActor *self)
return;
}
g_signal_emit (self, signals[EFFECTS_COMPLETED], 0);
meta_window_actor_sync_visibility (self);
meta_window_actor_sync_actor_geometry (self, FALSE);
}
@@ -2157,3 +2175,9 @@ meta_window_actor_sync_updates_frozen (MetaWindowActor *self)
meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (window));
}
MetaWindowActor *
meta_window_actor_from_window (MetaWindow *window)
{
return META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
}

View File

@@ -886,7 +886,8 @@ constrain_modal_dialog (MetaWindow *window,
MetaRectangle child_rect, parent_rect;
gboolean constraint_already_satisfied;
if (!meta_window_is_attached_dialog (window) ||
if (!parent ||
!meta_window_is_attached_dialog (window) ||
meta_window_get_placement_rule (window))
return TRUE;

View File

@@ -209,7 +209,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
output->is_dirty = TRUE;
output->crtc = crtc;
meta_output_assign_crtc (output, crtc);
}
}
}
@@ -255,7 +255,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
continue;
}
output->crtc = NULL;
meta_output_unassign_crtc (output);
output->is_primary = FALSE;
}
}

View File

@@ -449,22 +449,24 @@ check_current_monitor_mode (MetaMonitor *monitor,
CheckMonitorModeData *data = user_data;
MetaMonitorManager *monitor_manager = data->monitor_manager;
MetaOutput *output;
MetaCrtc *crtc;
output = output_from_winsys_id (monitor_manager,
data->expect_crtc_mode_iter->output);
crtc = meta_output_get_assigned_crtc (output);
if (data->expect_crtc_mode_iter->crtc_mode == -1)
{
g_assert_null (output->crtc);
g_assert_null (crtc);
}
else
{
MetaLogicalMonitor *logical_monitor;
g_assert_nonnull (output->crtc);
g_assert (monitor_crtc_mode->crtc_mode == output->crtc->current_mode);
g_assert_nonnull (crtc);
g_assert (monitor_crtc_mode->crtc_mode == crtc->current_mode);
logical_monitor = output->crtc->logical_monitor;
logical_monitor = crtc->logical_monitor;
g_assert_nonnull (logical_monitor);
}
@@ -553,6 +555,7 @@ check_logical_monitor (MonitorTestCase *test_case,
for (l_output = outputs; l_output; l_output = l_output->next)
{
MetaOutput *output = l_output->data;
MetaCrtc *crtc;
if (output->is_primary)
{
@@ -560,8 +563,8 @@ check_logical_monitor (MonitorTestCase *test_case,
primary_output = output;
}
g_assert (!output->crtc ||
output->crtc->logical_monitor == logical_monitor);
crtc = meta_output_get_assigned_crtc (output);
g_assert (!crtc || crtc->logical_monitor == logical_monitor);
g_assert_cmpint (logical_monitor->is_presentation,
==,
output->is_presentation);
@@ -983,7 +986,8 @@ create_monitor_test_setup (MonitorTestCase *test_case,
output = g_object_new (META_TYPE_OUTPUT, NULL);
output->crtc = crtc;
if (crtc)
meta_output_assign_crtc (output, crtc);
output->winsys_id = i;
output->name = (is_laptop_panel ? g_strdup_printf ("eDP-%d",
++n_laptop_panels)

View File

@@ -71,6 +71,14 @@ static MetaFrameControl get_control (MetaUIFrame *frame,
G_DEFINE_TYPE (MetaFrames, meta_frames, GTK_TYPE_WINDOW);
enum {
META_ACTION_CLICK,
META_ACTION_RIGHT_CLICK,
META_ACTION_MIDDLE_CLICK,
META_ACTION_DOUBLE_CLICK,
META_ACTION_IGNORE
};
static GObject *
meta_frames_constructor (GType gtype,
guint n_properties,
@@ -742,17 +750,25 @@ redraw_control (MetaUIFrame *frame,
}
static gboolean
meta_frame_titlebar_event (MetaUIFrame *frame,
ClutterButtonEvent *event,
int action)
meta_frame_titlebar_event (MetaUIFrame *frame,
const ClutterEvent *event,
int action)
{
MetaFrameFlags flags;
Display *display;
uint32_t evtime;
float x, y;
g_assert (event->type == CLUTTER_BUTTON_PRESS ||
event->type == CLUTTER_TOUCH_BEGIN);
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
flags = meta_frame_get_flags (frame->meta_window->frame);
evtime = clutter_event_get_time (event);
clutter_event_get_coords (event, &x, &y);
switch (action)
{
case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_SHADE:
@@ -760,9 +776,9 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
if (flags & META_FRAME_ALLOWS_SHADE)
{
if (flags & META_FRAME_SHADED)
meta_window_unshade (frame->meta_window, event->time);
meta_window_unshade (frame->meta_window, evtime);
else
meta_window_shade (frame->meta_window, event->time);
meta_window_shade (frame->meta_window, evtime);
}
}
break;
@@ -808,16 +824,14 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
case G_DESKTOP_TITLEBAR_ACTION_LOWER:
meta_core_user_lower_and_unfocus (display,
frame->xwindow,
event->time);
evtime);
break;
case G_DESKTOP_TITLEBAR_ACTION_MENU:
meta_core_show_window_menu (display,
frame->xwindow,
META_WINDOW_MENU_WM,
event->x,
event->y,
event->time);
x, y, evtime);
break;
}
@@ -825,8 +839,8 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
}
static gboolean
meta_frame_double_click_event (MetaUIFrame *frame,
ClutterButtonEvent *event)
meta_frame_double_click_event (MetaUIFrame *frame,
const ClutterEvent *event)
{
int action = meta_prefs_get_action_double_click_titlebar ();
@@ -839,7 +853,8 @@ meta_frame_middle_click_event (MetaUIFrame *frame,
{
int action = meta_prefs_get_action_middle_click_titlebar();
return meta_frame_titlebar_event (frame, event, action);
return meta_frame_titlebar_event (frame, (const ClutterEvent *) event,
action);
}
static gboolean
@@ -848,7 +863,8 @@ meta_frame_right_click_event (MetaUIFrame *frame,
{
int action = meta_prefs_get_action_right_click_titlebar();
return meta_frame_titlebar_event (frame, event, action);
return meta_frame_titlebar_event (frame, (const ClutterEvent *) event,
action);
}
static gboolean
@@ -879,6 +895,8 @@ meta_frames_try_grab_op (MetaUIFrame *frame,
frames->grab_x = grab_x;
frames->grab_y = grab_y;
}
else
frames->grab_touch = NULL;
return ret;
}
@@ -889,6 +907,7 @@ meta_frames_retry_grab_op (MetaFrames *frames,
{
Display *display;
MetaGrabOp op;
gboolean ret;
if (frames->current_grab_op == META_GRAB_OP_NONE)
return TRUE;
@@ -897,16 +916,20 @@ meta_frames_retry_grab_op (MetaFrames *frames,
frames->current_grab_op = META_GRAB_OP_NONE;
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
return meta_core_begin_grab_op (display,
frames->grab_frame->xwindow,
op,
FALSE,
TRUE,
frames->grab_frame->grab_button,
0,
time,
frames->grab_x,
frames->grab_y);
ret = meta_core_begin_grab_op (display,
frames->grab_frame->xwindow,
op,
FALSE,
TRUE,
frames->grab_frame->grab_button,
0,
time,
frames->grab_x,
frames->grab_y);
if (ret)
frames->grab_touch = NULL;
return ret;
}
static MetaGrabOp
@@ -935,12 +958,65 @@ grab_op_from_resize_control (MetaFrameControl control)
}
}
static guint
get_action (const ClutterEvent *event)
{
if (event->type == CLUTTER_BUTTON_PRESS ||
event->type == CLUTTER_BUTTON_RELEASE)
{
switch (event->button.button)
{
case CLUTTER_BUTTON_PRIMARY:
if (clutter_event_get_click_count (event) == 2)
return META_ACTION_DOUBLE_CLICK;
else
return META_ACTION_CLICK;
case CLUTTER_BUTTON_SECONDARY:
return META_ACTION_RIGHT_CLICK;
case CLUTTER_BUTTON_MIDDLE:
return META_ACTION_MIDDLE_CLICK;
default:
meta_verbose ("No action triggered for button %u %s\n",
event->button.button,
(event->type == CLUTTER_BUTTON_PRESS) ? "press" : "release");
}
}
else if (event->type == CLUTTER_TOUCH_BEGIN ||
event->type == CLUTTER_TOUCH_UPDATE ||
event->type == CLUTTER_TOUCH_END)
{
return META_ACTION_CLICK;
}
return META_ACTION_IGNORE;
}
static uint32_t
get_button_number (const ClutterEvent *event)
{
if (event->type == CLUTTER_TOUCH_BEGIN ||
event->type == CLUTTER_TOUCH_UPDATE ||
event->type == CLUTTER_TOUCH_END)
return -1;
else if (event->type == CLUTTER_BUTTON_PRESS ||
event->type == CLUTTER_BUTTON_RELEASE)
return clutter_event_get_button (event);
g_assert_not_reached ();
}
static gboolean
meta_frame_left_click_event (MetaUIFrame *frame,
ClutterButtonEvent *event)
meta_frame_left_click_event (MetaUIFrame *frame,
const ClutterEvent *event)
{
Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
MetaFrameControl control = get_control (frame, event->x, event->y);
MetaFrameControl control;
guint32 evtime;
gfloat x, y;
evtime = clutter_event_get_time (event);
clutter_event_get_coords (event, &x, &y);
control = get_control (frame, x, y);
switch (control)
{
@@ -950,7 +1026,7 @@ meta_frame_left_click_event (MetaUIFrame *frame,
case META_FRAME_CONTROL_DELETE:
case META_FRAME_CONTROL_MENU:
case META_FRAME_CONTROL_APPMENU:
frame->grab_button = event->button;
frame->grab_button = get_button_number (event);
frame->button_state = META_BUTTON_STATE_PRESSED;
frame->prelit_control = control;
redraw_control (frame, control);
@@ -987,13 +1063,12 @@ meta_frame_left_click_event (MetaUIFrame *frame,
frame->xwindow,
menu,
&root_rect,
event->time);
evtime);
}
else
{
meta_frames_try_grab_op (frame, META_GRAB_OP_FRAME_BUTTON,
event->x, event->y,
event->time);
x, y, evtime);
}
return TRUE;
@@ -1007,8 +1082,7 @@ meta_frame_left_click_event (MetaUIFrame *frame,
case META_FRAME_CONTROL_RESIZE_W:
meta_frames_try_grab_op (frame,
grab_op_from_resize_control (control),
event->x, event->y,
event->time);
x, y, evtime);
return TRUE;
case META_FRAME_CONTROL_TITLE:
@@ -1019,8 +1093,7 @@ meta_frame_left_click_event (MetaUIFrame *frame,
{
meta_frames_try_grab_op (frame,
META_GRAB_OP_MOVING,
event->x, event->y,
event->time);
x, y, evtime);
}
}
@@ -1036,21 +1109,31 @@ meta_frame_left_click_event (MetaUIFrame *frame,
}
static gboolean
handle_button_press_event (MetaUIFrame *frame,
ClutterButtonEvent *event)
handle_press_event (MetaUIFrame *frame,
const ClutterEvent *event)
{
MetaFrameControl control;
Display *display;
uint32_t evtime, action;
float x, y;
g_assert (event->type == CLUTTER_BUTTON_PRESS ||
event->type == CLUTTER_TOUCH_BEGIN);
action = get_action (event);
if (action == META_ACTION_IGNORE)
return FALSE;
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
control = get_control (frame, event->x, event->y);
evtime = clutter_event_get_time (event);
clutter_event_get_coords (event, &x, &y);
control = get_control (frame, x, y);
/* don't do the rest of this if on client area */
if (control == META_FRAME_CONTROL_CLIENT_AREA)
return FALSE; /* not on the frame, just passed through from client */
if (event->button == 1 &&
if (action == META_ACTION_CLICK &&
!(control == META_FRAME_CONTROL_MINIMIZE ||
control == META_FRAME_CONTROL_DELETE ||
control == META_FRAME_CONTROL_MAXIMIZE))
@@ -1058,52 +1141,60 @@ handle_button_press_event (MetaUIFrame *frame,
meta_topic (META_DEBUG_FOCUS,
"Focusing window with frame 0x%lx due to button 1 press\n",
frame->xwindow);
meta_window_focus (frame->meta_window, event->time);
meta_window_focus (frame->meta_window, evtime);
}
/* We want to shade even if we have a GrabOp, since we'll have a move grab
* if we double click the titlebar.
*/
if (control == META_FRAME_CONTROL_TITLE &&
event->button == 1 &&
event->click_count == 2)
action == META_ACTION_DOUBLE_CLICK)
{
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, evtime);
return meta_frame_double_click_event (frame, event);
}
if (meta_core_get_grab_op (display) != META_GRAB_OP_NONE)
return FALSE; /* already up to something */
frame->grab_button = event->button;
frame->grab_button = get_button_number (event);
switch (event->button)
switch (action)
{
case 1:
case META_ACTION_CLICK:
return meta_frame_left_click_event (frame, event);
case 2:
return meta_frame_middle_click_event (frame, event);
case 3:
return meta_frame_right_click_event (frame, event);
case META_ACTION_MIDDLE_CLICK:
return meta_frame_middle_click_event (frame, (ClutterButtonEvent *) event);
case META_ACTION_RIGHT_CLICK:
return meta_frame_right_click_event (frame, (ClutterButtonEvent *) event);
default:
return FALSE;
}
}
static gboolean
handle_button_release_event (MetaUIFrame *frame,
ClutterButtonEvent *event)
handle_release_event (MetaUIFrame *frame,
const ClutterEvent *event)
{
Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
guint32 evtime, button;
gfloat x, y;
g_assert (event->type == CLUTTER_BUTTON_RELEASE ||
event->type == CLUTTER_TOUCH_END);
evtime = clutter_event_get_time (event);
clutter_event_get_coords (event, &x, &y);
button = get_button_number (event);
frame->frames->current_grab_op = META_GRAB_OP_NONE;
meta_core_end_grab_op (display, event->time);
meta_core_end_grab_op (display, evtime);
/* We only handle the releases we handled the presses for (things
* involving frame controls). Window ops that don't require a
* frame are handled in the Xlib part of the code, display.c/window.c
*/
if (((int) event->button) == frame->grab_button &&
if (((int) button) == frame->grab_button &&
frame->button_state == META_BUTTON_STATE_PRESSED)
{
switch (frame->prelit_control)
@@ -1113,7 +1204,7 @@ handle_button_release_event (MetaUIFrame *frame,
break;
case META_FRAME_CONTROL_MAXIMIZE:
/* Focus the window on the maximize */
meta_window_focus (frame->meta_window, event->time);
meta_window_focus (frame->meta_window, evtime);
if (meta_prefs_get_raise_on_click ())
meta_window_raise (frame->meta_window);
meta_window_maximize (frame->meta_window, META_MAXIMIZE_BOTH);
@@ -1124,7 +1215,7 @@ handle_button_release_event (MetaUIFrame *frame,
meta_window_unmaximize (frame->meta_window, META_MAXIMIZE_BOTH);
break;
case META_FRAME_CONTROL_DELETE:
meta_window_delete (frame->meta_window, event->time);
meta_window_delete (frame->meta_window, evtime);
break;
default:
break;
@@ -1135,7 +1226,7 @@ handle_button_release_event (MetaUIFrame *frame,
* prelit so to let the user know that it can now be pressed.
* :)
*/
MetaFrameControl control = get_control (frame, event->x, event->y);
MetaFrameControl control = get_control (frame, x, y);
meta_ui_frame_update_prelit_control (frame, control);
}
@@ -1236,13 +1327,22 @@ meta_ui_frame_update_prelit_control (MetaUIFrame *frame,
}
static gboolean
handle_motion_notify_event (MetaUIFrame *frame,
ClutterMotionEvent *event)
handle_motion_event (MetaUIFrame *frame,
const ClutterEvent *event)
{
MetaFrames *frames = frame->frames;
MetaFrameControl control;
ClutterModifierType modifiers;
guint32 evtime;
gfloat x, y;
control = get_control (frame, event->x, event->y);
g_assert (event->type == CLUTTER_MOTION ||
event->type == CLUTTER_TOUCH_UPDATE);
modifiers = clutter_event_get_state (event);
evtime = clutter_event_get_time (event);
clutter_event_get_coords (event, &x, &y);
control = get_control (frame, x, y);
if (frame->button_state == META_BUTTON_STATE_PRESSED)
{
@@ -1260,9 +1360,11 @@ handle_motion_notify_event (MetaUIFrame *frame,
meta_ui_frame_update_prelit_control (frame, control);
}
if ((event->modifier_state & CLUTTER_BUTTON1_MASK) &&
frames->current_grab_op != META_GRAB_OP_NONE)
meta_frames_retry_grab_op (frames, event->time);
if (frames->current_grab_op != META_GRAB_OP_NONE &&
(event->type == CLUTTER_TOUCH_UPDATE ||
(event->type == CLUTTER_MOTION &&
(modifiers & CLUTTER_BUTTON1_MASK))))
meta_frames_retry_grab_op (frames, evtime);
return TRUE;
}
@@ -1516,14 +1618,51 @@ gboolean
meta_ui_frame_handle_event (MetaUIFrame *frame,
const ClutterEvent *event)
{
if (event->type == CLUTTER_TOUCH_BEGIN ||
event->type == CLUTTER_TOUCH_UPDATE ||
event->type == CLUTTER_TOUCH_END)
{
ClutterEventSequence *sequence;
MetaFrames *frames = frame->frames;
/* In X11, mutter sets up passive touch grabs which basically
* means we handle those events twice (once through the passive
* grab, and then through XISelectEvents).
*
* Receiving touch events here means we are going through the
* former, but passive grabs are exclusively for gesture
* recognition purposes.
*
* We do actually want this to happen though the regular event
* selection paths to avoid breaking internal state, which means
* we will get pointer events, because we don't select for XI_Touch*.
*/
if (!meta_is_wayland_compositor ())
return FALSE;
sequence = clutter_event_get_event_sequence (event);
/* Lock onto a single touch */
if (frames->grab_touch && frames->grab_touch != sequence)
return FALSE;
if (event->type == CLUTTER_TOUCH_BEGIN)
frames->grab_touch = sequence;
else if (event->type == CLUTTER_TOUCH_END)
frames->grab_touch = NULL;
}
switch (event->any.type)
{
case CLUTTER_BUTTON_PRESS:
return handle_button_press_event (frame, (ClutterButtonEvent *) event);
case CLUTTER_TOUCH_BEGIN:
return handle_press_event (frame, event);
case CLUTTER_BUTTON_RELEASE:
return handle_button_release_event (frame, (ClutterButtonEvent *) event);
case CLUTTER_TOUCH_END:
return handle_release_event (frame, event);
case CLUTTER_MOTION:
return handle_motion_notify_event (frame, (ClutterMotionEvent *) event);
case CLUTTER_TOUCH_UPDATE:
return handle_motion_event (frame, event);
case CLUTTER_ENTER:
return handle_enter_notify_event (frame, (ClutterCrossingEvent *) event);
case CLUTTER_LEAVE:

View File

@@ -99,6 +99,8 @@ struct _MetaFrames
guint grab_button;
gdouble grab_x;
gdouble grab_y;
ClutterEventSequence *grab_touch;
};
struct _MetaFramesClass

View File

@@ -585,17 +585,6 @@ is_new_size_hints_valid (MetaWindow *window,
(new_max_height == 0 || new_min_height <= new_max_height));
}
static inline gboolean
did_geometry_change (MetaWaylandZxdgSurfaceV6 *xdg_surface,
MetaWaylandPendingState *pending)
{
MetaWaylandZxdgSurfaceV6Private *priv =
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
return pending->has_new_geometry &&
!meta_rectangle_equal (&priv->geometry, &pending->new_geometry);
}
static void
meta_wayland_zxdg_toplevel_v6_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandPendingState *pending)
@@ -611,11 +600,10 @@ meta_wayland_zxdg_toplevel_v6_commit (MetaWaylandSurfaceRole *surface_role,
meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window = surface->window;
MetaRectangle window_geometry;
MetaRectangle old_geometry;
gboolean geometry_changed;
/* This check must happen before chaining up, otherwise the new geometry
* is applied and it'll always return FALSE. */
geometry_changed = did_geometry_change (xdg_surface, pending);
old_geometry = xdg_surface_priv->geometry;
surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class);
@@ -634,6 +622,8 @@ meta_wayland_zxdg_toplevel_v6_commit (MetaWaylandSurfaceRole *surface_role,
if (!window)
return;
geometry_changed = !meta_rectangle_equal (&old_geometry, &xdg_surface_priv->geometry);
if (geometry_changed || meta_window_wayland_needs_move_resize (window))
{
window_geometry =

View File

@@ -195,14 +195,15 @@ cursor_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *role,
META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
ClutterRect rect;
ClutterPoint point;
ClutterRect logical_monitor_rect;
rect = meta_cursor_renderer_calculate_rect (priv->cursor_renderer,
priv->cursor_sprite);
logical_monitor_rect =
meta_rectangle_to_clutter_rect (&logical_monitor->rect);
return clutter_rect_intersection (&rect, &logical_monitor_rect, NULL);
point = meta_cursor_renderer_get_position (priv->cursor_renderer);
return clutter_rect_contains_point (&logical_monitor_rect, &point);
}
static void

View File

@@ -54,6 +54,7 @@
#include "compositor/region-utils.h"
#include "compositor/meta-shaped-texture-private.h"
#include "compositor/meta-window-actor-private.h"
#include "meta-surface-actor.h"
#include "meta-surface-actor-wayland.h"
@@ -142,6 +143,9 @@ surface_actor_position_notify (MetaSurfaceActorWayland *surface_actor,
static void
window_position_changed (MetaWindow *window,
MetaWaylandSurface *surface);
static void
window_actor_effects_completed (MetaWindowActor *window_actor,
MetaWaylandSurface *surface);
static void
role_assignment_valist_to_properties (GType role_type,
@@ -1138,6 +1142,9 @@ meta_wayland_surface_set_window (MetaWaylandSurface *surface,
g_signal_handlers_disconnect_by_func (surface->window,
window_position_changed,
surface);
g_signal_handlers_disconnect_by_func (meta_window_actor_from_window (surface->window),
window_actor_effects_completed,
surface);
}
surface->window = window;
@@ -1154,6 +1161,10 @@ meta_wayland_surface_set_window (MetaWaylandSurface *surface,
"position-changed",
G_CALLBACK (window_position_changed),
surface, 0);
g_signal_connect_object (meta_window_actor_from_window (window),
"effects-completed",
G_CALLBACK (window_actor_effects_completed),
surface, 0);
}
}
@@ -1255,6 +1266,13 @@ window_position_changed (MetaWindow *window,
meta_wayland_surface_update_outputs_recursively (surface);
}
static void
window_actor_effects_completed (MetaWindowActor *window_actor,
MetaWaylandSurface *surface)
{
meta_wayland_surface_update_outputs_recursively (surface);
}
void
meta_wayland_surface_create_surface_actor (MetaWaylandSurface *surface)
{

View File

@@ -120,8 +120,6 @@ meta_wayland_text_input_focus_commit_text (ClutterInputFocus *focus,
gtk_text_input_send_preedit_string (resource, NULL, 0);
gtk_text_input_send_commit_string (resource, text);
}
clutter_input_focus_reset (focus);
}
static void

View File

@@ -608,17 +608,6 @@ is_new_size_hints_valid (MetaWindow *window,
(new_max_height == 0 || new_min_height <= new_max_height));
}
static inline gboolean
did_geometry_change (MetaWaylandXdgSurface *xdg_surface,
MetaWaylandPendingState *pending)
{
MetaWaylandXdgSurfacePrivate *priv =
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
return pending->has_new_geometry &&
!meta_rectangle_equal (&priv->geometry, &pending->new_geometry);
}
static void
meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandPendingState *pending)
@@ -632,6 +621,7 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window;
MetaRectangle window_geometry;
MetaRectangle old_geometry;
gboolean geometry_changed;
if (!surface->buffer_ref.buffer && xdg_surface_priv->first_buffer_attached)
@@ -641,10 +631,7 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
}
window = surface->window;
/* This check must happen before chaining up, otherwise the new geometry
* is applied and it'll always return FALSE. */
geometry_changed = did_geometry_change (xdg_surface, pending);
old_geometry = xdg_surface_priv->geometry;
surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class);
@@ -659,6 +646,8 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
if (!pending->newly_attached)
return;
geometry_changed = !meta_rectangle_equal (&old_geometry, &xdg_surface_priv->geometry);
if (geometry_changed || meta_window_wayland_needs_move_resize (window))
{
window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface);