Compare commits
174 Commits
citadel
...
gnome-3-28
Author | SHA1 | Date | |
---|---|---|---|
![]() |
079a625eaa | ||
![]() |
f3420b0341 | ||
![]() |
dde0906639 | ||
![]() |
a611dadc0b | ||
![]() |
88e855bf0a | ||
![]() |
f205dabc5e | ||
![]() |
74e3126b77 | ||
![]() |
4f36e82f68 | ||
![]() |
b7bc8e56b7 | ||
![]() |
d3f75f31c8 | ||
![]() |
0ca9d88926 | ||
![]() |
0276630671 | ||
![]() |
7d54c5621c | ||
![]() |
7951ddab40 | ||
![]() |
a6df771747 | ||
![]() |
90d8fef5f5 | ||
![]() |
b462e519e8 | ||
![]() |
0060ddc5bf | ||
![]() |
8dd564adff | ||
![]() |
556d36baa8 | ||
![]() |
1dd0799c77 | ||
![]() |
1ebf32187a | ||
![]() |
ac1503a559 | ||
![]() |
93f268a4a8 | ||
![]() |
68691cb1b9 | ||
![]() |
8d936a410c | ||
![]() |
fc74c7def9 | ||
![]() |
9b8a3fbaed | ||
![]() |
e356424282 | ||
![]() |
b838fe8f05 | ||
![]() |
2e64457f4c | ||
![]() |
9b289728e3 | ||
![]() |
6198d389b5 | ||
![]() |
24b4c82ae2 | ||
![]() |
4af8d9d475 | ||
![]() |
0f9eb6566f | ||
![]() |
56a4f33da0 | ||
![]() |
0be812161e | ||
![]() |
b63bbda431 | ||
![]() |
6603925f72 | ||
![]() |
fe4c3aa6b5 | ||
![]() |
d9cc8530ec | ||
![]() |
1b78ca8c5e | ||
![]() |
6a6d477d71 | ||
![]() |
721de281a3 | ||
![]() |
00cd99c3a7 | ||
![]() |
8ddbe9d98b | ||
![]() |
a22cb8832d | ||
![]() |
082efaca96 | ||
![]() |
80f942773a | ||
![]() |
b5c2555601 | ||
![]() |
0a85e6272e | ||
![]() |
4dfe4256ae | ||
![]() |
998e3279c2 | ||
![]() |
1514880e92 | ||
![]() |
6ed36cd6e3 | ||
![]() |
49c06fd9b1 | ||
![]() |
f7658ac5f0 | ||
![]() |
037d9915d5 | ||
![]() |
075bfc4e11 | ||
![]() |
02e80af200 | ||
![]() |
398f03bd0f | ||
![]() |
d81dcd13e4 | ||
![]() |
5d0365991f | ||
![]() |
03dfcbab67 | ||
![]() |
47505dc5f6 | ||
![]() |
9d88fc8cb7 | ||
![]() |
17ae09ad3f | ||
![]() |
4ca83f3c47 | ||
![]() |
b44f93ee9b | ||
![]() |
59d2d5ef3b | ||
![]() |
53b040be5c | ||
![]() |
c647bd7807 | ||
![]() |
9ac07b4005 | ||
![]() |
527f6ef835 | ||
![]() |
0b666dbeb2 | ||
![]() |
24b87b364d | ||
![]() |
15f01174ff | ||
![]() |
f45af3315d | ||
![]() |
007864ac64 | ||
![]() |
f76cacd154 | ||
![]() |
abe682efa0 | ||
![]() |
83b7b17b64 | ||
![]() |
30266605b5 | ||
![]() |
2e0d758811 | ||
![]() |
aa6d1614c0 | ||
![]() |
255146e4a3 | ||
![]() |
2ad5a39bd0 | ||
![]() |
ce3278b4b7 | ||
![]() |
0d134522d8 | ||
![]() |
f4a7620dff | ||
![]() |
a41ae88c09 | ||
![]() |
1276cc97d1 | ||
![]() |
5b9f5329bd | ||
![]() |
d0d8078013 | ||
![]() |
0a09a3c906 | ||
![]() |
137f22236c | ||
![]() |
513cc535f3 | ||
![]() |
d74a046060 | ||
![]() |
0c5e61a2ab | ||
![]() |
44682a2cc5 | ||
![]() |
62660bbd15 | ||
![]() |
34f5bdeea3 | ||
![]() |
ca71b0eb1a | ||
![]() |
ca4209d88a | ||
![]() |
3288edf677 | ||
![]() |
fe1616668e | ||
![]() |
7d01aec48d | ||
![]() |
a41d84db00 | ||
![]() |
e73b321c2e | ||
![]() |
b6dc2052c3 | ||
![]() |
72965aaaf0 | ||
![]() |
2a6782dc10 | ||
![]() |
5142c8c7e7 | ||
![]() |
abc7ad8e9f | ||
![]() |
1a3f9a3323 | ||
![]() |
235c35182b | ||
![]() |
e4661d7870 | ||
![]() |
9d4c7e4e75 | ||
![]() |
47131b1dad | ||
![]() |
51c0130645 | ||
![]() |
2dd9fc17c1 | ||
![]() |
c7a38c3139 | ||
![]() |
7d52be0229 | ||
![]() |
41303bc01b | ||
![]() |
0d188c3898 | ||
![]() |
28eff93143 | ||
![]() |
b380aa72aa | ||
![]() |
920dc9e5a1 | ||
![]() |
32f02010ae | ||
![]() |
889c56c776 | ||
![]() |
67a4cd898e | ||
![]() |
43d6c0ea61 | ||
![]() |
2872bb1f2a | ||
![]() |
1c00cd5ca3 | ||
![]() |
2919a7f25f | ||
![]() |
ca0d56a3a4 | ||
![]() |
a89baa44ab | ||
![]() |
7076a48bcf | ||
![]() |
1b439c42d1 | ||
![]() |
928a40f328 | ||
![]() |
59397266ed | ||
![]() |
d0147591b3 | ||
![]() |
25c7e52ada | ||
![]() |
99d766c044 | ||
![]() |
fcd4c816c4 | ||
![]() |
2a63a47d5a | ||
![]() |
c80e2c9ae5 | ||
![]() |
d3d5eb8e1b | ||
![]() |
4837cec89f | ||
![]() |
32329e6c00 | ||
![]() |
89261be556 | ||
![]() |
e3e76d658b | ||
![]() |
34644b2133 | ||
![]() |
7da4e8cf14 | ||
![]() |
23c3f8bb18 | ||
![]() |
60866e0f85 | ||
![]() |
45c02645f3 | ||
![]() |
e515e37a7e | ||
![]() |
957f4ec69d | ||
![]() |
a98eb107be | ||
![]() |
1851fa2bd0 | ||
![]() |
de7d7bbf3d | ||
![]() |
7ac551cd05 | ||
![]() |
8696a79477 | ||
![]() |
b2f9de98d0 | ||
![]() |
2da2489da5 | ||
![]() |
31779404f0 | ||
![]() |
b096c0ac33 | ||
![]() |
44a7f74dcd | ||
![]() |
3832c6b607 | ||
![]() |
14b7e79d3c | ||
![]() |
e99b0b9368 | ||
![]() |
de294f34bb |
72
NEWS
72
NEWS
@ -1,3 +1,75 @@
|
|||||||
|
3.28.4
|
||||||
|
======
|
||||||
|
* Don't expose resolutions that are below the minimum [Andrea; #793223]
|
||||||
|
* Fix lock up with some DRI drivers [Alex; #127]
|
||||||
|
* Improve grab-device clock updates on X11 [Jeff; !174]
|
||||||
|
* Prevent clients from modifying the shared keymap [Jonas; #784206]
|
||||||
|
* Fix screen rotation regression [Jonas; #216]
|
||||||
|
* Fix non-lowercase letters on virtual key devices [Carlos; gnome-shell#135]
|
||||||
|
* Send correct button codes from virtual evdev devices [Jonas; !190]
|
||||||
|
* Avoid crash when a cursor is not found [Sebastian; #254]
|
||||||
|
* Improve EGLstream support [Miguel; #2, #782575]
|
||||||
|
* Handle requests to unmanaged windows gracefully [Jonas; #240]
|
||||||
|
* Improve support for proprietary Nvidia driver [Jonas; #790316]
|
||||||
|
* Fix handling of non-UTF8 encodings [Florian; !227]
|
||||||
|
* Consider remapped keys when guessing keycode from keysym [Andrea; #443]
|
||||||
|
* Fix support of extended characters in on-screen keyboard [Andrea; #109]
|
||||||
|
* Various crash fixes [Jonas, Olivier, Florian, Marco; #70, #189, #15,
|
||||||
|
#130, #255, #194, #336, #576]
|
||||||
|
* Misc. bug fixes [Iain, Jonas, Sam, Carlos, Florian, Olivier, Marco; #223,
|
||||||
|
#192, #788834, #782344, !130, #134, #221, #306, #279, #331, !557]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Jonas Ådahl, Andrea Azzarone, Olivier Fourdan, Carlos Garnacho,
|
||||||
|
Sebastian Keller, Iain Lane, Alex Villacís Lasso, Florian Müllner,
|
||||||
|
Bastien Nocera, Aaron Plattner, Jeff Smith, Sam Spilsbury,
|
||||||
|
Marco Trevisan (Treviño), Miguel A. Vico, Daniel van Vugt
|
||||||
|
|
||||||
|
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]
|
||||||
|
* Fix window animations on wayland [Georges; #780292]
|
||||||
|
* Misc. bug fixes [Mario, Jonas, Olivier, Florian; gnome-shell#157, #130,
|
||||||
|
#21, #124, !96, #138, !102, #781471]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Florian Müllner,
|
||||||
|
Georges Basile Stavracas Neto, Bastien Nocera, Mario Sanchez Prada,
|
||||||
|
Ray Strode, Marco Trevisan (Treviño)
|
||||||
|
|
||||||
|
3.28.1
|
||||||
|
======
|
||||||
|
* Fix various input-method regressions [Carlos; #65, #74, #66]
|
||||||
|
* Fix wayland build on FreeBSD [Ting-Wei; #792280, #792717]
|
||||||
|
* Fix swapped colors in screenshots (again) [Carlos; #72]
|
||||||
|
* Allow building with elogind [Rasmus; !46]
|
||||||
|
* Consider display rotation for cursor [Olivier; #85]
|
||||||
|
* Fall back to non-modifier GBM surfaces [Daniel; #84]
|
||||||
|
* Disable KMS modifiers by default [Jonas; #81]
|
||||||
|
* Misc bug fixes [handsome-feng; !45]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, handsome-feng, Yussuf Khalil,
|
||||||
|
Ting-Wei Lan, Aleksandr Mezin, Alberts Muktupāvels,
|
||||||
|
Georges Basile Stavracas Neto, Benjamin Otte, Daniel Stone, Rasmus Thomsen,
|
||||||
|
Marco Trevisan (Treviño), Daniel van Vugt
|
||||||
|
|
||||||
|
Translators:
|
||||||
|
Emin Tufan Çetin [tr], Dušan Kazik [sk], Matej Urbančič [sl]
|
||||||
|
|
||||||
3.28.0
|
3.28.0
|
||||||
======
|
======
|
||||||
* Fix xdg-foreign regression [Carlos; #63]
|
* Fix xdg-foreign regression [Carlos; #63]
|
||||||
|
@ -692,7 +692,7 @@ Cally_@LIBMUTTER_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS)
|
|||||||
Cally_@LIBMUTTER_API_VERSION@_gir_SCANNERFLAGS = \
|
Cally_@LIBMUTTER_API_VERSION@_gir_SCANNERFLAGS = \
|
||||||
--warn-all \
|
--warn-all \
|
||||||
--c-include='cally/cally.h' \
|
--c-include='cally/cally.h' \
|
||||||
--pkg-export=mutter-cally-@LIBMUTTER_API_VERSION@ \
|
--pkg-export=mutter-clutter-@LIBMUTTER_API_VERSION@ \
|
||||||
--include-uninstalled=$(top_builddir)/clutter/Clutter-@LIBMUTTER_API_VERSION@.gir
|
--include-uninstalled=$(top_builddir)/clutter/Clutter-@LIBMUTTER_API_VERSION@.gir
|
||||||
|
|
||||||
INTROSPECTION_GIRS += Cally-@LIBMUTTER_API_VERSION@.gir
|
INTROSPECTION_GIRS += Cally-@LIBMUTTER_API_VERSION@.gir
|
||||||
|
@ -214,6 +214,8 @@ cally_util_simulate_snooper_install (void)
|
|||||||
G_CALLBACK (cally_util_stage_added_cb), cally_key_snooper);
|
G_CALLBACK (cally_util_stage_added_cb), cally_key_snooper);
|
||||||
g_signal_connect (G_OBJECT (stage_manager), "stage-removed",
|
g_signal_connect (G_OBJECT (stage_manager), "stage-removed",
|
||||||
G_CALLBACK (cally_util_stage_removed_cb), cally_key_snooper);
|
G_CALLBACK (cally_util_stage_removed_cb), cally_key_snooper);
|
||||||
|
|
||||||
|
g_slist_free (stage_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -840,6 +840,8 @@ struct _ClutterActorPrivate
|
|||||||
guint needs_compute_expand : 1;
|
guint needs_compute_expand : 1;
|
||||||
guint needs_x_expand : 1;
|
guint needs_x_expand : 1;
|
||||||
guint needs_y_expand : 1;
|
guint needs_y_expand : 1;
|
||||||
|
guint needs_paint_volume_update : 1;
|
||||||
|
guint had_effects_on_last_paint_volume_update : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -1092,6 +1094,11 @@ static void clutter_actor_set_child_transform_internal (ClutterActor *sel
|
|||||||
static void clutter_actor_realize_internal (ClutterActor *self);
|
static void clutter_actor_realize_internal (ClutterActor *self);
|
||||||
static void clutter_actor_unrealize_internal (ClutterActor *self);
|
static void clutter_actor_unrealize_internal (ClutterActor *self);
|
||||||
|
|
||||||
|
static void clutter_actor_push_in_cloned_branch (ClutterActor *self,
|
||||||
|
gulong count);
|
||||||
|
static void clutter_actor_pop_in_cloned_branch (ClutterActor *self,
|
||||||
|
gulong count);
|
||||||
|
|
||||||
/* Helper macro which translates by the anchor coord, applies the
|
/* Helper macro which translates by the anchor coord, applies the
|
||||||
given transformation and then translates back */
|
given transformation and then translates back */
|
||||||
#define TRANSFORM_ABOUT_ANCHOR_COORD(a,m,c,_transform) G_STMT_START { \
|
#define TRANSFORM_ABOUT_ANCHOR_COORD(a,m,c,_transform) G_STMT_START { \
|
||||||
@ -1504,6 +1511,8 @@ clutter_actor_real_map (ClutterActor *self)
|
|||||||
|
|
||||||
CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_MAPPED);
|
CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_MAPPED);
|
||||||
|
|
||||||
|
self->priv->needs_paint_volume_update = TRUE;
|
||||||
|
|
||||||
stage = _clutter_actor_get_stage_internal (self);
|
stage = _clutter_actor_get_stage_internal (self);
|
||||||
priv->pick_id = _clutter_stage_acquire_pick_id (CLUTTER_STAGE (stage), self);
|
priv->pick_id = _clutter_stage_acquire_pick_id (CLUTTER_STAGE (stage), self);
|
||||||
|
|
||||||
@ -2737,6 +2746,7 @@ clutter_actor_real_queue_relayout (ClutterActor *self)
|
|||||||
priv->needs_width_request = TRUE;
|
priv->needs_width_request = TRUE;
|
||||||
priv->needs_height_request = TRUE;
|
priv->needs_height_request = TRUE;
|
||||||
priv->needs_allocation = TRUE;
|
priv->needs_allocation = TRUE;
|
||||||
|
priv->needs_paint_volume_update = TRUE;
|
||||||
|
|
||||||
/* reset the cached size requests */
|
/* reset the cached size requests */
|
||||||
memset (priv->width_requests, 0,
|
memset (priv->width_requests, 0,
|
||||||
@ -2821,7 +2831,7 @@ _clutter_actor_fully_transform_vertices (ClutterActor *self,
|
|||||||
/* Note: we pass NULL as the ancestor because we don't just want the modelview
|
/* Note: we pass NULL as the ancestor because we don't just want the modelview
|
||||||
* that gets us to stage coordinates, we want to go all the way to eye
|
* that gets us to stage coordinates, we want to go all the way to eye
|
||||||
* coordinates */
|
* coordinates */
|
||||||
_clutter_actor_apply_relative_transformation_matrix (self, NULL, &modelview);
|
_clutter_actor_get_relative_transformation_matrix (self, NULL, &modelview);
|
||||||
|
|
||||||
/* Fetch the projection and viewport */
|
/* Fetch the projection and viewport */
|
||||||
_clutter_stage_get_projection_matrix (CLUTTER_STAGE (stage), &projection);
|
_clutter_stage_get_projection_matrix (CLUTTER_STAGE (stage), &projection);
|
||||||
@ -4285,6 +4295,9 @@ clutter_actor_remove_child_internal (ClutterActor *self,
|
|||||||
|
|
||||||
self->priv->age += 1;
|
self->priv->age += 1;
|
||||||
|
|
||||||
|
if (self->priv->in_cloned_branch)
|
||||||
|
clutter_actor_pop_in_cloned_branch (child, self->priv->in_cloned_branch);
|
||||||
|
|
||||||
/* if the child that got removed was visible and set to
|
/* if the child that got removed was visible and set to
|
||||||
* expand then we want to reset the parent's state in
|
* expand then we want to reset the parent's state in
|
||||||
* case the child was the only thing that was making it
|
* case the child was the only thing that was making it
|
||||||
@ -8518,6 +8531,7 @@ clutter_actor_init (ClutterActor *self)
|
|||||||
priv->needs_width_request = TRUE;
|
priv->needs_width_request = TRUE;
|
||||||
priv->needs_height_request = TRUE;
|
priv->needs_height_request = TRUE;
|
||||||
priv->needs_allocation = TRUE;
|
priv->needs_allocation = TRUE;
|
||||||
|
priv->needs_paint_volume_update = TRUE;
|
||||||
|
|
||||||
priv->cached_width_age = 1;
|
priv->cached_width_age = 1;
|
||||||
priv->cached_height_age = 1;
|
priv->cached_height_age = 1;
|
||||||
@ -10084,6 +10098,9 @@ clutter_actor_allocate (ClutterActor *self,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CLUTTER_ACTOR_IS_MAPPED (self))
|
||||||
|
self->priv->needs_paint_volume_update = TRUE;
|
||||||
|
|
||||||
if (!stage_allocation_changed)
|
if (!stage_allocation_changed)
|
||||||
{
|
{
|
||||||
/* If the actor didn't move but needs_allocation is set, we just
|
/* If the actor didn't move but needs_allocation is set, we just
|
||||||
@ -12902,6 +12919,9 @@ clutter_actor_add_child_internal (ClutterActor *self,
|
|||||||
|
|
||||||
self->priv->age += 1;
|
self->priv->age += 1;
|
||||||
|
|
||||||
|
if (self->priv->in_cloned_branch)
|
||||||
|
clutter_actor_push_in_cloned_branch (child, self->priv->in_cloned_branch);
|
||||||
|
|
||||||
/* if push_internal() has been called then we automatically set
|
/* if push_internal() has been called then we automatically set
|
||||||
* the flag on the actor
|
* the flag on the actor
|
||||||
*/
|
*/
|
||||||
@ -12972,6 +12992,9 @@ clutter_actor_add_child_internal (ClutterActor *self,
|
|||||||
child->priv->needs_height_request = TRUE;
|
child->priv->needs_height_request = TRUE;
|
||||||
child->priv->needs_allocation = TRUE;
|
child->priv->needs_allocation = TRUE;
|
||||||
|
|
||||||
|
if (CLUTTER_ACTOR_IS_MAPPED (child))
|
||||||
|
child->priv->needs_paint_volume_update = TRUE;
|
||||||
|
|
||||||
/* we only queue a relayout here, because any possible
|
/* we only queue a relayout here, because any possible
|
||||||
* redraw has already been queued either by show() or
|
* redraw has already been queued either by show() or
|
||||||
* by our call to queue_redraw() above
|
* by our call to queue_redraw() above
|
||||||
@ -17463,7 +17486,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
|
|||||||
*/
|
*/
|
||||||
effects = _clutter_meta_group_peek_metas (priv->effects);
|
effects = _clutter_meta_group_peek_metas (priv->effects);
|
||||||
for (l = effects;
|
for (l = effects;
|
||||||
l != NULL || (l != NULL && l->data != priv->current_effect);
|
l != NULL && l->data != priv->current_effect;
|
||||||
l = l->next)
|
l = l->next)
|
||||||
{
|
{
|
||||||
if (!_clutter_effect_get_paint_volume (l->data, pv))
|
if (!_clutter_effect_get_paint_volume (l->data, pv))
|
||||||
@ -17499,6 +17522,32 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_clutter_actor_has_active_paint_volume_override_effects (ClutterActor *self)
|
||||||
|
{
|
||||||
|
const GList *l;
|
||||||
|
|
||||||
|
if (self->priv->effects == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* We just need to all effects current effect to see
|
||||||
|
* if anyone wants to override the paint volume. If so, then
|
||||||
|
* we need to recompute, since the paint volume returned can
|
||||||
|
* change from call to call. */
|
||||||
|
for (l = _clutter_meta_group_peek_metas (self->priv->effects);
|
||||||
|
l != NULL;
|
||||||
|
l = l->next)
|
||||||
|
{
|
||||||
|
ClutterEffect *effect = l->data;
|
||||||
|
|
||||||
|
if (clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)) &&
|
||||||
|
_clutter_effect_has_custom_paint_volume (effect))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* The public clutter_actor_get_paint_volume API returns a const
|
/* The public clutter_actor_get_paint_volume API returns a const
|
||||||
* pointer since we return a pointer directly to the cached
|
* pointer since we return a pointer directly to the cached
|
||||||
* PaintVolume associated with the actor and don't want the user to
|
* PaintVolume associated with the actor and don't want the user to
|
||||||
@ -17509,16 +17558,37 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
|
|||||||
static ClutterPaintVolume *
|
static ClutterPaintVolume *
|
||||||
_clutter_actor_get_paint_volume_mutable (ClutterActor *self)
|
_clutter_actor_get_paint_volume_mutable (ClutterActor *self)
|
||||||
{
|
{
|
||||||
|
gboolean has_paint_volume_override_effects;
|
||||||
ClutterActorPrivate *priv;
|
ClutterActorPrivate *priv;
|
||||||
|
|
||||||
priv = self->priv;
|
priv = self->priv;
|
||||||
|
|
||||||
|
has_paint_volume_override_effects = _clutter_actor_has_active_paint_volume_override_effects (self);
|
||||||
|
|
||||||
if (priv->paint_volume_valid)
|
if (priv->paint_volume_valid)
|
||||||
|
{
|
||||||
|
/* If effects are applied, the actor paint volume
|
||||||
|
* needs to be recomputed on each paint, since those
|
||||||
|
* paint volumes could change over the duration of the
|
||||||
|
* effect.
|
||||||
|
*
|
||||||
|
* We also need to update the paint volume if we went
|
||||||
|
* from having effects to not having effects on the last
|
||||||
|
* paint volume update. */
|
||||||
|
if (!priv->needs_paint_volume_update &&
|
||||||
|
priv->current_effect == NULL &&
|
||||||
|
!has_paint_volume_override_effects &&
|
||||||
|
!priv->had_effects_on_last_paint_volume_update)
|
||||||
|
return &priv->paint_volume;
|
||||||
clutter_paint_volume_free (&priv->paint_volume);
|
clutter_paint_volume_free (&priv->paint_volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->had_effects_on_last_paint_volume_update = has_paint_volume_override_effects;
|
||||||
|
|
||||||
if (_clutter_actor_get_paint_volume_real (self, &priv->paint_volume))
|
if (_clutter_actor_get_paint_volume_real (self, &priv->paint_volume))
|
||||||
{
|
{
|
||||||
priv->paint_volume_valid = TRUE;
|
priv->paint_volume_valid = TRUE;
|
||||||
|
priv->needs_paint_volume_update = FALSE;
|
||||||
return &priv->paint_volume;
|
return &priv->paint_volume;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -20688,29 +20758,31 @@ clutter_actor_get_child_transform (ClutterActor *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_actor_push_in_cloned_branch (ClutterActor *self)
|
clutter_actor_push_in_cloned_branch (ClutterActor *self,
|
||||||
|
gulong count)
|
||||||
{
|
{
|
||||||
ClutterActor *iter;
|
ClutterActor *iter;
|
||||||
|
|
||||||
for (iter = self->priv->first_child;
|
for (iter = self->priv->first_child;
|
||||||
iter != NULL;
|
iter != NULL;
|
||||||
iter = iter->priv->next_sibling)
|
iter = iter->priv->next_sibling)
|
||||||
clutter_actor_push_in_cloned_branch (iter);
|
clutter_actor_push_in_cloned_branch (iter, count);
|
||||||
|
|
||||||
self->priv->in_cloned_branch += 1;
|
self->priv->in_cloned_branch += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_actor_pop_in_cloned_branch (ClutterActor *self)
|
clutter_actor_pop_in_cloned_branch (ClutterActor *self,
|
||||||
|
gulong count)
|
||||||
{
|
{
|
||||||
ClutterActor *iter;
|
ClutterActor *iter;
|
||||||
|
|
||||||
self->priv->in_cloned_branch -= 1;
|
self->priv->in_cloned_branch -= count;
|
||||||
|
|
||||||
for (iter = self->priv->first_child;
|
for (iter = self->priv->first_child;
|
||||||
iter != NULL;
|
iter != NULL;
|
||||||
iter = iter->priv->next_sibling)
|
iter = iter->priv->next_sibling)
|
||||||
clutter_actor_pop_in_cloned_branch (iter);
|
clutter_actor_pop_in_cloned_branch (iter, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -20726,7 +20798,7 @@ _clutter_actor_attach_clone (ClutterActor *actor,
|
|||||||
|
|
||||||
g_hash_table_add (priv->clones, clone);
|
g_hash_table_add (priv->clones, clone);
|
||||||
|
|
||||||
clutter_actor_push_in_cloned_branch (actor);
|
clutter_actor_push_in_cloned_branch (actor, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -20741,7 +20813,7 @@ _clutter_actor_detach_clone (ClutterActor *actor,
|
|||||||
g_hash_table_lookup (priv->clones, clone) == NULL)
|
g_hash_table_lookup (priv->clones, clone) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clutter_actor_pop_in_cloned_branch (actor);
|
clutter_actor_pop_in_cloned_branch (actor, 1);
|
||||||
|
|
||||||
g_hash_table_remove (priv->clones, clone);
|
g_hash_table_remove (priv->clones, clone);
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ gboolean _clutter_effect_pre_paint (ClutterEffect
|
|||||||
void _clutter_effect_post_paint (ClutterEffect *effect);
|
void _clutter_effect_post_paint (ClutterEffect *effect);
|
||||||
gboolean _clutter_effect_get_paint_volume (ClutterEffect *effect,
|
gboolean _clutter_effect_get_paint_volume (ClutterEffect *effect,
|
||||||
ClutterPaintVolume *volume);
|
ClutterPaintVolume *volume);
|
||||||
|
gboolean _clutter_effect_has_custom_paint_volume (ClutterEffect *effect);
|
||||||
void _clutter_effect_paint (ClutterEffect *effect,
|
void _clutter_effect_paint (ClutterEffect *effect,
|
||||||
ClutterEffectPaintFlags flags);
|
ClutterEffectPaintFlags flags);
|
||||||
void _clutter_effect_pick (ClutterEffect *effect,
|
void _clutter_effect_pick (ClutterEffect *effect,
|
||||||
|
@ -308,6 +308,14 @@ _clutter_effect_get_paint_volume (ClutterEffect *effect,
|
|||||||
return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume (effect, volume);
|
return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume (effect, volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_clutter_effect_has_custom_paint_volume (ClutterEffect *effect)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
|
||||||
|
|
||||||
|
return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume != clutter_effect_real_get_paint_volume;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_effect_queue_repaint:
|
* clutter_effect_queue_repaint:
|
||||||
* @effect: A #ClutterEffect which needs redrawing
|
* @effect: A #ClutterEffect which needs redrawing
|
||||||
|
@ -353,6 +353,7 @@ clutter_input_method_notify_key_event (ClutterInputMethod *im,
|
|||||||
copy = clutter_event_copy (event);
|
copy = clutter_event_copy (event);
|
||||||
clutter_event_set_flags (copy, clutter_event_get_flags (event) |
|
clutter_event_set_flags (copy, clutter_event_get_flags (event) |
|
||||||
CLUTTER_EVENT_FLAG_INPUT_METHOD);
|
CLUTTER_EVENT_FLAG_INPUT_METHOD);
|
||||||
|
clutter_event_set_source_device (copy, clutter_event_get_device (copy));
|
||||||
clutter_event_put (copy);
|
clutter_event_put (copy);
|
||||||
clutter_event_free (copy);
|
clutter_event_free (copy);
|
||||||
}
|
}
|
||||||
|
@ -186,6 +186,12 @@ update_fbo (ClutterEffect *effect, int fbo_width, int fbo_height)
|
|||||||
priv->texture = NULL;
|
priv->texture = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->offscreen != NULL)
|
||||||
|
{
|
||||||
|
cogl_handle_unref (priv->offscreen);
|
||||||
|
priv->offscreen = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
priv->texture =
|
priv->texture =
|
||||||
clutter_offscreen_effect_create_texture (self, fbo_width, fbo_height);
|
clutter_offscreen_effect_create_texture (self, fbo_width, fbo_height);
|
||||||
if (priv->texture == NULL)
|
if (priv->texture == NULL)
|
||||||
@ -196,9 +202,6 @@ update_fbo (ClutterEffect *effect, int fbo_width, int fbo_height)
|
|||||||
priv->fbo_width = fbo_width;
|
priv->fbo_width = fbo_width;
|
||||||
priv->fbo_height = fbo_height;
|
priv->fbo_height = fbo_height;
|
||||||
|
|
||||||
if (priv->offscreen != NULL)
|
|
||||||
cogl_handle_unref (priv->offscreen);
|
|
||||||
|
|
||||||
priv->offscreen = cogl_offscreen_new_to_texture (priv->texture);
|
priv->offscreen = cogl_offscreen_new_to_texture (priv->texture);
|
||||||
if (priv->offscreen == NULL)
|
if (priv->offscreen == NULL)
|
||||||
{
|
{
|
||||||
|
@ -1166,6 +1166,21 @@ _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv,
|
|||||||
|
|
||||||
_clutter_paint_volume_get_bounding_box (&projected_pv, box);
|
_clutter_paint_volume_get_bounding_box (&projected_pv, box);
|
||||||
|
|
||||||
|
if (pv->is_2d && pv->actor &&
|
||||||
|
clutter_actor_get_z_position (pv->actor) == 0)
|
||||||
|
{
|
||||||
|
/* If the volume/actor are perfectly 2D, take the bounding box as
|
||||||
|
* good. We won't need to add any extra room for sub-pixel positioning
|
||||||
|
* in this case.
|
||||||
|
*/
|
||||||
|
clutter_paint_volume_free (&projected_pv);
|
||||||
|
box->x1 = CLUTTER_NEARBYINT (box->x1);
|
||||||
|
box->y1 = CLUTTER_NEARBYINT (box->y1);
|
||||||
|
box->x2 = CLUTTER_NEARBYINT (box->x2);
|
||||||
|
box->y2 = CLUTTER_NEARBYINT (box->y2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* The aim here is that for a given rectangle defined with floating point
|
/* The aim here is that for a given rectangle defined with floating point
|
||||||
* coordinates we want to determine a stable quantized size in pixels
|
* coordinates we want to determine a stable quantized size in pixels
|
||||||
* that doesn't vary due to the original box's sub-pixel position.
|
* that doesn't vary due to the original box's sub-pixel position.
|
||||||
|
@ -1782,7 +1782,7 @@ selection_paint (ClutterText *self)
|
|||||||
CoglColor cogl_color = { 0, };
|
CoglColor cogl_color = { 0, };
|
||||||
CoglFramebuffer *fb;
|
CoglFramebuffer *fb;
|
||||||
|
|
||||||
fb = _clutter_actor_get_active_framebuffer (actor);
|
fb = cogl_get_draw_framebuffer ();
|
||||||
if (G_UNLIKELY (fb == NULL))
|
if (G_UNLIKELY (fb == NULL))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -2391,12 +2391,6 @@ clutter_text_paint (ClutterActor *self)
|
|||||||
float alloc_width;
|
float alloc_width;
|
||||||
float alloc_height;
|
float alloc_height;
|
||||||
|
|
||||||
/* FIXME: this should not be needed, but apparently the text-cache
|
|
||||||
* test unit manages to get in a situation where the active frame
|
|
||||||
* buffer is NULL
|
|
||||||
*/
|
|
||||||
fb = _clutter_actor_get_active_framebuffer (self);
|
|
||||||
if (fb == NULL)
|
|
||||||
fb = cogl_get_draw_framebuffer ();
|
fb = cogl_get_draw_framebuffer ();
|
||||||
|
|
||||||
/* Note that if anything in this paint method changes it needs to be
|
/* Note that if anything in this paint method changes it needs to be
|
||||||
@ -2830,6 +2824,10 @@ clutter_text_key_focus_in (ClutterActor *actor)
|
|||||||
if (method && priv->editable)
|
if (method && priv->editable)
|
||||||
{
|
{
|
||||||
clutter_input_method_focus_in (method, priv->input_focus);
|
clutter_input_method_focus_in (method, priv->input_focus);
|
||||||
|
clutter_input_focus_set_content_purpose (priv->input_focus,
|
||||||
|
priv->input_purpose);
|
||||||
|
clutter_input_focus_set_content_hints (priv->input_focus,
|
||||||
|
priv->input_hints);
|
||||||
update_cursor_location (CLUTTER_TEXT (actor));
|
update_cursor_location (CLUTTER_TEXT (actor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4511,6 +4509,27 @@ buffer_deleted_text (ClutterTextBuffer *buffer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_text_queue_redraw_or_relayout (ClutterText *self)
|
||||||
|
{
|
||||||
|
ClutterActor *actor = CLUTTER_ACTOR (self);
|
||||||
|
gfloat preferred_width;
|
||||||
|
gfloat preferred_height;
|
||||||
|
|
||||||
|
clutter_text_dirty_cache (self);
|
||||||
|
|
||||||
|
/* we're using our private implementations here to avoid the caching done by ClutterActor */
|
||||||
|
clutter_text_get_preferred_width (actor, -1, NULL, &preferred_width);
|
||||||
|
clutter_text_get_preferred_height (actor, preferred_width, NULL, &preferred_height);
|
||||||
|
|
||||||
|
if (clutter_actor_has_allocation (actor) &&
|
||||||
|
(fabsf (preferred_width - clutter_actor_get_width (actor)) > 0.001 ||
|
||||||
|
fabsf (preferred_height - clutter_actor_get_height (actor)) > 0.001))
|
||||||
|
clutter_actor_queue_relayout (actor);
|
||||||
|
else
|
||||||
|
clutter_text_queue_redraw (actor);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
buffer_notify_text (ClutterTextBuffer *buffer,
|
buffer_notify_text (ClutterTextBuffer *buffer,
|
||||||
GParamSpec *spec,
|
GParamSpec *spec,
|
||||||
@ -4518,9 +4537,7 @@ buffer_notify_text (ClutterTextBuffer *buffer,
|
|||||||
{
|
{
|
||||||
g_object_freeze_notify (G_OBJECT (self));
|
g_object_freeze_notify (G_OBJECT (self));
|
||||||
|
|
||||||
clutter_text_dirty_cache (self);
|
clutter_text_queue_redraw_or_relayout (self);
|
||||||
|
|
||||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
|
||||||
|
|
||||||
g_signal_emit (self, text_signals[TEXT_CHANGED], 0);
|
g_signal_emit (self, text_signals[TEXT_CHANGED], 0);
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_TEXT]);
|
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_TEXT]);
|
||||||
@ -4872,8 +4889,7 @@ clutter_text_set_cursor_visible (ClutterText *self,
|
|||||||
{
|
{
|
||||||
priv->cursor_visible = cursor_visible;
|
priv->cursor_visible = cursor_visible;
|
||||||
|
|
||||||
clutter_text_dirty_cache (self);
|
clutter_text_queue_redraw_or_relayout (self);
|
||||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CURSOR_VISIBLE]);
|
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CURSOR_VISIBLE]);
|
||||||
}
|
}
|
||||||
@ -5774,9 +5790,7 @@ clutter_text_set_line_alignment (ClutterText *self,
|
|||||||
{
|
{
|
||||||
priv->alignment = alignment;
|
priv->alignment = alignment;
|
||||||
|
|
||||||
clutter_text_dirty_cache (self);
|
clutter_text_queue_redraw_or_relayout (self);
|
||||||
|
|
||||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_LINE_ALIGNMENT]);
|
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_LINE_ALIGNMENT]);
|
||||||
}
|
}
|
||||||
@ -5831,9 +5845,7 @@ clutter_text_set_use_markup (ClutterText *self,
|
|||||||
if (setting)
|
if (setting)
|
||||||
clutter_text_set_markup_internal (self, text);
|
clutter_text_set_markup_internal (self, text);
|
||||||
|
|
||||||
clutter_text_dirty_cache (self);
|
clutter_text_queue_redraw_or_relayout (self);
|
||||||
|
|
||||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -5880,9 +5892,7 @@ clutter_text_set_justify (ClutterText *self,
|
|||||||
{
|
{
|
||||||
priv->justify = justify;
|
priv->justify = justify;
|
||||||
|
|
||||||
clutter_text_dirty_cache (self);
|
clutter_text_queue_redraw_or_relayout (self);
|
||||||
|
|
||||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_JUSTIFY]);
|
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_JUSTIFY]);
|
||||||
}
|
}
|
||||||
@ -6449,8 +6459,7 @@ clutter_text_set_preedit_string (ClutterText *self,
|
|||||||
priv->preedit_set = TRUE;
|
priv->preedit_set = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
clutter_text_dirty_cache (self);
|
clutter_text_queue_redraw_or_relayout (self);
|
||||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6512,6 +6521,8 @@ clutter_text_set_input_hints (ClutterText *self,
|
|||||||
g_return_if_fail (CLUTTER_IS_TEXT (self));
|
g_return_if_fail (CLUTTER_IS_TEXT (self));
|
||||||
|
|
||||||
self->priv->input_hints = hints;
|
self->priv->input_hints = hints;
|
||||||
|
|
||||||
|
if (clutter_input_focus_is_focused (self->priv->input_focus))
|
||||||
clutter_input_focus_set_content_hints (self->priv->input_focus, hints);
|
clutter_input_focus_set_content_hints (self->priv->input_focus, hints);
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_INPUT_HINTS]);
|
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_INPUT_HINTS]);
|
||||||
}
|
}
|
||||||
@ -6531,6 +6542,8 @@ clutter_text_set_input_purpose (ClutterText *self,
|
|||||||
g_return_if_fail (CLUTTER_IS_TEXT (self));
|
g_return_if_fail (CLUTTER_IS_TEXT (self));
|
||||||
|
|
||||||
self->priv->input_purpose = purpose;
|
self->priv->input_purpose = purpose;
|
||||||
|
|
||||||
|
if (clutter_input_focus_is_focused (self->priv->input_focus))
|
||||||
clutter_input_focus_set_content_purpose (self->priv->input_focus, purpose);
|
clutter_input_focus_set_content_purpose (self->priv->input_focus, purpose);
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_INPUT_PURPOSE]);
|
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_INPUT_PURPOSE]);
|
||||||
}
|
}
|
||||||
|
@ -793,10 +793,12 @@ evdev_add_device (ClutterDeviceManagerEvdev *manager_evdev,
|
|||||||
if (priv->main_seat->libinput_seat == NULL)
|
if (priv->main_seat->libinput_seat == NULL)
|
||||||
seat = priv->main_seat;
|
seat = priv->main_seat;
|
||||||
else
|
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);
|
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);
|
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;
|
ClutterDeviceManagerEvdev *manager_evdev;
|
||||||
ClutterDeviceManagerEvdevPrivate *priv;
|
ClutterDeviceManagerEvdevPrivate *priv;
|
||||||
GSList *l;
|
GSList *l;
|
||||||
GSList *device_it;
|
|
||||||
|
|
||||||
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager);
|
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager);
|
||||||
priv = manager_evdev->priv;
|
priv = manager_evdev->priv;
|
||||||
@ -927,15 +928,11 @@ clutter_device_manager_evdev_get_device (ClutterDeviceManager *manager,
|
|||||||
for (l = priv->seats; l; l = l->next)
|
for (l = priv->seats; l; l = l->next)
|
||||||
{
|
{
|
||||||
ClutterSeatEvdev *seat = l->data;
|
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)
|
if (device)
|
||||||
{
|
|
||||||
ClutterInputDevice *device = device_it->data;
|
|
||||||
|
|
||||||
if (clutter_input_device_get_device_id (device) == id)
|
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1967,6 +1964,7 @@ clutter_device_manager_evdev_constructed (GObject *gobject)
|
|||||||
xkb_context_unref (ctx);
|
xkb_context_unref (ctx);
|
||||||
|
|
||||||
priv->main_seat = clutter_seat_evdev_new (manager_evdev);
|
priv->main_seat = clutter_seat_evdev_new (manager_evdev);
|
||||||
|
priv->seats = g_slist_append (priv->seats, priv->main_seat);
|
||||||
|
|
||||||
dispatch_libinput (manager_evdev);
|
dispatch_libinput (manager_evdev);
|
||||||
|
|
||||||
|
@ -433,6 +433,8 @@ key_event_is_modifier (ClutterEvent *event)
|
|||||||
case XKB_KEY_Super_R:
|
case XKB_KEY_Super_R:
|
||||||
case XKB_KEY_Hyper_L:
|
case XKB_KEY_Hyper_L:
|
||||||
case XKB_KEY_Hyper_R:
|
case XKB_KEY_Hyper_R:
|
||||||
|
case XKB_KEY_Caps_Lock:
|
||||||
|
case XKB_KEY_Shift_Lock:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -584,6 +586,12 @@ handle_stickykeys_press (ClutterEvent *event,
|
|||||||
}
|
}
|
||||||
|
|
||||||
depressed_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED);
|
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_latched_mask = device->stickykeys_latched_mask;
|
||||||
new_locked_mask = device->stickykeys_locked_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);
|
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)
|
if (!device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)
|
||||||
goto emit_event;
|
goto emit_event;
|
||||||
|
|
||||||
|
@ -858,6 +858,24 @@ clutter_seat_evdev_free (ClutterSeatEvdev *seat)
|
|||||||
g_free (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
|
void
|
||||||
clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat,
|
clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat,
|
||||||
ClutterStage *stage)
|
ClutterStage *stage)
|
||||||
|
@ -139,6 +139,9 @@ void clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
|
|||||||
|
|
||||||
void clutter_seat_evdev_sync_leds (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,
|
ClutterTouchState * clutter_seat_evdev_acquire_touch_state (ClutterSeatEvdev *seat,
|
||||||
int device_slot);
|
int device_slot);
|
||||||
|
|
||||||
|
@ -185,6 +185,26 @@ clutter_virtual_input_device_evdev_notify_absolute_motion (ClutterVirtualInputDe
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
translate_to_evdev_button (int clutter_button)
|
||||||
|
{
|
||||||
|
switch (clutter_button)
|
||||||
|
{
|
||||||
|
case CLUTTER_BUTTON_PRIMARY:
|
||||||
|
return BTN_LEFT;
|
||||||
|
case CLUTTER_BUTTON_SECONDARY:
|
||||||
|
return BTN_RIGHT;
|
||||||
|
case CLUTTER_BUTTON_MIDDLE:
|
||||||
|
return BTN_MIDDLE;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* For compatibility reasons, all additional buttons go after the old
|
||||||
|
* 4-7 scroll ones.
|
||||||
|
*/
|
||||||
|
return clutter_button + (BTN_LEFT - 1) - 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_virtual_input_device_evdev_notify_button (ClutterVirtualInputDevice *virtual_device,
|
clutter_virtual_input_device_evdev_notify_button (ClutterVirtualInputDevice *virtual_device,
|
||||||
uint64_t time_us,
|
uint64_t time_us,
|
||||||
@ -194,30 +214,33 @@ clutter_virtual_input_device_evdev_notify_button (ClutterVirtualInputDevice *vir
|
|||||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||||
int button_count;
|
int button_count;
|
||||||
|
int evdev_button;
|
||||||
|
|
||||||
if (time_us == CLUTTER_CURRENT_TIME)
|
if (time_us == CLUTTER_CURRENT_TIME)
|
||||||
time_us = g_get_monotonic_time ();
|
time_us = g_get_monotonic_time ();
|
||||||
|
|
||||||
if (get_button_type (button) != EVDEV_BUTTON_TYPE_BUTTON)
|
evdev_button = translate_to_evdev_button (button);
|
||||||
|
|
||||||
|
if (get_button_type (evdev_button) != EVDEV_BUTTON_TYPE_BUTTON)
|
||||||
{
|
{
|
||||||
g_warning ("Unknown/invalid virtual device button 0x%x pressed",
|
g_warning ("Unknown/invalid virtual device button 0x%x pressed",
|
||||||
button);
|
evdev_button);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
button_count = update_button_count (virtual_evdev, button, button_state);
|
button_count = update_button_count (virtual_evdev, evdev_button, button_state);
|
||||||
if (button_count < 0 || button_count > 1)
|
if (button_count < 0 || button_count > 1)
|
||||||
{
|
{
|
||||||
g_warning ("Received multiple virtual 0x%x button %s (ignoring)", button,
|
g_warning ("Received multiple virtual 0x%x button %s (ignoring)", evdev_button,
|
||||||
button_state == CLUTTER_BUTTON_STATE_PRESSED ? "presses" : "releases");
|
button_state == CLUTTER_BUTTON_STATE_PRESSED ? "presses" : "releases");
|
||||||
update_button_count (virtual_evdev, button, 1 - button_state);
|
update_button_count (virtual_evdev, evdev_button, 1 - button_state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clutter_seat_evdev_notify_button (virtual_evdev->seat,
|
clutter_seat_evdev_notify_button (virtual_evdev->seat,
|
||||||
virtual_evdev->device,
|
virtual_evdev->device,
|
||||||
time_us,
|
time_us,
|
||||||
button,
|
evdev_button,
|
||||||
button_state);
|
button_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,14 @@
|
|||||||
|
|
||||||
typedef struct _ClutterKeymapX11Class ClutterKeymapX11Class;
|
typedef struct _ClutterKeymapX11Class ClutterKeymapX11Class;
|
||||||
typedef struct _DirectionCacheEntry DirectionCacheEntry;
|
typedef struct _DirectionCacheEntry DirectionCacheEntry;
|
||||||
|
typedef struct _ClutterKeymapKey ClutterKeymapKey;
|
||||||
|
|
||||||
|
struct _ClutterKeymapKey
|
||||||
|
{
|
||||||
|
guint keycode;
|
||||||
|
guint group;
|
||||||
|
guint level;
|
||||||
|
};
|
||||||
|
|
||||||
struct _DirectionCacheEntry
|
struct _DirectionCacheEntry
|
||||||
{
|
{
|
||||||
@ -59,6 +67,7 @@ struct _ClutterKeymapX11
|
|||||||
|
|
||||||
ClutterModifierType num_lock_mask;
|
ClutterModifierType num_lock_mask;
|
||||||
ClutterModifierType scroll_lock_mask;
|
ClutterModifierType scroll_lock_mask;
|
||||||
|
ClutterModifierType level3_shift_mask;
|
||||||
|
|
||||||
PangoDirection current_direction;
|
PangoDirection current_direction;
|
||||||
|
|
||||||
@ -69,6 +78,10 @@ struct _ClutterKeymapX11
|
|||||||
Atom current_group_atom;
|
Atom current_group_atom;
|
||||||
guint current_cache_serial;
|
guint current_cache_serial;
|
||||||
DirectionCacheEntry group_direction_cache[4];
|
DirectionCacheEntry group_direction_cache[4];
|
||||||
|
int current_group;
|
||||||
|
|
||||||
|
GHashTable *reserved_keycodes;
|
||||||
|
GQueue *available_keycodes;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
guint caps_lock_state : 1;
|
guint caps_lock_state : 1;
|
||||||
@ -198,6 +211,9 @@ get_xkb (ClutterKeymapX11 *keymap_x11)
|
|||||||
if (keymap_x11->scroll_lock_mask == 0)
|
if (keymap_x11->scroll_lock_mask == 0)
|
||||||
keymap_x11->scroll_lock_mask = XkbKeysymToModifiers (backend_x11->xdpy,
|
keymap_x11->scroll_lock_mask = XkbKeysymToModifiers (backend_x11->xdpy,
|
||||||
XK_Scroll_Lock);
|
XK_Scroll_Lock);
|
||||||
|
if (keymap_x11->level3_shift_mask == 0)
|
||||||
|
keymap_x11->level3_shift_mask = XkbKeysymToModifiers (backend_x11->xdpy,
|
||||||
|
XK_ISO_Level3_Shift);
|
||||||
|
|
||||||
return keymap_x11->xkb_desc;
|
return keymap_x11->xkb_desc;
|
||||||
}
|
}
|
||||||
@ -428,16 +444,100 @@ clutter_keymap_x11_set_property (GObject *gobject,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_XKB
|
||||||
|
static void
|
||||||
|
clutter_keymap_x11_refresh_reserved_keycodes (ClutterKeymapX11 *keymap_x11)
|
||||||
|
{
|
||||||
|
Display *dpy = clutter_x11_get_default_display ();
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||||
|
{
|
||||||
|
guint reserved_keycode = GPOINTER_TO_UINT (key);
|
||||||
|
guint reserved_keysym = GPOINTER_TO_UINT (value);
|
||||||
|
guint actual_keysym = XkbKeycodeToKeysym (dpy, reserved_keycode, 0, 0);
|
||||||
|
|
||||||
|
/* If an available keycode is no longer mapped to the stored keysym, then
|
||||||
|
* the keycode should not be considered available anymore and should be
|
||||||
|
* removed both from the list of available and reserved keycodes.
|
||||||
|
*/
|
||||||
|
if (reserved_keysym != actual_keysym)
|
||||||
|
{
|
||||||
|
g_hash_table_iter_remove (&iter);
|
||||||
|
g_queue_remove (keymap_x11->available_keycodes, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
clutter_keymap_x11_replace_keycode (ClutterKeymapX11 *keymap_x11,
|
||||||
|
KeyCode keycode,
|
||||||
|
KeySym keysym)
|
||||||
|
{
|
||||||
|
if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb)
|
||||||
|
{
|
||||||
|
Display *dpy = clutter_x11_get_default_display ();
|
||||||
|
XkbDescPtr xkb = get_xkb (keymap_x11);
|
||||||
|
XkbMapChangesRec changes;
|
||||||
|
|
||||||
|
XFlush (dpy);
|
||||||
|
|
||||||
|
xkb->device_spec = XkbUseCoreKbd;
|
||||||
|
memset (&changes, 0, sizeof(changes));
|
||||||
|
|
||||||
|
if (keysym != NoSymbol)
|
||||||
|
{
|
||||||
|
int types[XkbNumKbdGroups] = { XkbOneLevelIndex };
|
||||||
|
XkbChangeTypesOfKey (xkb, keycode, 1, XkbGroup1Mask, types, &changes);
|
||||||
|
XkbKeySymEntry (xkb, keycode, 0, 0) = keysym;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Reset to NoSymbol */
|
||||||
|
XkbChangeTypesOfKey (xkb, keycode, 0, XkbGroup1Mask, NULL, &changes);
|
||||||
|
}
|
||||||
|
|
||||||
|
changes.changed = XkbKeySymsMask | XkbKeyTypesMask;
|
||||||
|
changes.first_key_sym = keycode;
|
||||||
|
changes.num_key_syms = 1;
|
||||||
|
changes.first_type = 0;
|
||||||
|
changes.num_types = xkb->map->num_types;
|
||||||
|
XkbChangeMap (dpy, xkb, &changes);
|
||||||
|
|
||||||
|
XFlush (dpy);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_keymap_x11_finalize (GObject *gobject)
|
clutter_keymap_x11_finalize (GObject *gobject)
|
||||||
{
|
{
|
||||||
ClutterKeymapX11 *keymap;
|
ClutterKeymapX11 *keymap;
|
||||||
ClutterEventTranslator *translator;
|
ClutterEventTranslator *translator;
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
keymap = CLUTTER_KEYMAP_X11 (gobject);
|
keymap = CLUTTER_KEYMAP_X11 (gobject);
|
||||||
translator = CLUTTER_EVENT_TRANSLATOR (keymap);
|
translator = CLUTTER_EVENT_TRANSLATOR (keymap);
|
||||||
|
|
||||||
#ifdef HAVE_XKB
|
#ifdef HAVE_XKB
|
||||||
|
clutter_keymap_x11_refresh_reserved_keycodes (keymap);
|
||||||
|
g_hash_table_iter_init (&iter, keymap->reserved_keycodes);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||||
|
{
|
||||||
|
guint keycode = GPOINTER_TO_UINT (key);
|
||||||
|
clutter_keymap_x11_replace_keycode (keymap, keycode, NoSymbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hash_table_destroy (keymap->reserved_keycodes);
|
||||||
|
g_queue_free (keymap->available_keycodes);
|
||||||
|
|
||||||
_clutter_backend_remove_event_translator (keymap->backend, translator);
|
_clutter_backend_remove_event_translator (keymap->backend, translator);
|
||||||
|
|
||||||
if (keymap->xkb_desc != NULL)
|
if (keymap->xkb_desc != NULL)
|
||||||
@ -447,6 +547,7 @@ clutter_keymap_x11_finalize (GObject *gobject)
|
|||||||
G_OBJECT_CLASS (clutter_keymap_x11_parent_class)->finalize (gobject);
|
G_OBJECT_CLASS (clutter_keymap_x11_parent_class)->finalize (gobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_keymap_x11_class_init (ClutterKeymapX11Class *klass)
|
clutter_keymap_x11_class_init (ClutterKeymapX11Class *klass)
|
||||||
{
|
{
|
||||||
@ -469,6 +570,12 @@ static void
|
|||||||
clutter_keymap_x11_init (ClutterKeymapX11 *keymap)
|
clutter_keymap_x11_init (ClutterKeymapX11 *keymap)
|
||||||
{
|
{
|
||||||
keymap->current_direction = PANGO_DIRECTION_NEUTRAL;
|
keymap->current_direction = PANGO_DIRECTION_NEUTRAL;
|
||||||
|
keymap->current_group = -1;
|
||||||
|
|
||||||
|
#ifdef HAVE_XKB
|
||||||
|
keymap->reserved_keycodes = g_hash_table_new (NULL, NULL);
|
||||||
|
keymap->available_keycodes = g_queue_new ();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClutterTranslateReturn
|
static ClutterTranslateReturn
|
||||||
@ -498,7 +605,8 @@ clutter_keymap_x11_translate_event (ClutterEventTranslator *translator,
|
|||||||
{
|
{
|
||||||
case XkbStateNotify:
|
case XkbStateNotify:
|
||||||
CLUTTER_NOTE (EVENT, "Updating keyboard state");
|
CLUTTER_NOTE (EVENT, "Updating keyboard state");
|
||||||
update_direction (keymap_x11, XkbStateGroup (&xkb_event->state));
|
keymap_x11->current_group = XkbStateGroup (&xkb_event->state);
|
||||||
|
update_direction (keymap_x11, keymap_x11->current_group);
|
||||||
update_locked_mods (keymap_x11, xkb_event->state.locked_mods);
|
update_locked_mods (keymap_x11, xkb_event->state.locked_mods);
|
||||||
retval = CLUTTER_TRANSLATE_REMOVE;
|
retval = CLUTTER_TRANSLATE_REMOVE;
|
||||||
break;
|
break;
|
||||||
@ -665,3 +773,258 @@ _clutter_keymap_x11_get_direction (ClutterKeymapX11 *keymap)
|
|||||||
#endif
|
#endif
|
||||||
return PANGO_DIRECTION_NEUTRAL;
|
return PANGO_DIRECTION_NEUTRAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
clutter_keymap_x11_get_entries_for_keyval (ClutterKeymapX11 *keymap_x11,
|
||||||
|
guint keyval,
|
||||||
|
ClutterKeymapKey **keys,
|
||||||
|
gint *n_keys)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_XKB
|
||||||
|
if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb)
|
||||||
|
{
|
||||||
|
XkbDescRec *xkb = get_xkb (keymap_x11);
|
||||||
|
GArray *retval;
|
||||||
|
gint keycode;
|
||||||
|
|
||||||
|
keycode = keymap_x11->min_keycode;
|
||||||
|
retval = g_array_new (FALSE, FALSE, sizeof (ClutterKeymapKey));
|
||||||
|
|
||||||
|
while (keycode <= keymap_x11->max_keycode)
|
||||||
|
{
|
||||||
|
gint max_shift_levels = XkbKeyGroupsWidth (xkb, keycode);
|
||||||
|
gint group = 0;
|
||||||
|
gint level = 0;
|
||||||
|
gint total_syms = XkbKeyNumSyms (xkb, keycode);
|
||||||
|
gint i = 0;
|
||||||
|
KeySym *entry;
|
||||||
|
|
||||||
|
/* entry is an array with all syms for group 0, all
|
||||||
|
* syms for group 1, etc. and for each group the
|
||||||
|
* shift level syms are in order
|
||||||
|
*/
|
||||||
|
entry = XkbKeySymsPtr (xkb, keycode);
|
||||||
|
|
||||||
|
while (i < total_syms)
|
||||||
|
{
|
||||||
|
g_assert (i == (group * max_shift_levels + level));
|
||||||
|
|
||||||
|
if (entry[i] == keyval)
|
||||||
|
{
|
||||||
|
ClutterKeymapKey key;
|
||||||
|
|
||||||
|
key.keycode = keycode;
|
||||||
|
key.group = group;
|
||||||
|
key.level = level;
|
||||||
|
|
||||||
|
g_array_append_val (retval, key);
|
||||||
|
|
||||||
|
g_assert (XkbKeySymEntry (xkb, keycode, level, group) ==
|
||||||
|
keyval);
|
||||||
|
}
|
||||||
|
|
||||||
|
++level;
|
||||||
|
|
||||||
|
if (level == max_shift_levels)
|
||||||
|
{
|
||||||
|
level = 0;
|
||||||
|
++group;
|
||||||
|
}
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
++keycode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retval->len > 0)
|
||||||
|
{
|
||||||
|
*keys = (ClutterKeymapKey*) retval->data;
|
||||||
|
*n_keys = retval->len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*keys = NULL;
|
||||||
|
*n_keys = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_free (retval, retval->len > 0 ? FALSE : TRUE);
|
||||||
|
|
||||||
|
return *n_keys > 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_XKB
|
||||||
|
static guint
|
||||||
|
clutter_keymap_x11_get_available_keycode (ClutterKeymapX11 *keymap_x11)
|
||||||
|
{
|
||||||
|
if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb)
|
||||||
|
{
|
||||||
|
clutter_keymap_x11_refresh_reserved_keycodes (keymap_x11);
|
||||||
|
|
||||||
|
if (g_hash_table_size (keymap_x11->reserved_keycodes) < 5)
|
||||||
|
{
|
||||||
|
Display *dpy = clutter_x11_get_default_display ();
|
||||||
|
XkbDescPtr xkb = get_xkb (keymap_x11);
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = xkb->max_key_code; i >= xkb->min_key_code; --i)
|
||||||
|
{
|
||||||
|
if (XkbKeycodeToKeysym (dpy, i, 0, 0) == NoSymbol)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GPOINTER_TO_UINT (g_queue_pop_head (keymap_x11->available_keycodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11,
|
||||||
|
guint keyval,
|
||||||
|
guint *keycode_out)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11), FALSE);
|
||||||
|
g_return_val_if_fail (keyval != 0, FALSE);
|
||||||
|
g_return_val_if_fail (keycode_out != NULL, FALSE);
|
||||||
|
|
||||||
|
#ifdef HAVE_XKB
|
||||||
|
*keycode_out = clutter_keymap_x11_get_available_keycode (keymap_x11);
|
||||||
|
|
||||||
|
if (*keycode_out == NoSymbol)
|
||||||
|
{
|
||||||
|
g_warning ("Cannot reserve a keycode for keyval %d: no available keycode", keyval);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!clutter_keymap_x11_replace_keycode (keymap_x11, *keycode_out, keyval))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to remap keycode %d to keyval %d", *keycode_out, keyval);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hash_table_insert (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (*keycode_out), GUINT_TO_POINTER (keyval));
|
||||||
|
g_queue_remove (keymap_x11->available_keycodes, GUINT_TO_POINTER (*keycode_out));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
#else
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11,
|
||||||
|
guint keycode)
|
||||||
|
{
|
||||||
|
g_return_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11));
|
||||||
|
|
||||||
|
#ifdef HAVE_XKB
|
||||||
|
if (!g_hash_table_contains (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (keycode)) ||
|
||||||
|
g_queue_index (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)) != -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_queue_push_tail (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11,
|
||||||
|
uint32_t level,
|
||||||
|
gboolean enable)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_XKB
|
||||||
|
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend);
|
||||||
|
uint32_t modifiers[] = {
|
||||||
|
0,
|
||||||
|
ShiftMask,
|
||||||
|
keymap_x11->level3_shift_mask,
|
||||||
|
keymap_x11->level3_shift_mask | ShiftMask,
|
||||||
|
};
|
||||||
|
uint32_t value = 0;
|
||||||
|
|
||||||
|
if (!backend_x11->use_xkb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
level = CLAMP (level, 0, G_N_ELEMENTS (modifiers) - 1);
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
value = modifiers[level];
|
||||||
|
else
|
||||||
|
value = 0;
|
||||||
|
|
||||||
|
XkbLatchModifiers (clutter_x11_get_default_display (),
|
||||||
|
XkbUseCoreKbd, modifiers[level],
|
||||||
|
value);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
clutter_keymap_x11_get_current_group (ClutterKeymapX11 *keymap_x11)
|
||||||
|
{
|
||||||
|
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (keymap_x11->backend);
|
||||||
|
XkbStateRec state_rec;
|
||||||
|
|
||||||
|
if (keymap_x11->current_group >= 0)
|
||||||
|
return keymap_x11->current_group;
|
||||||
|
|
||||||
|
XkbGetState (backend_x11->xdpy, XkbUseCoreKbd, &state_rec);
|
||||||
|
return XkbStateGroup (&state_rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11,
|
||||||
|
guint keyval,
|
||||||
|
guint *keycode_out,
|
||||||
|
guint *level_out)
|
||||||
|
{
|
||||||
|
ClutterKeymapKey *keys;
|
||||||
|
gint i, n_keys, group;
|
||||||
|
gboolean found = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (keycode_out != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (level_out != NULL, FALSE);
|
||||||
|
|
||||||
|
group = clutter_keymap_x11_get_current_group (keymap_x11);
|
||||||
|
|
||||||
|
if (!clutter_keymap_x11_get_entries_for_keyval (keymap_x11, keyval, &keys, &n_keys))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < n_keys && !found; i++)
|
||||||
|
{
|
||||||
|
if (keys[i].group == group)
|
||||||
|
{
|
||||||
|
*keycode_out = keys[i].keycode;
|
||||||
|
*level_out = keys[i].level;
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes);
|
||||||
|
while (!found && g_hash_table_iter_next (&iter, &key, &value))
|
||||||
|
{
|
||||||
|
guint reserved_keycode = GPOINTER_TO_UINT (key);
|
||||||
|
guint reserved_keysym = GPOINTER_TO_UINT (value);
|
||||||
|
|
||||||
|
if (keyval == reserved_keysym)
|
||||||
|
{
|
||||||
|
*keycode_out = reserved_keycode;
|
||||||
|
*level_out = 0;
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (keys);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
@ -51,6 +51,18 @@ gboolean _clutter_keymap_x11_get_is_modifier (ClutterKeymapX11 *keymap,
|
|||||||
|
|
||||||
PangoDirection _clutter_keymap_x11_get_direction (ClutterKeymapX11 *keymap);
|
PangoDirection _clutter_keymap_x11_get_direction (ClutterKeymapX11 *keymap);
|
||||||
|
|
||||||
|
gboolean clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11,
|
||||||
|
guint keyval,
|
||||||
|
guint *keycode_out,
|
||||||
|
guint *level_out);
|
||||||
|
void clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11,
|
||||||
|
uint32_t level,
|
||||||
|
gboolean enable);
|
||||||
|
gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11,
|
||||||
|
guint keyval,
|
||||||
|
guint *keycode_out);
|
||||||
|
void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11,
|
||||||
|
guint keycode);
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __CLUTTER_KEYMAP_X11_H__ */
|
#endif /* __CLUTTER_KEYMAP_X11_H__ */
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
#include "clutter-virtual-input-device.h"
|
#include "clutter-virtual-input-device.h"
|
||||||
#include "x11/clutter-virtual-input-device-x11.h"
|
#include "x11/clutter-virtual-input-device-x11.h"
|
||||||
|
#include "x11/clutter-backend-x11.h"
|
||||||
|
#include "x11/clutter-keymap-x11.h"
|
||||||
|
|
||||||
struct _ClutterVirtualInputDeviceX11
|
struct _ClutterVirtualInputDeviceX11
|
||||||
{
|
{
|
||||||
@ -135,11 +137,36 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu
|
|||||||
uint32_t keyval,
|
uint32_t keyval,
|
||||||
ClutterKeyState key_state)
|
ClutterKeyState key_state)
|
||||||
{
|
{
|
||||||
KeyCode keycode;
|
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
|
||||||
|
ClutterKeymapX11 *keymap = backend_x11->keymap;
|
||||||
|
uint32_t keycode, level;
|
||||||
|
|
||||||
|
if (!clutter_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level))
|
||||||
|
{
|
||||||
|
level = 0;
|
||||||
|
|
||||||
|
if (!clutter_keymap_x11_reserve_keycode (keymap, keyval, &keycode))
|
||||||
|
{
|
||||||
|
g_warning ("No keycode found for keyval %x in current group", keyval);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) &&
|
||||||
|
key_state == CLUTTER_KEY_STATE_PRESSED)
|
||||||
|
clutter_keymap_x11_latch_modifiers (keymap, level, TRUE);
|
||||||
|
|
||||||
keycode = XKeysymToKeycode (clutter_x11_get_default_display (), keyval);
|
|
||||||
XTestFakeKeyEvent (clutter_x11_get_default_display (),
|
XTestFakeKeyEvent (clutter_x11_get_default_display (),
|
||||||
keycode, key_state == CLUTTER_KEY_STATE_PRESSED, 0);
|
(KeyCode) keycode,
|
||||||
|
key_state == CLUTTER_KEY_STATE_PRESSED, 0);
|
||||||
|
|
||||||
|
|
||||||
|
if (key_state == CLUTTER_KEY_STATE_RELEASED)
|
||||||
|
{
|
||||||
|
if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode))
|
||||||
|
clutter_keymap_x11_latch_modifiers (keymap, level, FALSE);
|
||||||
|
clutter_keymap_x11_release_keycode_if_needed (keymap, keycode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -230,13 +230,13 @@ paint_cb (ClutterStage *stage,
|
|||||||
gboolean *was_painted = data;
|
gboolean *was_painted = data;
|
||||||
|
|
||||||
/* old shader effect */
|
/* old shader effect */
|
||||||
g_assert_cmpint (get_pixel (50, 50), ==, 0xff0000);
|
g_assert_cmpint (get_pixel (0, 25), ==, 0xff0000);
|
||||||
/* new shader effect */
|
/* new shader effect */
|
||||||
g_assert_cmpint (get_pixel (150, 50), ==, 0x00ffff);
|
g_assert_cmpint (get_pixel (100, 25), ==, 0x00ffff);
|
||||||
/* another new shader effect */
|
/* another new shader effect */
|
||||||
g_assert_cmpint (get_pixel (250, 50), ==, 0xff00ff);
|
g_assert_cmpint (get_pixel (200, 25), ==, 0xff00ff);
|
||||||
/* new shader effect */
|
/* new shader effect */
|
||||||
g_assert_cmpint (get_pixel (350, 50), ==, 0x00ffff);
|
g_assert_cmpint (get_pixel (300, 25), ==, 0x00ffff);
|
||||||
|
|
||||||
*was_painted = TRUE;
|
*was_painted = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -452,7 +452,7 @@ libmutter_cogl_@LIBMUTTER_API_VERSION@_la_LDFLAGS = \
|
|||||||
-avoid-version \
|
-avoid-version \
|
||||||
-export-dynamic \
|
-export-dynamic \
|
||||||
-rpath $(mutterlibdir) \
|
-rpath $(mutterlibdir) \
|
||||||
-export-symbols-regex "^(cogl|_cogl_debug_flags|_cogl_atlas_new|_cogl_atlas_add_reorganize_callback|_cogl_atlas_reserve_space|_cogl_callback|_cogl_util_get_eye_planes_for_screen_poly|_cogl_atlas_texture_remove_reorganize_callback|_cogl_atlas_texture_add_reorganize_callback|_cogl_texture_get_format|_cogl_texture_foreach_sub_texture_in_region|_cogl_texture_set_region|_cogl_profile_trace_message|_cogl_context_get_default|_cogl_framebuffer_get_stencil_bits|_cogl_clip_stack_push_rectangle|_cogl_framebuffer_get_modelview_stack|_cogl_object_default_unref|_cogl_pipeline_foreach_layer_internal|_cogl_clip_stack_push_primitive|_cogl_buffer_unmap_for_fill_or_fallback|_cogl_framebuffer_draw_primitive|_cogl_debug_instances|_cogl_framebuffer_get_projection_stack|_cogl_pipeline_layer_get_texture|_cogl_buffer_map_for_fill_or_fallback|_cogl_texture_can_hardware_repeat|_cogl_pipeline_prune_to_n_layers|_cogl_primitive_draw|test_|unit_test_|_cogl_winsys_glx_get_vtable|_cogl_winsys_egl_xlib_get_vtable|_cogl_winsys_egl_get_vtable|_cogl_closure_disconnect|_cogl_onscreen_notify_complete|_cogl_onscreen_notify_frame_sync|_cogl_winsys_egl_renderer_connect_common|_cogl_winsys_error_quark|_cogl_set_error|_cogl_poll_renderer_add_fd|_cogl_poll_renderer_add_idle|_cogl_framebuffer_winsys_update_size|_cogl_winsys_egl_make_current|_cogl_pixel_format_get_bytes_per_pixel).*"
|
-export-symbols-regex "^(cogl|_cogl_debug_flags|_cogl_atlas_new|_cogl_atlas_add_reorganize_callback|_cogl_atlas_reserve_space|_cogl_callback|_cogl_util_get_eye_planes_for_screen_poly|_cogl_atlas_texture_remove_reorganize_callback|_cogl_atlas_texture_add_reorganize_callback|_cogl_texture_get_format|_cogl_texture_foreach_sub_texture_in_region|_cogl_texture_set_region|_cogl_profile_trace_message|_cogl_context_get_default|_cogl_framebuffer_get_stencil_bits|_cogl_clip_stack_push_rectangle|_cogl_framebuffer_get_modelview_stack|_cogl_object_default_unref|_cogl_pipeline_foreach_layer_internal|_cogl_clip_stack_push_primitive|_cogl_buffer_unmap_for_fill_or_fallback|_cogl_framebuffer_draw_primitive|_cogl_debug_instances|_cogl_framebuffer_get_projection_stack|_cogl_pipeline_layer_get_texture|_cogl_buffer_map_for_fill_or_fallback|_cogl_texture_can_hardware_repeat|_cogl_pipeline_prune_to_n_layers|_cogl_primitive_draw|test_|unit_test_|_cogl_winsys_glx_get_vtable|_cogl_winsys_egl_xlib_get_vtable|_cogl_winsys_egl_get_vtable|_cogl_closure_disconnect|_cogl_onscreen_notify_complete|_cogl_onscreen_notify_frame_sync|_cogl_winsys_egl_renderer_connect_common|_cogl_winsys_error_quark|_cogl_set_error|_cogl_poll_renderer_add_fd|_cogl_poll_renderer_add_idle|_cogl_framebuffer_winsys_update_size|_cogl_winsys_egl_make_current|_cogl_winsys_egl_ensure_current|_cogl_pixel_format_get_bytes_per_pixel).*"
|
||||||
|
|
||||||
libmutter_cogl_@LIBMUTTER_API_VERSION@_la_SOURCES = $(cogl_sources_c)
|
libmutter_cogl_@LIBMUTTER_API_VERSION@_la_SOURCES = $(cogl_sources_c)
|
||||||
nodist_libmutter_cogl_@LIBMUTTER_API_VERSION@_la_SOURCES = $(BUILT_SOURCES)
|
nodist_libmutter_cogl_@LIBMUTTER_API_VERSION@_la_SOURCES = $(BUILT_SOURCES)
|
||||||
|
@ -109,7 +109,11 @@ _cogl_object_default_unref (void *object)
|
|||||||
void
|
void
|
||||||
cogl_object_unref (void *obj)
|
cogl_object_unref (void *obj)
|
||||||
{
|
{
|
||||||
void (* unref_func) (void *) = ((CoglObject *) obj)->klass->virt_unref;
|
void (* unref_func) (void *);
|
||||||
|
|
||||||
|
_COGL_RETURN_IF_FAIL (obj != NULL);
|
||||||
|
|
||||||
|
unref_func = ((CoglObject *) obj)->klass->virt_unref;
|
||||||
unref_func (obj);
|
unref_func (obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,9 +492,6 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
|
|||||||
_cogl_bitmask_destroy (&uniforms_state->changed_mask);
|
_cogl_bitmask_destroy (&uniforms_state->changed_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
|
|
||||||
g_slice_free (CoglPipelineBigState, pipeline->big_state);
|
|
||||||
|
|
||||||
if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
|
if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
|
||||||
{
|
{
|
||||||
g_list_foreach (pipeline->layer_differences,
|
g_list_foreach (pipeline->layer_differences,
|
||||||
@ -508,6 +505,9 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
|
|||||||
if (pipeline->differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS)
|
if (pipeline->differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS)
|
||||||
_cogl_pipeline_snippet_list_free (&pipeline->big_state->fragment_snippets);
|
_cogl_pipeline_snippet_list_free (&pipeline->big_state->fragment_snippets);
|
||||||
|
|
||||||
|
if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
|
||||||
|
g_slice_free (CoglPipelineBigState, pipeline->big_state);
|
||||||
|
|
||||||
g_list_free (pipeline->deprecated_get_layers_list);
|
g_list_free (pipeline->deprecated_get_layers_list);
|
||||||
|
|
||||||
recursively_free_layer_caches (pipeline);
|
recursively_free_layer_caches (pipeline);
|
||||||
|
@ -94,6 +94,7 @@ cogl_texture_new_with_size (unsigned int width,
|
|||||||
if (!cogl_texture_allocate (tex, &skip_error))
|
if (!cogl_texture_allocate (tex, &skip_error))
|
||||||
{
|
{
|
||||||
cogl_error_free (skip_error);
|
cogl_error_free (skip_error);
|
||||||
|
skip_error = NULL;
|
||||||
cogl_object_unref (tex);
|
cogl_object_unref (tex);
|
||||||
tex = NULL;
|
tex = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1412,22 +1412,12 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
|
|||||||
if (!cogl_is_offscreen (framebuffer))
|
if (!cogl_is_offscreen (framebuffer))
|
||||||
y = framebuffer_height - y - height;
|
y = framebuffer_height - y - height;
|
||||||
|
|
||||||
required_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
|
required_format = ctx->driver_vtable->pixel_format_to_gl_with_target (ctx,
|
||||||
|
framebuffer->internal_format,
|
||||||
format,
|
format,
|
||||||
&gl_intformat,
|
&gl_intformat,
|
||||||
&gl_format,
|
&gl_format,
|
||||||
&gl_type);
|
&gl_type);
|
||||||
#if HAVE_COGL_GL
|
|
||||||
/* As we are reading pixels, we want to consider the bitmap according to
|
|
||||||
* its real pixel format, not the swizzled channels we pretend face to the
|
|
||||||
* pipeline.
|
|
||||||
*/
|
|
||||||
if ((ctx->driver == COGL_DRIVER_GL || ctx->driver == COGL_DRIVER_GL3) &&
|
|
||||||
(format == COGL_PIXEL_FORMAT_BGRA_8888 ||
|
|
||||||
format == COGL_PIXEL_FORMAT_BGRA_8888_PRE) &&
|
|
||||||
_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE))
|
|
||||||
gl_format = GL_BGRA;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* NB: All offscreen rendering is done upside down so there is no need
|
/* NB: All offscreen rendering is done upside down so there is no need
|
||||||
* to flip in this case... */
|
* to flip in this case... */
|
||||||
|
@ -181,6 +181,9 @@ _cogl_winsys_egl_make_current (CoglDisplay *display,
|
|||||||
EGLSurface read,
|
EGLSurface read,
|
||||||
EGLContext context);
|
EGLContext context);
|
||||||
|
|
||||||
|
EGLBoolean
|
||||||
|
_cogl_winsys_egl_ensure_current (CoglDisplay *display);
|
||||||
|
|
||||||
#ifdef EGL_KHR_image_base
|
#ifdef EGL_KHR_image_base
|
||||||
EGLImageKHR
|
EGLImageKHR
|
||||||
_cogl_egl_create_image (CoglContext *ctx,
|
_cogl_egl_create_image (CoglContext *ctx,
|
||||||
|
@ -309,6 +309,18 @@ _cogl_winsys_egl_make_current (CoglDisplay *display,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EGLBoolean
|
||||||
|
_cogl_winsys_egl_ensure_current (CoglDisplay *display)
|
||||||
|
{
|
||||||
|
CoglDisplayEGL *egl_display = display->winsys;
|
||||||
|
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
||||||
|
|
||||||
|
return eglMakeCurrent (egl_renderer->edpy,
|
||||||
|
egl_display->current_draw_surface,
|
||||||
|
egl_display->current_read_surface,
|
||||||
|
egl_display->current_context);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cleanup_context (CoglDisplay *display)
|
cleanup_context (CoglDisplay *display)
|
||||||
{
|
{
|
||||||
|
16
configure.ac
16
configure.ac
@ -2,7 +2,7 @@ AC_PREREQ(2.62)
|
|||||||
|
|
||||||
m4_define([mutter_major_version], [3])
|
m4_define([mutter_major_version], [3])
|
||||||
m4_define([mutter_minor_version], [28])
|
m4_define([mutter_minor_version], [28])
|
||||||
m4_define([mutter_micro_version], [0])
|
m4_define([mutter_micro_version], [4])
|
||||||
|
|
||||||
m4_define([mutter_version],
|
m4_define([mutter_version],
|
||||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||||
@ -262,7 +262,19 @@ AC_SUBST(XWAYLAND_PATH)
|
|||||||
|
|
||||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
|
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
|
||||||
|
|
||||||
MUTTER_NATIVE_BACKEND_MODULES="libdrm >= 2.4.83 libsystemd libinput >= 1.4 gudev-1.0 gbm >= 17.1"
|
PKG_CHECK_MODULES(ELOGIND, [libelogind], [have_elogind=yes], [have_elogind=no])
|
||||||
|
|
||||||
|
if test x$have_elogind = xyes; then
|
||||||
|
logind_provider="libelogind"
|
||||||
|
fi
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES(SYSTEMD, [libsystemd], [have_systemd=yes], [have_systemd=no])
|
||||||
|
|
||||||
|
if test x$have_systemd = xyes -o -z "$logind_provider"; then
|
||||||
|
logind_provider="libsystemd"
|
||||||
|
fi
|
||||||
|
|
||||||
|
MUTTER_NATIVE_BACKEND_MODULES="libdrm $logind_provider libinput >= 1.4 gudev-1.0 gbm >= 10.3"
|
||||||
|
|
||||||
AC_ARG_ENABLE(native-backend,
|
AC_ARG_ENABLE(native-backend,
|
||||||
AS_HELP_STRING([--disable-native-backend], [disable mutter native (KMS) backend]),,
|
AS_HELP_STRING([--disable-native-backend], [disable mutter native (KMS) backend]),,
|
||||||
|
23
po/sl.po
23
po/sl.po
@ -10,8 +10,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: mutter master\n"
|
"Project-Id-Version: mutter master\n"
|
||||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
|
||||||
"POT-Creation-Date: 2018-03-05 19:32+0000\n"
|
"POT-Creation-Date: 2018-04-03 20:43+0000\n"
|
||||||
"PO-Revision-Date: 2018-03-06 22:02+0100\n"
|
"PO-Revision-Date: 2018-04-09 20:28+0200\n"
|
||||||
"Last-Translator: Matej Urbančič <mateju@svn.gnome.org>\n"
|
"Last-Translator: Matej Urbančič <mateju@svn.gnome.org>\n"
|
||||||
"Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\n"
|
"Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\n"
|
||||||
"Language: sl_SI\n"
|
"Language: sl_SI\n"
|
||||||
@ -21,7 +21,7 @@ msgstr ""
|
|||||||
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n"
|
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n"
|
||||||
"%100==4 ? 3 : 0);\n"
|
"%100==4 ? 3 : 0);\n"
|
||||||
"X-Poedit-SourceCharset: utf-8\n"
|
"X-Poedit-SourceCharset: utf-8\n"
|
||||||
"X-Generator: Poedit 2.0.4\n"
|
"X-Generator: Poedit 2.0.6\n"
|
||||||
|
|
||||||
#: data/50-mutter-navigation.xml:6
|
#: data/50-mutter-navigation.xml:6
|
||||||
msgid "Navigation"
|
msgid "Navigation"
|
||||||
@ -481,7 +481,7 @@ msgstr "Ponovno omogoči tipkovne bližnjice"
|
|||||||
|
|
||||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:64
|
#: data/org.gnome.mutter.wayland.gschema.xml.in:64
|
||||||
msgid "Allow grabs with Xwayland"
|
msgid "Allow grabs with Xwayland"
|
||||||
msgstr ""
|
msgstr "Dovoli zajemanje z XWayland"
|
||||||
|
|
||||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:65
|
#: data/org.gnome.mutter.wayland.gschema.xml.in:65
|
||||||
msgid ""
|
msgid ""
|
||||||
@ -491,10 +491,14 @@ msgid ""
|
|||||||
"window or be among the applications white-listed in key “xwayland-grab-"
|
"window or be among the applications white-listed in key “xwayland-grab-"
|
||||||
"access-rules”."
|
"access-rules”."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Upošteva zajeme s tipkovnico, ki jih sprožijo programi X11, zagnani v okolju "
|
||||||
|
"Xwayland. Če naj se programski zajem upošteva, mora odjemalec ali poslati "
|
||||||
|
"specifično sporočilo X11 na korensko okno ali pa mora biti zaveden na "
|
||||||
|
"seznamu programov v ključu »xwayland-garb-access-rules«."
|
||||||
|
|
||||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:77
|
#: data/org.gnome.mutter.wayland.gschema.xml.in:77
|
||||||
msgid "Xwayland applications allowed to issue keyboard grabs"
|
msgid "Xwayland applications allowed to issue keyboard grabs"
|
||||||
msgstr ""
|
msgstr "Program XWayland ima dovoljenje za zajemanje s tipkovnico"
|
||||||
|
|
||||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:78
|
#: data/org.gnome.mutter.wayland.gschema.xml.in:78
|
||||||
msgid ""
|
msgid ""
|
||||||
@ -509,6 +513,15 @@ msgid ""
|
|||||||
"using the specific keyboard shortcut defined by the keybinding key “restore-"
|
"using the specific keyboard shortcut defined by the keybinding key “restore-"
|
||||||
"shortcuts”."
|
"shortcuts”."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Seznam imen ali razredov virov oken X11, ki lahko sprožijo zajeme v okolju "
|
||||||
|
"Xwayland. Ime oziroma razred vira podanega okna X11 je mogoče pridobiti z "
|
||||||
|
"ukazom »xprop WM_CLASS«. Uporaba pomožnih znakov » * « in » ? « je podprta. "
|
||||||
|
"Vrednosti, ki se začnejo z znakom » ! « so uvrščeni na črni seznam. Ta "
|
||||||
|
"seznam je obravnavan prednostno pred belim seznamom in prekliče zajeme na "
|
||||||
|
"seznamu sistema. Privzeti seznam vključuje ključ: "
|
||||||
|
"»@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@« Uporabniki lahko prekinejo obstoječi "
|
||||||
|
"zajem z uporabo posebne tipkovne bližnjice, določene s tipkovnim ključem "
|
||||||
|
"»restore-shortcuts«."
|
||||||
|
|
||||||
#. TRANSLATORS: This string refers to a button that switches between
|
#. TRANSLATORS: This string refers to a button that switches between
|
||||||
#. * different modes.
|
#. * different modes.
|
||||||
|
@ -14,6 +14,13 @@ stackingdir = $(pkgdatadir)/tests/stacking
|
|||||||
dist_stacking_DATA = \
|
dist_stacking_DATA = \
|
||||||
tests/stacking/basic-x11.metatest \
|
tests/stacking/basic-x11.metatest \
|
||||||
tests/stacking/basic-wayland.metatest \
|
tests/stacking/basic-wayland.metatest \
|
||||||
|
tests/stacking/closed-transient.metatest \
|
||||||
|
tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest \
|
||||||
|
tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest \
|
||||||
|
tests/stacking/closed-transient-no-input-parent.metatest \
|
||||||
|
tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest \
|
||||||
|
tests/stacking/closed-transient-no-input-parents.metatest \
|
||||||
|
tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest \
|
||||||
tests/stacking/minimized.metatest \
|
tests/stacking/minimized.metatest \
|
||||||
tests/stacking/mixed-windows.metatest \
|
tests/stacking/mixed-windows.metatest \
|
||||||
tests/stacking/set-parent.metatest \
|
tests/stacking/set-parent.metatest \
|
||||||
|
@ -153,7 +153,7 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
|
|||||||
backends/meta-pointer-constraint.h \
|
backends/meta-pointer-constraint.h \
|
||||||
backends/meta-settings.c \
|
backends/meta-settings.c \
|
||||||
backends/meta-settings-private.h \
|
backends/meta-settings-private.h \
|
||||||
backends/meta-stage.h \
|
backends/meta-stage-private.h \
|
||||||
backends/meta-stage.c \
|
backends/meta-stage.c \
|
||||||
backends/meta-renderer.c \
|
backends/meta-renderer.c \
|
||||||
backends/meta-renderer.h \
|
backends/meta-renderer.h \
|
||||||
@ -161,6 +161,7 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
|
|||||||
backends/meta-renderer-view.h \
|
backends/meta-renderer-view.h \
|
||||||
backends/edid-parse.c \
|
backends/edid-parse.c \
|
||||||
backends/edid.h \
|
backends/edid.h \
|
||||||
|
backends/gsm-inhibitor-flag.h \
|
||||||
backends/x11/meta-backend-x11.c \
|
backends/x11/meta-backend-x11.c \
|
||||||
backends/x11/meta-backend-x11.h \
|
backends/x11/meta-backend-x11.h \
|
||||||
backends/x11/meta-barrier-x11.c \
|
backends/x11/meta-barrier-x11.c \
|
||||||
@ -183,8 +184,6 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
|
|||||||
backends/x11/nested/meta-cursor-renderer-x11-nested.h \
|
backends/x11/nested/meta-cursor-renderer-x11-nested.h \
|
||||||
backends/x11/nested/meta-renderer-x11-nested.c \
|
backends/x11/nested/meta-renderer-x11-nested.c \
|
||||||
backends/x11/nested/meta-renderer-x11-nested.h \
|
backends/x11/nested/meta-renderer-x11-nested.h \
|
||||||
backends/x11/meta-idle-monitor-xsync.c \
|
|
||||||
backends/x11/meta-idle-monitor-xsync.h \
|
|
||||||
backends/x11/meta-input-settings-x11.c \
|
backends/x11/meta-input-settings-x11.c \
|
||||||
backends/x11/meta-input-settings-x11.h \
|
backends/x11/meta-input-settings-x11.h \
|
||||||
backends/x11/meta-monitor-manager-xrandr.c \
|
backends/x11/meta-monitor-manager-xrandr.c \
|
||||||
@ -247,7 +246,7 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
|
|||||||
compositor/meta-window-actor.c \
|
compositor/meta-window-actor.c \
|
||||||
compositor/meta-window-actor-private.h \
|
compositor/meta-window-actor-private.h \
|
||||||
compositor/meta-window-group.c \
|
compositor/meta-window-group.c \
|
||||||
compositor/meta-window-group.h \
|
compositor/meta-window-group-private.h \
|
||||||
compositor/meta-window-shape.c \
|
compositor/meta-window-shape.c \
|
||||||
compositor/region-utils.c \
|
compositor/region-utils.c \
|
||||||
compositor/region-utils.h \
|
compositor/region-utils.h \
|
||||||
@ -487,8 +486,6 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES += \
|
|||||||
backends/native/meta-default-modes.h \
|
backends/native/meta-default-modes.h \
|
||||||
backends/native/meta-gpu-kms.c \
|
backends/native/meta-gpu-kms.c \
|
||||||
backends/native/meta-gpu-kms.h \
|
backends/native/meta-gpu-kms.h \
|
||||||
backends/native/meta-idle-monitor-native.c \
|
|
||||||
backends/native/meta-idle-monitor-native.h \
|
|
||||||
backends/native/meta-input-settings-native.c \
|
backends/native/meta-input-settings-native.c \
|
||||||
backends/native/meta-input-settings-native.h \
|
backends/native/meta-input-settings-native.h \
|
||||||
backends/native/meta-monitor-manager-kms.c \
|
backends/native/meta-monitor-manager-kms.c \
|
||||||
@ -546,7 +543,9 @@ libmutterinclude_headers = \
|
|||||||
meta/meta-settings.h \
|
meta/meta-settings.h \
|
||||||
meta/meta-shaped-texture.h \
|
meta/meta-shaped-texture.h \
|
||||||
meta/meta-shadow-factory.h \
|
meta/meta-shadow-factory.h \
|
||||||
|
meta/meta-stage.h \
|
||||||
meta/meta-window-actor.h \
|
meta/meta-window-actor.h \
|
||||||
|
meta/meta-window-group.h \
|
||||||
meta/meta-window-shape.h \
|
meta/meta-window-shape.h \
|
||||||
meta/prefs.h \
|
meta/prefs.h \
|
||||||
meta/screen.h \
|
meta/screen.h \
|
||||||
|
36
src/backends/gsm-inhibitor-flag.h
Normal file
36
src/backends/gsm-inhibitor-flag.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GSM_INHIBITOR_FLAG_H__
|
||||||
|
#define __GSM_INHIBITOR_FLAG_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GSM_INHIBITOR_FLAG_LOGOUT = 1 << 0,
|
||||||
|
GSM_INHIBITOR_FLAG_SWITCH_USER = 1 << 1,
|
||||||
|
GSM_INHIBITOR_FLAG_SUSPEND = 1 << 2,
|
||||||
|
GSM_INHIBITOR_FLAG_IDLE = 1 << 3,
|
||||||
|
GSM_INHIBITOR_FLAG_AUTOMOUNT = 1 << 4
|
||||||
|
} GsmInhibitorFlag;
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GSM_INHIBITOR_FLAG_H__ */
|
@ -51,6 +51,14 @@
|
|||||||
#define META_TYPE_BACKEND (meta_backend_get_type ())
|
#define META_TYPE_BACKEND (meta_backend_get_type ())
|
||||||
G_DECLARE_DERIVABLE_TYPE (MetaBackend, meta_backend, META, BACKEND, GObject)
|
G_DECLARE_DERIVABLE_TYPE (MetaBackend, meta_backend, META, BACKEND, GObject)
|
||||||
|
|
||||||
|
typedef enum _MetaSequenceState
|
||||||
|
{
|
||||||
|
META_SEQUENCE_NONE,
|
||||||
|
META_SEQUENCE_ACCEPTED,
|
||||||
|
META_SEQUENCE_REJECTED,
|
||||||
|
META_SEQUENCE_PENDING_END
|
||||||
|
} MetaSequenceState;
|
||||||
|
|
||||||
struct _MetaBackendClass
|
struct _MetaBackendClass
|
||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
@ -59,8 +67,6 @@ struct _MetaBackendClass
|
|||||||
|
|
||||||
void (* post_init) (MetaBackend *backend);
|
void (* post_init) (MetaBackend *backend);
|
||||||
|
|
||||||
MetaIdleMonitor * (* create_idle_monitor) (MetaBackend *backend,
|
|
||||||
int device_id);
|
|
||||||
MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend,
|
MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend,
|
||||||
GError **error);
|
GError **error);
|
||||||
MetaCursorRenderer * (* create_cursor_renderer) (MetaBackend *backend);
|
MetaCursorRenderer * (* create_cursor_renderer) (MetaBackend *backend);
|
||||||
@ -75,6 +81,10 @@ struct _MetaBackendClass
|
|||||||
int device_id,
|
int device_id,
|
||||||
uint32_t timestamp);
|
uint32_t timestamp);
|
||||||
|
|
||||||
|
void (* finish_touch_sequence) (MetaBackend *backend,
|
||||||
|
ClutterEventSequence *sequence,
|
||||||
|
MetaSequenceState state);
|
||||||
|
|
||||||
void (* warp_pointer) (MetaBackend *backend,
|
void (* warp_pointer) (MetaBackend *backend,
|
||||||
int x,
|
int x,
|
||||||
int y);
|
int y);
|
||||||
@ -136,6 +146,10 @@ gboolean meta_backend_ungrab_device (MetaBackend *backend,
|
|||||||
int device_id,
|
int device_id,
|
||||||
uint32_t timestamp);
|
uint32_t timestamp);
|
||||||
|
|
||||||
|
void meta_backend_finish_touch_sequence (MetaBackend *backend,
|
||||||
|
ClutterEventSequence *sequence,
|
||||||
|
MetaSequenceState state);
|
||||||
|
|
||||||
void meta_backend_warp_pointer (MetaBackend *backend,
|
void meta_backend_warp_pointer (MetaBackend *backend,
|
||||||
int x,
|
int x,
|
||||||
int y);
|
int y);
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include "meta-input-settings-private.h"
|
#include "meta-input-settings-private.h"
|
||||||
#include "backends/x11/meta-backend-x11.h"
|
#include "backends/x11/meta-backend-x11.h"
|
||||||
#include "meta-cursor-tracker-private.h"
|
#include "meta-cursor-tracker-private.h"
|
||||||
#include "meta-stage.h"
|
#include "meta-stage-private.h"
|
||||||
|
|
||||||
#ifdef HAVE_REMOTE_DESKTOP
|
#ifdef HAVE_REMOTE_DESKTOP
|
||||||
#include "backends/meta-dbus-session-watcher.h"
|
#include "backends/meta-dbus-session-watcher.h"
|
||||||
@ -110,6 +110,11 @@ struct _MetaBackendPrivate
|
|||||||
|
|
||||||
MetaPointerConstraint *client_pointer_constraint;
|
MetaPointerConstraint *client_pointer_constraint;
|
||||||
MetaDnd *dnd;
|
MetaDnd *dnd;
|
||||||
|
|
||||||
|
UpClient *up_client;
|
||||||
|
guint sleep_signal_id;
|
||||||
|
GCancellable *cancellable;
|
||||||
|
GDBusConnection *system_bus;
|
||||||
};
|
};
|
||||||
typedef struct _MetaBackendPrivate MetaBackendPrivate;
|
typedef struct _MetaBackendPrivate MetaBackendPrivate;
|
||||||
|
|
||||||
@ -136,6 +141,13 @@ meta_backend_finalize (GObject *object)
|
|||||||
g_clear_object (&priv->dbus_session_watcher);
|
g_clear_object (&priv->dbus_session_watcher);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
g_object_unref (priv->up_client);
|
||||||
|
if (priv->sleep_signal_id)
|
||||||
|
g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id);
|
||||||
|
g_cancellable_cancel (priv->cancellable);
|
||||||
|
g_clear_object (&priv->cancellable);
|
||||||
|
g_clear_object (&priv->system_bus);
|
||||||
|
|
||||||
if (priv->device_update_idle_id)
|
if (priv->device_update_idle_id)
|
||||||
g_source_remove (priv->device_update_idle_id);
|
g_source_remove (priv->device_update_idle_id);
|
||||||
|
|
||||||
@ -158,7 +170,7 @@ meta_backend_sync_screen_size (MetaBackend *backend)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
center_pointer (MetaBackend *backend)
|
reset_pointer_position (MetaBackend *backend)
|
||||||
{
|
{
|
||||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||||
MetaMonitorManager *monitor_manager = priv->monitor_manager;
|
MetaMonitorManager *monitor_manager = priv->monitor_manager;
|
||||||
@ -167,9 +179,11 @@ center_pointer (MetaBackend *backend)
|
|||||||
primary =
|
primary =
|
||||||
meta_monitor_manager_get_primary_logical_monitor (monitor_manager);
|
meta_monitor_manager_get_primary_logical_monitor (monitor_manager);
|
||||||
|
|
||||||
|
/* Move the pointer out of the way to avoid hovering over reactive
|
||||||
|
* elements (e.g. users list at login) causing undesired behaviour. */
|
||||||
meta_backend_warp_pointer (backend,
|
meta_backend_warp_pointer (backend,
|
||||||
primary->rect.x + primary->rect.width / 2,
|
primary->rect.x + primary->rect.width * 0.9,
|
||||||
primary->rect.y + primary->rect.height / 2);
|
primary->rect.y + primary->rect.height * 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -192,7 +206,7 @@ meta_backend_monitors_changed (MetaBackend *backend)
|
|||||||
!priv->is_pointer_position_initialized) &&
|
!priv->is_pointer_position_initialized) &&
|
||||||
!meta_monitor_manager_is_headless (monitor_manager))
|
!meta_monitor_manager_is_headless (monitor_manager))
|
||||||
{
|
{
|
||||||
center_pointer (backend);
|
reset_pointer_position (backend);
|
||||||
priv->is_pointer_position_initialized = TRUE;
|
priv->is_pointer_position_initialized = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,7 +236,9 @@ static MetaIdleMonitor *
|
|||||||
meta_backend_create_idle_monitor (MetaBackend *backend,
|
meta_backend_create_idle_monitor (MetaBackend *backend,
|
||||||
int device_id)
|
int device_id)
|
||||||
{
|
{
|
||||||
return META_BACKEND_GET_CLASS (backend)->create_idle_monitor (backend, device_id);
|
return g_object_new (META_TYPE_IDLE_MONITOR,
|
||||||
|
"device-id", device_id,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -465,7 +481,7 @@ meta_backend_real_post_init (MetaBackend *backend)
|
|||||||
|
|
||||||
if (!meta_monitor_manager_is_headless (priv->monitor_manager))
|
if (!meta_monitor_manager_is_headless (priv->monitor_manager))
|
||||||
{
|
{
|
||||||
center_pointer (backend);
|
reset_pointer_position (backend);
|
||||||
priv->is_pointer_position_initialized = TRUE;
|
priv->is_pointer_position_initialized = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -590,6 +606,61 @@ meta_backend_create_renderer (MetaBackend *backend,
|
|||||||
return META_BACKEND_GET_CLASS (backend)->create_renderer (backend, error);
|
return META_BACKEND_GET_CLASS (backend)->create_renderer (backend, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lid_is_closed_changed_cb (UpClient *client,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
if (up_client_get_lid_is_closed (client))
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prepare_for_sleep_cb (GDBusConnection *connection,
|
||||||
|
const gchar *sender_name,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
const gchar *signal_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
gboolean suspending;
|
||||||
|
|
||||||
|
g_variant_get (parameters, "(b)", &suspending);
|
||||||
|
if (suspending)
|
||||||
|
return;
|
||||||
|
meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
system_bus_gotten_cb (GObject *object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaBackendPrivate *priv;
|
||||||
|
GDBusConnection *bus;
|
||||||
|
|
||||||
|
bus = g_bus_get_finish (res, NULL);
|
||||||
|
if (!bus)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv = meta_backend_get_instance_private (user_data);
|
||||||
|
priv->system_bus = bus;
|
||||||
|
priv->sleep_signal_id =
|
||||||
|
g_dbus_connection_signal_subscribe (priv->system_bus,
|
||||||
|
"org.freedesktop.login1",
|
||||||
|
"org.freedesktop.login1.Manager",
|
||||||
|
"PrepareForSleep",
|
||||||
|
"/org/freedesktop/login1",
|
||||||
|
NULL,
|
||||||
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||||
|
prepare_for_sleep_cb,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_backend_initable_init (GInitable *initable,
|
meta_backend_initable_init (GInitable *initable,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
@ -619,6 +690,16 @@ meta_backend_initable_init (GInitable *initable,
|
|||||||
|
|
||||||
priv->dnd = g_object_new (META_TYPE_DND, NULL);
|
priv->dnd = g_object_new (META_TYPE_DND, NULL);
|
||||||
|
|
||||||
|
priv->up_client = up_client_new ();
|
||||||
|
g_signal_connect (priv->up_client, "notify::lid-is-closed",
|
||||||
|
G_CALLBACK (lid_is_closed_changed_cb), NULL);
|
||||||
|
|
||||||
|
priv->cancellable = g_cancellable_new ();
|
||||||
|
g_bus_get (G_BUS_TYPE_SYSTEM,
|
||||||
|
priv->cancellable,
|
||||||
|
system_bus_gotten_cb,
|
||||||
|
backend);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -765,6 +846,20 @@ meta_backend_ungrab_device (MetaBackend *backend,
|
|||||||
return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp);
|
return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_backend_finish_touch_sequence: (skip)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
meta_backend_finish_touch_sequence (MetaBackend *backend,
|
||||||
|
ClutterEventSequence *sequence,
|
||||||
|
MetaSequenceState state)
|
||||||
|
{
|
||||||
|
if (META_BACKEND_GET_CLASS (backend)->finish_touch_sequence)
|
||||||
|
META_BACKEND_GET_CLASS (backend)->finish_touch_sequence (backend,
|
||||||
|
sequence,
|
||||||
|
state);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_backend_warp_pointer: (skip)
|
* meta_backend_warp_pointer: (skip)
|
||||||
*/
|
*/
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#include <cogl/cogl.h>
|
#include <cogl/cogl.h>
|
||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
#include "meta-stage.h"
|
#include "meta-stage-private.h"
|
||||||
|
|
||||||
struct _MetaCursorRendererPrivate
|
struct _MetaCursorRendererPrivate
|
||||||
{
|
{
|
||||||
@ -264,6 +264,18 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
|||||||
update_cursor (renderer, priv->displayed_cursor);
|
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 *
|
MetaCursorSprite *
|
||||||
meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
|
meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
|
||||||
{
|
{
|
||||||
|
@ -62,6 +62,7 @@ void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
|||||||
void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
||||||
float x,
|
float x,
|
||||||
float y);
|
float y);
|
||||||
|
ClutterPoint meta_cursor_renderer_get_position (MetaCursorRenderer *renderer);
|
||||||
void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer);
|
void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer);
|
||||||
|
|
||||||
MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
|
MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "meta-idle-monitor-dbus.h"
|
#include "meta-idle-monitor-dbus.h"
|
||||||
#include <meta/meta-idle-monitor.h>
|
#include <meta/meta-idle-monitor.h>
|
||||||
|
#include <backends/meta-idle-monitor-private.h>
|
||||||
#include "meta-dbus-idle-monitor.h"
|
#include "meta-dbus-idle-monitor.h"
|
||||||
|
|
||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
@ -43,6 +44,26 @@ handle_get_idletime (MetaDBusIdleMonitor *skeleton,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_reset_idletime (MetaDBusIdleMonitor *skeleton,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
MetaIdleMonitor *monitor)
|
||||||
|
{
|
||||||
|
if (!g_getenv ("MUTTER_DEBUG_RESET_IDLETIME"))
|
||||||
|
{
|
||||||
|
g_dbus_method_invocation_return_error_literal (invocation,
|
||||||
|
G_DBUS_ERROR,
|
||||||
|
G_DBUS_ERROR_UNKNOWN_METHOD,
|
||||||
|
"No such method");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta_idle_monitor_reset_idletime (meta_idle_monitor_get_core ());
|
||||||
|
meta_dbus_idle_monitor_complete_reset_idletime (skeleton, invocation);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
MetaDBusIdleMonitor *dbus_monitor;
|
MetaDBusIdleMonitor *dbus_monitor;
|
||||||
MetaIdleMonitor *monitor;
|
MetaIdleMonitor *monitor;
|
||||||
@ -173,6 +194,8 @@ create_monitor_skeleton (GDBusObjectManagerServer *manager,
|
|||||||
G_CALLBACK (handle_add_user_active_watch), monitor, 0);
|
G_CALLBACK (handle_add_user_active_watch), monitor, 0);
|
||||||
g_signal_connect_object (skeleton, "handle-remove-watch",
|
g_signal_connect_object (skeleton, "handle-remove-watch",
|
||||||
G_CALLBACK (handle_remove_watch), monitor, 0);
|
G_CALLBACK (handle_remove_watch), monitor, 0);
|
||||||
|
g_signal_connect_object (skeleton, "handle-reset-idletime",
|
||||||
|
G_CALLBACK (handle_reset_idletime), monitor, 0);
|
||||||
g_signal_connect_object (skeleton, "handle-get-idletime",
|
g_signal_connect_object (skeleton, "handle-get-idletime",
|
||||||
G_CALLBACK (handle_get_idletime), monitor, 0);
|
G_CALLBACK (handle_get_idletime), monitor, 0);
|
||||||
|
|
||||||
|
@ -26,9 +26,6 @@
|
|||||||
#include <meta/meta-idle-monitor.h>
|
#include <meta/meta-idle-monitor.h>
|
||||||
#include "display-private.h"
|
#include "display-private.h"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/extensions/sync.h>
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
MetaIdleMonitor *monitor;
|
MetaIdleMonitor *monitor;
|
||||||
@ -38,28 +35,26 @@ typedef struct
|
|||||||
GDestroyNotify notify;
|
GDestroyNotify notify;
|
||||||
guint64 timeout_msec;
|
guint64 timeout_msec;
|
||||||
int idle_source_id;
|
int idle_source_id;
|
||||||
|
GSource *timeout_source;
|
||||||
} MetaIdleMonitorWatch;
|
} MetaIdleMonitorWatch;
|
||||||
|
|
||||||
struct _MetaIdleMonitor
|
struct _MetaIdleMonitor
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
|
GDBusProxy *session_proxy;
|
||||||
|
gboolean inhibited;
|
||||||
GHashTable *watches;
|
GHashTable *watches;
|
||||||
int device_id;
|
int device_id;
|
||||||
|
guint64 last_event_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaIdleMonitorClass
|
struct _MetaIdleMonitorClass
|
||||||
{
|
{
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
gint64 (*get_idletime) (MetaIdleMonitor *monitor);
|
|
||||||
MetaIdleMonitorWatch * (*make_watch) (MetaIdleMonitor *monitor,
|
|
||||||
guint64 timeout_msec,
|
|
||||||
MetaIdleMonitorWatchFunc callback,
|
|
||||||
gpointer user_data,
|
|
||||||
GDestroyNotify notify);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void _meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch);
|
void _meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch);
|
||||||
|
void meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor);
|
||||||
|
|
||||||
#endif /* META_IDLE_MONITOR_PRIVATE_H */
|
#endif /* META_IDLE_MONITOR_PRIVATE_H */
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <meta/util.h>
|
#include <meta/util.h>
|
||||||
#include <meta/main.h>
|
#include <meta/main.h>
|
||||||
#include <meta/meta-idle-monitor.h>
|
#include <meta/meta-idle-monitor.h>
|
||||||
|
#include "gsm-inhibitor-flag.h"
|
||||||
#include "meta-idle-monitor-private.h"
|
#include "meta-idle-monitor-private.h"
|
||||||
#include "meta-idle-monitor-dbus.h"
|
#include "meta-idle-monitor-dbus.h"
|
||||||
#include "meta-backend-private.h"
|
#include "meta-backend-private.h"
|
||||||
@ -87,6 +88,7 @@ meta_idle_monitor_dispose (GObject *object)
|
|||||||
MetaIdleMonitor *monitor = META_IDLE_MONITOR (object);
|
MetaIdleMonitor *monitor = META_IDLE_MONITOR (object);
|
||||||
|
|
||||||
g_clear_pointer (&monitor->watches, g_hash_table_destroy);
|
g_clear_pointer (&monitor->watches, g_hash_table_destroy);
|
||||||
|
g_clear_object (&monitor->session_proxy);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_idle_monitor_parent_class)->dispose (object);
|
G_OBJECT_CLASS (meta_idle_monitor_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
@ -151,9 +153,121 @@ meta_idle_monitor_class_init (MetaIdleMonitorClass *klass)
|
|||||||
g_object_class_install_property (object_class, PROP_DEVICE_ID, obj_props[PROP_DEVICE_ID]);
|
g_object_class_install_property (object_class, PROP_DEVICE_ID, obj_props[PROP_DEVICE_ID]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_watch (gpointer data)
|
||||||
|
{
|
||||||
|
MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) data;
|
||||||
|
MetaIdleMonitor *monitor = watch->monitor;
|
||||||
|
|
||||||
|
g_object_ref (monitor);
|
||||||
|
|
||||||
|
if (watch->idle_source_id)
|
||||||
|
{
|
||||||
|
g_source_remove (watch->idle_source_id);
|
||||||
|
watch->idle_source_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (watch->notify != NULL)
|
||||||
|
watch->notify (watch->user_data);
|
||||||
|
|
||||||
|
if (watch->timeout_source != NULL)
|
||||||
|
g_source_destroy (watch->timeout_source);
|
||||||
|
|
||||||
|
g_object_unref (monitor);
|
||||||
|
g_slice_free (MetaIdleMonitorWatch, watch);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_inhibited_watch (gpointer key,
|
||||||
|
gpointer value,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaIdleMonitor *monitor = user_data;
|
||||||
|
MetaIdleMonitorWatch *watch = value;
|
||||||
|
|
||||||
|
if (!watch->timeout_source)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (monitor->inhibited)
|
||||||
|
{
|
||||||
|
g_source_set_ready_time (watch->timeout_source, -1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_source_set_ready_time (watch->timeout_source,
|
||||||
|
monitor->last_event_time +
|
||||||
|
watch->timeout_msec * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_inhibited (MetaIdleMonitor *monitor,
|
||||||
|
gboolean inhibited)
|
||||||
|
{
|
||||||
|
if (inhibited == monitor->inhibited)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_hash_table_foreach (monitor->watches,
|
||||||
|
update_inhibited_watch,
|
||||||
|
monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_idle_monitor_inhibited_actions_changed (GDBusProxy *session,
|
||||||
|
GVariant *changed,
|
||||||
|
char **invalidated,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaIdleMonitor *monitor = user_data;
|
||||||
|
GVariant *v;
|
||||||
|
|
||||||
|
v = g_variant_lookup_value (changed, "InhibitedActions", G_VARIANT_TYPE_UINT32);
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
|
gboolean inhibited;
|
||||||
|
|
||||||
|
inhibited = g_variant_get_uint32 (v) & GSM_INHIBITOR_FLAG_IDLE;
|
||||||
|
g_variant_unref (v);
|
||||||
|
|
||||||
|
if (!inhibited)
|
||||||
|
monitor->last_event_time = g_get_monotonic_time ();
|
||||||
|
update_inhibited (monitor, inhibited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_idle_monitor_init (MetaIdleMonitor *monitor)
|
meta_idle_monitor_init (MetaIdleMonitor *monitor)
|
||||||
{
|
{
|
||||||
|
GVariant *v;
|
||||||
|
|
||||||
|
monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch);
|
||||||
|
monitor->last_event_time = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
/* Monitor inhibitors */
|
||||||
|
monitor->session_proxy =
|
||||||
|
g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
|
||||||
|
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
|
||||||
|
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||||
|
NULL,
|
||||||
|
"org.gnome.SessionManager",
|
||||||
|
"/org/gnome/SessionManager",
|
||||||
|
"org.gnome.SessionManager",
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
if (!monitor->session_proxy)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_signal_connect (monitor->session_proxy, "g-properties-changed",
|
||||||
|
G_CALLBACK (meta_idle_monitor_inhibited_actions_changed),
|
||||||
|
monitor);
|
||||||
|
|
||||||
|
v = g_dbus_proxy_get_cached_property (monitor->session_proxy,
|
||||||
|
"InhibitedActions");
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
|
monitor->inhibited = g_variant_get_uint32 (v) & GSM_INHIBITOR_FLAG_IDLE;
|
||||||
|
g_variant_unref (v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,6 +299,36 @@ meta_idle_monitor_get_for_device (int device_id)
|
|||||||
return meta_backend_get_idle_monitor (backend, device_id);
|
return meta_backend_get_idle_monitor (backend, device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static guint32
|
||||||
|
get_next_watch_serial (void)
|
||||||
|
{
|
||||||
|
static guint32 serial = 0;
|
||||||
|
|
||||||
|
g_atomic_int_inc (&serial);
|
||||||
|
|
||||||
|
return serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
idle_monitor_dispatch_timeout (GSource *source,
|
||||||
|
GSourceFunc callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) user_data;
|
||||||
|
|
||||||
|
_meta_idle_monitor_watch_fire (watch);
|
||||||
|
g_source_set_ready_time (watch->timeout_source, -1);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSourceFuncs idle_monitor_source_funcs = {
|
||||||
|
.prepare = NULL,
|
||||||
|
.check = NULL,
|
||||||
|
.dispatch = idle_monitor_dispatch_timeout,
|
||||||
|
.finalize = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
static MetaIdleMonitorWatch *
|
static MetaIdleMonitorWatch *
|
||||||
make_watch (MetaIdleMonitor *monitor,
|
make_watch (MetaIdleMonitor *monitor,
|
||||||
guint64 timeout_msec,
|
guint64 timeout_msec,
|
||||||
@ -194,11 +338,32 @@ make_watch (MetaIdleMonitor *monitor,
|
|||||||
{
|
{
|
||||||
MetaIdleMonitorWatch *watch;
|
MetaIdleMonitorWatch *watch;
|
||||||
|
|
||||||
watch = META_IDLE_MONITOR_GET_CLASS (monitor)->make_watch (monitor,
|
watch = g_slice_new0 (MetaIdleMonitorWatch);
|
||||||
timeout_msec,
|
|
||||||
callback,
|
watch->monitor = monitor;
|
||||||
user_data,
|
watch->id = get_next_watch_serial ();
|
||||||
notify);
|
watch->callback = callback;
|
||||||
|
watch->user_data = user_data;
|
||||||
|
watch->notify = notify;
|
||||||
|
watch->timeout_msec = timeout_msec;
|
||||||
|
|
||||||
|
if (timeout_msec != 0)
|
||||||
|
{
|
||||||
|
GSource *source = g_source_new (&idle_monitor_source_funcs,
|
||||||
|
sizeof (GSource));
|
||||||
|
|
||||||
|
g_source_set_callback (source, NULL, watch, NULL);
|
||||||
|
if (!monitor->inhibited)
|
||||||
|
{
|
||||||
|
g_source_set_ready_time (source,
|
||||||
|
monitor->last_event_time +
|
||||||
|
timeout_msec * 1000);
|
||||||
|
}
|
||||||
|
g_source_attach (source, NULL);
|
||||||
|
g_source_unref (source);
|
||||||
|
|
||||||
|
watch->timeout_source = source;
|
||||||
|
}
|
||||||
|
|
||||||
g_hash_table_insert (monitor->watches,
|
g_hash_table_insert (monitor->watches,
|
||||||
GUINT_TO_POINTER (watch->id),
|
GUINT_TO_POINTER (watch->id),
|
||||||
@ -314,5 +479,39 @@ meta_idle_monitor_remove_watch (MetaIdleMonitor *monitor,
|
|||||||
gint64
|
gint64
|
||||||
meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor)
|
meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor)
|
||||||
{
|
{
|
||||||
return META_IDLE_MONITOR_GET_CLASS (monitor)->get_idletime (monitor);
|
return (g_get_monotonic_time () - monitor->last_event_time) / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_idle_monitor_reset_idletime (MetaIdleMonitor *monitor)
|
||||||
|
{
|
||||||
|
GList *node, *watch_ids;
|
||||||
|
|
||||||
|
monitor->last_event_time = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
watch_ids = g_hash_table_get_keys (monitor->watches);
|
||||||
|
|
||||||
|
for (node = watch_ids; node != NULL; node = node->next)
|
||||||
|
{
|
||||||
|
guint watch_id = GPOINTER_TO_UINT (node->data);
|
||||||
|
MetaIdleMonitorWatch *watch;
|
||||||
|
|
||||||
|
watch = g_hash_table_lookup (monitor->watches,
|
||||||
|
GUINT_TO_POINTER (watch_id));
|
||||||
|
if (!watch)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (watch->timeout_msec == 0)
|
||||||
|
{
|
||||||
|
_meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_source_set_ready_time (watch->timeout_source,
|
||||||
|
monitor->last_event_time +
|
||||||
|
watch->timeout_msec * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (watch_ids);
|
||||||
}
|
}
|
||||||
|
@ -1088,7 +1088,7 @@ meta_input_settings_changed_cb (GSettings *settings,
|
|||||||
update_device_natural_scroll (input_settings, NULL);
|
update_device_natural_scroll (input_settings, NULL);
|
||||||
else if (strcmp (key, "tap-to-click") == 0)
|
else if (strcmp (key, "tap-to-click") == 0)
|
||||||
update_touchpad_tap_enabled (input_settings, NULL);
|
update_touchpad_tap_enabled (input_settings, NULL);
|
||||||
else if (strcmp (key, "tap-and_drag") == 0)
|
else if (strcmp (key, "tap-and-drag") == 0)
|
||||||
update_touchpad_tap_and_drag_enabled (input_settings, NULL);
|
update_touchpad_tap_and_drag_enabled (input_settings, NULL);
|
||||||
else if (strcmp(key, "disable-while-typing") == 0)
|
else if (strcmp(key, "disable-while-typing") == 0)
|
||||||
update_touchpad_disable_while_typing (input_settings, NULL);
|
update_touchpad_disable_while_typing (input_settings, NULL);
|
||||||
|
@ -100,11 +100,12 @@ static MetaMonitorTransform
|
|||||||
derive_monitor_transform (MetaMonitor *monitor)
|
derive_monitor_transform (MetaMonitor *monitor)
|
||||||
{
|
{
|
||||||
MetaOutput *main_output;
|
MetaOutput *main_output;
|
||||||
|
MetaMonitorTransform transform;
|
||||||
|
|
||||||
main_output = meta_monitor_get_main_output (monitor);
|
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,
|
return meta_monitor_crtc_to_logical_transform (monitor, transform);
|
||||||
main_output->crtc->transform);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaLogicalMonitor *
|
MetaLogicalMonitor *
|
||||||
@ -145,7 +146,7 @@ meta_logical_monitor_add_monitor (MetaLogicalMonitor *logical_monitor,
|
|||||||
|
|
||||||
is_presentation = logical_monitor->is_presentation;
|
is_presentation = logical_monitor->is_presentation;
|
||||||
logical_monitor->monitors = g_list_append (logical_monitor->monitors,
|
logical_monitor->monitors = g_list_append (logical_monitor->monitors,
|
||||||
monitor);
|
g_object_ref (monitor));
|
||||||
|
|
||||||
for (l = logical_monitor->monitors; l; l = l->next)
|
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)
|
for (l_output = outputs; l_output; l_output = l_output->next)
|
||||||
{
|
{
|
||||||
MetaOutput *output = l_output->data;
|
MetaOutput *output = l_output->data;
|
||||||
|
MetaCrtc *crtc;
|
||||||
|
|
||||||
is_presentation = is_presentation && output->is_presentation;
|
is_presentation = is_presentation && output->is_presentation;
|
||||||
if (output->crtc)
|
crtc = meta_output_get_assigned_crtc (output);
|
||||||
output->crtc->logical_monitor = logical_monitor;
|
if (crtc)
|
||||||
|
crtc->logical_monitor = logical_monitor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,7 +223,7 @@ foreach_crtc (MetaMonitor *monitor,
|
|||||||
ForeachCrtcData *data = user_data;
|
ForeachCrtcData *data = user_data;
|
||||||
|
|
||||||
data->func (data->logical_monitor,
|
data->func (data->logical_monitor,
|
||||||
monitor_crtc_mode->output->crtc,
|
meta_output_get_assigned_crtc (monitor_crtc_mode->output),
|
||||||
data->user_data);
|
data->user_data);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -254,13 +257,17 @@ meta_logical_monitor_init (MetaLogicalMonitor *logical_monitor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_logical_monitor_finalize (GObject *object)
|
meta_logical_monitor_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
MetaLogicalMonitor *logical_monitor = META_LOGICAL_MONITOR (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
|
static void
|
||||||
@ -268,7 +275,7 @@ meta_logical_monitor_class_init (MetaLogicalMonitorClass *klass)
|
|||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
object_class->finalize = meta_logical_monitor_finalize;
|
object_class->dispose = meta_logical_monitor_dispose;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -330,23 +330,35 @@ MetaMonitorsConfigKey *
|
|||||||
meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager)
|
meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager)
|
||||||
{
|
{
|
||||||
MetaMonitorsConfigKey *config_key;
|
MetaMonitorsConfigKey *config_key;
|
||||||
|
MetaMonitorSpec *laptop_monitor_spec;
|
||||||
GList *l;
|
GList *l;
|
||||||
GList *monitor_specs;
|
GList *monitor_specs;
|
||||||
|
|
||||||
|
laptop_monitor_spec = NULL;
|
||||||
monitor_specs = NULL;
|
monitor_specs = NULL;
|
||||||
for (l = monitor_manager->monitors; l; l = l->next)
|
for (l = monitor_manager->monitors; l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaMonitor *monitor = l->data;
|
MetaMonitor *monitor = l->data;
|
||||||
MetaMonitorSpec *monitor_spec;
|
MetaMonitorSpec *monitor_spec;
|
||||||
|
|
||||||
if (meta_monitor_is_laptop_panel (monitor) &&
|
if (meta_monitor_is_laptop_panel (monitor))
|
||||||
meta_monitor_manager_is_lid_closed (monitor_manager))
|
{
|
||||||
|
laptop_monitor_spec = meta_monitor_get_spec (monitor);
|
||||||
|
|
||||||
|
if (meta_monitor_manager_is_lid_closed (monitor_manager))
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
monitor_spec = meta_monitor_spec_clone (meta_monitor_get_spec (monitor));
|
monitor_spec = meta_monitor_spec_clone (meta_monitor_get_spec (monitor));
|
||||||
monitor_specs = g_list_prepend (monitor_specs, monitor_spec);
|
monitor_specs = g_list_prepend (monitor_specs, monitor_spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!monitor_specs && laptop_monitor_spec)
|
||||||
|
{
|
||||||
|
monitor_specs =
|
||||||
|
g_list_prepend (NULL, meta_monitor_spec_clone (laptop_monitor_spec));
|
||||||
|
}
|
||||||
|
|
||||||
if (!monitor_specs)
|
if (!monitor_specs)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -1007,6 +1019,7 @@ meta_monitor_config_manager_create_for_switch_config (MetaMonitorConfigManager
|
|||||||
MetaMonitorSwitchConfigType config_type)
|
MetaMonitorSwitchConfigType config_type)
|
||||||
{
|
{
|
||||||
MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
|
MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
|
||||||
|
MetaMonitorsConfig *config;
|
||||||
|
|
||||||
if (!meta_monitor_manager_can_switch_config (monitor_manager))
|
if (!meta_monitor_manager_can_switch_config (monitor_manager))
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1014,18 +1027,27 @@ meta_monitor_config_manager_create_for_switch_config (MetaMonitorConfigManager
|
|||||||
switch (config_type)
|
switch (config_type)
|
||||||
{
|
{
|
||||||
case META_MONITOR_SWITCH_CONFIG_ALL_MIRROR:
|
case META_MONITOR_SWITCH_CONFIG_ALL_MIRROR:
|
||||||
return create_for_switch_config_all_mirror (config_manager);
|
config = create_for_switch_config_all_mirror (config_manager);
|
||||||
case META_MONITOR_SWITCH_CONFIG_ALL_LINEAR:
|
|
||||||
return meta_monitor_config_manager_create_linear (config_manager);
|
|
||||||
case META_MONITOR_SWITCH_CONFIG_EXTERNAL:
|
|
||||||
return create_for_switch_config_external (config_manager);
|
|
||||||
case META_MONITOR_SWITCH_CONFIG_BUILTIN:
|
|
||||||
return create_for_switch_config_builtin (config_manager);
|
|
||||||
case META_MONITOR_SWITCH_CONFIG_UNKNOWN:
|
|
||||||
g_warn_if_reached ();
|
|
||||||
break;
|
break;
|
||||||
}
|
case META_MONITOR_SWITCH_CONFIG_ALL_LINEAR:
|
||||||
|
config = meta_monitor_config_manager_create_linear (config_manager);
|
||||||
|
break;
|
||||||
|
case META_MONITOR_SWITCH_CONFIG_EXTERNAL:
|
||||||
|
config = create_for_switch_config_external (config_manager);
|
||||||
|
break;
|
||||||
|
case META_MONITOR_SWITCH_CONFIG_BUILTIN:
|
||||||
|
config = create_for_switch_config_builtin (config_manager);
|
||||||
|
break;
|
||||||
|
case META_MONITOR_SWITCH_CONFIG_UNKNOWN:
|
||||||
|
default:
|
||||||
|
g_warn_if_reached ();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config)
|
||||||
|
meta_monitors_config_set_switch_config (config, config_type);
|
||||||
|
|
||||||
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1217,6 +1239,19 @@ meta_monitors_config_key_equal (gconstpointer data_a,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaMonitorSwitchConfigType
|
||||||
|
meta_monitors_config_get_switch_config (MetaMonitorsConfig *config)
|
||||||
|
{
|
||||||
|
return config->switch_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_monitors_config_set_switch_config (MetaMonitorsConfig *config,
|
||||||
|
MetaMonitorSwitchConfigType switch_config)
|
||||||
|
{
|
||||||
|
config->switch_config = switch_config;
|
||||||
|
}
|
||||||
|
|
||||||
MetaMonitorsConfig *
|
MetaMonitorsConfig *
|
||||||
meta_monitors_config_new_full (GList *logical_monitor_configs,
|
meta_monitors_config_new_full (GList *logical_monitor_configs,
|
||||||
GList *disabled_monitor_specs,
|
GList *disabled_monitor_specs,
|
||||||
@ -1232,6 +1267,7 @@ meta_monitors_config_new_full (GList *logical_monitor_con
|
|||||||
disabled_monitor_specs);
|
disabled_monitor_specs);
|
||||||
config->layout_mode = layout_mode;
|
config->layout_mode = layout_mode;
|
||||||
config->flags = flags;
|
config->flags = flags;
|
||||||
|
config->switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN;
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,8 @@ struct _MetaMonitorsConfig
|
|||||||
MetaMonitorsConfigFlag flags;
|
MetaMonitorsConfigFlag flags;
|
||||||
|
|
||||||
MetaLogicalMonitorLayoutMode layout_mode;
|
MetaLogicalMonitorLayoutMode layout_mode;
|
||||||
|
|
||||||
|
MetaMonitorSwitchConfigType switch_config;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define META_TYPE_MONITORS_CONFIG (meta_monitors_config_get_type ())
|
#define META_TYPE_MONITORS_CONFIG (meta_monitors_config_get_type ())
|
||||||
@ -124,6 +126,11 @@ MetaMonitorsConfig * meta_monitors_config_new (MetaMonitorManager *mon
|
|||||||
MetaLogicalMonitorLayoutMode layout_mode,
|
MetaLogicalMonitorLayoutMode layout_mode,
|
||||||
MetaMonitorsConfigFlag flags);
|
MetaMonitorsConfigFlag flags);
|
||||||
|
|
||||||
|
MetaMonitorSwitchConfigType meta_monitors_config_get_switch_config (MetaMonitorsConfig *config);
|
||||||
|
|
||||||
|
void meta_monitors_config_set_switch_config (MetaMonitorsConfig *config,
|
||||||
|
MetaMonitorSwitchConfigType switch_config);
|
||||||
|
|
||||||
unsigned int meta_monitors_config_key_hash (gconstpointer config_key);
|
unsigned int meta_monitors_config_key_hash (gconstpointer config_key);
|
||||||
|
|
||||||
gboolean meta_monitors_config_key_equal (gconstpointer config_key_a,
|
gboolean meta_monitors_config_key_equal (gconstpointer config_key_a,
|
||||||
|
@ -486,7 +486,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
|||||||
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
|
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
|
||||||
|
|
||||||
output->is_dirty = TRUE;
|
output->is_dirty = TRUE;
|
||||||
output->crtc = crtc;
|
meta_output_assign_crtc (output, crtc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -531,7 +531,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
output->crtc = NULL;
|
meta_output_unassign_crtc (output);
|
||||||
output->is_primary = FALSE;
|
output->is_primary = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,6 +181,7 @@ struct _MetaMonitorManager
|
|||||||
|
|
||||||
GnomePnpIds *pnp_ids;
|
GnomePnpIds *pnp_ids;
|
||||||
UpClient *up_client;
|
UpClient *up_client;
|
||||||
|
gboolean lid_is_closed;
|
||||||
|
|
||||||
gulong experimental_features_changed_handler_id;
|
gulong experimental_features_changed_handler_id;
|
||||||
|
|
||||||
|
@ -89,6 +89,9 @@ static gboolean
|
|||||||
meta_monitor_manager_is_config_complete (MetaMonitorManager *manager,
|
meta_monitor_manager_is_config_complete (MetaMonitorManager *manager,
|
||||||
MetaMonitorsConfig *config);
|
MetaMonitorsConfig *config);
|
||||||
|
|
||||||
|
static MetaMonitor *
|
||||||
|
meta_monitor_manager_get_active_monitor (MetaMonitorManager *manager);
|
||||||
|
|
||||||
MetaBackend *
|
MetaBackend *
|
||||||
meta_monitor_manager_get_backend (MetaMonitorManager *manager)
|
meta_monitor_manager_get_backend (MetaMonitorManager *manager)
|
||||||
{
|
{
|
||||||
@ -198,13 +201,17 @@ calculate_monitor_scale (MetaMonitorManager *manager,
|
|||||||
static float
|
static float
|
||||||
derive_calculated_global_scale (MetaMonitorManager *manager)
|
derive_calculated_global_scale (MetaMonitorManager *manager)
|
||||||
{
|
{
|
||||||
MetaMonitor *primary_monitor;
|
MetaMonitor *monitor = NULL;
|
||||||
|
|
||||||
primary_monitor = meta_monitor_manager_get_primary_monitor (manager);
|
monitor = meta_monitor_manager_get_primary_monitor (manager);
|
||||||
if (!primary_monitor)
|
|
||||||
|
if (!monitor || !meta_monitor_is_active (monitor))
|
||||||
|
monitor = meta_monitor_manager_get_active_monitor (manager);
|
||||||
|
|
||||||
|
if (!monitor)
|
||||||
return 1.0;
|
return 1.0;
|
||||||
|
|
||||||
return calculate_monitor_scale (manager, primary_monitor);
|
return calculate_monitor_scale (manager, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float
|
static float
|
||||||
@ -344,7 +351,13 @@ lid_is_closed_changed (UpClient *client,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaMonitorManager *manager = user_data;
|
MetaMonitorManager *manager = user_data;
|
||||||
|
gboolean lid_is_closed;
|
||||||
|
|
||||||
|
lid_is_closed = up_client_get_lid_is_closed (manager->up_client);
|
||||||
|
if (lid_is_closed == manager->lid_is_closed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
manager->lid_is_closed = lid_is_closed;
|
||||||
meta_monitor_manager_lid_is_closed_changed (manager);
|
meta_monitor_manager_lid_is_closed_changed (manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +367,7 @@ meta_monitor_manager_real_is_lid_closed (MetaMonitorManager *manager)
|
|||||||
if (!manager->up_client)
|
if (!manager->up_client)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return up_client_get_lid_is_closed (manager->up_client);
|
return manager->lid_is_closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -726,8 +739,12 @@ meta_monitor_manager_constructed (GObject *object)
|
|||||||
if (manager_class->is_lid_closed == meta_monitor_manager_real_is_lid_closed)
|
if (manager_class->is_lid_closed == meta_monitor_manager_real_is_lid_closed)
|
||||||
{
|
{
|
||||||
manager->up_client = up_client_new ();
|
manager->up_client = up_client_new ();
|
||||||
|
if (manager->up_client)
|
||||||
|
{
|
||||||
g_signal_connect_object (manager->up_client, "notify::lid-is-closed",
|
g_signal_connect_object (manager->up_client, "notify::lid-is-closed",
|
||||||
G_CALLBACK (lid_is_closed_changed), manager, 0);
|
G_CALLBACK (lid_is_closed_changed), manager, 0);
|
||||||
|
manager->lid_is_closed = up_client_get_lid_is_closed (manager->up_client);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_signal_connect_object (manager, "notify::power-save-mode",
|
g_signal_connect_object (manager, "notify::power-save-mode",
|
||||||
@ -1032,12 +1049,13 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
|||||||
NULL /* properties */);
|
NULL /* properties */);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (l = combined_outputs; l; l = l->next)
|
for (l = combined_outputs, i = 0; l; l = l->next, i++)
|
||||||
{
|
{
|
||||||
MetaOutput *output = l->data;
|
MetaOutput *output = l->data;
|
||||||
GVariantBuilder crtcs, modes, clones, properties;
|
GVariantBuilder crtcs, modes, clones, properties;
|
||||||
GBytes *edid;
|
GBytes *edid;
|
||||||
char *edid_file;
|
char *edid_file;
|
||||||
|
MetaCrtc *crtc;
|
||||||
int crtc_index;
|
int crtc_index;
|
||||||
|
|
||||||
g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
|
g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
|
||||||
@ -1131,8 +1149,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
|||||||
output->tile_info.tile_h));
|
output->tile_info.tile_h));
|
||||||
}
|
}
|
||||||
|
|
||||||
crtc_index = output->crtc ? g_list_index (combined_crtcs, output->crtc)
|
crtc = meta_output_get_assigned_crtc (output);
|
||||||
: -1;
|
crtc_index = crtc ? g_list_index (combined_crtcs, crtc) : -1;
|
||||||
g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
|
g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
|
||||||
i, /* ID */
|
i, /* ID */
|
||||||
(gint64)output->winsys_id,
|
(gint64)output->winsys_id,
|
||||||
@ -1315,9 +1333,13 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
|
|||||||
GVariantBuilder mode_properties_builder;
|
GVariantBuilder mode_properties_builder;
|
||||||
MetaCrtcModeFlag mode_flags;
|
MetaCrtcModeFlag mode_flags;
|
||||||
|
|
||||||
|
if (!meta_monitor_mode_should_be_advertised (monitor_mode))
|
||||||
|
continue;
|
||||||
|
|
||||||
mode_id = meta_monitor_mode_get_id (monitor_mode);
|
mode_id = meta_monitor_mode_get_id (monitor_mode);
|
||||||
meta_monitor_mode_get_resolution (monitor_mode,
|
meta_monitor_mode_get_resolution (monitor_mode,
|
||||||
&mode_width, &mode_height);
|
&mode_width, &mode_height);
|
||||||
|
|
||||||
refresh_rate = meta_monitor_mode_get_refresh_rate (monitor_mode);
|
refresh_rate = meta_monitor_mode_get_refresh_rate (monitor_mode);
|
||||||
|
|
||||||
preferred_scale =
|
preferred_scale =
|
||||||
@ -2382,6 +2404,12 @@ meta_monitor_manager_get_laptop_panel (MetaMonitorManager *manager)
|
|||||||
return find_monitor (manager, meta_monitor_is_laptop_panel);
|
return find_monitor (manager, meta_monitor_is_laptop_panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MetaMonitor *
|
||||||
|
meta_monitor_manager_get_active_monitor (MetaMonitorManager *manager)
|
||||||
|
{
|
||||||
|
return find_monitor (manager, meta_monitor_is_active);
|
||||||
|
}
|
||||||
|
|
||||||
MetaMonitor *
|
MetaMonitor *
|
||||||
meta_monitor_manager_get_monitor_from_connector (MetaMonitorManager *manager,
|
meta_monitor_manager_get_monitor_from_connector (MetaMonitorManager *manager,
|
||||||
const char *connector)
|
const char *connector)
|
||||||
@ -2624,8 +2652,6 @@ meta_monitor_manager_read_current_state (MetaMonitorManager *manager)
|
|||||||
static void
|
static void
|
||||||
meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager)
|
meta_monitor_manager_notify_monitors_changed (MetaMonitorManager *manager)
|
||||||
{
|
{
|
||||||
manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN;
|
|
||||||
|
|
||||||
meta_backend_monitors_changed (manager->backend);
|
meta_backend_monitors_changed (manager->backend);
|
||||||
|
|
||||||
g_signal_emit (manager, signals[MONITORS_CHANGED_INTERNAL], 0);
|
g_signal_emit (manager, signals[MONITORS_CHANGED_INTERNAL], 0);
|
||||||
@ -2682,10 +2708,17 @@ meta_monitor_manager_update_logical_state (MetaMonitorManager *manager,
|
|||||||
MetaMonitorsConfig *config)
|
MetaMonitorsConfig *config)
|
||||||
{
|
{
|
||||||
if (config)
|
if (config)
|
||||||
|
{
|
||||||
manager->layout_mode = config->layout_mode;
|
manager->layout_mode = config->layout_mode;
|
||||||
|
manager->current_switch_config =
|
||||||
|
meta_monitors_config_get_switch_config (config);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
manager->layout_mode =
|
manager->layout_mode =
|
||||||
meta_monitor_manager_get_default_layout_mode (manager);
|
meta_monitor_manager_get_default_layout_mode (manager);
|
||||||
|
manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
meta_monitor_manager_rebuild_logical_monitors (manager, config);
|
meta_monitor_manager_rebuild_logical_monitors (manager, config);
|
||||||
}
|
}
|
||||||
@ -2727,6 +2760,12 @@ void
|
|||||||
meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager,
|
meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager,
|
||||||
MetaMonitorsConfig *config)
|
MetaMonitorsConfig *config)
|
||||||
{
|
{
|
||||||
|
if (config)
|
||||||
|
manager->current_switch_config =
|
||||||
|
meta_monitors_config_get_switch_config (config);
|
||||||
|
else
|
||||||
|
manager->current_switch_config = META_MONITOR_SWITCH_CONFIG_UNKNOWN;
|
||||||
|
|
||||||
manager->layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
manager->layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
||||||
|
|
||||||
meta_monitor_manager_rebuild_logical_monitors_derived (manager, config);
|
meta_monitor_manager_rebuild_logical_monitors_derived (manager, config);
|
||||||
@ -2894,11 +2933,7 @@ meta_monitor_manager_get_monitor_for_connector (MetaMonitorManager *manager,
|
|||||||
|
|
||||||
if (meta_monitor_is_active (monitor) &&
|
if (meta_monitor_is_active (monitor) &&
|
||||||
g_str_equal (connector, meta_monitor_get_connector (monitor)))
|
g_str_equal (connector, meta_monitor_get_connector (monitor)))
|
||||||
{
|
return meta_monitor_get_logical_monitor (monitor)->number;
|
||||||
MetaOutput *main_output = meta_monitor_get_main_output (monitor);
|
|
||||||
|
|
||||||
return main_output->crtc->logical_monitor->number;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -203,11 +203,9 @@ meta_monitor_get_main_output (MetaMonitor *monitor)
|
|||||||
gboolean
|
gboolean
|
||||||
meta_monitor_is_active (MetaMonitor *monitor)
|
meta_monitor_is_active (MetaMonitor *monitor)
|
||||||
{
|
{
|
||||||
MetaOutput *output;
|
MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
|
||||||
|
|
||||||
output = meta_monitor_get_main_output (monitor);
|
return !!priv->current_mode;
|
||||||
|
|
||||||
return output->crtc && output->crtc->current_mode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -385,6 +383,21 @@ meta_monitor_crtc_to_logical_transform (MetaMonitor *monitor,
|
|||||||
return new_transform;
|
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
|
static void
|
||||||
meta_monitor_finalize (GObject *object)
|
meta_monitor_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
@ -393,7 +406,6 @@ meta_monitor_finalize (GObject *object)
|
|||||||
|
|
||||||
g_hash_table_destroy (priv->mode_ids);
|
g_hash_table_destroy (priv->mode_ids);
|
||||||
g_list_free_full (priv->modes, (GDestroyNotify) meta_monitor_mode_free);
|
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);
|
meta_monitor_spec_free (priv->spec);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_monitor_parent_class)->finalize (object);
|
G_OBJECT_CLASS (meta_monitor_parent_class)->finalize (object);
|
||||||
@ -412,6 +424,7 @@ meta_monitor_class_init (MetaMonitorClass *klass)
|
|||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->dispose = meta_monitor_dispose;
|
||||||
object_class->finalize = meta_monitor_finalize;
|
object_class->finalize = meta_monitor_finalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,6 +506,7 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
|
|||||||
for (i = 0; i < output->n_modes; i++)
|
for (i = 0; i < output->n_modes; i++)
|
||||||
{
|
{
|
||||||
MetaCrtcMode *crtc_mode = output->modes[i];
|
MetaCrtcMode *crtc_mode = output->modes[i];
|
||||||
|
MetaCrtc *crtc;
|
||||||
MetaMonitorMode *mode;
|
MetaMonitorMode *mode;
|
||||||
gboolean replace;
|
gboolean replace;
|
||||||
|
|
||||||
@ -526,7 +540,9 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
|
|||||||
|
|
||||||
if (crtc_mode == output->preferred_mode)
|
if (crtc_mode == output->preferred_mode)
|
||||||
monitor_priv->preferred_mode = 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;
|
monitor_priv->current_mode = mode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -545,7 +561,7 @@ meta_monitor_normal_new (MetaGpu *gpu,
|
|||||||
|
|
||||||
monitor_priv->gpu = 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;
|
monitor_priv->winsys_id = output->winsys_id;
|
||||||
meta_monitor_generate_spec (monitor);
|
meta_monitor_generate_spec (monitor);
|
||||||
|
|
||||||
@ -568,13 +584,15 @@ meta_monitor_normal_derive_layout (MetaMonitor *monitor,
|
|||||||
MetaRectangle *layout)
|
MetaRectangle *layout)
|
||||||
{
|
{
|
||||||
MetaOutput *output;
|
MetaOutput *output;
|
||||||
|
MetaCrtc *crtc;
|
||||||
|
|
||||||
output = meta_monitor_get_main_output (monitor);
|
output = meta_monitor_get_main_output (monitor);
|
||||||
|
crtc = meta_output_get_assigned_crtc (output);
|
||||||
*layout = (MetaRectangle) {
|
*layout = (MetaRectangle) {
|
||||||
.x = output->crtc->rect.x,
|
.x = crtc->rect.x,
|
||||||
.y = output->crtc->rect.y,
|
.y = crtc->rect.y,
|
||||||
.width = output->crtc->rect.width,
|
.width = crtc->rect.width,
|
||||||
.height = output->crtc->rect.height
|
.height = crtc->rect.height
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,7 +676,8 @@ add_tiled_monitor_outputs (MetaGpu *gpu,
|
|||||||
g_warn_if_fail (output->subpixel_order ==
|
g_warn_if_fail (output->subpixel_order ==
|
||||||
monitor_tiled->origin_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 +783,13 @@ is_monitor_mode_assigned (MetaMonitor *monitor,
|
|||||||
{
|
{
|
||||||
MetaOutput *output = l->data;
|
MetaOutput *output = l->data;
|
||||||
MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i];
|
MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i];
|
||||||
|
MetaCrtc *crtc;
|
||||||
|
|
||||||
|
crtc = meta_output_get_assigned_crtc (output);
|
||||||
if (monitor_crtc_mode->crtc_mode &&
|
if (monitor_crtc_mode->crtc_mode &&
|
||||||
(!output->crtc ||
|
(!crtc || crtc->current_mode != monitor_crtc_mode->crtc_mode))
|
||||||
output->crtc->current_mode != monitor_crtc_mode->crtc_mode))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
else if (!monitor_crtc_mode->crtc_mode && output->crtc)
|
else if (!monitor_crtc_mode->crtc_mode && crtc)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1217,14 +1237,16 @@ meta_monitor_tiled_derive_layout (MetaMonitor *monitor,
|
|||||||
for (l = monitor_priv->outputs; l; l = l->next)
|
for (l = monitor_priv->outputs; l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaOutput *output = l->data;
|
MetaOutput *output = l->data;
|
||||||
|
MetaCrtc *crtc;
|
||||||
|
|
||||||
if (!output->crtc)
|
crtc = meta_output_get_assigned_crtc (output);
|
||||||
|
if (!crtc)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
min_x = MIN (output->crtc->rect.x, min_x);
|
min_x = MIN (crtc->rect.x, min_x);
|
||||||
min_y = MIN (output->crtc->rect.y, min_y);
|
min_y = MIN (crtc->rect.y, min_y);
|
||||||
max_x = MAX (output->crtc->rect.x + output->crtc->rect.width, max_x);
|
max_x = MAX (crtc->rect.x + crtc->rect.width, max_x);
|
||||||
max_y = MAX (output->crtc->rect.y + output->crtc->rect.height, max_y);
|
max_y = MAX (crtc->rect.y + crtc->rect.height, max_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
*layout = (MetaRectangle) {
|
*layout = (MetaRectangle) {
|
||||||
@ -1318,10 +1340,14 @@ meta_monitor_get_spec (MetaMonitor *monitor)
|
|||||||
MetaLogicalMonitor *
|
MetaLogicalMonitor *
|
||||||
meta_monitor_get_logical_monitor (MetaMonitor *monitor)
|
meta_monitor_get_logical_monitor (MetaMonitor *monitor)
|
||||||
{
|
{
|
||||||
MetaOutput *output = meta_monitor_get_main_output (monitor);
|
MetaOutput *output;
|
||||||
|
MetaCrtc *crtc;
|
||||||
|
|
||||||
if (output->crtc)
|
output = meta_monitor_get_main_output (monitor);
|
||||||
return output->crtc->logical_monitor;
|
crtc = meta_output_get_assigned_crtc (output);
|
||||||
|
|
||||||
|
if (crtc)
|
||||||
|
return crtc->logical_monitor;
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1381,6 +1407,18 @@ meta_monitor_get_current_mode (MetaMonitor *monitor)
|
|||||||
return priv->current_mode;
|
return priv->current_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_current_mode_known (MetaMonitor *monitor)
|
||||||
|
{
|
||||||
|
MetaOutput *output;
|
||||||
|
MetaCrtc *crtc;
|
||||||
|
|
||||||
|
output = meta_monitor_get_main_output (monitor);
|
||||||
|
crtc = meta_output_get_assigned_crtc (output);
|
||||||
|
|
||||||
|
return meta_monitor_is_active (monitor) == (crtc && crtc->current_mode);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_monitor_derive_current_mode (MetaMonitor *monitor)
|
meta_monitor_derive_current_mode (MetaMonitor *monitor)
|
||||||
{
|
{
|
||||||
@ -1400,6 +1438,8 @@ meta_monitor_derive_current_mode (MetaMonitor *monitor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
priv->current_mode = current_mode;
|
priv->current_mode = current_mode;
|
||||||
|
|
||||||
|
g_warn_if_fail (is_current_mode_known (monitor));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1523,6 +1563,22 @@ meta_monitor_calculate_mode_scale (MetaMonitor *monitor,
|
|||||||
return calculate_scale (monitor, monitor_mode);
|
return calculate_scale (monitor, monitor_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_logical_size_large_enough (gint width, gint height)
|
||||||
|
{
|
||||||
|
return width >= MINIMUM_LOGICAL_WIDTH &&
|
||||||
|
height >= MINIMUM_LOGICAL_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_monitor_mode_should_be_advertised (MetaMonitorMode *monitor_mode)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (monitor_mode != NULL, FALSE);
|
||||||
|
|
||||||
|
return is_logical_size_large_enough (monitor_mode->spec.width,
|
||||||
|
monitor_mode->spec.height);
|
||||||
|
}
|
||||||
|
|
||||||
static float
|
static float
|
||||||
get_closest_scale_factor_for_resolution (float width,
|
get_closest_scale_factor_for_resolution (float width,
|
||||||
float height,
|
float height,
|
||||||
@ -1543,8 +1599,7 @@ get_closest_scale_factor_for_resolution (float width,
|
|||||||
|
|
||||||
if (scale < MINIMUM_SCALE_FACTOR ||
|
if (scale < MINIMUM_SCALE_FACTOR ||
|
||||||
scale > MAXIMUM_SCALE_FACTOR ||
|
scale > MAXIMUM_SCALE_FACTOR ||
|
||||||
floorf (scaled_w) < MINIMUM_LOGICAL_WIDTH ||
|
!is_logical_size_large_enough (floorf (scaled_w), floorf (scaled_h)))
|
||||||
floorf (scaled_h) < MINIMUM_LOGICAL_HEIGHT)
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (floorf (scaled_w) == scaled_w && floorf (scaled_h) == scaled_h)
|
if (floorf (scaled_w) == scaled_w && floorf (scaled_h) == scaled_h)
|
||||||
|
@ -219,6 +219,8 @@ gboolean meta_monitor_mode_foreach_output (MetaMonitor *monitor,
|
|||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
gboolean meta_monitor_mode_should_be_advertised (MetaMonitorMode *monitor_mode);
|
||||||
|
|
||||||
MetaMonitorSpec * meta_monitor_spec_clone (MetaMonitorSpec *monitor_id);
|
MetaMonitorSpec * meta_monitor_spec_clone (MetaMonitorSpec *monitor_id);
|
||||||
|
|
||||||
gboolean meta_monitor_spec_equals (MetaMonitorSpec *monitor_id,
|
gboolean meta_monitor_spec_equals (MetaMonitorSpec *monitor_id,
|
||||||
|
@ -21,7 +21,13 @@
|
|||||||
|
|
||||||
#include "backends/meta-output.h"
|
#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 *
|
MetaGpu *
|
||||||
meta_output_get_gpu (MetaOutput *output)
|
meta_output_get_gpu (MetaOutput *output)
|
||||||
@ -29,6 +35,44 @@ meta_output_get_gpu (MetaOutput *output)
|
|||||||
return output->gpu;
|
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
|
static void
|
||||||
meta_output_finalize (GObject *object)
|
meta_output_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
@ -58,5 +102,6 @@ meta_output_class_init (MetaOutputClass *klass)
|
|||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->dispose = meta_output_dispose;
|
||||||
object_class->finalize = meta_output_finalize;
|
object_class->finalize = meta_output_finalize;
|
||||||
}
|
}
|
||||||
|
@ -64,9 +64,6 @@ struct _MetaOutput
|
|||||||
|
|
||||||
MetaGpu *gpu;
|
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 */
|
/* The low-level ID of this output, used to apply back configuration */
|
||||||
glong winsys_id;
|
glong winsys_id;
|
||||||
char *name;
|
char *name;
|
||||||
@ -122,4 +119,11 @@ G_DECLARE_FINAL_TYPE (MetaOutput, meta_output, META, OUTPUT, GObject)
|
|||||||
|
|
||||||
MetaGpu * meta_output_get_gpu (MetaOutput *output);
|
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 */
|
#endif /* META_OUTPUT_H */
|
||||||
|
@ -153,6 +153,11 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
buffer = pw_stream_peek_buffer (priv->pipewire_stream, buffer_id);
|
buffer = pw_stream_peek_buffer (priv->pipewire_stream, buffer_id);
|
||||||
|
if (!buffer)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to peek at PipeWire buffer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (buffer->datas[0].type == priv->pipewire_type->data.MemFd)
|
if (buffer->datas[0].type == priv->pipewire_type->data.MemFd)
|
||||||
{
|
{
|
||||||
@ -327,10 +332,18 @@ create_pipewire_stream (MetaScreenCastStreamSrc *src,
|
|||||||
struct spa_fraction max_framerate;
|
struct spa_fraction max_framerate;
|
||||||
struct spa_fraction min_framerate;
|
struct spa_fraction min_framerate;
|
||||||
const struct spa_pod *params[1];
|
const struct spa_pod *params[1];
|
||||||
|
int result;
|
||||||
|
|
||||||
pipewire_stream = pw_stream_new (priv->pipewire_remote,
|
pipewire_stream = pw_stream_new (priv->pipewire_remote,
|
||||||
"meta-screen-cast-src",
|
"meta-screen-cast-src",
|
||||||
NULL);
|
NULL);
|
||||||
|
if (!pipewire_stream)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Failed to create PipeWire stream: %s",
|
||||||
|
strerror (errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
meta_screen_cast_stream_src_get_specs (src, &width, &height, &frame_rate);
|
meta_screen_cast_stream_src_get_specs (src, &width, &height, &frame_rate);
|
||||||
frame_rate_fraction = meta_fraction_from_double (frame_rate);
|
frame_rate_fraction = meta_fraction_from_double (frame_rate);
|
||||||
@ -347,7 +360,7 @@ create_pipewire_stream (MetaScreenCastStreamSrc *src,
|
|||||||
":", spa_type->format_video.format, "I", spa_type->video_format.BGRx,
|
":", 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.size, "R", &SPA_RECTANGLE (width, height),
|
||||||
":", spa_type->format_video.framerate, "F", &SPA_FRACTION (0, 1),
|
":", spa_type->format_video.framerate, "F", &SPA_FRACTION (0, 1),
|
||||||
":", spa_type->format_video.max_framerate, "Fr", &max_framerate,
|
":", spa_type->format_video.max_framerate, "Fru", &max_framerate,
|
||||||
PROP_RANGE (&min_framerate,
|
PROP_RANGE (&min_framerate,
|
||||||
&max_framerate));
|
&max_framerate));
|
||||||
|
|
||||||
@ -356,14 +369,15 @@ create_pipewire_stream (MetaScreenCastStreamSrc *src,
|
|||||||
&stream_events,
|
&stream_events,
|
||||||
src);
|
src);
|
||||||
|
|
||||||
if (pw_stream_connect (pipewire_stream,
|
result = pw_stream_connect (pipewire_stream,
|
||||||
PW_DIRECTION_OUTPUT,
|
PW_DIRECTION_OUTPUT,
|
||||||
NULL,
|
NULL,
|
||||||
PW_STREAM_FLAG_NONE,
|
PW_STREAM_FLAG_NONE,
|
||||||
params, G_N_ELEMENTS (¶ms)) != 0)
|
params, G_N_ELEMENTS (params));
|
||||||
|
if (result != 0)
|
||||||
{
|
{
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
"Could not connect");
|
"Could not connect: %s", spa_strerror (result));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,6 +480,12 @@ create_pipewire_source (void)
|
|||||||
(MetaPipeWireSource *) g_source_new (&pipewire_source_funcs,
|
(MetaPipeWireSource *) g_source_new (&pipewire_source_funcs,
|
||||||
sizeof (MetaPipeWireSource));
|
sizeof (MetaPipeWireSource));
|
||||||
pipewire_source->pipewire_loop = pw_loop_new (NULL);
|
pipewire_source->pipewire_loop = pw_loop_new (NULL);
|
||||||
|
if (!pipewire_source->pipewire_loop)
|
||||||
|
{
|
||||||
|
g_source_destroy ((GSource *) pipewire_source);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
g_source_add_unix_fd (&pipewire_source->base,
|
g_source_add_unix_fd (&pipewire_source->base,
|
||||||
pw_loop_get_fd (pipewire_source->pipewire_loop),
|
pw_loop_get_fd (pipewire_source->pipewire_loop),
|
||||||
G_IO_IN | G_IO_ERR);
|
G_IO_IN | G_IO_ERR);
|
||||||
@ -491,6 +511,13 @@ meta_screen_cast_stream_src_initable_init (GInitable *initable,
|
|||||||
meta_screen_cast_stream_src_get_instance_private (src);
|
meta_screen_cast_stream_src_get_instance_private (src);
|
||||||
|
|
||||||
priv->pipewire_source = create_pipewire_source ();
|
priv->pipewire_source = create_pipewire_source ();
|
||||||
|
if (!priv->pipewire_source)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Failed to create PipeWire source");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
priv->pipewire_core = pw_core_new (priv->pipewire_source->pipewire_loop,
|
priv->pipewire_core = pw_core_new (priv->pipewire_source->pipewire_loop,
|
||||||
NULL);
|
NULL);
|
||||||
if (!priv->pipewire_core)
|
if (!priv->pipewire_core)
|
||||||
|
@ -33,6 +33,7 @@ typedef enum _MetaExperimentalFeature
|
|||||||
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
|
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
|
||||||
META_EXPERIMENTAL_FEATURE_SCREEN_CAST = (1 << 1),
|
META_EXPERIMENTAL_FEATURE_SCREEN_CAST = (1 << 1),
|
||||||
META_EXPERIMENTAL_FEATURE_REMOTE_DESKTOP = (1 << 2),
|
META_EXPERIMENTAL_FEATURE_REMOTE_DESKTOP = (1 << 2),
|
||||||
|
META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS = (1 << 3),
|
||||||
} MetaExperimentalFeature;
|
} MetaExperimentalFeature;
|
||||||
|
|
||||||
#define META_TYPE_SETTINGS (meta_settings_get_type ())
|
#define META_TYPE_SETTINGS (meta_settings_get_type ())
|
||||||
|
@ -267,6 +267,8 @@ experimental_features_handler (GVariant *features_variant,
|
|||||||
features |= META_EXPERIMENTAL_FEATURE_SCREEN_CAST;
|
features |= META_EXPERIMENTAL_FEATURE_SCREEN_CAST;
|
||||||
else if (g_str_equal (feature, "remote-desktop"))
|
else if (g_str_equal (feature, "remote-desktop"))
|
||||||
features |= META_EXPERIMENTAL_FEATURE_REMOTE_DESKTOP;
|
features |= META_EXPERIMENTAL_FEATURE_REMOTE_DESKTOP;
|
||||||
|
else if (g_str_equal (feature, "kms-modifiers"))
|
||||||
|
features |= META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS;
|
||||||
else
|
else
|
||||||
g_info ("Unknown experimental feature '%s'\n", feature);
|
g_info ("Unknown experimental feature '%s'\n", feature);
|
||||||
}
|
}
|
||||||
|
@ -17,39 +17,23 @@
|
|||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef META_STAGE_H
|
#ifndef META_STAGE_PRIVATE_H
|
||||||
#define META_STAGE_H
|
#define META_STAGE_PRIVATE_H
|
||||||
|
|
||||||
#include <clutter/clutter.h>
|
#include <meta/meta-stage.h>
|
||||||
|
|
||||||
#include "meta-cursor.h"
|
#include "meta-cursor.h"
|
||||||
#include <meta/boxes.h>
|
#include <meta/boxes.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define META_TYPE_STAGE (meta_stage_get_type ())
|
|
||||||
#define META_STAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_STAGE, MetaStage))
|
|
||||||
#define META_STAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_STAGE, MetaStageClass))
|
|
||||||
#define META_IS_STAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_STAGE))
|
|
||||||
#define META_IS_STAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_STAGE))
|
|
||||||
#define META_STAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_STAGE, MetaStageClass))
|
|
||||||
|
|
||||||
typedef struct _MetaStage MetaStage;
|
|
||||||
typedef struct _MetaStageClass MetaStageClass;
|
|
||||||
typedef struct _MetaOverlay MetaOverlay;
|
typedef struct _MetaOverlay MetaOverlay;
|
||||||
|
|
||||||
struct _MetaStageClass
|
|
||||||
{
|
|
||||||
ClutterStageClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _MetaStage
|
struct _MetaStage
|
||||||
{
|
{
|
||||||
ClutterStage parent;
|
ClutterStage parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType meta_stage_get_type (void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
ClutterActor *meta_stage_new (void);
|
ClutterActor *meta_stage_new (void);
|
||||||
|
|
||||||
MetaOverlay *meta_stage_create_cursor_overlay (MetaStage *stage);
|
MetaOverlay *meta_stage_create_cursor_overlay (MetaStage *stage);
|
||||||
@ -68,4 +52,4 @@ void meta_stage_update_view_layout (MetaStage *stage);
|
|||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* META_STAGE_H */
|
#endif /* META_STAGE_PRIVATE_H */
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include "meta-stage.h"
|
#include "meta-stage-private.h"
|
||||||
|
|
||||||
#include <meta/meta-backend.h>
|
#include <meta/meta-backend.h>
|
||||||
#include <meta/meta-monitor-manager.h>
|
#include <meta/meta-monitor-manager.h>
|
||||||
|
@ -35,15 +35,15 @@
|
|||||||
#include "clutter/evdev/clutter-evdev.h"
|
#include "clutter/evdev/clutter-evdev.h"
|
||||||
#include "meta-barrier-native.h"
|
#include "meta-barrier-native.h"
|
||||||
#include "meta-border.h"
|
#include "meta-border.h"
|
||||||
#include "meta-idle-monitor-native.h"
|
|
||||||
#include "meta-monitor-manager-kms.h"
|
#include "meta-monitor-manager-kms.h"
|
||||||
#include "meta-cursor-renderer-native.h"
|
#include "meta-cursor-renderer-native.h"
|
||||||
#include "meta-launcher.h"
|
#include "meta-launcher.h"
|
||||||
#include "backends/meta-cursor-tracker-private.h"
|
#include "backends/meta-cursor-tracker-private.h"
|
||||||
|
#include "backends/meta-idle-monitor-private.h"
|
||||||
#include "backends/meta-logical-monitor.h"
|
#include "backends/meta-logical-monitor.h"
|
||||||
#include "backends/meta-monitor-manager-private.h"
|
#include "backends/meta-monitor-manager-private.h"
|
||||||
#include "backends/meta-pointer-constraint.h"
|
#include "backends/meta-pointer-constraint.h"
|
||||||
#include "backends/meta-stage.h"
|
#include "backends/meta-stage-private.h"
|
||||||
#include "backends/native/meta-clutter-backend-native.h"
|
#include "backends/native/meta-clutter-backend-native.h"
|
||||||
#include "backends/native/meta-input-settings-native.h"
|
#include "backends/native/meta-input-settings-native.h"
|
||||||
#include "backends/native/meta-renderer-native.h"
|
#include "backends/native/meta-renderer-native.h"
|
||||||
@ -60,10 +60,6 @@ struct _MetaBackendNativePrivate
|
|||||||
{
|
{
|
||||||
MetaLauncher *launcher;
|
MetaLauncher *launcher;
|
||||||
MetaBarrierManagerNative *barrier_manager;
|
MetaBarrierManagerNative *barrier_manager;
|
||||||
UpClient *up_client;
|
|
||||||
guint sleep_signal_id;
|
|
||||||
GCancellable *cancellable;
|
|
||||||
GDBusConnection *system_bus;
|
|
||||||
};
|
};
|
||||||
typedef struct _MetaBackendNativePrivate MetaBackendNativePrivate;
|
typedef struct _MetaBackendNativePrivate MetaBackendNativePrivate;
|
||||||
|
|
||||||
@ -85,69 +81,9 @@ meta_backend_native_finalize (GObject *object)
|
|||||||
|
|
||||||
meta_launcher_free (priv->launcher);
|
meta_launcher_free (priv->launcher);
|
||||||
|
|
||||||
g_object_unref (priv->up_client);
|
|
||||||
if (priv->sleep_signal_id)
|
|
||||||
g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id);
|
|
||||||
g_cancellable_cancel (priv->cancellable);
|
|
||||||
g_clear_object (&priv->cancellable);
|
|
||||||
g_clear_object (&priv->system_bus);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object);
|
G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
prepare_for_sleep_cb (GDBusConnection *connection,
|
|
||||||
const gchar *sender_name,
|
|
||||||
const gchar *object_path,
|
|
||||||
const gchar *interface_name,
|
|
||||||
const gchar *signal_name,
|
|
||||||
GVariant *parameters,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
gboolean suspending;
|
|
||||||
g_variant_get (parameters, "(b)", &suspending);
|
|
||||||
if (suspending)
|
|
||||||
return;
|
|
||||||
meta_idle_monitor_native_reset_idletime (meta_idle_monitor_get_core ());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
system_bus_gotten_cb (GObject *object,
|
|
||||||
GAsyncResult *res,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
MetaBackendNativePrivate *priv;
|
|
||||||
GDBusConnection *bus;
|
|
||||||
|
|
||||||
bus = g_bus_get_finish (res, NULL);
|
|
||||||
if (!bus)
|
|
||||||
return;
|
|
||||||
|
|
||||||
priv = meta_backend_native_get_instance_private (META_BACKEND_NATIVE (user_data));
|
|
||||||
priv->system_bus = bus;
|
|
||||||
priv->sleep_signal_id = g_dbus_connection_signal_subscribe (priv->system_bus,
|
|
||||||
"org.freedesktop.login1",
|
|
||||||
"org.freedesktop.login1.Manager",
|
|
||||||
"PrepareForSleep",
|
|
||||||
"/org/freedesktop/login1",
|
|
||||||
NULL,
|
|
||||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
|
||||||
prepare_for_sleep_cb,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
lid_is_closed_changed_cb (UpClient *client,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
if (up_client_get_lid_is_closed (client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
meta_idle_monitor_native_reset_idletime (meta_idle_monitor_get_core ());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
constrain_to_barriers (ClutterInputDevice *device,
|
constrain_to_barriers (ClutterInputDevice *device,
|
||||||
guint32 time,
|
guint32 time,
|
||||||
@ -398,15 +334,6 @@ meta_backend_native_post_init (MetaBackend *backend)
|
|||||||
meta_backend_get_monitor_manager (backend));
|
meta_backend_get_monitor_manager (backend));
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaIdleMonitor *
|
|
||||||
meta_backend_native_create_idle_monitor (MetaBackend *backend,
|
|
||||||
int device_id)
|
|
||||||
{
|
|
||||||
return g_object_new (META_TYPE_IDLE_MONITOR_NATIVE,
|
|
||||||
"device-id", device_id,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static MetaMonitorManager *
|
static MetaMonitorManager *
|
||||||
meta_backend_native_create_monitor_manager (MetaBackend *backend,
|
meta_backend_native_create_monitor_manager (MetaBackend *backend,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -604,7 +531,6 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
|||||||
|
|
||||||
backend_class->post_init = meta_backend_native_post_init;
|
backend_class->post_init = meta_backend_native_post_init;
|
||||||
|
|
||||||
backend_class->create_idle_monitor = meta_backend_native_create_idle_monitor;
|
|
||||||
backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager;
|
backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager;
|
||||||
backend_class->create_cursor_renderer = meta_backend_native_create_cursor_renderer;
|
backend_class->create_cursor_renderer = meta_backend_native_create_cursor_renderer;
|
||||||
backend_class->create_renderer = meta_backend_native_create_renderer;
|
backend_class->create_renderer = meta_backend_native_create_renderer;
|
||||||
@ -637,16 +563,6 @@ meta_backend_native_init (MetaBackendNative *native)
|
|||||||
}
|
}
|
||||||
|
|
||||||
priv->barrier_manager = meta_barrier_manager_native_new ();
|
priv->barrier_manager = meta_barrier_manager_native_new ();
|
||||||
|
|
||||||
priv->up_client = up_client_new ();
|
|
||||||
g_signal_connect (priv->up_client, "notify::lid-is-closed",
|
|
||||||
G_CALLBACK (lid_is_closed_changed_cb), NULL);
|
|
||||||
|
|
||||||
priv->cancellable = g_cancellable_new ();
|
|
||||||
g_bus_get (G_BUS_TYPE_SYSTEM,
|
|
||||||
priv->cancellable,
|
|
||||||
system_bus_gotten_cb,
|
|
||||||
native);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaLauncher *
|
MetaLauncher *
|
||||||
@ -747,5 +663,5 @@ void meta_backend_native_resume (MetaBackendNative *native)
|
|||||||
meta_cursor_renderer_native_force_update (cursor_renderer_native);
|
meta_cursor_renderer_native_force_update (cursor_renderer_native);
|
||||||
|
|
||||||
idle_monitor = meta_backend_get_idle_monitor (backend, 0);
|
idle_monitor = meta_backend_get_idle_monitor (backend, 0);
|
||||||
meta_idle_monitor_native_reset_idletime (idle_monitor);
|
meta_idle_monitor_reset_idletime (idle_monitor);
|
||||||
}
|
}
|
||||||
|
@ -291,9 +291,12 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
|||||||
data->in_cursor_renderer_native;
|
data->in_cursor_renderer_native;
|
||||||
MetaCursorRendererNativePrivate *priv =
|
MetaCursorRendererNativePrivate *priv =
|
||||||
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
|
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
|
||||||
|
MetaCrtc *crtc;
|
||||||
|
MetaMonitorTransform transform;
|
||||||
ClutterRect scaled_crtc_rect;
|
ClutterRect scaled_crtc_rect;
|
||||||
float scale;
|
float scale;
|
||||||
int crtc_x, crtc_y;
|
int crtc_x, crtc_y;
|
||||||
|
int crtc_width, crtc_height;
|
||||||
|
|
||||||
if (meta_is_stage_views_scaled ())
|
if (meta_is_stage_views_scaled ())
|
||||||
scale = meta_logical_monitor_get_scale (data->in_logical_monitor);
|
scale = meta_logical_monitor_get_scale (data->in_logical_monitor);
|
||||||
@ -305,17 +308,31 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
|||||||
META_MONITOR_TRANSFORM_NORMAL,
|
META_MONITOR_TRANSFORM_NORMAL,
|
||||||
&crtc_x, &crtc_y);
|
&crtc_x, &crtc_y);
|
||||||
|
|
||||||
|
transform = meta_logical_monitor_get_transform (data->in_logical_monitor);
|
||||||
|
if (meta_monitor_transform_is_rotated (transform))
|
||||||
|
{
|
||||||
|
crtc_width = monitor_crtc_mode->crtc_mode->height;
|
||||||
|
crtc_height = monitor_crtc_mode->crtc_mode->width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
crtc_width = monitor_crtc_mode->crtc_mode->width;
|
||||||
|
crtc_height = monitor_crtc_mode->crtc_mode->height;
|
||||||
|
}
|
||||||
|
|
||||||
scaled_crtc_rect = (ClutterRect) {
|
scaled_crtc_rect = (ClutterRect) {
|
||||||
.origin = {
|
.origin = {
|
||||||
.x = crtc_x / scale,
|
.x = crtc_x / scale,
|
||||||
.y = crtc_y / scale
|
.y = crtc_y / scale
|
||||||
},
|
},
|
||||||
.size = {
|
.size = {
|
||||||
.width = monitor_crtc_mode->crtc_mode->width / scale,
|
.width = crtc_width / scale,
|
||||||
.height = monitor_crtc_mode->crtc_mode->height / scale
|
.height = crtc_height / scale
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
crtc = meta_output_get_assigned_crtc (monitor_crtc_mode->output);
|
||||||
|
|
||||||
if (priv->has_hw_cursor &&
|
if (priv->has_hw_cursor &&
|
||||||
clutter_rect_intersection (&scaled_crtc_rect,
|
clutter_rect_intersection (&scaled_crtc_rect,
|
||||||
&data->in_local_cursor_rect,
|
&data->in_local_cursor_rect,
|
||||||
@ -326,7 +343,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
|||||||
float crtc_cursor_x, crtc_cursor_y;
|
float crtc_cursor_x, crtc_cursor_y;
|
||||||
|
|
||||||
set_crtc_cursor (data->in_cursor_renderer_native,
|
set_crtc_cursor (data->in_cursor_renderer_native,
|
||||||
monitor_crtc_mode->output->crtc,
|
crtc,
|
||||||
data->in_cursor_sprite);
|
data->in_cursor_sprite);
|
||||||
|
|
||||||
gpu_kms = META_GPU_KMS (meta_monitor_get_gpu (monitor));
|
gpu_kms = META_GPU_KMS (meta_monitor_get_gpu (monitor));
|
||||||
@ -336,7 +353,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
|||||||
crtc_cursor_y = (data->in_local_cursor_rect.origin.y -
|
crtc_cursor_y = (data->in_local_cursor_rect.origin.y -
|
||||||
scaled_crtc_rect.origin.y) * scale;
|
scaled_crtc_rect.origin.y) * scale;
|
||||||
drmModeMoveCursor (kms_fd,
|
drmModeMoveCursor (kms_fd,
|
||||||
monitor_crtc_mode->output->crtc->crtc_id,
|
crtc->crtc_id,
|
||||||
roundf (crtc_cursor_x),
|
roundf (crtc_cursor_x),
|
||||||
roundf (crtc_cursor_y));
|
roundf (crtc_cursor_y));
|
||||||
|
|
||||||
@ -344,8 +361,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
set_crtc_cursor (data->in_cursor_renderer_native,
|
set_crtc_cursor (data->in_cursor_renderer_native, crtc, NULL);
|
||||||
monitor_crtc_mode->output->crtc, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -694,6 +710,7 @@ static void
|
|||||||
cursor_priv_free (MetaCursorNativePrivate *cursor_priv)
|
cursor_priv_free (MetaCursorNativePrivate *cursor_priv)
|
||||||
{
|
{
|
||||||
g_hash_table_destroy (cursor_priv->gpu_states);
|
g_hash_table_destroy (cursor_priv->gpu_states);
|
||||||
|
g_free (cursor_priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaCursorNativePrivate *
|
static MetaCursorNativePrivate *
|
||||||
|
@ -47,6 +47,12 @@ typedef struct _MetaKmsSource
|
|||||||
MetaGpuKms *gpu_kms;
|
MetaGpuKms *gpu_kms;
|
||||||
} MetaKmsSource;
|
} MetaKmsSource;
|
||||||
|
|
||||||
|
typedef struct _MetaGpuKmsFlipClosureContainer
|
||||||
|
{
|
||||||
|
GClosure *flip_closure;
|
||||||
|
MetaGpuKms *gpu_kms;
|
||||||
|
} MetaGpuKmsFlipClosureContainer;
|
||||||
|
|
||||||
struct _MetaGpuKms
|
struct _MetaGpuKms
|
||||||
{
|
{
|
||||||
MetaGpu parent;
|
MetaGpu parent;
|
||||||
@ -62,8 +68,11 @@ struct _MetaGpuKms
|
|||||||
int max_buffer_height;
|
int max_buffer_height;
|
||||||
|
|
||||||
gboolean page_flips_not_supported;
|
gboolean page_flips_not_supported;
|
||||||
|
|
||||||
|
gboolean resources_init_failed_before;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
G_DEFINE_QUARK (MetaGpuKmsError, meta_gpu_kms_error)
|
||||||
G_DEFINE_TYPE (MetaGpuKms, meta_gpu_kms, META_TYPE_GPU)
|
G_DEFINE_TYPE (MetaGpuKms, meta_gpu_kms, META_TYPE_GPU)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -104,8 +113,10 @@ get_crtc_drm_connectors (MetaGpu *gpu,
|
|||||||
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
|
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaOutput *output = l->data;
|
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);
|
g_array_append_val (connectors_array, output->winsys_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +151,10 @@ meta_gpu_kms_apply_crtc_mode (MetaGpuKms *gpu_kms,
|
|||||||
connectors, n_connectors,
|
connectors, n_connectors,
|
||||||
mode) != 0)
|
mode) != 0)
|
||||||
{
|
{
|
||||||
|
if (mode)
|
||||||
g_warning ("Failed to set CRTC mode %s: %m", crtc->current_mode->name);
|
g_warning ("Failed to set CRTC mode %s: %m", crtc->current_mode->name);
|
||||||
|
else
|
||||||
|
g_warning ("Failed to disable CRTC");
|
||||||
g_free (connectors);
|
g_free (connectors);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -185,8 +199,10 @@ meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
|
|||||||
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
|
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaOutput *output = l->data;
|
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;
|
connected_crtc_found = TRUE;
|
||||||
break;
|
break;
|
||||||
@ -199,11 +215,26 @@ meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _GpuClosureContainer
|
MetaGpuKmsFlipClosureContainer *
|
||||||
|
meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms,
|
||||||
|
GClosure *flip_closure)
|
||||||
{
|
{
|
||||||
GClosure *flip_closure;
|
MetaGpuKmsFlipClosureContainer *closure_container;
|
||||||
MetaGpuKms *gpu_kms;
|
|
||||||
} GpuClosureContainer;
|
closure_container = g_new0 (MetaGpuKmsFlipClosureContainer, 1);
|
||||||
|
*closure_container = (MetaGpuKmsFlipClosureContainer) {
|
||||||
|
.flip_closure = flip_closure,
|
||||||
|
.gpu_kms = gpu_kms
|
||||||
|
};
|
||||||
|
|
||||||
|
return closure_container;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_gpu_kms_flip_closure_container_free (MetaGpuKmsFlipClosureContainer *closure_container)
|
||||||
|
{
|
||||||
|
g_free (closure_container);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms,
|
meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms,
|
||||||
@ -229,14 +260,11 @@ meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms,
|
|||||||
|
|
||||||
if (!gpu_kms->page_flips_not_supported)
|
if (!gpu_kms->page_flips_not_supported)
|
||||||
{
|
{
|
||||||
GpuClosureContainer *closure_container;
|
MetaGpuKmsFlipClosureContainer *closure_container;
|
||||||
int kms_fd = meta_gpu_kms_get_fd (gpu_kms);
|
int kms_fd = meta_gpu_kms_get_fd (gpu_kms);
|
||||||
|
|
||||||
closure_container = g_new0 (GpuClosureContainer, 1);
|
closure_container = meta_gpu_kms_wrap_flip_closure (gpu_kms,
|
||||||
*closure_container = (GpuClosureContainer) {
|
flip_closure);
|
||||||
.flip_closure = flip_closure,
|
|
||||||
.gpu_kms = gpu_kms
|
|
||||||
};
|
|
||||||
|
|
||||||
ret = drmModePageFlip (kms_fd,
|
ret = drmModePageFlip (kms_fd,
|
||||||
crtc->crtc_id,
|
crtc->crtc_id,
|
||||||
@ -245,7 +273,7 @@ meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms,
|
|||||||
closure_container);
|
closure_container);
|
||||||
if (ret != 0 && ret != -EACCES)
|
if (ret != 0 && ret != -EACCES)
|
||||||
{
|
{
|
||||||
g_free (closure_container);
|
meta_gpu_kms_flip_closure_container_free (closure_container);
|
||||||
g_warning ("Failed to flip: %s", strerror (-ret));
|
g_warning ("Failed to flip: %s", strerror (-ret));
|
||||||
gpu_kms->page_flips_not_supported = TRUE;
|
gpu_kms->page_flips_not_supported = TRUE;
|
||||||
}
|
}
|
||||||
@ -276,12 +304,12 @@ page_flip_handler (int fd,
|
|||||||
unsigned int usec,
|
unsigned int usec,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
GpuClosureContainer *closure_container = user_data;
|
MetaGpuKmsFlipClosureContainer *closure_container = user_data;
|
||||||
GClosure *flip_closure = closure_container->flip_closure;
|
GClosure *flip_closure = closure_container->flip_closure;
|
||||||
MetaGpuKms *gpu_kms = closure_container->gpu_kms;
|
MetaGpuKms *gpu_kms = closure_container->gpu_kms;
|
||||||
|
|
||||||
invoke_flip_closure (flip_closure, gpu_kms);
|
invoke_flip_closure (flip_closure, gpu_kms);
|
||||||
g_free (closure_container);
|
meta_gpu_kms_flip_closure_container_free (closure_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -701,20 +729,34 @@ init_outputs (MetaGpuKms *gpu_kms,
|
|||||||
setup_output_clones (gpu);
|
setup_output_clones (gpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
meta_kms_resources_init (MetaKmsResources *resources,
|
meta_kms_resources_init (MetaKmsResources *resources,
|
||||||
int fd)
|
int fd,
|
||||||
|
GError **error)
|
||||||
|
|
||||||
{
|
{
|
||||||
drmModeRes *drm_resources;
|
drmModeRes *drm_resources;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
drm_resources = drmModeGetResources (fd);
|
drm_resources = drmModeGetResources (fd);
|
||||||
|
|
||||||
|
if (!drm_resources)
|
||||||
|
{
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_FAILED,
|
||||||
|
"Calling drmModeGetResources() failed");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
resources->resources = drm_resources;
|
resources->resources = drm_resources;
|
||||||
|
|
||||||
resources->n_encoders = (unsigned int) drm_resources->count_encoders;
|
resources->n_encoders = (unsigned int) drm_resources->count_encoders;
|
||||||
resources->encoders = g_new (drmModeEncoder *, resources->n_encoders);
|
resources->encoders = g_new (drmModeEncoder *, resources->n_encoders);
|
||||||
for (i = 0; i < resources->n_encoders; i++)
|
for (i = 0; i < resources->n_encoders; i++)
|
||||||
resources->encoders[i] = drmModeGetEncoder (fd, drm_resources->encoders[i]);
|
resources->encoders[i] = drmModeGetEncoder (fd, drm_resources->encoders[i]);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -726,7 +768,7 @@ meta_kms_resources_release (MetaKmsResources *resources)
|
|||||||
drmModeFreeEncoder (resources->encoders[i]);
|
drmModeFreeEncoder (resources->encoders[i]);
|
||||||
g_free (resources->encoders);
|
g_free (resources->encoders);
|
||||||
|
|
||||||
drmModeFreeResources (resources->resources);
|
g_clear_pointer (&resources->resources, drmModeFreeResources);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -737,8 +779,18 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
|
|||||||
MetaMonitorManager *monitor_manager =
|
MetaMonitorManager *monitor_manager =
|
||||||
meta_gpu_get_monitor_manager (gpu);
|
meta_gpu_get_monitor_manager (gpu);
|
||||||
MetaKmsResources resources;
|
MetaKmsResources resources;
|
||||||
|
g_autoptr (GError) local_error = NULL;
|
||||||
|
|
||||||
meta_kms_resources_init (&resources, gpu_kms->fd);
|
if (!meta_kms_resources_init (&resources, gpu_kms->fd, &local_error))
|
||||||
|
{
|
||||||
|
if (!gpu_kms->resources_init_failed_before)
|
||||||
|
{
|
||||||
|
g_warning ("meta_kms_resources_init failed: %s, assuming we have no outputs",
|
||||||
|
local_error->message);
|
||||||
|
gpu_kms->resources_init_failed_before = TRUE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
gpu_kms->max_buffer_width = resources.resources->max_width;
|
gpu_kms->max_buffer_width = resources.resources->max_width;
|
||||||
gpu_kms->max_buffer_height = resources.resources->max_height;
|
gpu_kms->max_buffer_height = resources.resources->max_height;
|
||||||
@ -751,6 +803,8 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
|
|||||||
are freed by the platform-independent layer. */
|
are freed by the platform-independent layer. */
|
||||||
free_resources (gpu_kms);
|
free_resources (gpu_kms);
|
||||||
|
|
||||||
|
g_assert (resources.resources->count_connectors > 0);
|
||||||
|
|
||||||
init_connectors (gpu_kms, resources.resources);
|
init_connectors (gpu_kms, resources.resources);
|
||||||
init_modes (gpu_kms, resources.resources);
|
init_modes (gpu_kms, resources.resources);
|
||||||
init_crtcs (gpu_kms, &resources);
|
init_crtcs (gpu_kms, &resources);
|
||||||
@ -761,6 +815,12 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_gpu_kms_can_have_outputs (MetaGpuKms *gpu_kms)
|
||||||
|
{
|
||||||
|
return gpu_kms->n_connectors > 0;
|
||||||
|
}
|
||||||
|
|
||||||
MetaGpuKms *
|
MetaGpuKms *
|
||||||
meta_gpu_kms_new (MetaMonitorManagerKms *monitor_manager_kms,
|
meta_gpu_kms_new (MetaMonitorManagerKms *monitor_manager_kms,
|
||||||
const char *kms_file_path,
|
const char *kms_file_path,
|
||||||
@ -774,11 +834,46 @@ meta_gpu_kms_new (MetaMonitorManagerKms *monitor_manager_kms,
|
|||||||
GSource *source;
|
GSource *source;
|
||||||
MetaKmsSource *kms_source;
|
MetaKmsSource *kms_source;
|
||||||
MetaGpuKms *gpu_kms;
|
MetaGpuKms *gpu_kms;
|
||||||
|
drmModeRes *drm_resources;
|
||||||
|
guint n_connectors;
|
||||||
int kms_fd;
|
int kms_fd;
|
||||||
|
|
||||||
kms_fd = meta_launcher_open_restricted (launcher, kms_file_path, error);
|
kms_fd = meta_launcher_open_restricted (launcher, kms_file_path, error);
|
||||||
if (kms_fd == -1)
|
if (kms_fd == -1)
|
||||||
return FALSE;
|
return NULL;
|
||||||
|
|
||||||
|
/* Some GPUs might have no connectors, for example dedicated GPUs on PRIME (hybrid) laptops.
|
||||||
|
* These GPUs cannot render anything on separate screens, and they are aggressively switched
|
||||||
|
* off by the kernel.
|
||||||
|
*
|
||||||
|
* If we add these PRIME GPUs to the GPU list anyway, Mutter keeps awakening the secondary GPU,
|
||||||
|
* and doing this causes a considerable stuttering. These GPUs are usually put to sleep again
|
||||||
|
* after ~2s without a workload.
|
||||||
|
*
|
||||||
|
* For now, to avoid this situation, only create the MetaGpuKms when the GPU has any connectors.
|
||||||
|
*/
|
||||||
|
drm_resources = drmModeGetResources (kms_fd);
|
||||||
|
|
||||||
|
if (!drm_resources)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No resources");
|
||||||
|
meta_launcher_close_restricted (launcher, kms_fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
n_connectors = drm_resources->count_connectors;
|
||||||
|
|
||||||
|
drmModeFreeResources (drm_resources);
|
||||||
|
|
||||||
|
if (n_connectors == 0)
|
||||||
|
{
|
||||||
|
g_set_error (error,
|
||||||
|
META_GPU_KMS_ERROR,
|
||||||
|
META_GPU_KMS_ERROR_NO_CONNECTORS,
|
||||||
|
"No connectors available in this GPU. This is probably a dedicated GPU in a hybrid setup.");
|
||||||
|
meta_launcher_close_restricted (launcher, kms_fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
gpu_kms = g_object_new (META_TYPE_GPU_KMS,
|
gpu_kms = g_object_new (META_TYPE_GPU_KMS,
|
||||||
"monitor-manager", monitor_manager_kms,
|
"monitor-manager", monitor_manager_kms,
|
||||||
@ -789,6 +884,8 @@ meta_gpu_kms_new (MetaMonitorManagerKms *monitor_manager_kms,
|
|||||||
|
|
||||||
drmSetClientCap (gpu_kms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
drmSetClientCap (gpu_kms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||||
|
|
||||||
|
meta_gpu_kms_read_current (META_GPU (gpu_kms), NULL);
|
||||||
|
|
||||||
source = g_source_new (&kms_event_funcs, sizeof (MetaKmsSource));
|
source = g_source_new (&kms_event_funcs, sizeof (MetaKmsSource));
|
||||||
kms_source = (MetaKmsSource *) source;
|
kms_source = (MetaKmsSource *) source;
|
||||||
kms_source->fd_tag = g_source_add_unix_fd (source,
|
kms_source->fd_tag = g_source_add_unix_fd (source,
|
||||||
|
@ -29,9 +29,19 @@
|
|||||||
#include "backends/meta-gpu.h"
|
#include "backends/meta-gpu.h"
|
||||||
#include "backends/native/meta-monitor-manager-kms.h"
|
#include "backends/native/meta-monitor-manager-kms.h"
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
META_GPU_KMS_ERROR_NO_CONNECTORS,
|
||||||
|
} MetaGpuKmsError;
|
||||||
|
|
||||||
|
#define META_GPU_KMS_ERROR (meta_gpu_kms_error_quark ())
|
||||||
|
GQuark meta_gpu_kms_error_quark (void);
|
||||||
|
|
||||||
#define META_TYPE_GPU_KMS (meta_gpu_kms_get_type ())
|
#define META_TYPE_GPU_KMS (meta_gpu_kms_get_type ())
|
||||||
G_DECLARE_FINAL_TYPE (MetaGpuKms, meta_gpu_kms, META, GPU_KMS, MetaGpu)
|
G_DECLARE_FINAL_TYPE (MetaGpuKms, meta_gpu_kms, META, GPU_KMS, MetaGpu)
|
||||||
|
|
||||||
|
typedef struct _MetaGpuKmsFlipClosureContainer MetaGpuKmsFlipClosureContainer;
|
||||||
|
|
||||||
typedef struct _MetaKmsResources
|
typedef struct _MetaKmsResources
|
||||||
{
|
{
|
||||||
drmModeRes *resources;
|
drmModeRes *resources;
|
||||||
@ -51,6 +61,8 @@ gboolean meta_gpu_kms_apply_crtc_mode (MetaGpuKms *gpu_kms,
|
|||||||
int y,
|
int y,
|
||||||
uint32_t fb_id);
|
uint32_t fb_id);
|
||||||
|
|
||||||
|
gboolean meta_gpu_kms_can_have_outputs (MetaGpuKms *gpu_kms);
|
||||||
|
|
||||||
gboolean meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
|
gboolean meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
|
||||||
MetaCrtc *crtc);
|
MetaCrtc *crtc);
|
||||||
|
|
||||||
@ -84,4 +96,9 @@ gboolean meta_drm_mode_equal (const drmModeModeInfo *one,
|
|||||||
|
|
||||||
float meta_calculate_drm_mode_refresh_rate (const drmModeModeInfo *mode);
|
float meta_calculate_drm_mode_refresh_rate (const drmModeModeInfo *mode);
|
||||||
|
|
||||||
|
MetaGpuKmsFlipClosureContainer * meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms,
|
||||||
|
GClosure *flip_closure);
|
||||||
|
|
||||||
|
void meta_gpu_kms_flip_closure_container_free (MetaGpuKmsFlipClosureContainer *closure_container);
|
||||||
|
|
||||||
#endif /* META_GPU_KMS_H */
|
#endif /* META_GPU_KMS_H */
|
||||||
|
@ -1,200 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2013 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Adapted from gnome-session/gnome-session/gs-idle-monitor.c and
|
|
||||||
* from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "meta-idle-monitor-native.h"
|
|
||||||
#include "meta-idle-monitor-private.h"
|
|
||||||
|
|
||||||
#include <meta/util.h>
|
|
||||||
#include "display-private.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
struct _MetaIdleMonitorNative
|
|
||||||
{
|
|
||||||
MetaIdleMonitor parent;
|
|
||||||
|
|
||||||
guint64 last_event_time;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _MetaIdleMonitorNativeClass
|
|
||||||
{
|
|
||||||
MetaIdleMonitorClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
MetaIdleMonitorWatch base;
|
|
||||||
|
|
||||||
GSource *timeout_source;
|
|
||||||
} MetaIdleMonitorWatchNative;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaIdleMonitorNative, meta_idle_monitor_native, META_TYPE_IDLE_MONITOR)
|
|
||||||
|
|
||||||
static gint64
|
|
||||||
meta_idle_monitor_native_get_idletime (MetaIdleMonitor *monitor)
|
|
||||||
{
|
|
||||||
MetaIdleMonitorNative *monitor_native = META_IDLE_MONITOR_NATIVE (monitor);
|
|
||||||
|
|
||||||
return (g_get_monotonic_time () - monitor_native->last_event_time) / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
static guint32
|
|
||||||
get_next_watch_serial (void)
|
|
||||||
{
|
|
||||||
static guint32 serial = 0;
|
|
||||||
g_atomic_int_inc (&serial);
|
|
||||||
return serial;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
native_dispatch_timeout (GSource *source,
|
|
||||||
GSourceFunc callback,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
MetaIdleMonitorWatchNative *watch_native = user_data;
|
|
||||||
MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_native;
|
|
||||||
|
|
||||||
_meta_idle_monitor_watch_fire (watch);
|
|
||||||
g_source_set_ready_time (watch_native->timeout_source, -1);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GSourceFuncs native_source_funcs = {
|
|
||||||
NULL, /* prepare */
|
|
||||||
NULL, /* check */
|
|
||||||
native_dispatch_timeout,
|
|
||||||
NULL, /* finalize */
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
free_watch (gpointer data)
|
|
||||||
{
|
|
||||||
MetaIdleMonitorWatchNative *watch_native = data;
|
|
||||||
MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_native;
|
|
||||||
MetaIdleMonitor *monitor = watch->monitor;
|
|
||||||
|
|
||||||
g_object_ref (monitor);
|
|
||||||
|
|
||||||
if (watch->idle_source_id)
|
|
||||||
{
|
|
||||||
g_source_remove (watch->idle_source_id);
|
|
||||||
watch->idle_source_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (watch->notify != NULL)
|
|
||||||
watch->notify (watch->user_data);
|
|
||||||
|
|
||||||
if (watch_native->timeout_source != NULL)
|
|
||||||
g_source_destroy (watch_native->timeout_source);
|
|
||||||
|
|
||||||
g_object_unref (monitor);
|
|
||||||
g_slice_free (MetaIdleMonitorWatchNative, watch_native);
|
|
||||||
}
|
|
||||||
|
|
||||||
static MetaIdleMonitorWatch *
|
|
||||||
meta_idle_monitor_native_make_watch (MetaIdleMonitor *monitor,
|
|
||||||
guint64 timeout_msec,
|
|
||||||
MetaIdleMonitorWatchFunc callback,
|
|
||||||
gpointer user_data,
|
|
||||||
GDestroyNotify notify)
|
|
||||||
{
|
|
||||||
MetaIdleMonitorWatchNative *watch_native;
|
|
||||||
MetaIdleMonitorWatch *watch;
|
|
||||||
MetaIdleMonitorNative *monitor_native = META_IDLE_MONITOR_NATIVE (monitor);
|
|
||||||
|
|
||||||
watch_native = g_slice_new0 (MetaIdleMonitorWatchNative);
|
|
||||||
watch = (MetaIdleMonitorWatch *) watch_native;
|
|
||||||
|
|
||||||
watch->monitor = monitor;
|
|
||||||
watch->id = get_next_watch_serial ();
|
|
||||||
watch->callback = callback;
|
|
||||||
watch->user_data = user_data;
|
|
||||||
watch->notify = notify;
|
|
||||||
watch->timeout_msec = timeout_msec;
|
|
||||||
|
|
||||||
if (timeout_msec != 0)
|
|
||||||
{
|
|
||||||
GSource *source = g_source_new (&native_source_funcs, sizeof (GSource));
|
|
||||||
|
|
||||||
g_source_set_callback (source, NULL, watch, NULL);
|
|
||||||
g_source_set_ready_time (source, monitor_native->last_event_time + timeout_msec * 1000);
|
|
||||||
g_source_attach (source, NULL);
|
|
||||||
g_source_unref (source);
|
|
||||||
|
|
||||||
watch_native->timeout_source = source;
|
|
||||||
}
|
|
||||||
|
|
||||||
return watch;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_idle_monitor_native_class_init (MetaIdleMonitorNativeClass *klass)
|
|
||||||
{
|
|
||||||
MetaIdleMonitorClass *idle_monitor_class = META_IDLE_MONITOR_CLASS (klass);
|
|
||||||
|
|
||||||
idle_monitor_class->get_idletime = meta_idle_monitor_native_get_idletime;
|
|
||||||
idle_monitor_class->make_watch = meta_idle_monitor_native_make_watch;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_idle_monitor_native_init (MetaIdleMonitorNative *monitor_native)
|
|
||||||
{
|
|
||||||
MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_native);
|
|
||||||
|
|
||||||
monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch);
|
|
||||||
monitor_native->last_event_time = g_get_monotonic_time ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_idle_monitor_native_reset_idletime (MetaIdleMonitor *monitor)
|
|
||||||
{
|
|
||||||
MetaIdleMonitorNative *monitor_native = META_IDLE_MONITOR_NATIVE (monitor);
|
|
||||||
GList *node, *watch_ids;
|
|
||||||
|
|
||||||
monitor_native->last_event_time = g_get_monotonic_time ();
|
|
||||||
|
|
||||||
watch_ids = g_hash_table_get_keys (monitor->watches);
|
|
||||||
|
|
||||||
for (node = watch_ids; node != NULL; node = node->next)
|
|
||||||
{
|
|
||||||
guint watch_id = GPOINTER_TO_UINT (node->data);
|
|
||||||
MetaIdleMonitorWatchNative *watch;
|
|
||||||
|
|
||||||
watch = g_hash_table_lookup (monitor->watches, GUINT_TO_POINTER (watch_id));
|
|
||||||
if (!watch)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (watch->base.timeout_msec == 0)
|
|
||||||
{
|
|
||||||
_meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_source_set_ready_time (watch->timeout_source,
|
|
||||||
monitor_native->last_event_time +
|
|
||||||
watch->base.timeout_msec * 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_list_free (watch_ids);
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2013 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Adapted from gnome-session/gnome-session/gs-idle-monitor.c and
|
|
||||||
* from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef META_IDLE_MONITOR_NATIVE_H
|
|
||||||
#define META_IDLE_MONITOR_NATIVE_H
|
|
||||||
|
|
||||||
#include <glib-object.h>
|
|
||||||
#include <meta/meta-idle-monitor.h>
|
|
||||||
|
|
||||||
#define META_TYPE_IDLE_MONITOR_NATIVE (meta_idle_monitor_native_get_type ())
|
|
||||||
#define META_IDLE_MONITOR_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_IDLE_MONITOR_NATIVE, MetaIdleMonitorNative))
|
|
||||||
#define META_IDLE_MONITOR_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_IDLE_MONITOR_NATIVE, MetaIdleMonitorNativeClass))
|
|
||||||
#define META_IS_IDLE_MONITOR_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_IDLE_MONITOR_NATIVE))
|
|
||||||
#define META_IS_IDLE_MONITOR_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_IDLE_MONITOR_NATIVE))
|
|
||||||
#define META_IDLE_MONITOR_NATIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_IDLE_MONITOR_NATIVE, MetaIdleMonitorNativeClass))
|
|
||||||
|
|
||||||
typedef struct _MetaIdleMonitorNative MetaIdleMonitorNative;
|
|
||||||
typedef struct _MetaIdleMonitorNativeClass MetaIdleMonitorNativeClass;
|
|
||||||
|
|
||||||
GType meta_idle_monitor_native_get_type (void);
|
|
||||||
|
|
||||||
void meta_idle_monitor_native_reset_idletime (MetaIdleMonitor *monitor);
|
|
||||||
|
|
||||||
#endif /* META_IDLE_MONITOR_NATIVE_H */
|
|
@ -44,7 +44,6 @@
|
|||||||
#include "backends/meta-backend-private.h"
|
#include "backends/meta-backend-private.h"
|
||||||
#include "backends/native/meta-backend-native.h"
|
#include "backends/native/meta-backend-native.h"
|
||||||
#include "meta-cursor-renderer-native.h"
|
#include "meta-cursor-renderer-native.h"
|
||||||
#include "meta-idle-monitor-native.h"
|
|
||||||
#include "meta-renderer-native.h"
|
#include "meta-renderer-native.h"
|
||||||
|
|
||||||
struct _MetaLauncher
|
struct _MetaLauncher
|
||||||
|
@ -188,7 +188,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
|||||||
MetaOutput *output = g_ptr_array_index (crtc_info->outputs, j);
|
MetaOutput *output = g_ptr_array_index (crtc_info->outputs, j);
|
||||||
|
|
||||||
output->is_dirty = TRUE;
|
output->is_dirty = TRUE;
|
||||||
output->crtc = crtc;
|
meta_output_assign_crtc (output, crtc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
output->crtc = NULL;
|
meta_output_unassign_crtc (output);
|
||||||
output->is_primary = FALSE;
|
output->is_primary = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -642,10 +642,12 @@ meta_monitor_manager_kms_initable_init (GInitable *initable,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (initable);
|
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (initable);
|
||||||
|
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
|
||||||
const char *subsystems[2] = { "drm", NULL };
|
const char *subsystems[2] = { "drm", NULL };
|
||||||
GList *gpu_paths;
|
GList *gpu_paths;
|
||||||
g_autofree char *primary_gpu_path = NULL;
|
g_autofree char *primary_gpu_path = NULL;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
gboolean can_have_outputs;
|
||||||
|
|
||||||
manager_kms->udev = g_udev_client_new (subsystems);
|
manager_kms->udev = g_udev_client_new (subsystems);
|
||||||
|
|
||||||
@ -674,16 +676,19 @@ meta_monitor_manager_kms_initable_init (GInitable *initable,
|
|||||||
gpu_paths = get_gpu_paths (manager_kms, GPU_TYPE_SECONDARY, primary_gpu_path);
|
gpu_paths = get_gpu_paths (manager_kms, GPU_TYPE_SECONDARY, primary_gpu_path);
|
||||||
for (l = gpu_paths; l; l = l->next)
|
for (l = gpu_paths; l; l = l->next)
|
||||||
{
|
{
|
||||||
GError *secondary_error = NULL;
|
g_autoptr (GError) secondary_error = NULL;
|
||||||
char *gpu_path = l->data;
|
char *gpu_path = l->data;
|
||||||
MetaGpuKms *gpu_kms;
|
MetaGpuKms *gpu_kms;
|
||||||
|
|
||||||
gpu_kms = meta_gpu_kms_new (manager_kms, gpu_path, &secondary_error);
|
gpu_kms = meta_gpu_kms_new (manager_kms, gpu_path, &secondary_error);
|
||||||
if (!gpu_kms)
|
if (!gpu_kms)
|
||||||
{
|
{
|
||||||
g_warning ("Failed to open secondary gpu '%s': %s",
|
if (g_error_matches (secondary_error, META_GPU_KMS_ERROR, META_GPU_KMS_ERROR_NO_CONNECTORS))
|
||||||
gpu_path, secondary_error->message);
|
g_message ("Ignoring GPU %s due to the lack of connectors", gpu_path);
|
||||||
g_error_free (secondary_error);
|
else
|
||||||
|
g_warning ("Failed to open secondary gpu '%s': %s", gpu_path, secondary_error->message);
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_monitor_manager_add_gpu (META_MONITOR_MANAGER (manager_kms),
|
meta_monitor_manager_add_gpu (META_MONITOR_MANAGER (manager_kms),
|
||||||
@ -691,6 +696,24 @@ meta_monitor_manager_kms_initable_init (GInitable *initable,
|
|||||||
}
|
}
|
||||||
g_list_free_full (gpu_paths, g_free);
|
g_list_free_full (gpu_paths, g_free);
|
||||||
|
|
||||||
|
can_have_outputs = FALSE;
|
||||||
|
for (l = meta_monitor_manager_get_gpus (manager); l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaGpuKms *gpu_kms = l->data;
|
||||||
|
|
||||||
|
if (meta_gpu_kms_can_have_outputs (gpu_kms))
|
||||||
|
{
|
||||||
|
can_have_outputs = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!can_have_outputs)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||||
|
"No GPUs with outputs found");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,11 +64,13 @@ typedef struct _MetaOutputKms
|
|||||||
void
|
void
|
||||||
meta_output_kms_set_underscan (MetaOutput *output)
|
meta_output_kms_set_underscan (MetaOutput *output)
|
||||||
{
|
{
|
||||||
if (!output->crtc)
|
MetaCrtc *crtc;
|
||||||
|
|
||||||
|
crtc = meta_output_get_assigned_crtc (output);
|
||||||
|
if (!crtc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
meta_crtc_kms_set_underscan (output->crtc,
|
meta_crtc_kms_set_underscan (crtc, output->is_underscanning);
|
||||||
output->is_underscanning);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -600,14 +602,14 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
|
|||||||
|
|
||||||
if (crtc->crtc_id == output_kms->current_encoder->crtc_id)
|
if (crtc->crtc_id == output_kms->current_encoder->crtc_id)
|
||||||
{
|
{
|
||||||
output->crtc = crtc;
|
meta_output_assign_crtc (output, crtc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
output->crtc = NULL;
|
meta_output_unassign_crtc (output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_output)
|
if (old_output)
|
||||||
|
@ -193,6 +193,8 @@ struct _MetaRendererNative
|
|||||||
MetaMonitorManagerKms *monitor_manager_kms;
|
MetaMonitorManagerKms *monitor_manager_kms;
|
||||||
MetaGles3 *gles3;
|
MetaGles3 *gles3;
|
||||||
|
|
||||||
|
gboolean use_modifiers;
|
||||||
|
|
||||||
GHashTable *gpu_datas;
|
GHashTable *gpu_datas;
|
||||||
|
|
||||||
CoglClosure *swap_notify_idle;
|
CoglClosure *swap_notify_idle;
|
||||||
@ -991,14 +993,29 @@ meta_renderer_native_choose_egl_config (CoglDisplay *cogl_display,
|
|||||||
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
|
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaEgl *egl = meta_backend_get_egl (backend);
|
MetaEgl *egl = meta_backend_get_egl (backend);
|
||||||
|
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
|
||||||
EGLDisplay egl_display = cogl_renderer_egl->edpy;
|
EGLDisplay egl_display = cogl_renderer_egl->edpy;
|
||||||
|
|
||||||
|
switch (renderer_gpu_data->mode)
|
||||||
|
{
|
||||||
|
case META_RENDERER_NATIVE_MODE_GBM:
|
||||||
return choose_egl_config_from_gbm_format (egl,
|
return choose_egl_config_from_gbm_format (egl,
|
||||||
egl_display,
|
egl_display,
|
||||||
attributes,
|
attributes,
|
||||||
GBM_FORMAT_XRGB8888,
|
GBM_FORMAT_XRGB8888,
|
||||||
out_config,
|
out_config,
|
||||||
error);
|
error);
|
||||||
|
#ifdef HAVE_EGL_DEVICE
|
||||||
|
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
|
||||||
|
return meta_egl_choose_first_config (egl,
|
||||||
|
egl_display,
|
||||||
|
attributes,
|
||||||
|
out_config,
|
||||||
|
error);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -1269,6 +1286,7 @@ flip_egl_stream (MetaOnscreenNative *onscreen_native,
|
|||||||
MetaRendererNativeGpuData *renderer_gpu_data;
|
MetaRendererNativeGpuData *renderer_gpu_data;
|
||||||
EGLDisplay *egl_display;
|
EGLDisplay *egl_display;
|
||||||
MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
|
MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
|
||||||
|
MetaGpuKmsFlipClosureContainer *closure_container;
|
||||||
EGLAttrib *acquire_attribs;
|
EGLAttrib *acquire_attribs;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
@ -1278,9 +1296,12 @@ flip_egl_stream (MetaOnscreenNative *onscreen_native,
|
|||||||
if (renderer_gpu_data->egl.no_egl_output_drm_flip_event)
|
if (renderer_gpu_data->egl.no_egl_output_drm_flip_event)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
closure_container =
|
||||||
|
meta_gpu_kms_wrap_flip_closure (onscreen_native->render_gpu, flip_closure);
|
||||||
|
|
||||||
acquire_attribs = (EGLAttrib[]) {
|
acquire_attribs = (EGLAttrib[]) {
|
||||||
EGL_DRM_FLIP_EVENT_DATA_NV,
|
EGL_DRM_FLIP_EVENT_DATA_NV,
|
||||||
(EGLAttrib) flip_closure,
|
(EGLAttrib) closure_container,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1299,6 +1320,7 @@ flip_egl_stream (MetaOnscreenNative *onscreen_native,
|
|||||||
renderer_gpu_data->egl.no_egl_output_drm_flip_event = TRUE;
|
renderer_gpu_data->egl.no_egl_output_drm_flip_event = TRUE;
|
||||||
}
|
}
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
|
meta_gpu_kms_flip_closure_container_free (closure_container);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1586,6 +1608,7 @@ gbm_get_next_fb_id (MetaGpuKms *gpu_kms,
|
|||||||
struct gbm_bo **out_next_bo,
|
struct gbm_bo **out_next_bo,
|
||||||
uint32_t *out_next_fb_id)
|
uint32_t *out_next_fb_id)
|
||||||
{
|
{
|
||||||
|
MetaRendererNative *renderer_native = meta_renderer_native_from_gpu (gpu_kms);
|
||||||
struct gbm_bo *next_bo;
|
struct gbm_bo *next_bo;
|
||||||
uint32_t next_fb_id;
|
uint32_t next_fb_id;
|
||||||
int kms_fd;
|
int kms_fd;
|
||||||
@ -1598,6 +1621,22 @@ gbm_get_next_fb_id (MetaGpuKms *gpu_kms,
|
|||||||
/* Now we need to set the CRTC to whatever is the front buffer */
|
/* Now we need to set the CRTC to whatever is the front buffer */
|
||||||
next_bo = gbm_surface_lock_front_buffer (gbm_surface);
|
next_bo = gbm_surface_lock_front_buffer (gbm_surface);
|
||||||
|
|
||||||
|
if (!next_bo)
|
||||||
|
{
|
||||||
|
g_error ("Impossible to lock surface front buffer: %m");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gbm_bo_get_handle_for_plane (next_bo, 0).s32 == -1)
|
||||||
|
{
|
||||||
|
/* Failed to fetch handle to plane, falling back to old method */
|
||||||
|
strides[0] = gbm_bo_get_stride (next_bo);
|
||||||
|
handles[0] = gbm_bo_get_handle (next_bo).u32;
|
||||||
|
offsets[0] = 0;
|
||||||
|
modifiers[0] = DRM_FORMAT_MOD_INVALID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for (i = 0; i < gbm_bo_get_plane_count (next_bo); i++)
|
for (i = 0; i < gbm_bo_get_plane_count (next_bo); i++)
|
||||||
{
|
{
|
||||||
strides[i] = gbm_bo_get_stride_for_plane (next_bo, i);
|
strides[i] = gbm_bo_get_stride_for_plane (next_bo, i);
|
||||||
@ -1605,10 +1644,12 @@ gbm_get_next_fb_id (MetaGpuKms *gpu_kms,
|
|||||||
offsets[i] = gbm_bo_get_offset (next_bo, i);
|
offsets[i] = gbm_bo_get_offset (next_bo, i);
|
||||||
modifiers[i] = gbm_bo_get_modifier (next_bo);
|
modifiers[i] = gbm_bo_get_modifier (next_bo);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
|
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
|
||||||
|
|
||||||
if (modifiers[0] != DRM_FORMAT_MOD_INVALID)
|
if (renderer_native->use_modifiers &&
|
||||||
|
modifiers[0] != DRM_FORMAT_MOD_INVALID)
|
||||||
{
|
{
|
||||||
if (drmModeAddFB2WithModifiers (kms_fd,
|
if (drmModeAddFB2WithModifiers (kms_fd,
|
||||||
gbm_bo_get_width (next_bo),
|
gbm_bo_get_width (next_bo),
|
||||||
@ -1854,18 +1895,18 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||||||
frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos);
|
frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos);
|
||||||
frame_info->global_frame_counter = renderer_native->frame_counter;
|
frame_info->global_frame_counter = renderer_native->frame_counter;
|
||||||
|
|
||||||
/*
|
|
||||||
* Wait for the flip callback before continuing, as we might have started the
|
|
||||||
* animation earlier due to the animation being driven by some other monitor.
|
|
||||||
*/
|
|
||||||
wait_for_pending_flips (onscreen);
|
|
||||||
|
|
||||||
update_secondary_gpu_state_pre_swap_buffers (onscreen);
|
update_secondary_gpu_state_pre_swap_buffers (onscreen);
|
||||||
|
|
||||||
parent_vtable->onscreen_swap_buffers_with_damage (onscreen,
|
parent_vtable->onscreen_swap_buffers_with_damage (onscreen,
|
||||||
rectangles,
|
rectangles,
|
||||||
n_rectangles);
|
n_rectangles);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for the flip callback before continuing, as we might have started the
|
||||||
|
* animation earlier due to the animation being driven by some other monitor.
|
||||||
|
*/
|
||||||
|
wait_for_pending_flips (onscreen);
|
||||||
|
|
||||||
renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
|
renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
|
||||||
render_gpu);
|
render_gpu);
|
||||||
switch (renderer_gpu_data->mode)
|
switch (renderer_gpu_data->mode)
|
||||||
@ -1907,12 +1948,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||||||
* context.
|
* context.
|
||||||
*/
|
*/
|
||||||
if (egl_context_changed)
|
if (egl_context_changed)
|
||||||
{
|
_cogl_winsys_egl_ensure_current (cogl_display);
|
||||||
_cogl_winsys_egl_make_current (cogl_display,
|
|
||||||
EGL_NO_SURFACE,
|
|
||||||
EGL_NO_SURFACE,
|
|
||||||
EGL_NO_CONTEXT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -1996,7 +2032,7 @@ meta_renderer_native_create_surface_gbm (CoglOnscreen *onscreen,
|
|||||||
CoglRenderer *cogl_renderer = cogl_display->renderer;
|
CoglRenderer *cogl_renderer = cogl_display->renderer;
|
||||||
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
|
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
|
||||||
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
|
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
|
||||||
struct gbm_surface *new_gbm_surface;
|
struct gbm_surface *new_gbm_surface = NULL;
|
||||||
EGLNativeWindowType egl_native_window;
|
EGLNativeWindowType egl_native_window;
|
||||||
EGLSurface new_egl_surface;
|
EGLSurface new_egl_surface;
|
||||||
uint32_t format = GBM_FORMAT_XRGB8888;
|
uint32_t format = GBM_FORMAT_XRGB8888;
|
||||||
@ -2006,7 +2042,10 @@ meta_renderer_native_create_surface_gbm (CoglOnscreen *onscreen,
|
|||||||
meta_renderer_native_get_gpu_data (renderer_native,
|
meta_renderer_native_get_gpu_data (renderer_native,
|
||||||
onscreen_native->render_gpu);
|
onscreen_native->render_gpu);
|
||||||
|
|
||||||
|
if (renderer_native->use_modifiers)
|
||||||
modifiers = get_supported_modifiers (onscreen, format);
|
modifiers = get_supported_modifiers (onscreen, format);
|
||||||
|
else
|
||||||
|
modifiers = NULL;
|
||||||
|
|
||||||
if (modifiers)
|
if (modifiers)
|
||||||
{
|
{
|
||||||
@ -2017,7 +2056,8 @@ meta_renderer_native_create_surface_gbm (CoglOnscreen *onscreen,
|
|||||||
modifiers->len);
|
modifiers->len);
|
||||||
g_array_free (modifiers, TRUE);
|
g_array_free (modifiers, TRUE);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (!new_gbm_surface)
|
||||||
{
|
{
|
||||||
uint32_t flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
|
uint32_t flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
|
||||||
|
|
||||||
@ -2080,6 +2120,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
|
|||||||
EGLDisplay egl_display = renderer_gpu_data->egl_display;
|
EGLDisplay egl_display = renderer_gpu_data->egl_display;
|
||||||
MetaMonitor *monitor;
|
MetaMonitor *monitor;
|
||||||
MetaOutput *output;
|
MetaOutput *output;
|
||||||
|
MetaCrtc *crtc;
|
||||||
EGLConfig egl_config;
|
EGLConfig egl_config;
|
||||||
EGLStreamKHR egl_stream;
|
EGLStreamKHR egl_stream;
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
@ -2103,6 +2144,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
|
|||||||
|
|
||||||
monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
|
monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
|
||||||
output = meta_monitor_get_main_output (monitor);
|
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,
|
* An "logical_monitor" may have multiple outputs/crtcs in case its tiled,
|
||||||
@ -2110,7 +2152,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
|
|||||||
* lets pass the first one.
|
* lets pass the first one.
|
||||||
*/
|
*/
|
||||||
output_attribs[0] = EGL_DRM_CRTC_EXT;
|
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;
|
output_attribs[2] = EGL_NONE;
|
||||||
|
|
||||||
if (!meta_egl_get_output_layers (egl, egl_display,
|
if (!meta_egl_get_output_layers (egl, egl_display,
|
||||||
@ -2708,9 +2750,12 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
|
|||||||
{
|
{
|
||||||
MetaMonitor *main_monitor;
|
MetaMonitor *main_monitor;
|
||||||
MetaOutput *main_output;
|
MetaOutput *main_output;
|
||||||
|
MetaCrtc *crtc;
|
||||||
MetaMonitorTransform crtc_transform;
|
MetaMonitorTransform crtc_transform;
|
||||||
|
|
||||||
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
|
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
|
||||||
main_output = meta_monitor_get_main_output (main_monitor);
|
main_output = meta_monitor_get_main_output (main_monitor);
|
||||||
|
crtc = meta_output_get_assigned_crtc (main_output);
|
||||||
crtc_transform =
|
crtc_transform =
|
||||||
meta_monitor_logical_to_crtc_transform (main_monitor,
|
meta_monitor_logical_to_crtc_transform (main_monitor,
|
||||||
logical_monitor->transform);
|
logical_monitor->transform);
|
||||||
@ -2721,7 +2766,7 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (meta_monitor_manager_is_transform_handled (monitor_manager,
|
if (meta_monitor_manager_is_transform_handled (monitor_manager,
|
||||||
main_output->crtc,
|
crtc,
|
||||||
crtc_transform))
|
crtc_transform))
|
||||||
return META_MONITOR_TRANSFORM_NORMAL;
|
return META_MONITOR_TRANSFORM_NORMAL;
|
||||||
else
|
else
|
||||||
@ -2899,6 +2944,7 @@ meta_renderer_native_set_property (GObject *object,
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
create_secondary_egl_config (MetaEgl *egl,
|
create_secondary_egl_config (MetaEgl *egl,
|
||||||
|
MetaRendererNativeMode mode,
|
||||||
EGLDisplay egl_display,
|
EGLDisplay egl_display,
|
||||||
EGLConfig *egl_config,
|
EGLConfig *egl_config,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -2914,12 +2960,26 @@ create_secondary_egl_config (MetaEgl *egl,
|
|||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case META_RENDERER_NATIVE_MODE_GBM:
|
||||||
return choose_egl_config_from_gbm_format (egl,
|
return choose_egl_config_from_gbm_format (egl,
|
||||||
egl_display,
|
egl_display,
|
||||||
attributes,
|
attributes,
|
||||||
GBM_FORMAT_XRGB8888,
|
GBM_FORMAT_XRGB8888,
|
||||||
egl_config,
|
egl_config,
|
||||||
error);
|
error);
|
||||||
|
#ifdef HAVE_EGL_DEVICE
|
||||||
|
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
|
||||||
|
return meta_egl_choose_first_config (egl,
|
||||||
|
egl_display,
|
||||||
|
attributes,
|
||||||
|
egl_config,
|
||||||
|
error);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EGLContext
|
static EGLContext
|
||||||
@ -2963,7 +3023,8 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data,
|
|||||||
EGLContext egl_context;
|
EGLContext egl_context;
|
||||||
char **missing_gl_extensions;
|
char **missing_gl_extensions;
|
||||||
|
|
||||||
if (!create_secondary_egl_config (egl,egl_display, &egl_config, error))
|
if (!create_secondary_egl_config (egl, renderer_gpu_data->mode, egl_display,
|
||||||
|
&egl_config, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
egl_context = create_secondary_egl_context (egl, egl_display, egl_config, error);
|
egl_context = create_secondary_egl_context (egl, egl_display, egl_config, error);
|
||||||
@ -3389,6 +3450,22 @@ meta_renderer_native_finalize (GObject *object)
|
|||||||
G_OBJECT_CLASS (meta_renderer_native_parent_class)->finalize (object);
|
G_OBJECT_CLASS (meta_renderer_native_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_renderer_native_constructed (GObject *object)
|
||||||
|
{
|
||||||
|
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (object);
|
||||||
|
MetaMonitorManager *monitor_manager =
|
||||||
|
META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
|
||||||
|
MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager);
|
||||||
|
MetaSettings *settings = meta_backend_get_settings (backend);
|
||||||
|
|
||||||
|
if (meta_settings_is_experimental_feature_enabled (
|
||||||
|
settings, META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS))
|
||||||
|
renderer_native->use_modifiers = TRUE;
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (meta_renderer_native_parent_class)->constructed (object);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_renderer_native_init (MetaRendererNative *renderer_native)
|
meta_renderer_native_init (MetaRendererNative *renderer_native)
|
||||||
{
|
{
|
||||||
@ -3407,6 +3484,7 @@ meta_renderer_native_class_init (MetaRendererNativeClass *klass)
|
|||||||
object_class->get_property = meta_renderer_native_get_property;
|
object_class->get_property = meta_renderer_native_get_property;
|
||||||
object_class->set_property = meta_renderer_native_set_property;
|
object_class->set_property = meta_renderer_native_set_property;
|
||||||
object_class->finalize = meta_renderer_native_finalize;
|
object_class->finalize = meta_renderer_native_finalize;
|
||||||
|
object_class->constructed = meta_renderer_native_constructed;
|
||||||
|
|
||||||
renderer_class->create_cogl_renderer = meta_renderer_native_create_cogl_renderer;
|
renderer_class->create_cogl_renderer = meta_renderer_native_create_cogl_renderer;
|
||||||
renderer_class->create_view = meta_renderer_native_create_view;
|
renderer_class->create_view = meta_renderer_native_create_view;
|
||||||
|
@ -37,8 +37,7 @@
|
|||||||
#include <X11/Xlib-xcb.h>
|
#include <X11/Xlib-xcb.h>
|
||||||
#include <xkbcommon/xkbcommon-x11.h>
|
#include <xkbcommon/xkbcommon-x11.h>
|
||||||
|
|
||||||
#include "meta-idle-monitor-xsync.h"
|
#include "backends/meta-stage-private.h"
|
||||||
#include "backends/meta-stage.h"
|
|
||||||
#include "backends/x11/meta-clutter-backend-x11.h"
|
#include "backends/x11/meta-clutter-backend-x11.h"
|
||||||
#include "backends/x11/meta-renderer-x11.h"
|
#include "backends/x11/meta-renderer-x11.h"
|
||||||
#include "meta/meta-cursor-tracker.h"
|
#include "meta/meta-cursor-tracker.h"
|
||||||
@ -47,6 +46,7 @@
|
|||||||
#include "display-private.h"
|
#include "display-private.h"
|
||||||
#include "compositor/compositor-private.h"
|
#include "compositor/compositor-private.h"
|
||||||
#include "backends/meta-dnd-private.h"
|
#include "backends/meta-dnd-private.h"
|
||||||
|
#include "backends/meta-idle-monitor-private.h"
|
||||||
|
|
||||||
struct _MetaBackendX11Private
|
struct _MetaBackendX11Private
|
||||||
{
|
{
|
||||||
@ -57,6 +57,12 @@ struct _MetaBackendX11Private
|
|||||||
|
|
||||||
int xsync_event_base;
|
int xsync_event_base;
|
||||||
int xsync_error_base;
|
int xsync_error_base;
|
||||||
|
XSyncAlarm user_active_alarm;
|
||||||
|
XSyncCounter counter;
|
||||||
|
|
||||||
|
int current_touch_replay_sync_serial;
|
||||||
|
int pending_touch_replay_sync_serial;
|
||||||
|
Atom touch_replay_sync_atom;
|
||||||
|
|
||||||
int xinput_opcode;
|
int xinput_opcode;
|
||||||
int xinput_event_base;
|
int xinput_event_base;
|
||||||
@ -83,13 +89,77 @@ G_DEFINE_TYPE_WITH_CODE (MetaBackendX11, meta_backend_x11, META_TYPE_BACKEND,
|
|||||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||||
initable_iface_init));
|
initable_iface_init));
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
uint64_to_xsync_value (uint64_t value,
|
||||||
|
XSyncValue *xsync_value)
|
||||||
|
{
|
||||||
|
XSyncIntsToValue (xsync_value, value & 0xffffffff, value >> 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static XSyncAlarm
|
||||||
|
xsync_user_active_alarm_set (MetaBackendX11Private *priv)
|
||||||
|
{
|
||||||
|
XSyncAlarmAttributes attr;
|
||||||
|
XSyncValue delta;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
flags = (XSyncCACounter | XSyncCAValueType | XSyncCATestType |
|
||||||
|
XSyncCAValue | XSyncCADelta | XSyncCAEvents);
|
||||||
|
|
||||||
|
XSyncIntToValue (&delta, 0);
|
||||||
|
attr.trigger.counter = priv->counter;
|
||||||
|
attr.trigger.value_type = XSyncAbsolute;
|
||||||
|
attr.delta = delta;
|
||||||
|
attr.events = TRUE;
|
||||||
|
|
||||||
|
uint64_to_xsync_value (1, &attr.trigger.wait_value);
|
||||||
|
|
||||||
|
attr.trigger.test_type = XSyncNegativeTransition;
|
||||||
|
return XSyncCreateAlarm (priv->xdisplay, flags, &attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static XSyncCounter
|
||||||
|
find_idletime_counter (MetaBackendX11Private *priv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int n_counters;
|
||||||
|
XSyncSystemCounter *counters;
|
||||||
|
XSyncCounter counter = None;
|
||||||
|
|
||||||
|
counters = XSyncListSystemCounters (priv->xdisplay, &n_counters);
|
||||||
|
for (i = 0; i < n_counters; i++)
|
||||||
|
{
|
||||||
|
if (g_strcmp0 (counters[i].name, "IDLETIME") == 0)
|
||||||
|
{
|
||||||
|
counter = counters[i].counter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XSyncFreeSystemCounterList (counters);
|
||||||
|
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_alarm_notify (MetaBackend *backend,
|
handle_alarm_notify (MetaBackend *backend,
|
||||||
XEvent *event)
|
XSyncAlarmNotifyEvent *alarm_event)
|
||||||
{
|
{
|
||||||
meta_backend_foreach_device_monitor (backend,
|
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||||
(GFunc) meta_idle_monitor_xsync_handle_xevent,
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
event);
|
MetaIdleMonitor *idle_monitor;
|
||||||
|
XSyncAlarmAttributes attr;
|
||||||
|
|
||||||
|
if (alarm_event->state != XSyncAlarmActive ||
|
||||||
|
alarm_event->alarm != priv->user_active_alarm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
attr.events = TRUE;
|
||||||
|
XSyncChangeAlarm (priv->xdisplay, priv->user_active_alarm,
|
||||||
|
XSyncCAEvents, &attr);
|
||||||
|
|
||||||
|
idle_monitor = meta_backend_get_idle_monitor (backend, 0);
|
||||||
|
meta_idle_monitor_reset_idletime (idle_monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -102,6 +172,26 @@ meta_backend_x11_translate_device_event (MetaBackendX11 *x11,
|
|||||||
backend_x11_class->translate_device_event (x11, device_event);
|
backend_x11_class->translate_device_event (x11, device_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
maybe_translate_touch_replay_pointer_event (MetaBackendX11 *x11,
|
||||||
|
XIDeviceEvent *device_event)
|
||||||
|
{
|
||||||
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
|
|
||||||
|
if (!device_event->send_event &&
|
||||||
|
device_event->time != CurrentTime &&
|
||||||
|
priv->current_touch_replay_sync_serial !=
|
||||||
|
priv->pending_touch_replay_sync_serial &&
|
||||||
|
XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime))
|
||||||
|
{
|
||||||
|
/* Emulated pointer events received after XIRejectTouch is received
|
||||||
|
* on a passive touch grab will contain older timestamps, update those
|
||||||
|
* so we dont get InvalidTime at grabs.
|
||||||
|
*/
|
||||||
|
device_event->time = priv->latest_evtime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
translate_device_event (MetaBackendX11 *x11,
|
translate_device_event (MetaBackendX11 *x11,
|
||||||
XIDeviceEvent *device_event)
|
XIDeviceEvent *device_event)
|
||||||
@ -111,19 +201,7 @@ translate_device_event (MetaBackendX11 *x11,
|
|||||||
meta_backend_x11_translate_device_event (x11, device_event);
|
meta_backend_x11_translate_device_event (x11, device_event);
|
||||||
|
|
||||||
if (!device_event->send_event && device_event->time != CurrentTime)
|
if (!device_event->send_event && device_event->time != CurrentTime)
|
||||||
{
|
|
||||||
if (XSERVER_TIME_IS_BEFORE (device_event->time, priv->latest_evtime))
|
|
||||||
{
|
|
||||||
/* Emulated pointer events received after XIRejectTouch is received
|
|
||||||
* on a passive touch grab will contain older timestamps, update those
|
|
||||||
* so we dont get InvalidTime at grabs.
|
|
||||||
*/
|
|
||||||
device_event->time = priv->latest_evtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update the internal latest evtime, for any possible later use */
|
|
||||||
priv->latest_evtime = device_event->time;
|
priv->latest_evtime = device_event->time;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -188,6 +266,9 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
|
|||||||
case XI_Motion:
|
case XI_Motion:
|
||||||
case XI_ButtonPress:
|
case XI_ButtonPress:
|
||||||
case XI_ButtonRelease:
|
case XI_ButtonRelease:
|
||||||
|
maybe_translate_touch_replay_pointer_event (x11,
|
||||||
|
(XIDeviceEvent *) input_event);
|
||||||
|
/* Intentional fall-through */
|
||||||
case XI_KeyPress:
|
case XI_KeyPress:
|
||||||
case XI_KeyRelease:
|
case XI_KeyRelease:
|
||||||
case XI_TouchBegin:
|
case XI_TouchBegin:
|
||||||
@ -255,6 +336,17 @@ handle_host_xevent (MetaBackend *backend,
|
|||||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
gboolean bypass_clutter = FALSE;
|
gboolean bypass_clutter = FALSE;
|
||||||
|
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case ClientMessage:
|
||||||
|
if (event->xclient.window == meta_backend_x11_get_xwindow (x11) &&
|
||||||
|
event->xclient.message_type == priv->touch_replay_sync_atom)
|
||||||
|
priv->current_touch_replay_sync_serial = event->xclient.data.l[0];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
XGetEventData (priv->xdisplay, &event->xcookie);
|
XGetEventData (priv->xdisplay, &event->xcookie);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -275,7 +367,7 @@ handle_host_xevent (MetaBackend *backend,
|
|||||||
bypass_clutter);
|
bypass_clutter);
|
||||||
|
|
||||||
if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
|
if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
|
||||||
handle_alarm_notify (backend, event);
|
handle_alarm_notify (backend, (XSyncAlarmNotifyEvent *) event);
|
||||||
|
|
||||||
if (event->type == priv->xkb_event_base)
|
if (event->type == priv->xkb_event_base)
|
||||||
{
|
{
|
||||||
@ -423,6 +515,12 @@ meta_backend_x11_post_init (MetaBackend *backend)
|
|||||||
!XSyncInitialize (priv->xdisplay, &major, &minor))
|
!XSyncInitialize (priv->xdisplay, &major, &minor))
|
||||||
meta_fatal ("Could not initialize XSync");
|
meta_fatal ("Could not initialize XSync");
|
||||||
|
|
||||||
|
priv->counter = find_idletime_counter (priv);
|
||||||
|
if (priv->counter == None)
|
||||||
|
meta_fatal ("Could not initialize XSync counter");
|
||||||
|
|
||||||
|
priv->user_active_alarm = xsync_user_active_alarm_set (priv);
|
||||||
|
|
||||||
if (XQueryExtension (priv->xdisplay,
|
if (XQueryExtension (priv->xdisplay,
|
||||||
"XInputExtension",
|
"XInputExtension",
|
||||||
&priv->xinput_opcode,
|
&priv->xinput_opcode,
|
||||||
@ -456,6 +554,10 @@ meta_backend_x11_post_init (MetaBackend *backend)
|
|||||||
monitor_manager = meta_backend_get_monitor_manager (backend);
|
monitor_manager = meta_backend_get_monitor_manager (backend);
|
||||||
g_signal_connect (monitor_manager, "monitors-changed-internal",
|
g_signal_connect (monitor_manager, "monitors-changed-internal",
|
||||||
G_CALLBACK (on_monitors_changed), backend);
|
G_CALLBACK (on_monitors_changed), backend);
|
||||||
|
|
||||||
|
priv->touch_replay_sync_atom = XInternAtom (priv->xdisplay,
|
||||||
|
"_MUTTER_TOUCH_SEQUENCE_SYNC",
|
||||||
|
False);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClutterBackend *
|
static ClutterBackend *
|
||||||
@ -464,15 +566,6 @@ meta_backend_x11_create_clutter_backend (MetaBackend *backend)
|
|||||||
return g_object_new (META_TYPE_CLUTTER_BACKEND_X11, NULL);
|
return g_object_new (META_TYPE_CLUTTER_BACKEND_X11, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaIdleMonitor *
|
|
||||||
meta_backend_x11_create_idle_monitor (MetaBackend *backend,
|
|
||||||
int device_id)
|
|
||||||
{
|
|
||||||
return g_object_new (META_TYPE_IDLE_MONITOR_XSYNC,
|
|
||||||
"device-id", device_id,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_backend_x11_grab_device (MetaBackend *backend,
|
meta_backend_x11_grab_device (MetaBackend *backend,
|
||||||
int device_id,
|
int device_id,
|
||||||
@ -484,8 +577,9 @@ meta_backend_x11_grab_device (MetaBackend *backend,
|
|||||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (timestamp != CurrentTime)
|
if (timestamp != CurrentTime &&
|
||||||
timestamp = MAX (timestamp, priv->latest_evtime);
|
XSERVER_TIME_IS_BEFORE (timestamp, priv->latest_evtime))
|
||||||
|
timestamp = priv->latest_evtime;
|
||||||
|
|
||||||
XISetMask (mask.mask, XI_ButtonPress);
|
XISetMask (mask.mask, XI_ButtonPress);
|
||||||
XISetMask (mask.mask, XI_ButtonRelease);
|
XISetMask (mask.mask, XI_ButtonRelease);
|
||||||
@ -520,6 +614,43 @@ meta_backend_x11_ungrab_device (MetaBackend *backend,
|
|||||||
return (ret == Success);
|
return (ret == Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_backend_x11_finish_touch_sequence (MetaBackend *backend,
|
||||||
|
ClutterEventSequence *sequence,
|
||||||
|
MetaSequenceState state)
|
||||||
|
{
|
||||||
|
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||||
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
|
int event_mode;
|
||||||
|
|
||||||
|
if (state == META_SEQUENCE_ACCEPTED)
|
||||||
|
event_mode = XIAcceptTouch;
|
||||||
|
else if (state == META_SEQUENCE_REJECTED)
|
||||||
|
event_mode = XIRejectTouch;
|
||||||
|
else
|
||||||
|
g_return_if_reached ();
|
||||||
|
|
||||||
|
XIAllowTouchEvents (priv->xdisplay,
|
||||||
|
META_VIRTUAL_CORE_POINTER_ID,
|
||||||
|
clutter_x11_event_sequence_get_touch_detail (sequence),
|
||||||
|
DefaultRootWindow (priv->xdisplay), event_mode);
|
||||||
|
|
||||||
|
if (state == META_SEQUENCE_REJECTED)
|
||||||
|
{
|
||||||
|
XClientMessageEvent ev;
|
||||||
|
|
||||||
|
ev = (XClientMessageEvent) {
|
||||||
|
.type = ClientMessage,
|
||||||
|
.window = meta_backend_x11_get_xwindow (x11),
|
||||||
|
.message_type = priv->touch_replay_sync_atom,
|
||||||
|
.format = 32,
|
||||||
|
.data.l[0] = ++priv->pending_touch_replay_sync_serial,
|
||||||
|
};
|
||||||
|
XSendEvent (priv->xdisplay, meta_backend_x11_get_xwindow (x11),
|
||||||
|
False, 0, (XEvent *) &ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_backend_x11_warp_pointer (MetaBackend *backend,
|
meta_backend_x11_warp_pointer (MetaBackend *backend,
|
||||||
int x,
|
int x,
|
||||||
@ -679,16 +810,33 @@ initable_iface_init (GInitableIface *initable_iface)
|
|||||||
initable_iface->init = meta_backend_x11_initable_init;
|
initable_iface->init = meta_backend_x11_initable_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_backend_x11_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
MetaBackendX11 *x11 = META_BACKEND_X11 (object);
|
||||||
|
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||||
|
|
||||||
|
if (priv->user_active_alarm != None)
|
||||||
|
{
|
||||||
|
XSyncDestroyAlarm (priv->xdisplay, priv->user_active_alarm);
|
||||||
|
priv->user_active_alarm = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (meta_backend_x11_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
||||||
{
|
{
|
||||||
MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
|
MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = meta_backend_x11_finalize;
|
||||||
backend_class->create_clutter_backend = meta_backend_x11_create_clutter_backend;
|
backend_class->create_clutter_backend = meta_backend_x11_create_clutter_backend;
|
||||||
backend_class->post_init = meta_backend_x11_post_init;
|
backend_class->post_init = meta_backend_x11_post_init;
|
||||||
backend_class->create_idle_monitor = meta_backend_x11_create_idle_monitor;
|
|
||||||
backend_class->grab_device = meta_backend_x11_grab_device;
|
backend_class->grab_device = meta_backend_x11_grab_device;
|
||||||
backend_class->ungrab_device = meta_backend_x11_ungrab_device;
|
backend_class->ungrab_device = meta_backend_x11_ungrab_device;
|
||||||
|
backend_class->finish_touch_sequence = meta_backend_x11_finish_touch_sequence;
|
||||||
backend_class->warp_pointer = meta_backend_x11_warp_pointer;
|
backend_class->warp_pointer = meta_backend_x11_warp_pointer;
|
||||||
backend_class->get_current_logical_monitor = meta_backend_x11_get_current_logical_monitor;
|
backend_class->get_current_logical_monitor = meta_backend_x11_get_current_logical_monitor;
|
||||||
backend_class->get_keymap = meta_backend_x11_get_keymap;
|
backend_class->get_keymap = meta_backend_x11_get_keymap;
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include <X11/extensions/Xfixes.h>
|
#include <X11/extensions/Xfixes.h>
|
||||||
|
|
||||||
#include "meta-backend-x11.h"
|
#include "meta-backend-x11.h"
|
||||||
#include "meta-stage.h"
|
#include "meta-stage-private.h"
|
||||||
|
|
||||||
struct _MetaCursorRendererX11Private
|
struct _MetaCursorRendererX11Private
|
||||||
{
|
{
|
||||||
|
@ -1,373 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2013 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Adapted from gnome-session/gnome-session/gs-idle-monitor.c and
|
|
||||||
* from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "meta-idle-monitor-xsync.h"
|
|
||||||
#include "meta-idle-monitor-private.h"
|
|
||||||
|
|
||||||
#include "meta-backend-x11.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
struct _MetaIdleMonitorXSync
|
|
||||||
{
|
|
||||||
MetaIdleMonitor parent;
|
|
||||||
|
|
||||||
GHashTable *alarms;
|
|
||||||
Display *display;
|
|
||||||
XSyncCounter counter;
|
|
||||||
XSyncAlarm user_active_alarm;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _MetaIdleMonitorXSyncClass
|
|
||||||
{
|
|
||||||
MetaIdleMonitorClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
MetaIdleMonitorWatch base;
|
|
||||||
|
|
||||||
XSyncAlarm xalarm;
|
|
||||||
} MetaIdleMonitorWatchXSync;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaIdleMonitorXSync, meta_idle_monitor_xsync, META_TYPE_IDLE_MONITOR)
|
|
||||||
|
|
||||||
static gint64
|
|
||||||
_xsyncvalue_to_int64 (XSyncValue value)
|
|
||||||
{
|
|
||||||
return ((guint64) XSyncValueHigh32 (value)) << 32
|
|
||||||
| (guint64) XSyncValueLow32 (value);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GUINT64_TO_XSYNCVALUE(value, ret) XSyncIntsToValue (ret, (value) & 0xFFFFFFFF, ((guint64)(value)) >> 32)
|
|
||||||
|
|
||||||
static XSyncAlarm
|
|
||||||
_xsync_alarm_set (MetaIdleMonitorXSync *monitor_xsync,
|
|
||||||
XSyncTestType test_type,
|
|
||||||
guint64 interval,
|
|
||||||
gboolean want_events)
|
|
||||||
{
|
|
||||||
XSyncAlarmAttributes attr;
|
|
||||||
XSyncValue delta;
|
|
||||||
guint flags;
|
|
||||||
|
|
||||||
flags = XSyncCACounter | XSyncCAValueType | XSyncCATestType |
|
|
||||||
XSyncCAValue | XSyncCADelta | XSyncCAEvents;
|
|
||||||
|
|
||||||
XSyncIntToValue (&delta, 0);
|
|
||||||
attr.trigger.counter = monitor_xsync->counter;
|
|
||||||
attr.trigger.value_type = XSyncAbsolute;
|
|
||||||
attr.delta = delta;
|
|
||||||
attr.events = want_events;
|
|
||||||
|
|
||||||
GUINT64_TO_XSYNCVALUE (interval, &attr.trigger.wait_value);
|
|
||||||
attr.trigger.test_type = test_type;
|
|
||||||
return XSyncCreateAlarm (monitor_xsync->display, flags, &attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ensure_alarm_rescheduled (Display *dpy,
|
|
||||||
XSyncAlarm alarm)
|
|
||||||
{
|
|
||||||
XSyncAlarmAttributes attr;
|
|
||||||
|
|
||||||
/* Some versions of Xorg have an issue where alarms aren't
|
|
||||||
* always rescheduled. Calling XSyncChangeAlarm, even
|
|
||||||
* without any attributes, will reschedule the alarm. */
|
|
||||||
XSyncChangeAlarm (dpy, alarm, 0, &attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_alarm_enabled (Display *dpy,
|
|
||||||
XSyncAlarm alarm,
|
|
||||||
gboolean enabled)
|
|
||||||
{
|
|
||||||
XSyncAlarmAttributes attr;
|
|
||||||
attr.events = enabled;
|
|
||||||
XSyncChangeAlarm (dpy, alarm, XSyncCAEvents, &attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
counter_name_for_device (int device_id)
|
|
||||||
{
|
|
||||||
if (device_id > 0)
|
|
||||||
return g_strdup_printf ("DEVICEIDLETIME %d", device_id);
|
|
||||||
|
|
||||||
return g_strdup ("IDLETIME");
|
|
||||||
}
|
|
||||||
|
|
||||||
static XSyncCounter
|
|
||||||
find_idletime_counter (MetaIdleMonitorXSync *monitor_xsync)
|
|
||||||
{
|
|
||||||
MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_xsync);
|
|
||||||
int i;
|
|
||||||
int ncounters;
|
|
||||||
XSyncSystemCounter *counters;
|
|
||||||
XSyncCounter counter = None;
|
|
||||||
char *counter_name;
|
|
||||||
|
|
||||||
counter_name = counter_name_for_device (monitor->device_id);
|
|
||||||
counters = XSyncListSystemCounters (monitor_xsync->display, &ncounters);
|
|
||||||
for (i = 0; i < ncounters; i++)
|
|
||||||
{
|
|
||||||
if (counters[i].name != NULL && strcmp (counters[i].name, counter_name) == 0)
|
|
||||||
{
|
|
||||||
counter = counters[i].counter;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
XSyncFreeSystemCounterList (counters);
|
|
||||||
g_free (counter_name);
|
|
||||||
|
|
||||||
return counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
init_xsync (MetaIdleMonitorXSync *monitor_xsync)
|
|
||||||
{
|
|
||||||
monitor_xsync->counter = find_idletime_counter (monitor_xsync);
|
|
||||||
/* IDLETIME counter not found? */
|
|
||||||
if (monitor_xsync->counter == None)
|
|
||||||
{
|
|
||||||
g_warning ("IDLETIME counter not found\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor_xsync->user_active_alarm = _xsync_alarm_set (monitor_xsync, XSyncNegativeTransition, 1, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_idle_monitor_xsync_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (object);
|
|
||||||
|
|
||||||
if (monitor_xsync->user_active_alarm != None)
|
|
||||||
{
|
|
||||||
XSyncDestroyAlarm (monitor_xsync->display, monitor_xsync->user_active_alarm);
|
|
||||||
monitor_xsync->user_active_alarm = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_clear_pointer (&monitor_xsync->alarms, g_hash_table_destroy);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_idle_monitor_xsync_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_idle_monitor_xsync_constructed (GObject *object)
|
|
||||||
{
|
|
||||||
MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (object);
|
|
||||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
|
||||||
|
|
||||||
monitor_xsync->display = meta_backend_x11_get_xdisplay (backend);
|
|
||||||
init_xsync (monitor_xsync);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_idle_monitor_xsync_parent_class)->constructed (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gint64
|
|
||||||
meta_idle_monitor_xsync_get_idletime (MetaIdleMonitor *monitor)
|
|
||||||
{
|
|
||||||
MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor);
|
|
||||||
XSyncValue value;
|
|
||||||
|
|
||||||
if (!XSyncQueryCounter (monitor_xsync->display, monitor_xsync->counter, &value))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return _xsyncvalue_to_int64 (value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
fire_watch_idle (gpointer data)
|
|
||||||
{
|
|
||||||
MetaIdleMonitorWatch *watch = data;
|
|
||||||
|
|
||||||
watch->idle_source_id = 0;
|
|
||||||
_meta_idle_monitor_watch_fire (watch);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static guint32
|
|
||||||
get_next_watch_serial (void)
|
|
||||||
{
|
|
||||||
static guint32 serial = 0;
|
|
||||||
g_atomic_int_inc (&serial);
|
|
||||||
return serial;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
free_watch (gpointer data)
|
|
||||||
{
|
|
||||||
MetaIdleMonitorWatchXSync *watch_xsync = data;
|
|
||||||
MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_xsync;
|
|
||||||
MetaIdleMonitor *monitor = watch->monitor;
|
|
||||||
MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor);
|
|
||||||
|
|
||||||
g_object_ref (monitor);
|
|
||||||
|
|
||||||
if (watch->idle_source_id)
|
|
||||||
{
|
|
||||||
g_source_remove (watch->idle_source_id);
|
|
||||||
watch->idle_source_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (watch->notify != NULL)
|
|
||||||
watch->notify (watch->user_data);
|
|
||||||
|
|
||||||
if (watch_xsync->xalarm != monitor_xsync->user_active_alarm &&
|
|
||||||
watch_xsync->xalarm != None)
|
|
||||||
{
|
|
||||||
XSyncDestroyAlarm (monitor_xsync->display, watch_xsync->xalarm);
|
|
||||||
g_hash_table_remove (monitor_xsync->alarms, (gpointer) watch_xsync->xalarm);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref (monitor);
|
|
||||||
g_slice_free (MetaIdleMonitorWatchXSync, watch_xsync);
|
|
||||||
}
|
|
||||||
|
|
||||||
static MetaIdleMonitorWatch *
|
|
||||||
meta_idle_monitor_xsync_make_watch (MetaIdleMonitor *monitor,
|
|
||||||
guint64 timeout_msec,
|
|
||||||
MetaIdleMonitorWatchFunc callback,
|
|
||||||
gpointer user_data,
|
|
||||||
GDestroyNotify notify)
|
|
||||||
{
|
|
||||||
MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor);
|
|
||||||
MetaIdleMonitorWatchXSync *watch_xsync;
|
|
||||||
MetaIdleMonitorWatch *watch;
|
|
||||||
|
|
||||||
watch_xsync = g_slice_new0 (MetaIdleMonitorWatchXSync);
|
|
||||||
watch = (MetaIdleMonitorWatch *) watch_xsync;
|
|
||||||
|
|
||||||
watch->monitor = monitor;
|
|
||||||
watch->id = get_next_watch_serial ();
|
|
||||||
watch->callback = callback;
|
|
||||||
watch->user_data = user_data;
|
|
||||||
watch->notify = notify;
|
|
||||||
watch->timeout_msec = timeout_msec;
|
|
||||||
|
|
||||||
if (monitor_xsync->user_active_alarm != None)
|
|
||||||
{
|
|
||||||
if (timeout_msec != 0)
|
|
||||||
{
|
|
||||||
watch_xsync->xalarm = _xsync_alarm_set (monitor_xsync, XSyncPositiveTransition, timeout_msec, TRUE);
|
|
||||||
|
|
||||||
g_hash_table_add (monitor_xsync->alarms, (gpointer) watch_xsync->xalarm);
|
|
||||||
|
|
||||||
if (meta_idle_monitor_get_idletime (monitor) > (gint64)timeout_msec)
|
|
||||||
{
|
|
||||||
watch->idle_source_id = g_idle_add (fire_watch_idle, watch);
|
|
||||||
g_source_set_name_by_id (watch->idle_source_id, "[mutter] fire_watch_idle");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
watch_xsync->xalarm = monitor_xsync->user_active_alarm;
|
|
||||||
|
|
||||||
set_alarm_enabled (monitor_xsync->display, monitor_xsync->user_active_alarm, TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return watch;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_idle_monitor_xsync_class_init (MetaIdleMonitorXSyncClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
MetaIdleMonitorClass *idle_monitor_class = META_IDLE_MONITOR_CLASS (klass);
|
|
||||||
|
|
||||||
object_class->dispose = meta_idle_monitor_xsync_dispose;
|
|
||||||
object_class->constructed = meta_idle_monitor_xsync_constructed;
|
|
||||||
|
|
||||||
idle_monitor_class->get_idletime = meta_idle_monitor_xsync_get_idletime;
|
|
||||||
idle_monitor_class->make_watch = meta_idle_monitor_xsync_make_watch;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
meta_idle_monitor_xsync_init (MetaIdleMonitorXSync *monitor_xsync)
|
|
||||||
{
|
|
||||||
MetaIdleMonitor *monitor = META_IDLE_MONITOR (monitor_xsync);
|
|
||||||
|
|
||||||
monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch);
|
|
||||||
monitor_xsync->alarms = g_hash_table_new (NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
check_x11_watches (MetaIdleMonitor *monitor,
|
|
||||||
XSyncAlarm alarm)
|
|
||||||
{
|
|
||||||
GList *node, *watch_ids;
|
|
||||||
|
|
||||||
/* we get the keys and do explicit look ups in case
|
|
||||||
* an early iteration of the loop ends up leading
|
|
||||||
* to watches from later iterations getting invalidated
|
|
||||||
*/
|
|
||||||
watch_ids = g_hash_table_get_keys (monitor->watches);
|
|
||||||
|
|
||||||
for (node = watch_ids; node != NULL; node = node->next)
|
|
||||||
{
|
|
||||||
guint watch_id = GPOINTER_TO_UINT (node->data);
|
|
||||||
MetaIdleMonitorWatchXSync *watch;
|
|
||||||
|
|
||||||
watch = g_hash_table_lookup (monitor->watches, GUINT_TO_POINTER (watch_id));
|
|
||||||
|
|
||||||
if (watch && watch->xalarm == alarm)
|
|
||||||
_meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_list_free (watch_ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor *monitor,
|
|
||||||
XSyncAlarmNotifyEvent *alarm_event)
|
|
||||||
{
|
|
||||||
MetaIdleMonitorXSync *monitor_xsync = META_IDLE_MONITOR_XSYNC (monitor);
|
|
||||||
XSyncAlarm alarm;
|
|
||||||
gboolean has_alarm;
|
|
||||||
|
|
||||||
if (alarm_event->state != XSyncAlarmActive)
|
|
||||||
return;
|
|
||||||
|
|
||||||
alarm = alarm_event->alarm;
|
|
||||||
|
|
||||||
has_alarm = FALSE;
|
|
||||||
|
|
||||||
if (alarm == monitor_xsync->user_active_alarm)
|
|
||||||
{
|
|
||||||
set_alarm_enabled (monitor_xsync->display,
|
|
||||||
alarm,
|
|
||||||
FALSE);
|
|
||||||
has_alarm = TRUE;
|
|
||||||
}
|
|
||||||
else if (g_hash_table_contains (monitor_xsync->alarms, (gpointer) alarm))
|
|
||||||
{
|
|
||||||
ensure_alarm_rescheduled (monitor_xsync->display,
|
|
||||||
alarm);
|
|
||||||
has_alarm = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (has_alarm)
|
|
||||||
check_x11_watches (monitor, alarm);
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2013 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Adapted from gnome-session/gnome-session/gs-idle-monitor.c and
|
|
||||||
* from gnome-desktop/libgnome-desktop/gnome-idle-monitor.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef META_IDLE_MONITOR_XSYNC_H
|
|
||||||
#define META_IDLE_MONITOR_XSYNC_H
|
|
||||||
|
|
||||||
#include <glib-object.h>
|
|
||||||
#include <meta/meta-idle-monitor.h>
|
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/extensions/sync.h>
|
|
||||||
|
|
||||||
#define META_TYPE_IDLE_MONITOR_XSYNC (meta_idle_monitor_xsync_get_type ())
|
|
||||||
#define META_IDLE_MONITOR_XSYNC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_IDLE_MONITOR_XSYNC, MetaIdleMonitorXSync))
|
|
||||||
#define META_IDLE_MONITOR_XSYNC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_IDLE_MONITOR_XSYNC, MetaIdleMonitorXSyncClass))
|
|
||||||
#define META_IS_IDLE_MONITOR_XSYNC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_IDLE_MONITOR_XSYNC))
|
|
||||||
#define META_IS_IDLE_MONITOR_XSYNC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_IDLE_MONITOR_XSYNC))
|
|
||||||
#define META_IDLE_MONITOR_XSYNC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_IDLE_MONITOR_XSYNC, MetaIdleMonitorXSyncClass))
|
|
||||||
|
|
||||||
typedef struct _MetaIdleMonitorXSync MetaIdleMonitorXSync;
|
|
||||||
typedef struct _MetaIdleMonitorXSyncClass MetaIdleMonitorXSyncClass;
|
|
||||||
|
|
||||||
GType meta_idle_monitor_xsync_get_type (void);
|
|
||||||
|
|
||||||
void meta_idle_monitor_xsync_handle_xevent (MetaIdleMonitor *monitor,
|
|
||||||
XSyncAlarmNotifyEvent *xevent);
|
|
||||||
|
|
||||||
#endif /* META_IDLE_MONITOR_XSYNC_H */
|
|
@ -225,8 +225,10 @@ is_crtc_assignment_changed (MetaCrtc *crtc,
|
|||||||
for (j = 0; j < crtc_info->outputs->len; j++)
|
for (j = 0; j < crtc_info->outputs->len; j++)
|
||||||
{
|
{
|
||||||
MetaOutput *output = ((MetaOutput**) crtc_info->outputs->pdata)[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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,6 +245,7 @@ is_output_assignment_changed (MetaOutput *output,
|
|||||||
MetaOutputInfo **output_infos,
|
MetaOutputInfo **output_infos,
|
||||||
unsigned int n_output_infos)
|
unsigned int n_output_infos)
|
||||||
{
|
{
|
||||||
|
MetaCrtc *assigned_crtc;
|
||||||
gboolean output_is_found = FALSE;
|
gboolean output_is_found = FALSE;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
@ -265,8 +268,10 @@ is_output_assignment_changed (MetaOutput *output,
|
|||||||
output_is_found = TRUE;
|
output_is_found = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assigned_crtc = meta_output_get_assigned_crtc (output);
|
||||||
|
|
||||||
if (!output_is_found)
|
if (!output_is_found)
|
||||||
return output->crtc != NULL;
|
return assigned_crtc != NULL;
|
||||||
|
|
||||||
for (i = 0; i < n_crtc_infos; i++)
|
for (i = 0; i < n_crtc_infos; i++)
|
||||||
{
|
{
|
||||||
@ -279,7 +284,7 @@ is_output_assignment_changed (MetaOutput *output,
|
|||||||
((MetaOutput**) crtc_info->outputs->pdata)[j];
|
((MetaOutput**) crtc_info->outputs->pdata)[j];
|
||||||
|
|
||||||
if (crtc_info_output == output &&
|
if (crtc_info_output == output &&
|
||||||
crtc_info->crtc == output->crtc)
|
crtc_info->crtc == assigned_crtc)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -455,7 +460,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
|||||||
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
|
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
|
||||||
|
|
||||||
output->is_dirty = TRUE;
|
output->is_dirty = TRUE;
|
||||||
output->crtc = crtc;
|
meta_output_assign_crtc (output, crtc);
|
||||||
|
|
||||||
output_ids[j] = output->winsys_id;
|
output_ids[j] = output->winsys_id;
|
||||||
}
|
}
|
||||||
@ -521,7 +526,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
output->crtc = NULL;
|
meta_output_unassign_crtc (output);
|
||||||
output->is_primary = FALSE;
|
output->is_primary = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,10 +97,13 @@ output_set_underscanning_xrandr (MetaOutput *output,
|
|||||||
* make the border configurable. */
|
* make the border configurable. */
|
||||||
if (underscanning)
|
if (underscanning)
|
||||||
{
|
{
|
||||||
|
MetaCrtc *crtc;
|
||||||
uint32_t border_value;
|
uint32_t border_value;
|
||||||
|
|
||||||
|
crtc = meta_output_get_assigned_crtc (output);
|
||||||
|
|
||||||
prop = XInternAtom (xdisplay, "underscan hborder", False);
|
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),
|
xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
|
||||||
(XID) output->winsys_id,
|
(XID) output->winsys_id,
|
||||||
@ -109,7 +112,7 @@ output_set_underscanning_xrandr (MetaOutput *output,
|
|||||||
1, &border_value);
|
1, &border_value);
|
||||||
|
|
||||||
prop = XInternAtom (xdisplay, "underscan vborder", False);
|
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),
|
xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
|
||||||
(XID) output->winsys_id,
|
(XID) output->winsys_id,
|
||||||
@ -737,14 +740,14 @@ output_get_crtcs (MetaOutput *output,
|
|||||||
}
|
}
|
||||||
output->n_possible_crtcs = n_actual_crtcs;
|
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)
|
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaCrtc *crtc = l->data;
|
MetaCrtc *crtc = l->data;
|
||||||
|
|
||||||
if ((XID) crtc->crtc_id == xrandr_output->crtc)
|
if ((XID) crtc->crtc_id == xrandr_output->crtc)
|
||||||
{
|
{
|
||||||
output->crtc = crtc;
|
meta_output_assign_crtc (output, crtc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ draw_crtc (MetaMonitor *monitor,
|
|||||||
CoglTexture *texture = data->texture;
|
CoglTexture *texture = data->texture;
|
||||||
MetaLogicalMonitor *logical_monitor = data->logical_monitor;
|
MetaLogicalMonitor *logical_monitor = data->logical_monitor;
|
||||||
MetaOutput *output = monitor_crtc_mode->output;
|
MetaOutput *output = monitor_crtc_mode->output;
|
||||||
MetaCrtc *crtc = output->crtc;
|
MetaCrtc *crtc;
|
||||||
MetaRendererView *renderer_view = META_RENDERER_VIEW (data->view);
|
MetaRendererView *renderer_view = META_RENDERER_VIEW (data->view);
|
||||||
MetaMonitorTransform view_transform;
|
MetaMonitorTransform view_transform;
|
||||||
MetaMonitorTransform layout_transform = META_MONITOR_TRANSFORM_NORMAL;
|
MetaMonitorTransform layout_transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||||
@ -129,6 +129,8 @@ draw_crtc (MetaMonitor *monitor,
|
|||||||
texture_width = cogl_texture_get_width (texture);
|
texture_width = cogl_texture_get_width (texture);
|
||||||
texture_height = cogl_texture_get_height (texture);
|
texture_height = cogl_texture_get_height (texture);
|
||||||
|
|
||||||
|
crtc = meta_output_get_assigned_crtc (output);
|
||||||
|
|
||||||
clutter_stage_view_get_layout (data->view, &view_layout);
|
clutter_stage_view_get_layout (data->view, &view_layout);
|
||||||
sample_x = crtc->rect.x - view_layout.x;
|
sample_x = crtc->rect.x - view_layout.x;
|
||||||
sample_y = crtc->rect.y - view_layout.y;
|
sample_y = crtc->rect.y - view_layout.y;
|
||||||
|
@ -50,20 +50,22 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
|
|||||||
{
|
{
|
||||||
MetaMonitor *main_monitor;
|
MetaMonitor *main_monitor;
|
||||||
MetaOutput *main_output;
|
MetaOutput *main_output;
|
||||||
|
MetaCrtc *crtc;
|
||||||
MetaMonitorTransform crtc_transform;
|
MetaMonitorTransform crtc_transform;
|
||||||
|
|
||||||
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
|
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
|
||||||
main_output = meta_monitor_get_main_output (main_monitor);
|
main_output = meta_monitor_get_main_output (main_monitor);
|
||||||
|
crtc = meta_output_get_assigned_crtc (main_output);
|
||||||
crtc_transform =
|
crtc_transform =
|
||||||
meta_monitor_logical_to_crtc_transform (main_monitor,
|
meta_monitor_logical_to_crtc_transform (main_monitor,
|
||||||
logical_monitor->transform);
|
logical_monitor->transform);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pick any monitor and output and check; all CRTCs of a logical monitor will
|
* Pick any monitor and output and check; all CRTCs of a logical monitor will
|
||||||
* always have the same transform assigned to them.
|
* always have the same transform assigned to them.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (meta_monitor_manager_is_transform_handled (monitor_manager,
|
if (meta_monitor_manager_is_transform_handled (monitor_manager,
|
||||||
main_output->crtc,
|
crtc,
|
||||||
crtc_transform))
|
crtc_transform))
|
||||||
return META_MONITOR_TRANSFORM_NORMAL;
|
return META_MONITOR_TRANSFORM_NORMAL;
|
||||||
else
|
else
|
||||||
|
@ -18,6 +18,9 @@ struct _MetaCompositor
|
|||||||
guint pre_paint_func_id;
|
guint pre_paint_func_id;
|
||||||
guint post_paint_func_id;
|
guint post_paint_func_id;
|
||||||
|
|
||||||
|
guint stage_presented_id;
|
||||||
|
guint stage_after_paint_id;
|
||||||
|
|
||||||
gint64 server_time_query_time;
|
gint64 server_time_query_time;
|
||||||
gint64 server_time_offset;
|
gint64 server_time_offset;
|
||||||
|
|
||||||
@ -70,4 +73,6 @@ MetaCloseDialog * meta_compositor_create_close_dialog (MetaCompositor *composito
|
|||||||
MetaInhibitShortcutsDialog * meta_compositor_create_inhibit_shortcuts_dialog (MetaCompositor *compositor,
|
MetaInhibitShortcutsDialog * meta_compositor_create_inhibit_shortcuts_dialog (MetaCompositor *compositor,
|
||||||
MetaWindow *window);
|
MetaWindow *window);
|
||||||
|
|
||||||
|
void meta_compositor_unmanage_window_actors (MetaCompositor *compositor);
|
||||||
|
|
||||||
#endif /* META_COMPOSITOR_PRIVATE_H */
|
#endif /* META_COMPOSITOR_PRIVATE_H */
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
#include <meta/meta-background-group.h>
|
#include <meta/meta-background-group.h>
|
||||||
#include <meta/meta-shadow-factory.h>
|
#include <meta/meta-shadow-factory.h>
|
||||||
#include "meta-window-actor-private.h"
|
#include "meta-window-actor-private.h"
|
||||||
#include "meta-window-group.h"
|
#include "meta-window-group-private.h"
|
||||||
#include "window-private.h" /* to check window->hidden */
|
#include "window-private.h" /* to check window->hidden */
|
||||||
#include "display-private.h" /* for meta_display_lookup_x_window() and meta_display_cancel_touch() */
|
#include "display-private.h" /* for meta_display_lookup_x_window() and meta_display_cancel_touch() */
|
||||||
#include "util-private.h"
|
#include "util-private.h"
|
||||||
@ -90,6 +90,10 @@ on_presented (ClutterStage *stage,
|
|||||||
ClutterFrameInfo *frame_info,
|
ClutterFrameInfo *frame_info,
|
||||||
MetaCompositor *compositor);
|
MetaCompositor *compositor);
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_top_window_actor_destroyed (MetaWindowActor *window_actor,
|
||||||
|
MetaCompositor *compositor);
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_modal (MetaDisplay *display)
|
is_modal (MetaDisplay *display)
|
||||||
{
|
{
|
||||||
@ -129,6 +133,15 @@ meta_switch_workspace_completed (MetaCompositor *compositor)
|
|||||||
void
|
void
|
||||||
meta_compositor_destroy (MetaCompositor *compositor)
|
meta_compositor_destroy (MetaCompositor *compositor)
|
||||||
{
|
{
|
||||||
|
g_signal_handler_disconnect (compositor->stage,
|
||||||
|
compositor->stage_after_paint_id);
|
||||||
|
g_signal_handler_disconnect (compositor->stage,
|
||||||
|
compositor->stage_presented_id);
|
||||||
|
|
||||||
|
compositor->stage_after_paint_id = 0;
|
||||||
|
compositor->stage_presented_id = 0;
|
||||||
|
compositor->stage = NULL;
|
||||||
|
|
||||||
clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
|
clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
|
||||||
clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
|
clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
|
||||||
|
|
||||||
@ -499,6 +512,7 @@ meta_compositor_manage (MetaCompositor *compositor)
|
|||||||
|
|
||||||
compositor->stage = meta_backend_get_stage (backend);
|
compositor->stage = meta_backend_get_stage (backend);
|
||||||
|
|
||||||
|
compositor->stage_presented_id =
|
||||||
g_signal_connect (compositor->stage, "presented",
|
g_signal_connect (compositor->stage, "presented",
|
||||||
G_CALLBACK (on_presented),
|
G_CALLBACK (on_presented),
|
||||||
compositor);
|
compositor);
|
||||||
@ -511,7 +525,8 @@ meta_compositor_manage (MetaCompositor *compositor)
|
|||||||
* connections to ::after-paint, connect() vs. connect_after() doesn't
|
* connections to ::after-paint, connect() vs. connect_after() doesn't
|
||||||
* matter.
|
* matter.
|
||||||
*/
|
*/
|
||||||
g_signal_connect_after (CLUTTER_STAGE (compositor->stage), "after-paint",
|
compositor->stage_after_paint_id =
|
||||||
|
g_signal_connect_after (compositor->stage, "after-paint",
|
||||||
G_CALLBACK (after_stage_paint), compositor);
|
G_CALLBACK (after_stage_paint), compositor);
|
||||||
|
|
||||||
clutter_stage_set_sync_delay (CLUTTER_STAGE (compositor->stage), META_SYNC_DELAY);
|
clutter_stage_set_sync_delay (CLUTTER_STAGE (compositor->stage), META_SYNC_DELAY);
|
||||||
@ -582,6 +597,23 @@ meta_compositor_unmanage (MetaCompositor *compositor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_compositor_unmanage_window_actors (MetaCompositor *compositor)
|
||||||
|
{
|
||||||
|
if (compositor->top_window_actor)
|
||||||
|
{
|
||||||
|
g_signal_handlers_disconnect_by_func (compositor->top_window_actor,
|
||||||
|
on_top_window_actor_destroyed,
|
||||||
|
compositor);
|
||||||
|
compositor->top_window_actor = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_pointer (&compositor->window_group, clutter_actor_destroy);
|
||||||
|
g_clear_pointer (&compositor->top_window_group, clutter_actor_destroy);
|
||||||
|
g_clear_pointer (&compositor->feedback_group, clutter_actor_destroy);
|
||||||
|
g_clear_pointer (&compositor->windows, g_list_free);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_shape_cow_for_window:
|
* meta_shape_cow_for_window:
|
||||||
* @compositor: A #MetaCompositor
|
* @compositor: A #MetaCompositor
|
||||||
@ -798,6 +830,7 @@ meta_compositor_hide_window (MetaCompositor *compositor,
|
|||||||
{
|
{
|
||||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||||
meta_window_actor_hide (window_actor, effect);
|
meta_window_actor_hide (window_actor, effect);
|
||||||
|
meta_stack_tracker_queue_sync_stack (compositor->display->screen->stack_tracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -944,6 +977,9 @@ get_top_visible_window_actor (MetaCompositor *compositor)
|
|||||||
MetaWindow *window = meta_window_actor_get_meta_window (window_actor);
|
MetaWindow *window = meta_window_actor_get_meta_window (window_actor);
|
||||||
MetaRectangle buffer_rect;
|
MetaRectangle buffer_rect;
|
||||||
|
|
||||||
|
if (!window->visible_to_compositor)
|
||||||
|
continue;
|
||||||
|
|
||||||
meta_window_get_buffer_rect (window, &buffer_rect);
|
meta_window_get_buffer_rect (window, &buffer_rect);
|
||||||
|
|
||||||
if (meta_rectangle_overlap (&compositor->display->screen->rect,
|
if (meta_rectangle_overlap (&compositor->display->screen->rect,
|
||||||
|
@ -220,9 +220,7 @@ meta_shadow_paint (MetaShadow *shadow,
|
|||||||
int dest_x[4];
|
int dest_x[4];
|
||||||
int dest_y[4];
|
int dest_y[4];
|
||||||
int n_x, n_y;
|
int n_x, n_y;
|
||||||
|
gboolean source_updated = FALSE;
|
||||||
cogl_pipeline_set_color4ub (shadow->pipeline,
|
|
||||||
opacity, opacity, opacity, opacity);
|
|
||||||
|
|
||||||
cogl_set_source (shadow->pipeline);
|
cogl_set_source (shadow->pipeline);
|
||||||
|
|
||||||
@ -300,6 +298,17 @@ meta_shadow_paint (MetaShadow *shadow,
|
|||||||
else
|
else
|
||||||
overlap = CAIRO_REGION_OVERLAP_IN;
|
overlap = CAIRO_REGION_OVERLAP_IN;
|
||||||
|
|
||||||
|
if (overlap == CAIRO_REGION_OVERLAP_OUT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!source_updated)
|
||||||
|
{
|
||||||
|
cogl_pipeline_set_color4ub (shadow->pipeline,
|
||||||
|
opacity, opacity, opacity, opacity);
|
||||||
|
cogl_set_source (shadow->pipeline);
|
||||||
|
source_updated = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* There's quite a bit of overhead from allocating a new
|
/* There's quite a bit of overhead from allocating a new
|
||||||
* region in order to find an exact intersection and
|
* region in order to find an exact intersection and
|
||||||
* generating more geometry - we make the assumption that
|
* generating more geometry - we make the assumption that
|
||||||
|
@ -38,6 +38,20 @@
|
|||||||
|
|
||||||
#include "meta-cullable.h"
|
#include "meta-cullable.h"
|
||||||
|
|
||||||
|
/* MAX_MIPMAPPING_FPS needs to be as small as possible for the best GPU
|
||||||
|
* performance, but higher than the refresh rate of commonly slow updating
|
||||||
|
* windows like top or a blinking cursor, so that such windows do get
|
||||||
|
* mipmapped.
|
||||||
|
*/
|
||||||
|
#define MAX_MIPMAPPING_FPS 5
|
||||||
|
#define MIN_MIPMAP_AGE_USEC (G_USEC_PER_SEC / MAX_MIPMAPPING_FPS)
|
||||||
|
|
||||||
|
/* MIN_FAST_UPDATES_BEFORE_UNMIPMAP allows windows to update themselves
|
||||||
|
* occasionally without causing mipmapping to be disabled, so long as such
|
||||||
|
* an update takes fewer update_area calls than:
|
||||||
|
*/
|
||||||
|
#define MIN_FAST_UPDATES_BEFORE_UNMIPMAP 20
|
||||||
|
|
||||||
static void meta_shaped_texture_dispose (GObject *object);
|
static void meta_shaped_texture_dispose (GObject *object);
|
||||||
|
|
||||||
static void meta_shaped_texture_paint (ClutterActor *actor);
|
static void meta_shaped_texture_paint (ClutterActor *actor);
|
||||||
@ -95,6 +109,11 @@ struct _MetaShapedTexturePrivate
|
|||||||
guint tex_width, tex_height;
|
guint tex_width, tex_height;
|
||||||
guint fallback_width, fallback_height;
|
guint fallback_width, fallback_height;
|
||||||
|
|
||||||
|
gint64 prev_invalidation, last_invalidation;
|
||||||
|
guint fast_updates;
|
||||||
|
guint remipmap_timeout_id;
|
||||||
|
gint64 earliest_remipmap;
|
||||||
|
|
||||||
guint create_mipmaps : 1;
|
guint create_mipmaps : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -191,6 +210,12 @@ meta_shaped_texture_dispose (GObject *object)
|
|||||||
MetaShapedTexture *self = (MetaShapedTexture *) object;
|
MetaShapedTexture *self = (MetaShapedTexture *) object;
|
||||||
MetaShapedTexturePrivate *priv = self->priv;
|
MetaShapedTexturePrivate *priv = self->priv;
|
||||||
|
|
||||||
|
if (priv->remipmap_timeout_id)
|
||||||
|
{
|
||||||
|
g_source_remove (priv->remipmap_timeout_id);
|
||||||
|
priv->remipmap_timeout_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (priv->paint_tower)
|
if (priv->paint_tower)
|
||||||
meta_texture_tower_free (priv->paint_tower);
|
meta_texture_tower_free (priv->paint_tower);
|
||||||
priv->paint_tower = NULL;
|
priv->paint_tower = NULL;
|
||||||
@ -372,6 +397,21 @@ set_cogl_texture (MetaShapedTexture *stex,
|
|||||||
meta_texture_tower_set_base_texture (priv->paint_tower, cogl_tex);
|
meta_texture_tower_set_base_texture (priv->paint_tower, cogl_tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
texture_is_idle_and_not_mipmapped (gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaShapedTexture *stex = META_SHAPED_TEXTURE (user_data);
|
||||||
|
MetaShapedTexturePrivate *priv = stex->priv;
|
||||||
|
|
||||||
|
if ((g_get_monotonic_time () - priv->earliest_remipmap) < 0)
|
||||||
|
return G_SOURCE_CONTINUE;
|
||||||
|
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
|
||||||
|
priv->remipmap_timeout_id = 0;
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_shaped_texture_paint (ClutterActor *actor)
|
meta_shaped_texture_paint (ClutterActor *actor)
|
||||||
{
|
{
|
||||||
@ -381,9 +421,10 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|||||||
guchar opacity;
|
guchar opacity;
|
||||||
CoglContext *ctx;
|
CoglContext *ctx;
|
||||||
CoglFramebuffer *fb;
|
CoglFramebuffer *fb;
|
||||||
CoglTexture *paint_tex;
|
CoglTexture *paint_tex = NULL;
|
||||||
ClutterActorBox alloc;
|
ClutterActorBox alloc;
|
||||||
CoglPipelineFilter filter;
|
CoglPipelineFilter filter;
|
||||||
|
gint64 now = g_get_monotonic_time ();
|
||||||
|
|
||||||
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
|
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
|
||||||
return;
|
return;
|
||||||
@ -406,14 +447,35 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
|||||||
* Setting the texture quality to high without SGIS_generate_mipmap
|
* Setting the texture quality to high without SGIS_generate_mipmap
|
||||||
* support for TFP textures will result in fallbacks to XGetImage.
|
* support for TFP textures will result in fallbacks to XGetImage.
|
||||||
*/
|
*/
|
||||||
if (priv->create_mipmaps)
|
if (priv->create_mipmaps && priv->last_invalidation)
|
||||||
|
{
|
||||||
|
gint64 age = now - priv->last_invalidation;
|
||||||
|
|
||||||
|
if (age >= MIN_MIPMAP_AGE_USEC ||
|
||||||
|
priv->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP)
|
||||||
paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower);
|
paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower);
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if (paint_tex == NULL)
|
||||||
|
{
|
||||||
paint_tex = COGL_TEXTURE (priv->texture);
|
paint_tex = COGL_TEXTURE (priv->texture);
|
||||||
|
|
||||||
if (paint_tex == NULL)
|
if (paint_tex == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (priv->create_mipmaps)
|
||||||
|
{
|
||||||
|
/* Minus 1000 to ensure we don't fail the age test in timeout */
|
||||||
|
priv->earliest_remipmap = now + MIN_MIPMAP_AGE_USEC - 1000;
|
||||||
|
|
||||||
|
if (!priv->remipmap_timeout_id)
|
||||||
|
priv->remipmap_timeout_id =
|
||||||
|
g_timeout_add (MIN_MIPMAP_AGE_USEC / 1000,
|
||||||
|
texture_is_idle_and_not_mipmapped,
|
||||||
|
stex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tex_width = priv->tex_width;
|
tex_width = priv->tex_width;
|
||||||
tex_height = priv->tex_height;
|
tex_height = priv->tex_height;
|
||||||
|
|
||||||
@ -632,46 +694,11 @@ effective_unobscured_region (MetaShapedTexture *self)
|
|||||||
return priv->unobscured_region;
|
return priv->unobscured_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
get_unobscured_bounds (MetaShapedTexture *self,
|
|
||||||
cairo_rectangle_int_t *unobscured_bounds)
|
|
||||||
{
|
|
||||||
cairo_region_t *unobscured_region = effective_unobscured_region (self);
|
|
||||||
|
|
||||||
if (unobscured_region)
|
|
||||||
{
|
|
||||||
cairo_region_get_extents (unobscured_region, unobscured_bounds);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_shaped_texture_get_paint_volume (ClutterActor *actor,
|
meta_shaped_texture_get_paint_volume (ClutterActor *actor,
|
||||||
ClutterPaintVolume *volume)
|
ClutterPaintVolume *volume)
|
||||||
{
|
{
|
||||||
MetaShapedTexture *self = META_SHAPED_TEXTURE (actor);
|
return clutter_paint_volume_set_from_allocation (volume, actor);
|
||||||
ClutterActorBox box;
|
|
||||||
cairo_rectangle_int_t unobscured_bounds;
|
|
||||||
|
|
||||||
if (!clutter_actor_has_allocation (actor))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
clutter_actor_get_allocation_box (actor, &box);
|
|
||||||
|
|
||||||
if (get_unobscured_bounds (self, &unobscured_bounds))
|
|
||||||
{
|
|
||||||
box.x1 = MAX (unobscured_bounds.x, box.x1);
|
|
||||||
box.x2 = MIN (unobscured_bounds.x + unobscured_bounds.width, box.x2);
|
|
||||||
box.y1 = MAX (unobscured_bounds.y, box.y1);
|
|
||||||
box.y2 = MIN (unobscured_bounds.y + unobscured_bounds.height, box.y2);
|
|
||||||
}
|
|
||||||
box.x2 = MAX (box.x2, box.x1);
|
|
||||||
box.y2 = MAX (box.y2, box.y1);
|
|
||||||
|
|
||||||
clutter_paint_volume_union_box (volume, &box);
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -758,6 +785,20 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
|||||||
|
|
||||||
meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
|
meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
|
||||||
|
|
||||||
|
priv->prev_invalidation = priv->last_invalidation;
|
||||||
|
priv->last_invalidation = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
if (priv->prev_invalidation)
|
||||||
|
{
|
||||||
|
gint64 interval = priv->last_invalidation - priv->prev_invalidation;
|
||||||
|
gboolean fast_update = interval < MIN_MIPMAP_AGE_USEC;
|
||||||
|
|
||||||
|
if (!fast_update)
|
||||||
|
priv->fast_updates = 0;
|
||||||
|
else if (priv->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP)
|
||||||
|
priv->fast_updates++;
|
||||||
|
}
|
||||||
|
|
||||||
unobscured_region = effective_unobscured_region (stex);
|
unobscured_region = effective_unobscured_region (stex);
|
||||||
if (unobscured_region)
|
if (unobscured_region)
|
||||||
{
|
{
|
||||||
|
@ -101,6 +101,13 @@ meta_surface_actor_pick (ClutterActor *actor,
|
|||||||
clutter_actor_paint (child);
|
clutter_actor_paint (child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_surface_actor_get_paint_volume (ClutterActor *actor,
|
||||||
|
ClutterPaintVolume *volume)
|
||||||
|
{
|
||||||
|
return clutter_paint_volume_set_from_allocation (volume, actor);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_surface_actor_dispose (GObject *object)
|
meta_surface_actor_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
@ -120,6 +127,7 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
|
|||||||
|
|
||||||
object_class->dispose = meta_surface_actor_dispose;
|
object_class->dispose = meta_surface_actor_dispose;
|
||||||
actor_class->pick = meta_surface_actor_pick;
|
actor_class->pick = meta_surface_actor_pick;
|
||||||
|
actor_class->get_paint_volume = meta_surface_actor_get_paint_volume;
|
||||||
|
|
||||||
signals[REPAINT_SCHEDULED] = g_signal_new ("repaint-scheduled",
|
signals[REPAINT_SCHEDULED] = g_signal_new ("repaint-scheduled",
|
||||||
G_TYPE_FROM_CLASS (object_class),
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
|
@ -58,5 +58,6 @@ void meta_window_actor_effect_completed (MetaWindowActor *actor,
|
|||||||
|
|
||||||
MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self);
|
MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self);
|
||||||
void meta_window_actor_update_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 */
|
#endif /* META_WINDOW_ACTOR_PRIVATE_H */
|
||||||
|
@ -142,6 +142,8 @@ struct _FrameData
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
FIRST_FRAME,
|
FIRST_FRAME,
|
||||||
|
EFFECTS_COMPLETED,
|
||||||
|
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -238,6 +240,21 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
|
|||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
G_TYPE_NONE, 0);
|
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",
|
pspec = g_param_spec_object ("meta-window",
|
||||||
"MetaWindow",
|
"MetaWindow",
|
||||||
"The displayed MetaWindow",
|
"The displayed MetaWindow",
|
||||||
@ -1131,6 +1148,7 @@ meta_window_actor_after_effects (MetaWindowActor *self)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_signal_emit (self, signals[EFFECTS_COMPLETED], 0);
|
||||||
meta_window_actor_sync_visibility (self);
|
meta_window_actor_sync_visibility (self);
|
||||||
meta_window_actor_sync_actor_geometry (self, FALSE);
|
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));
|
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));
|
||||||
|
}
|
||||||
|
24
src/compositor/meta-window-group-private.h
Normal file
24
src/compositor/meta-window-group-private.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
|
||||||
|
#ifndef META_WINDOW_GROUP_PRIVATE_H
|
||||||
|
#define META_WINDOW_GROUP_PRIVATE_H
|
||||||
|
|
||||||
|
#include <meta/meta-window-group.h>
|
||||||
|
|
||||||
|
#include <meta/screen.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MetaWindowGroup:
|
||||||
|
*
|
||||||
|
* This class is a subclass of ClutterActor with special handling for
|
||||||
|
* #MetaCullable when painting children. It uses code similar to
|
||||||
|
* meta_cullable_cull_out_children(), but also has additional special
|
||||||
|
* cases for the undirected window, and similar.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _MetaWindowGroupPrivate MetaWindowGroupPrivate;
|
||||||
|
|
||||||
|
ClutterActor *meta_window_group_new (MetaScreen *screen);
|
||||||
|
|
||||||
|
#endif /* META_WINDOW_GROUP_PRIVATE_H */
|
@ -10,7 +10,7 @@
|
|||||||
#include "clutter-utils.h"
|
#include "clutter-utils.h"
|
||||||
#include "compositor-private.h"
|
#include "compositor-private.h"
|
||||||
#include "meta-window-actor-private.h"
|
#include "meta-window-actor-private.h"
|
||||||
#include "meta-window-group.h"
|
#include "meta-window-group-private.h"
|
||||||
#include "window-private.h"
|
#include "window-private.h"
|
||||||
#include "meta-cullable.h"
|
#include "meta-cullable.h"
|
||||||
|
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
|
|
||||||
#ifndef META_WINDOW_GROUP_H
|
|
||||||
#define META_WINDOW_GROUP_H
|
|
||||||
|
|
||||||
#include <clutter/clutter.h>
|
|
||||||
|
|
||||||
#include <meta/screen.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MetaWindowGroup:
|
|
||||||
*
|
|
||||||
* This class is a subclass of ClutterActor with special handling for
|
|
||||||
* #MetaCullable when painting children. It uses code similar to
|
|
||||||
* meta_cullable_cull_out_children(), but also has additional special
|
|
||||||
* cases for the undirected window, and similar.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define META_TYPE_WINDOW_GROUP (meta_window_group_get_type ())
|
|
||||||
#define META_WINDOW_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW_GROUP, MetaWindowGroup))
|
|
||||||
#define META_WINDOW_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW_GROUP, MetaWindowGroupClass))
|
|
||||||
#define META_IS_WINDOW_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WINDOW_GROUP))
|
|
||||||
#define META_IS_WINDOW_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WINDOW_GROUP))
|
|
||||||
#define META_WINDOW_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WINDOW_GROUP, MetaWindowGroupClass))
|
|
||||||
|
|
||||||
typedef struct _MetaWindowGroup MetaWindowGroup;
|
|
||||||
typedef struct _MetaWindowGroupClass MetaWindowGroupClass;
|
|
||||||
typedef struct _MetaWindowGroupPrivate MetaWindowGroupPrivate;
|
|
||||||
|
|
||||||
GType meta_window_group_get_type (void);
|
|
||||||
|
|
||||||
ClutterActor *meta_window_group_new (MetaScreen *screen);
|
|
||||||
|
|
||||||
gboolean meta_window_group_actor_is_untransformed (ClutterActor *actor,
|
|
||||||
int *x_origin,
|
|
||||||
int *y_origin);
|
|
||||||
#endif /* META_WINDOW_GROUP_H */
|
|
@ -886,7 +886,8 @@ constrain_modal_dialog (MetaWindow *window,
|
|||||||
MetaRectangle child_rect, parent_rect;
|
MetaRectangle child_rect, parent_rect;
|
||||||
gboolean constraint_already_satisfied;
|
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))
|
meta_window_get_placement_rule (window))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -115,5 +115,8 @@ meta_window_kill (MetaWindow *window)
|
|||||||
void
|
void
|
||||||
meta_window_free_delete_dialog (MetaWindow *window)
|
meta_window_free_delete_dialog (MetaWindow *window)
|
||||||
{
|
{
|
||||||
|
if (window->close_dialog &&
|
||||||
|
meta_close_dialog_is_visible (window->close_dialog))
|
||||||
|
meta_close_dialog_hide (window->close_dialog);
|
||||||
g_clear_object (&window->close_dialog);
|
g_clear_object (&window->close_dialog);
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,9 @@
|
|||||||
#include "backends/meta-logical-monitor.h"
|
#include "backends/meta-logical-monitor.h"
|
||||||
#include "backends/native/meta-backend-native.h"
|
#include "backends/native/meta-backend-native.h"
|
||||||
#include "backends/x11/meta-backend-x11.h"
|
#include "backends/x11/meta-backend-x11.h"
|
||||||
#include "backends/meta-stage.h"
|
#include "backends/meta-stage-private.h"
|
||||||
#include "backends/meta-input-settings-private.h"
|
#include "backends/meta-input-settings-private.h"
|
||||||
|
#include "backends/meta-backend-private.h"
|
||||||
#include <clutter/x11/clutter-x11.h>
|
#include <clutter/x11/clutter-x11.h>
|
||||||
|
|
||||||
#ifdef HAVE_RANDR
|
#ifdef HAVE_RANDR
|
||||||
@ -533,27 +534,23 @@ gesture_tracker_state_changed (MetaGestureTracker *tracker,
|
|||||||
MetaSequenceState state,
|
MetaSequenceState state,
|
||||||
MetaDisplay *display)
|
MetaDisplay *display)
|
||||||
{
|
{
|
||||||
if (meta_is_wayland_compositor ())
|
switch (state)
|
||||||
{
|
{
|
||||||
if (state == META_SEQUENCE_ACCEPTED)
|
case META_SEQUENCE_NONE:
|
||||||
meta_display_cancel_touch (display);
|
case META_SEQUENCE_PENDING_END:
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
|
||||||
int event_mode;
|
|
||||||
|
|
||||||
if (state == META_SEQUENCE_ACCEPTED)
|
|
||||||
event_mode = XIAcceptTouch;
|
|
||||||
else if (state == META_SEQUENCE_REJECTED)
|
|
||||||
event_mode = XIRejectTouch;
|
|
||||||
else
|
|
||||||
return;
|
return;
|
||||||
|
case META_SEQUENCE_ACCEPTED:
|
||||||
|
meta_display_cancel_touch (display);
|
||||||
|
|
||||||
XIAllowTouchEvents (meta_backend_x11_get_xdisplay (backend),
|
/* Intentional fall-through */
|
||||||
META_VIRTUAL_CORE_POINTER_ID,
|
case META_SEQUENCE_REJECTED:
|
||||||
clutter_x11_event_sequence_get_touch_detail (sequence),
|
{
|
||||||
DefaultRootWindow (display->xdisplay), event_mode);
|
MetaBackend *backend;
|
||||||
|
|
||||||
|
backend = meta_get_backend ();
|
||||||
|
meta_backend_finish_touch_sequence (backend, sequence, state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,9 +32,10 @@
|
|||||||
|
|
||||||
#ifdef HAVE_NATIVE_BACKEND
|
#ifdef HAVE_NATIVE_BACKEND
|
||||||
#include "backends/native/meta-backend-native.h"
|
#include "backends/native/meta-backend-native.h"
|
||||||
#include "backends/native/meta-idle-monitor-native.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "backends/meta-idle-monitor-private.h"
|
||||||
|
|
||||||
#ifdef HAVE_WAYLAND
|
#ifdef HAVE_WAYLAND
|
||||||
#include "wayland/meta-wayland-private.h"
|
#include "wayland/meta-wayland-private.h"
|
||||||
#endif
|
#endif
|
||||||
@ -92,12 +93,6 @@ get_window_for_event (MetaDisplay *display,
|
|||||||
static void
|
static void
|
||||||
handle_idletime_for_event (const ClutterEvent *event)
|
handle_idletime_for_event (const ClutterEvent *event)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_NATIVE_BACKEND
|
|
||||||
/* This is handled by XSync under X11. */
|
|
||||||
MetaBackend *backend = meta_get_backend ();
|
|
||||||
|
|
||||||
if (META_IS_BACKEND_NATIVE (backend))
|
|
||||||
{
|
|
||||||
ClutterInputDevice *device, *source_device;
|
ClutterInputDevice *device, *source_device;
|
||||||
MetaIdleMonitor *core_monitor, *device_monitor;
|
MetaIdleMonitor *core_monitor, *device_monitor;
|
||||||
int device_id;
|
int device_id;
|
||||||
@ -120,18 +115,16 @@ handle_idletime_for_event (const ClutterEvent *event)
|
|||||||
core_monitor = meta_idle_monitor_get_core ();
|
core_monitor = meta_idle_monitor_get_core ();
|
||||||
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
||||||
|
|
||||||
meta_idle_monitor_native_reset_idletime (core_monitor);
|
meta_idle_monitor_reset_idletime (core_monitor);
|
||||||
meta_idle_monitor_native_reset_idletime (device_monitor);
|
meta_idle_monitor_reset_idletime (device_monitor);
|
||||||
|
|
||||||
source_device = clutter_event_get_source_device (event);
|
source_device = clutter_event_get_source_device (event);
|
||||||
if (source_device != device)
|
if (source_device != device)
|
||||||
{
|
{
|
||||||
device_id = clutter_input_device_get_device_id (device);
|
device_id = clutter_input_device_get_device_id (device);
|
||||||
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
||||||
meta_idle_monitor_native_reset_idletime (device_monitor);
|
meta_idle_monitor_reset_idletime (device_monitor);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif /* HAVE_NATIVE_BACKEND */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -105,6 +105,12 @@ meta_window_ensure_frame (MetaWindow *window)
|
|||||||
/* FIXME handle this error */
|
/* FIXME handle this error */
|
||||||
meta_error_trap_pop (window->display);
|
meta_error_trap_pop (window->display);
|
||||||
|
|
||||||
|
/* Ensure focus is restored after the unmap/map events triggered
|
||||||
|
* by XReparentWindow().
|
||||||
|
*/
|
||||||
|
if (meta_window_has_focus (window))
|
||||||
|
window->restore_focus_on_map = TRUE;
|
||||||
|
|
||||||
/* stick frame to the window */
|
/* stick frame to the window */
|
||||||
window->frame = frame;
|
window->frame = frame;
|
||||||
|
|
||||||
@ -194,6 +200,12 @@ meta_window_destroy_frame (MetaWindow *window)
|
|||||||
|
|
||||||
meta_ui_frame_unmanage (frame->ui_frame);
|
meta_ui_frame_unmanage (frame->ui_frame);
|
||||||
|
|
||||||
|
/* Ensure focus is restored after the unmap/map events triggered
|
||||||
|
* by XReparentWindow().
|
||||||
|
*/
|
||||||
|
if (meta_window_has_focus (window))
|
||||||
|
window->restore_focus_on_map = TRUE;
|
||||||
|
|
||||||
meta_display_unregister_x_window (window->display,
|
meta_display_unregister_x_window (window->display,
|
||||||
frame->xwindow);
|
frame->xwindow);
|
||||||
|
|
||||||
|
@ -38,12 +38,7 @@
|
|||||||
typedef struct _MetaGestureTracker MetaGestureTracker;
|
typedef struct _MetaGestureTracker MetaGestureTracker;
|
||||||
typedef struct _MetaGestureTrackerClass MetaGestureTrackerClass;
|
typedef struct _MetaGestureTrackerClass MetaGestureTrackerClass;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum _MetaSequenceState MetaSequenceState;
|
||||||
META_SEQUENCE_NONE,
|
|
||||||
META_SEQUENCE_ACCEPTED,
|
|
||||||
META_SEQUENCE_REJECTED,
|
|
||||||
META_SEQUENCE_PENDING_END
|
|
||||||
} MetaSequenceState;
|
|
||||||
|
|
||||||
struct _MetaGestureTracker
|
struct _MetaGestureTracker
|
||||||
{
|
{
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "meta-gesture-tracker-private.h"
|
#include "meta-gesture-tracker-private.h"
|
||||||
#include "meta-surface-actor.h"
|
#include "meta-surface-actor.h"
|
||||||
|
#include "meta-backend-private.h"
|
||||||
|
|
||||||
#define DISTANCE_THRESHOLD 30
|
#define DISTANCE_THRESHOLD 30
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
#include <meta/compositor.h>
|
#include <meta/compositor.h>
|
||||||
#include <meta/meta-enum-types.h>
|
#include <meta/meta-enum-types.h>
|
||||||
|
#include "compositor-private.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "meta-cursor-tracker-private.h"
|
#include "meta-cursor-tracker-private.h"
|
||||||
#include "boxes-private.h"
|
#include "boxes-private.h"
|
||||||
@ -835,6 +836,7 @@ meta_screen_free (MetaScreen *screen,
|
|||||||
guint32 timestamp)
|
guint32 timestamp)
|
||||||
{
|
{
|
||||||
MetaDisplay *display;
|
MetaDisplay *display;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
display = screen->display;
|
display = screen->display;
|
||||||
|
|
||||||
@ -844,6 +846,8 @@ meta_screen_free (MetaScreen *screen,
|
|||||||
|
|
||||||
meta_display_unmanage_windows_for_screen (display, screen, timestamp);
|
meta_display_unmanage_windows_for_screen (display, screen, timestamp);
|
||||||
|
|
||||||
|
meta_compositor_unmanage_window_actors (display->compositor);
|
||||||
|
|
||||||
meta_prefs_remove_listener (prefs_changed_callback, screen);
|
meta_prefs_remove_listener (prefs_changed_callback, screen);
|
||||||
|
|
||||||
meta_screen_ungrab_keys (screen);
|
meta_screen_ungrab_keys (screen);
|
||||||
@ -874,6 +878,16 @@ meta_screen_free (MetaScreen *screen,
|
|||||||
|
|
||||||
g_free (screen->screen_name);
|
g_free (screen->screen_name);
|
||||||
|
|
||||||
|
screen->active_workspace = NULL;
|
||||||
|
|
||||||
|
for (l = screen->workspaces; l;)
|
||||||
|
{
|
||||||
|
MetaWorkspace *workspace = l->data;
|
||||||
|
l = l->next;
|
||||||
|
|
||||||
|
meta_workspace_remove (workspace);
|
||||||
|
}
|
||||||
|
|
||||||
g_object_unref (screen);
|
g_object_unref (screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1394,6 +1408,8 @@ meta_screen_update_cursor (MetaScreen *screen)
|
|||||||
|
|
||||||
XDefineCursor (display->xdisplay, screen->xroot, xcursor);
|
XDefineCursor (display->xdisplay, screen->xroot, xcursor);
|
||||||
XFlush (display->xdisplay);
|
XFlush (display->xdisplay);
|
||||||
|
|
||||||
|
if (xcursor)
|
||||||
XFreeCursor (display->xdisplay, xcursor);
|
XFreeCursor (display->xdisplay, xcursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1176,6 +1176,27 @@ window_contains_point (MetaWindow *window,
|
|||||||
return POINT_IN_RECT (root_x, root_y, rect);
|
return POINT_IN_RECT (root_x, root_y, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
window_can_get_default_focus (MetaWindow *window)
|
||||||
|
{
|
||||||
|
if (window->unmaps_pending > 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (window->unmanaging)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!(window->input || window->take_focus))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!meta_window_should_be_showing (window))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (window->type == META_WINDOW_DOCK)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static MetaWindow*
|
static MetaWindow*
|
||||||
get_default_focus_window (MetaStack *stack,
|
get_default_focus_window (MetaStack *stack,
|
||||||
MetaWorkspace *workspace,
|
MetaWorkspace *workspace,
|
||||||
@ -1203,24 +1224,12 @@ get_default_focus_window (MetaStack *stack,
|
|||||||
if (window == not_this_one)
|
if (window == not_this_one)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (window->unmaps_pending > 0)
|
if (!window_can_get_default_focus (window))
|
||||||
continue;
|
|
||||||
|
|
||||||
if (window->unmanaging)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(window->input || window->take_focus))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!meta_window_should_be_showing (window))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (must_be_at_point && !window_contains_point (window, root_x, root_y))
|
if (must_be_at_point && !window_contains_point (window, root_x, root_y))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (window->type == META_WINDOW_DOCK)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1275,6 +1284,26 @@ meta_stack_list_windows (MetaStack *stack,
|
|||||||
return workspace_windows;
|
return workspace_windows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GList *
|
||||||
|
meta_stack_get_default_focus_candidates (MetaStack *stack,
|
||||||
|
MetaWorkspace *workspace)
|
||||||
|
{
|
||||||
|
GList *windows = meta_stack_list_windows (stack, workspace);
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = windows; l;)
|
||||||
|
{
|
||||||
|
GList *next = l->next;
|
||||||
|
|
||||||
|
if (!window_can_get_default_focus (l->data))
|
||||||
|
windows = g_list_delete_link (windows, l);
|
||||||
|
|
||||||
|
l = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return windows;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
meta_stack_windows_cmp (MetaStack *stack,
|
meta_stack_windows_cmp (MetaStack *stack,
|
||||||
MetaWindow *window_a,
|
MetaWindow *window_a,
|
||||||
|
@ -337,6 +337,21 @@ MetaWindow* meta_stack_get_default_focus_window_at_point (MetaStack *stack,
|
|||||||
int root_x,
|
int root_x,
|
||||||
int root_y);
|
int root_y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_stack_get_default_focus_candidates:
|
||||||
|
* @stack: The stack to examine.
|
||||||
|
* @workspace: If not %NULL, only windows on this workspace will be
|
||||||
|
* returned; otherwise all windows in the stack will be
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* Returns all the focus candidate windows in the stack, in order.
|
||||||
|
*
|
||||||
|
* Returns: (transfer container) (element-type Meta.Window):
|
||||||
|
* A #GList of #MetaWindow, in stacking order, honouring layers.
|
||||||
|
*/
|
||||||
|
GList * meta_stack_get_default_focus_candidates (MetaStack *stack,
|
||||||
|
MetaWorkspace *workspace);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_stack_list_windows:
|
* meta_stack_list_windows:
|
||||||
* @stack: The stack to examine.
|
* @stack: The stack to examine.
|
||||||
|
@ -81,6 +81,8 @@ typedef enum
|
|||||||
META_MOVE_RESIZE_STATE_CHANGED = 1 << 5,
|
META_MOVE_RESIZE_STATE_CHANGED = 1 << 5,
|
||||||
META_MOVE_RESIZE_UNMAXIMIZE = 1 << 6,
|
META_MOVE_RESIZE_UNMAXIMIZE = 1 << 6,
|
||||||
META_MOVE_RESIZE_FORCE_MOVE = 1 << 7,
|
META_MOVE_RESIZE_FORCE_MOVE = 1 << 7,
|
||||||
|
META_MOVE_RESIZE_WAYLAND_STATE_CHANGED = 1 << 8,
|
||||||
|
META_MOVE_RESIZE_FORCE_UPDATE_MONITOR = 1 << 9,
|
||||||
} MetaMoveResizeFlags;
|
} MetaMoveResizeFlags;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -88,6 +90,7 @@ typedef enum
|
|||||||
META_MOVE_RESIZE_RESULT_MOVED = 1 << 0,
|
META_MOVE_RESIZE_RESULT_MOVED = 1 << 0,
|
||||||
META_MOVE_RESIZE_RESULT_RESIZED = 1 << 1,
|
META_MOVE_RESIZE_RESULT_RESIZED = 1 << 1,
|
||||||
META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED = 1 << 2,
|
META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED = 1 << 2,
|
||||||
|
META_MOVE_RESIZE_RESULT_STATE_CHANGED = 1 << 3,
|
||||||
} MetaMoveResizeResultFlags;
|
} MetaMoveResizeResultFlags;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -119,6 +122,13 @@ typedef enum
|
|||||||
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 1 << 5,
|
META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 1 << 5,
|
||||||
} MetaPlacementConstraintAdjustment;
|
} MetaPlacementConstraintAdjustment;
|
||||||
|
|
||||||
|
typedef enum _MetaWindowUpdateMonitorFlags
|
||||||
|
{
|
||||||
|
META_WINDOW_UPDATE_MONITOR_FLAGS_NONE = 0,
|
||||||
|
META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP = 1 << 0,
|
||||||
|
META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE = 1 << 1,
|
||||||
|
} MetaWindowUpdateMonitorFlags;
|
||||||
|
|
||||||
typedef struct _MetaPlacementRule
|
typedef struct _MetaPlacementRule
|
||||||
{
|
{
|
||||||
MetaRectangle anchor_rect;
|
MetaRectangle anchor_rect;
|
||||||
@ -407,6 +417,9 @@ struct _MetaWindow
|
|||||||
/* whether or not the window is from a program running on another machine */
|
/* whether or not the window is from a program running on another machine */
|
||||||
guint is_remote : 1;
|
guint is_remote : 1;
|
||||||
|
|
||||||
|
/* whether focus should be restored on map */
|
||||||
|
guint restore_focus_on_map : 1;
|
||||||
|
|
||||||
/* if non-NULL, the bounds of the window frame */
|
/* if non-NULL, the bounds of the window frame */
|
||||||
cairo_region_t *frame_bounds;
|
cairo_region_t *frame_bounds;
|
||||||
|
|
||||||
@ -548,7 +561,7 @@ struct _MetaWindowClass
|
|||||||
cairo_surface_t **mini_icon);
|
cairo_surface_t **mini_icon);
|
||||||
uint32_t (*get_client_pid) (MetaWindow *window);
|
uint32_t (*get_client_pid) (MetaWindow *window);
|
||||||
void (*update_main_monitor) (MetaWindow *window,
|
void (*update_main_monitor) (MetaWindow *window,
|
||||||
gboolean user_op);
|
MetaWindowUpdateMonitorFlags flags);
|
||||||
void (*main_monitor_changed) (MetaWindow *window,
|
void (*main_monitor_changed) (MetaWindow *window,
|
||||||
const MetaLogicalMonitor *old);
|
const MetaLogicalMonitor *old);
|
||||||
void (*force_restore_shortcuts) (MetaWindow *window,
|
void (*force_restore_shortcuts) (MetaWindow *window,
|
||||||
@ -767,7 +780,7 @@ MetaLogicalMonitor * meta_window_calculate_main_logical_monitor (MetaWindow *win
|
|||||||
|
|
||||||
MetaLogicalMonitor * meta_window_get_main_logical_monitor (MetaWindow *window);
|
MetaLogicalMonitor * meta_window_get_main_logical_monitor (MetaWindow *window);
|
||||||
void meta_window_update_monitor (MetaWindow *window,
|
void meta_window_update_monitor (MetaWindow *window,
|
||||||
gboolean user_op);
|
MetaWindowUpdateMonitorFlags flags);
|
||||||
|
|
||||||
void meta_window_set_urgent (MetaWindow *window,
|
void meta_window_set_urgent (MetaWindow *window,
|
||||||
gboolean urgent);
|
gboolean urgent);
|
||||||
|
@ -119,6 +119,7 @@ static gboolean queue_calc_showing_func (MetaWindow *window,
|
|||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
static void meta_window_move_between_rects (MetaWindow *window,
|
static void meta_window_move_between_rects (MetaWindow *window,
|
||||||
|
MetaMoveResizeFlags move_resize_flags,
|
||||||
const MetaRectangle *old_area,
|
const MetaRectangle *old_area,
|
||||||
const MetaRectangle *new_area);
|
const MetaRectangle *new_area);
|
||||||
|
|
||||||
@ -1031,7 +1032,6 @@ _meta_window_shared_new (MetaDisplay *display,
|
|||||||
window->tab_unminimized = FALSE;
|
window->tab_unminimized = FALSE;
|
||||||
window->iconic = FALSE;
|
window->iconic = FALSE;
|
||||||
window->mapped = attrs->map_state != IsUnmapped;
|
window->mapped = attrs->map_state != IsUnmapped;
|
||||||
window->hidden = FALSE;
|
|
||||||
window->known_to_compositor = FALSE;
|
window->known_to_compositor = FALSE;
|
||||||
window->visible_to_compositor = FALSE;
|
window->visible_to_compositor = FALSE;
|
||||||
window->pending_compositor_effect = effect;
|
window->pending_compositor_effect = effect;
|
||||||
@ -1070,10 +1070,17 @@ _meta_window_shared_new (MetaDisplay *display,
|
|||||||
window->mwm_has_move_func = TRUE;
|
window->mwm_has_move_func = TRUE;
|
||||||
window->mwm_has_resize_func = TRUE;
|
window->mwm_has_resize_func = TRUE;
|
||||||
|
|
||||||
if (client_type == META_WINDOW_CLIENT_TYPE_X11)
|
switch (client_type)
|
||||||
|
{
|
||||||
|
case META_WINDOW_CLIENT_TYPE_X11:
|
||||||
window->decorated = TRUE;
|
window->decorated = TRUE;
|
||||||
else
|
window->hidden = FALSE;
|
||||||
|
break;
|
||||||
|
case META_WINDOW_CLIENT_TYPE_WAYLAND:
|
||||||
window->decorated = FALSE;
|
window->decorated = FALSE;
|
||||||
|
window->hidden = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
window->has_close_func = TRUE;
|
window->has_close_func = TRUE;
|
||||||
window->has_minimize_func = TRUE;
|
window->has_minimize_func = TRUE;
|
||||||
@ -1265,11 +1272,10 @@ _meta_window_shared_new (MetaDisplay *display,
|
|||||||
window->desc, window->transient_for->desc);
|
window->desc, window->transient_for->desc);
|
||||||
|
|
||||||
set_workspace_state (window,
|
set_workspace_state (window,
|
||||||
window->transient_for->on_all_workspaces_requested,
|
window->transient_for->on_all_workspaces,
|
||||||
window->transient_for->workspace);
|
window->transient_for->workspace);
|
||||||
}
|
}
|
||||||
|
else if (window->on_all_workspaces)
|
||||||
if (window->on_all_workspaces)
|
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_PLACEMENT,
|
meta_topic (META_DEBUG_PLACEMENT,
|
||||||
"Putting window %s on all workspaces\n",
|
"Putting window %s on all workspaces\n",
|
||||||
@ -1469,7 +1475,9 @@ meta_window_unmanage (MetaWindow *window,
|
|||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing default window since we're unmanaging %s\n",
|
"Focusing default window since we're unmanaging %s\n",
|
||||||
window->desc);
|
window->desc);
|
||||||
meta_workspace_focus_default_window (window->screen->active_workspace, NULL, timestamp);
|
meta_workspace_focus_default_window (window->screen->active_workspace,
|
||||||
|
window,
|
||||||
|
timestamp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3613,6 +3621,13 @@ meta_window_activate_full (MetaWindow *window,
|
|||||||
MetaWorkspace *workspace)
|
MetaWorkspace *workspace)
|
||||||
{
|
{
|
||||||
gboolean allow_workspace_switch;
|
gboolean allow_workspace_switch;
|
||||||
|
|
||||||
|
if (window->unmanaging)
|
||||||
|
{
|
||||||
|
g_warning ("Trying to activate unmanaged window '%s'", window->desc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"_NET_ACTIVE_WINDOW message sent for %s at time %u "
|
"_NET_ACTIVE_WINDOW message sent for %s at time %u "
|
||||||
"by client type %u.\n",
|
"by client type %u.\n",
|
||||||
@ -3750,11 +3765,15 @@ maybe_move_attached_dialog (MetaWindow *window,
|
|||||||
*
|
*
|
||||||
* Gets index of the monitor that this window is on.
|
* Gets index of the monitor that this window is on.
|
||||||
*
|
*
|
||||||
* Return Value: The index of the monitor in the screens monitor list
|
* Return Value: The index of the monitor in the screens monitor list, or -1
|
||||||
|
* if the window has been recently unmanaged and does not have a monitor.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
meta_window_get_monitor (MetaWindow *window)
|
meta_window_get_monitor (MetaWindow *window)
|
||||||
{
|
{
|
||||||
|
if (!window->monitor)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return window->monitor->number;
|
return window->monitor->number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3802,7 +3821,8 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
|
|||||||
|
|
||||||
if (window->override_redirect || window->type == META_WINDOW_DESKTOP)
|
if (window->override_redirect || window->type == META_WINDOW_DESKTOP)
|
||||||
{
|
{
|
||||||
meta_window_update_monitor (window, FALSE);
|
meta_window_update_monitor (window,
|
||||||
|
META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3832,23 +3852,25 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
|
|||||||
* monitors changed and the same index could be refereing
|
* monitors changed and the same index could be refereing
|
||||||
* to a different monitor. */
|
* to a different monitor. */
|
||||||
meta_window_move_between_rects (window,
|
meta_window_move_between_rects (window,
|
||||||
|
META_MOVE_RESIZE_FORCE_UPDATE_MONITOR,
|
||||||
&old->rect,
|
&old->rect,
|
||||||
&new->rect);
|
&new->rect);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
meta_window_update_monitor (window, FALSE);
|
meta_window_update_monitor (window,
|
||||||
|
META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_window_update_monitor (MetaWindow *window,
|
meta_window_update_monitor (MetaWindow *window,
|
||||||
gboolean user_op)
|
MetaWindowUpdateMonitorFlags flags)
|
||||||
{
|
{
|
||||||
const MetaLogicalMonitor *old;
|
const MetaLogicalMonitor *old;
|
||||||
|
|
||||||
old = window->monitor;
|
old = window->monitor;
|
||||||
META_WINDOW_GET_CLASS (window)->update_main_monitor (window, user_op);
|
META_WINDOW_GET_CLASS (window)->update_main_monitor (window, flags);
|
||||||
if (old != window->monitor)
|
if (old != window->monitor)
|
||||||
{
|
{
|
||||||
meta_window_on_all_workspaces_changed (window);
|
meta_window_on_all_workspaces_changed (window);
|
||||||
@ -3862,7 +3884,8 @@ meta_window_update_monitor (MetaWindow *window,
|
|||||||
* That should be handled by explicitly moving the window before changing the
|
* That should be handled by explicitly moving the window before changing the
|
||||||
* workspace.
|
* workspace.
|
||||||
*/
|
*/
|
||||||
if (meta_prefs_get_workspaces_only_on_primary () && user_op &&
|
if (meta_prefs_get_workspaces_only_on_primary () &&
|
||||||
|
flags & META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP &&
|
||||||
meta_window_is_on_primary_monitor (window) &&
|
meta_window_is_on_primary_monitor (window) &&
|
||||||
window->screen->active_workspace != window->workspace)
|
window->screen->active_workspace != window->workspace)
|
||||||
meta_window_change_workspace (window, window->screen->active_workspace);
|
meta_window_change_workspace (window, window->screen->active_workspace);
|
||||||
@ -3905,6 +3928,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
MetaRectangle constrained_rect;
|
MetaRectangle constrained_rect;
|
||||||
MetaMoveResizeResultFlags result = 0;
|
MetaMoveResizeResultFlags result = 0;
|
||||||
gboolean moved_or_resized = FALSE;
|
gboolean moved_or_resized = FALSE;
|
||||||
|
MetaWindowUpdateMonitorFlags update_monitor_flags;
|
||||||
|
|
||||||
g_return_if_fail (!window->override_redirect);
|
g_return_if_fail (!window->override_redirect);
|
||||||
|
|
||||||
@ -3997,7 +4021,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
|
|
||||||
if ((moved_or_resized ||
|
if ((moved_or_resized ||
|
||||||
did_placement ||
|
did_placement ||
|
||||||
(flags & META_MOVE_RESIZE_STATE_CHANGED) != 0) &&
|
(result & META_MOVE_RESIZE_RESULT_STATE_CHANGED) != 0) &&
|
||||||
window->known_to_compositor)
|
window->known_to_compositor)
|
||||||
{
|
{
|
||||||
meta_compositor_sync_window_geometry (window->display->compositor,
|
meta_compositor_sync_window_geometry (window->display->compositor,
|
||||||
@ -4005,13 +4029,19 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
did_placement);
|
did_placement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_monitor_flags = META_WINDOW_UPDATE_MONITOR_FLAGS_NONE;
|
||||||
|
if (flags & META_MOVE_RESIZE_USER_ACTION)
|
||||||
|
update_monitor_flags |= META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP;
|
||||||
|
if (flags & META_MOVE_RESIZE_FORCE_UPDATE_MONITOR)
|
||||||
|
update_monitor_flags |= META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE;
|
||||||
|
|
||||||
if (window->monitor)
|
if (window->monitor)
|
||||||
{
|
{
|
||||||
guint old_output_winsys_id;
|
guint old_output_winsys_id;
|
||||||
|
|
||||||
old_output_winsys_id = window->monitor->winsys_id;
|
old_output_winsys_id = window->monitor->winsys_id;
|
||||||
|
|
||||||
meta_window_update_monitor (window, flags & META_MOVE_RESIZE_USER_ACTION);
|
meta_window_update_monitor (window, update_monitor_flags);
|
||||||
|
|
||||||
if (old_output_winsys_id != window->monitor->winsys_id &&
|
if (old_output_winsys_id != window->monitor->winsys_id &&
|
||||||
flags & META_MOVE_RESIZE_MOVE_ACTION && flags & META_MOVE_RESIZE_USER_ACTION)
|
flags & META_MOVE_RESIZE_MOVE_ACTION && flags & META_MOVE_RESIZE_USER_ACTION)
|
||||||
@ -4019,7 +4049,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
meta_window_update_monitor (window, flags & META_MOVE_RESIZE_USER_ACTION);
|
meta_window_update_monitor (window, update_monitor_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result & META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED) && window->frame_bounds)
|
if ((result & META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED) && window->frame_bounds)
|
||||||
@ -4063,6 +4093,7 @@ meta_window_move_frame (MetaWindow *window,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_move_between_rects (MetaWindow *window,
|
meta_window_move_between_rects (MetaWindow *window,
|
||||||
|
MetaMoveResizeFlags move_resize_flags,
|
||||||
const MetaRectangle *old_area,
|
const MetaRectangle *old_area,
|
||||||
const MetaRectangle *new_area)
|
const MetaRectangle *new_area)
|
||||||
{
|
{
|
||||||
@ -4086,7 +4117,12 @@ meta_window_move_between_rects (MetaWindow *window,
|
|||||||
window->saved_rect.x = window->unconstrained_rect.x;
|
window->saved_rect.x = window->unconstrained_rect.x;
|
||||||
window->saved_rect.y = window->unconstrained_rect.y;
|
window->saved_rect.y = window->unconstrained_rect.y;
|
||||||
|
|
||||||
meta_window_move_resize_now (window);
|
meta_window_move_resize_internal (window,
|
||||||
|
move_resize_flags |
|
||||||
|
META_MOVE_RESIZE_MOVE_ACTION |
|
||||||
|
META_MOVE_RESIZE_RESIZE_ACTION,
|
||||||
|
NorthWestGravity,
|
||||||
|
window->unconstrained_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4147,14 +4183,14 @@ meta_window_move_to_monitor (MetaWindow *window,
|
|||||||
window->unconstrained_rect.height == 0 ||
|
window->unconstrained_rect.height == 0 ||
|
||||||
!meta_rectangle_overlap (&window->unconstrained_rect, &old_area))
|
!meta_rectangle_overlap (&window->unconstrained_rect, &old_area))
|
||||||
{
|
{
|
||||||
meta_window_move_between_rects (window, NULL, &new_area);
|
meta_window_move_between_rects (window, 0, NULL, &new_area);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (monitor == window->monitor->number)
|
if (monitor == window->monitor->number)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
meta_window_move_between_rects (window, &old_area, &new_area);
|
meta_window_move_between_rects (window, 0, &old_area, &new_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
window->preferred_output_winsys_id = window->monitor->winsys_id;
|
window->preferred_output_winsys_id = window->monitor->winsys_id;
|
||||||
@ -4615,11 +4651,15 @@ meta_window_focus (MetaWindow *window,
|
|||||||
|
|
||||||
g_return_if_fail (!window->override_redirect);
|
g_return_if_fail (!window->override_redirect);
|
||||||
|
|
||||||
|
/* This is a oneshot flag */
|
||||||
|
window->restore_focus_on_map = FALSE;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Setting input focus to window %s, input: %d take_focus: %d\n",
|
"Setting input focus to window %s, input: %d take_focus: %d\n",
|
||||||
window->desc, window->input, window->take_focus);
|
window->desc, window->input, window->take_focus);
|
||||||
|
|
||||||
if (window->display->grab_window &&
|
if (window->display->grab_window &&
|
||||||
|
window->display->grab_window != window &&
|
||||||
window->display->grab_window->all_keys_grabbed &&
|
window->display->grab_window->all_keys_grabbed &&
|
||||||
!window->display->grab_window->unmanaging)
|
!window->display->grab_window->unmanaging)
|
||||||
{
|
{
|
||||||
@ -5268,7 +5308,7 @@ static cairo_surface_t *
|
|||||||
load_default_window_icon (int size)
|
load_default_window_icon (int size)
|
||||||
{
|
{
|
||||||
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
||||||
GdkPixbuf *pixbuf;
|
g_autoptr (GdkPixbuf) pixbuf = NULL;
|
||||||
const char *icon_name;
|
const char *icon_name;
|
||||||
|
|
||||||
if (gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME))
|
if (gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME))
|
||||||
@ -7927,7 +7967,15 @@ meta_window_set_transient_for (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (window->attached && parent == NULL)
|
||||||
|
{
|
||||||
|
guint32 timestamp;
|
||||||
|
|
||||||
|
timestamp =
|
||||||
|
meta_display_get_current_time_roundtrip (window->display);
|
||||||
|
meta_window_unmanage (window, timestamp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* We know this won't create a reference cycle because we check for loops */
|
/* We know this won't create a reference cycle because we check for loops */
|
||||||
g_clear_object (&window->transient_for);
|
g_clear_object (&window->transient_for);
|
||||||
window->transient_for = parent ? g_object_ref (parent) : NULL;
|
window->transient_for = parent ? g_object_ref (parent) : NULL;
|
||||||
|
@ -85,6 +85,12 @@ typedef struct _MetaWorkspaceLogicalMonitorData
|
|||||||
MetaRectangle logical_monitor_work_area;
|
MetaRectangle logical_monitor_work_area;
|
||||||
} MetaWorkspaceLogicalMonitorData;
|
} MetaWorkspaceLogicalMonitorData;
|
||||||
|
|
||||||
|
typedef struct _MetaWorkspaceFocusableAncestorData
|
||||||
|
{
|
||||||
|
MetaWorkspace *workspace;
|
||||||
|
MetaWindow *out_window;
|
||||||
|
} MetaWorkspaceFocusableAncestorData;
|
||||||
|
|
||||||
static MetaWorkspaceLogicalMonitorData *
|
static MetaWorkspaceLogicalMonitorData *
|
||||||
meta_workspace_get_logical_monitor_data (MetaWorkspace *workspace,
|
meta_workspace_get_logical_monitor_data (MetaWorkspace *workspace,
|
||||||
MetaLogicalMonitor *logical_monitor)
|
MetaLogicalMonitor *logical_monitor)
|
||||||
@ -1319,13 +1325,20 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
record_ancestor (MetaWindow *window,
|
find_focusable_ancestor (MetaWindow *window,
|
||||||
void *data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaWindow **result = data;
|
MetaWorkspaceFocusableAncestorData *data = user_data;
|
||||||
|
|
||||||
*result = window;
|
if (!window->unmanaging && (window->input || window->take_focus) &&
|
||||||
return FALSE; /* quit with the first ancestor we find */
|
meta_window_located_on_workspace (window, data->workspace) &&
|
||||||
|
meta_window_showing_on_its_workspace (window))
|
||||||
|
{
|
||||||
|
data->out_window = window;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Focus ancestor of not_this_one if there is one */
|
/* Focus ancestor of not_this_one if there is one */
|
||||||
@ -1347,11 +1360,15 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
|
|||||||
if (not_this_one)
|
if (not_this_one)
|
||||||
{
|
{
|
||||||
MetaWindow *ancestor;
|
MetaWindow *ancestor;
|
||||||
ancestor = NULL;
|
MetaWorkspaceFocusableAncestorData data;
|
||||||
meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor);
|
|
||||||
if (ancestor != NULL &&
|
data = (MetaWorkspaceFocusableAncestorData) {
|
||||||
meta_window_located_on_workspace (ancestor, workspace) &&
|
.workspace = workspace,
|
||||||
meta_window_showing_on_its_workspace (ancestor))
|
};
|
||||||
|
meta_window_foreach_ancestor (not_this_one, find_focusable_ancestor, &data);
|
||||||
|
ancestor = data.out_window;
|
||||||
|
|
||||||
|
if (ancestor)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_FOCUS,
|
meta_topic (META_DEBUG_FOCUS,
|
||||||
"Focusing %s, ancestor of %s\n",
|
"Focusing %s, ancestor of %s\n",
|
||||||
|
@ -54,4 +54,7 @@ MetaMonitorSwitchConfigType meta_monitor_manager_get_switch_config (MetaMonitorM
|
|||||||
|
|
||||||
gint meta_monitor_manager_get_display_configuration_timeout (void);
|
gint meta_monitor_manager_get_display_configuration_timeout (void);
|
||||||
|
|
||||||
|
/* Re-declaration of parent type for introspection */
|
||||||
|
GType meta_dbus_display_config_skeleton_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
#endif /* META_MONITOR_MANAGER_H */
|
#endif /* META_MONITOR_MANAGER_H */
|
||||||
|
32
src/meta/meta-stage.h
Normal file
32
src/meta/meta-stage.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Intel Corporation
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_STAGE_H
|
||||||
|
#define META_STAGE_H
|
||||||
|
|
||||||
|
#include "clutter/clutter.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define META_TYPE_STAGE (meta_stage_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaStage, meta_stage, META, STAGE, ClutterStage)
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* META_STAGE_H */
|
11
src/meta/meta-window-group.h
Normal file
11
src/meta/meta-window-group.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
|
||||||
|
#ifndef META_WINDOW_GROUP_H
|
||||||
|
#define META_WINDOW_GROUP_H
|
||||||
|
|
||||||
|
#include "clutter/clutter.h"
|
||||||
|
|
||||||
|
#define META_TYPE_WINDOW_GROUP (meta_window_group_get_type())
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaWindowGroup, meta_window_group, META, WINDOW_GROUP, ClutterActor)
|
||||||
|
|
||||||
|
#endif /* META_WINDOW_GROUP_H */
|
@ -28,6 +28,8 @@
|
|||||||
<arg name="id" direction="in" type="u" />
|
<arg name="id" direction="in" type="u" />
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
<method name="ResetIdletime"/>
|
||||||
|
|
||||||
<signal name="WatchFired">
|
<signal name="WatchFired">
|
||||||
<arg name="id" direction="out" type="u" />
|
<arg name="id" direction="out" type="u" />
|
||||||
</signal>
|
</signal>
|
||||||
|
@ -209,7 +209,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
|||||||
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
|
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
|
||||||
|
|
||||||
output->is_dirty = TRUE;
|
output->is_dirty = TRUE;
|
||||||
output->crtc = crtc;
|
meta_output_assign_crtc (output, crtc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,7 +255,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
output->crtc = NULL;
|
meta_output_unassign_crtc (output);
|
||||||
output->is_primary = FALSE;
|
output->is_primary = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user