Compare commits
72 Commits
wip/carlos
...
3.28.3
Author | SHA1 | Date | |
---|---|---|---|
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 |
45
NEWS
45
NEWS
@ -1,3 +1,48 @@
|
||||
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
|
||||
======
|
||||
* 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 = \
|
||||
--warn-all \
|
||||
--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
|
||||
|
||||
INTROSPECTION_GIRS += Cally-@LIBMUTTER_API_VERSION@.gir
|
||||
|
@ -353,6 +353,7 @@ clutter_input_method_notify_key_event (ClutterInputMethod *im,
|
||||
copy = clutter_event_copy (event);
|
||||
clutter_event_set_flags (copy, clutter_event_get_flags (event) |
|
||||
CLUTTER_EVENT_FLAG_INPUT_METHOD);
|
||||
clutter_event_set_source_device (copy, clutter_event_get_device (copy));
|
||||
clutter_event_put (copy);
|
||||
clutter_event_free (copy);
|
||||
}
|
||||
|
@ -2830,6 +2830,10 @@ clutter_text_key_focus_in (ClutterActor *actor)
|
||||
if (method && priv->editable)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
@ -4511,6 +4515,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
|
||||
buffer_notify_text (ClutterTextBuffer *buffer,
|
||||
GParamSpec *spec,
|
||||
@ -4518,9 +4543,7 @@ buffer_notify_text (ClutterTextBuffer *buffer,
|
||||
{
|
||||
g_object_freeze_notify (G_OBJECT (self));
|
||||
|
||||
clutter_text_dirty_cache (self);
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
clutter_text_queue_redraw_or_relayout (self);
|
||||
|
||||
g_signal_emit (self, text_signals[TEXT_CHANGED], 0);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_TEXT]);
|
||||
@ -4872,8 +4895,7 @@ clutter_text_set_cursor_visible (ClutterText *self,
|
||||
{
|
||||
priv->cursor_visible = cursor_visible;
|
||||
|
||||
clutter_text_dirty_cache (self);
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
clutter_text_queue_redraw_or_relayout (self);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CURSOR_VISIBLE]);
|
||||
}
|
||||
@ -5774,9 +5796,7 @@ clutter_text_set_line_alignment (ClutterText *self,
|
||||
{
|
||||
priv->alignment = alignment;
|
||||
|
||||
clutter_text_dirty_cache (self);
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
clutter_text_queue_redraw_or_relayout (self);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_LINE_ALIGNMENT]);
|
||||
}
|
||||
@ -5831,9 +5851,7 @@ clutter_text_set_use_markup (ClutterText *self,
|
||||
if (setting)
|
||||
clutter_text_set_markup_internal (self, text);
|
||||
|
||||
clutter_text_dirty_cache (self);
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
clutter_text_queue_redraw_or_relayout (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5880,9 +5898,7 @@ clutter_text_set_justify (ClutterText *self,
|
||||
{
|
||||
priv->justify = justify;
|
||||
|
||||
clutter_text_dirty_cache (self);
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
clutter_text_queue_redraw_or_relayout (self);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_JUSTIFY]);
|
||||
}
|
||||
@ -6449,8 +6465,7 @@ clutter_text_set_preedit_string (ClutterText *self,
|
||||
priv->preedit_set = TRUE;
|
||||
}
|
||||
|
||||
clutter_text_dirty_cache (self);
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
clutter_text_queue_redraw_or_relayout (self);
|
||||
}
|
||||
|
||||
|
||||
@ -6512,7 +6527,9 @@ clutter_text_set_input_hints (ClutterText *self,
|
||||
g_return_if_fail (CLUTTER_IS_TEXT (self));
|
||||
|
||||
self->priv->input_hints = hints;
|
||||
clutter_input_focus_set_content_hints (self->priv->input_focus, hints);
|
||||
|
||||
if (clutter_input_focus_is_focused (self->priv->input_focus))
|
||||
clutter_input_focus_set_content_hints (self->priv->input_focus, hints);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_INPUT_HINTS]);
|
||||
}
|
||||
|
||||
@ -6531,7 +6548,9 @@ clutter_text_set_input_purpose (ClutterText *self,
|
||||
g_return_if_fail (CLUTTER_IS_TEXT (self));
|
||||
|
||||
self->priv->input_purpose = purpose;
|
||||
clutter_input_focus_set_content_purpose (self->priv->input_focus, purpose);
|
||||
|
||||
if (clutter_input_focus_is_focused (self->priv->input_focus))
|
||||
clutter_input_focus_set_content_purpose (self->priv->input_focus, 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)
|
||||
seat = priv->main_seat;
|
||||
else
|
||||
seat = clutter_seat_evdev_new (manager_evdev);
|
||||
{
|
||||
seat = clutter_seat_evdev_new (manager_evdev);
|
||||
priv->seats = g_slist_append (priv->seats, seat);
|
||||
}
|
||||
|
||||
clutter_seat_evdev_set_libinput_seat (seat, libinput_seat);
|
||||
priv->seats = g_slist_append (priv->seats, seat);
|
||||
}
|
||||
|
||||
device = _clutter_input_device_evdev_new (manager, seat, libinput_device);
|
||||
@ -919,7 +921,6 @@ clutter_device_manager_evdev_get_device (ClutterDeviceManager *manager,
|
||||
ClutterDeviceManagerEvdev *manager_evdev;
|
||||
ClutterDeviceManagerEvdevPrivate *priv;
|
||||
GSList *l;
|
||||
GSList *device_it;
|
||||
|
||||
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager);
|
||||
priv = manager_evdev->priv;
|
||||
@ -927,14 +928,10 @@ clutter_device_manager_evdev_get_device (ClutterDeviceManager *manager,
|
||||
for (l = priv->seats; l; l = l->next)
|
||||
{
|
||||
ClutterSeatEvdev *seat = l->data;
|
||||
ClutterInputDevice *device = clutter_seat_evdev_get_device (seat, id);
|
||||
|
||||
for (device_it = seat->devices; device_it; device_it = device_it->next)
|
||||
{
|
||||
ClutterInputDevice *device = device_it->data;
|
||||
|
||||
if (clutter_input_device_get_device_id (device) == id)
|
||||
return device;
|
||||
}
|
||||
if (device)
|
||||
return device;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -1967,6 +1964,7 @@ clutter_device_manager_evdev_constructed (GObject *gobject)
|
||||
xkb_context_unref (ctx);
|
||||
|
||||
priv->main_seat = clutter_seat_evdev_new (manager_evdev);
|
||||
priv->seats = g_slist_append (priv->seats, priv->main_seat);
|
||||
|
||||
dispatch_libinput (manager_evdev);
|
||||
|
||||
|
@ -433,6 +433,8 @@ key_event_is_modifier (ClutterEvent *event)
|
||||
case XKB_KEY_Super_R:
|
||||
case XKB_KEY_Hyper_L:
|
||||
case XKB_KEY_Hyper_R:
|
||||
case XKB_KEY_Caps_Lock:
|
||||
case XKB_KEY_Shift_Lock:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
@ -584,6 +586,12 @@ handle_stickykeys_press (ClutterEvent *event,
|
||||
}
|
||||
|
||||
depressed_mods = xkb_state_serialize_mods (seat->xkb, XKB_STATE_MODS_DEPRESSED);
|
||||
/* Ignore the lock modifier mask, that one cannot be sticky, yet the
|
||||
* CAPS_LOCK key itself counts as a modifier as it might be remapped
|
||||
* to some other modifier which can be sticky.
|
||||
*/
|
||||
depressed_mods &= ~CLUTTER_LOCK_MASK;
|
||||
|
||||
new_latched_mask = device->stickykeys_latched_mask;
|
||||
new_locked_mask = device->stickykeys_locked_mask;
|
||||
|
||||
@ -1122,6 +1130,10 @@ clutter_input_device_evdev_process_kbd_a11y_event (ClutterEvent *e
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device);
|
||||
|
||||
/* Ignore key events injected from IM */
|
||||
if (event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD)
|
||||
goto emit_event;
|
||||
|
||||
if (!device_evdev->a11y_flags & CLUTTER_A11Y_KEYBOARD_ENABLED)
|
||||
goto emit_event;
|
||||
|
||||
|
@ -858,6 +858,24 @@ clutter_seat_evdev_free (ClutterSeatEvdev *seat)
|
||||
g_free (seat);
|
||||
}
|
||||
|
||||
ClutterInputDevice *
|
||||
clutter_seat_evdev_get_device (ClutterSeatEvdev *seat,
|
||||
gint id)
|
||||
{
|
||||
ClutterInputDevice *device;
|
||||
GSList *l;
|
||||
|
||||
for (l = seat->devices; l; l = l->next)
|
||||
{
|
||||
device = l->data;
|
||||
|
||||
if (clutter_input_device_get_device_id (device) == id)
|
||||
return device;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat,
|
||||
ClutterStage *stage)
|
||||
|
@ -139,6 +139,9 @@ void clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
|
||||
|
||||
void clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat);
|
||||
|
||||
ClutterInputDevice * clutter_seat_evdev_get_device (ClutterSeatEvdev *seat,
|
||||
gint id);
|
||||
|
||||
ClutterTouchState * clutter_seat_evdev_acquire_touch_state (ClutterSeatEvdev *seat,
|
||||
int device_slot);
|
||||
|
||||
|
@ -452,7 +452,7 @@ libmutter_cogl_@LIBMUTTER_API_VERSION@_la_LDFLAGS = \
|
||||
-avoid-version \
|
||||
-export-dynamic \
|
||||
-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)
|
||||
nodist_libmutter_cogl_@LIBMUTTER_API_VERSION@_la_SOURCES = $(BUILT_SOURCES)
|
||||
|
@ -109,7 +109,11 @@ _cogl_object_default_unref (void *object)
|
||||
void
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1412,22 +1412,12 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
|
||||
if (!cogl_is_offscreen (framebuffer))
|
||||
y = framebuffer_height - y - height;
|
||||
|
||||
required_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
|
||||
format,
|
||||
&gl_intformat,
|
||||
&gl_format,
|
||||
&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
|
||||
required_format = ctx->driver_vtable->pixel_format_to_gl_with_target (ctx,
|
||||
framebuffer->internal_format,
|
||||
format,
|
||||
&gl_intformat,
|
||||
&gl_format,
|
||||
&gl_type);
|
||||
|
||||
/* NB: All offscreen rendering is done upside down so there is no need
|
||||
* to flip in this case... */
|
||||
|
@ -181,6 +181,9 @@ _cogl_winsys_egl_make_current (CoglDisplay *display,
|
||||
EGLSurface read,
|
||||
EGLContext context);
|
||||
|
||||
EGLBoolean
|
||||
_cogl_winsys_egl_ensure_current (CoglDisplay *display);
|
||||
|
||||
#ifdef EGL_KHR_image_base
|
||||
EGLImageKHR
|
||||
_cogl_egl_create_image (CoglContext *ctx,
|
||||
|
@ -309,6 +309,18 @@ _cogl_winsys_egl_make_current (CoglDisplay *display,
|
||||
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
|
||||
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_minor_version], [28])
|
||||
m4_define([mutter_micro_version], [0])
|
||||
m4_define([mutter_micro_version], [3])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@ -262,7 +262,19 @@ AC_SUBST(XWAYLAND_PATH)
|
||||
|
||||
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,
|
||||
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 ""
|
||||
"Project-Id-Version: mutter master\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
|
||||
"POT-Creation-Date: 2018-03-05 19:32+0000\n"
|
||||
"PO-Revision-Date: 2018-03-06 22:02+0100\n"
|
||||
"POT-Creation-Date: 2018-04-03 20:43+0000\n"
|
||||
"PO-Revision-Date: 2018-04-09 20:28+0200\n"
|
||||
"Last-Translator: Matej Urbančič <mateju@svn.gnome.org>\n"
|
||||
"Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\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"
|
||||
"%100==4 ? 3 : 0);\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
|
||||
msgid "Navigation"
|
||||
@ -481,7 +481,7 @@ msgstr "Ponovno omogoči tipkovne bližnjice"
|
||||
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:64
|
||||
msgid "Allow grabs with Xwayland"
|
||||
msgstr ""
|
||||
msgstr "Dovoli zajemanje z XWayland"
|
||||
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:65
|
||||
msgid ""
|
||||
@ -491,10 +491,14 @@ msgid ""
|
||||
"window or be among the applications white-listed in key “xwayland-grab-"
|
||||
"access-rules”."
|
||||
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
|
||||
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
|
||||
msgid ""
|
||||
@ -509,6 +513,15 @@ msgid ""
|
||||
"using the specific keyboard shortcut defined by the keybinding key “restore-"
|
||||
"shortcuts”."
|
||||
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
|
||||
#. * different modes.
|
||||
|
@ -153,7 +153,7 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
|
||||
backends/meta-pointer-constraint.h \
|
||||
backends/meta-settings.c \
|
||||
backends/meta-settings-private.h \
|
||||
backends/meta-stage.h \
|
||||
backends/meta-stage-private.h \
|
||||
backends/meta-stage.c \
|
||||
backends/meta-renderer.c \
|
||||
backends/meta-renderer.h \
|
||||
@ -161,6 +161,7 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
|
||||
backends/meta-renderer-view.h \
|
||||
backends/edid-parse.c \
|
||||
backends/edid.h \
|
||||
backends/gsm-inhibitor-flag.h \
|
||||
backends/x11/meta-backend-x11.c \
|
||||
backends/x11/meta-backend-x11.h \
|
||||
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-renderer-x11-nested.c \
|
||||
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.h \
|
||||
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-private.h \
|
||||
compositor/meta-window-group.c \
|
||||
compositor/meta-window-group.h \
|
||||
compositor/meta-window-group-private.h \
|
||||
compositor/meta-window-shape.c \
|
||||
compositor/region-utils.c \
|
||||
compositor/region-utils.h \
|
||||
@ -487,8 +486,6 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES += \
|
||||
backends/native/meta-default-modes.h \
|
||||
backends/native/meta-gpu-kms.c \
|
||||
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.h \
|
||||
backends/native/meta-monitor-manager-kms.c \
|
||||
@ -546,7 +543,9 @@ libmutterinclude_headers = \
|
||||
meta/meta-settings.h \
|
||||
meta/meta-shaped-texture.h \
|
||||
meta/meta-shadow-factory.h \
|
||||
meta/meta-stage.h \
|
||||
meta/meta-window-actor.h \
|
||||
meta/meta-window-group.h \
|
||||
meta/meta-window-shape.h \
|
||||
meta/prefs.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__ */
|
@ -59,8 +59,6 @@ struct _MetaBackendClass
|
||||
|
||||
void (* post_init) (MetaBackend *backend);
|
||||
|
||||
MetaIdleMonitor * (* create_idle_monitor) (MetaBackend *backend,
|
||||
int device_id);
|
||||
MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend,
|
||||
GError **error);
|
||||
MetaCursorRenderer * (* create_cursor_renderer) (MetaBackend *backend);
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "meta-input-settings-private.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "meta-stage.h"
|
||||
#include "meta-stage-private.h"
|
||||
|
||||
#ifdef HAVE_REMOTE_DESKTOP
|
||||
#include "backends/meta-dbus-session-watcher.h"
|
||||
@ -110,6 +110,11 @@ struct _MetaBackendPrivate
|
||||
|
||||
MetaPointerConstraint *client_pointer_constraint;
|
||||
MetaDnd *dnd;
|
||||
|
||||
UpClient *up_client;
|
||||
guint sleep_signal_id;
|
||||
GCancellable *cancellable;
|
||||
GDBusConnection *system_bus;
|
||||
};
|
||||
typedef struct _MetaBackendPrivate MetaBackendPrivate;
|
||||
|
||||
@ -136,6 +141,13 @@ meta_backend_finalize (GObject *object)
|
||||
g_clear_object (&priv->dbus_session_watcher);
|
||||
#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)
|
||||
g_source_remove (priv->device_update_idle_id);
|
||||
|
||||
@ -158,7 +170,7 @@ meta_backend_sync_screen_size (MetaBackend *backend)
|
||||
}
|
||||
|
||||
static void
|
||||
center_pointer (MetaBackend *backend)
|
||||
reset_pointer_position (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
MetaMonitorManager *monitor_manager = priv->monitor_manager;
|
||||
@ -167,9 +179,11 @@ center_pointer (MetaBackend *backend)
|
||||
primary =
|
||||
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,
|
||||
primary->rect.x + primary->rect.width / 2,
|
||||
primary->rect.y + primary->rect.height / 2);
|
||||
primary->rect.x + primary->rect.width * 0.9,
|
||||
primary->rect.y + primary->rect.height * 0.9);
|
||||
}
|
||||
|
||||
void
|
||||
@ -192,7 +206,7 @@ meta_backend_monitors_changed (MetaBackend *backend)
|
||||
!priv->is_pointer_position_initialized) &&
|
||||
!meta_monitor_manager_is_headless (monitor_manager))
|
||||
{
|
||||
center_pointer (backend);
|
||||
reset_pointer_position (backend);
|
||||
priv->is_pointer_position_initialized = TRUE;
|
||||
}
|
||||
}
|
||||
@ -222,7 +236,9 @@ static MetaIdleMonitor *
|
||||
meta_backend_create_idle_monitor (MetaBackend *backend,
|
||||
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
|
||||
@ -465,7 +481,7 @@ meta_backend_real_post_init (MetaBackend *backend)
|
||||
|
||||
if (!meta_monitor_manager_is_headless (priv->monitor_manager))
|
||||
{
|
||||
center_pointer (backend);
|
||||
reset_pointer_position (backend);
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
meta_backend_initable_init (GInitable *initable,
|
||||
GCancellable *cancellable,
|
||||
@ -619,6 +690,16 @@ meta_backend_initable_init (GInitable *initable,
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <cogl/cogl.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "meta-stage.h"
|
||||
#include "meta-stage-private.h"
|
||||
|
||||
struct _MetaCursorRendererPrivate
|
||||
{
|
||||
@ -264,6 +264,18 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
||||
update_cursor (renderer, priv->displayed_cursor);
|
||||
}
|
||||
|
||||
ClutterPoint
|
||||
meta_cursor_renderer_get_position (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv =
|
||||
meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
return (ClutterPoint) {
|
||||
.x = priv->current_x,
|
||||
.y = priv->current_y
|
||||
};
|
||||
}
|
||||
|
||||
MetaCursorSprite *
|
||||
meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
|
||||
{
|
||||
|
@ -62,6 +62,7 @@ void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
||||
void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
||||
float x,
|
||||
float y);
|
||||
ClutterPoint meta_cursor_renderer_get_position (MetaCursorRenderer *renderer);
|
||||
void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer);
|
||||
|
||||
MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "meta-idle-monitor-dbus.h"
|
||||
#include <meta/meta-idle-monitor.h>
|
||||
#include <backends/meta-idle-monitor-private.h>
|
||||
#include "meta-dbus-idle-monitor.h"
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
@ -43,6 +44,26 @@ handle_get_idletime (MetaDBusIdleMonitor *skeleton,
|
||||
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 {
|
||||
MetaDBusIdleMonitor *dbus_monitor;
|
||||
MetaIdleMonitor *monitor;
|
||||
@ -173,6 +194,8 @@ create_monitor_skeleton (GDBusObjectManagerServer *manager,
|
||||
G_CALLBACK (handle_add_user_active_watch), monitor, 0);
|
||||
g_signal_connect_object (skeleton, "handle-remove-watch",
|
||||
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_CALLBACK (handle_get_idletime), monitor, 0);
|
||||
|
||||
|
@ -26,9 +26,6 @@
|
||||
#include <meta/meta-idle-monitor.h>
|
||||
#include "display-private.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/sync.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaIdleMonitor *monitor;
|
||||
@ -38,28 +35,26 @@ typedef struct
|
||||
GDestroyNotify notify;
|
||||
guint64 timeout_msec;
|
||||
int idle_source_id;
|
||||
GSource *timeout_source;
|
||||
} MetaIdleMonitorWatch;
|
||||
|
||||
struct _MetaIdleMonitor
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GDBusProxy *session_proxy;
|
||||
gboolean inhibited;
|
||||
GHashTable *watches;
|
||||
int device_id;
|
||||
guint64 last_event_time;
|
||||
};
|
||||
|
||||
struct _MetaIdleMonitorClass
|
||||
{
|
||||
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_reset_idletime (MetaIdleMonitor *monitor);
|
||||
|
||||
#endif /* META_IDLE_MONITOR_PRIVATE_H */
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <meta/util.h>
|
||||
#include <meta/main.h>
|
||||
#include <meta/meta-idle-monitor.h>
|
||||
#include "gsm-inhibitor-flag.h"
|
||||
#include "meta-idle-monitor-private.h"
|
||||
#include "meta-idle-monitor-dbus.h"
|
||||
#include "meta-backend-private.h"
|
||||
@ -87,6 +88,7 @@ meta_idle_monitor_dispose (GObject *object)
|
||||
MetaIdleMonitor *monitor = META_IDLE_MONITOR (object);
|
||||
|
||||
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);
|
||||
}
|
||||
@ -151,9 +153,117 @@ meta_idle_monitor_class_init (MetaIdleMonitorClass *klass)
|
||||
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
|
||||
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,
|
||||
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");
|
||||
monitor->inhibited = g_variant_get_uint32 (v) & GSM_INHIBITOR_FLAG_IDLE;
|
||||
g_variant_unref (v);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -185,6 +295,36 @@ meta_idle_monitor_get_for_device (int 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 *
|
||||
make_watch (MetaIdleMonitor *monitor,
|
||||
guint64 timeout_msec,
|
||||
@ -194,11 +334,32 @@ make_watch (MetaIdleMonitor *monitor,
|
||||
{
|
||||
MetaIdleMonitorWatch *watch;
|
||||
|
||||
watch = META_IDLE_MONITOR_GET_CLASS (monitor)->make_watch (monitor,
|
||||
timeout_msec,
|
||||
callback,
|
||||
user_data,
|
||||
notify);
|
||||
watch = g_slice_new0 (MetaIdleMonitorWatch);
|
||||
|
||||
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 (&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,
|
||||
GUINT_TO_POINTER (watch->id),
|
||||
@ -314,5 +475,39 @@ meta_idle_monitor_remove_watch (MetaIdleMonitor *monitor,
|
||||
gint64
|
||||
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);
|
||||
else if (strcmp (key, "tap-to-click") == 0)
|
||||
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);
|
||||
else if (strcmp(key, "disable-while-typing") == 0)
|
||||
update_touchpad_disable_while_typing (input_settings, NULL);
|
||||
|
@ -100,11 +100,12 @@ static MetaMonitorTransform
|
||||
derive_monitor_transform (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *main_output;
|
||||
MetaMonitorTransform transform;
|
||||
|
||||
main_output = meta_monitor_get_main_output (monitor);
|
||||
transform = meta_output_get_assigned_crtc (main_output)->transform;
|
||||
|
||||
return meta_monitor_crtc_to_logical_transform (monitor,
|
||||
main_output->crtc->transform);
|
||||
return meta_monitor_crtc_to_logical_transform (monitor, transform);
|
||||
}
|
||||
|
||||
MetaLogicalMonitor *
|
||||
@ -145,7 +146,7 @@ meta_logical_monitor_add_monitor (MetaLogicalMonitor *logical_monitor,
|
||||
|
||||
is_presentation = logical_monitor->is_presentation;
|
||||
logical_monitor->monitors = g_list_append (logical_monitor->monitors,
|
||||
monitor);
|
||||
g_object_ref (monitor));
|
||||
|
||||
for (l = logical_monitor->monitors; l; l = l->next)
|
||||
{
|
||||
@ -157,10 +158,12 @@ meta_logical_monitor_add_monitor (MetaLogicalMonitor *logical_monitor,
|
||||
for (l_output = outputs; l_output; l_output = l_output->next)
|
||||
{
|
||||
MetaOutput *output = l_output->data;
|
||||
MetaCrtc *crtc;
|
||||
|
||||
is_presentation = is_presentation && output->is_presentation;
|
||||
if (output->crtc)
|
||||
output->crtc->logical_monitor = logical_monitor;
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
if (crtc)
|
||||
crtc->logical_monitor = logical_monitor;
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,7 +223,7 @@ foreach_crtc (MetaMonitor *monitor,
|
||||
ForeachCrtcData *data = user_data;
|
||||
|
||||
data->func (data->logical_monitor,
|
||||
monitor_crtc_mode->output->crtc,
|
||||
meta_output_get_assigned_crtc (monitor_crtc_mode->output),
|
||||
data->user_data);
|
||||
|
||||
return TRUE;
|
||||
@ -254,13 +257,17 @@ meta_logical_monitor_init (MetaLogicalMonitor *logical_monitor)
|
||||
}
|
||||
|
||||
static void
|
||||
meta_logical_monitor_finalize (GObject *object)
|
||||
meta_logical_monitor_dispose (GObject *object)
|
||||
{
|
||||
MetaLogicalMonitor *logical_monitor = META_LOGICAL_MONITOR (object);
|
||||
|
||||
g_list_free (logical_monitor->monitors);
|
||||
if (logical_monitor->monitors)
|
||||
{
|
||||
g_list_free_full (logical_monitor->monitors, g_object_unref);
|
||||
logical_monitor->monitors = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (meta_logical_monitor_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (meta_logical_monitor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -268,7 +275,7 @@ meta_logical_monitor_class_init (MetaLogicalMonitorClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_logical_monitor_finalize;
|
||||
object_class->dispose = meta_logical_monitor_dispose;
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -486,7 +486,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
meta_output_assign_crtc (output, crtc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -531,7 +531,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
continue;
|
||||
}
|
||||
|
||||
output->crtc = NULL;
|
||||
meta_output_unassign_crtc (output);
|
||||
output->is_primary = FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,9 @@ static gboolean
|
||||
meta_monitor_manager_is_config_complete (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config);
|
||||
|
||||
static MetaMonitor *
|
||||
meta_monitor_manager_get_active_monitor (MetaMonitorManager *manager);
|
||||
|
||||
MetaBackend *
|
||||
meta_monitor_manager_get_backend (MetaMonitorManager *manager)
|
||||
{
|
||||
@ -198,13 +201,17 @@ calculate_monitor_scale (MetaMonitorManager *manager,
|
||||
static float
|
||||
derive_calculated_global_scale (MetaMonitorManager *manager)
|
||||
{
|
||||
MetaMonitor *primary_monitor;
|
||||
MetaMonitor *monitor = NULL;
|
||||
|
||||
primary_monitor = meta_monitor_manager_get_primary_monitor (manager);
|
||||
if (!primary_monitor)
|
||||
monitor = meta_monitor_manager_get_primary_monitor (manager);
|
||||
|
||||
if (!monitor || !meta_monitor_is_active (monitor))
|
||||
monitor = meta_monitor_manager_get_active_monitor (manager);
|
||||
|
||||
if (!monitor)
|
||||
return 1.0;
|
||||
|
||||
return calculate_monitor_scale (manager, primary_monitor);
|
||||
return calculate_monitor_scale (manager, monitor);
|
||||
}
|
||||
|
||||
static float
|
||||
@ -598,7 +605,7 @@ meta_monitor_manager_ensure_configured (MetaMonitorManager *manager)
|
||||
{
|
||||
g_clear_object (&config);
|
||||
g_warning ("Failed to use fallback monitor configuration: %s",
|
||||
error->message);
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
else
|
||||
@ -1032,12 +1039,13 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
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;
|
||||
GVariantBuilder crtcs, modes, clones, properties;
|
||||
GBytes *edid;
|
||||
char *edid_file;
|
||||
MetaCrtc *crtc;
|
||||
int crtc_index;
|
||||
|
||||
g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
|
||||
@ -1131,8 +1139,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
output->tile_info.tile_h));
|
||||
}
|
||||
|
||||
crtc_index = output->crtc ? g_list_index (combined_crtcs, output->crtc)
|
||||
: -1;
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
crtc_index = crtc ? g_list_index (combined_crtcs, crtc) : -1;
|
||||
g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
|
||||
i, /* ID */
|
||||
(gint64)output->winsys_id,
|
||||
@ -2382,6 +2390,12 @@ meta_monitor_manager_get_laptop_panel (MetaMonitorManager *manager)
|
||||
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 *
|
||||
meta_monitor_manager_get_monitor_from_connector (MetaMonitorManager *manager,
|
||||
const char *connector)
|
||||
@ -2894,11 +2908,7 @@ meta_monitor_manager_get_monitor_for_connector (MetaMonitorManager *manager,
|
||||
|
||||
if (meta_monitor_is_active (monitor) &&
|
||||
g_str_equal (connector, meta_monitor_get_connector (monitor)))
|
||||
{
|
||||
MetaOutput *main_output = meta_monitor_get_main_output (monitor);
|
||||
|
||||
return main_output->crtc->logical_monitor->number;
|
||||
}
|
||||
return meta_monitor_get_logical_monitor (monitor)->number;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
@ -204,10 +204,12 @@ gboolean
|
||||
meta_monitor_is_active (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *output;
|
||||
MetaCrtc *crtc;
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
|
||||
return output->crtc && output->crtc->current_mode;
|
||||
return crtc && crtc->current_mode;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -385,6 +387,21 @@ meta_monitor_crtc_to_logical_transform (MetaMonitor *monitor,
|
||||
return new_transform;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_dispose (GObject *object)
|
||||
{
|
||||
MetaMonitor *monitor = META_MONITOR (object);
|
||||
MetaMonitorPrivate *priv = meta_monitor_get_instance_private (monitor);
|
||||
|
||||
if (priv->outputs)
|
||||
{
|
||||
g_list_free_full (priv->outputs, g_object_unref);
|
||||
priv->outputs = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (meta_monitor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_finalize (GObject *object)
|
||||
{
|
||||
@ -393,7 +410,6 @@ meta_monitor_finalize (GObject *object)
|
||||
|
||||
g_hash_table_destroy (priv->mode_ids);
|
||||
g_list_free_full (priv->modes, (GDestroyNotify) meta_monitor_mode_free);
|
||||
g_clear_pointer (&priv->outputs, g_list_free);
|
||||
meta_monitor_spec_free (priv->spec);
|
||||
|
||||
G_OBJECT_CLASS (meta_monitor_parent_class)->finalize (object);
|
||||
@ -412,6 +428,7 @@ meta_monitor_class_init (MetaMonitorClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = meta_monitor_dispose;
|
||||
object_class->finalize = meta_monitor_finalize;
|
||||
}
|
||||
|
||||
@ -493,6 +510,7 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
|
||||
for (i = 0; i < output->n_modes; i++)
|
||||
{
|
||||
MetaCrtcMode *crtc_mode = output->modes[i];
|
||||
MetaCrtc *crtc;
|
||||
MetaMonitorMode *mode;
|
||||
gboolean replace;
|
||||
|
||||
@ -526,7 +544,9 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
|
||||
|
||||
if (crtc_mode == output->preferred_mode)
|
||||
monitor_priv->preferred_mode = mode;
|
||||
if (output->crtc && crtc_mode == output->crtc->current_mode)
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
if (crtc && crtc_mode == crtc->current_mode)
|
||||
monitor_priv->current_mode = mode;
|
||||
}
|
||||
}
|
||||
@ -545,7 +565,7 @@ meta_monitor_normal_new (MetaGpu *gpu,
|
||||
|
||||
monitor_priv->gpu = gpu;
|
||||
|
||||
monitor_priv->outputs = g_list_append (NULL, output);
|
||||
monitor_priv->outputs = g_list_append (NULL, g_object_ref (output));
|
||||
monitor_priv->winsys_id = output->winsys_id;
|
||||
meta_monitor_generate_spec (monitor);
|
||||
|
||||
@ -568,13 +588,15 @@ meta_monitor_normal_derive_layout (MetaMonitor *monitor,
|
||||
MetaRectangle *layout)
|
||||
{
|
||||
MetaOutput *output;
|
||||
MetaCrtc *crtc;
|
||||
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
*layout = (MetaRectangle) {
|
||||
.x = output->crtc->rect.x,
|
||||
.y = output->crtc->rect.y,
|
||||
.width = output->crtc->rect.width,
|
||||
.height = output->crtc->rect.height
|
||||
.x = crtc->rect.x,
|
||||
.y = crtc->rect.y,
|
||||
.width = crtc->rect.width,
|
||||
.height = crtc->rect.height
|
||||
};
|
||||
}
|
||||
|
||||
@ -658,7 +680,8 @@ add_tiled_monitor_outputs (MetaGpu *gpu,
|
||||
g_warn_if_fail (output->subpixel_order ==
|
||||
monitor_tiled->origin_output->subpixel_order);
|
||||
|
||||
monitor_priv->outputs = g_list_append (monitor_priv->outputs, output);
|
||||
monitor_priv->outputs = g_list_append (monitor_priv->outputs,
|
||||
g_object_ref (output));
|
||||
}
|
||||
}
|
||||
|
||||
@ -764,12 +787,13 @@ is_monitor_mode_assigned (MetaMonitor *monitor,
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i];
|
||||
MetaCrtc *crtc;
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
if (monitor_crtc_mode->crtc_mode &&
|
||||
(!output->crtc ||
|
||||
output->crtc->current_mode != monitor_crtc_mode->crtc_mode))
|
||||
(!crtc || crtc->current_mode != monitor_crtc_mode->crtc_mode))
|
||||
return FALSE;
|
||||
else if (!monitor_crtc_mode->crtc_mode && output->crtc)
|
||||
else if (!monitor_crtc_mode->crtc_mode && crtc)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1217,14 +1241,16 @@ meta_monitor_tiled_derive_layout (MetaMonitor *monitor,
|
||||
for (l = monitor_priv->outputs; l; l = l->next)
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
MetaCrtc *crtc;
|
||||
|
||||
if (!output->crtc)
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
if (!crtc)
|
||||
continue;
|
||||
|
||||
min_x = MIN (output->crtc->rect.x, min_x);
|
||||
min_y = MIN (output->crtc->rect.y, min_y);
|
||||
max_x = MAX (output->crtc->rect.x + output->crtc->rect.width, max_x);
|
||||
max_y = MAX (output->crtc->rect.y + output->crtc->rect.height, max_y);
|
||||
min_x = MIN (crtc->rect.x, min_x);
|
||||
min_y = MIN (crtc->rect.y, min_y);
|
||||
max_x = MAX (crtc->rect.x + crtc->rect.width, max_x);
|
||||
max_y = MAX (crtc->rect.y + crtc->rect.height, max_y);
|
||||
}
|
||||
|
||||
*layout = (MetaRectangle) {
|
||||
@ -1318,10 +1344,14 @@ meta_monitor_get_spec (MetaMonitor *monitor)
|
||||
MetaLogicalMonitor *
|
||||
meta_monitor_get_logical_monitor (MetaMonitor *monitor)
|
||||
{
|
||||
MetaOutput *output = meta_monitor_get_main_output (monitor);
|
||||
MetaOutput *output;
|
||||
MetaCrtc *crtc;
|
||||
|
||||
if (output->crtc)
|
||||
return output->crtc->logical_monitor;
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
|
||||
if (crtc)
|
||||
return crtc->logical_monitor;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
@ -21,7 +21,13 @@
|
||||
|
||||
#include "backends/meta-output.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaOutput, meta_output, G_TYPE_OBJECT)
|
||||
typedef struct _MetaOutputPrivate
|
||||
{
|
||||
/* The CRTC driving this output, NULL if the output is not enabled */
|
||||
MetaCrtc *crtc;
|
||||
} MetaOutputPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaOutput, meta_output, G_TYPE_OBJECT)
|
||||
|
||||
MetaGpu *
|
||||
meta_output_get_gpu (MetaOutput *output)
|
||||
@ -29,6 +35,44 @@ meta_output_get_gpu (MetaOutput *output)
|
||||
return output->gpu;
|
||||
}
|
||||
|
||||
void
|
||||
meta_output_assign_crtc (MetaOutput *output,
|
||||
MetaCrtc *crtc)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
g_assert (crtc);
|
||||
|
||||
g_set_object (&priv->crtc, crtc);
|
||||
}
|
||||
|
||||
void
|
||||
meta_output_unassign_crtc (MetaOutput *output)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
g_clear_object (&priv->crtc);
|
||||
}
|
||||
|
||||
MetaCrtc *
|
||||
meta_output_get_assigned_crtc (MetaOutput *output)
|
||||
{
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
return priv->crtc;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_output_dispose (GObject *object)
|
||||
{
|
||||
MetaOutput *output = META_OUTPUT (object);
|
||||
MetaOutputPrivate *priv = meta_output_get_instance_private (output);
|
||||
|
||||
g_clear_object (&priv->crtc);
|
||||
|
||||
G_OBJECT_CLASS (meta_output_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_output_finalize (GObject *object)
|
||||
{
|
||||
@ -58,5 +102,6 @@ meta_output_class_init (MetaOutputClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = meta_output_dispose;
|
||||
object_class->finalize = meta_output_finalize;
|
||||
}
|
||||
|
@ -64,9 +64,6 @@ struct _MetaOutput
|
||||
|
||||
MetaGpu *gpu;
|
||||
|
||||
/* The CRTC driving this output, NULL if the output is not enabled */
|
||||
MetaCrtc *crtc;
|
||||
|
||||
/* The low-level ID of this output, used to apply back configuration */
|
||||
glong winsys_id;
|
||||
char *name;
|
||||
@ -122,4 +119,11 @@ G_DECLARE_FINAL_TYPE (MetaOutput, meta_output, META, OUTPUT, GObject)
|
||||
|
||||
MetaGpu * meta_output_get_gpu (MetaOutput *output);
|
||||
|
||||
void meta_output_assign_crtc (MetaOutput *output,
|
||||
MetaCrtc *crtc);
|
||||
|
||||
void meta_output_unassign_crtc (MetaOutput *output);
|
||||
|
||||
MetaCrtc * meta_output_get_assigned_crtc (MetaOutput *output);
|
||||
|
||||
#endif /* META_OUTPUT_H */
|
||||
|
@ -153,6 +153,11 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
|
||||
return;
|
||||
|
||||
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)
|
||||
{
|
||||
@ -327,10 +332,18 @@ create_pipewire_stream (MetaScreenCastStreamSrc *src,
|
||||
struct spa_fraction max_framerate;
|
||||
struct spa_fraction min_framerate;
|
||||
const struct spa_pod *params[1];
|
||||
int result;
|
||||
|
||||
pipewire_stream = pw_stream_new (priv->pipewire_remote,
|
||||
"meta-screen-cast-src",
|
||||
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);
|
||||
frame_rate_fraction = meta_fraction_from_double (frame_rate);
|
||||
@ -347,23 +360,24 @@ create_pipewire_stream (MetaScreenCastStreamSrc *src,
|
||||
":", spa_type->format_video.format, "I", spa_type->video_format.BGRx,
|
||||
":", spa_type->format_video.size, "R", &SPA_RECTANGLE (width, height),
|
||||
":", spa_type->format_video.framerate, "F", &SPA_FRACTION (0, 1),
|
||||
":", spa_type->format_video.max_framerate, "Fr", &max_framerate,
|
||||
PROP_RANGE (&min_framerate,
|
||||
&max_framerate));
|
||||
":", spa_type->format_video.max_framerate, "Fru", &max_framerate,
|
||||
PROP_RANGE (&min_framerate,
|
||||
&max_framerate));
|
||||
|
||||
pw_stream_add_listener (pipewire_stream,
|
||||
&priv->pipewire_stream_listener,
|
||||
&stream_events,
|
||||
src);
|
||||
|
||||
if (pw_stream_connect (pipewire_stream,
|
||||
PW_DIRECTION_OUTPUT,
|
||||
NULL,
|
||||
PW_STREAM_FLAG_NONE,
|
||||
params, G_N_ELEMENTS (¶ms)) != 0)
|
||||
result = pw_stream_connect (pipewire_stream,
|
||||
PW_DIRECTION_OUTPUT,
|
||||
NULL,
|
||||
PW_STREAM_FLAG_NONE,
|
||||
params, G_N_ELEMENTS (params));
|
||||
if (result != 0)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Could not connect");
|
||||
"Could not connect: %s", spa_strerror (result));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -466,6 +480,12 @@ create_pipewire_source (void)
|
||||
(MetaPipeWireSource *) g_source_new (&pipewire_source_funcs,
|
||||
sizeof (MetaPipeWireSource));
|
||||
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,
|
||||
pw_loop_get_fd (pipewire_source->pipewire_loop),
|
||||
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);
|
||||
|
||||
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,
|
||||
NULL);
|
||||
if (!priv->pipewire_core)
|
||||
|
@ -33,6 +33,7 @@ typedef enum _MetaExperimentalFeature
|
||||
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
|
||||
META_EXPERIMENTAL_FEATURE_SCREEN_CAST = (1 << 1),
|
||||
META_EXPERIMENTAL_FEATURE_REMOTE_DESKTOP = (1 << 2),
|
||||
META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS = (1 << 3),
|
||||
} MetaExperimentalFeature;
|
||||
|
||||
#define META_TYPE_SETTINGS (meta_settings_get_type ())
|
||||
|
@ -267,6 +267,8 @@ experimental_features_handler (GVariant *features_variant,
|
||||
features |= META_EXPERIMENTAL_FEATURE_SCREEN_CAST;
|
||||
else if (g_str_equal (feature, "remote-desktop"))
|
||||
features |= META_EXPERIMENTAL_FEATURE_REMOTE_DESKTOP;
|
||||
else if (g_str_equal (feature, "kms-modifiers"))
|
||||
features |= META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS;
|
||||
else
|
||||
g_info ("Unknown experimental feature '%s'\n", feature);
|
||||
}
|
||||
|
@ -17,39 +17,23 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_STAGE_H
|
||||
#define META_STAGE_H
|
||||
#ifndef META_STAGE_PRIVATE_H
|
||||
#define META_STAGE_PRIVATE_H
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <meta/meta-stage.h>
|
||||
|
||||
#include "meta-cursor.h"
|
||||
#include <meta/boxes.h>
|
||||
|
||||
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;
|
||||
|
||||
struct _MetaStageClass
|
||||
{
|
||||
ClutterStageClass parent_class;
|
||||
};
|
||||
|
||||
struct _MetaStage
|
||||
{
|
||||
ClutterStage parent;
|
||||
};
|
||||
|
||||
GType meta_stage_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterActor *meta_stage_new (void);
|
||||
|
||||
MetaOverlay *meta_stage_create_cursor_overlay (MetaStage *stage);
|
||||
@ -68,4 +52,4 @@ void meta_stage_update_view_layout (MetaStage *stage);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* META_STAGE_H */
|
||||
#endif /* META_STAGE_PRIVATE_H */
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "meta-stage.h"
|
||||
#include "meta-stage-private.h"
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/meta-monitor-manager.h>
|
||||
|
@ -35,15 +35,15 @@
|
||||
#include "clutter/evdev/clutter-evdev.h"
|
||||
#include "meta-barrier-native.h"
|
||||
#include "meta-border.h"
|
||||
#include "meta-idle-monitor-native.h"
|
||||
#include "meta-monitor-manager-kms.h"
|
||||
#include "meta-cursor-renderer-native.h"
|
||||
#include "meta-launcher.h"
|
||||
#include "backends/meta-cursor-tracker-private.h"
|
||||
#include "backends/meta-idle-monitor-private.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "backends/meta-monitor-manager-private.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-input-settings-native.h"
|
||||
#include "backends/native/meta-renderer-native.h"
|
||||
@ -60,10 +60,6 @@ struct _MetaBackendNativePrivate
|
||||
{
|
||||
MetaLauncher *launcher;
|
||||
MetaBarrierManagerNative *barrier_manager;
|
||||
UpClient *up_client;
|
||||
guint sleep_signal_id;
|
||||
GCancellable *cancellable;
|
||||
GDBusConnection *system_bus;
|
||||
};
|
||||
typedef struct _MetaBackendNativePrivate MetaBackendNativePrivate;
|
||||
|
||||
@ -85,69 +81,9 @@ meta_backend_native_finalize (GObject *object)
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
constrain_to_barriers (ClutterInputDevice *device,
|
||||
guint32 time,
|
||||
@ -398,15 +334,6 @@ meta_backend_native_post_init (MetaBackend *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 *
|
||||
meta_backend_native_create_monitor_manager (MetaBackend *backend,
|
||||
GError **error)
|
||||
@ -604,7 +531,6 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
||||
|
||||
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_cursor_renderer = meta_backend_native_create_cursor_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->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 *
|
||||
@ -747,5 +663,5 @@ void meta_backend_native_resume (MetaBackendNative *native)
|
||||
meta_cursor_renderer_native_force_update (cursor_renderer_native);
|
||||
|
||||
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;
|
||||
MetaCursorRendererNativePrivate *priv =
|
||||
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
|
||||
MetaCrtc *crtc;
|
||||
MetaMonitorTransform transform;
|
||||
ClutterRect scaled_crtc_rect;
|
||||
float scale;
|
||||
int crtc_x, crtc_y;
|
||||
int crtc_width, crtc_height;
|
||||
|
||||
if (meta_is_stage_views_scaled ())
|
||||
scale = meta_logical_monitor_get_scale (data->in_logical_monitor);
|
||||
@ -305,17 +308,31 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
META_MONITOR_TRANSFORM_NORMAL,
|
||||
&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) {
|
||||
.origin = {
|
||||
.x = crtc_x / scale,
|
||||
.y = crtc_y / scale
|
||||
},
|
||||
.size = {
|
||||
.width = monitor_crtc_mode->crtc_mode->width / scale,
|
||||
.height = monitor_crtc_mode->crtc_mode->height / scale
|
||||
.width = crtc_width / scale,
|
||||
.height = crtc_height / scale
|
||||
},
|
||||
};
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (monitor_crtc_mode->output);
|
||||
|
||||
if (priv->has_hw_cursor &&
|
||||
clutter_rect_intersection (&scaled_crtc_rect,
|
||||
&data->in_local_cursor_rect,
|
||||
@ -326,7 +343,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
float crtc_cursor_x, crtc_cursor_y;
|
||||
|
||||
set_crtc_cursor (data->in_cursor_renderer_native,
|
||||
monitor_crtc_mode->output->crtc,
|
||||
crtc,
|
||||
data->in_cursor_sprite);
|
||||
|
||||
gpu_kms = META_GPU_KMS (meta_monitor_get_gpu (monitor));
|
||||
@ -336,7 +353,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
crtc_cursor_y = (data->in_local_cursor_rect.origin.y -
|
||||
scaled_crtc_rect.origin.y) * scale;
|
||||
drmModeMoveCursor (kms_fd,
|
||||
monitor_crtc_mode->output->crtc->crtc_id,
|
||||
crtc->crtc_id,
|
||||
roundf (crtc_cursor_x),
|
||||
roundf (crtc_cursor_y));
|
||||
|
||||
@ -344,8 +361,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
}
|
||||
else
|
||||
{
|
||||
set_crtc_cursor (data->in_cursor_renderer_native,
|
||||
monitor_crtc_mode->output->crtc, NULL);
|
||||
set_crtc_cursor (data->in_cursor_renderer_native, crtc, NULL);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -64,6 +64,7 @@ struct _MetaGpuKms
|
||||
gboolean page_flips_not_supported;
|
||||
};
|
||||
|
||||
G_DEFINE_QUARK (MetaGpuKmsError, meta_gpu_kms_error)
|
||||
G_DEFINE_TYPE (MetaGpuKms, meta_gpu_kms, META_TYPE_GPU)
|
||||
|
||||
static gboolean
|
||||
@ -104,8 +105,10 @@ get_crtc_drm_connectors (MetaGpu *gpu,
|
||||
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
MetaCrtc *assigned_crtc;
|
||||
|
||||
if (output->crtc == crtc)
|
||||
assigned_crtc = meta_output_get_assigned_crtc (output);
|
||||
if (assigned_crtc == crtc)
|
||||
g_array_append_val (connectors_array, output->winsys_id);
|
||||
}
|
||||
|
||||
@ -185,8 +188,10 @@ meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
|
||||
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
MetaCrtc *assigned_crtc;
|
||||
|
||||
if (output->crtc == crtc)
|
||||
assigned_crtc = meta_output_get_assigned_crtc (output);
|
||||
if (assigned_crtc == crtc)
|
||||
{
|
||||
connected_crtc_found = TRUE;
|
||||
break;
|
||||
@ -751,6 +756,8 @@ meta_gpu_kms_read_current (MetaGpu *gpu,
|
||||
are freed by the platform-independent layer. */
|
||||
free_resources (gpu_kms);
|
||||
|
||||
g_assert (resources.resources->count_connectors > 0);
|
||||
|
||||
init_connectors (gpu_kms, resources.resources);
|
||||
init_modes (gpu_kms, resources.resources);
|
||||
init_crtcs (gpu_kms, &resources);
|
||||
@ -774,11 +781,39 @@ meta_gpu_kms_new (MetaMonitorManagerKms *monitor_manager_kms,
|
||||
GSource *source;
|
||||
MetaKmsSource *kms_source;
|
||||
MetaGpuKms *gpu_kms;
|
||||
drmModeRes *drm_resources;
|
||||
guint n_connectors;
|
||||
int kms_fd;
|
||||
|
||||
kms_fd = meta_launcher_open_restricted (launcher, kms_file_path, error);
|
||||
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);
|
||||
|
||||
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,
|
||||
"monitor-manager", monitor_manager_kms,
|
||||
|
@ -29,6 +29,14 @@
|
||||
#include "backends/meta-gpu.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 ())
|
||||
G_DECLARE_FINAL_TYPE (MetaGpuKms, meta_gpu_kms, META, GPU_KMS, MetaGpu)
|
||||
|
||||
|
@ -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/native/meta-backend-native.h"
|
||||
#include "meta-cursor-renderer-native.h"
|
||||
#include "meta-idle-monitor-native.h"
|
||||
#include "meta-renderer-native.h"
|
||||
|
||||
struct _MetaLauncher
|
||||
|
@ -188,7 +188,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
MetaOutput *output = g_ptr_array_index (crtc_info->outputs, j);
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
meta_output_assign_crtc (output, crtc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
continue;
|
||||
}
|
||||
|
||||
output->crtc = NULL;
|
||||
meta_output_unassign_crtc (output);
|
||||
output->is_primary = FALSE;
|
||||
}
|
||||
}
|
||||
@ -674,16 +674,19 @@ meta_monitor_manager_kms_initable_init (GInitable *initable,
|
||||
gpu_paths = get_gpu_paths (manager_kms, GPU_TYPE_SECONDARY, primary_gpu_path);
|
||||
for (l = gpu_paths; l; l = l->next)
|
||||
{
|
||||
GError *secondary_error = NULL;
|
||||
g_autoptr (GError) secondary_error = NULL;
|
||||
char *gpu_path = l->data;
|
||||
MetaGpuKms *gpu_kms;
|
||||
|
||||
gpu_kms = meta_gpu_kms_new (manager_kms, gpu_path, &secondary_error);
|
||||
if (!gpu_kms)
|
||||
{
|
||||
g_warning ("Failed to open secondary gpu '%s': %s",
|
||||
gpu_path, secondary_error->message);
|
||||
g_error_free (secondary_error);
|
||||
if (g_error_matches (secondary_error, META_GPU_KMS_ERROR, META_GPU_KMS_ERROR_NO_CONNECTORS))
|
||||
g_message ("Ignoring GPU %s due to the lack of connectors", gpu_path);
|
||||
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),
|
||||
|
@ -64,11 +64,13 @@ typedef struct _MetaOutputKms
|
||||
void
|
||||
meta_output_kms_set_underscan (MetaOutput *output)
|
||||
{
|
||||
if (!output->crtc)
|
||||
MetaCrtc *crtc;
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
if (!crtc)
|
||||
return;
|
||||
|
||||
meta_crtc_kms_set_underscan (output->crtc,
|
||||
output->is_underscanning);
|
||||
meta_crtc_kms_set_underscan (crtc, output->is_underscanning);
|
||||
}
|
||||
|
||||
void
|
||||
@ -600,14 +602,14 @@ meta_create_kms_output (MetaGpuKms *gpu_kms,
|
||||
|
||||
if (crtc->crtc_id == output_kms->current_encoder->crtc_id)
|
||||
{
|
||||
output->crtc = crtc;
|
||||
meta_output_assign_crtc (output, crtc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
output->crtc = NULL;
|
||||
meta_output_unassign_crtc (output);
|
||||
}
|
||||
|
||||
if (old_output)
|
||||
|
@ -193,6 +193,8 @@ struct _MetaRendererNative
|
||||
MetaMonitorManagerKms *monitor_manager_kms;
|
||||
MetaGles3 *gles3;
|
||||
|
||||
gboolean use_modifiers;
|
||||
|
||||
GHashTable *gpu_datas;
|
||||
|
||||
CoglClosure *swap_notify_idle;
|
||||
@ -1586,6 +1588,7 @@ gbm_get_next_fb_id (MetaGpuKms *gpu_kms,
|
||||
struct gbm_bo **out_next_bo,
|
||||
uint32_t *out_next_fb_id)
|
||||
{
|
||||
MetaRendererNative *renderer_native = meta_renderer_native_from_gpu (gpu_kms);
|
||||
struct gbm_bo *next_bo;
|
||||
uint32_t next_fb_id;
|
||||
int kms_fd;
|
||||
@ -1598,6 +1601,12 @@ gbm_get_next_fb_id (MetaGpuKms *gpu_kms,
|
||||
/* Now we need to set the CRTC to whatever is the front buffer */
|
||||
next_bo = gbm_surface_lock_front_buffer (gbm_surface);
|
||||
|
||||
if (!next_bo)
|
||||
{
|
||||
g_error ("Impossible to lock surface front buffer: %m");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < gbm_bo_get_plane_count (next_bo); i++)
|
||||
{
|
||||
strides[i] = gbm_bo_get_stride_for_plane (next_bo, i);
|
||||
@ -1608,7 +1617,8 @@ gbm_get_next_fb_id (MetaGpuKms *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,
|
||||
gbm_bo_get_width (next_bo),
|
||||
@ -1854,18 +1864,18 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos);
|
||||
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);
|
||||
|
||||
parent_vtable->onscreen_swap_buffers_with_damage (onscreen,
|
||||
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,
|
||||
render_gpu);
|
||||
switch (renderer_gpu_data->mode)
|
||||
@ -1907,12 +1917,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
* context.
|
||||
*/
|
||||
if (egl_context_changed)
|
||||
{
|
||||
_cogl_winsys_egl_make_current (cogl_display,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
}
|
||||
_cogl_winsys_egl_ensure_current (cogl_display);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1996,7 +2001,7 @@ meta_renderer_native_create_surface_gbm (CoglOnscreen *onscreen,
|
||||
CoglRenderer *cogl_renderer = cogl_display->renderer;
|
||||
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
|
||||
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;
|
||||
EGLSurface new_egl_surface;
|
||||
uint32_t format = GBM_FORMAT_XRGB8888;
|
||||
@ -2006,7 +2011,10 @@ meta_renderer_native_create_surface_gbm (CoglOnscreen *onscreen,
|
||||
meta_renderer_native_get_gpu_data (renderer_native,
|
||||
onscreen_native->render_gpu);
|
||||
|
||||
modifiers = get_supported_modifiers (onscreen, format);
|
||||
if (renderer_native->use_modifiers)
|
||||
modifiers = get_supported_modifiers (onscreen, format);
|
||||
else
|
||||
modifiers = NULL;
|
||||
|
||||
if (modifiers)
|
||||
{
|
||||
@ -2017,7 +2025,8 @@ meta_renderer_native_create_surface_gbm (CoglOnscreen *onscreen,
|
||||
modifiers->len);
|
||||
g_array_free (modifiers, TRUE);
|
||||
}
|
||||
else
|
||||
|
||||
if (!new_gbm_surface)
|
||||
{
|
||||
uint32_t flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
|
||||
|
||||
@ -2080,6 +2089,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
|
||||
EGLDisplay egl_display = renderer_gpu_data->egl_display;
|
||||
MetaMonitor *monitor;
|
||||
MetaOutput *output;
|
||||
MetaCrtc *crtc;
|
||||
EGLConfig egl_config;
|
||||
EGLStreamKHR egl_stream;
|
||||
EGLSurface egl_surface;
|
||||
@ -2103,6 +2113,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
|
||||
|
||||
monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
|
||||
output = meta_monitor_get_main_output (monitor);
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
|
||||
/*
|
||||
* An "logical_monitor" may have multiple outputs/crtcs in case its tiled,
|
||||
@ -2110,7 +2121,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
|
||||
* lets pass the first one.
|
||||
*/
|
||||
output_attribs[0] = EGL_DRM_CRTC_EXT;
|
||||
output_attribs[1] = output->crtc->crtc_id;
|
||||
output_attribs[1] = crtc->crtc_id;
|
||||
output_attribs[2] = EGL_NONE;
|
||||
|
||||
if (!meta_egl_get_output_layers (egl, egl_display,
|
||||
@ -2708,12 +2719,10 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
|
||||
{
|
||||
MetaMonitor *main_monitor;
|
||||
MetaOutput *main_output;
|
||||
MetaMonitorTransform crtc_transform;
|
||||
MetaCrtc *crtc;
|
||||
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
|
||||
main_output = meta_monitor_get_main_output (main_monitor);
|
||||
crtc_transform =
|
||||
meta_monitor_logical_to_crtc_transform (main_monitor,
|
||||
logical_monitor->transform);
|
||||
crtc = meta_output_get_assigned_crtc (main_output);
|
||||
|
||||
/*
|
||||
* Pick any monitor and output and check; all CRTCs of a logical monitor will
|
||||
@ -2721,11 +2730,11 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
|
||||
*/
|
||||
|
||||
if (meta_monitor_manager_is_transform_handled (monitor_manager,
|
||||
main_output->crtc,
|
||||
crtc_transform))
|
||||
crtc,
|
||||
crtc->transform))
|
||||
return META_MONITOR_TRANSFORM_NORMAL;
|
||||
else
|
||||
return crtc_transform;
|
||||
return crtc->transform;
|
||||
}
|
||||
|
||||
static MetaRendererView *
|
||||
@ -3389,6 +3398,22 @@ meta_renderer_native_finalize (GObject *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
|
||||
meta_renderer_native_init (MetaRendererNative *renderer_native)
|
||||
{
|
||||
@ -3407,6 +3432,7 @@ meta_renderer_native_class_init (MetaRendererNativeClass *klass)
|
||||
object_class->get_property = meta_renderer_native_get_property;
|
||||
object_class->set_property = meta_renderer_native_set_property;
|
||||
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_view = meta_renderer_native_create_view;
|
||||
|
@ -37,8 +37,7 @@
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <xkbcommon/xkbcommon-x11.h>
|
||||
|
||||
#include "meta-idle-monitor-xsync.h"
|
||||
#include "backends/meta-stage.h"
|
||||
#include "backends/meta-stage-private.h"
|
||||
#include "backends/x11/meta-clutter-backend-x11.h"
|
||||
#include "backends/x11/meta-renderer-x11.h"
|
||||
#include "meta/meta-cursor-tracker.h"
|
||||
@ -47,6 +46,7 @@
|
||||
#include "display-private.h"
|
||||
#include "compositor/compositor-private.h"
|
||||
#include "backends/meta-dnd-private.h"
|
||||
#include "backends/meta-idle-monitor-private.h"
|
||||
|
||||
struct _MetaBackendX11Private
|
||||
{
|
||||
@ -57,6 +57,8 @@ struct _MetaBackendX11Private
|
||||
|
||||
int xsync_event_base;
|
||||
int xsync_error_base;
|
||||
XSyncAlarm user_active_alarm;
|
||||
XSyncCounter counter;
|
||||
|
||||
int xinput_opcode;
|
||||
int xinput_event_base;
|
||||
@ -83,13 +85,77 @@ G_DEFINE_TYPE_WITH_CODE (MetaBackendX11, meta_backend_x11, META_TYPE_BACKEND,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
initable_iface_init));
|
||||
|
||||
|
||||
static void
|
||||
handle_alarm_notify (MetaBackend *backend,
|
||||
XEvent *event)
|
||||
uint64_to_xsync_value (uint64_t value,
|
||||
XSyncValue *xsync_value)
|
||||
{
|
||||
meta_backend_foreach_device_monitor (backend,
|
||||
(GFunc) meta_idle_monitor_xsync_handle_xevent,
|
||||
event);
|
||||
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
|
||||
handle_alarm_notify (MetaBackend *backend,
|
||||
XSyncAlarmNotifyEvent *alarm_event)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
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
|
||||
@ -275,7 +341,7 @@ handle_host_xevent (MetaBackend *backend,
|
||||
bypass_clutter);
|
||||
|
||||
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)
|
||||
{
|
||||
@ -423,6 +489,12 @@ meta_backend_x11_post_init (MetaBackend *backend)
|
||||
!XSyncInitialize (priv->xdisplay, &major, &minor))
|
||||
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,
|
||||
"XInputExtension",
|
||||
&priv->xinput_opcode,
|
||||
@ -464,15 +536,6 @@ meta_backend_x11_create_clutter_backend (MetaBackend *backend)
|
||||
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
|
||||
meta_backend_x11_grab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
@ -679,14 +742,30 @@ initable_iface_init (GInitableIface *initable_iface)
|
||||
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
|
||||
meta_backend_x11_class_init (MetaBackendX11Class *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->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->ungrab_device = meta_backend_x11_ungrab_device;
|
||||
backend_class->warp_pointer = meta_backend_x11_warp_pointer;
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
|
||||
#include "meta-backend-x11.h"
|
||||
#include "meta-stage.h"
|
||||
#include "meta-stage-private.h"
|
||||
|
||||
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++)
|
||||
{
|
||||
MetaOutput *output = ((MetaOutput**) crtc_info->outputs->pdata)[j];
|
||||
MetaCrtc *assigned_crtc;
|
||||
|
||||
if (output->crtc != crtc)
|
||||
assigned_crtc = meta_output_get_assigned_crtc (output);
|
||||
if (assigned_crtc != crtc)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -243,6 +245,7 @@ is_output_assignment_changed (MetaOutput *output,
|
||||
MetaOutputInfo **output_infos,
|
||||
unsigned int n_output_infos)
|
||||
{
|
||||
MetaCrtc *assigned_crtc;
|
||||
gboolean output_is_found = FALSE;
|
||||
unsigned int i;
|
||||
|
||||
@ -265,8 +268,10 @@ is_output_assignment_changed (MetaOutput *output,
|
||||
output_is_found = TRUE;
|
||||
}
|
||||
|
||||
assigned_crtc = meta_output_get_assigned_crtc (output);
|
||||
|
||||
if (!output_is_found)
|
||||
return output->crtc != NULL;
|
||||
return assigned_crtc != NULL;
|
||||
|
||||
for (i = 0; i < n_crtc_infos; i++)
|
||||
{
|
||||
@ -279,7 +284,7 @@ is_output_assignment_changed (MetaOutput *output,
|
||||
((MetaOutput**) crtc_info->outputs->pdata)[j];
|
||||
|
||||
if (crtc_info_output == output &&
|
||||
crtc_info->crtc == output->crtc)
|
||||
crtc_info->crtc == assigned_crtc)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -455,7 +460,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
meta_output_assign_crtc (output, crtc);
|
||||
|
||||
output_ids[j] = output->winsys_id;
|
||||
}
|
||||
@ -521,7 +526,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
continue;
|
||||
}
|
||||
|
||||
output->crtc = NULL;
|
||||
meta_output_unassign_crtc (output);
|
||||
output->is_primary = FALSE;
|
||||
}
|
||||
|
||||
|
@ -97,10 +97,13 @@ output_set_underscanning_xrandr (MetaOutput *output,
|
||||
* make the border configurable. */
|
||||
if (underscanning)
|
||||
{
|
||||
MetaCrtc *crtc;
|
||||
uint32_t border_value;
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
|
||||
prop = XInternAtom (xdisplay, "underscan hborder", False);
|
||||
border_value = output->crtc->current_mode->width * 0.05;
|
||||
border_value = crtc->current_mode->width * 0.05;
|
||||
|
||||
xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
|
||||
(XID) output->winsys_id,
|
||||
@ -109,7 +112,7 @@ output_set_underscanning_xrandr (MetaOutput *output,
|
||||
1, &border_value);
|
||||
|
||||
prop = XInternAtom (xdisplay, "underscan vborder", False);
|
||||
border_value = output->crtc->current_mode->height * 0.05;
|
||||
border_value = crtc->current_mode->height * 0.05;
|
||||
|
||||
xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
|
||||
(XID) output->winsys_id,
|
||||
@ -737,14 +740,14 @@ output_get_crtcs (MetaOutput *output,
|
||||
}
|
||||
output->n_possible_crtcs = n_actual_crtcs;
|
||||
|
||||
output->crtc = NULL;
|
||||
meta_output_unassign_crtc (output);
|
||||
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
|
||||
{
|
||||
MetaCrtc *crtc = l->data;
|
||||
|
||||
if ((XID) crtc->crtc_id == xrandr_output->crtc)
|
||||
{
|
||||
output->crtc = crtc;
|
||||
meta_output_assign_crtc (output, crtc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ draw_crtc (MetaMonitor *monitor,
|
||||
CoglTexture *texture = data->texture;
|
||||
MetaLogicalMonitor *logical_monitor = data->logical_monitor;
|
||||
MetaOutput *output = monitor_crtc_mode->output;
|
||||
MetaCrtc *crtc = output->crtc;
|
||||
MetaCrtc *crtc;
|
||||
MetaRendererView *renderer_view = META_RENDERER_VIEW (data->view);
|
||||
MetaMonitorTransform view_transform;
|
||||
MetaMonitorTransform layout_transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
@ -129,6 +129,8 @@ draw_crtc (MetaMonitor *monitor,
|
||||
texture_width = cogl_texture_get_width (texture);
|
||||
texture_height = cogl_texture_get_height (texture);
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
|
||||
clutter_stage_view_get_layout (data->view, &view_layout);
|
||||
sample_x = crtc->rect.x - view_layout.x;
|
||||
sample_y = crtc->rect.y - view_layout.y;
|
||||
|
@ -50,24 +50,22 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
|
||||
{
|
||||
MetaMonitor *main_monitor;
|
||||
MetaOutput *main_output;
|
||||
MetaMonitorTransform crtc_transform;
|
||||
MetaCrtc *crtc;
|
||||
|
||||
main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data;
|
||||
main_output = meta_monitor_get_main_output (main_monitor);
|
||||
crtc_transform =
|
||||
meta_monitor_logical_to_crtc_transform (main_monitor,
|
||||
logical_monitor->transform);
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (main_output);
|
||||
/*
|
||||
* Pick any monitor and output and check; all CRTCs of a logical monitor will
|
||||
* always have the same transform assigned to them.
|
||||
*/
|
||||
|
||||
if (meta_monitor_manager_is_transform_handled (monitor_manager,
|
||||
main_output->crtc,
|
||||
crtc_transform))
|
||||
crtc,
|
||||
crtc->transform))
|
||||
return META_MONITOR_TRANSFORM_NORMAL;
|
||||
else
|
||||
return crtc_transform;
|
||||
return crtc->transform;
|
||||
}
|
||||
|
||||
static MetaRendererView *
|
||||
|
@ -67,7 +67,7 @@
|
||||
#include <meta/meta-background-group.h>
|
||||
#include <meta/meta-shadow-factory.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 "display-private.h" /* for meta_display_lookup_x_window() and meta_display_cancel_touch() */
|
||||
#include "util-private.h"
|
||||
|
@ -58,5 +58,6 @@ void meta_window_actor_effect_completed (MetaWindowActor *actor,
|
||||
|
||||
MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self);
|
||||
void meta_window_actor_update_surface (MetaWindowActor *self);
|
||||
MetaWindowActor *meta_window_actor_from_window (MetaWindow *window);
|
||||
|
||||
#endif /* META_WINDOW_ACTOR_PRIVATE_H */
|
||||
|
@ -142,6 +142,8 @@ struct _FrameData
|
||||
enum
|
||||
{
|
||||
FIRST_FRAME,
|
||||
EFFECTS_COMPLETED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@ -238,6 +240,21 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* MetaWindowActor::effects-completed:
|
||||
* @actor: the #MetaWindowActor instance
|
||||
*
|
||||
* The ::effects-completed signal will be emitted once all pending compositor
|
||||
* effects are completed.
|
||||
*/
|
||||
signals[EFFECTS_COMPLETED] =
|
||||
g_signal_new ("effects-completed",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
pspec = g_param_spec_object ("meta-window",
|
||||
"MetaWindow",
|
||||
"The displayed MetaWindow",
|
||||
@ -1131,6 +1148,7 @@ meta_window_actor_after_effects (MetaWindowActor *self)
|
||||
return;
|
||||
}
|
||||
|
||||
g_signal_emit (self, signals[EFFECTS_COMPLETED], 0);
|
||||
meta_window_actor_sync_visibility (self);
|
||||
meta_window_actor_sync_actor_geometry (self, FALSE);
|
||||
}
|
||||
@ -2157,3 +2175,9 @@ meta_window_actor_sync_updates_frozen (MetaWindowActor *self)
|
||||
|
||||
meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (window));
|
||||
}
|
||||
|
||||
MetaWindowActor *
|
||||
meta_window_actor_from_window (MetaWindow *window)
|
||||
{
|
||||
return META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
}
|
||||
|
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 "compositor-private.h"
|
||||
#include "meta-window-actor-private.h"
|
||||
#include "meta-window-group.h"
|
||||
#include "meta-window-group-private.h"
|
||||
#include "window-private.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;
|
||||
gboolean constraint_already_satisfied;
|
||||
|
||||
if (!meta_window_is_attached_dialog (window) ||
|
||||
if (!parent ||
|
||||
!meta_window_is_attached_dialog (window) ||
|
||||
meta_window_get_placement_rule (window))
|
||||
return TRUE;
|
||||
|
||||
|
@ -53,7 +53,7 @@
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "backends/native/meta-backend-native.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 <clutter/x11/clutter-x11.h>
|
||||
|
||||
|
@ -32,9 +32,10 @@
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/native/meta-idle-monitor-native.h"
|
||||
#endif
|
||||
|
||||
#include "backends/meta-idle-monitor-private.h"
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#endif
|
||||
@ -92,46 +93,38 @@ get_window_for_event (MetaDisplay *display,
|
||||
static void
|
||||
handle_idletime_for_event (const ClutterEvent *event)
|
||||
{
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
/* This is handled by XSync under X11. */
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterInputDevice *device, *source_device;
|
||||
MetaIdleMonitor *core_monitor, *device_monitor;
|
||||
int device_id;
|
||||
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
device = clutter_event_get_device (event);
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
if (event->any.flags & CLUTTER_EVENT_FLAG_SYNTHETIC ||
|
||||
event->type == CLUTTER_ENTER ||
|
||||
event->type == CLUTTER_LEAVE ||
|
||||
event->type == CLUTTER_STAGE_STATE ||
|
||||
event->type == CLUTTER_DESTROY_NOTIFY ||
|
||||
event->type == CLUTTER_CLIENT_MESSAGE ||
|
||||
event->type == CLUTTER_DELETE)
|
||||
return;
|
||||
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
|
||||
core_monitor = meta_idle_monitor_get_core ();
|
||||
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
||||
|
||||
meta_idle_monitor_reset_idletime (core_monitor);
|
||||
meta_idle_monitor_reset_idletime (device_monitor);
|
||||
|
||||
source_device = clutter_event_get_source_device (event);
|
||||
if (source_device != device)
|
||||
{
|
||||
ClutterInputDevice *device, *source_device;
|
||||
MetaIdleMonitor *core_monitor, *device_monitor;
|
||||
int device_id;
|
||||
|
||||
device = clutter_event_get_device (event);
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
if (event->any.flags & CLUTTER_EVENT_FLAG_SYNTHETIC ||
|
||||
event->type == CLUTTER_ENTER ||
|
||||
event->type == CLUTTER_LEAVE ||
|
||||
event->type == CLUTTER_STAGE_STATE ||
|
||||
event->type == CLUTTER_DESTROY_NOTIFY ||
|
||||
event->type == CLUTTER_CLIENT_MESSAGE ||
|
||||
event->type == CLUTTER_DELETE)
|
||||
return;
|
||||
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
|
||||
core_monitor = meta_idle_monitor_get_core ();
|
||||
device_monitor = meta_idle_monitor_get_for_device (device_id);
|
||||
|
||||
meta_idle_monitor_native_reset_idletime (core_monitor);
|
||||
meta_idle_monitor_native_reset_idletime (device_monitor);
|
||||
|
||||
source_device = clutter_event_get_source_device (event);
|
||||
if (source_device != device)
|
||||
{
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
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
|
||||
|
@ -81,6 +81,7 @@ typedef enum
|
||||
META_MOVE_RESIZE_STATE_CHANGED = 1 << 5,
|
||||
META_MOVE_RESIZE_UNMAXIMIZE = 1 << 6,
|
||||
META_MOVE_RESIZE_FORCE_MOVE = 1 << 7,
|
||||
META_MOVE_RESIZE_WAYLAND_STATE_CHANGED = 1 << 8,
|
||||
} MetaMoveResizeFlags;
|
||||
|
||||
typedef enum
|
||||
@ -88,6 +89,7 @@ typedef enum
|
||||
META_MOVE_RESIZE_RESULT_MOVED = 1 << 0,
|
||||
META_MOVE_RESIZE_RESULT_RESIZED = 1 << 1,
|
||||
META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED = 1 << 2,
|
||||
META_MOVE_RESIZE_RESULT_STATE_CHANGED = 1 << 3,
|
||||
} MetaMoveResizeResultFlags;
|
||||
|
||||
typedef enum
|
||||
|
@ -3997,7 +3997,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
|
||||
if ((moved_or_resized ||
|
||||
did_placement ||
|
||||
(flags & META_MOVE_RESIZE_STATE_CHANGED) != 0) &&
|
||||
(result & META_MOVE_RESIZE_RESULT_STATE_CHANGED) != 0) &&
|
||||
window->known_to_compositor)
|
||||
{
|
||||
meta_compositor_sync_window_geometry (window->display->compositor,
|
||||
@ -5268,7 +5268,7 @@ static cairo_surface_t *
|
||||
load_default_window_icon (int size)
|
||||
{
|
||||
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
||||
GdkPixbuf *pixbuf;
|
||||
g_autoptr (GdkPixbuf) pixbuf = NULL;
|
||||
const char *icon_name;
|
||||
|
||||
if (gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME))
|
||||
|
@ -54,4 +54,7 @@ MetaMonitorSwitchConfigType meta_monitor_manager_get_switch_config (MetaMonitorM
|
||||
|
||||
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 */
|
||||
|
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" />
|
||||
</method>
|
||||
|
||||
<method name="ResetIdletime"/>
|
||||
|
||||
<signal name="WatchFired">
|
||||
<arg name="id" direction="out" type="u" />
|
||||
</signal>
|
||||
|
@ -209,7 +209,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
meta_output_assign_crtc (output, crtc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -255,7 +255,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
|
||||
continue;
|
||||
}
|
||||
|
||||
output->crtc = NULL;
|
||||
meta_output_unassign_crtc (output);
|
||||
output->is_primary = FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -449,22 +449,24 @@ check_current_monitor_mode (MetaMonitor *monitor,
|
||||
CheckMonitorModeData *data = user_data;
|
||||
MetaMonitorManager *monitor_manager = data->monitor_manager;
|
||||
MetaOutput *output;
|
||||
MetaCrtc *crtc;
|
||||
|
||||
output = output_from_winsys_id (monitor_manager,
|
||||
data->expect_crtc_mode_iter->output);
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
|
||||
if (data->expect_crtc_mode_iter->crtc_mode == -1)
|
||||
{
|
||||
g_assert_null (output->crtc);
|
||||
g_assert_null (crtc);
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaLogicalMonitor *logical_monitor;
|
||||
|
||||
g_assert_nonnull (output->crtc);
|
||||
g_assert (monitor_crtc_mode->crtc_mode == output->crtc->current_mode);
|
||||
g_assert_nonnull (crtc);
|
||||
g_assert (monitor_crtc_mode->crtc_mode == crtc->current_mode);
|
||||
|
||||
logical_monitor = output->crtc->logical_monitor;
|
||||
logical_monitor = crtc->logical_monitor;
|
||||
g_assert_nonnull (logical_monitor);
|
||||
}
|
||||
|
||||
@ -553,6 +555,7 @@ check_logical_monitor (MonitorTestCase *test_case,
|
||||
for (l_output = outputs; l_output; l_output = l_output->next)
|
||||
{
|
||||
MetaOutput *output = l_output->data;
|
||||
MetaCrtc *crtc;
|
||||
|
||||
if (output->is_primary)
|
||||
{
|
||||
@ -560,8 +563,8 @@ check_logical_monitor (MonitorTestCase *test_case,
|
||||
primary_output = output;
|
||||
}
|
||||
|
||||
g_assert (!output->crtc ||
|
||||
output->crtc->logical_monitor == logical_monitor);
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
g_assert (!crtc || crtc->logical_monitor == logical_monitor);
|
||||
g_assert_cmpint (logical_monitor->is_presentation,
|
||||
==,
|
||||
output->is_presentation);
|
||||
@ -983,7 +986,8 @@ create_monitor_test_setup (MonitorTestCase *test_case,
|
||||
|
||||
output = g_object_new (META_TYPE_OUTPUT, NULL);
|
||||
|
||||
output->crtc = crtc;
|
||||
if (crtc)
|
||||
meta_output_assign_crtc (output, crtc);
|
||||
output->winsys_id = i;
|
||||
output->name = (is_laptop_panel ? g_strdup_printf ("eDP-%d",
|
||||
++n_laptop_panels)
|
||||
|
283
src/ui/frames.c
283
src/ui/frames.c
@ -71,6 +71,14 @@ static MetaFrameControl get_control (MetaUIFrame *frame,
|
||||
|
||||
G_DEFINE_TYPE (MetaFrames, meta_frames, GTK_TYPE_WINDOW);
|
||||
|
||||
enum {
|
||||
META_ACTION_CLICK,
|
||||
META_ACTION_RIGHT_CLICK,
|
||||
META_ACTION_MIDDLE_CLICK,
|
||||
META_ACTION_DOUBLE_CLICK,
|
||||
META_ACTION_IGNORE
|
||||
};
|
||||
|
||||
static GObject *
|
||||
meta_frames_constructor (GType gtype,
|
||||
guint n_properties,
|
||||
@ -742,17 +750,25 @@ redraw_control (MetaUIFrame *frame,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_frame_titlebar_event (MetaUIFrame *frame,
|
||||
ClutterButtonEvent *event,
|
||||
int action)
|
||||
meta_frame_titlebar_event (MetaUIFrame *frame,
|
||||
const ClutterEvent *event,
|
||||
int action)
|
||||
{
|
||||
MetaFrameFlags flags;
|
||||
Display *display;
|
||||
uint32_t evtime;
|
||||
float x, y;
|
||||
|
||||
g_assert (event->type == CLUTTER_BUTTON_PRESS ||
|
||||
event->type == CLUTTER_TOUCH_BEGIN);
|
||||
|
||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
|
||||
flags = meta_frame_get_flags (frame->meta_window->frame);
|
||||
|
||||
evtime = clutter_event_get_time (event);
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_SHADE:
|
||||
@ -760,9 +776,9 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
|
||||
if (flags & META_FRAME_ALLOWS_SHADE)
|
||||
{
|
||||
if (flags & META_FRAME_SHADED)
|
||||
meta_window_unshade (frame->meta_window, event->time);
|
||||
meta_window_unshade (frame->meta_window, evtime);
|
||||
else
|
||||
meta_window_shade (frame->meta_window, event->time);
|
||||
meta_window_shade (frame->meta_window, evtime);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -808,16 +824,14 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
|
||||
case G_DESKTOP_TITLEBAR_ACTION_LOWER:
|
||||
meta_core_user_lower_and_unfocus (display,
|
||||
frame->xwindow,
|
||||
event->time);
|
||||
evtime);
|
||||
break;
|
||||
|
||||
case G_DESKTOP_TITLEBAR_ACTION_MENU:
|
||||
meta_core_show_window_menu (display,
|
||||
frame->xwindow,
|
||||
META_WINDOW_MENU_WM,
|
||||
event->x,
|
||||
event->y,
|
||||
event->time);
|
||||
x, y, evtime);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -825,8 +839,8 @@ meta_frame_titlebar_event (MetaUIFrame *frame,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_frame_double_click_event (MetaUIFrame *frame,
|
||||
ClutterButtonEvent *event)
|
||||
meta_frame_double_click_event (MetaUIFrame *frame,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
int action = meta_prefs_get_action_double_click_titlebar ();
|
||||
|
||||
@ -839,7 +853,8 @@ meta_frame_middle_click_event (MetaUIFrame *frame,
|
||||
{
|
||||
int action = meta_prefs_get_action_middle_click_titlebar();
|
||||
|
||||
return meta_frame_titlebar_event (frame, event, action);
|
||||
return meta_frame_titlebar_event (frame, (const ClutterEvent *) event,
|
||||
action);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -848,7 +863,8 @@ meta_frame_right_click_event (MetaUIFrame *frame,
|
||||
{
|
||||
int action = meta_prefs_get_action_right_click_titlebar();
|
||||
|
||||
return meta_frame_titlebar_event (frame, event, action);
|
||||
return meta_frame_titlebar_event (frame, (const ClutterEvent *) event,
|
||||
action);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -879,6 +895,8 @@ meta_frames_try_grab_op (MetaUIFrame *frame,
|
||||
frames->grab_x = grab_x;
|
||||
frames->grab_y = grab_y;
|
||||
}
|
||||
else
|
||||
frames->grab_touch = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -889,6 +907,7 @@ meta_frames_retry_grab_op (MetaFrames *frames,
|
||||
{
|
||||
Display *display;
|
||||
MetaGrabOp op;
|
||||
gboolean ret;
|
||||
|
||||
if (frames->current_grab_op == META_GRAB_OP_NONE)
|
||||
return TRUE;
|
||||
@ -897,16 +916,20 @@ meta_frames_retry_grab_op (MetaFrames *frames,
|
||||
frames->current_grab_op = META_GRAB_OP_NONE;
|
||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
|
||||
return meta_core_begin_grab_op (display,
|
||||
frames->grab_frame->xwindow,
|
||||
op,
|
||||
FALSE,
|
||||
TRUE,
|
||||
frames->grab_frame->grab_button,
|
||||
0,
|
||||
time,
|
||||
frames->grab_x,
|
||||
frames->grab_y);
|
||||
ret = meta_core_begin_grab_op (display,
|
||||
frames->grab_frame->xwindow,
|
||||
op,
|
||||
FALSE,
|
||||
TRUE,
|
||||
frames->grab_frame->grab_button,
|
||||
0,
|
||||
time,
|
||||
frames->grab_x,
|
||||
frames->grab_y);
|
||||
if (ret)
|
||||
frames->grab_touch = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static MetaGrabOp
|
||||
@ -935,12 +958,65 @@ grab_op_from_resize_control (MetaFrameControl control)
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
get_action (const ClutterEvent *event)
|
||||
{
|
||||
if (event->type == CLUTTER_BUTTON_PRESS ||
|
||||
event->type == CLUTTER_BUTTON_RELEASE)
|
||||
{
|
||||
switch (event->button.button)
|
||||
{
|
||||
case CLUTTER_BUTTON_PRIMARY:
|
||||
if (clutter_event_get_click_count (event) == 2)
|
||||
return META_ACTION_DOUBLE_CLICK;
|
||||
else
|
||||
return META_ACTION_CLICK;
|
||||
case CLUTTER_BUTTON_SECONDARY:
|
||||
return META_ACTION_RIGHT_CLICK;
|
||||
case CLUTTER_BUTTON_MIDDLE:
|
||||
return META_ACTION_MIDDLE_CLICK;
|
||||
default:
|
||||
meta_verbose ("No action triggered for button %u %s\n",
|
||||
event->button.button,
|
||||
(event->type == CLUTTER_BUTTON_PRESS) ? "press" : "release");
|
||||
}
|
||||
}
|
||||
else if (event->type == CLUTTER_TOUCH_BEGIN ||
|
||||
event->type == CLUTTER_TOUCH_UPDATE ||
|
||||
event->type == CLUTTER_TOUCH_END)
|
||||
{
|
||||
return META_ACTION_CLICK;
|
||||
}
|
||||
|
||||
return META_ACTION_IGNORE;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_button_number (const ClutterEvent *event)
|
||||
{
|
||||
if (event->type == CLUTTER_TOUCH_BEGIN ||
|
||||
event->type == CLUTTER_TOUCH_UPDATE ||
|
||||
event->type == CLUTTER_TOUCH_END)
|
||||
return -1;
|
||||
else if (event->type == CLUTTER_BUTTON_PRESS ||
|
||||
event->type == CLUTTER_BUTTON_RELEASE)
|
||||
return clutter_event_get_button (event);
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_frame_left_click_event (MetaUIFrame *frame,
|
||||
ClutterButtonEvent *event)
|
||||
meta_frame_left_click_event (MetaUIFrame *frame,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
MetaFrameControl control = get_control (frame, event->x, event->y);
|
||||
MetaFrameControl control;
|
||||
guint32 evtime;
|
||||
gfloat x, y;
|
||||
|
||||
evtime = clutter_event_get_time (event);
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
control = get_control (frame, x, y);
|
||||
|
||||
switch (control)
|
||||
{
|
||||
@ -950,7 +1026,7 @@ meta_frame_left_click_event (MetaUIFrame *frame,
|
||||
case META_FRAME_CONTROL_DELETE:
|
||||
case META_FRAME_CONTROL_MENU:
|
||||
case META_FRAME_CONTROL_APPMENU:
|
||||
frame->grab_button = event->button;
|
||||
frame->grab_button = get_button_number (event);
|
||||
frame->button_state = META_BUTTON_STATE_PRESSED;
|
||||
frame->prelit_control = control;
|
||||
redraw_control (frame, control);
|
||||
@ -987,13 +1063,12 @@ meta_frame_left_click_event (MetaUIFrame *frame,
|
||||
frame->xwindow,
|
||||
menu,
|
||||
&root_rect,
|
||||
event->time);
|
||||
evtime);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_frames_try_grab_op (frame, META_GRAB_OP_FRAME_BUTTON,
|
||||
event->x, event->y,
|
||||
event->time);
|
||||
x, y, evtime);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -1007,8 +1082,7 @@ meta_frame_left_click_event (MetaUIFrame *frame,
|
||||
case META_FRAME_CONTROL_RESIZE_W:
|
||||
meta_frames_try_grab_op (frame,
|
||||
grab_op_from_resize_control (control),
|
||||
event->x, event->y,
|
||||
event->time);
|
||||
x, y, evtime);
|
||||
|
||||
return TRUE;
|
||||
case META_FRAME_CONTROL_TITLE:
|
||||
@ -1019,8 +1093,7 @@ meta_frame_left_click_event (MetaUIFrame *frame,
|
||||
{
|
||||
meta_frames_try_grab_op (frame,
|
||||
META_GRAB_OP_MOVING,
|
||||
event->x, event->y,
|
||||
event->time);
|
||||
x, y, evtime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1036,21 +1109,31 @@ meta_frame_left_click_event (MetaUIFrame *frame,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_button_press_event (MetaUIFrame *frame,
|
||||
ClutterButtonEvent *event)
|
||||
handle_press_event (MetaUIFrame *frame,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaFrameControl control;
|
||||
Display *display;
|
||||
uint32_t evtime, action;
|
||||
float x, y;
|
||||
|
||||
g_assert (event->type == CLUTTER_BUTTON_PRESS ||
|
||||
event->type == CLUTTER_TOUCH_BEGIN);
|
||||
|
||||
action = get_action (event);
|
||||
if (action == META_ACTION_IGNORE)
|
||||
return FALSE;
|
||||
|
||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
|
||||
control = get_control (frame, event->x, event->y);
|
||||
|
||||
evtime = clutter_event_get_time (event);
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
control = get_control (frame, x, y);
|
||||
/* don't do the rest of this if on client area */
|
||||
if (control == META_FRAME_CONTROL_CLIENT_AREA)
|
||||
return FALSE; /* not on the frame, just passed through from client */
|
||||
|
||||
if (event->button == 1 &&
|
||||
if (action == META_ACTION_CLICK &&
|
||||
!(control == META_FRAME_CONTROL_MINIMIZE ||
|
||||
control == META_FRAME_CONTROL_DELETE ||
|
||||
control == META_FRAME_CONTROL_MAXIMIZE))
|
||||
@ -1058,52 +1141,60 @@ handle_button_press_event (MetaUIFrame *frame,
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Focusing window with frame 0x%lx due to button 1 press\n",
|
||||
frame->xwindow);
|
||||
meta_window_focus (frame->meta_window, event->time);
|
||||
meta_window_focus (frame->meta_window, evtime);
|
||||
}
|
||||
|
||||
/* We want to shade even if we have a GrabOp, since we'll have a move grab
|
||||
* if we double click the titlebar.
|
||||
*/
|
||||
if (control == META_FRAME_CONTROL_TITLE &&
|
||||
event->button == 1 &&
|
||||
event->click_count == 2)
|
||||
action == META_ACTION_DOUBLE_CLICK)
|
||||
{
|
||||
meta_core_end_grab_op (display, event->time);
|
||||
meta_core_end_grab_op (display, evtime);
|
||||
return meta_frame_double_click_event (frame, event);
|
||||
}
|
||||
|
||||
if (meta_core_get_grab_op (display) != META_GRAB_OP_NONE)
|
||||
return FALSE; /* already up to something */
|
||||
|
||||
frame->grab_button = event->button;
|
||||
frame->grab_button = get_button_number (event);
|
||||
|
||||
switch (event->button)
|
||||
switch (action)
|
||||
{
|
||||
case 1:
|
||||
case META_ACTION_CLICK:
|
||||
return meta_frame_left_click_event (frame, event);
|
||||
case 2:
|
||||
return meta_frame_middle_click_event (frame, event);
|
||||
case 3:
|
||||
return meta_frame_right_click_event (frame, event);
|
||||
case META_ACTION_MIDDLE_CLICK:
|
||||
return meta_frame_middle_click_event (frame, (ClutterButtonEvent *) event);
|
||||
case META_ACTION_RIGHT_CLICK:
|
||||
return meta_frame_right_click_event (frame, (ClutterButtonEvent *) event);
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_button_release_event (MetaUIFrame *frame,
|
||||
ClutterButtonEvent *event)
|
||||
handle_release_event (MetaUIFrame *frame,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
guint32 evtime, button;
|
||||
gfloat x, y;
|
||||
|
||||
g_assert (event->type == CLUTTER_BUTTON_RELEASE ||
|
||||
event->type == CLUTTER_TOUCH_END);
|
||||
|
||||
evtime = clutter_event_get_time (event);
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
button = get_button_number (event);
|
||||
|
||||
frame->frames->current_grab_op = META_GRAB_OP_NONE;
|
||||
meta_core_end_grab_op (display, event->time);
|
||||
meta_core_end_grab_op (display, evtime);
|
||||
|
||||
/* We only handle the releases we handled the presses for (things
|
||||
* involving frame controls). Window ops that don't require a
|
||||
* frame are handled in the Xlib part of the code, display.c/window.c
|
||||
*/
|
||||
if (((int) event->button) == frame->grab_button &&
|
||||
if (((int) button) == frame->grab_button &&
|
||||
frame->button_state == META_BUTTON_STATE_PRESSED)
|
||||
{
|
||||
switch (frame->prelit_control)
|
||||
@ -1113,7 +1204,7 @@ handle_button_release_event (MetaUIFrame *frame,
|
||||
break;
|
||||
case META_FRAME_CONTROL_MAXIMIZE:
|
||||
/* Focus the window on the maximize */
|
||||
meta_window_focus (frame->meta_window, event->time);
|
||||
meta_window_focus (frame->meta_window, evtime);
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (frame->meta_window);
|
||||
meta_window_maximize (frame->meta_window, META_MAXIMIZE_BOTH);
|
||||
@ -1124,7 +1215,7 @@ handle_button_release_event (MetaUIFrame *frame,
|
||||
meta_window_unmaximize (frame->meta_window, META_MAXIMIZE_BOTH);
|
||||
break;
|
||||
case META_FRAME_CONTROL_DELETE:
|
||||
meta_window_delete (frame->meta_window, event->time);
|
||||
meta_window_delete (frame->meta_window, evtime);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1135,7 +1226,7 @@ handle_button_release_event (MetaUIFrame *frame,
|
||||
* prelit so to let the user know that it can now be pressed.
|
||||
* :)
|
||||
*/
|
||||
MetaFrameControl control = get_control (frame, event->x, event->y);
|
||||
MetaFrameControl control = get_control (frame, x, y);
|
||||
meta_ui_frame_update_prelit_control (frame, control);
|
||||
}
|
||||
|
||||
@ -1236,13 +1327,22 @@ meta_ui_frame_update_prelit_control (MetaUIFrame *frame,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_motion_notify_event (MetaUIFrame *frame,
|
||||
ClutterMotionEvent *event)
|
||||
handle_motion_event (MetaUIFrame *frame,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaFrames *frames = frame->frames;
|
||||
MetaFrameControl control;
|
||||
ClutterModifierType modifiers;
|
||||
guint32 evtime;
|
||||
gfloat x, y;
|
||||
|
||||
control = get_control (frame, event->x, event->y);
|
||||
g_assert (event->type == CLUTTER_MOTION ||
|
||||
event->type == CLUTTER_TOUCH_UPDATE);
|
||||
|
||||
modifiers = clutter_event_get_state (event);
|
||||
evtime = clutter_event_get_time (event);
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
control = get_control (frame, x, y);
|
||||
|
||||
if (frame->button_state == META_BUTTON_STATE_PRESSED)
|
||||
{
|
||||
@ -1260,9 +1360,11 @@ handle_motion_notify_event (MetaUIFrame *frame,
|
||||
meta_ui_frame_update_prelit_control (frame, control);
|
||||
}
|
||||
|
||||
if ((event->modifier_state & CLUTTER_BUTTON1_MASK) &&
|
||||
frames->current_grab_op != META_GRAB_OP_NONE)
|
||||
meta_frames_retry_grab_op (frames, event->time);
|
||||
if (frames->current_grab_op != META_GRAB_OP_NONE &&
|
||||
(event->type == CLUTTER_TOUCH_UPDATE ||
|
||||
(event->type == CLUTTER_MOTION &&
|
||||
(modifiers & CLUTTER_BUTTON1_MASK))))
|
||||
meta_frames_retry_grab_op (frames, evtime);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1330,7 +1432,9 @@ meta_ui_frame_get_mask (MetaUIFrame *frame,
|
||||
MetaFrameBorders borders;
|
||||
MetaFrameFlags flags;
|
||||
MetaRectangle frame_rect;
|
||||
int scale = meta_theme_get_window_scaling_factor ();
|
||||
cairo_surface_t *surface;
|
||||
double xscale, yscale;
|
||||
int scale;
|
||||
|
||||
meta_window_get_frame_rect (frame->meta_window, &frame_rect);
|
||||
|
||||
@ -1340,7 +1444,11 @@ meta_ui_frame_get_mask (MetaUIFrame *frame,
|
||||
meta_ui_frame_get_borders (frame, &borders);
|
||||
|
||||
/* See comment in meta_frame_layout_draw_with_style() for details on HiDPI handling */
|
||||
cairo_scale (cr, scale, scale);
|
||||
scale = meta_theme_get_window_scaling_factor ();
|
||||
surface = cairo_get_target (cr);
|
||||
cairo_surface_get_device_scale (surface, &xscale, &yscale);
|
||||
cairo_surface_set_device_scale (surface, scale, scale);
|
||||
|
||||
gtk_render_background (frame->style_info->styles[META_STYLE_ELEMENT_FRAME], cr,
|
||||
borders.invisible.left / scale,
|
||||
borders.invisible.top / scale,
|
||||
@ -1349,6 +1457,8 @@ meta_ui_frame_get_mask (MetaUIFrame *frame,
|
||||
borders.invisible.left / scale,
|
||||
borders.invisible.top / scale,
|
||||
frame_rect.width / scale, borders.total.top / scale);
|
||||
|
||||
cairo_surface_set_device_scale (surface, xscale, yscale);
|
||||
}
|
||||
|
||||
/* XXX -- this is disgusting. Find a better approach here.
|
||||
@ -1508,14 +1618,51 @@ gboolean
|
||||
meta_ui_frame_handle_event (MetaUIFrame *frame,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
if (event->type == CLUTTER_TOUCH_BEGIN ||
|
||||
event->type == CLUTTER_TOUCH_UPDATE ||
|
||||
event->type == CLUTTER_TOUCH_END)
|
||||
{
|
||||
ClutterEventSequence *sequence;
|
||||
MetaFrames *frames = frame->frames;
|
||||
|
||||
/* In X11, mutter sets up passive touch grabs which basically
|
||||
* means we handle those events twice (once through the passive
|
||||
* grab, and then through XISelectEvents).
|
||||
*
|
||||
* Receiving touch events here means we are going through the
|
||||
* former, but passive grabs are exclusively for gesture
|
||||
* recognition purposes.
|
||||
*
|
||||
* We do actually want this to happen though the regular event
|
||||
* selection paths to avoid breaking internal state, which means
|
||||
* we will get pointer events, because we don't select for XI_Touch*.
|
||||
*/
|
||||
if (!meta_is_wayland_compositor ())
|
||||
return FALSE;
|
||||
|
||||
sequence = clutter_event_get_event_sequence (event);
|
||||
|
||||
/* Lock onto a single touch */
|
||||
if (frames->grab_touch && frames->grab_touch != sequence)
|
||||
return FALSE;
|
||||
|
||||
if (event->type == CLUTTER_TOUCH_BEGIN)
|
||||
frames->grab_touch = sequence;
|
||||
else if (event->type == CLUTTER_TOUCH_END)
|
||||
frames->grab_touch = NULL;
|
||||
}
|
||||
|
||||
switch (event->any.type)
|
||||
{
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
return handle_button_press_event (frame, (ClutterButtonEvent *) event);
|
||||
case CLUTTER_TOUCH_BEGIN:
|
||||
return handle_press_event (frame, event);
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
return handle_button_release_event (frame, (ClutterButtonEvent *) event);
|
||||
case CLUTTER_TOUCH_END:
|
||||
return handle_release_event (frame, event);
|
||||
case CLUTTER_MOTION:
|
||||
return handle_motion_notify_event (frame, (ClutterMotionEvent *) event);
|
||||
case CLUTTER_TOUCH_UPDATE:
|
||||
return handle_motion_event (frame, event);
|
||||
case CLUTTER_ENTER:
|
||||
return handle_enter_notify_event (frame, (ClutterCrossingEvent *) event);
|
||||
case CLUTTER_LEAVE:
|
||||
|
@ -99,6 +99,8 @@ struct _MetaFrames
|
||||
guint grab_button;
|
||||
gdouble grab_x;
|
||||
gdouble grab_y;
|
||||
|
||||
ClutterEventSequence *grab_touch;
|
||||
};
|
||||
|
||||
struct _MetaFramesClass
|
||||
|
@ -580,7 +580,7 @@ meta_frame_layout_calc_geometry (MetaFrameLayout *layout,
|
||||
x = rect->visible.x - layout->button_margin.left * scale;
|
||||
|
||||
if (i > 0)
|
||||
x -= layout->titlebar_spacing;
|
||||
x -= layout->titlebar_spacing * scale;
|
||||
|
||||
--i;
|
||||
}
|
||||
@ -712,6 +712,8 @@ get_class_from_button_type (MetaButtonType type)
|
||||
return "maximize";
|
||||
case META_BUTTON_TYPE_MINIMIZE:
|
||||
return "minimize";
|
||||
case META_BUTTON_TYPE_APPMENU:
|
||||
return "appmenu";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@ -734,7 +736,9 @@ meta_frame_layout_draw_with_style (MetaFrameLayout *layout,
|
||||
GdkRectangle titlebar_rect;
|
||||
GdkRectangle button_rect;
|
||||
const MetaFrameBorders *borders;
|
||||
int scale = meta_theme_get_window_scaling_factor ();
|
||||
cairo_surface_t *frame_surface;
|
||||
double xscale, yscale;
|
||||
int scale;
|
||||
|
||||
/* We opt out of GTK+/Clutter's HiDPI handling, so we have to do the scaling
|
||||
* ourselves; the nitty-gritty is a bit confusing, so here is an overview:
|
||||
@ -746,8 +750,14 @@ meta_frame_layout_draw_with_style (MetaFrameLayout *layout,
|
||||
* - for drawing, we scale the canvas to have GTK+ render elements (borders,
|
||||
* radii, ...) at the correct scale - as a result, we have to "unscale"
|
||||
* the geometry again to not apply the scaling twice
|
||||
* - As per commit e36b629c GTK expects the device scale to be set and match
|
||||
* the final scaling or the surface caching won't take this in account
|
||||
* breaking -gtk-scaled items.
|
||||
*/
|
||||
cairo_scale (cr, scale, scale);
|
||||
scale = meta_theme_get_window_scaling_factor ();
|
||||
frame_surface = cairo_get_target (cr);
|
||||
cairo_surface_get_device_scale (frame_surface, &xscale, &yscale);
|
||||
cairo_surface_set_device_scale (frame_surface, scale, scale);
|
||||
|
||||
borders = &fgeom->borders;
|
||||
|
||||
@ -903,6 +913,8 @@ meta_frame_layout_draw_with_style (MetaFrameLayout *layout,
|
||||
gtk_style_context_remove_class (style, button_class);
|
||||
gtk_style_context_set_state (style, state);
|
||||
}
|
||||
|
||||
cairo_surface_set_device_scale (frame_surface, xscale, yscale);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -600,6 +600,10 @@ meta_wayland_zxdg_toplevel_v6_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *window = surface->window;
|
||||
MetaRectangle window_geometry;
|
||||
MetaRectangle old_geometry;
|
||||
gboolean geometry_changed;
|
||||
|
||||
old_geometry = xdg_surface_priv->geometry;
|
||||
|
||||
surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class);
|
||||
@ -618,7 +622,9 @@ meta_wayland_zxdg_toplevel_v6_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
if (pending->has_new_geometry)
|
||||
geometry_changed = !meta_rectangle_equal (&old_geometry, &xdg_surface_priv->geometry);
|
||||
|
||||
if (geometry_changed || meta_window_wayland_needs_move_resize (window))
|
||||
{
|
||||
window_geometry =
|
||||
meta_wayland_zxdg_surface_v6_get_window_geometry (xdg_surface);
|
||||
|
@ -325,7 +325,8 @@ void
|
||||
meta_wayland_seat_update (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
if (!event_from_supported_hardware_device (seat, event) &&
|
||||
if (!(clutter_event_get_flags (event) & CLUTTER_EVENT_FLAG_INPUT_METHOD) &&
|
||||
!event_from_supported_hardware_device (seat, event) &&
|
||||
!event_is_synthesized_crossing (event))
|
||||
return;
|
||||
|
||||
@ -363,7 +364,8 @@ gboolean
|
||||
meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
if (!event_from_supported_hardware_device (seat, event))
|
||||
if (!(clutter_event_get_flags (event) & CLUTTER_EVENT_FLAG_INPUT_METHOD) &&
|
||||
!event_from_supported_hardware_device (seat, event))
|
||||
return FALSE;
|
||||
|
||||
switch (event->type)
|
||||
|
@ -195,14 +195,15 @@ cursor_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *role,
|
||||
META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
|
||||
MetaWaylandSurfaceRoleCursorPrivate *priv =
|
||||
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
|
||||
ClutterRect rect;
|
||||
ClutterPoint point;
|
||||
ClutterRect logical_monitor_rect;
|
||||
|
||||
rect = meta_cursor_renderer_calculate_rect (priv->cursor_renderer,
|
||||
priv->cursor_sprite);
|
||||
logical_monitor_rect =
|
||||
meta_rectangle_to_clutter_rect (&logical_monitor->rect);
|
||||
return clutter_rect_intersection (&rect, &logical_monitor_rect, NULL);
|
||||
|
||||
point = meta_cursor_renderer_get_position (priv->cursor_renderer);
|
||||
|
||||
return clutter_rect_contains_point (&logical_monitor_rect, &point);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -54,6 +54,7 @@
|
||||
|
||||
#include "compositor/region-utils.h"
|
||||
#include "compositor/meta-shaped-texture-private.h"
|
||||
#include "compositor/meta-window-actor-private.h"
|
||||
|
||||
#include "meta-surface-actor.h"
|
||||
#include "meta-surface-actor-wayland.h"
|
||||
@ -142,6 +143,9 @@ surface_actor_position_notify (MetaSurfaceActorWayland *surface_actor,
|
||||
static void
|
||||
window_position_changed (MetaWindow *window,
|
||||
MetaWaylandSurface *surface);
|
||||
static void
|
||||
window_actor_effects_completed (MetaWindowActor *window_actor,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
static void
|
||||
role_assignment_valist_to_properties (GType role_type,
|
||||
@ -392,6 +396,7 @@ pending_state_init (MetaWaylandPendingState *state)
|
||||
{
|
||||
state->newly_attached = FALSE;
|
||||
state->buffer = NULL;
|
||||
state->buffer_destroy_handler_id = 0;
|
||||
state->dx = 0;
|
||||
state->dy = 0;
|
||||
state->scale = 0;
|
||||
@ -421,8 +426,11 @@ pending_state_destroy (MetaWaylandPendingState *state)
|
||||
g_clear_pointer (&state->opaque_region, cairo_region_destroy);
|
||||
|
||||
if (state->buffer)
|
||||
g_signal_handler_disconnect (state->buffer,
|
||||
state->buffer_destroy_handler_id);
|
||||
{
|
||||
g_signal_handler_disconnect (state->buffer,
|
||||
state->buffer_destroy_handler_id);
|
||||
state->buffer_destroy_handler_id = 0;
|
||||
}
|
||||
wl_list_for_each_safe (cb, next, &state->frame_callback_list, link)
|
||||
wl_resource_destroy (cb->resource);
|
||||
}
|
||||
@ -435,36 +443,84 @@ pending_state_reset (MetaWaylandPendingState *state)
|
||||
}
|
||||
|
||||
static void
|
||||
move_pending_state (MetaWaylandPendingState *from,
|
||||
MetaWaylandPendingState *to)
|
||||
merge_pending_state (MetaWaylandPendingState *from,
|
||||
MetaWaylandPendingState *to)
|
||||
{
|
||||
if (from->buffer)
|
||||
g_signal_handler_disconnect (from->buffer, from->buffer_destroy_handler_id);
|
||||
if (from->newly_attached)
|
||||
{
|
||||
if (to->buffer)
|
||||
{
|
||||
g_signal_handler_disconnect (to->buffer,
|
||||
to->buffer_destroy_handler_id);
|
||||
to->buffer_destroy_handler_id = 0;
|
||||
}
|
||||
|
||||
to->newly_attached = from->newly_attached;
|
||||
to->buffer = from->buffer;
|
||||
to->dx = from->dx;
|
||||
to->dy = from->dy;
|
||||
to->scale = from->scale;
|
||||
to->surface_damage = from->surface_damage;
|
||||
to->buffer_damage = from->buffer_damage;
|
||||
to->input_region = from->input_region;
|
||||
to->input_region_set = from->input_region_set;
|
||||
to->opaque_region = from->opaque_region;
|
||||
to->opaque_region_set = from->opaque_region_set;
|
||||
to->new_geometry = from->new_geometry;
|
||||
to->has_new_geometry = from->has_new_geometry;
|
||||
to->has_new_min_size = from->has_new_min_size;
|
||||
to->new_min_width = from->new_min_width;
|
||||
to->new_min_height = from->new_min_height;
|
||||
to->has_new_max_size = from->has_new_max_size;
|
||||
to->new_max_width = from->new_max_width;
|
||||
to->new_max_height = from->new_max_height;
|
||||
if (from->buffer)
|
||||
{
|
||||
g_signal_handler_disconnect (from->buffer,
|
||||
from->buffer_destroy_handler_id);
|
||||
from->buffer_destroy_handler_id = 0;
|
||||
}
|
||||
|
||||
to->newly_attached = TRUE;
|
||||
to->buffer = from->buffer;
|
||||
to->dx = from->dx;
|
||||
to->dy = from->dy;
|
||||
}
|
||||
|
||||
wl_list_init (&to->frame_callback_list);
|
||||
wl_list_insert_list (&to->frame_callback_list, &from->frame_callback_list);
|
||||
|
||||
if (to->buffer)
|
||||
cairo_region_union (to->surface_damage, from->surface_damage);
|
||||
cairo_region_union (to->buffer_damage, from->buffer_damage);
|
||||
cairo_region_destroy (from->surface_damage);
|
||||
cairo_region_destroy (from->buffer_damage);
|
||||
|
||||
if (from->input_region_set)
|
||||
{
|
||||
if (to->input_region)
|
||||
cairo_region_union (to->input_region, from->input_region);
|
||||
else
|
||||
to->input_region = cairo_region_reference (from->input_region);
|
||||
|
||||
to->input_region_set = TRUE;
|
||||
cairo_region_destroy (from->input_region);
|
||||
}
|
||||
|
||||
if (from->opaque_region_set)
|
||||
{
|
||||
if (to->opaque_region)
|
||||
cairo_region_union (to->opaque_region, from->opaque_region);
|
||||
else
|
||||
to->opaque_region = cairo_region_reference (from->opaque_region);
|
||||
|
||||
to->opaque_region_set = TRUE;
|
||||
cairo_region_destroy (from->opaque_region);
|
||||
}
|
||||
|
||||
if (from->has_new_geometry)
|
||||
{
|
||||
to->new_geometry = from->new_geometry;
|
||||
to->has_new_geometry = TRUE;
|
||||
}
|
||||
|
||||
if (from->has_new_min_size)
|
||||
{
|
||||
to->new_min_width = from->new_min_width;
|
||||
to->new_min_height = from->new_min_height;
|
||||
to->has_new_min_size = TRUE;
|
||||
}
|
||||
|
||||
if (from->has_new_max_size)
|
||||
{
|
||||
to->new_max_width = from->new_max_width;
|
||||
to->new_max_height = from->new_max_height;
|
||||
to->has_new_max_size = TRUE;
|
||||
}
|
||||
|
||||
if (from->scale > 0)
|
||||
to->scale = from->scale;
|
||||
|
||||
if (to->buffer && to->buffer_destroy_handler_id == 0)
|
||||
{
|
||||
to->buffer_destroy_handler_id =
|
||||
g_signal_connect (to->buffer, "resource-destroyed",
|
||||
@ -528,7 +584,10 @@ meta_wayland_surface_is_effectively_synchronized (MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandSurface *parent = surface->sub.parent;
|
||||
|
||||
return meta_wayland_surface_is_effectively_synchronized (parent);
|
||||
if (parent)
|
||||
return meta_wayland_surface_is_effectively_synchronized (parent);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -712,7 +771,7 @@ meta_wayland_surface_commit (MetaWaylandSurface *surface)
|
||||
* surface is in effective desynchronized mode.
|
||||
*/
|
||||
if (meta_wayland_surface_is_effectively_synchronized (surface))
|
||||
move_pending_state (surface->pending, surface->sub.pending);
|
||||
merge_pending_state (surface->pending, surface->sub.pending);
|
||||
else
|
||||
meta_wayland_surface_apply_pending_state (surface, surface->pending);
|
||||
}
|
||||
@ -1083,6 +1142,9 @@ meta_wayland_surface_set_window (MetaWaylandSurface *surface,
|
||||
g_signal_handlers_disconnect_by_func (surface->window,
|
||||
window_position_changed,
|
||||
surface);
|
||||
g_signal_handlers_disconnect_by_func (meta_window_actor_from_window (surface->window),
|
||||
window_actor_effects_completed,
|
||||
surface);
|
||||
}
|
||||
|
||||
surface->window = window;
|
||||
@ -1099,6 +1161,10 @@ meta_wayland_surface_set_window (MetaWaylandSurface *surface,
|
||||
"position-changed",
|
||||
G_CALLBACK (window_position_changed),
|
||||
surface, 0);
|
||||
g_signal_connect_object (meta_window_actor_from_window (window),
|
||||
"effects-completed",
|
||||
G_CALLBACK (window_actor_effects_completed),
|
||||
surface, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1200,6 +1266,13 @@ window_position_changed (MetaWindow *window,
|
||||
meta_wayland_surface_update_outputs_recursively (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
window_actor_effects_completed (MetaWindowActor *window_actor,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
meta_wayland_surface_update_outputs_recursively (surface);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_create_surface_actor (MetaWaylandSurface *surface)
|
||||
{
|
||||
|
@ -120,8 +120,6 @@ meta_wayland_text_input_focus_commit_text (ClutterInputFocus *focus,
|
||||
gtk_text_input_send_preedit_string (resource, NULL, 0);
|
||||
gtk_text_input_send_commit_string (resource, text);
|
||||
}
|
||||
|
||||
clutter_input_focus_reset (focus);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -252,10 +252,8 @@ is_valid_child (MetaWaylandSurface *surface)
|
||||
if (!surface->role)
|
||||
return FALSE;
|
||||
|
||||
if (!META_IS_WAYLAND_XDG_SURFACE (surface->role))
|
||||
return FALSE;
|
||||
|
||||
if (!META_IS_WAYLAND_ZXDG_SURFACE_V6 (surface->role))
|
||||
if (!META_IS_WAYLAND_XDG_TOPLEVEL (surface->role) &&
|
||||
!META_IS_WAYLAND_ZXDG_TOPLEVEL_V6 (surface->role))
|
||||
return FALSE;
|
||||
|
||||
if (!surface->window)
|
||||
@ -384,7 +382,7 @@ xdg_importer_import (struct wl_client *client,
|
||||
(!META_IS_WAYLAND_XDG_SURFACE (exported->surface->role) &&
|
||||
!META_IS_WAYLAND_ZXDG_SURFACE_V6 (exported->surface->role)))
|
||||
{
|
||||
zxdg_imported_v1_send_destroyed (resource);
|
||||
zxdg_imported_v1_send_destroyed (xdg_imported_resource);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -621,6 +621,8 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *window;
|
||||
MetaRectangle window_geometry;
|
||||
MetaRectangle old_geometry;
|
||||
gboolean geometry_changed;
|
||||
|
||||
if (!surface->buffer_ref.buffer && xdg_surface_priv->first_buffer_attached)
|
||||
{
|
||||
@ -629,6 +631,7 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
}
|
||||
|
||||
window = surface->window;
|
||||
old_geometry = xdg_surface_priv->geometry;
|
||||
|
||||
surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class);
|
||||
@ -643,7 +646,9 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
if (!pending->newly_attached)
|
||||
return;
|
||||
|
||||
if (pending->has_new_geometry)
|
||||
geometry_changed = !meta_rectangle_equal (&old_geometry, &xdg_surface_priv->geometry);
|
||||
|
||||
if (geometry_changed || meta_window_wayland_needs_move_resize (window))
|
||||
{
|
||||
window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface);
|
||||
meta_window_wayland_move_resize (window,
|
||||
|
@ -48,6 +48,7 @@ struct _MetaWindowWayland
|
||||
int geometry_scale;
|
||||
|
||||
MetaWaylandSerial pending_configure_serial;
|
||||
gboolean has_pending_state_change;
|
||||
gboolean has_pending_move;
|
||||
int pending_move_x;
|
||||
int pending_move_y;
|
||||
@ -324,6 +325,9 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
|
||||
window->buffer_rect.x = new_buffer_x;
|
||||
window->buffer_rect.y = new_buffer_y;
|
||||
}
|
||||
|
||||
if (flags & META_MOVE_RESIZE_WAYLAND_STATE_CHANGED)
|
||||
*result |= META_MOVE_RESIZE_RESULT_STATE_CHANGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -336,6 +340,8 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
|
||||
wl_window->pending_move_x = new_x;
|
||||
wl_window->pending_move_y = new_y;
|
||||
}
|
||||
|
||||
wl_window->has_pending_state_change = (flags & META_MOVE_RESIZE_STATE_CHANGED) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -629,12 +635,9 @@ meta_window_wayland_new (MetaDisplay *display,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_do_pending_move (MetaWindowWayland *wl_window,
|
||||
MetaWaylandSerial *acked_configure_serial)
|
||||
is_pending_ack_configure (MetaWindowWayland *wl_window,
|
||||
MetaWaylandSerial *acked_configure_serial)
|
||||
{
|
||||
if (!wl_window->has_pending_move)
|
||||
return FALSE;
|
||||
|
||||
if (wl_window->pending_configure_serial.set)
|
||||
{
|
||||
/* If we're waiting for a configure and this isn't an ACK for
|
||||
@ -677,6 +680,7 @@ meta_window_wayland_move_resize (MetaWindow *window,
|
||||
int gravity;
|
||||
MetaRectangle rect;
|
||||
MetaMoveResizeFlags flags;
|
||||
gboolean pending_ack_configure;
|
||||
|
||||
/* new_geom is in the logical pixel coordinate space, but MetaWindow wants its
|
||||
* rects to represent what in turn will end up on the stage, i.e. we need to
|
||||
@ -700,10 +704,12 @@ meta_window_wayland_move_resize (MetaWindow *window,
|
||||
|
||||
flags = META_MOVE_RESIZE_WAYLAND_RESIZE;
|
||||
|
||||
pending_ack_configure = is_pending_ack_configure (wl_window, acked_configure_serial);
|
||||
|
||||
/* x/y are ignored when we're doing interactive resizing */
|
||||
if (!meta_grab_op_is_resizing (window->display->grab_op))
|
||||
{
|
||||
if (wl_window->has_pending_move && should_do_pending_move (wl_window, acked_configure_serial))
|
||||
if (wl_window->has_pending_move && pending_ack_configure)
|
||||
{
|
||||
rect.x = wl_window->pending_move_x;
|
||||
rect.y = wl_window->pending_move_y;
|
||||
@ -724,6 +730,12 @@ meta_window_wayland_move_resize (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
if (wl_window->has_pending_state_change && pending_ack_configure)
|
||||
{
|
||||
flags |= META_MOVE_RESIZE_WAYLAND_STATE_CHANGED;
|
||||
wl_window->has_pending_state_change = FALSE;
|
||||
}
|
||||
|
||||
wl_window->pending_configure_serial.set = FALSE;
|
||||
|
||||
rect.width = new_geom.width;
|
||||
@ -903,3 +915,10 @@ meta_window_wayland_get_max_size (MetaWindow *window,
|
||||
scale_size (width, height, scale);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_window_wayland_needs_move_resize (MetaWindow *window)
|
||||
{
|
||||
MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
|
||||
|
||||
return wl_window->has_pending_state_change || wl_window->has_pending_move;
|
||||
}
|
||||
|
@ -78,5 +78,6 @@ void meta_window_wayland_get_max_size (MetaWindow *window,
|
||||
int *width,
|
||||
int *height);
|
||||
|
||||
gboolean meta_window_wayland_needs_move_resize (MetaWindow *window);
|
||||
|
||||
#endif
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "meta-xwayland.h"
|
||||
#include "meta-xwayland-private.h"
|
||||
|
||||
#include <meta/main.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-unix.h>
|
||||
#include <errno.h>
|
||||
@ -393,30 +395,34 @@ xserver_died (GObject *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSubprocess *proc = G_SUBPROCESS (source);
|
||||
GError *error = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
if (!g_subprocess_wait_finish (proc, result, &error))
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
g_error ("Failed to finish waiting for Xwayland: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
g_warning ("Failed to finish waiting for Xwayland: %s", error->message);
|
||||
}
|
||||
else if (!g_subprocess_get_successful (proc))
|
||||
g_error ("X Wayland crashed; aborting");
|
||||
g_warning ("X Wayland crashed; exiting");
|
||||
else
|
||||
{
|
||||
/* For now we simply abort if we see the server exit.
|
||||
*
|
||||
* In the future X will only be loaded lazily for legacy X support
|
||||
* but for now it's a hard requirement. */
|
||||
g_error ("Spurious exit of X Wayland server");
|
||||
g_warning ("Spurious exit of X Wayland server");
|
||||
}
|
||||
|
||||
meta_exit (META_EXIT_ERROR);
|
||||
}
|
||||
|
||||
static int
|
||||
x_io_error (Display *display)
|
||||
{
|
||||
g_error ("Connection to xwayland lost");
|
||||
g_warning ("Connection to xwayland lost");
|
||||
meta_exit (META_EXIT_ERROR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1282,6 +1282,8 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
|
||||
*result |= META_MOVE_RESIZE_RESULT_MOVED;
|
||||
if (need_resize_client || need_resize_frame)
|
||||
*result |= META_MOVE_RESIZE_RESULT_RESIZED;
|
||||
if (flags & META_MOVE_RESIZE_STATE_CHANGED)
|
||||
*result |= META_MOVE_RESIZE_RESULT_STATE_CHANGED;
|
||||
|
||||
update_gtk_edge_constraints (window);
|
||||
}
|
||||
|
Reference in New Issue
Block a user