Compare commits
76 Commits
Author | SHA1 | Date | |
---|---|---|---|
dc75c7d297 | |||
33c008b90a | |||
98a0c5cb35 | |||
b425f11536 | |||
a1bc2e0adc | |||
63fc71f05b | |||
31307720bf | |||
cb7ba2e90f | |||
ba1f4221e9 | |||
6e6183ec08 | |||
493aeb65c8 | |||
36f5a0a491 | |||
3daf912449 | |||
fadfca2e16 | |||
b1df6d08a5 | |||
63bf5f1150 | |||
d9d8732096 | |||
797c349245 | |||
b5691d6bf0 | |||
c7ad9b33c2 | |||
e49297975a | |||
858c12e73f | |||
b80b465a65 | |||
2cc8061f35 | |||
dbecb93233 | |||
adbe09afc3 | |||
bfe9b333c0 | |||
06b0d41baf | |||
a62fe66a25 | |||
5f40493c84 | |||
e8d9996c9c | |||
5465c912c7 | |||
a32bb758f7 | |||
ac8075bbf5 | |||
da9eb4718b | |||
9ad61fe02f | |||
7a09d07b9c | |||
456e6f345d | |||
20cf6b630d | |||
1e17f8813b | |||
d985517573 | |||
107bb3d9c2 | |||
b1c47c6213 | |||
c43f178495 | |||
c46bea9dff | |||
622e8c348f | |||
51b65b98f5 | |||
7ec0a9dd68 | |||
6ce42e100f | |||
13a23f16c1 | |||
40dc22659b | |||
fdcb68f4d0 | |||
17491bae06 | |||
568876da95 | |||
ea546a8b90 | |||
e8f29a3336 | |||
5e9986bbcb | |||
3edf6a5292 | |||
ad500ef4e5 | |||
9a2471db47 | |||
db164bcfa2 | |||
83553e3f6e | |||
3b2f6ae93d | |||
bc47f0a1ac | |||
c8986d19e5 | |||
7baabc7ed0 | |||
b0709504ea | |||
7e94311e2e | |||
e339a57ddf | |||
e3b2b90c72 | |||
6f094bd399 | |||
2c805524b4 | |||
95c1baf3d1 | |||
6f9b5edd4d | |||
31809e1214 | |||
82f3bdd14e |
39
NEWS
39
NEWS
@ -1,3 +1,42 @@
|
||||
3.36.3
|
||||
======
|
||||
* Broadcast clipboard/primary offers [Carlos; !1262]
|
||||
* Fix monitor screen cast on X11 [Jonas Å.; !1251]
|
||||
* Implement touch-mode detecation for the X11 backend [Carlos; !1278]
|
||||
* Drop external keyboard detection from touch-mode heuristics [Carlos; !1277]
|
||||
* Fix leaked DMA buffers in screencasts [Jonas; !1283]
|
||||
* Fixed crashes [Daniel, Carlos, Jonas D.; !1256, !1258, !1280]
|
||||
|
||||
Contributors:
|
||||
Carlos Garnacho, Daniel van Vugt, Jonas Ådahl
|
||||
|
||||
3.36.2
|
||||
======
|
||||
* Sync timelines to hardware vsync [Daniel; !724]
|
||||
* Fix screencasting non-maximized windows [Jonas; !1174]
|
||||
* Make window-aliveness checks less aggressive [Jonas; !1182]
|
||||
* Fix stylus coordinates when using screen rotation [Jonas T.; #1118]
|
||||
* Preserve keyboard state on VT switch [Olivier; !1185]
|
||||
* Fix trackball button scrolling [Phillip; #1120]
|
||||
* Fix tiled monitor support [Jonas Å.; !1199]
|
||||
* Fix various clipboard issues [Carlos; !1198, !1203, !1204, !1186, !1206]
|
||||
* Synchronize shadows to server-side decorations [Olivier; !1214]
|
||||
* Fix overview key on X11 when using multiple keyboard layouts [Olivier; !1219]
|
||||
* Fix capturing with multiple stage views [Jonas Å.; !1222]
|
||||
* Fixed crashes [Jonas D., Carlos; !1173, !1183]
|
||||
* Misc. bug fixes and cleanups [Andre, Georges, Simon, Christian, Carlos, Marco,
|
||||
Pekka, Laurent, Jonas D.; !1169, !1170, !1172, !1168, !1184, !1200, !1209,
|
||||
#1074, !1208]
|
||||
|
||||
Contributors:
|
||||
Marco Trevisan (Treviño), Laurent Bigonville, Jonas Dreßler, Olivier Fourdan,
|
||||
Carlos Garnacho, Andre Moreira Magalhaes, Simon McVittie,
|
||||
Georges Basile Stavracas Neto, Pekka Paalanen, Christian Rauch, Jonas Troeger,
|
||||
Daniel van Vugt, Phillip Wood, Jonas Ådahl
|
||||
|
||||
Translators:
|
||||
Dušan Kazik [sk], Christian Kirbach [de]
|
||||
|
||||
3.36.1
|
||||
======
|
||||
* Fix hardware cursor on GPU hotplpug [Pekka; !1097]
|
||||
|
@ -2410,6 +2410,7 @@ clutter_actor_should_pick_paint (ClutterActor *self)
|
||||
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_MAPPED (self) &&
|
||||
clutter_actor_has_allocation (self) &&
|
||||
(_clutter_context_get_pick_mode () == CLUTTER_PICK_ALL ||
|
||||
CLUTTER_ACTOR_IS_REACTIVE (self)))
|
||||
return TRUE;
|
||||
@ -2603,6 +2604,9 @@ clutter_actor_set_allocation_internal (ClutterActor *self,
|
||||
gboolean retval;
|
||||
ClutterActorBox old_alloc = { 0, };
|
||||
|
||||
g_return_val_if_fail (!isnan (box->x1) && !isnan (box->x2) &&
|
||||
!isnan (box->y1) && !isnan (box->y2), FALSE);
|
||||
|
||||
obj = G_OBJECT (self);
|
||||
|
||||
g_object_freeze_notify (obj);
|
||||
@ -4193,7 +4197,9 @@ clutter_actor_continue_paint (ClutterActor *self,
|
||||
clutter_paint_node_unref (dummy);
|
||||
|
||||
/* XXX:2.0 - Call the paint() virtual directly */
|
||||
if (g_signal_has_handler_pending (self, actor_signals[PAINT],
|
||||
if (!(clutter_paint_context_get_paint_flags (paint_context) &
|
||||
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL) &&
|
||||
g_signal_has_handler_pending (self, actor_signals[PAINT],
|
||||
0, TRUE))
|
||||
g_signal_emit (self, actor_signals[PAINT], 0, paint_context);
|
||||
else
|
||||
@ -10363,6 +10369,11 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
old_allocation = priv->allocation;
|
||||
real_allocation = *box;
|
||||
|
||||
g_return_if_fail (!isnan (real_allocation.x1) &&
|
||||
!isnan (real_allocation.x2) &&
|
||||
!isnan (real_allocation.y1) &&
|
||||
!isnan (real_allocation.y2));
|
||||
|
||||
/* constraints are allowed to modify the allocation only here; we do
|
||||
* this prior to all the other checks so that we can bail out if the
|
||||
* allocation did not change
|
||||
|
@ -346,6 +346,12 @@ on_captured_event (ClutterActor *stage,
|
||||
ClutterModifierType modifier_state;
|
||||
gboolean has_button = TRUE;
|
||||
|
||||
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action)))
|
||||
{
|
||||
clutter_click_action_release (action);
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||
|
||||
switch (clutter_event_type (event))
|
||||
|
@ -190,6 +190,26 @@ master_clock_get_swap_wait_time (ClutterMasterClockDefault *master_clock)
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t
|
||||
master_clock_get_next_presentation_time (ClutterMasterClockDefault *master_clock)
|
||||
{
|
||||
ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
|
||||
const GSList *stages, *l;
|
||||
int64_t earliest = -1;
|
||||
|
||||
stages = clutter_stage_manager_peek_stages (stage_manager);
|
||||
|
||||
for (l = stages; l != NULL; l = l->next)
|
||||
{
|
||||
gint64 t = _clutter_stage_get_next_presentation_time (l->data);
|
||||
|
||||
if (earliest == -1 || (t != -1 && t < earliest))
|
||||
earliest = t;
|
||||
}
|
||||
|
||||
return earliest;
|
||||
}
|
||||
|
||||
static void
|
||||
master_clock_schedule_stage_updates (ClutterMasterClockDefault *master_clock)
|
||||
{
|
||||
@ -466,7 +486,11 @@ clutter_clock_dispatch (GSource *source,
|
||||
COGL_TRACE_BEGIN (ClutterMasterClockTick, "Master Clock (tick)");
|
||||
|
||||
/* Get the time to use for this frame */
|
||||
master_clock->cur_tick = g_source_get_time (source);
|
||||
master_clock->cur_tick = master_clock_get_next_presentation_time (master_clock);
|
||||
|
||||
/* On the first frame the backend might not have an answer */
|
||||
if (master_clock->cur_tick <= 0)
|
||||
master_clock->cur_tick = g_source_get_time (source);
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
master_clock->remaining_budget = master_clock->frame_budget;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "clutter-input-device-private.h"
|
||||
#include "clutter-input-pointer-a11y-private.h"
|
||||
#include "clutter-macros.h"
|
||||
#include "clutter-paint-context-private.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-stage-view.h"
|
||||
@ -48,6 +49,23 @@ void clutter_stage_capture_into (ClutterStage *stage,
|
||||
cairo_rectangle_int_t *rect,
|
||||
uint8_t *data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_paint_to_framebuffer (ClutterStage *stage,
|
||||
CoglFramebuffer *framebuffer,
|
||||
const cairo_rectangle_int_t *rect,
|
||||
float scale,
|
||||
ClutterPaintFlag paint_flags);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
gboolean clutter_stage_paint_to_buffer (ClutterStage *stage,
|
||||
const cairo_rectangle_int_t *rect,
|
||||
float scale,
|
||||
uint8_t *data,
|
||||
int stride,
|
||||
CoglPixelFormat format,
|
||||
ClutterPaintFlag paint_flags,
|
||||
GError **error);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_freeze_updates (ClutterStage *stage);
|
||||
|
||||
|
@ -20,11 +20,22 @@
|
||||
|
||||
#include "clutter-paint-context.h"
|
||||
|
||||
typedef enum _ClutterPaintFlag
|
||||
{
|
||||
CLUTTER_PAINT_FLAG_NONE = 0,
|
||||
CLUTTER_PAINT_FLAG_NO_CURSORS = 1 << 0,
|
||||
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL = 1 << 0,
|
||||
} ClutterPaintFlag;
|
||||
|
||||
ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||
const cairo_region_t *redraw_clip);
|
||||
const cairo_region_t *redraw_clip,
|
||||
ClutterPaintFlag paint_flags);
|
||||
|
||||
gboolean clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context);
|
||||
|
||||
CoglFramebuffer * clutter_paint_context_get_base_framebuffer (ClutterPaintContext *paint_context);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintFlag clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context);
|
||||
|
||||
#endif /* CLUTTER_PAINT_CONTEXT_PRIVATE_H */
|
||||
|
@ -23,6 +23,8 @@ struct _ClutterPaintContext
|
||||
{
|
||||
grefcount ref_count;
|
||||
|
||||
ClutterPaintFlag paint_flags;
|
||||
|
||||
GList *framebuffers;
|
||||
|
||||
ClutterStageView *view;
|
||||
@ -36,7 +38,8 @@ G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
|
||||
|
||||
ClutterPaintContext *
|
||||
clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||
const cairo_region_t *redraw_clip)
|
||||
const cairo_region_t *redraw_clip,
|
||||
ClutterPaintFlag paint_flags)
|
||||
{
|
||||
ClutterPaintContext *paint_context;
|
||||
CoglFramebuffer *framebuffer;
|
||||
@ -45,6 +48,7 @@ clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||
g_ref_count_init (&paint_context->ref_count);
|
||||
paint_context->view = view;
|
||||
paint_context->redraw_clip = cairo_region_copy (redraw_clip);
|
||||
paint_context->paint_flags = paint_flags;
|
||||
|
||||
framebuffer = clutter_stage_view_get_framebuffer (view);
|
||||
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
|
||||
@ -62,6 +66,8 @@ clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer)
|
||||
|
||||
paint_context = g_new0 (ClutterPaintContext, 1);
|
||||
g_ref_count_init (&paint_context->ref_count);
|
||||
paint_context->paint_flags = (CLUTTER_PAINT_FLAG_NO_CURSORS |
|
||||
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL);
|
||||
|
||||
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
|
||||
|
||||
@ -170,3 +176,12 @@ clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context)
|
||||
|
||||
return !paint_context->view;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_paint_context_get_paint_flags: (skip)
|
||||
*/
|
||||
ClutterPaintFlag
|
||||
clutter_paint_context_get_paint_flags (ClutterPaintContext *paint_context)
|
||||
{
|
||||
return paint_context->paint_flags;
|
||||
}
|
||||
|
@ -682,7 +682,6 @@ clutter_seat_warp_pointer (ClutterSeat *seat,
|
||||
* requirements are fulfilled:
|
||||
*
|
||||
* - A touchscreen is available
|
||||
* - No external keyboard is attached to the device
|
||||
* - A tablet mode switch, if present, is enabled
|
||||
*
|
||||
* Returns: %TRUE if the device is a tablet that doesn't have an external
|
||||
|
@ -78,6 +78,7 @@ void _clutter_stage_schedule_update (ClutterStage *stage);
|
||||
gint64 _clutter_stage_get_update_time (ClutterStage *stage);
|
||||
void _clutter_stage_clear_update_time (ClutterStage *stage);
|
||||
gboolean _clutter_stage_has_full_redraw_queued (ClutterStage *stage);
|
||||
int64_t _clutter_stage_get_next_presentation_time (ClutterStage *stage);
|
||||
|
||||
void clutter_stage_log_pick (ClutterStage *stage,
|
||||
const graphene_point_t *vertices,
|
||||
|
@ -178,6 +178,22 @@ _clutter_stage_window_clear_update_time (ClutterStageWindow *window)
|
||||
iface->clear_update_time (window);
|
||||
}
|
||||
|
||||
int64_t
|
||||
_clutter_stage_window_get_next_presentation_time (ClutterStageWindow *window)
|
||||
{
|
||||
ClutterStageWindowInterface *iface;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), 0);
|
||||
|
||||
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
||||
|
||||
/* If not implemented then just revert to the old behaviour... */
|
||||
if (iface->get_next_presentation_time == NULL)
|
||||
return _clutter_stage_window_get_update_time (window);
|
||||
|
||||
return iface->get_next_presentation_time (window);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
|
||||
gboolean accept_focus)
|
||||
|
@ -61,6 +61,8 @@ struct _ClutterStageWindowInterface
|
||||
GList *(* get_views) (ClutterStageWindow *stage_window);
|
||||
int64_t (* get_frame_counter) (ClutterStageWindow *stage_window);
|
||||
void (* finish_frame) (ClutterStageWindow *stage_window);
|
||||
|
||||
int64_t (* get_next_presentation_time) (ClutterStageWindow *stage_window);
|
||||
};
|
||||
|
||||
ClutterActor * _clutter_stage_window_get_wrapper (ClutterStageWindow *window);
|
||||
@ -101,6 +103,8 @@ void _clutter_stage_window_finish_frame (ClutterStageWin
|
||||
|
||||
int64_t _clutter_stage_window_get_frame_counter (ClutterStageWindow *window);
|
||||
|
||||
int64_t _clutter_stage_window_get_next_presentation_time (ClutterStageWindow *window);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_STAGE_WINDOW_H__ */
|
||||
|
@ -934,7 +934,8 @@ clutter_stage_do_paint_view (ClutterStage *stage,
|
||||
ClutterPaintContext *paint_context;
|
||||
cairo_rectangle_int_t clip_rect;
|
||||
|
||||
paint_context = clutter_paint_context_new_for_view (view, redraw_clip);
|
||||
paint_context = clutter_paint_context_new_for_view (view, redraw_clip,
|
||||
CLUTTER_PAINT_FLAG_NONE);
|
||||
|
||||
cairo_region_get_extents (redraw_clip, &clip_rect);
|
||||
setup_view_for_pick_or_paint (stage, view, &clip_rect);
|
||||
@ -1320,15 +1321,9 @@ clutter_stage_queue_actor_relayout (ClutterStage *stage,
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
if (g_hash_table_contains (priv->pending_relayouts, stage))
|
||||
return;
|
||||
|
||||
if (g_hash_table_size (priv->pending_relayouts) == 0)
|
||||
_clutter_stage_schedule_update (stage);
|
||||
|
||||
if (actor == (ClutterActor *) stage)
|
||||
g_hash_table_remove_all (priv->pending_relayouts);
|
||||
|
||||
g_hash_table_add (priv->pending_relayouts, g_object_ref (actor));
|
||||
priv->pending_relayouts_version++;
|
||||
}
|
||||
@ -3751,6 +3746,21 @@ _clutter_stage_clear_update_time (ClutterStage *stage)
|
||||
_clutter_stage_window_clear_update_time (stage_window);
|
||||
}
|
||||
|
||||
int64_t
|
||||
_clutter_stage_get_next_presentation_time (ClutterStage *stage)
|
||||
{
|
||||
ClutterStageWindow *stage_window;
|
||||
|
||||
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
|
||||
return 0;
|
||||
|
||||
stage_window = _clutter_stage_get_window (stage);
|
||||
if (stage_window == NULL)
|
||||
return 0;
|
||||
|
||||
return _clutter_stage_window_get_next_presentation_time (stage_window);
|
||||
}
|
||||
|
||||
ClutterPaintVolume *
|
||||
_clutter_stage_paint_volume_stack_allocate (ClutterStage *stage)
|
||||
{
|
||||
@ -4463,6 +4473,100 @@ clutter_stage_get_capture_final_size (ClutterStage *stage,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_stage_paint_to_framebuffer: (skip)
|
||||
*/
|
||||
void
|
||||
clutter_stage_paint_to_framebuffer (ClutterStage *stage,
|
||||
CoglFramebuffer *framebuffer,
|
||||
const cairo_rectangle_int_t *rect,
|
||||
float scale,
|
||||
ClutterPaintFlag paint_flags)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
ClutterPaintContext *paint_context;
|
||||
cairo_region_t *redraw_clip;
|
||||
|
||||
redraw_clip = cairo_region_create_rectangle (rect);
|
||||
paint_context = clutter_paint_context_new_for_framebuffer (framebuffer);
|
||||
cairo_region_destroy (redraw_clip);
|
||||
|
||||
cogl_framebuffer_push_matrix (framebuffer);
|
||||
cogl_framebuffer_set_projection_matrix (framebuffer, &priv->projection);
|
||||
cogl_framebuffer_set_viewport (framebuffer,
|
||||
-(rect->x * scale),
|
||||
-(rect->y * scale),
|
||||
priv->viewport[2] * scale,
|
||||
priv->viewport[3] * scale);
|
||||
clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context);
|
||||
cogl_framebuffer_pop_matrix (framebuffer);
|
||||
|
||||
clutter_paint_context_destroy (paint_context);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_stage_paint_to_buffer: (skip)
|
||||
*/
|
||||
gboolean
|
||||
clutter_stage_paint_to_buffer (ClutterStage *stage,
|
||||
const cairo_rectangle_int_t *rect,
|
||||
float scale,
|
||||
uint8_t *data,
|
||||
int stride,
|
||||
CoglPixelFormat format,
|
||||
ClutterPaintFlag paint_flags,
|
||||
GError **error)
|
||||
{
|
||||
ClutterBackend *clutter_backend = clutter_get_default_backend ();
|
||||
CoglContext *cogl_context =
|
||||
clutter_backend_get_cogl_context (clutter_backend);
|
||||
int texture_width, texture_height;
|
||||
CoglTexture2D *texture;
|
||||
CoglOffscreen *offscreen;
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglBitmap *bitmap;
|
||||
|
||||
texture_width = (int) ceilf (rect->width * scale);
|
||||
texture_height = (int) ceilf (rect->height * scale);
|
||||
texture = cogl_texture_2d_new_with_size (cogl_context,
|
||||
texture_width,
|
||||
texture_height);
|
||||
if (!texture)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Failed to create %dx%d texture",
|
||||
texture_width, texture_height);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
|
||||
framebuffer = COGL_FRAMEBUFFER (offscreen);
|
||||
|
||||
cogl_object_unref (texture);
|
||||
|
||||
if (!cogl_framebuffer_allocate (framebuffer, error))
|
||||
return FALSE;
|
||||
|
||||
clutter_stage_paint_to_framebuffer (stage, framebuffer,
|
||||
rect, scale, paint_flags);
|
||||
|
||||
bitmap = cogl_bitmap_new_for_data (cogl_context,
|
||||
texture_width, texture_height,
|
||||
format,
|
||||
stride,
|
||||
data);
|
||||
|
||||
cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
|
||||
0, 0,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
bitmap);
|
||||
|
||||
cogl_object_unref (bitmap);
|
||||
cogl_object_unref (framebuffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
capture_view_into (ClutterStage *stage,
|
||||
gboolean paint,
|
||||
@ -4471,50 +4575,17 @@ capture_view_into (ClutterStage *stage,
|
||||
uint8_t *data,
|
||||
int stride)
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
ClutterBackend *backend;
|
||||
CoglContext *context;
|
||||
CoglBitmap *bitmap;
|
||||
cairo_rectangle_int_t view_layout;
|
||||
g_autoptr (GError) error = NULL;
|
||||
float view_scale;
|
||||
float texture_width;
|
||||
float texture_height;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
|
||||
framebuffer = clutter_stage_view_get_framebuffer (view);
|
||||
|
||||
if (paint)
|
||||
{
|
||||
cairo_region_t *region;
|
||||
|
||||
_clutter_stage_maybe_setup_viewport (stage, view);
|
||||
region = cairo_region_create_rectangle (rect);
|
||||
clutter_stage_do_paint_view (stage, view, region);
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
|
||||
view_scale = clutter_stage_view_get_scale (view);
|
||||
texture_width = roundf (rect->width * view_scale);
|
||||
texture_height = roundf (rect->height * view_scale);
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
context = clutter_backend_get_cogl_context (backend);
|
||||
bitmap = cogl_bitmap_new_for_data (context,
|
||||
texture_width, texture_height,
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||
stride,
|
||||
data);
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
|
||||
roundf ((rect->x - view_layout.x) * view_scale),
|
||||
roundf ((rect->y - view_layout.y) * view_scale),
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
bitmap);
|
||||
|
||||
cogl_object_unref (bitmap);
|
||||
if (!clutter_stage_paint_to_buffer (stage, rect, view_scale, data, stride,
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||
CLUTTER_PAINT_FLAG_NO_CURSORS,
|
||||
&error))
|
||||
g_warning ("Failed to capture stage: %s", error->message);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -235,7 +235,12 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
|
||||
stage_cogl->update_time = next_presentation_time - max_render_time_allowed;
|
||||
|
||||
if (stage_cogl->update_time == stage_cogl->last_update_time)
|
||||
stage_cogl->update_time = stage_cogl->last_update_time + refresh_interval;
|
||||
{
|
||||
stage_cogl->update_time += refresh_interval;
|
||||
next_presentation_time += refresh_interval;
|
||||
}
|
||||
|
||||
stage_cogl->next_presentation_time = next_presentation_time;
|
||||
}
|
||||
|
||||
static gint64
|
||||
@ -256,6 +261,29 @@ clutter_stage_cogl_clear_update_time (ClutterStageWindow *stage_window)
|
||||
|
||||
stage_cogl->last_update_time = stage_cogl->update_time;
|
||||
stage_cogl->update_time = -1;
|
||||
stage_cogl->next_presentation_time = -1;
|
||||
}
|
||||
|
||||
static int64_t
|
||||
clutter_stage_cogl_get_next_presentation_time (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||
int64_t now = g_get_monotonic_time ();
|
||||
|
||||
if (stage_cogl->next_presentation_time > 0 &&
|
||||
stage_cogl->next_presentation_time <= now)
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND,
|
||||
"Missed some frames. Something blocked for over "
|
||||
"%" G_GINT64_FORMAT "ms.",
|
||||
(now - stage_cogl->next_presentation_time) / 1000);
|
||||
|
||||
stage_cogl->update_time = -1;
|
||||
clutter_stage_cogl_schedule_update (stage_window,
|
||||
stage_cogl->last_sync_delay);
|
||||
}
|
||||
|
||||
return stage_cogl->next_presentation_time;
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
@ -375,15 +403,11 @@ static gboolean
|
||||
swap_framebuffer (ClutterStageWindow *stage_window,
|
||||
ClutterStageView *view,
|
||||
cairo_region_t *swap_region,
|
||||
gboolean swap_with_damage,
|
||||
cairo_region_t *queued_redraw_clip)
|
||||
gboolean swap_with_damage)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
|
||||
int *damage, n_rects, i;
|
||||
|
||||
if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)))
|
||||
paint_damage_region (stage_window, view, swap_region, queued_redraw_clip);
|
||||
|
||||
n_rects = cairo_region_num_rectangles (swap_region);
|
||||
damage = g_newa (int, n_rects * 4);
|
||||
for (i = 0; i < n_rects; i++)
|
||||
@ -620,7 +644,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
gboolean swap_with_damage;
|
||||
ClutterActor *wrapper;
|
||||
cairo_region_t *redraw_clip;
|
||||
cairo_region_t *queued_redraw_clip;
|
||||
cairo_region_t *queued_redraw_clip = NULL;
|
||||
cairo_region_t *fb_clip_region;
|
||||
cairo_region_t *swap_region;
|
||||
cairo_rectangle_int_t redraw_rect;
|
||||
@ -644,6 +668,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
has_buffer_age = cogl_is_onscreen (fb) && is_buffer_age_enabled ();
|
||||
|
||||
redraw_clip = clutter_stage_view_take_redraw_clip (view);
|
||||
if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION))
|
||||
queued_redraw_clip = cairo_region_copy (redraw_clip);
|
||||
|
||||
/* NB: a NULL redraw clip == full stage redraw */
|
||||
if (!redraw_clip)
|
||||
@ -711,8 +737,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
redraw_clip = cairo_region_create_rectangle (&view_rect);
|
||||
}
|
||||
|
||||
queued_redraw_clip = cairo_region_copy (redraw_clip);
|
||||
|
||||
if (may_use_clipped_redraw &&
|
||||
G_LIKELY (!(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS)))
|
||||
use_clipped_redraw = TRUE;
|
||||
@ -922,7 +946,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
}
|
||||
|
||||
g_clear_pointer (&redraw_clip, cairo_region_destroy);
|
||||
g_clear_pointer (&queued_redraw_clip, cairo_region_destroy);
|
||||
g_clear_pointer (&fb_clip_region, cairo_region_destroy);
|
||||
|
||||
if (do_swap_buffer)
|
||||
@ -943,11 +966,17 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
swap_region = transformed_swap_region;
|
||||
}
|
||||
|
||||
if (queued_redraw_clip)
|
||||
{
|
||||
paint_damage_region (stage_window, view,
|
||||
swap_region, queued_redraw_clip);
|
||||
cairo_region_destroy (queued_redraw_clip);
|
||||
}
|
||||
|
||||
res = swap_framebuffer (stage_window,
|
||||
view,
|
||||
swap_region,
|
||||
swap_with_damage,
|
||||
queued_redraw_clip);
|
||||
swap_with_damage);
|
||||
|
||||
cairo_region_destroy (swap_region);
|
||||
|
||||
@ -955,6 +984,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_clear_pointer (&queued_redraw_clip, cairo_region_destroy);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -1008,6 +1038,7 @@ clutter_stage_window_iface_init (ClutterStageWindowInterface *iface)
|
||||
iface->schedule_update = clutter_stage_cogl_schedule_update;
|
||||
iface->get_update_time = clutter_stage_cogl_get_update_time;
|
||||
iface->clear_update_time = clutter_stage_cogl_clear_update_time;
|
||||
iface->get_next_presentation_time = clutter_stage_cogl_get_next_presentation_time;
|
||||
iface->redraw = clutter_stage_cogl_redraw;
|
||||
}
|
||||
|
||||
@ -1053,6 +1084,7 @@ _clutter_stage_cogl_init (ClutterStageCogl *stage)
|
||||
stage->refresh_rate = 0.0;
|
||||
|
||||
stage->update_time = -1;
|
||||
stage->next_presentation_time = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -48,6 +48,7 @@ struct _ClutterStageCogl
|
||||
gint64 last_presentation_time;
|
||||
gint64 update_time;
|
||||
int64_t last_update_time;
|
||||
int64_t next_presentation_time;
|
||||
|
||||
/* We only enable clipped redraws after 2 frames, since we've seen
|
||||
* a lot of drivers can struggle to get going and may output some
|
||||
|
@ -121,6 +121,9 @@ cogl_texture_2d_new_with_size (CoglContext *ctx,
|
||||
{
|
||||
CoglTextureLoader *loader;
|
||||
|
||||
g_return_val_if_fail (width >= 1, NULL);
|
||||
g_return_val_if_fail (height >= 1, NULL);
|
||||
|
||||
loader = _cogl_texture_create_loader ();
|
||||
loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZED;
|
||||
loader->src.sized.width = width;
|
||||
|
@ -132,8 +132,8 @@ _cogl_framebuffer_gl_flush_viewport_state (CoglFramebuffer *framebuffer)
|
||||
{
|
||||
float gl_viewport_y;
|
||||
|
||||
g_assert (framebuffer->viewport_width >=0 &&
|
||||
framebuffer->viewport_height >=0);
|
||||
g_return_if_fail (framebuffer->viewport_width >= 0);
|
||||
g_return_if_fail (framebuffer->viewport_height >= 0);
|
||||
|
||||
/* Convert the Cogl viewport y offset to an OpenGL viewport y offset
|
||||
* NB: OpenGL defines its window and viewport origins to be bottom
|
||||
|
@ -1,5 +1,5 @@
|
||||
project('mutter', 'c',
|
||||
version: '3.36.1',
|
||||
version: '3.36.3',
|
||||
meson_version: '>= 0.50.0',
|
||||
license: 'GPLv2+'
|
||||
)
|
||||
|
85
po/de.po
85
po/de.po
@ -13,8 +13,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mutter master\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
|
||||
"POT-Creation-Date: 2019-08-06 00:49+0000\n"
|
||||
"PO-Revision-Date: 2019-09-05 23:42+0200\n"
|
||||
"POT-Creation-Date: 2020-03-30 20:11+0000\n"
|
||||
"PO-Revision-Date: 2020-04-06 23:13+0200\n"
|
||||
"Last-Translator: Christian Kirbach <christian.kirbach@gmail.com>\n"
|
||||
"Language-Team: Deutsch <gnome-de@gnome.org>\n"
|
||||
"Language: de\n"
|
||||
@ -22,7 +22,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 2.2.1\n"
|
||||
"X-Generator: Poedit 2.3\n"
|
||||
|
||||
#: data/50-mutter-navigation.xml:6
|
||||
msgid "Navigation"
|
||||
@ -435,20 +435,33 @@ msgstr "Zusatztaste zum Finden des Zeigers"
|
||||
msgid "This key will initiate the “locate pointer” action."
|
||||
msgstr "Diese Taste wird die Aktion »Zeiger finden« auslösen."
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:155
|
||||
#: data/org.gnome.mutter.gschema.xml.in:142
|
||||
msgid "Timeout for check-alive ping"
|
||||
msgstr "Reaktionsschwellwert bei Kontaktkontrolle"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:143
|
||||
msgid ""
|
||||
"Number of milliseconds a client has to respond to a ping request in order to "
|
||||
"not be detected as frozen. Using 0 will disable the alive check completely."
|
||||
msgstr ""
|
||||
"Zeit in Millisekunden, innerhalb welcher ein Client auf eine "
|
||||
"Kontaktkontrolle antworten muss, um nicht als abgestürzt zu gelten. »0« "
|
||||
"bedeutet, dass die Kontaktkontrolle ausgeschaltet wird."
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:165
|
||||
msgid "Select window from tab popup"
|
||||
msgstr "Fenster aus Tab-Anzeige auswählen"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:160
|
||||
#: data/org.gnome.mutter.gschema.xml.in:170
|
||||
msgid "Cancel tab popup"
|
||||
msgstr "Tab-Anzeige abbrechen"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:165
|
||||
#: data/org.gnome.mutter.gschema.xml.in:175
|
||||
msgid "Switch monitor configurations"
|
||||
msgstr "Bildschirmkonfigurationen wechseln"
|
||||
|
||||
# Ich denke nicht, dass »rotate« hier die Bildschirmdrehung meint, sondern eher eine Liste aus Konfigurationen rotiert (d.h. umgewälzt) wird.
|
||||
#: data/org.gnome.mutter.gschema.xml.in:170
|
||||
#: data/org.gnome.mutter.gschema.xml.in:180
|
||||
msgid "Rotates the built-in monitor configuration"
|
||||
msgstr "Wechselt die Konfiguration des eingebauten Bildschirms"
|
||||
|
||||
@ -569,7 +582,7 @@ msgstr ""
|
||||
#. TRANSLATORS: This string refers to a button that switches between
|
||||
#. * different modes.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2531
|
||||
#: src/backends/meta-input-settings.c:2631
|
||||
#, c-format
|
||||
msgid "Mode Switch (Group %d)"
|
||||
msgstr "Moduswechsel (Gruppe %d)"
|
||||
@ -577,34 +590,34 @@ msgstr "Moduswechsel (Gruppe %d)"
|
||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
|
||||
#. * mapping through the available outputs.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2554
|
||||
#: src/backends/meta-input-settings.c:2654
|
||||
msgid "Switch monitor"
|
||||
msgstr "Bildschirm wechseln"
|
||||
|
||||
#: src/backends/meta-input-settings.c:2556
|
||||
#: src/backends/meta-input-settings.c:2656
|
||||
msgid "Show on-screen help"
|
||||
msgstr "Bildschirmhilfe anzeigen"
|
||||
|
||||
#: src/backends/meta-monitor.c:223
|
||||
#: src/backends/meta-monitor.c:226
|
||||
msgid "Built-in display"
|
||||
msgstr "Eingebaute Anzeige"
|
||||
|
||||
#: src/backends/meta-monitor.c:252
|
||||
#: src/backends/meta-monitor.c:255
|
||||
msgid "Unknown"
|
||||
msgstr "Unbekannt"
|
||||
|
||||
#: src/backends/meta-monitor.c:254
|
||||
#: src/backends/meta-monitor.c:257
|
||||
msgid "Unknown Display"
|
||||
msgstr "Unbekannte Anzeige"
|
||||
|
||||
#: src/backends/meta-monitor.c:262
|
||||
#: src/backends/meta-monitor.c:265
|
||||
#, c-format
|
||||
msgctxt ""
|
||||
"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#: src/backends/meta-monitor.c:270
|
||||
#: src/backends/meta-monitor.c:273
|
||||
#, c-format
|
||||
msgctxt ""
|
||||
"This is a monitor vendor name followed by product/model name where size in "
|
||||
@ -614,13 +627,13 @@ msgstr "%s %s"
|
||||
|
||||
# https://de.wikipedia.org/wiki/Composition-Manager
|
||||
#. Translators: this string will appear in Sysprof
|
||||
#: src/backends/meta-profiler.c:82
|
||||
#: src/backends/meta-profiler.c:79
|
||||
msgid "Compositor"
|
||||
msgstr "Compositor"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: src/compositor/compositor.c:510
|
||||
#: src/compositor/compositor.c:533
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display “%s”."
|
||||
@ -632,47 +645,47 @@ msgstr ""
|
||||
msgid "Bell event"
|
||||
msgstr "Klangereignis"
|
||||
|
||||
#: src/core/main.c:185
|
||||
#: src/core/main.c:190
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "Verbindung zur Sitzungsverwaltung deaktivieren"
|
||||
|
||||
#: src/core/main.c:191
|
||||
#: src/core/main.c:196
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "Den aktuellen Fensterverwalter ersetzen"
|
||||
|
||||
#: src/core/main.c:197
|
||||
#: src/core/main.c:202
|
||||
msgid "Specify session management ID"
|
||||
msgstr "Kennung der Sitzungsverwaltung angeben"
|
||||
|
||||
#: src/core/main.c:202
|
||||
#: src/core/main.c:207
|
||||
msgid "X Display to use"
|
||||
msgstr "Zu verwendende X-Anzeige"
|
||||
|
||||
#: src/core/main.c:208
|
||||
#: src/core/main.c:213
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "Sitzung anhand gespeicherter Datei starten"
|
||||
|
||||
#: src/core/main.c:214
|
||||
#: src/core/main.c:219
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "X-Aufrufe abgleichen"
|
||||
|
||||
#: src/core/main.c:221
|
||||
#: src/core/main.c:226
|
||||
msgid "Run as a wayland compositor"
|
||||
msgstr "Als Wayland-Compositor ausführen"
|
||||
|
||||
#: src/core/main.c:227
|
||||
#: src/core/main.c:232
|
||||
msgid "Run as a nested compositor"
|
||||
msgstr "Als eingebetteten Compositor ausführen"
|
||||
|
||||
#: src/core/main.c:233
|
||||
#: src/core/main.c:238
|
||||
msgid "Run wayland compositor without starting Xwayland"
|
||||
msgstr "Wayland-Compositor ausführen, ohne Xwayland zu starten"
|
||||
|
||||
#: src/core/main.c:241
|
||||
#: src/core/main.c:246
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Als vollwertigen Display-Server verwenden (nicht eingebettet)"
|
||||
|
||||
#: src/core/main.c:247
|
||||
#: src/core/main.c:252
|
||||
msgid "Run with X11 backend"
|
||||
msgstr "Mit X11-Backend ausführen"
|
||||
|
||||
@ -728,21 +741,21 @@ msgstr "Version ausgeben"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Zu benutzendes Mutter-Plugin"
|
||||
|
||||
#: src/core/prefs.c:1849
|
||||
#: src/core/prefs.c:1911
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Arbeitsfläche %d"
|
||||
|
||||
#: src/core/util.c:121
|
||||
#: src/core/util.c:122
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "Mutter wurde ohne Unterstützung für den redseligen Modus kompiliert\n"
|
||||
|
||||
#: src/wayland/meta-wayland-tablet-pad.c:567
|
||||
#: src/wayland/meta-wayland-tablet-pad.c:568
|
||||
#, c-format
|
||||
msgid "Mode Switch: Mode %d"
|
||||
msgstr "Moduswechsel: Modus %d"
|
||||
|
||||
#: src/x11/meta-x11-display.c:671
|
||||
#: src/x11/meta-x11-display.c:676
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Display “%s” already has a window manager; try using the --replace option to "
|
||||
@ -751,21 +764,21 @@ msgstr ""
|
||||
"Bildschirm »%s« hat bereits einen Fensterverwalter. Versuchen Sie die Option "
|
||||
"»--replace«, um den aktuellen Fensterverwalter zu ersetzen."
|
||||
|
||||
#: src/x11/meta-x11-display.c:1032
|
||||
#: src/x11/meta-x11-display.c:1089
|
||||
msgid "Failed to initialize GDK\n"
|
||||
msgstr "GDK konnte nicht initialisiert werden\n"
|
||||
|
||||
#: src/x11/meta-x11-display.c:1056
|
||||
#: src/x11/meta-x11-display.c:1113
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display “%s”\n"
|
||||
msgstr "X-Window-Systemanzeige »%s« konnte nicht geöffnet werden\n"
|
||||
|
||||
#: src/x11/meta-x11-display.c:1140
|
||||
#: src/x11/meta-x11-display.c:1196
|
||||
#, c-format
|
||||
msgid "Screen %d on display “%s” is invalid\n"
|
||||
msgstr "Bildschirm %d auf Anzeige »%s« ist ungültig\n"
|
||||
|
||||
#: src/x11/meta-x11-selection-input-stream.c:445
|
||||
#: src/x11/meta-x11-selection-input-stream.c:460
|
||||
#, c-format
|
||||
msgid "Format %s not supported"
|
||||
msgstr "Format %s wird nicht unterstützt"
|
||||
|
167
po/sk.po
167
po/sk.po
@ -13,8 +13,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mutter\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
|
||||
"POT-Creation-Date: 2018-02-06 04:14+0000\n"
|
||||
"PO-Revision-Date: 2018-03-17 21:52+0100\n"
|
||||
"POT-Creation-Date: 2020-03-30 20:11+0000\n"
|
||||
"PO-Revision-Date: 2020-04-05 22:21+0200\n"
|
||||
"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
|
||||
"Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
|
||||
"Language: sk\n"
|
||||
@ -22,7 +22,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
|
||||
"X-Generator: Poedit 2.0.6\n"
|
||||
"X-Generator: Poedit 2.3\n"
|
||||
|
||||
#: data/50-mutter-navigation.xml:6
|
||||
msgid "Navigation"
|
||||
@ -468,29 +468,47 @@ msgid ""
|
||||
"proof. Currently possible keywords: • “scale-monitor-framebuffer” — makes "
|
||||
"mutter default to layout logical monitors in a logical pixel coordinate "
|
||||
"space, while scaling monitor framebuffers instead of window content, to "
|
||||
"manage HiDPI monitors. Does not require a restart. • “remote-desktop” — "
|
||||
"enables remote desktop support. To support remote desktop with screen "
|
||||
"sharing, “screen-cast” must also be enabled. • “screen-cast” — enables "
|
||||
"screen cast support."
|
||||
"manage HiDPI monitors. Does not require a restart. • “rt-scheduler” — makes "
|
||||
"mutter request a low priority real-time scheduling. The executable or user "
|
||||
"must have CAP_SYS_NICE. Requires a restart. • “autostart-xwayland” — "
|
||||
"initializes Xwayland lazily if there are X11 clients. Requires restart."
|
||||
msgstr ""
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:134
|
||||
msgid "Modifier to use to locate the pointer"
|
||||
msgstr "Modifikátor použitý na lokalizovanie ukazovateľa"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:135
|
||||
msgid "This key will initiate the “locate pointer” action."
|
||||
msgstr ""
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:142
|
||||
msgid "Timeout for check-alive ping"
|
||||
msgstr ""
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:143
|
||||
msgid ""
|
||||
"Number of milliseconds a client has to respond to a ping request in order to "
|
||||
"not be detected as frozen. Using 0 will disable the alive check completely."
|
||||
msgstr ""
|
||||
|
||||
# summary
|
||||
#: data/org.gnome.mutter.gschema.xml.in:145
|
||||
#: data/org.gnome.mutter.gschema.xml.in:165
|
||||
msgid "Select window from tab popup"
|
||||
msgstr "Vybrať okno z rozbaľovacej ponuky tabulátora"
|
||||
|
||||
# summary
|
||||
#: data/org.gnome.mutter.gschema.xml.in:150
|
||||
#: data/org.gnome.mutter.gschema.xml.in:170
|
||||
msgid "Cancel tab popup"
|
||||
msgstr "Zrušit rozbaľovaciu ponuku tabulátora"
|
||||
|
||||
# PK: predpokladam ze to prepisane medzi tlacidlami
|
||||
# description
|
||||
#: data/org.gnome.mutter.gschema.xml.in:155
|
||||
#: data/org.gnome.mutter.gschema.xml.in:175
|
||||
msgid "Switch monitor configurations"
|
||||
msgstr "Prepnúť nastavenia monitorov"
|
||||
|
||||
#: data/org.gnome.mutter.gschema.xml.in:160
|
||||
#: data/org.gnome.mutter.gschema.xml.in:180
|
||||
msgid "Rotates the built-in monitor configuration"
|
||||
msgstr "Otočí nastavenie vstavaného monitora"
|
||||
|
||||
@ -554,23 +572,27 @@ msgid "Re-enable shortcuts"
|
||||
msgstr "Znovu povoliť klávesové skratky"
|
||||
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:64
|
||||
msgid "Allow grabs with Xwayland"
|
||||
msgid "Allow X11 grabs to lock keyboard focus with Xwayland"
|
||||
msgstr ""
|
||||
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:65
|
||||
msgid ""
|
||||
"Allow keyboard grabs issued by X11 applications running in Xwayland to be "
|
||||
"taken into account. For a X11 grab to be taken into account under Wayland, "
|
||||
"the client must also either send a specific X11 ClientMessage to the root "
|
||||
"window or be among the applications white-listed in key “xwayland-grab-"
|
||||
"access-rules”."
|
||||
"Allow all keyboard events to be routed to X11 “override redirect” windows "
|
||||
"with a grab when running in Xwayland. This option is to support X11 clients "
|
||||
"which map an “override redirect” window (which do not receive keyboard "
|
||||
"focus) and issue a keyboard grab to force all keyboard events to that "
|
||||
"window. This option is seldom used and has no effect on regular X11 windows "
|
||||
"which can receive keyboard focus under normal circumstances. For a X11 grab "
|
||||
"to be taken into account under Wayland, the client must also either send a "
|
||||
"specific X11 ClientMessage to the root window or be among the applications "
|
||||
"white-listed in key “xwayland-grab-access-rules”."
|
||||
msgstr ""
|
||||
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:77
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:84
|
||||
msgid "Xwayland applications allowed to issue keyboard grabs"
|
||||
msgstr ""
|
||||
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:78
|
||||
#: data/org.gnome.mutter.wayland.gschema.xml.in:85
|
||||
msgid ""
|
||||
"List the resource names or resource class of X11 windows either allowed or "
|
||||
"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or "
|
||||
@ -587,7 +609,7 @@ msgstr ""
|
||||
#. TRANSLATORS: This string refers to a button that switches between
|
||||
#. * different modes.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2260
|
||||
#: src/backends/meta-input-settings.c:2631
|
||||
#, c-format
|
||||
msgid "Mode Switch (Group %d)"
|
||||
msgstr "Prepínač režimu (skupina č. %d)"
|
||||
@ -597,53 +619,61 @@ msgstr "Prepínač režimu (skupina č. %d)"
|
||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
|
||||
#. * mapping through the available outputs.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2283
|
||||
#: src/backends/meta-input-settings.c:2654
|
||||
msgid "Switch monitor"
|
||||
msgstr "Prepnúť monitor"
|
||||
|
||||
#: src/backends/meta-input-settings.c:2285
|
||||
#: src/backends/meta-input-settings.c:2656
|
||||
msgid "Show on-screen help"
|
||||
msgstr "Zobraziť pomocníka na obrazovke"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:900
|
||||
#: src/backends/meta-monitor.c:226
|
||||
msgid "Built-in display"
|
||||
msgstr "Vstavaný displej"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:923
|
||||
#: src/backends/meta-monitor.c:255
|
||||
msgid "Unknown"
|
||||
msgstr "Neznámy"
|
||||
|
||||
#: src/backends/meta-monitor-manager.c:925
|
||||
#: src/backends/meta-monitor.c:257
|
||||
msgid "Unknown Display"
|
||||
msgstr "Neznámy displej"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: src/backends/meta-monitor-manager.c:933
|
||||
#: src/backends/meta-monitor.c:265
|
||||
#, c-format
|
||||
#| msgid "%s %s"
|
||||
msgctxt ""
|
||||
"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#: src/backends/meta-monitor.c:273
|
||||
#, c-format
|
||||
#| msgid "%s %s"
|
||||
msgctxt ""
|
||||
"This is a monitor vendor name followed by product/model name where size in "
|
||||
"inches could not be calculated, e.g. Dell U2414H"
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#. Translators: this string will appear in Sysprof
|
||||
#: src/backends/meta-profiler.c:79
|
||||
msgid "Compositor"
|
||||
msgstr "Kompozítor"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: src/compositor/compositor.c:481
|
||||
#: src/compositor/compositor.c:533
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display “%s”."
|
||||
msgstr ""
|
||||
"Pre obrazovku č. %i na displeji „%s“ je spustený už iný správca rozloženia."
|
||||
|
||||
#: src/core/bell.c:194
|
||||
#: src/core/bell.c:192
|
||||
msgid "Bell event"
|
||||
msgstr "Udalosť zvončeka"
|
||||
|
||||
# X window system preloz, napr. system na spravu okien X
|
||||
#: src/core/display.c:608
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display “%s”\n"
|
||||
msgstr "Zlyhalo otvorenie displeja systému na správu okien X „%s“\n"
|
||||
|
||||
# cmd desc
|
||||
#: src/core/main.c:190
|
||||
msgid "Disable connection to session manager"
|
||||
@ -683,41 +713,45 @@ msgstr "Spustí ako kompozitor protokolu wayland"
|
||||
msgid "Run as a nested compositor"
|
||||
msgstr "Spustí ako kompozitor s vnoreným režimom"
|
||||
|
||||
#: src/core/main.c:240
|
||||
#: src/core/main.c:238
|
||||
msgid "Run wayland compositor without starting Xwayland"
|
||||
msgstr ""
|
||||
|
||||
#: src/core/main.c:246
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Spustí ako plnohodnotný zobrazovací server, namiesto vnoreného režimu"
|
||||
|
||||
#: src/core/main.c:246
|
||||
#: src/core/main.c:252
|
||||
msgid "Run with X11 backend"
|
||||
msgstr "Spustí s obslužným programom X11"
|
||||
|
||||
# %s is a window title
|
||||
#. Translators: %s is a window title
|
||||
#: src/core/meta-close-dialog-default.c:147
|
||||
#: src/core/meta-close-dialog-default.c:151
|
||||
#, c-format
|
||||
msgid "“%s” is not responding."
|
||||
msgstr "„%s“ neodpovedá."
|
||||
|
||||
#: src/core/meta-close-dialog-default.c:149
|
||||
#: src/core/meta-close-dialog-default.c:153
|
||||
msgid "Application is not responding."
|
||||
msgstr "Aplikácia neodpovedá."
|
||||
|
||||
#: src/core/meta-close-dialog-default.c:154
|
||||
#: src/core/meta-close-dialog-default.c:158
|
||||
msgid ""
|
||||
"You may choose to wait a short while for it to continue or force the "
|
||||
"application to quit entirely."
|
||||
msgstr ""
|
||||
"Môžete chvíľu počkať na pokračovanie aplikácie, alebo ju môžete ukončiť."
|
||||
|
||||
#: src/core/meta-close-dialog-default.c:161
|
||||
#: src/core/meta-close-dialog-default.c:165
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Vynútiť ukončenie"
|
||||
|
||||
#: src/core/meta-close-dialog-default.c:161
|
||||
#: src/core/meta-close-dialog-default.c:165
|
||||
msgid "_Wait"
|
||||
msgstr "_Počkať"
|
||||
|
||||
#: src/core/mutter.c:39
|
||||
#: src/core/mutter.c:38
|
||||
#, c-format
|
||||
msgid ""
|
||||
"mutter %s\n"
|
||||
@ -733,21 +767,30 @@ msgstr ""
|
||||
"Záruka sa NEPOSKYTUJE; ani na PREDAJNOSŤ alebo VHODNOSŤ PRE URČITÝ ÚČEL.\n"
|
||||
|
||||
# cmd desc
|
||||
#: src/core/mutter.c:53
|
||||
#: src/core/mutter.c:52
|
||||
msgid "Print version"
|
||||
msgstr "Zobrazí verziu"
|
||||
|
||||
# cmd desc
|
||||
#: src/core/mutter.c:59
|
||||
#: src/core/mutter.c:58
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Použije zásuvný modul Mutter"
|
||||
|
||||
#: src/core/prefs.c:1997
|
||||
#: src/core/prefs.c:1911
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Pracovný priestor č. %d"
|
||||
|
||||
#: src/core/screen.c:583
|
||||
#: src/core/util.c:122
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "Mutter bol skompilovaný bez výpisu podrobností pri behu\n"
|
||||
|
||||
#: src/wayland/meta-wayland-tablet-pad.c:568
|
||||
#, c-format
|
||||
msgid "Mode Switch: Mode %d"
|
||||
msgstr "Prepínač režimu: Režim č. %d"
|
||||
|
||||
#: src/x11/meta-x11-display.c:676
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Display “%s” already has a window manager; try using the --replace option to "
|
||||
@ -756,21 +799,27 @@ msgstr ""
|
||||
"Displej „%s“ už má správcu okien. Skúste použiť prepínač --replace, aby sa "
|
||||
"aktuálny správca nahradil."
|
||||
|
||||
#: src/core/screen.c:668
|
||||
#: src/x11/meta-x11-display.c:1089
|
||||
msgid "Failed to initialize GDK\n"
|
||||
msgstr "Zlyhala inicializácia GDK\n"
|
||||
|
||||
# X window system preloz, napr. system na spravu okien X
|
||||
#: src/x11/meta-x11-display.c:1113
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display “%s”\n"
|
||||
msgstr "Zlyhalo otvorenie displeja systému na správu okien X „%s“\n"
|
||||
|
||||
#: src/x11/meta-x11-display.c:1196
|
||||
#, c-format
|
||||
msgid "Screen %d on display “%s” is invalid\n"
|
||||
msgstr "Obrazovka č. %d na displeji „%s“ nie je platná\n"
|
||||
|
||||
#: src/core/util.c:120
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "Mutter bol skompilovaný bez výpisu podrobností pri behu\n"
|
||||
|
||||
#: src/wayland/meta-wayland-tablet-pad.c:563
|
||||
#: src/x11/meta-x11-selection-input-stream.c:460
|
||||
#, c-format
|
||||
msgid "Mode Switch: Mode %d"
|
||||
msgstr "Prepínač režimu: Režim č. %d"
|
||||
msgid "Format %s not supported"
|
||||
msgstr "Formát %s nie je podporovaný"
|
||||
|
||||
#: src/x11/session.c:1818
|
||||
#: src/x11/session.c:1821
|
||||
msgid ""
|
||||
"These windows do not support “save current setup” and will have to be "
|
||||
"restarted manually next time you log in."
|
||||
@ -779,7 +828,7 @@ msgstr ""
|
||||
"prihlásení ich budete musieť znovu spustiť ručne."
|
||||
|
||||
# window title; wm_client_machine
|
||||
#: src/x11/window-props.c:559
|
||||
#: src/x11/window-props.c:569
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (na %s)"
|
||||
|
@ -818,7 +818,7 @@ update_trackball_scroll_button (MetaInputSettings *input_settings,
|
||||
|
||||
for (l = devices; l; l = l->next)
|
||||
{
|
||||
device = devices->data;
|
||||
device = l->data;
|
||||
|
||||
if (input_settings_class->is_trackball_device (input_settings, device))
|
||||
input_settings_class->set_scroll_button (input_settings, device, button);
|
||||
|
@ -172,6 +172,7 @@ assign_monitor_crtc (MetaMonitor *monitor,
|
||||
MetaCrtc *crtc;
|
||||
MetaMonitorTransform transform;
|
||||
MetaMonitorTransform crtc_transform;
|
||||
MetaMonitorTransform crtc_hw_transform;
|
||||
int crtc_x, crtc_y;
|
||||
float x_offset, y_offset;
|
||||
float scale = 0.0;
|
||||
@ -200,10 +201,12 @@ assign_monitor_crtc (MetaMonitor *monitor,
|
||||
|
||||
transform = data->logical_monitor_config->transform;
|
||||
crtc_transform = meta_monitor_logical_to_crtc_transform (monitor, transform);
|
||||
if (!meta_monitor_manager_is_transform_handled (data->monitor_manager,
|
||||
crtc,
|
||||
crtc_transform))
|
||||
crtc_transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
if (meta_monitor_manager_is_transform_handled (data->monitor_manager,
|
||||
crtc,
|
||||
crtc_transform))
|
||||
crtc_hw_transform = crtc_transform;
|
||||
else
|
||||
crtc_hw_transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
|
||||
meta_monitor_calculate_crtc_pos (monitor, mode, output, crtc_transform,
|
||||
&crtc_x, &crtc_y);
|
||||
@ -244,7 +247,7 @@ assign_monitor_crtc (MetaMonitor *monitor,
|
||||
.crtc = crtc,
|
||||
.mode = crtc_mode,
|
||||
.layout = crtc_layout,
|
||||
.transform = crtc_transform,
|
||||
.transform = crtc_hw_transform,
|
||||
.outputs = g_ptr_array_new ()
|
||||
};
|
||||
g_ptr_array_add (crtc_info->outputs, output);
|
||||
@ -443,23 +446,35 @@ MetaMonitorsConfigKey *
|
||||
meta_create_monitors_config_key_for_current_state (MetaMonitorManager *monitor_manager)
|
||||
{
|
||||
MetaMonitorsConfigKey *config_key;
|
||||
MetaMonitorSpec *laptop_monitor_spec;
|
||||
GList *l;
|
||||
GList *monitor_specs;
|
||||
|
||||
laptop_monitor_spec = NULL;
|
||||
monitor_specs = NULL;
|
||||
for (l = monitor_manager->monitors; l; l = l->next)
|
||||
{
|
||||
MetaMonitor *monitor = l->data;
|
||||
MetaMonitorSpec *monitor_spec;
|
||||
|
||||
if (meta_monitor_is_laptop_panel (monitor) &&
|
||||
is_lid_closed (monitor_manager))
|
||||
continue;
|
||||
if (meta_monitor_is_laptop_panel (monitor))
|
||||
{
|
||||
laptop_monitor_spec = meta_monitor_get_spec (monitor);
|
||||
|
||||
if (is_lid_closed (monitor_manager))
|
||||
continue;
|
||||
}
|
||||
|
||||
monitor_spec = meta_monitor_spec_clone (meta_monitor_get_spec (monitor));
|
||||
monitor_specs = g_list_prepend (monitor_specs, monitor_spec);
|
||||
}
|
||||
|
||||
if (!monitor_specs && laptop_monitor_spec)
|
||||
{
|
||||
monitor_specs =
|
||||
g_list_prepend (NULL, meta_monitor_spec_clone (laptop_monitor_spec));
|
||||
}
|
||||
|
||||
if (!monitor_specs)
|
||||
return NULL;
|
||||
|
||||
|
@ -817,19 +817,19 @@ calculate_tile_coordinate (MetaMonitor *monitor,
|
||||
case META_MONITOR_TRANSFORM_270:
|
||||
case META_MONITOR_TRANSFORM_FLIPPED_270:
|
||||
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
|
||||
other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile)
|
||||
other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile)
|
||||
y += other_output->tile_info.tile_w;
|
||||
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
|
||||
other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile)
|
||||
other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile)
|
||||
x += other_output->tile_info.tile_h;
|
||||
break;
|
||||
case META_MONITOR_TRANSFORM_90:
|
||||
case META_MONITOR_TRANSFORM_FLIPPED_90:
|
||||
if (other_output->tile_info.loc_v_tile == output->tile_info.loc_v_tile &&
|
||||
other_output->tile_info.loc_h_tile > output->tile_info.loc_h_tile)
|
||||
other_output->tile_info.loc_h_tile < output->tile_info.loc_h_tile)
|
||||
y += other_output->tile_info.tile_w;
|
||||
if (other_output->tile_info.loc_h_tile == output->tile_info.loc_h_tile &&
|
||||
other_output->tile_info.loc_v_tile > output->tile_info.loc_v_tile)
|
||||
other_output->tile_info.loc_v_tile < output->tile_info.loc_v_tile)
|
||||
x += other_output->tile_info.tile_h;
|
||||
break;
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ struct _MetaRemoteDesktopSession
|
||||
|
||||
MetaScreenCastSession *screen_cast_session;
|
||||
gulong screen_cast_session_closed_handler_id;
|
||||
guint started : 1;
|
||||
|
||||
ClutterVirtualInputDevice *virtual_pointer;
|
||||
ClutterVirtualInputDevice *virtual_keyboard;
|
||||
@ -119,7 +120,7 @@ meta_remote_desktop_session_start (MetaRemoteDesktopSession *session,
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterSeat *seat = clutter_backend_get_default_seat (backend);
|
||||
|
||||
g_assert (!session->virtual_pointer && !session->virtual_keyboard);
|
||||
g_assert (!session->started);
|
||||
|
||||
if (session->screen_cast_session)
|
||||
{
|
||||
@ -135,6 +136,7 @@ meta_remote_desktop_session_start (MetaRemoteDesktopSession *session,
|
||||
clutter_seat_create_virtual_device (seat, CLUTTER_TOUCHSCREEN_DEVICE);
|
||||
|
||||
init_remote_access_handle (session);
|
||||
session->started = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -145,6 +147,8 @@ meta_remote_desktop_session_close (MetaRemoteDesktopSession *session)
|
||||
MetaDBusRemoteDesktopSession *skeleton =
|
||||
META_DBUS_REMOTE_DESKTOP_SESSION (session);
|
||||
|
||||
session->started = FALSE;
|
||||
|
||||
if (session->screen_cast_session)
|
||||
{
|
||||
g_clear_signal_handler (&session->screen_cast_session_closed_handler_id,
|
||||
@ -249,6 +253,37 @@ check_permission (MetaRemoteDesktopSession *session,
|
||||
g_dbus_method_invocation_get_sender (invocation)) == 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_remote_desktop_session_check_can_notify (MetaRemoteDesktopSession *session,
|
||||
GDBusMethodInvocation *invocation)
|
||||
{
|
||||
if (!session->started)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Session not started");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"No screen cast active");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_start (MetaDBusRemoteDesktopSession *skeleton,
|
||||
GDBusMethodInvocation *invocation)
|
||||
@ -256,6 +291,14 @@ handle_start (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
GError *error = NULL;
|
||||
|
||||
if (session->started)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Already started");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
@ -288,6 +331,14 @@ handle_stop (MetaDBusRemoteDesktopSession *skeleton,
|
||||
{
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
|
||||
if (!session->started)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Session not started");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
@ -312,13 +363,8 @@ handle_notify_keyboard_keycode (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
ClutterKeyState state;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
if (pressed)
|
||||
state = CLUTTER_KEY_STATE_PRESSED;
|
||||
@ -344,13 +390,8 @@ handle_notify_keyboard_keysym (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
ClutterKeyState state;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
if (pressed)
|
||||
state = CLUTTER_KEY_STATE_PRESSED;
|
||||
@ -398,13 +439,8 @@ handle_notify_pointer_button (MetaDBusRemoteDesktopSession *skeleton,
|
||||
uint32_t button;
|
||||
ClutterButtonState state;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
button = translate_to_clutter_button (button_code);
|
||||
|
||||
@ -434,13 +470,8 @@ handle_notify_pointer_axis (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
ClutterScrollFinishFlags finish_flags = CLUTTER_SCROLL_FINISHED_NONE;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
if (flags & META_REMOTE_DESKTOP_NOTIFY_AXIS_FLAGS_FINISH)
|
||||
{
|
||||
@ -487,13 +518,8 @@ handle_notify_pointer_axis_discrete (MetaDBusRemoteDesktopSession *skeleton,
|
||||
ClutterScrollDirection direction;
|
||||
int step_count;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
if (axis > 1)
|
||||
{
|
||||
@ -538,13 +564,8 @@ handle_notify_pointer_motion_relative (MetaDBusRemoteDesktopSession *skeleton,
|
||||
{
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
clutter_virtual_input_device_notify_relative_motion (session->virtual_pointer,
|
||||
CLUTTER_CURRENT_TIME,
|
||||
@ -567,21 +588,8 @@ handle_notify_pointer_motion_absolute (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaScreenCastStream *stream;
|
||||
double abs_x, abs_y;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"No screen cast active");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
||||
stream_path);
|
||||
@ -617,21 +625,8 @@ handle_notify_touch_down (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaScreenCastStream *stream;
|
||||
double abs_x, abs_y;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"No screen cast active");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
||||
stream_path);
|
||||
@ -668,21 +663,8 @@ handle_notify_touch_motion (MetaDBusRemoteDesktopSession *skeleton,
|
||||
MetaScreenCastStream *stream;
|
||||
double abs_x, abs_y;
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"No screen cast active");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
|
||||
stream_path);
|
||||
@ -714,13 +696,8 @@ handle_notify_touch_up (MetaDBusRemoteDesktopSession *skeleton,
|
||||
{
|
||||
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
|
||||
|
||||
if (!check_permission (session, invocation))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Permission denied");
|
||||
return TRUE;
|
||||
}
|
||||
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
clutter_virtual_input_device_notify_touch_up (session->virtual_touchscreen,
|
||||
CLUTTER_CURRENT_TIME,
|
||||
|
@ -160,14 +160,12 @@ meta_renderer_real_rebuild_views (MetaRenderer *renderer)
|
||||
}
|
||||
|
||||
void
|
||||
meta_renderer_set_legacy_view (MetaRenderer *renderer,
|
||||
MetaRendererView *legacy_view)
|
||||
meta_renderer_add_view (MetaRenderer *renderer,
|
||||
MetaRendererView *view)
|
||||
{
|
||||
MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer);
|
||||
|
||||
g_assert (!priv->views);
|
||||
|
||||
priv->views = g_list_append (priv->views, legacy_view);
|
||||
priv->views = g_list_append (priv->views, view);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,8 +54,8 @@ CoglRenderer * meta_renderer_create_cogl_renderer (MetaRenderer *renderer);
|
||||
|
||||
void meta_renderer_rebuild_views (MetaRenderer *renderer);
|
||||
|
||||
void meta_renderer_set_legacy_view (MetaRenderer *renderer,
|
||||
MetaRendererView *legacy_view);
|
||||
void meta_renderer_add_view (MetaRenderer *renderer,
|
||||
MetaRendererView *view);
|
||||
|
||||
META_EXPORT_TEST
|
||||
GList * meta_renderer_get_views (MetaRenderer *renderer);
|
||||
|
@ -115,9 +115,10 @@ meta_screen_cast_monitor_stream_src_get_specs (MetaScreenCastStreamSrc *src,
|
||||
}
|
||||
|
||||
static void
|
||||
stage_painted (MetaStage *stage,
|
||||
ClutterStageView *view,
|
||||
gpointer user_data)
|
||||
stage_painted (MetaStage *stage,
|
||||
ClutterStageView *view,
|
||||
ClutterPaintContext *paint_context,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data);
|
||||
|
||||
|
@ -68,6 +68,7 @@ typedef struct _MetaPipeWireSource
|
||||
{
|
||||
GSource base;
|
||||
|
||||
MetaScreenCastStreamSrc *src;
|
||||
struct pw_loop *pipewire_loop;
|
||||
} MetaPipeWireSource;
|
||||
|
||||
@ -81,6 +82,7 @@ typedef struct _MetaScreenCastStreamSrcPrivate
|
||||
struct spa_hook pipewire_core_listener;
|
||||
|
||||
gboolean is_enabled;
|
||||
gboolean emit_closed_after_dispatch;
|
||||
|
||||
struct pw_stream *pipewire_stream;
|
||||
struct spa_hook pipewire_stream_listener;
|
||||
@ -445,7 +447,8 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
|
||||
uint64_t now_us;
|
||||
|
||||
now_us = g_get_monotonic_time ();
|
||||
if (priv->last_frame_timestamp_us != 0 &&
|
||||
if (priv->video_format.max_framerate.num > 0 &&
|
||||
priv->last_frame_timestamp_us != 0 &&
|
||||
(now_us - priv->last_frame_timestamp_us <
|
||||
((1000000 * priv->video_format.max_framerate.denom) /
|
||||
priv->video_format.max_framerate.num)))
|
||||
@ -539,12 +542,6 @@ meta_screen_cast_stream_src_disable (MetaScreenCastStreamSrc *src)
|
||||
priv->is_enabled = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_stream_src_notify_closed (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
g_signal_emit (src, signals[CLOSED], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
on_stream_state_changed (void *data,
|
||||
enum pw_stream_state old,
|
||||
@ -559,7 +556,9 @@ on_stream_state_changed (void *data,
|
||||
{
|
||||
case PW_STREAM_STATE_ERROR:
|
||||
g_warning ("pipewire stream error: %s", error_message);
|
||||
meta_screen_cast_stream_src_notify_closed (src);
|
||||
if (meta_screen_cast_stream_src_is_enabled (src))
|
||||
meta_screen_cast_stream_src_disable (src);
|
||||
priv->emit_closed_after_dispatch = TRUE;
|
||||
break;
|
||||
case PW_STREAM_STATE_PAUSED:
|
||||
if (priv->node_id == SPA_ID_INVALID && priv->pipewire_stream)
|
||||
@ -827,11 +826,17 @@ on_core_error (void *data,
|
||||
const char *message)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = data;
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
|
||||
g_warning ("pipewire remote error: id:%u %s", id, message);
|
||||
|
||||
if (id == PW_ID_CORE && res == -EPIPE)
|
||||
meta_screen_cast_stream_src_notify_closed (src);
|
||||
{
|
||||
if (meta_screen_cast_stream_src_is_enabled (src))
|
||||
meta_screen_cast_stream_src_disable (src);
|
||||
priv->emit_closed_after_dispatch = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -848,12 +853,18 @@ pipewire_loop_source_dispatch (GSource *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaPipeWireSource *pipewire_source = (MetaPipeWireSource *) source;
|
||||
MetaScreenCastStreamSrc *src = pipewire_source->src;
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
int result;
|
||||
|
||||
result = pw_loop_iterate (pipewire_source->pipewire_loop, 0);
|
||||
if (result < 0)
|
||||
g_warning ("pipewire_loop_iterate failed: %s", spa_strerror (result));
|
||||
|
||||
if (priv->emit_closed_after_dispatch)
|
||||
g_signal_emit (src, signals[CLOSED], 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -875,13 +886,14 @@ static GSourceFuncs pipewire_source_funcs =
|
||||
};
|
||||
|
||||
static MetaPipeWireSource *
|
||||
create_pipewire_source (void)
|
||||
create_pipewire_source (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
MetaPipeWireSource *pipewire_source;
|
||||
|
||||
pipewire_source =
|
||||
(MetaPipeWireSource *) g_source_new (&pipewire_source_funcs,
|
||||
sizeof (MetaPipeWireSource));
|
||||
pipewire_source->src = src;
|
||||
pipewire_source->pipewire_loop = pw_loop_new (NULL);
|
||||
if (!pipewire_source->pipewire_loop)
|
||||
{
|
||||
@ -913,7 +925,7 @@ meta_screen_cast_stream_src_initable_init (GInitable *initable,
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
|
||||
priv->pipewire_source = create_pipewire_source ();
|
||||
priv->pipewire_source = create_pipewire_source (src);
|
||||
if (!priv->pipewire_source)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
@ -975,8 +987,8 @@ meta_screen_cast_stream_src_finalize (GObject *object)
|
||||
if (meta_screen_cast_stream_src_is_enabled (src))
|
||||
meta_screen_cast_stream_src_disable (src);
|
||||
|
||||
g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy);
|
||||
g_clear_pointer (&priv->pipewire_stream, pw_stream_destroy);
|
||||
g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy);
|
||||
g_clear_pointer (&priv->pipewire_core, pw_core_disconnect);
|
||||
g_clear_pointer (&priv->pipewire_context, pw_context_destroy);
|
||||
g_source_destroy (&priv->pipewire_source->base);
|
||||
|
@ -38,9 +38,10 @@ typedef enum
|
||||
META_STAGE_WATCH_AFTER_PAINT,
|
||||
} MetaStageWatchPhase;
|
||||
|
||||
typedef void (* MetaStageWatchFunc) (MetaStage *stage,
|
||||
ClutterStageView *view,
|
||||
gpointer user_data);
|
||||
typedef void (* MetaStageWatchFunc) (MetaStage *stage,
|
||||
ClutterStageView *view,
|
||||
ClutterPaintContext *paint_context,
|
||||
gpointer user_data);
|
||||
|
||||
ClutterActor *meta_stage_new (MetaBackend *backend);
|
||||
|
||||
|
@ -65,7 +65,6 @@ struct _MetaStage
|
||||
ClutterStage parent;
|
||||
|
||||
GPtrArray *watchers[N_WATCH_MODES];
|
||||
ClutterStageView *current_view;
|
||||
|
||||
GList *overlays;
|
||||
gboolean is_active;
|
||||
@ -169,6 +168,7 @@ meta_stage_finalize (GObject *object)
|
||||
static void
|
||||
notify_watchers_for_mode (MetaStage *stage,
|
||||
ClutterStageView *view,
|
||||
ClutterPaintContext *paint_context,
|
||||
MetaStageWatchPhase watch_phase)
|
||||
{
|
||||
GPtrArray *watchers;
|
||||
@ -183,7 +183,7 @@ notify_watchers_for_mode (MetaStage *stage,
|
||||
if (watch->view && view != watch->view)
|
||||
continue;
|
||||
|
||||
watch->callback (stage, view, watch->user_data);
|
||||
watch->callback (stage, view, paint_context, watch->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,20 +192,34 @@ meta_stage_paint (ClutterActor *actor,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
MetaStage *stage = META_STAGE (actor);
|
||||
ClutterStageView *view;
|
||||
GList *l;
|
||||
|
||||
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor, paint_context);
|
||||
|
||||
notify_watchers_for_mode (stage, stage->current_view,
|
||||
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
|
||||
view = clutter_paint_context_get_stage_view (paint_context);
|
||||
if (view)
|
||||
{
|
||||
notify_watchers_for_mode (stage, view, paint_context,
|
||||
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
|
||||
}
|
||||
|
||||
g_signal_emit (stage, signals[ACTORS_PAINTED], 0);
|
||||
if (!(clutter_paint_context_get_paint_flags (paint_context) &
|
||||
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL))
|
||||
g_signal_emit (stage, signals[ACTORS_PAINTED], 0);
|
||||
|
||||
for (l = stage->overlays; l; l = l->next)
|
||||
meta_overlay_paint (l->data, paint_context);
|
||||
if (!(clutter_paint_context_get_paint_flags (paint_context) &
|
||||
CLUTTER_PAINT_FLAG_NO_CURSORS))
|
||||
{
|
||||
for (l = stage->overlays; l; l = l->next)
|
||||
meta_overlay_paint (l->data, paint_context);
|
||||
}
|
||||
|
||||
notify_watchers_for_mode (stage, stage->current_view,
|
||||
META_STAGE_WATCH_AFTER_OVERLAY_PAINT);
|
||||
if (view)
|
||||
{
|
||||
notify_watchers_for_mode (stage, view, paint_context,
|
||||
META_STAGE_WATCH_AFTER_OVERLAY_PAINT);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -215,13 +229,14 @@ meta_stage_paint_view (ClutterStage *stage,
|
||||
{
|
||||
MetaStage *meta_stage = META_STAGE (stage);
|
||||
|
||||
notify_watchers_for_mode (meta_stage, view, META_STAGE_WATCH_BEFORE_PAINT);
|
||||
notify_watchers_for_mode (meta_stage, view, NULL,
|
||||
META_STAGE_WATCH_BEFORE_PAINT);
|
||||
|
||||
meta_stage->current_view = view;
|
||||
CLUTTER_STAGE_CLASS (meta_stage_parent_class)->paint_view (stage, view,
|
||||
redraw_clip);
|
||||
|
||||
notify_watchers_for_mode (meta_stage, view, META_STAGE_WATCH_AFTER_PAINT);
|
||||
notify_watchers_for_mode (meta_stage, view, NULL,
|
||||
META_STAGE_WATCH_AFTER_PAINT);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -407,13 +407,14 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
else
|
||||
scale = 1.0;
|
||||
|
||||
meta_monitor_calculate_crtc_pos (monitor, monitor_mode,
|
||||
monitor_crtc_mode->output,
|
||||
META_MONITOR_TRANSFORM_NORMAL,
|
||||
&crtc_x, &crtc_y);
|
||||
|
||||
transform = meta_logical_monitor_get_transform (data->in_logical_monitor);
|
||||
transform = meta_monitor_logical_to_crtc_transform (monitor, transform);
|
||||
|
||||
meta_monitor_calculate_crtc_pos (monitor, monitor_mode,
|
||||
monitor_crtc_mode->output,
|
||||
transform,
|
||||
&crtc_x, &crtc_y);
|
||||
|
||||
if (meta_monitor_transform_is_rotated (transform))
|
||||
{
|
||||
crtc_width = monitor_crtc_mode->crtc_mode->height;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 Red Hat
|
||||
* Copyright (C) 2019 DisplayLink (UK) Ltd.
|
||||
* Copyright (C) 2019-2020 DisplayLink (UK) Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
@ -660,6 +660,9 @@ process_page_flip (MetaKmsImpl *impl,
|
||||
meta_kms_page_flip_data_ref (page_flip_data));
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
meta_kms_page_flip_data_unref (page_flip_data);
|
||||
|
||||
if (ret == -EBUSY)
|
||||
{
|
||||
CachedModeSet *cached_mode_set;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Red Hat
|
||||
* Copyright 2020 DisplayLink (UK) Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
@ -383,6 +384,7 @@ meta_kms_add_source_in_impl (MetaKms *kms,
|
||||
simple_impl_source->kms = kms;
|
||||
|
||||
g_source_set_callback (source, func, user_data, user_data_destroy);
|
||||
g_source_set_ready_time (source, 0);
|
||||
g_source_attach (source, g_main_context_get_thread_default ());
|
||||
|
||||
return source;
|
||||
|
@ -3037,6 +3037,7 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
||||
float scale;
|
||||
int onscreen_width;
|
||||
int onscreen_height;
|
||||
MetaRectangle view_layout;
|
||||
MetaRendererView *view;
|
||||
GError *error = NULL;
|
||||
|
||||
@ -3108,8 +3109,11 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
||||
else
|
||||
scale = 1.0;
|
||||
|
||||
meta_rectangle_from_graphene_rect (&crtc->config->layout,
|
||||
META_ROUNDING_STRATEGY_ROUND,
|
||||
&view_layout);
|
||||
view = g_object_new (META_TYPE_RENDERER_VIEW,
|
||||
"layout", &logical_monitor->rect,
|
||||
"layout", &view_layout,
|
||||
"scale", scale,
|
||||
"framebuffer", onscreen,
|
||||
"offscreen", offscreen,
|
||||
|
@ -424,6 +424,9 @@ new_absolute_motion_event (MetaSeatNative *seat,
|
||||
meta_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
event->motion.x = x;
|
||||
event->motion.y = y;
|
||||
meta_input_device_native_translate_coordinates (input_device, stage,
|
||||
&event->motion.x,
|
||||
&event->motion.y);
|
||||
event->motion.axes = axes;
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
@ -1377,35 +1380,6 @@ has_touchscreen (MetaSeatNative *seat)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_external_keyboard (MetaSeatNative *seat)
|
||||
{
|
||||
GList *devices, *l;
|
||||
gboolean has_external = FALSE;
|
||||
|
||||
devices = g_udev_client_query_by_subsystem (seat->udev_client, "input");
|
||||
|
||||
for (l = devices; l; l = l->next)
|
||||
{
|
||||
if (!g_udev_device_has_property (l->data, "ID_INPUT_KEYBOARD"))
|
||||
continue;
|
||||
|
||||
/* May be "hid" or something else, we don't care. This property
|
||||
* will not be present in virtual "AT Translated Set 2 keyboard"
|
||||
* devices.
|
||||
*/
|
||||
if (!g_udev_device_has_property (l->data, "ID_TYPE"))
|
||||
break;
|
||||
|
||||
has_external = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
g_list_free_full (devices, g_object_unref);
|
||||
|
||||
return has_external;
|
||||
}
|
||||
|
||||
static void
|
||||
update_touch_mode (MetaSeatNative *seat)
|
||||
{
|
||||
@ -1418,10 +1392,10 @@ update_touch_mode (MetaSeatNative *seat)
|
||||
else if (seat->has_tablet_switch && !seat->tablet_mode_switch_state)
|
||||
touch_mode = FALSE;
|
||||
/* If tablet mode is enabled, or if there is no tablet mode switch
|
||||
* (eg. kiosk machines), check availability of external keyboards.
|
||||
* (eg. kiosk machines), assume touch-mode.
|
||||
*/
|
||||
else
|
||||
touch_mode = !seat->has_external_keyboard;
|
||||
touch_mode = TRUE;
|
||||
|
||||
if (seat->touch_mode != touch_mode)
|
||||
{
|
||||
@ -1462,12 +1436,7 @@ evdev_add_device (MetaSeatNative *seat,
|
||||
|
||||
g_signal_emit_by_name (seat, "device-added", device);
|
||||
|
||||
if (type == CLUTTER_KEYBOARD_DEVICE)
|
||||
{
|
||||
seat->has_external_keyboard = has_external_keyboard (seat);
|
||||
check_touch_mode = TRUE;
|
||||
}
|
||||
else if (type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
if (type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
{
|
||||
seat->has_touchscreen = TRUE;
|
||||
check_touch_mode = TRUE;
|
||||
@ -1500,12 +1469,7 @@ evdev_remove_device (MetaSeatNative *seat,
|
||||
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
|
||||
if (device_type == CLUTTER_KEYBOARD_DEVICE)
|
||||
{
|
||||
seat->has_external_keyboard = has_external_keyboard (seat);
|
||||
update_touch_mode (seat);
|
||||
}
|
||||
else if (device_type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
if (device_type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
{
|
||||
seat->has_touchscreen = has_touchscreen (seat);
|
||||
update_touch_mode (seat);
|
||||
@ -2550,7 +2514,6 @@ meta_seat_native_constructed (GObject *object)
|
||||
xkb_keymap_led_get_index (xkb_keymap, XKB_LED_NAME_SCROLL);
|
||||
}
|
||||
|
||||
seat->has_external_keyboard = has_external_keyboard (seat);
|
||||
seat->has_touchscreen = has_touchscreen (seat);
|
||||
update_touch_mode (seat);
|
||||
|
||||
|
@ -120,7 +120,6 @@ struct _MetaSeatNative
|
||||
|
||||
GUdevClient *udev_client;
|
||||
guint tablet_mode_switch_state : 1;
|
||||
guint has_external_keyboard : 1;
|
||||
guint has_touchscreen : 1;
|
||||
guint has_tablet_switch : 1;
|
||||
guint touch_mode : 1;
|
||||
|
@ -24,14 +24,75 @@
|
||||
|
||||
#include "backends/x11/cm/meta-renderer-x11-cm.h"
|
||||
|
||||
#include "backends/meta-renderer-view.h"
|
||||
|
||||
struct _MetaRendererX11Cm
|
||||
{
|
||||
MetaRendererX11 parent;
|
||||
|
||||
MetaRendererView *screen_view;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaRendererX11Cm, meta_renderer_x11_cm,
|
||||
META_TYPE_RENDERER_X11)
|
||||
|
||||
void
|
||||
meta_renderer_x11_cm_ensure_screen_view (MetaRendererX11Cm *renderer_x11_cm,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_rectangle_int_t view_layout;
|
||||
|
||||
if (renderer_x11_cm->screen_view)
|
||||
return;
|
||||
|
||||
view_layout = (cairo_rectangle_int_t) {
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
renderer_x11_cm->screen_view = g_object_new (META_TYPE_RENDERER_VIEW,
|
||||
"layout", &view_layout,
|
||||
NULL);
|
||||
meta_renderer_add_view (META_RENDERER (renderer_x11_cm),
|
||||
renderer_x11_cm->screen_view);
|
||||
}
|
||||
|
||||
void
|
||||
meta_renderer_x11_cm_resize (MetaRendererX11Cm *renderer_x11_cm,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_rectangle_int_t view_layout;
|
||||
|
||||
view_layout = (cairo_rectangle_int_t) {
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
|
||||
g_object_set (G_OBJECT (renderer_x11_cm->screen_view),
|
||||
"layout", &view_layout,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_renderer_x11_cm_set_onscreen (MetaRendererX11Cm *renderer_x11_cm,
|
||||
CoglOnscreen *onscreen)
|
||||
{
|
||||
g_object_set (G_OBJECT (renderer_x11_cm->screen_view),
|
||||
"framebuffer", onscreen,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_renderer_x11_cm_rebuild_views (MetaRenderer *renderer)
|
||||
{
|
||||
MetaRendererX11Cm *renderer_x11_cm = META_RENDERER_X11_CM (renderer);
|
||||
|
||||
g_return_if_fail (!meta_renderer_get_views (renderer));
|
||||
|
||||
meta_renderer_add_view (renderer, renderer_x11_cm->screen_view);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_renderer_x11_cm_init (MetaRendererX11Cm *renderer_x11_cm)
|
||||
{
|
||||
@ -40,4 +101,7 @@ meta_renderer_x11_cm_init (MetaRendererX11Cm *renderer_x11_cm)
|
||||
static void
|
||||
meta_renderer_x11_cm_class_init (MetaRendererX11CmClass *klass)
|
||||
{
|
||||
MetaRendererClass *renderer_class = META_RENDERER_CLASS (klass);
|
||||
|
||||
renderer_class->rebuild_views = meta_renderer_x11_cm_rebuild_views;
|
||||
}
|
||||
|
@ -30,4 +30,15 @@ G_DECLARE_FINAL_TYPE (MetaRendererX11Cm, meta_renderer_x11_cm,
|
||||
META, RENDERER_X11_CM,
|
||||
MetaRendererX11)
|
||||
|
||||
void meta_renderer_x11_cm_ensure_screen_view (MetaRendererX11Cm *renderer_x11_cm,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
void meta_renderer_x11_cm_resize (MetaRendererX11Cm *renderer_x11_cm,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
void meta_renderer_x11_cm_set_onscreen (MetaRendererX11Cm *renderer_x11_cm,
|
||||
CoglOnscreen *onscreen);
|
||||
|
||||
#endif /* META_RENDERER_X11_CM_H */
|
||||
|
@ -855,6 +855,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
||||
static void
|
||||
meta_backend_x11_init (MetaBackendX11 *x11)
|
||||
{
|
||||
XInitThreads ();
|
||||
}
|
||||
|
||||
Display *
|
||||
|
@ -38,7 +38,6 @@ struct _MetaInputDeviceX11
|
||||
float current_y;
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
WacomDevice *wacom_device;
|
||||
GArray *group_modes;
|
||||
#endif
|
||||
};
|
||||
@ -93,13 +92,16 @@ meta_input_device_x11_is_grouped (ClutterInputDevice *device,
|
||||
ClutterInputDevice *other_device)
|
||||
{
|
||||
#ifdef HAVE_LIBWACOM
|
||||
MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device);
|
||||
MetaInputDeviceX11 *other_device_x11 = META_INPUT_DEVICE_X11 (other_device);
|
||||
WacomDevice *wacom_device, *other_wacom_device;
|
||||
|
||||
if (device_x11->wacom_device &&
|
||||
other_device_x11->wacom_device &&
|
||||
libwacom_compare (device_x11->wacom_device,
|
||||
other_device_x11->wacom_device,
|
||||
wacom_device =
|
||||
meta_input_device_get_wacom_device (META_INPUT_DEVICE (device));
|
||||
other_wacom_device =
|
||||
meta_input_device_get_wacom_device (META_INPUT_DEVICE (other_device));
|
||||
|
||||
if (wacom_device && other_wacom_device &&
|
||||
libwacom_compare (wacom_device,
|
||||
other_wacom_device,
|
||||
WCOMPARE_NORMAL) == 0)
|
||||
return TRUE;
|
||||
#endif
|
||||
@ -122,9 +124,9 @@ meta_input_device_x11_is_grouped (ClutterInputDevice *device,
|
||||
static void
|
||||
meta_input_device_x11_finalize (GObject *object)
|
||||
{
|
||||
#ifdef HAVE_LIBWACOM
|
||||
MetaInputDeviceX11 *device_xi2 = META_INPUT_DEVICE_X11 (object);
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
if (device_xi2->group_modes)
|
||||
g_array_unref (device_xi2->group_modes);
|
||||
#endif
|
||||
@ -413,9 +415,12 @@ pad_switch_mode (ClutterInputDevice *device,
|
||||
{
|
||||
MetaInputDeviceX11 *device_x11 = META_INPUT_DEVICE_X11 (device);
|
||||
uint32_t n_buttons, n_modes, button_group, next_mode, i;
|
||||
WacomDevice *wacom_device;
|
||||
GList *switch_buttons = NULL;
|
||||
|
||||
n_buttons = libwacom_get_num_buttons (device_x11->wacom_device);
|
||||
wacom_device =
|
||||
meta_input_device_get_wacom_device (META_INPUT_DEVICE (device));
|
||||
n_buttons = libwacom_get_num_buttons (wacom_device);
|
||||
|
||||
for (i = 0; i < n_buttons; i++)
|
||||
{
|
||||
|
@ -38,7 +38,10 @@ enum
|
||||
PROP_OPCODE,
|
||||
PROP_POINTER_ID,
|
||||
PROP_KEYBOARD_ID,
|
||||
N_PROPS
|
||||
N_PROPS,
|
||||
|
||||
/* This property is overridden */
|
||||
PROP_TOUCH_MODE,
|
||||
};
|
||||
|
||||
struct _MetaSeatX11
|
||||
@ -54,6 +57,8 @@ struct _MetaSeatX11
|
||||
int pointer_id;
|
||||
int keyboard_id;
|
||||
int opcode;
|
||||
guint has_touchscreens : 1;
|
||||
guint touch_mode : 1;
|
||||
};
|
||||
|
||||
static GParamSpec *props[N_PROPS] = { 0 };
|
||||
@ -605,6 +610,20 @@ pad_passive_button_grab (ClutterInputDevice *device)
|
||||
g_free (xi_event_mask.mask);
|
||||
}
|
||||
|
||||
static void
|
||||
update_touch_mode (MetaSeatX11 *seat_x11)
|
||||
{
|
||||
gboolean touch_mode;
|
||||
|
||||
touch_mode = seat_x11->has_touchscreens;
|
||||
|
||||
if (seat_x11->touch_mode == touch_mode)
|
||||
return;
|
||||
|
||||
seat_x11->touch_mode = touch_mode;
|
||||
g_object_notify (G_OBJECT (seat_x11), "touch-mode");
|
||||
}
|
||||
|
||||
static ClutterInputDevice *
|
||||
add_device (MetaSeatX11 *seat_x11,
|
||||
ClutterBackend *backend,
|
||||
@ -635,6 +654,8 @@ add_device (MetaSeatX11 *seat_x11,
|
||||
info->attachment == seat_x11->keyboard_id))
|
||||
{
|
||||
seat_x11->devices = g_list_prepend (seat_x11->devices, device);
|
||||
seat_x11->has_touchscreens |=
|
||||
clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -663,18 +684,38 @@ add_device (MetaSeatX11 *seat_x11,
|
||||
}
|
||||
}
|
||||
|
||||
update_touch_mode (seat_x11);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_touchscreens (MetaSeatX11 *seat_x11)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = seat_x11->devices; l; l = l->next)
|
||||
{
|
||||
if (clutter_input_device_get_device_type (l->data) == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_device (MetaSeatX11 *seat_x11,
|
||||
int device_id)
|
||||
{
|
||||
ClutterInputDevice *device;
|
||||
gboolean check_touchscreens = FALSE;
|
||||
|
||||
device = g_hash_table_lookup (seat_x11->devices_by_id,
|
||||
GINT_TO_POINTER (device_id));
|
||||
|
||||
if (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
check_touchscreens = TRUE;
|
||||
|
||||
if (device != NULL)
|
||||
{
|
||||
if (seat_x11->core_pointer == device)
|
||||
@ -695,6 +736,12 @@ remove_device (MetaSeatX11 *seat_x11,
|
||||
g_hash_table_remove (seat_x11->devices_by_id,
|
||||
GINT_TO_POINTER (device_id));
|
||||
}
|
||||
|
||||
if (check_touchscreens)
|
||||
{
|
||||
seat_x11->has_touchscreens = has_touchscreens (seat_x11);
|
||||
update_touch_mode (seat_x11);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1272,6 +1319,7 @@ meta_seat_x11_set_property (GObject *object,
|
||||
case PROP_KEYBOARD_ID:
|
||||
seat_x11->keyboard_id = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_TOUCH_MODE:
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -1296,6 +1344,9 @@ meta_seat_x11_get_property (GObject *object,
|
||||
case PROP_KEYBOARD_ID:
|
||||
g_value_set_int (value, seat_x11->keyboard_id);
|
||||
break;
|
||||
case PROP_TOUCH_MODE:
|
||||
g_value_set_boolean (value, seat_x11->touch_mode);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -1547,6 +1598,9 @@ meta_seat_x11_class_init (MetaSeatX11Class *klass)
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, props);
|
||||
|
||||
g_object_class_override_property (object_class, PROP_TOUCH_MODE,
|
||||
"touch-mode");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -26,15 +26,17 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "backends/x11/cm/meta-backend-x11-cm.h"
|
||||
#include "backends/x11/cm/meta-renderer-x11-cm.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "backends/x11/meta-seat-x11.h"
|
||||
#include "backends/x11/meta-stage-x11.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "clutter/x11/clutter-x11.h"
|
||||
#include "clutter/x11/clutter-backend-x11.h"
|
||||
#include "cogl/cogl.h"
|
||||
#include "core/display-private.h"
|
||||
#include "meta/meta-x11-errors.h"
|
||||
#include "meta-backend-x11.h"
|
||||
#include "meta-seat-x11.h"
|
||||
#include "meta-stage-x11.h"
|
||||
|
||||
#define STAGE_X11_IS_MAPPED(s) ((((MetaStageX11 *) (s))->wm_state & STAGE_X11_WITHDRAWN) == 0)
|
||||
|
||||
@ -287,8 +289,6 @@ meta_stage_x11_unrealize (ClutterStageWindow *stage_window)
|
||||
|
||||
clutter_stage_window_parent_iface->unrealize (stage_window);
|
||||
|
||||
g_list_free (stage_x11->legacy_views);
|
||||
g_clear_object (&stage_x11->legacy_view);
|
||||
g_clear_pointer (&stage_x11->onscreen, cogl_object_unref);
|
||||
}
|
||||
|
||||
@ -330,10 +330,13 @@ meta_stage_x11_realize (ClutterStageWindow *stage_window)
|
||||
stage_cogl,
|
||||
NULL);
|
||||
|
||||
if (stage_x11->legacy_view)
|
||||
g_object_set (G_OBJECT (stage_x11->legacy_view),
|
||||
"framebuffer", stage_x11->onscreen,
|
||||
NULL);
|
||||
if (META_IS_BACKEND_X11_CM (stage_x11->backend))
|
||||
{
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (stage_x11->backend);
|
||||
MetaRendererX11Cm *renderer_x11_cm = META_RENDERER_X11_CM (renderer);
|
||||
|
||||
meta_renderer_x11_cm_set_onscreen (renderer_x11_cm, stage_x11->onscreen);
|
||||
}
|
||||
|
||||
/* We just created a window of the size of the actor. No need to fix
|
||||
the size of the stage, just update it. */
|
||||
@ -522,34 +525,13 @@ meta_stage_x11_can_clip_redraws (ClutterStageWindow *stage_window)
|
||||
return stage_x11->clipped_redraws_cool_off == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_legacy_view (ClutterStageWindow *stage_window)
|
||||
{
|
||||
MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window);
|
||||
cairo_rectangle_int_t view_layout;
|
||||
CoglFramebuffer *framebuffer;
|
||||
|
||||
if (stage_x11->legacy_view)
|
||||
return;
|
||||
|
||||
_clutter_stage_window_get_geometry (stage_window, &view_layout);
|
||||
framebuffer = COGL_FRAMEBUFFER (stage_x11->onscreen);
|
||||
stage_x11->legacy_view = g_object_new (CLUTTER_TYPE_STAGE_VIEW_COGL,
|
||||
"layout", &view_layout,
|
||||
"framebuffer", framebuffer,
|
||||
NULL);
|
||||
stage_x11->legacy_views = g_list_append (stage_x11->legacy_views,
|
||||
stage_x11->legacy_view);
|
||||
}
|
||||
|
||||
static GList *
|
||||
meta_stage_x11_get_views (ClutterStageWindow *stage_window)
|
||||
{
|
||||
MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window);
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (stage_x11->backend);
|
||||
|
||||
ensure_legacy_view (stage_window);
|
||||
|
||||
return stage_x11->legacy_views;
|
||||
return meta_renderer_get_views (renderer);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
@ -581,6 +563,9 @@ meta_stage_x11_class_init (MetaStageX11Class *klass)
|
||||
static void
|
||||
meta_stage_x11_init (MetaStageX11 *stage)
|
||||
{
|
||||
MetaRenderer *renderer;
|
||||
MetaRendererX11Cm *renderer_x11_cm;
|
||||
|
||||
stage->xwin = None;
|
||||
stage->xwin_width = 640;
|
||||
stage->xwin_height = 480;
|
||||
@ -591,6 +576,19 @@ meta_stage_x11_init (MetaStageX11 *stage)
|
||||
stage->accept_focus = TRUE;
|
||||
|
||||
stage->title = NULL;
|
||||
|
||||
stage->backend = meta_get_backend ();
|
||||
g_assert (stage->backend);
|
||||
|
||||
if (META_IS_BACKEND_X11_CM (stage->backend))
|
||||
{
|
||||
renderer = meta_backend_get_renderer (stage->backend);
|
||||
renderer_x11_cm = META_RENDERER_X11_CM (renderer);
|
||||
|
||||
meta_renderer_x11_cm_ensure_screen_view (renderer_x11_cm,
|
||||
stage->xwin_width,
|
||||
stage->xwin_height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -778,16 +776,16 @@ meta_stage_x11_translate_event (MetaStageX11 *stage_x11,
|
||||
* X11 compositing manager, we need to reset the legacy
|
||||
* stage view, now that it has a new size.
|
||||
*/
|
||||
if (stage_x11->legacy_view)
|
||||
if (META_IS_BACKEND_X11_CM (stage_x11->backend))
|
||||
{
|
||||
cairo_rectangle_int_t view_layout = {
|
||||
.width = stage_width,
|
||||
.height = stage_height
|
||||
};
|
||||
MetaBackend *backend = stage_x11->backend;
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
MetaRendererX11Cm *renderer_x11_cm =
|
||||
META_RENDERER_X11_CM (renderer);
|
||||
|
||||
g_object_set (G_OBJECT (stage_x11->legacy_view),
|
||||
"layout", &view_layout,
|
||||
NULL);
|
||||
meta_renderer_x11_cm_resize (renderer_x11_cm,
|
||||
stage_width,
|
||||
stage_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "clutter/x11/clutter-x11.h"
|
||||
|
||||
@ -51,14 +52,13 @@ struct _MetaStageX11
|
||||
{
|
||||
ClutterStageCogl parent_instance;
|
||||
|
||||
MetaBackend *backend;
|
||||
|
||||
CoglOnscreen *onscreen;
|
||||
Window xwin;
|
||||
gint xwin_width;
|
||||
gint xwin_height; /* FIXME target_width / height */
|
||||
|
||||
ClutterStageView *legacy_view;
|
||||
GList *legacy_views;
|
||||
|
||||
CoglFrameClosure *frame_closure;
|
||||
|
||||
gchar *title;
|
||||
|
@ -167,7 +167,8 @@ meta_renderer_x11_nested_ensure_legacy_view (MetaRendererX11Nested *renderer_x11
|
||||
"framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
|
||||
NULL);
|
||||
|
||||
meta_renderer_set_legacy_view (renderer, legacy_view);
|
||||
g_assert (!meta_renderer_get_views (renderer));
|
||||
meta_renderer_add_view (renderer, legacy_view);
|
||||
}
|
||||
|
||||
static MetaRendererView *
|
||||
|
@ -63,7 +63,6 @@
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "cogl/cogl.h"
|
||||
#include "compositor/meta-window-actor-x11.h"
|
||||
#include "compositor/meta-window-actor-wayland.h"
|
||||
#include "compositor/meta-window-actor-private.h"
|
||||
#include "compositor/meta-window-group-private.h"
|
||||
#include "core/display-private.h"
|
||||
@ -82,6 +81,7 @@
|
||||
#include "x11/meta-x11-display-private.h"
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "compositor/meta-window-actor-wayland.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#endif
|
||||
|
||||
|
@ -85,6 +85,8 @@ struct _MetaWindowActorX11
|
||||
cairo_region_t *shape_region;
|
||||
/* The region we should clip to when painting the shadow */
|
||||
cairo_region_t *shadow_clip;
|
||||
/* The frame region */
|
||||
cairo_region_t *frame_bounds;
|
||||
|
||||
/* Extracted size-invariant shape used for shadows */
|
||||
MetaWindowShape *shadow_shape;
|
||||
@ -702,11 +704,8 @@ set_clip_region_beneath (MetaWindowActorX11 *actor_x11,
|
||||
|
||||
if (clip_shadow_under_window (actor_x11))
|
||||
{
|
||||
cairo_region_t *frame_bounds;
|
||||
|
||||
frame_bounds = meta_window_get_frame_bounds (window);
|
||||
if (frame_bounds)
|
||||
cairo_region_subtract (actor_x11->shadow_clip, frame_bounds);
|
||||
if (actor_x11->frame_bounds)
|
||||
cairo_region_subtract (actor_x11->shadow_clip, actor_x11->frame_bounds);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1126,6 +1125,17 @@ update_opaque_region (MetaWindowActorX11 *actor_x11)
|
||||
cairo_region_destroy (opaque_region);
|
||||
}
|
||||
|
||||
static void
|
||||
update_frame_bounds (MetaWindowActorX11 *actor_x11)
|
||||
{
|
||||
MetaWindow *window =
|
||||
meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11));
|
||||
|
||||
g_clear_pointer (&actor_x11->frame_bounds, cairo_region_destroy);
|
||||
actor_x11->frame_bounds =
|
||||
cairo_region_copy (meta_window_get_frame_bounds (window));
|
||||
}
|
||||
|
||||
static void
|
||||
update_regions (MetaWindowActorX11 *actor_x11)
|
||||
{
|
||||
@ -1197,6 +1207,7 @@ handle_updates (MetaWindowActorX11 *actor_x11)
|
||||
if (!meta_surface_actor_is_visible (surface))
|
||||
return;
|
||||
|
||||
update_frame_bounds (actor_x11);
|
||||
check_needs_reshape (actor_x11);
|
||||
check_needs_shadow (actor_x11);
|
||||
}
|
||||
@ -1250,15 +1261,13 @@ meta_window_actor_x11_paint (ClutterActor *actor,
|
||||
*/
|
||||
if (!clip && clip_shadow_under_window (actor_x11))
|
||||
{
|
||||
cairo_region_t *frame_bounds;
|
||||
cairo_rectangle_int_t bounds;
|
||||
|
||||
get_shadow_bounds (actor_x11, appears_focused, &bounds);
|
||||
clip = cairo_region_create_rectangle (&bounds);
|
||||
|
||||
frame_bounds = meta_window_get_frame_bounds (window);
|
||||
if (frame_bounds)
|
||||
cairo_region_subtract (clip, frame_bounds);
|
||||
if (actor_x11->frame_bounds)
|
||||
cairo_region_subtract (clip, actor_x11->frame_bounds);
|
||||
}
|
||||
|
||||
framebuffer = clutter_paint_context_get_framebuffer (paint_context);
|
||||
@ -1545,6 +1554,7 @@ meta_window_actor_x11_dispose (GObject *object)
|
||||
|
||||
g_clear_pointer (&actor_x11->shape_region, cairo_region_destroy);
|
||||
g_clear_pointer (&actor_x11->shadow_clip, cairo_region_destroy);
|
||||
g_clear_pointer (&actor_x11->frame_bounds, cairo_region_destroy);
|
||||
|
||||
g_clear_pointer (&actor_x11->shadow_class, g_free);
|
||||
g_clear_pointer (&actor_x11->focused_shadow, meta_shadow_unref);
|
||||
|
@ -1300,6 +1300,7 @@ meta_window_actor_blit_to_framebuffer (MetaScreenCastWindow *screen_cast_window,
|
||||
cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
|
||||
cogl_framebuffer_clear (framebuffer, COGL_BUFFER_BIT_COLOR, &clear_color);
|
||||
cogl_framebuffer_orthographic (framebuffer, 0, 0, width, height, 0, 1.0);
|
||||
cogl_framebuffer_set_viewport (framebuffer, 0, 0, width, height);
|
||||
|
||||
meta_rectangle_scale_double (bounds, resource_scale,
|
||||
META_ROUNDING_STRATEGY_GROW,
|
||||
|
@ -2129,7 +2129,7 @@ process_special_modifier_key (MetaDisplay *display,
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->type == CLUTTER_KEY_PRESS &&
|
||||
(event->modifier_state & ~(IGNORED_MODIFIERS)) == 0 &&
|
||||
((event->modifier_state & ~(IGNORED_MODIFIERS)) & CLUTTER_MODIFIER_MASK) == 0 &&
|
||||
resolved_key_combo_has_keycode (resolved_key_combo,
|
||||
event->hardware_keycode))
|
||||
{
|
||||
|
32
src/core/meta-selection-private.h
Normal file
32
src/core/meta-selection-private.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Red Hat
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Written by:
|
||||
* Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_SELECTION_PRIVATE_H
|
||||
#define META_SELECTION_PRIVATE_H
|
||||
|
||||
#include "meta/meta-selection.h"
|
||||
|
||||
MetaSelectionSource *
|
||||
meta_selection_get_current_owner (MetaSelection *selection,
|
||||
MetaSelectionType selection_type);
|
||||
|
||||
#endif /* META_SELECTION_PRIVATE_H */
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "core/meta-selection-private.h"
|
||||
#include "meta/meta-selection.h"
|
||||
|
||||
typedef struct TransferRequest TransferRequest;
|
||||
@ -50,6 +51,9 @@ static guint signals[N_SIGNALS] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (MetaSelection, meta_selection, G_TYPE_OBJECT)
|
||||
|
||||
static void read_selection_source_async (GTask *task,
|
||||
TransferRequest *request);
|
||||
|
||||
static void
|
||||
meta_selection_dispose (GObject *object)
|
||||
{
|
||||
@ -216,6 +220,7 @@ write_cb (GOutputStream *stream,
|
||||
GAsyncResult *result,
|
||||
GTask *task)
|
||||
{
|
||||
TransferRequest *request;
|
||||
GError *error = NULL;
|
||||
|
||||
g_output_stream_write_bytes_finish (stream, result, &error);
|
||||
@ -226,8 +231,17 @@ write_cb (GOutputStream *stream,
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_return_boolean (task, TRUE);
|
||||
g_object_unref (task);
|
||||
request = g_task_get_task_data (task);
|
||||
|
||||
if (request->len > 0)
|
||||
{
|
||||
read_selection_source_async (task, request);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_boolean (task, TRUE);
|
||||
g_object_unref (task);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -246,8 +260,26 @@ read_cb (GInputStream *stream,
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
else if (g_bytes_get_size (bytes) == 0)
|
||||
{
|
||||
g_task_return_boolean (task, TRUE);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
request = g_task_get_task_data (task);
|
||||
|
||||
if (request->len < g_bytes_get_size (bytes))
|
||||
{
|
||||
GBytes *copy;
|
||||
|
||||
/* Trim content */
|
||||
copy = g_bytes_new_from_bytes (bytes, 0, request->len);
|
||||
g_bytes_unref (bytes);
|
||||
bytes = copy;
|
||||
}
|
||||
|
||||
request->len -= g_bytes_get_size (bytes);
|
||||
g_output_stream_write_bytes_async (request->ostream,
|
||||
bytes,
|
||||
G_PRIORITY_DEFAULT,
|
||||
@ -257,6 +289,18 @@ read_cb (GInputStream *stream,
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
static void
|
||||
read_selection_source_async (GTask *task,
|
||||
TransferRequest *request)
|
||||
{
|
||||
g_input_stream_read_bytes_async (request->istream,
|
||||
(gsize) request->len,
|
||||
G_PRIORITY_DEFAULT,
|
||||
g_task_get_cancellable (task),
|
||||
(GAsyncReadyCallback) read_cb,
|
||||
task);
|
||||
}
|
||||
|
||||
static void
|
||||
source_read_cb (MetaSelectionSource *source,
|
||||
GAsyncResult *result,
|
||||
@ -290,12 +334,7 @@ source_read_cb (MetaSelectionSource *source,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_input_stream_read_bytes_async (request->istream,
|
||||
(gsize) request->len,
|
||||
G_PRIORITY_DEFAULT,
|
||||
g_task_get_cancellable (task),
|
||||
(GAsyncReadyCallback) read_cb,
|
||||
task);
|
||||
read_selection_source_async (task, request);
|
||||
}
|
||||
}
|
||||
|
||||
@ -364,3 +403,13 @@ meta_selection_transfer_finish (MetaSelection *selection,
|
||||
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
||||
|
||||
MetaSelectionSource *
|
||||
meta_selection_get_current_owner (MetaSelection *selection,
|
||||
MetaSelectionType selection_type)
|
||||
{
|
||||
g_return_val_if_fail (META_IS_SELECTION (selection), NULL);
|
||||
g_return_val_if_fail (selection_type < META_N_SELECTION_TYPES, NULL);
|
||||
|
||||
return selection->owners[selection_type];
|
||||
}
|
||||
|
@ -3751,6 +3751,8 @@ meta_window_activate_full (MetaWindow *window,
|
||||
meta_window_focus (window, timestamp);
|
||||
else
|
||||
meta_workspace_activate_with_focus (window->workspace, window, timestamp);
|
||||
|
||||
meta_window_check_alive (window, timestamp);
|
||||
}
|
||||
|
||||
/* This function exists since most of the functionality in window_activate
|
||||
@ -4790,8 +4792,6 @@ meta_window_focus (MetaWindow *window,
|
||||
return;
|
||||
}
|
||||
|
||||
meta_window_check_alive (window, timestamp);
|
||||
|
||||
META_WINDOW_GET_CLASS (window)->focus (window, timestamp);
|
||||
|
||||
if (window->display->event_route == META_EVENT_ROUTE_NORMAL)
|
||||
@ -8349,6 +8349,7 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
|
||||
"Focusing %s due to button %u press (display.c)\n",
|
||||
window->desc, button);
|
||||
meta_window_focus (window, event->any.time);
|
||||
meta_window_check_alive (window, event->any.time);
|
||||
}
|
||||
else
|
||||
/* However, do allow terminals to lose focus due to new
|
||||
|
@ -67,6 +67,9 @@ on_timeout (gpointer data)
|
||||
}
|
||||
else if (test_num == 2)
|
||||
{
|
||||
ClutterActorBox over_actor_box =
|
||||
CLUTTER_ACTOR_BOX_INIT (0, 0, STAGE_WIDTH, STAGE_HEIGHT);
|
||||
|
||||
/* Make the actor visible but set a clip so that only some
|
||||
of the actors are accessible */
|
||||
clutter_actor_show (over_actor);
|
||||
@ -76,6 +79,11 @@ on_timeout (gpointer data)
|
||||
state->actor_width * (ACTORS_X - 4),
|
||||
state->actor_height * (ACTORS_Y - 4));
|
||||
|
||||
/* Only allocated actors can be picked, so force an allocation
|
||||
* of the overlay actor here.
|
||||
*/
|
||||
clutter_actor_allocate (over_actor, &over_actor_box, 0);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("Clipped covering actor:\n");
|
||||
}
|
||||
@ -175,10 +183,10 @@ actor_pick (void)
|
||||
for (y = 0; y < ACTORS_Y; y++)
|
||||
for (x = 0; x < ACTORS_X; x++)
|
||||
{
|
||||
ClutterColor color = { x * 255 / (ACTORS_X - 1),
|
||||
y * 255 / (ACTORS_Y - 1),
|
||||
128, 255 };
|
||||
ClutterActor *rect = clutter_rectangle_new_with_color (&color);
|
||||
ClutterColor color = { x * 255 / (ACTORS_X - 1),
|
||||
y * 255 / (ACTORS_Y - 1),
|
||||
128, 255 };
|
||||
ClutterActor *rect = clutter_rectangle_new_with_color (&color);
|
||||
|
||||
clutter_actor_set_position (rect,
|
||||
x * state.actor_width,
|
||||
@ -187,9 +195,9 @@ actor_pick (void)
|
||||
state.actor_width,
|
||||
state.actor_height);
|
||||
|
||||
clutter_actor_add_child (state.stage, rect);
|
||||
clutter_actor_add_child (state.stage, rect);
|
||||
|
||||
state.actors[y * ACTORS_X + x] = rect;
|
||||
state.actors[y * ACTORS_X + x] = rect;
|
||||
}
|
||||
|
||||
clutter_actor_show (state.stage);
|
||||
|
23
src/tests/monitor-configs/lid-scale.xml
Normal file
23
src/tests/monitor-configs/lid-scale.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<monitors version="2">
|
||||
<configuration>
|
||||
<logicalmonitor>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<primary>yes</primary>
|
||||
<scale>2</scale>
|
||||
<monitor>
|
||||
<monitorspec>
|
||||
<connector>eDP-1</connector>
|
||||
<vendor>MetaProduct's Inc.</vendor>
|
||||
<product>MetaMonitor</product>
|
||||
<serial>0x123456</serial>
|
||||
</monitorspec>
|
||||
<mode>
|
||||
<width>1920</width>
|
||||
<height>1080</height>
|
||||
<rate>60.000495910644531</rate>
|
||||
</mode>
|
||||
</monitor>
|
||||
</logicalmonitor>
|
||||
</configuration>
|
||||
</monitors>
|
@ -2868,6 +2868,116 @@ meta_test_monitor_lid_closed_with_hotplugged_external (void)
|
||||
check_monitor_configuration (&test_case);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_test_monitor_lid_scaled_closed_opened (void)
|
||||
{
|
||||
MonitorTestCase test_case = {
|
||||
.setup = {
|
||||
.modes = {
|
||||
{
|
||||
.width = 1920,
|
||||
.height = 1080,
|
||||
.refresh_rate = 60.000495910644531
|
||||
}
|
||||
},
|
||||
.n_modes = 1,
|
||||
.outputs = {
|
||||
{
|
||||
.crtc = 0,
|
||||
.modes = { 0 },
|
||||
.n_modes = 1,
|
||||
.preferred_mode = 0,
|
||||
.possible_crtcs = { 0 },
|
||||
.n_possible_crtcs = 1,
|
||||
.width_mm = 222,
|
||||
.height_mm = 125,
|
||||
.is_laptop_panel = TRUE
|
||||
},
|
||||
},
|
||||
.n_outputs = 1,
|
||||
.crtcs = {
|
||||
{
|
||||
.current_mode = 0
|
||||
},
|
||||
},
|
||||
.n_crtcs = 1
|
||||
},
|
||||
|
||||
.expect = {
|
||||
.monitors = {
|
||||
{
|
||||
.outputs = { 0 },
|
||||
.n_outputs = 1,
|
||||
.modes = {
|
||||
{
|
||||
.width = 1920,
|
||||
.height = 1080,
|
||||
.refresh_rate = 60.000495910644531,
|
||||
.crtc_modes = {
|
||||
{
|
||||
.output = 0,
|
||||
.crtc_mode = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
.n_modes = 1,
|
||||
.current_mode = 0,
|
||||
.width_mm = 222,
|
||||
.height_mm = 125,
|
||||
}
|
||||
},
|
||||
.n_monitors = 1,
|
||||
.logical_monitors = {
|
||||
{
|
||||
.monitors = { 0 },
|
||||
.n_monitors = 1,
|
||||
.layout = { .x = 0, .y = 0, .width = 960, .height = 540 },
|
||||
.scale = 2
|
||||
}
|
||||
},
|
||||
.n_logical_monitors = 1,
|
||||
.primary_logical_monitor = 0,
|
||||
.n_outputs = 1,
|
||||
.crtcs = {
|
||||
{
|
||||
.current_mode = 0,
|
||||
}
|
||||
},
|
||||
.n_crtcs = 1,
|
||||
.n_tiled_monitors = 0,
|
||||
.screen_width = 960,
|
||||
.screen_height = 540
|
||||
}
|
||||
};
|
||||
MetaMonitorTestSetup *test_setup;
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
|
||||
if (!meta_is_stage_views_enabled ())
|
||||
{
|
||||
g_test_skip ("Not using stage views");
|
||||
return;
|
||||
}
|
||||
|
||||
test_setup = create_monitor_test_setup (&test_case,
|
||||
MONITOR_TEST_FLAG_NONE);
|
||||
set_custom_monitor_config ("lid-scale.xml");
|
||||
emulate_hotplug (test_setup);
|
||||
check_monitor_configuration (&test_case);
|
||||
|
||||
meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), TRUE);
|
||||
meta_monitor_manager_lid_is_closed_changed (monitor_manager);
|
||||
|
||||
check_monitor_configuration (&test_case);
|
||||
|
||||
meta_backend_test_set_is_lid_closed (META_BACKEND_TEST (backend), FALSE);
|
||||
meta_monitor_manager_lid_is_closed_changed (monitor_manager);
|
||||
|
||||
check_monitor_configuration (&test_case);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_test_monitor_no_outputs (void)
|
||||
{
|
||||
@ -4828,12 +4938,13 @@ meta_test_monitor_custom_second_rotated_tiled_config (void)
|
||||
.current_mode = 1,
|
||||
.transform = META_MONITOR_TRANSFORM_90,
|
||||
.x = 1024,
|
||||
.y = 400,
|
||||
.y = 0,
|
||||
},
|
||||
{
|
||||
.current_mode = 1,
|
||||
.transform = META_MONITOR_TRANSFORM_90,
|
||||
.x = 1024,
|
||||
.y = 400,
|
||||
}
|
||||
},
|
||||
.n_crtcs = 3,
|
||||
@ -4859,6 +4970,198 @@ meta_test_monitor_custom_second_rotated_tiled_config (void)
|
||||
check_monitor_configuration (&test_case);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_test_monitor_custom_second_rotated_nonnative_tiled_config (void)
|
||||
{
|
||||
MonitorTestCase test_case = {
|
||||
.setup = {
|
||||
.modes = {
|
||||
{
|
||||
.width = 1024,
|
||||
.height = 768,
|
||||
.refresh_rate = 60.000495910644531
|
||||
},
|
||||
{
|
||||
.width = 400,
|
||||
.height = 600,
|
||||
.refresh_rate = 60.000495910644531
|
||||
}
|
||||
},
|
||||
.n_modes = 2,
|
||||
.outputs = {
|
||||
{
|
||||
.crtc = 0,
|
||||
.modes = { 0 },
|
||||
.n_modes = 1,
|
||||
.preferred_mode = 0,
|
||||
.possible_crtcs = { 0 },
|
||||
.n_possible_crtcs = 1,
|
||||
.width_mm = 222,
|
||||
.height_mm = 125,
|
||||
},
|
||||
{
|
||||
.crtc = -1,
|
||||
.modes = { 1 },
|
||||
.n_modes = 1,
|
||||
.preferred_mode = 1,
|
||||
.possible_crtcs = { 1, 2 },
|
||||
.n_possible_crtcs = 2,
|
||||
.width_mm = 222,
|
||||
.height_mm = 125,
|
||||
.tile_info = {
|
||||
.group_id = 1,
|
||||
.max_h_tiles = 2,
|
||||
.max_v_tiles = 1,
|
||||
.loc_h_tile = 0,
|
||||
.loc_v_tile = 0,
|
||||
.tile_w = 400,
|
||||
.tile_h = 600
|
||||
}
|
||||
},
|
||||
{
|
||||
.crtc = -1,
|
||||
.modes = { 1 },
|
||||
.n_modes = 1,
|
||||
.preferred_mode = 1,
|
||||
.possible_crtcs = { 1, 2 },
|
||||
.n_possible_crtcs = 2,
|
||||
.width_mm = 222,
|
||||
.height_mm = 125,
|
||||
.tile_info = {
|
||||
.group_id = 1,
|
||||
.max_h_tiles = 2,
|
||||
.max_v_tiles = 1,
|
||||
.loc_h_tile = 1,
|
||||
.loc_v_tile = 0,
|
||||
.tile_w = 400,
|
||||
.tile_h = 600
|
||||
}
|
||||
}
|
||||
},
|
||||
.n_outputs = 3,
|
||||
.crtcs = {
|
||||
{
|
||||
.current_mode = -1
|
||||
},
|
||||
{
|
||||
.current_mode = -1
|
||||
},
|
||||
{
|
||||
.current_mode = -1
|
||||
}
|
||||
},
|
||||
.n_crtcs = 3
|
||||
},
|
||||
|
||||
.expect = {
|
||||
.monitors = {
|
||||
{
|
||||
.outputs = { 0 },
|
||||
.n_outputs = 1,
|
||||
.modes = {
|
||||
{
|
||||
.width = 1024,
|
||||
.height = 768,
|
||||
.refresh_rate = 60.000495910644531,
|
||||
.crtc_modes = {
|
||||
{
|
||||
.output = 0,
|
||||
.crtc_mode = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
.n_modes = 1,
|
||||
.current_mode = 0,
|
||||
.width_mm = 222,
|
||||
.height_mm = 125,
|
||||
},
|
||||
{
|
||||
.outputs = { 1, 2 },
|
||||
.n_outputs = 2,
|
||||
.modes = {
|
||||
{
|
||||
.width = 800,
|
||||
.height = 600,
|
||||
.refresh_rate = 60.000495910644531,
|
||||
.crtc_modes = {
|
||||
{
|
||||
.output = 1,
|
||||
.crtc_mode = 1,
|
||||
},
|
||||
{
|
||||
.output = 2,
|
||||
.crtc_mode = 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
.n_modes = 1,
|
||||
.current_mode = 0,
|
||||
.width_mm = 222,
|
||||
.height_mm = 125,
|
||||
}
|
||||
},
|
||||
.n_monitors = 2,
|
||||
.logical_monitors = {
|
||||
{
|
||||
.monitors = { 0 },
|
||||
.n_monitors = 1,
|
||||
.layout = { .x = 0, .y = 256, .width = 1024, .height = 768 },
|
||||
.scale = 1
|
||||
},
|
||||
{
|
||||
.monitors = { 1 },
|
||||
.n_monitors = 1,
|
||||
.layout = { .x = 1024, .y = 0, .width = 600, .height = 800 },
|
||||
.scale = 1,
|
||||
.transform = META_MONITOR_TRANSFORM_90
|
||||
}
|
||||
},
|
||||
.n_logical_monitors = 2,
|
||||
.primary_logical_monitor = 0,
|
||||
.n_outputs = 3,
|
||||
.crtcs = {
|
||||
{
|
||||
.current_mode = 0,
|
||||
.y = 256,
|
||||
},
|
||||
{
|
||||
.current_mode = 1,
|
||||
.transform = META_MONITOR_TRANSFORM_NORMAL,
|
||||
.x = 1024,
|
||||
.y = 0,
|
||||
},
|
||||
{
|
||||
.current_mode = 1,
|
||||
.transform = META_MONITOR_TRANSFORM_NORMAL,
|
||||
.x = 1024,
|
||||
.y = 400,
|
||||
}
|
||||
},
|
||||
.n_crtcs = 3,
|
||||
.n_tiled_monitors = 1,
|
||||
.screen_width = 1024 + 600,
|
||||
.screen_height = 1024
|
||||
}
|
||||
};
|
||||
MetaMonitorTestSetup *test_setup;
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
MetaMonitorManagerTest *monitor_manager_test =
|
||||
META_MONITOR_MANAGER_TEST (monitor_manager);
|
||||
|
||||
meta_monitor_manager_test_set_handles_transforms (monitor_manager_test,
|
||||
FALSE);
|
||||
|
||||
test_setup = create_monitor_test_setup (&test_case,
|
||||
MONITOR_TEST_FLAG_NONE);
|
||||
set_custom_monitor_config ("second-rotated-tiled.xml");
|
||||
emulate_hotplug (test_setup);
|
||||
check_monitor_configuration (&test_case);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_test_monitor_custom_second_rotated_nonnative_config (void)
|
||||
{
|
||||
@ -6058,6 +6361,8 @@ init_monitor_tests (void)
|
||||
meta_test_monitor_lid_closed_no_external);
|
||||
add_monitor_test ("/backends/monitor/lid-closed-with-hotplugged-external",
|
||||
meta_test_monitor_lid_closed_with_hotplugged_external);
|
||||
add_monitor_test ("/backends/monitor/lid-scaled-closed-opened",
|
||||
meta_test_monitor_lid_scaled_closed_opened);
|
||||
add_monitor_test ("/backends/monitor/no-outputs",
|
||||
meta_test_monitor_no_outputs);
|
||||
add_monitor_test ("/backends/monitor/underscanning-config",
|
||||
@ -6093,6 +6398,8 @@ init_monitor_tests (void)
|
||||
meta_test_monitor_custom_second_rotated_config);
|
||||
add_monitor_test ("/backends/monitor/custom/second-rotated-tiled-config",
|
||||
meta_test_monitor_custom_second_rotated_tiled_config);
|
||||
add_monitor_test ("/backends/monitor/custom/second-rotated-nonnative-tiled-config",
|
||||
meta_test_monitor_custom_second_rotated_nonnative_tiled_config);
|
||||
add_monitor_test ("/backends/monitor/custom/second-rotated-nonnative-config",
|
||||
meta_test_monitor_custom_second_rotated_nonnative_config);
|
||||
add_monitor_test ("/backends/monitor/custom/interlaced-config",
|
||||
|
@ -108,6 +108,30 @@ static struct wl_resource * create_and_send_primary_offer (MetaWaylandDataDevi
|
||||
struct wl_resource *target);
|
||||
static struct wl_resource * meta_wayland_data_source_get_resource (MetaWaylandDataSource *source);
|
||||
|
||||
static void
|
||||
move_resources (struct wl_list *destination,
|
||||
struct wl_list *source)
|
||||
{
|
||||
wl_list_insert_list (destination, source);
|
||||
wl_list_init (source);
|
||||
}
|
||||
|
||||
static void
|
||||
move_resources_for_client (struct wl_list *destination,
|
||||
struct wl_list *source,
|
||||
struct wl_client *client)
|
||||
{
|
||||
struct wl_resource *resource, *tmp;
|
||||
wl_resource_for_each_safe (resource, tmp, source)
|
||||
{
|
||||
if (wl_resource_get_client (resource) == client)
|
||||
{
|
||||
wl_list_remove (wl_resource_get_link (resource));
|
||||
wl_list_insert (destination, wl_resource_get_link (resource));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unbind_resource (struct wl_resource *resource)
|
||||
{
|
||||
@ -901,6 +925,12 @@ meta_wayland_drag_grab_set_focus (MetaWaylandDragGrab *drag_grab,
|
||||
client = wl_resource_get_client (surface->resource);
|
||||
|
||||
data_device_resource = wl_resource_find_for_client (&seat->data_device.resource_list, client);
|
||||
if (!data_device_resource)
|
||||
{
|
||||
data_device_resource =
|
||||
wl_resource_find_for_client (&seat->data_device.focus_resource_list,
|
||||
client);
|
||||
}
|
||||
|
||||
if (source && data_device_resource)
|
||||
offer = create_and_send_dnd_offer (source, data_device_resource);
|
||||
@ -1344,20 +1374,8 @@ static void
|
||||
selection_data_source_destroyed (gpointer data, GObject *object_was_here)
|
||||
{
|
||||
MetaWaylandDataDevice *data_device = data;
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
struct wl_resource *data_device_resource;
|
||||
struct wl_client *focus_client = NULL;
|
||||
|
||||
data_device->selection_data_source = NULL;
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||
if (focus_client)
|
||||
{
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
wl_data_device_send_selection (data_device_resource, NULL);
|
||||
}
|
||||
|
||||
unset_selection_source (data_device, META_SELECTION_CLIPBOARD);
|
||||
}
|
||||
|
||||
@ -1392,8 +1410,7 @@ meta_wayland_source_cancel (MetaWaylandDataSource *source)
|
||||
if (!priv->resource)
|
||||
return;
|
||||
|
||||
if (wl_resource_get_version(priv->resource) >= WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION)
|
||||
wl_data_source_send_cancelled (priv->resource);
|
||||
wl_data_source_send_cancelled (priv->resource);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1414,11 +1431,12 @@ meta_wayland_source_drop_performed (MetaWaylandDataSource *source)
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
priv->drop_performed = TRUE;
|
||||
|
||||
if (wl_resource_get_version (priv->resource) >=
|
||||
WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION)
|
||||
wl_data_source_send_dnd_drop_performed (priv->resource);
|
||||
{
|
||||
priv->drop_performed = TRUE;
|
||||
wl_data_source_send_dnd_drop_performed (priv->resource);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1659,8 +1677,6 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
|
||||
guint32 serial)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
struct wl_resource *data_device_resource;
|
||||
struct wl_client *focus_client;
|
||||
MetaSelectionSource *selection_source;
|
||||
|
||||
if (data_device->selection_data_source &&
|
||||
@ -1669,7 +1685,6 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
|
||||
|
||||
if (data_device->selection_data_source)
|
||||
{
|
||||
meta_wayland_data_source_cancel (data_device->selection_data_source);
|
||||
g_object_weak_unref (G_OBJECT (data_device->selection_data_source),
|
||||
selection_data_source_destroyed,
|
||||
data_device);
|
||||
@ -1696,18 +1711,6 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
|
||||
set_selection_source (data_device, META_SELECTION_CLIPBOARD,
|
||||
selection_source);
|
||||
g_object_unref (selection_source);
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||
if (focus_client)
|
||||
{
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
{
|
||||
struct wl_resource *offer;
|
||||
offer = create_and_send_clipboard_offer (data_device, data_device_resource);
|
||||
wl_data_device_send_selection (data_device_resource, offer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1758,21 +1761,8 @@ primary_source_destroyed (gpointer data,
|
||||
GObject *object_was_here)
|
||||
{
|
||||
MetaWaylandDataDevice *data_device = data;
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
struct wl_client *focus_client = NULL;
|
||||
|
||||
data_device->primary_data_source = NULL;
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||
if (focus_client)
|
||||
{
|
||||
struct wl_resource *data_device_resource;
|
||||
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
gtk_primary_selection_device_send_selection (data_device_resource, NULL);
|
||||
}
|
||||
|
||||
unset_selection_source (data_device, META_SELECTION_PRIMARY);
|
||||
}
|
||||
|
||||
@ -1782,8 +1772,6 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device,
|
||||
guint32 serial)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
|
||||
struct wl_resource *data_device_resource;
|
||||
struct wl_client *focus_client;
|
||||
MetaSelectionSource *selection_source;
|
||||
|
||||
g_assert (!source || META_IS_WAYLAND_DATA_SOURCE_PRIMARY (source));
|
||||
@ -1794,7 +1782,6 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device,
|
||||
|
||||
if (data_device->primary_data_source)
|
||||
{
|
||||
meta_wayland_data_source_cancel (data_device->primary_data_source);
|
||||
g_object_weak_unref (G_OBJECT (data_device->primary_data_source),
|
||||
primary_source_destroyed,
|
||||
data_device);
|
||||
@ -1820,18 +1807,6 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device,
|
||||
set_selection_source (data_device, META_SELECTION_PRIMARY,
|
||||
selection_source);
|
||||
g_object_unref (selection_source);
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||
if (focus_client)
|
||||
{
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
{
|
||||
struct wl_resource *offer;
|
||||
offer = create_and_send_primary_offer (data_device, data_device_resource);
|
||||
gtk_primary_selection_device_send_selection (data_device_resource, offer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1896,10 +1871,7 @@ owner_changed_cb (MetaSelection *selection,
|
||||
|
||||
if (selection_type == META_SELECTION_PRIMARY)
|
||||
{
|
||||
data_device_resource =
|
||||
wl_resource_find_for_client (&data_device->primary_resource_list,
|
||||
focus_client);
|
||||
if (data_device_resource)
|
||||
wl_resource_for_each (data_device_resource, &data_device->primary_focus_resource_list)
|
||||
{
|
||||
struct wl_resource *offer = NULL;
|
||||
|
||||
@ -1915,10 +1887,7 @@ owner_changed_cb (MetaSelection *selection,
|
||||
}
|
||||
else if (selection_type == META_SELECTION_CLIPBOARD)
|
||||
{
|
||||
data_device_resource =
|
||||
wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
||||
|
||||
if (data_device_resource)
|
||||
wl_resource_for_each (data_device_resource, &data_device->focus_resource_list)
|
||||
{
|
||||
struct wl_resource *offer = NULL;
|
||||
|
||||
@ -2053,7 +2022,9 @@ void
|
||||
meta_wayland_data_device_init (MetaWaylandDataDevice *data_device)
|
||||
{
|
||||
wl_list_init (&data_device->resource_list);
|
||||
wl_list_init (&data_device->focus_resource_list);
|
||||
wl_list_init (&data_device->primary_resource_list);
|
||||
wl_list_init (&data_device->primary_focus_resource_list);
|
||||
}
|
||||
|
||||
static struct wl_resource *
|
||||
@ -2135,22 +2106,34 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device)
|
||||
return;
|
||||
|
||||
data_device->focus_client = focus_client;
|
||||
move_resources (&data_device->resource_list,
|
||||
&data_device->focus_resource_list);
|
||||
move_resources (&data_device->primary_resource_list,
|
||||
&data_device->primary_focus_resource_list);
|
||||
|
||||
if (!focus_client)
|
||||
return;
|
||||
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
move_resources_for_client (&data_device->focus_resource_list,
|
||||
&data_device->resource_list,
|
||||
focus_client);
|
||||
|
||||
wl_resource_for_each (data_device_resource, &data_device->focus_resource_list)
|
||||
{
|
||||
struct wl_resource *offer;
|
||||
|
||||
offer = create_and_send_clipboard_offer (data_device, data_device_resource);
|
||||
wl_data_device_send_selection (data_device_resource, offer);
|
||||
}
|
||||
|
||||
data_device_resource = wl_resource_find_for_client (&data_device->primary_resource_list, focus_client);
|
||||
if (data_device_resource)
|
||||
move_resources_for_client (&data_device->primary_focus_resource_list,
|
||||
&data_device->primary_resource_list,
|
||||
focus_client);
|
||||
|
||||
wl_resource_for_each (data_device_resource, &data_device->primary_focus_resource_list)
|
||||
{
|
||||
struct wl_resource *offer;
|
||||
|
||||
offer = create_and_send_primary_offer (data_device, data_device_resource);
|
||||
gtk_primary_selection_device_send_selection (data_device_resource, offer);
|
||||
}
|
||||
|
@ -63,7 +63,9 @@ struct _MetaWaylandDataDevice
|
||||
MetaWaylandDataSource *primary_data_source;
|
||||
struct wl_listener selection_data_source_listener;
|
||||
struct wl_list resource_list;
|
||||
struct wl_list focus_resource_list;
|
||||
struct wl_list primary_resource_list;
|
||||
struct wl_list primary_focus_resource_list;
|
||||
MetaWaylandDragGrab *current_grab;
|
||||
struct wl_client *focus_client;
|
||||
|
||||
|
@ -603,7 +603,6 @@ meta_wayland_keyboard_disable (MetaWaylandKeyboard *keyboard)
|
||||
|
||||
meta_wayland_keyboard_end_grab (keyboard);
|
||||
meta_wayland_keyboard_set_focus (keyboard, NULL);
|
||||
meta_wayland_xkb_info_destroy (&keyboard->xkb_info);
|
||||
|
||||
wl_list_remove (&keyboard->resource_list);
|
||||
wl_list_init (&keyboard->resource_list);
|
||||
@ -917,7 +916,18 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard)
|
||||
keyboard_handle_focus_surface_destroy;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_keyboard_finalize (GObject *object)
|
||||
{
|
||||
MetaWaylandKeyboard *keyboard = META_WAYLAND_KEYBOARD (object);
|
||||
|
||||
meta_wayland_xkb_info_destroy (&keyboard->xkb_info);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_keyboard_class_init (MetaWaylandKeyboardClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_wayland_keyboard_finalize;
|
||||
}
|
||||
|
@ -145,6 +145,8 @@ xdnd_send_enter (MetaXWaylandDnd *dnd,
|
||||
gchar **p;
|
||||
struct wl_array *source_mime_types;
|
||||
|
||||
meta_x11_error_trap_push (x11_display);
|
||||
|
||||
data_source = compositor->seat->data_device.dnd_data_source;
|
||||
xev.xclient.type = ClientMessage;
|
||||
xev.xclient.message_type = xdnd_atoms[ATOM_DND_ENTER];
|
||||
@ -189,6 +191,9 @@ xdnd_send_enter (MetaXWaylandDnd *dnd,
|
||||
}
|
||||
|
||||
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
|
||||
|
||||
if (meta_x11_error_trap_pop_with_return (x11_display) != Success)
|
||||
g_critical ("Error sending XdndEnter");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -205,7 +210,9 @@ xdnd_send_leave (MetaXWaylandDnd *dnd,
|
||||
xev.xclient.window = dest;
|
||||
xev.xclient.data.l[0] = x11_display->selection.xwindow;
|
||||
|
||||
meta_x11_error_trap_push (x11_display);
|
||||
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
|
||||
meta_x11_error_trap_pop (x11_display);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -241,7 +248,11 @@ xdnd_send_position (MetaXWaylandDnd *dnd,
|
||||
xev.xclient.data.l[3] = time;
|
||||
xev.xclient.data.l[4] = action_to_atom (action);
|
||||
|
||||
meta_x11_error_trap_push (x11_display);
|
||||
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
|
||||
|
||||
if (meta_x11_error_trap_pop_with_return (x11_display) != Success)
|
||||
g_critical ("Error sending XdndPosition");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -261,7 +272,11 @@ xdnd_send_drop (MetaXWaylandDnd *dnd,
|
||||
xev.xclient.data.l[0] = x11_display->selection.xwindow;
|
||||
xev.xclient.data.l[2] = time;
|
||||
|
||||
meta_x11_error_trap_push (x11_display);
|
||||
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
|
||||
|
||||
if (meta_x11_error_trap_pop_with_return (x11_display) != Success)
|
||||
g_critical ("Error sending XdndDrop");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -289,7 +304,11 @@ xdnd_send_finished (MetaXWaylandDnd *dnd,
|
||||
xev.xclient.data.l[2] = action_to_atom (action);
|
||||
}
|
||||
|
||||
meta_x11_error_trap_push (x11_display);
|
||||
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
|
||||
|
||||
if (meta_x11_error_trap_pop_with_return (x11_display) != Success)
|
||||
g_critical ("Error sending XdndFinished");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -297,6 +316,7 @@ xdnd_send_status (MetaXWaylandDnd *dnd,
|
||||
Window dest,
|
||||
uint32_t action)
|
||||
{
|
||||
MetaX11Display *x11_display = meta_get_display ()->x11_display;
|
||||
Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
XEvent xev = { 0 };
|
||||
|
||||
@ -312,7 +332,11 @@ xdnd_send_status (MetaXWaylandDnd *dnd,
|
||||
if (xev.xclient.data.l[4])
|
||||
xev.xclient.data.l[1] |= 1 << 0; /* Bit 1: dest accepts the drop */
|
||||
|
||||
meta_x11_error_trap_push (x11_display);
|
||||
XSendEvent (xdisplay, dest, False, NoEventMask, &xev);
|
||||
|
||||
if (meta_x11_error_trap_pop_with_return (x11_display) != Success)
|
||||
g_critical ("Error sending Xdndstatus");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -60,6 +60,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaX11SelectionOutputStream,
|
||||
meta_x11_selection_output_stream,
|
||||
G_TYPE_OUTPUT_STREAM);
|
||||
|
||||
static size_t get_element_size (int format);
|
||||
|
||||
static void
|
||||
meta_x11_selection_output_stream_notify_selection (MetaX11SelectionOutputStream *stream)
|
||||
{
|
||||
@ -97,6 +99,9 @@ meta_x11_selection_output_stream_can_flush (MetaX11SelectionOutputStream *stream
|
||||
|
||||
if (priv->delete_pending)
|
||||
return FALSE;
|
||||
if (!g_output_stream_is_closing (G_OUTPUT_STREAM (stream)) &&
|
||||
priv->data->len < get_element_size (priv->format))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -110,7 +115,7 @@ get_max_request_size (MetaX11Display *display)
|
||||
if (size <= 0)
|
||||
size = XMaxRequestSize (display->xdisplay);
|
||||
|
||||
return size - 100;
|
||||
return (size - 100) * 4;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -120,7 +125,12 @@ meta_x11_selection_output_stream_needs_flush_unlocked (MetaX11SelectionOutputStr
|
||||
meta_x11_selection_output_stream_get_instance_private (stream);
|
||||
|
||||
if (priv->data->len == 0)
|
||||
return FALSE;
|
||||
{
|
||||
if (priv->incr)
|
||||
return g_output_stream_is_closing (G_OUTPUT_STREAM (stream));
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_output_stream_is_closing (G_OUTPUT_STREAM (stream)))
|
||||
return TRUE;
|
||||
@ -193,7 +203,8 @@ meta_x11_selection_output_stream_perform_flush (MetaX11SelectionOutputStream *st
|
||||
MetaX11SelectionOutputStreamPrivate *priv =
|
||||
meta_x11_selection_output_stream_get_instance_private (stream);
|
||||
Display *xdisplay;
|
||||
size_t element_size, n_elements;
|
||||
size_t element_size, n_elements, max_size;
|
||||
gboolean first_chunk = FALSE;
|
||||
int error_code;
|
||||
|
||||
g_assert (!priv->delete_pending);
|
||||
@ -207,8 +218,12 @@ meta_x11_selection_output_stream_perform_flush (MetaX11SelectionOutputStream *st
|
||||
|
||||
element_size = get_element_size (priv->format);
|
||||
n_elements = priv->data->len / element_size;
|
||||
max_size = get_max_request_size (priv->x11_display);
|
||||
|
||||
if (!g_output_stream_is_closing (G_OUTPUT_STREAM (stream)))
|
||||
if (!priv->incr)
|
||||
first_chunk = TRUE;
|
||||
|
||||
if (!priv->incr && priv->data->len > max_size)
|
||||
{
|
||||
XWindowAttributes attrs;
|
||||
|
||||
@ -224,14 +239,22 @@ meta_x11_selection_output_stream_perform_flush (MetaX11SelectionOutputStream *st
|
||||
XChangeProperty (xdisplay,
|
||||
priv->xwindow,
|
||||
priv->xproperty,
|
||||
XInternAtom (priv->x11_display->xdisplay, "INCR", True),
|
||||
XInternAtom (priv->x11_display->xdisplay, "INCR", False),
|
||||
32,
|
||||
PropModeReplace,
|
||||
(guchar *) &(long) { n_elements },
|
||||
1);
|
||||
priv->delete_pending = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t copy_n_elements;
|
||||
|
||||
if (priv->incr && priv->data->len > 0)
|
||||
priv->delete_pending = TRUE;
|
||||
|
||||
copy_n_elements = MIN (n_elements, max_size / element_size);
|
||||
|
||||
XChangeProperty (xdisplay,
|
||||
priv->xwindow,
|
||||
priv->xproperty,
|
||||
@ -239,15 +262,13 @@ meta_x11_selection_output_stream_perform_flush (MetaX11SelectionOutputStream *st
|
||||
priv->format,
|
||||
PropModeReplace,
|
||||
priv->data->data,
|
||||
n_elements);
|
||||
g_byte_array_remove_range (priv->data, 0, n_elements * element_size);
|
||||
if (priv->data->len < element_size)
|
||||
priv->flush_requested = FALSE;
|
||||
copy_n_elements);
|
||||
g_byte_array_remove_range (priv->data, 0, copy_n_elements * element_size);
|
||||
}
|
||||
|
||||
meta_x11_selection_output_stream_notify_selection (stream);
|
||||
if (first_chunk)
|
||||
meta_x11_selection_output_stream_notify_selection (stream);
|
||||
|
||||
priv->delete_pending = TRUE;
|
||||
g_cond_broadcast (&priv->cond);
|
||||
g_mutex_unlock (&priv->mutex);
|
||||
|
||||
@ -257,19 +278,26 @@ meta_x11_selection_output_stream_perform_flush (MetaX11SelectionOutputStream *st
|
||||
{
|
||||
char error_str[100];
|
||||
|
||||
XGetErrorText (xdisplay, error_code, error_str, sizeof (error_str));
|
||||
g_task_return_new_error (priv->pending_task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_BROKEN_PIPE,
|
||||
"Failed to flush selection output stream: %s",
|
||||
error_str);
|
||||
g_clear_object (&priv->pending_task);
|
||||
priv->flush_requested = FALSE;
|
||||
priv->delete_pending = FALSE;
|
||||
priv->pipe_error = TRUE;
|
||||
|
||||
if (priv->pending_task)
|
||||
{
|
||||
XGetErrorText (xdisplay, error_code, error_str, sizeof (error_str));
|
||||
g_task_return_new_error (priv->pending_task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_BROKEN_PIPE,
|
||||
"Failed to flush selection output stream: %s",
|
||||
error_str);
|
||||
g_clear_object (&priv->pending_task);
|
||||
}
|
||||
}
|
||||
else if (priv->pending_task)
|
||||
else if (priv->pending_task && priv->data->len == 0 && !priv->delete_pending)
|
||||
{
|
||||
size_t result;
|
||||
|
||||
priv->flush_requested = FALSE;
|
||||
result = GPOINTER_TO_SIZE (g_task_get_task_data (priv->pending_task));
|
||||
g_task_return_int (priv->pending_task, result);
|
||||
g_clear_object (&priv->pending_task);
|
||||
@ -281,12 +309,17 @@ meta_x11_selection_output_stream_invoke_flush (gpointer data)
|
||||
{
|
||||
MetaX11SelectionOutputStream *stream =
|
||||
META_X11_SELECTION_OUTPUT_STREAM (data);
|
||||
MetaX11SelectionOutputStreamPrivate *priv =
|
||||
meta_x11_selection_output_stream_get_instance_private (stream);
|
||||
|
||||
if (meta_x11_selection_output_stream_needs_flush (stream) &&
|
||||
meta_x11_selection_output_stream_can_flush (stream))
|
||||
meta_x11_selection_output_stream_perform_flush (stream);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
if (priv->delete_pending || priv->data->len > 0)
|
||||
return G_SOURCE_CONTINUE;
|
||||
else
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gssize
|
||||
@ -354,16 +387,11 @@ meta_x11_selection_output_stream_write_async (GOutputStream *output_stream
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
else if (!meta_x11_selection_output_stream_can_flush (stream))
|
||||
{
|
||||
g_assert (priv->pending_task == NULL);
|
||||
priv->pending_task = task;
|
||||
g_task_set_task_data (task, GSIZE_TO_POINTER (count), NULL);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_x11_selection_output_stream_perform_flush (stream);
|
||||
if (meta_x11_selection_output_stream_can_flush (stream))
|
||||
meta_x11_selection_output_stream_perform_flush (stream);
|
||||
|
||||
g_task_return_int (task, count);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
@ -391,7 +419,7 @@ meta_x11_selection_output_request_flush (MetaX11SelectionOutputStream *stream)
|
||||
|
||||
g_mutex_lock (&priv->mutex);
|
||||
|
||||
if (priv->data->len >= get_element_size (priv->format))
|
||||
if (priv->data->len > 0)
|
||||
priv->flush_requested = TRUE;
|
||||
|
||||
needs_flush = meta_x11_selection_output_stream_needs_flush_unlocked (stream);
|
||||
@ -466,10 +494,9 @@ meta_x11_selection_output_stream_flush_async (GOutputStream *output_stream
|
||||
}
|
||||
}
|
||||
|
||||
g_assert (priv->pending_task == NULL);
|
||||
priv->pending_task = task;
|
||||
meta_x11_selection_output_stream_perform_flush (stream);
|
||||
g_task_return_boolean (task, TRUE);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -23,6 +23,8 @@
|
||||
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include "core/meta-selection-private.h"
|
||||
#include "meta/meta-selection-source-memory.h"
|
||||
#include "x11/meta-selection-source-x11-private.h"
|
||||
#include "x11/meta-x11-selection-output-stream-private.h"
|
||||
#include "x11/meta-x11-selection-private.h"
|
||||
@ -30,6 +32,13 @@
|
||||
#define UTF8_STRING_MIMETYPE "text/plain;charset=utf-8"
|
||||
#define STRING_MIMETYPE "text/plain"
|
||||
|
||||
/* Set an arbitrary (although generous) threshold to determine whether a
|
||||
* XFixesSelectionNotify corresponds to a XSetSelectionOwner from another
|
||||
* client. The selection timestamp is not updated if the owner client is
|
||||
* closed.
|
||||
*/
|
||||
#define SELECTION_CLEARED_BY_CLIENT(e) (e->timestamp - e->selection_timestamp < 50)
|
||||
|
||||
static gboolean
|
||||
atom_to_selection_type (Display *xdisplay,
|
||||
Atom selection,
|
||||
@ -296,8 +305,8 @@ source_new_cb (GObject *object,
|
||||
source = meta_selection_source_x11_new_finish (res, &error);
|
||||
if (source)
|
||||
{
|
||||
meta_selection_set_owner (selection, selection_type, source);
|
||||
g_set_object (&x11_display->selection.owners[selection_type], source);
|
||||
meta_selection_set_owner (selection, selection_type, source);
|
||||
g_object_unref (source);
|
||||
}
|
||||
else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
@ -331,16 +340,27 @@ meta_x11_selection_handle_xfixes_selection_notify (MetaX11Display *x11_display,
|
||||
|
||||
x11_display->selection.cancellables[selection_type] = g_cancellable_new ();
|
||||
|
||||
if (event->owner == None)
|
||||
if (event->owner == None && x11_display->selection.owners[selection_type])
|
||||
{
|
||||
if (x11_display->selection.owners[selection_type])
|
||||
if (SELECTION_CLEARED_BY_CLIENT (event))
|
||||
{
|
||||
MetaSelectionSource *source;
|
||||
|
||||
/* Replace with an empty owner */
|
||||
source = g_object_new (META_TYPE_SELECTION_SOURCE_MEMORY, NULL);
|
||||
g_set_object (&x11_display->selection.owners[selection_type], source);
|
||||
meta_selection_set_owner (selection, selection_type, source);
|
||||
g_object_unref (source);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* An X client went away, clear the selection */
|
||||
meta_selection_unset_owner (selection, selection_type,
|
||||
x11_display->selection.owners[selection_type]);
|
||||
g_clear_object (&x11_display->selection.owners[selection_type]);
|
||||
}
|
||||
}
|
||||
else if (event->owner != x11_display->selection.xwindow)
|
||||
else if (event->owner != None && event->owner != x11_display->selection.xwindow)
|
||||
{
|
||||
SourceNewData *data;
|
||||
|
||||
@ -374,14 +394,13 @@ meta_x11_selection_handle_event (MetaX11Display *x11_display,
|
||||
}
|
||||
|
||||
static void
|
||||
owner_changed_cb (MetaSelection *selection,
|
||||
MetaSelectionType selection_type,
|
||||
MetaSelectionSource *new_owner,
|
||||
MetaX11Display *x11_display)
|
||||
notify_selection_owner (MetaX11Display *x11_display,
|
||||
MetaSelectionType selection_type,
|
||||
MetaSelectionSource *new_owner)
|
||||
{
|
||||
Display *xdisplay = x11_display->xdisplay;
|
||||
|
||||
if (new_owner && !META_IS_SELECTION_SOURCE_X11 (new_owner))
|
||||
if (new_owner && new_owner != x11_display->selection.owners[selection_type])
|
||||
{
|
||||
if (x11_display->selection.cancellables[selection_type])
|
||||
{
|
||||
@ -404,6 +423,7 @@ meta_x11_selection_init (MetaX11Display *x11_display)
|
||||
{
|
||||
XSetWindowAttributes attributes = { 0 };
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
MetaSelection *selection;
|
||||
guint mask, i;
|
||||
|
||||
attributes.event_mask = PropertyChangeMask | SubstructureNotifyMask;
|
||||
@ -424,18 +444,24 @@ meta_x11_selection_init (MetaX11Display *x11_display)
|
||||
XFixesSelectionWindowDestroyNotifyMask |
|
||||
XFixesSelectionClientCloseNotifyMask;
|
||||
|
||||
selection = meta_display_get_selection (display);
|
||||
|
||||
for (i = 0; i < META_N_SELECTION_TYPES; i++)
|
||||
{
|
||||
MetaSelectionSource *owner;
|
||||
|
||||
XFixesSelectSelectionInput (x11_display->xdisplay,
|
||||
x11_display->selection.xwindow,
|
||||
selection_to_atom (i, x11_display->xdisplay),
|
||||
mask);
|
||||
owner = meta_selection_get_current_owner (selection, i);
|
||||
notify_selection_owner (x11_display, i, owner);
|
||||
}
|
||||
|
||||
g_signal_connect (meta_display_get_selection (display),
|
||||
"owner-changed",
|
||||
G_CALLBACK (owner_changed_cb),
|
||||
x11_display);
|
||||
g_signal_connect_swapped (selection,
|
||||
"owner-changed",
|
||||
G_CALLBACK (notify_selection_owner),
|
||||
x11_display);
|
||||
}
|
||||
|
||||
void
|
||||
@ -445,7 +471,7 @@ meta_x11_selection_shutdown (MetaX11Display *x11_display)
|
||||
guint i;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (meta_display_get_selection (display),
|
||||
owner_changed_cb,
|
||||
notify_selection_owner,
|
||||
x11_display);
|
||||
|
||||
for (i = 0; i < META_N_SELECTION_TYPES; i++)
|
||||
|
Reference in New Issue
Block a user