Compare commits
133 Commits
citadel
...
gnome-3-36
Author | SHA1 | Date | |
---|---|---|---|
|
d2747a1288 | ||
|
32d130ddf0 | ||
|
7d061a06de | ||
|
e3b213f9d7 | ||
|
eea81807ee | ||
|
fdb76593d0 | ||
|
143771441f | ||
|
52a6b5df5f | ||
|
299569c3b8 | ||
|
3dab5120ed | ||
|
eae21f01dd | ||
|
4d8538d6a9 | ||
|
ef3dac7064 | ||
|
1fd53c480f | ||
|
0c6ac287e6 | ||
|
e8052f169b | ||
|
449fa7bf81 | ||
|
2d899596e2 | ||
|
cf88d64882 | ||
|
92db8902d9 | ||
|
b1d45820ef | ||
|
d07335cd4c | ||
|
d03deb006c | ||
|
c2146b457e | ||
|
77dc3a5065 | ||
|
454875248a | ||
|
ae8acc9980 | ||
|
86d9cd1a66 | ||
|
3a70ba7ae2 | ||
|
36a6235f3a | ||
|
9b349cb25b | ||
|
a83d83f087 | ||
|
b8bd39793a | ||
|
70072c39dd | ||
|
bb4bd4b5c0 | ||
|
ef848f10d1 | ||
|
59cb259fdd | ||
|
76e4b5de7a | ||
|
9acb823603 | ||
|
d721750417 | ||
|
1ec91cc8ee | ||
|
5c7b5ef0d9 | ||
|
e98e1c13dd | ||
|
8b69e7902a | ||
|
b52a0be288 | ||
|
1eb0812f0a | ||
|
b98125a330 | ||
|
78248d8dd3 | ||
|
849d8dfae9 | ||
|
1f896c9735 | ||
|
cc617b059c | ||
|
44a3358125 | ||
|
81deb99435 | ||
|
f25417efcf | ||
|
ecc2b91016 | ||
|
b002343dca | ||
|
0d9ded403f | ||
|
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 |
74
NEWS
74
NEWS
@ -1,3 +1,77 @@
|
||||
3.36.5
|
||||
======
|
||||
* Screencast fixes and improvements [Jonas; !1351, !1365]
|
||||
* Fix glitches when subsurfaces extend outside the toplevel [Robert; #1316]
|
||||
* Mipmap background texture rendering [Daniel; !1347]
|
||||
* Fix wine copy & paste [Sebastian; !1369]
|
||||
* Plugged memory leaks [Marco, Thomas; !1195]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Thomas Hindoe Paaboel Andersen, Sebastian Keller, Robert Mader,
|
||||
Marco Trevisan (Treviño), Daniel van Vugt
|
||||
|
||||
Translators:
|
||||
Rafael Fontenelle [pt_BR]
|
||||
|
||||
3.36.4
|
||||
======
|
||||
* Fix crash on area screenshots with fractional scaling [Sebastian; !1320]
|
||||
* Do not paint textures of fully obscured windows [Robert; !1326]
|
||||
* Turn off CRTCs as well when enabling DPMS [Michel; !1240]
|
||||
* Improve selection support
|
||||
[Robert, Carlos, Sebastian; !1330, !1193, !1253, !1255, !1293, !1350]
|
||||
* Use a more appropriate combine function on opaque areas [Daniel; !1331]
|
||||
* Fix remote desktop being broken without screencast session [Olivier; #1307]
|
||||
* Fix popovers disappearing on wayland and HiDPI [Robert; #1312]
|
||||
* Fixed crashes [Jonas Å.; !1317]
|
||||
* Plugged memory leaks [Jonas Å.; !1283]
|
||||
* Misc. bug fixes and cleanups
|
||||
[Corentin, Sebastian, Jonas Å., Jonas D.; !1314, !1321, !1295, !1333]
|
||||
|
||||
Contributors:
|
||||
Jonas Dreßler, Michel Dänzer, Olivier Fourdan, Carlos Garnacho,
|
||||
Sebastian Keller, Robert Mader, Corentin Noël, Daniel van Vugt, Jonas Ådahl
|
||||
|
||||
|
||||
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
|
||||
|
@ -475,8 +475,10 @@ get_preferred_size_for_orientation (ClutterBoxLayout *self,
|
||||
ClutterActor *child;
|
||||
gint n_children = 0;
|
||||
gfloat minimum, natural;
|
||||
float largest_min_size, largest_nat_size;
|
||||
|
||||
minimum = natural = 0;
|
||||
largest_min_size = largest_nat_size = 0;
|
||||
|
||||
clutter_actor_iter_init (&iter, container);
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
@ -491,8 +493,22 @@ get_preferred_size_for_orientation (ClutterBoxLayout *self,
|
||||
get_child_size (child, priv->orientation,
|
||||
for_size, &child_min, &child_nat);
|
||||
|
||||
minimum += child_min;
|
||||
natural += child_nat;
|
||||
if (priv->is_homogeneous)
|
||||
{
|
||||
largest_min_size = MAX (largest_min_size, child_min);
|
||||
largest_nat_size = MAX (largest_nat_size, child_nat);
|
||||
}
|
||||
else
|
||||
{
|
||||
minimum += child_min;
|
||||
natural += child_nat;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->is_homogeneous)
|
||||
{
|
||||
minimum = largest_min_size * n_children;
|
||||
natural = largest_nat_size * n_children;
|
||||
}
|
||||
|
||||
if (n_children > 1)
|
||||
@ -623,6 +639,8 @@ get_preferred_size_for_opposite_orientation (ClutterBoxLayout *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
size -= (nvis_children - 1) * priv->spacing;
|
||||
|
||||
/* Bring children up to size first */
|
||||
if (isnormal (size) || size == 0)
|
||||
{
|
||||
|
@ -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 << 1,
|
||||
} 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) roundf (rect->width * scale);
|
||||
texture_height = (int) roundf (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
|
||||
|
@ -74,7 +74,7 @@ PangoFontMap *
|
||||
cogl_pango_font_map_new (void)
|
||||
{
|
||||
PangoFontMap *fm = pango_cairo_font_map_new ();
|
||||
CoglPangoFontMapPriv *priv = g_new0 (CoglPangoFontMapPriv, 1);
|
||||
g_autofree CoglPangoFontMapPriv *priv = g_new0 (CoglPangoFontMapPriv, 1);
|
||||
|
||||
_COGL_GET_CONTEXT (context, NULL);
|
||||
|
||||
@ -85,7 +85,7 @@ cogl_pango_font_map_new (void)
|
||||
* for now. */
|
||||
g_object_set_qdata_full (G_OBJECT (fm),
|
||||
cogl_pango_font_map_get_priv_key (),
|
||||
priv,
|
||||
g_steal_pointer (&priv),
|
||||
free_priv);
|
||||
|
||||
return fm;
|
||||
|
@ -93,10 +93,12 @@ _cogl_onscreen_init_from_template (CoglOnscreen *onscreen,
|
||||
CoglOnscreen *
|
||||
_cogl_onscreen_new (void)
|
||||
{
|
||||
CoglOnscreen *onscreen = g_new0 (CoglOnscreen, 1);
|
||||
g_autofree CoglOnscreen *onscreen_ptr = g_new0 (CoglOnscreen, 1);
|
||||
CoglOnscreen *onscreen;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NULL);
|
||||
|
||||
onscreen = g_steal_pointer (&onscreen_ptr);
|
||||
_cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen),
|
||||
ctx,
|
||||
COGL_FRAMEBUFFER_TYPE_ONSCREEN,
|
||||
|
@ -50,7 +50,7 @@ struct _CoglPipelineCache
|
||||
CoglPipelineCache *
|
||||
_cogl_pipeline_cache_new (void)
|
||||
{
|
||||
CoglPipelineCache *cache = g_new (CoglPipelineCache, 1);
|
||||
g_autofree CoglPipelineCache *cache = g_new (CoglPipelineCache, 1);
|
||||
unsigned long vertex_state;
|
||||
unsigned long layer_vertex_state;
|
||||
unsigned int fragment_state;
|
||||
@ -80,7 +80,7 @@ _cogl_pipeline_cache_new (void)
|
||||
layer_vertex_state | layer_fragment_state,
|
||||
"programs");
|
||||
|
||||
return cache;
|
||||
return g_steal_pointer (&cache);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -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;
|
||||
@ -399,6 +402,11 @@ _cogl_texture_2d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags)
|
||||
{
|
||||
CoglContext *ctx = tex->context;
|
||||
|
||||
/* Since we are about to ask the GPU to generate mipmaps of tex, we
|
||||
* better make sure tex is up-to-date.
|
||||
*/
|
||||
_cogl_texture_flush_journal_rendering (tex);
|
||||
|
||||
ctx->driver_vtable->texture_2d_generate_mipmap (tex_2d);
|
||||
|
||||
tex_2d->mipmaps_dirty = FALSE;
|
||||
|
@ -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.5',
|
||||
meson_version: '>= 0.50.0',
|
||||
license: 'GPLv2+'
|
||||
)
|
||||
|
@ -12,7 +12,7 @@ option('opengl_libname',
|
||||
|
||||
option('gles2_libname',
|
||||
type: 'string',
|
||||
value: 'libGLESv2.so',
|
||||
value: 'libGLESv2.so.2',
|
||||
description: 'GLESv2 library file name'
|
||||
)
|
||||
|
||||
|
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"
|
||||
|
68
po/pt_BR.po
68
po/pt_BR.po
@ -21,8 +21,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mutter\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
|
||||
"POT-Creation-Date: 2020-02-23 17:41+0000\n"
|
||||
"PO-Revision-Date: 2020-02-24 06:39-0300\n"
|
||||
"POT-Creation-Date: 2020-04-27 14:06+0000\n"
|
||||
"PO-Revision-Date: 2020-07-17 17:56-0300\n"
|
||||
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
|
||||
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
|
||||
"Language: pt_BR\n"
|
||||
@ -30,7 +30,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: Gtranslator 3.32.0\n"
|
||||
"X-Generator: Gtranslator 3.36.0\n"
|
||||
"X-Project-Style: gnome\n"
|
||||
|
||||
#: data/50-mutter-navigation.xml:6
|
||||
@ -59,35 +59,35 @@ msgstr "Mover a janela para o último espaço de trabalho"
|
||||
|
||||
#: data/50-mutter-navigation.xml:24
|
||||
msgid "Move window one workspace up"
|
||||
msgstr "Mover a janela um espaço de trabalho acima"
|
||||
msgstr "Mover a janela para um espaço de trabalho acima"
|
||||
|
||||
#: data/50-mutter-navigation.xml:27
|
||||
msgid "Move window one workspace down"
|
||||
msgstr "Mover a janela um espaço de trabalho abaixo"
|
||||
msgstr "Mover a janela para um espaço de trabalho abaixo"
|
||||
|
||||
# Em conformidade com a tradução do gsettings-desktop-schemas --Enrico
|
||||
#: data/50-mutter-navigation.xml:30
|
||||
msgid "Move window one monitor to the left"
|
||||
msgstr "Mover janela para o monitor da esquerda"
|
||||
msgstr "Mover a janela para o monitor da esquerda"
|
||||
|
||||
# Em conformidade com a tradução do gsettings-desktop-schemas --Enrico
|
||||
#: data/50-mutter-navigation.xml:33
|
||||
msgid "Move window one monitor to the right"
|
||||
msgstr "Mover janela para o monitor da direita"
|
||||
msgstr "Mover a janela para o monitor da direita"
|
||||
|
||||
# Em conformidade com a tradução do gsettings-desktop-schemas --Enrico
|
||||
#: data/50-mutter-navigation.xml:36
|
||||
msgid "Move window one monitor up"
|
||||
msgstr "Mover janela para o monitor acima"
|
||||
msgstr "Mover a janela para o monitor acima"
|
||||
|
||||
# Em conformidade com a tradução do gsettings-desktop-schemas --Enrico
|
||||
#: data/50-mutter-navigation.xml:39
|
||||
msgid "Move window one monitor down"
|
||||
msgstr "Mover janela para o monitor abaixo"
|
||||
msgstr "Mover a janela para o monitor abaixo"
|
||||
|
||||
#: data/50-mutter-navigation.xml:43
|
||||
msgid "Switch applications"
|
||||
msgstr "Alternar aplicativos"
|
||||
msgstr "Alternar entre aplicativos"
|
||||
|
||||
#: data/50-mutter-navigation.xml:48
|
||||
msgid "Switch to previous application"
|
||||
@ -95,7 +95,7 @@ msgstr "Alternar para o aplicativo anterior"
|
||||
|
||||
#: data/50-mutter-navigation.xml:52
|
||||
msgid "Switch windows"
|
||||
msgstr "Alternar janelas"
|
||||
msgstr "Alternar entre janelas"
|
||||
|
||||
#: data/50-mutter-navigation.xml:57
|
||||
msgid "Switch to previous window"
|
||||
@ -111,7 +111,7 @@ msgstr "Alternar para a janela anterior de um aplicativo"
|
||||
|
||||
#: data/50-mutter-navigation.xml:70
|
||||
msgid "Switch system controls"
|
||||
msgstr "Alternar controles do sistema"
|
||||
msgstr "Alternar os controles do sistema"
|
||||
|
||||
#: data/50-mutter-navigation.xml:75
|
||||
msgid "Switch to previous system control"
|
||||
@ -167,11 +167,11 @@ msgstr "Trocar para o último espaço de trabalho"
|
||||
|
||||
#: data/50-mutter-navigation.xml:123
|
||||
msgid "Move to workspace above"
|
||||
msgstr "Mover para o espaço de trabalho acima"
|
||||
msgstr "Mover a visualização para o espaço de trabalho acima"
|
||||
|
||||
#: data/50-mutter-navigation.xml:126
|
||||
msgid "Move to workspace below"
|
||||
msgstr "Mover para o espaço de trabalho abaixo"
|
||||
msgstr "Mover a visualização para o espaço de trabalho abaixo"
|
||||
|
||||
#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6
|
||||
msgid "System"
|
||||
@ -199,11 +199,11 @@ msgstr "Ativar o menu da janela"
|
||||
|
||||
#: data/50-mutter-windows.xml:10
|
||||
msgid "Toggle fullscreen mode"
|
||||
msgstr "Alternar modo de tela inteira"
|
||||
msgstr "Alternar o modo de tela inteira"
|
||||
|
||||
#: data/50-mutter-windows.xml:12
|
||||
msgid "Toggle maximization state"
|
||||
msgstr "Alternar estado de maximização"
|
||||
msgstr "Alternar o estado de maximização"
|
||||
|
||||
#: data/50-mutter-windows.xml:14
|
||||
msgid "Maximize window"
|
||||
@ -211,35 +211,35 @@ msgstr "Maximizar a janela"
|
||||
|
||||
#: data/50-mutter-windows.xml:16
|
||||
msgid "Restore window"
|
||||
msgstr "Restaurar janela"
|
||||
msgstr "Restaurar a anela"
|
||||
|
||||
#: data/50-mutter-windows.xml:18
|
||||
msgid "Close window"
|
||||
msgstr "Fechar janela"
|
||||
msgstr "Fechar a janela"
|
||||
|
||||
#: data/50-mutter-windows.xml:20
|
||||
msgid "Hide window"
|
||||
msgstr "Ocultar janela"
|
||||
msgstr "Ocultar a janela"
|
||||
|
||||
#: data/50-mutter-windows.xml:22
|
||||
msgid "Move window"
|
||||
msgstr "Mover janela"
|
||||
msgstr "Mover a janela"
|
||||
|
||||
#: data/50-mutter-windows.xml:24
|
||||
msgid "Resize window"
|
||||
msgstr "Redimensionar janela"
|
||||
msgstr "Redimensionar a janela"
|
||||
|
||||
#: data/50-mutter-windows.xml:27
|
||||
msgid "Toggle window on all workspaces or one"
|
||||
msgstr "Alternar a janela em todos os espaços de trabalho ou em apenas um"
|
||||
msgstr "Alternar a janela em todos os espaços de trabalho ou apenas em um"
|
||||
|
||||
#: data/50-mutter-windows.xml:29
|
||||
msgid "Raise window if covered, otherwise lower it"
|
||||
msgstr "Elevar a janela se estiver coberta; caso contrário, a abaixa"
|
||||
msgstr "Trazer a janela se estiver coberta; caso contrário, coloca atrás"
|
||||
|
||||
#: data/50-mutter-windows.xml:31
|
||||
msgid "Raise window above other windows"
|
||||
msgstr "Elevar a janela para frente das outras"
|
||||
msgstr "Trazer a janela para frente das outras"
|
||||
|
||||
#: data/50-mutter-windows.xml:33
|
||||
msgid "Lower window below other windows"
|
||||
@ -255,11 +255,11 @@ msgstr "Maximizar a janela horizontalmente"
|
||||
|
||||
#: data/50-mutter-windows.xml:41
|
||||
msgid "View split on left"
|
||||
msgstr "Visualizar divisão à esquerda"
|
||||
msgstr "Visualizar a divisão à esquerda"
|
||||
|
||||
#: data/50-mutter-windows.xml:45
|
||||
msgid "View split on right"
|
||||
msgstr "Visualizar divisão à direita"
|
||||
msgstr "Visualizar a divisão à direita"
|
||||
|
||||
#: data/mutter.desktop.in:4
|
||||
msgid "Mutter"
|
||||
@ -580,7 +580,7 @@ msgstr ""
|
||||
#. TRANSLATORS: This string refers to a button that switches between
|
||||
#. * different modes.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2567
|
||||
#: src/backends/meta-input-settings.c:2631
|
||||
#, c-format
|
||||
msgid "Mode Switch (Group %d)"
|
||||
msgstr "Alternador de modo (Grupo %d)"
|
||||
@ -588,34 +588,34 @@ msgstr "Alternador de modo (Grupo %d)"
|
||||
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
|
||||
#. * mapping through the available outputs.
|
||||
#.
|
||||
#: src/backends/meta-input-settings.c:2590
|
||||
#: src/backends/meta-input-settings.c:2654
|
||||
msgid "Switch monitor"
|
||||
msgstr "Trocar monitor"
|
||||
|
||||
#: src/backends/meta-input-settings.c:2592
|
||||
#: src/backends/meta-input-settings.c:2656
|
||||
msgid "Show on-screen help"
|
||||
msgstr "Mostrar ajuda na tela"
|
||||
|
||||
#: src/backends/meta-monitor.c:223
|
||||
#: src/backends/meta-monitor.c:226
|
||||
msgid "Built-in display"
|
||||
msgstr "Tela embutida"
|
||||
|
||||
#: src/backends/meta-monitor.c:252
|
||||
#: src/backends/meta-monitor.c:255
|
||||
msgid "Unknown"
|
||||
msgstr "Desconhecido"
|
||||
|
||||
#: src/backends/meta-monitor.c:254
|
||||
#: src/backends/meta-monitor.c:257
|
||||
msgid "Unknown Display"
|
||||
msgstr "Monitor desconhecido"
|
||||
|
||||
#: 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 "
|
||||
|
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,29 @@ 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;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_start (MetaDBusRemoteDesktopSession *skeleton,
|
||||
GDBusMethodInvocation *invocation)
|
||||
@ -256,6 +283,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 +323,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 +355,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 +382,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 +431,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 +462,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 +510,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 +556,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,13 +580,9 @@ 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 (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
@ -617,13 +626,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 (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
@ -668,13 +672,9 @@ 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 (!meta_remote_desktop_session_check_can_notify (session, invocation))
|
||||
return TRUE;
|
||||
|
||||
|
||||
if (!session->screen_cast_session)
|
||||
{
|
||||
@ -714,13 +714,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,13 +115,16 @@ 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);
|
||||
MetaScreenCastRecordFlag flags;
|
||||
|
||||
meta_screen_cast_stream_src_maybe_record_frame (src);
|
||||
flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
|
||||
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
|
||||
}
|
||||
|
||||
static MetaBackend *
|
||||
@ -180,6 +183,7 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src);
|
||||
ClutterStage *stage = get_stage (monitor_src);
|
||||
MetaScreenCastRecordFlag flags;
|
||||
|
||||
if (!is_cursor_in_stream (monitor_src))
|
||||
return;
|
||||
@ -187,7 +191,11 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
|
||||
if (clutter_stage_is_redraw_queued (stage))
|
||||
return;
|
||||
|
||||
meta_screen_cast_stream_src_maybe_record_frame (src);
|
||||
if (meta_screen_cast_stream_src_pending_follow_up_frame (src))
|
||||
return;
|
||||
|
||||
flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
|
||||
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -361,8 +369,9 @@ meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_screen_cast_monitor_stream_src_record_frame (MetaScreenCastStreamSrc *src,
|
||||
uint8_t *data)
|
||||
meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
|
||||
uint8_t *data,
|
||||
GError **error)
|
||||
{
|
||||
MetaScreenCastMonitorStreamSrc *monitor_src =
|
||||
META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
|
||||
@ -371,9 +380,6 @@ meta_screen_cast_monitor_stream_src_record_frame (MetaScreenCastStreamSrc *src,
|
||||
MetaLogicalMonitor *logical_monitor;
|
||||
|
||||
stage = get_stage (monitor_src);
|
||||
if (!clutter_stage_is_redraw_queued (stage))
|
||||
return FALSE;
|
||||
|
||||
monitor = get_monitor (monitor_src);
|
||||
logical_monitor = meta_monitor_get_logical_monitor (monitor);
|
||||
clutter_stage_capture_into (stage, FALSE, &logical_monitor->rect, data);
|
||||
@ -382,8 +388,9 @@ meta_screen_cast_monitor_stream_src_record_frame (MetaScreenCastStreamSrc *src,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_screen_cast_monitor_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
|
||||
CoglFramebuffer *framebuffer)
|
||||
meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
|
||||
CoglFramebuffer *framebuffer,
|
||||
GError **error)
|
||||
{
|
||||
MetaScreenCastMonitorStreamSrc *monitor_src =
|
||||
META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
|
||||
@ -407,7 +414,6 @@ meta_screen_cast_monitor_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc
|
||||
for (l = meta_renderer_get_views (renderer); l; l = l->next)
|
||||
{
|
||||
ClutterStageView *view = CLUTTER_STAGE_VIEW (l->data);
|
||||
g_autoptr (GError) error = NULL;
|
||||
CoglFramebuffer *view_framebuffer;
|
||||
MetaRectangle view_layout;
|
||||
int x, y;
|
||||
@ -428,12 +434,8 @@ meta_screen_cast_monitor_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc
|
||||
x, y,
|
||||
cogl_framebuffer_get_width (view_framebuffer),
|
||||
cogl_framebuffer_get_height (view_framebuffer),
|
||||
&error))
|
||||
{
|
||||
g_warning ("Error blitting view into DMABuf framebuffer: %s",
|
||||
error->message);
|
||||
return FALSE;
|
||||
}
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cogl_framebuffer_finish (framebuffer);
|
||||
@ -441,6 +443,44 @@ meta_screen_cast_monitor_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_monitor_stream_record_follow_up (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
MetaScreenCastMonitorStreamSrc *monitor_src =
|
||||
META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
|
||||
MetaBackend *backend = get_backend (monitor_src);
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
ClutterStage *stage = get_stage (monitor_src);
|
||||
MetaMonitor *monitor;
|
||||
MetaLogicalMonitor *logical_monitor;
|
||||
MetaRectangle logical_monitor_layout;
|
||||
GList *l;
|
||||
|
||||
monitor = get_monitor (monitor_src);
|
||||
logical_monitor = meta_monitor_get_logical_monitor (monitor);
|
||||
logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor);
|
||||
|
||||
for (l = meta_renderer_get_views (renderer); l; l = l->next)
|
||||
{
|
||||
MetaRendererView *view = l->data;
|
||||
MetaRectangle view_layout;
|
||||
MetaRectangle damage;
|
||||
|
||||
clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view), &view_layout);
|
||||
|
||||
if (!meta_rectangle_overlap (&logical_monitor_layout, &view_layout))
|
||||
continue;
|
||||
|
||||
damage = (cairo_rectangle_int_t) {
|
||||
.x = view_layout.x,
|
||||
.y = view_layout.y,
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
};
|
||||
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &damage);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
|
||||
struct spa_meta_cursor *spa_meta_cursor)
|
||||
@ -561,9 +601,12 @@ meta_screen_cast_monitor_stream_src_class_init (MetaScreenCastMonitorStreamSrcCl
|
||||
src_class->get_specs = meta_screen_cast_monitor_stream_src_get_specs;
|
||||
src_class->enable = meta_screen_cast_monitor_stream_src_enable;
|
||||
src_class->disable = meta_screen_cast_monitor_stream_src_disable;
|
||||
src_class->record_frame = meta_screen_cast_monitor_stream_src_record_frame;
|
||||
src_class->blit_to_framebuffer =
|
||||
meta_screen_cast_monitor_stream_src_blit_to_framebuffer;
|
||||
src_class->record_to_buffer =
|
||||
meta_screen_cast_monitor_stream_src_record_to_buffer;
|
||||
src_class->record_to_framebuffer =
|
||||
meta_screen_cast_monitor_stream_src_record_to_framebuffer;
|
||||
src_class->record_follow_up =
|
||||
meta_screen_cast_monitor_stream_record_follow_up;
|
||||
src_class->set_cursor_metadata =
|
||||
meta_screen_cast_monitor_stream_src_set_cursor_metadata;
|
||||
}
|
||||
|
@ -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;
|
||||
@ -89,7 +91,8 @@ typedef struct _MetaScreenCastStreamSrcPrivate
|
||||
struct spa_video_info_raw video_format;
|
||||
int video_stride;
|
||||
|
||||
uint64_t last_frame_timestamp_us;
|
||||
int64_t last_frame_timestamp_us;
|
||||
guint follow_up_frame_source_id;
|
||||
|
||||
GHashTable *dmabuf_handles;
|
||||
|
||||
@ -107,6 +110,12 @@ G_DEFINE_TYPE_WITH_CODE (MetaScreenCastStreamSrc,
|
||||
meta_screen_cast_stream_src_init_initable_iface)
|
||||
G_ADD_PRIVATE (MetaScreenCastStreamSrc))
|
||||
|
||||
static inline uint32_t
|
||||
us2ms (uint64_t us)
|
||||
{
|
||||
return (uint32_t) (us / 1000);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_stream_src_get_specs (MetaScreenCastStreamSrc *src,
|
||||
int *width,
|
||||
@ -133,23 +142,34 @@ meta_screen_cast_stream_src_get_videocrop (MetaScreenCastStreamSrc *src,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_screen_cast_stream_src_record_frame (MetaScreenCastStreamSrc *src,
|
||||
uint8_t *data)
|
||||
meta_screen_cast_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
|
||||
uint8_t *data,
|
||||
GError **error)
|
||||
{
|
||||
MetaScreenCastStreamSrcClass *klass =
|
||||
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
|
||||
|
||||
return klass->record_frame (src, data);
|
||||
return klass->record_to_buffer (src, data, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_screen_cast_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
|
||||
CoglFramebuffer *framebuffer)
|
||||
meta_screen_cast_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
|
||||
CoglFramebuffer *framebuffer,
|
||||
GError **error)
|
||||
{
|
||||
MetaScreenCastStreamSrcClass *klass =
|
||||
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
|
||||
|
||||
return klass->blit_to_framebuffer (src, framebuffer);
|
||||
return klass->record_to_framebuffer (src, framebuffer, error);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_stream_src_record_follow_up (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
MetaScreenCastStreamSrcClass *klass =
|
||||
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
|
||||
|
||||
klass->record_follow_up (src);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -407,9 +427,10 @@ maybe_record_cursor (MetaScreenCastStreamSrc *src,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
do_record_frame (MetaScreenCastStreamSrc *src,
|
||||
struct spa_buffer *spa_buffer,
|
||||
uint8_t *data)
|
||||
do_record_frame (MetaScreenCastStreamSrc *src,
|
||||
struct spa_buffer *spa_buffer,
|
||||
uint8_t *data,
|
||||
GError **error)
|
||||
{
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
@ -417,7 +438,7 @@ do_record_frame (MetaScreenCastStreamSrc *src,
|
||||
if (spa_buffer->datas[0].data ||
|
||||
spa_buffer->datas[0].type == SPA_DATA_MemFd)
|
||||
{
|
||||
return meta_screen_cast_stream_src_record_frame (src, data);
|
||||
return meta_screen_cast_stream_src_record_to_buffer (src, data, error);
|
||||
}
|
||||
else if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf)
|
||||
{
|
||||
@ -427,14 +448,56 @@ do_record_frame (MetaScreenCastStreamSrc *src,
|
||||
CoglFramebuffer *dmabuf_fbo =
|
||||
cogl_dma_buf_handle_get_framebuffer (dmabuf_handle);
|
||||
|
||||
return meta_screen_cast_stream_src_blit_to_framebuffer (src, dmabuf_fbo);
|
||||
return meta_screen_cast_stream_src_record_to_framebuffer (src,
|
||||
dmabuf_fbo,
|
||||
error);
|
||||
}
|
||||
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Unknown SPA buffer type %u", spa_buffer->datas[0].type);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_screen_cast_stream_src_pending_follow_up_frame (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
|
||||
return priv->follow_up_frame_source_id != 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
follow_up_frame_cb (gpointer user_data)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = user_data;
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
|
||||
priv->follow_up_frame_source_id = 0;
|
||||
meta_screen_cast_stream_src_record_follow_up (src);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_schedule_follow_up_frame (MetaScreenCastStreamSrc *src,
|
||||
int64_t timeout_us)
|
||||
{
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
|
||||
if (priv->follow_up_frame_source_id)
|
||||
return;
|
||||
|
||||
priv->follow_up_frame_source_id = g_timeout_add (us2ms (timeout_us),
|
||||
follow_up_frame_cb,
|
||||
src);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
|
||||
meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
|
||||
MetaScreenCastRecordFlag flags)
|
||||
{
|
||||
MetaScreenCastStreamSrcPrivate *priv =
|
||||
meta_screen_cast_stream_src_get_instance_private (src);
|
||||
@ -443,13 +506,29 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
|
||||
struct spa_buffer *spa_buffer;
|
||||
uint8_t *data = NULL;
|
||||
uint64_t now_us;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
now_us = g_get_monotonic_time ();
|
||||
if (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)))
|
||||
return;
|
||||
if (priv->video_format.max_framerate.num > 0 &&
|
||||
priv->last_frame_timestamp_us != 0)
|
||||
{
|
||||
int64_t min_interval_us;
|
||||
int64_t time_since_last_frame_us;
|
||||
|
||||
min_interval_us =
|
||||
((G_USEC_PER_SEC * priv->video_format.max_framerate.denom) /
|
||||
priv->video_format.max_framerate.num);
|
||||
|
||||
time_since_last_frame_us = now_us - priv->last_frame_timestamp_us;
|
||||
if (time_since_last_frame_us < min_interval_us)
|
||||
{
|
||||
int64_t timeout_us;
|
||||
|
||||
timeout_us = min_interval_us - time_since_last_frame_us;
|
||||
maybe_schedule_follow_up_frame (src, timeout_us);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!priv->pipewire_stream)
|
||||
return;
|
||||
@ -467,34 +546,43 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
|
||||
return;
|
||||
}
|
||||
|
||||
if (do_record_frame (src, spa_buffer, data))
|
||||
if (!(flags & META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY))
|
||||
{
|
||||
struct spa_meta_region *spa_meta_video_crop;
|
||||
|
||||
spa_buffer->datas[0].chunk->size = spa_buffer->datas[0].maxsize;
|
||||
spa_buffer->datas[0].chunk->stride = priv->video_stride;
|
||||
|
||||
/* Update VideoCrop if needed */
|
||||
spa_meta_video_crop =
|
||||
spa_buffer_find_meta_data (spa_buffer, SPA_META_VideoCrop,
|
||||
sizeof (*spa_meta_video_crop));
|
||||
if (spa_meta_video_crop)
|
||||
g_clear_handle_id (&priv->follow_up_frame_source_id, g_source_remove);
|
||||
if (do_record_frame (src, spa_buffer, data, &error))
|
||||
{
|
||||
if (meta_screen_cast_stream_src_get_videocrop (src, &crop_rect))
|
||||
struct spa_meta_region *spa_meta_video_crop;
|
||||
|
||||
spa_buffer->datas[0].chunk->size = spa_buffer->datas[0].maxsize;
|
||||
spa_buffer->datas[0].chunk->stride = priv->video_stride;
|
||||
|
||||
/* Update VideoCrop if needed */
|
||||
spa_meta_video_crop =
|
||||
spa_buffer_find_meta_data (spa_buffer, SPA_META_VideoCrop,
|
||||
sizeof (*spa_meta_video_crop));
|
||||
if (spa_meta_video_crop)
|
||||
{
|
||||
spa_meta_video_crop->region.position.x = crop_rect.x;
|
||||
spa_meta_video_crop->region.position.y = crop_rect.y;
|
||||
spa_meta_video_crop->region.size.width = crop_rect.width;
|
||||
spa_meta_video_crop->region.size.height = crop_rect.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
spa_meta_video_crop->region.position.x = 0;
|
||||
spa_meta_video_crop->region.position.y = 0;
|
||||
spa_meta_video_crop->region.size.width = priv->stream_width;
|
||||
spa_meta_video_crop->region.size.height = priv->stream_height;
|
||||
if (meta_screen_cast_stream_src_get_videocrop (src, &crop_rect))
|
||||
{
|
||||
spa_meta_video_crop->region.position.x = crop_rect.x;
|
||||
spa_meta_video_crop->region.position.y = crop_rect.y;
|
||||
spa_meta_video_crop->region.size.width = crop_rect.width;
|
||||
spa_meta_video_crop->region.size.height = crop_rect.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
spa_meta_video_crop->region.position.x = 0;
|
||||
spa_meta_video_crop->region.position.y = 0;
|
||||
spa_meta_video_crop->region.size.width = priv->stream_width;
|
||||
spa_meta_video_crop->region.size.height = priv->stream_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to record screen cast frame: %s", error->message);
|
||||
spa_buffer->datas[0].chunk->size = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -536,13 +624,9 @@ meta_screen_cast_stream_src_disable (MetaScreenCastStreamSrc *src)
|
||||
|
||||
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src)->disable (src);
|
||||
|
||||
priv->is_enabled = FALSE;
|
||||
}
|
||||
g_clear_handle_id (&priv->follow_up_frame_source_id, g_source_remove);
|
||||
|
||||
static void
|
||||
meta_screen_cast_stream_src_notify_closed (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
g_signal_emit (src, signals[CLOSED], 0);
|
||||
priv->is_enabled = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -559,7 +643,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 +913,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 +940,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 +973,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 +1012,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 +1074,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);
|
||||
|
@ -37,6 +37,12 @@
|
||||
|
||||
typedef struct _MetaScreenCastStream MetaScreenCastStream;
|
||||
|
||||
typedef enum _MetaScreenCastRecordFlag
|
||||
{
|
||||
META_SCREEN_CAST_RECORD_FLAG_NONE = 0,
|
||||
META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY = 1 << 0,
|
||||
} MetaScreenCastRecordFlag;
|
||||
|
||||
#define META_TYPE_SCREEN_CAST_STREAM_SRC (meta_screen_cast_stream_src_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (MetaScreenCastStreamSrc,
|
||||
meta_screen_cast_stream_src,
|
||||
@ -53,17 +59,24 @@ struct _MetaScreenCastStreamSrcClass
|
||||
float *frame_rate);
|
||||
void (* enable) (MetaScreenCastStreamSrc *src);
|
||||
void (* disable) (MetaScreenCastStreamSrc *src);
|
||||
gboolean (* record_frame) (MetaScreenCastStreamSrc *src,
|
||||
uint8_t *data);
|
||||
gboolean (* blit_to_framebuffer) (MetaScreenCastStreamSrc *src,
|
||||
CoglFramebuffer *framebuffer);
|
||||
gboolean (* record_to_buffer) (MetaScreenCastStreamSrc *src,
|
||||
uint8_t *data,
|
||||
GError **error);
|
||||
gboolean (* record_to_framebuffer) (MetaScreenCastStreamSrc *src,
|
||||
CoglFramebuffer *framebuffer,
|
||||
GError **error);
|
||||
void (* record_follow_up) (MetaScreenCastStreamSrc *src);
|
||||
|
||||
gboolean (* get_videocrop) (MetaScreenCastStreamSrc *src,
|
||||
MetaRectangle *crop_rect);
|
||||
void (* set_cursor_metadata) (MetaScreenCastStreamSrc *src,
|
||||
struct spa_meta_cursor *spa_meta_cursor);
|
||||
};
|
||||
|
||||
void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src);
|
||||
void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
|
||||
MetaScreenCastRecordFlag flags);
|
||||
|
||||
gboolean meta_screen_cast_stream_src_pending_follow_up_frame (MetaScreenCastStreamSrc *src);
|
||||
|
||||
MetaScreenCastStream * meta_screen_cast_stream_src_get_stream (MetaScreenCastStreamSrc *src);
|
||||
|
||||
|
@ -327,8 +327,10 @@ screen_cast_window_damaged (MetaWindowActor *actor,
|
||||
MetaScreenCastWindowStreamSrc *window_src)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
|
||||
MetaScreenCastRecordFlag flags;
|
||||
|
||||
meta_screen_cast_stream_src_maybe_record_frame (src);
|
||||
flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
|
||||
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -365,6 +367,7 @@ static void
|
||||
sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src)
|
||||
{
|
||||
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
|
||||
MetaScreenCastRecordFlag flags;
|
||||
|
||||
if (!is_cursor_in_stream (window_src))
|
||||
return;
|
||||
@ -372,7 +375,8 @@ sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src)
|
||||
if (meta_screen_cast_window_has_damage (window_src->screen_cast_window))
|
||||
return;
|
||||
|
||||
meta_screen_cast_stream_src_maybe_record_frame (src);
|
||||
flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
|
||||
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -401,6 +405,7 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src)
|
||||
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
|
||||
MetaWindowActor *window_actor;
|
||||
MetaScreenCastStream *stream;
|
||||
MetaScreenCastRecordFlag flags;
|
||||
|
||||
window_actor = meta_window_actor_from_window (get_window (window_src));
|
||||
if (!window_actor)
|
||||
@ -438,7 +443,8 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src)
|
||||
break;
|
||||
}
|
||||
|
||||
meta_screen_cast_stream_src_maybe_record_frame (src);
|
||||
flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
|
||||
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -451,8 +457,9 @@ meta_screen_cast_window_stream_src_disable (MetaScreenCastStreamSrc *src)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_screen_cast_window_stream_src_record_frame (MetaScreenCastStreamSrc *src,
|
||||
uint8_t *data)
|
||||
meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
|
||||
uint8_t *data,
|
||||
GError **error)
|
||||
{
|
||||
MetaScreenCastWindowStreamSrc *window_src =
|
||||
META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
|
||||
@ -463,8 +470,9 @@ meta_screen_cast_window_stream_src_record_frame (MetaScreenCastStreamSrc *src,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_screen_cast_window_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
|
||||
CoglFramebuffer *framebuffer)
|
||||
meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
|
||||
CoglFramebuffer *framebuffer,
|
||||
GError **error)
|
||||
{
|
||||
MetaScreenCastWindowStreamSrc *window_src =
|
||||
META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
|
||||
@ -477,9 +485,13 @@ meta_screen_cast_window_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc
|
||||
stream_rect.height = get_stream_height (window_src);
|
||||
|
||||
if (!meta_screen_cast_window_blit_to_framebuffer (window_src->screen_cast_window,
|
||||
&stream_rect,
|
||||
framebuffer))
|
||||
return FALSE;
|
||||
&stream_rect,
|
||||
framebuffer))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Failed to blit window content to framebuffer");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
stream = meta_screen_cast_stream_src_get_stream (src);
|
||||
switch (meta_screen_cast_stream_get_cursor_mode (stream))
|
||||
@ -497,6 +509,15 @@ meta_screen_cast_window_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_window_stream_record_follow_up (MetaScreenCastStreamSrc *src)
|
||||
{
|
||||
MetaScreenCastRecordFlag flags;
|
||||
|
||||
flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
|
||||
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_window_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
|
||||
struct spa_meta_cursor *spa_meta_cursor)
|
||||
@ -580,9 +601,12 @@ meta_screen_cast_window_stream_src_class_init (MetaScreenCastWindowStreamSrcClas
|
||||
src_class->get_specs = meta_screen_cast_window_stream_src_get_specs;
|
||||
src_class->enable = meta_screen_cast_window_stream_src_enable;
|
||||
src_class->disable = meta_screen_cast_window_stream_src_disable;
|
||||
src_class->record_frame = meta_screen_cast_window_stream_src_record_frame;
|
||||
src_class->blit_to_framebuffer =
|
||||
meta_screen_cast_window_stream_src_blit_to_framebuffer;
|
||||
src_class->record_to_buffer =
|
||||
meta_screen_cast_window_stream_src_record_to_buffer;
|
||||
src_class->record_to_framebuffer =
|
||||
meta_screen_cast_window_stream_src_record_to_framebuffer;
|
||||
src_class->record_follow_up =
|
||||
meta_screen_cast_window_stream_record_follow_up;
|
||||
src_class->get_videocrop = meta_screen_cast_window_stream_src_get_videocrop;
|
||||
src_class->set_cursor_metadata = meta_screen_cast_window_stream_src_set_cursor_metadata;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -232,14 +232,28 @@ meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms,
|
||||
uint64_t state,
|
||||
MetaKmsUpdate *kms_update)
|
||||
{
|
||||
MetaGpu *gpu = META_GPU (gpu_kms);
|
||||
GList *l;
|
||||
|
||||
for (l = meta_gpu_get_outputs (META_GPU (gpu_kms)); l; l = l->next)
|
||||
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
|
||||
{
|
||||
MetaOutput *output = l->data;
|
||||
|
||||
meta_output_kms_set_power_save_mode (output, state, kms_update);
|
||||
}
|
||||
|
||||
if (state != META_POWER_SAVE_ON)
|
||||
{
|
||||
/* Turn off CRTCs for DPMS */
|
||||
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
|
||||
{
|
||||
MetaCrtc *crtc = META_CRTC (l->data);
|
||||
|
||||
meta_kms_update_mode_set (kms_update,
|
||||
meta_crtc_kms_get_kms_crtc (crtc),
|
||||
NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -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;
|
||||
|
@ -2146,6 +2146,7 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
{
|
||||
CoglFramebuffer *dmabuf_fb;
|
||||
CoglDmaBufHandle *dmabuf_handle;
|
||||
struct gbm_bo *new_bo;
|
||||
int dmabuf_fd = -1;
|
||||
|
||||
@ -2182,8 +2183,11 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
|
||||
if (!dmabuf_fb)
|
||||
return NULL;
|
||||
|
||||
return cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd, new_bo,
|
||||
(GDestroyNotify) gbm_bo_destroy);
|
||||
dmabuf_handle =
|
||||
cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd, new_bo,
|
||||
(GDestroyNotify) gbm_bo_destroy);
|
||||
cogl_object_unref (dmabuf_fb);
|
||||
return dmabuf_handle;
|
||||
}
|
||||
break;
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
@ -3037,6 +3041,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 +3113,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -845,12 +843,16 @@ meta_stage_x11_translate_event (MetaStageX11 *stage_x11,
|
||||
g_debug ("Client message for stage, win:0x%x",
|
||||
(unsigned int) xevent->xany.window);
|
||||
|
||||
if (handle_wm_protocols_event (backend_x11, stage_x11, xevent))
|
||||
if (xevent->xclient.message_type == backend_x11->atom_WM_PROTOCOLS)
|
||||
{
|
||||
event->any.type = CLUTTER_DELETE;
|
||||
event->any.stage = stage;
|
||||
res = TRUE;
|
||||
if (handle_wm_protocols_event (backend_x11, stage_x11, xevent))
|
||||
{
|
||||
event->any.type = CLUTTER_DELETE;
|
||||
event->any.stage = stage;
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -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
|
||||
|
||||
|
@ -354,7 +354,7 @@ setup_pipeline (MetaBackgroundActor *self,
|
||||
guint8 opacity;
|
||||
float color_component;
|
||||
CoglFramebuffer *fb;
|
||||
CoglPipelineFilter filter;
|
||||
CoglPipelineFilter min_filter, mag_filter;
|
||||
|
||||
opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self));
|
||||
if (opacity < 255)
|
||||
@ -455,11 +455,17 @@ setup_pipeline (MetaBackgroundActor *self,
|
||||
actor_pixel_rect->width,
|
||||
actor_pixel_rect->height,
|
||||
NULL, NULL))
|
||||
filter = COGL_PIPELINE_FILTER_NEAREST;
|
||||
{
|
||||
min_filter = COGL_PIPELINE_FILTER_NEAREST;
|
||||
mag_filter = COGL_PIPELINE_FILTER_NEAREST;
|
||||
}
|
||||
else
|
||||
filter = COGL_PIPELINE_FILTER_LINEAR;
|
||||
{
|
||||
min_filter = COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST;
|
||||
mag_filter = COGL_PIPELINE_FILTER_LINEAR;
|
||||
}
|
||||
|
||||
cogl_pipeline_set_layer_filters (self->pipeline, 0, filter, filter);
|
||||
cogl_pipeline_set_layer_filters (self->pipeline, 0, min_filter, mag_filter);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -66,4 +66,7 @@ gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
||||
int meta_shaped_texture_get_width (MetaShapedTexture *stex);
|
||||
int meta_shaped_texture_get_height (MetaShapedTexture *stex);
|
||||
|
||||
void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
|
||||
cairo_region_t *clip_region);
|
||||
|
||||
#endif
|
||||
|
@ -87,6 +87,9 @@ struct _MetaShapedTexture
|
||||
/* The region containing only fully opaque pixels */
|
||||
cairo_region_t *opaque_region;
|
||||
|
||||
/* MetaCullable regions, see that documentation for more details */
|
||||
cairo_region_t *clip_region;
|
||||
|
||||
gboolean size_invalid;
|
||||
MetaMonitorTransform transform;
|
||||
gboolean has_viewport_src_rect;
|
||||
@ -214,6 +217,15 @@ ensure_size_valid (MetaShapedTexture *stex)
|
||||
update_size (stex);
|
||||
}
|
||||
|
||||
void
|
||||
meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
g_clear_pointer (&stex->clip_region, cairo_region_destroy);
|
||||
if (clip_region)
|
||||
stex->clip_region = cairo_region_reference (clip_region);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
|
||||
{
|
||||
@ -239,6 +251,7 @@ meta_shaped_texture_dispose (GObject *object)
|
||||
meta_shaped_texture_reset_pipelines (stex);
|
||||
|
||||
g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
|
||||
g_clear_pointer (&stex->clip_region, cairo_region_destroy);
|
||||
|
||||
g_clear_pointer (&stex->snippet, cogl_object_unref);
|
||||
|
||||
@ -390,17 +403,14 @@ get_unblended_pipeline (MetaShapedTexture *stex,
|
||||
CoglContext *ctx)
|
||||
{
|
||||
CoglPipeline *pipeline;
|
||||
CoglColor color;
|
||||
|
||||
if (stex->unblended_pipeline)
|
||||
return stex->unblended_pipeline;
|
||||
|
||||
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
|
||||
cogl_color_init_from_4ub (&color, 255, 255, 255, 255);
|
||||
cogl_pipeline_set_blend (pipeline,
|
||||
"RGBA = ADD (SRC_COLOR, 0)",
|
||||
NULL);
|
||||
cogl_pipeline_set_color (pipeline, &color);
|
||||
cogl_pipeline_set_layer_combine (pipeline, 0,
|
||||
"RGBA = REPLACE (TEXTURE)",
|
||||
NULL);
|
||||
|
||||
stex->unblended_pipeline = pipeline;
|
||||
|
||||
@ -585,12 +595,19 @@ do_paint_content (MetaShapedTexture *stex,
|
||||
|
||||
if (use_opaque_region)
|
||||
{
|
||||
blended_tex_region = cairo_region_create_rectangle (&content_rect);
|
||||
if (stex->clip_region)
|
||||
blended_tex_region = cairo_region_copy (stex->clip_region);
|
||||
else
|
||||
blended_tex_region = cairo_region_create_rectangle (&content_rect);
|
||||
|
||||
cairo_region_subtract (blended_tex_region, stex->opaque_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
blended_tex_region = NULL;
|
||||
if (stex->clip_region)
|
||||
blended_tex_region = cairo_region_reference (stex->clip_region);
|
||||
else
|
||||
blended_tex_region = NULL;
|
||||
}
|
||||
|
||||
/* Limit to how many separate rectangles we'll draw; beyond this just
|
||||
@ -612,10 +629,21 @@ do_paint_content (MetaShapedTexture *stex,
|
||||
/* First, paint the unblended parts, which are part of the opaque region. */
|
||||
if (use_opaque_region)
|
||||
{
|
||||
cairo_region_t *region;
|
||||
int n_rects;
|
||||
int i;
|
||||
|
||||
if (!cairo_region_is_empty (stex->opaque_region))
|
||||
if (stex->clip_region)
|
||||
{
|
||||
region = cairo_region_copy (stex->clip_region);
|
||||
cairo_region_intersect (region, stex->opaque_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
region = cairo_region_reference (stex->opaque_region);
|
||||
}
|
||||
|
||||
if (!cairo_region_is_empty (region))
|
||||
{
|
||||
CoglPipeline *opaque_pipeline;
|
||||
|
||||
@ -623,16 +651,18 @@ do_paint_content (MetaShapedTexture *stex,
|
||||
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
|
||||
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
|
||||
|
||||
n_rects = cairo_region_num_rectangles (stex->opaque_region);
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_region_get_rectangle (stex->opaque_region, i, &rect);
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
paint_clipped_rectangle_node (stex, root_node,
|
||||
opaque_pipeline,
|
||||
&rect, alloc);
|
||||
}
|
||||
}
|
||||
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
|
||||
/* Now, go ahead and paint the blended parts. */
|
||||
@ -757,6 +787,9 @@ meta_shaped_texture_paint_content (ClutterContent *content,
|
||||
CoglTexture *paint_tex = NULL;
|
||||
uint8_t opacity;
|
||||
|
||||
if (stex->clip_region && cairo_region_is_empty (stex->clip_region))
|
||||
return;
|
||||
|
||||
/* The GL EXT_texture_from_pixmap extension does allow for it to be
|
||||
* used together with SGIS_generate_mipmap, however this is very
|
||||
* rarely supported. Also, even when it is supported there
|
||||
|
@ -34,7 +34,6 @@ typedef struct _MetaSurfaceActorPrivate
|
||||
cairo_region_t *input_region;
|
||||
|
||||
/* MetaCullable regions, see that documentation for more details */
|
||||
cairo_region_t *clip_region;
|
||||
cairo_region_t *unobscured_region;
|
||||
|
||||
/* Freeze/thaw accounting */
|
||||
@ -58,6 +57,12 @@ enum
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IN_STAGE_PERSPECTIVE,
|
||||
IN_ACTOR_PERSPECTIVE
|
||||
} ScalePerspectiveType;
|
||||
|
||||
static cairo_region_t *
|
||||
effective_unobscured_region (MetaSurfaceActor *surface_actor)
|
||||
{
|
||||
@ -79,18 +84,39 @@ effective_unobscured_region (MetaSurfaceActor *surface_actor)
|
||||
}
|
||||
|
||||
static cairo_region_t*
|
||||
get_scaled_region (MetaSurfaceActor *surface_actor,
|
||||
cairo_region_t *region)
|
||||
get_scaled_region (MetaSurfaceActor *surface_actor,
|
||||
cairo_region_t *region,
|
||||
ScalePerspectiveType scale_perspective)
|
||||
{
|
||||
MetaWindowActor *window_actor;
|
||||
cairo_region_t *scaled_region;
|
||||
int geometry_scale;
|
||||
float x, y;
|
||||
|
||||
window_actor = meta_window_actor_from_actor (CLUTTER_ACTOR (surface_actor));
|
||||
geometry_scale = meta_window_actor_get_geometry_scale (window_actor);
|
||||
|
||||
return meta_region_scale_double (region,
|
||||
1.0 / geometry_scale,
|
||||
META_ROUNDING_STRATEGY_GROW);
|
||||
clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
|
||||
cairo_region_translate (region, x, y);
|
||||
|
||||
switch (scale_perspective)
|
||||
{
|
||||
case IN_STAGE_PERSPECTIVE:
|
||||
scaled_region = meta_region_scale_double (region,
|
||||
geometry_scale,
|
||||
META_ROUNDING_STRATEGY_GROW);
|
||||
break;
|
||||
case IN_ACTOR_PERSPECTIVE:
|
||||
scaled_region = meta_region_scale_double (region,
|
||||
1.0 / geometry_scale,
|
||||
META_ROUNDING_STRATEGY_GROW);
|
||||
break;
|
||||
}
|
||||
|
||||
cairo_region_translate (region, -x, -y);
|
||||
cairo_region_translate (scaled_region, -x, -y);
|
||||
|
||||
return scaled_region;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -120,8 +146,9 @@ set_unobscured_region (MetaSurfaceActor *surface_actor,
|
||||
.height = height,
|
||||
};
|
||||
|
||||
priv->unobscured_region =
|
||||
get_scaled_region (surface_actor, unobscured_region);
|
||||
priv->unobscured_region = get_scaled_region (surface_actor,
|
||||
unobscured_region,
|
||||
IN_ACTOR_PERSPECTIVE);
|
||||
|
||||
cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
|
||||
}
|
||||
@ -134,30 +161,23 @@ set_clip_region (MetaSurfaceActor *surface_actor,
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv =
|
||||
meta_surface_actor_get_instance_private (surface_actor);
|
||||
MetaShapedTexture *stex = priv->texture;
|
||||
|
||||
g_clear_pointer (&priv->clip_region, cairo_region_destroy);
|
||||
if (clip_region)
|
||||
if (clip_region && !cairo_region_is_empty (clip_region))
|
||||
{
|
||||
if (cairo_region_is_empty (clip_region))
|
||||
priv->clip_region = cairo_region_reference (clip_region);
|
||||
else
|
||||
priv->clip_region = get_scaled_region (surface_actor, clip_region);
|
||||
cairo_region_t *region;
|
||||
|
||||
region = get_scaled_region (surface_actor,
|
||||
clip_region,
|
||||
IN_ACTOR_PERSPECTIVE);
|
||||
meta_shaped_texture_set_clip_region (stex, region);
|
||||
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_shaped_texture_set_clip_region (stex, clip_region);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_paint (ClutterActor *actor,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (actor);
|
||||
MetaSurfaceActorPrivate *priv =
|
||||
meta_surface_actor_get_instance_private (surface_actor);
|
||||
|
||||
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
|
||||
return;
|
||||
|
||||
CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->paint (actor,
|
||||
paint_context);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -227,7 +247,6 @@ meta_surface_actor_dispose (GObject *object)
|
||||
g_clear_object (&priv->texture);
|
||||
|
||||
set_unobscured_region (self, NULL);
|
||||
set_clip_region (self, NULL);
|
||||
|
||||
G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object);
|
||||
}
|
||||
@ -239,7 +258,6 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
object_class->dispose = meta_surface_actor_dispose;
|
||||
actor_class->paint = meta_surface_actor_paint;
|
||||
actor_class->pick = meta_surface_actor_pick;
|
||||
actor_class->get_paint_volume = meta_surface_actor_get_paint_volume;
|
||||
|
||||
@ -279,11 +297,8 @@ meta_surface_actor_cull_out (MetaCullable *cullable,
|
||||
|
||||
if (opacity == 0xff)
|
||||
{
|
||||
MetaWindowActor *window_actor;
|
||||
cairo_region_t *scaled_opaque_region;
|
||||
cairo_region_t *opaque_region;
|
||||
int geometry_scale;
|
||||
float x, y;
|
||||
cairo_region_t *scaled_opaque_region;
|
||||
|
||||
opaque_region = meta_shaped_texture_get_opaque_region (priv->texture);
|
||||
if (opaque_region)
|
||||
@ -306,14 +321,9 @@ meta_surface_actor_cull_out (MetaCullable *cullable,
|
||||
return;
|
||||
}
|
||||
|
||||
window_actor = meta_window_actor_from_actor (CLUTTER_ACTOR (surface_actor));
|
||||
geometry_scale = meta_window_actor_get_geometry_scale (window_actor);
|
||||
clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
|
||||
|
||||
cairo_region_translate (opaque_region, x, y);
|
||||
scaled_opaque_region = meta_region_scale (opaque_region, geometry_scale);
|
||||
cairo_region_translate (scaled_opaque_region, -x, -y);
|
||||
cairo_region_translate (opaque_region, -x, -y);
|
||||
scaled_opaque_region = get_scaled_region (surface_actor,
|
||||
opaque_region,
|
||||
IN_STAGE_PERSPECTIVE);
|
||||
|
||||
if (unobscured_region)
|
||||
cairo_region_subtract (unobscured_region, scaled_opaque_region);
|
||||
|
@ -139,29 +139,6 @@ meta_window_actor_wayland_set_frozen (MetaWindowActor *actor,
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_window_actor_wayland_get_paint_volume (ClutterActor *actor,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
MetaSurfaceActor *surface;
|
||||
|
||||
surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor));
|
||||
if (surface)
|
||||
{
|
||||
ClutterActor *surface_actor = CLUTTER_ACTOR (surface);
|
||||
const ClutterPaintVolume *child_volume;
|
||||
|
||||
child_volume = clutter_actor_get_transformed_paint_volume (surface_actor,
|
||||
actor);
|
||||
if (!child_volume)
|
||||
return FALSE;
|
||||
|
||||
clutter_paint_volume_union (volume, child_volume);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_wayland_update_regions (MetaWindowActor *actor)
|
||||
{
|
||||
@ -171,9 +148,6 @@ static void
|
||||
meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass)
|
||||
{
|
||||
MetaWindowActorClass *window_actor_class = META_WINDOW_ACTOR_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
actor_class->get_paint_volume = meta_window_actor_wayland_get_paint_volume;
|
||||
|
||||
window_actor_class->assign_surface_actor = meta_window_actor_wayland_assign_surface_actor;
|
||||
window_actor_class->frame_complete = meta_window_actor_wayland_frame_complete;
|
||||
|
@ -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);
|
||||
@ -1620,8 +1630,8 @@ meta_window_actor_x11_init (MetaWindowActorX11 *self)
|
||||
|
||||
self->shadow_factory = meta_shadow_factory_get_default ();
|
||||
self->shadow_factory_changed_handler_id =
|
||||
g_signal_connect (self->shadow_factory,
|
||||
"changed",
|
||||
G_CALLBACK (invalidate_shadow),
|
||||
self);
|
||||
g_signal_connect_swapped (self->shadow_factory,
|
||||
"changed",
|
||||
G_CALLBACK (invalidate_shadow),
|
||||
self);
|
||||
}
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -152,6 +152,7 @@ owner_changed_cb (MetaSelection *selection,
|
||||
display->saved_clipboard);
|
||||
g_set_object (&display->selection_source, new_owner);
|
||||
meta_selection_set_owner (selection, selection_type, new_owner);
|
||||
g_object_unref (new_owner);
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,6 +171,7 @@ meta_clipboard_manager_shutdown (MetaDisplay *display)
|
||||
{
|
||||
MetaSelection *selection;
|
||||
|
||||
g_clear_object (&display->selection_source);
|
||||
g_clear_pointer (&display->saved_clipboard, g_bytes_unref);
|
||||
g_clear_pointer (&display->saved_clipboard_mimetype, g_free);
|
||||
selection = meta_display_get_selection (display);
|
||||
|
@ -1,7 +1,5 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
* 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
|
||||
@ -19,16 +17,16 @@
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
* Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_WAYLAND_DATA_DEVICE_PRIVATE_H
|
||||
#define META_WAYLAND_DATA_DEVICE_PRIVATE_H
|
||||
#ifndef META_SELECTION_PRIVATE_H
|
||||
#define META_SELECTION_PRIVATE_H
|
||||
|
||||
#define META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY (meta_wayland_data_source_primary_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandDataSourcePrimary,
|
||||
meta_wayland_data_source_primary,
|
||||
META, WAYLAND_DATA_SOURCE_PRIMARY,
|
||||
MetaWaylandDataSource);
|
||||
#include "meta/meta-selection.h"
|
||||
|
||||
#endif /* META_WAYLAND_DATA_DEVICE_PRIVATE_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
|
||||
|
@ -495,7 +495,22 @@ if have_wayland
|
||||
'wayland/meta-wayland-cursor-surface.h',
|
||||
'wayland/meta-wayland-data-device.c',
|
||||
'wayland/meta-wayland-data-device.h',
|
||||
'wayland/meta-wayland-data-device-private.h',
|
||||
'wayland/meta-wayland-data-device-primary.c',
|
||||
'wayland/meta-wayland-data-device-primary.h',
|
||||
'wayland/meta-wayland-data-device-primary-legacy.c',
|
||||
'wayland/meta-wayland-data-device-primary-legacy.h',
|
||||
'wayland/meta-wayland-data-offer.c',
|
||||
'wayland/meta-wayland-data-offer.h',
|
||||
'wayland/meta-wayland-data-offer-primary.c',
|
||||
'wayland/meta-wayland-data-offer-primary.h',
|
||||
'wayland/meta-wayland-data-offer-primary-legacy.c',
|
||||
'wayland/meta-wayland-data-offer-primary-legacy.h',
|
||||
'wayland/meta-wayland-data-source.c',
|
||||
'wayland/meta-wayland-data-source.h',
|
||||
'wayland/meta-wayland-data-source-primary.c',
|
||||
'wayland/meta-wayland-data-source-primary.h',
|
||||
'wayland/meta-wayland-data-source-primary-legacy.c',
|
||||
'wayland/meta-wayland-data-source-primary-legacy.h',
|
||||
'wayland/meta-wayland-dma-buf.c',
|
||||
'wayland/meta-wayland-dma-buf.h',
|
||||
'wayland/meta-wayland-dnd-surface.c',
|
||||
@ -790,6 +805,7 @@ if have_wayland
|
||||
['linux-dmabuf', 'unstable', 'v1', ],
|
||||
['pointer-constraints', 'unstable', 'v1', ],
|
||||
['pointer-gestures', 'unstable', 'v1', ],
|
||||
['primary-selection', 'unstable', 'v1', ],
|
||||
['relative-pointer', 'unstable', 'v1', ],
|
||||
['tablet', 'unstable', 'v2', ],
|
||||
['text-input', 'unstable', 'v3', ],
|
||||
|
@ -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);
|
||||
|
@ -112,7 +112,7 @@ test_cogl_multitexture_main (int argc, char *argv[])
|
||||
GError *error = NULL;
|
||||
ClutterActor *stage;
|
||||
ClutterColor stage_color = { 0x61, 0x56, 0x56, 0xff };
|
||||
TestMultiLayerMaterialState *state = g_new0 (TestMultiLayerMaterialState, 1);
|
||||
g_autofree TestMultiLayerMaterialState *state = g_new0 (TestMultiLayerMaterialState, 1);
|
||||
gfloat stage_w, stage_h;
|
||||
gchar **files;
|
||||
gfloat tex_coords[] =
|
||||
|
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",
|
||||
|
@ -427,7 +427,7 @@ test_client_new (const char *id,
|
||||
MetaWindowClientType type,
|
||||
GError **error)
|
||||
{
|
||||
TestClient *client = g_new0 (TestClient, 1);
|
||||
TestClient *client;
|
||||
GSubprocessLauncher *launcher;
|
||||
GSubprocess *subprocess;
|
||||
MetaWaylandCompositor *compositor;
|
||||
@ -462,6 +462,7 @@ test_client_new (const char *id,
|
||||
if (!subprocess)
|
||||
return NULL;
|
||||
|
||||
client = g_new0 (TestClient, 1);
|
||||
client->type = type;
|
||||
client->id = g_strdup (id);
|
||||
client->cancellable = g_cancellable_new ();
|
||||
|
@ -26,7 +26,6 @@
|
||||
|
||||
#include "meta/meta-selection-source.h"
|
||||
#include "wayland/meta-wayland-data-device.h"
|
||||
#include "wayland/meta-wayland-data-device-private.h"
|
||||
|
||||
#define META_TYPE_SELECTION_SOURCE_WAYLAND (meta_selection_source_wayland_get_type ())
|
||||
|
||||
|
354
src/wayland/meta-wayland-data-device-primary-legacy.c
Normal file
354
src/wayland/meta-wayland-data-device-primary-legacy.c
Normal file
@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* The file is based on src/data-device.c from Weston */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "wayland/meta-wayland-data-device-primary-legacy.h"
|
||||
|
||||
#include "compositor/meta-dnd-actor-private.h"
|
||||
#include "meta/meta-selection-source-memory.h"
|
||||
#include "wayland/meta-selection-source-wayland-private.h"
|
||||
#include "wayland/meta-wayland-data-offer-primary-legacy.h"
|
||||
#include "wayland/meta-wayland-data-source-primary-legacy.h"
|
||||
#include "wayland/meta-wayland-dnd-surface.h"
|
||||
#include "wayland/meta-wayland-pointer.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#include "wayland/meta-wayland-seat.h"
|
||||
|
||||
#include "gtk-primary-selection-server-protocol.h"
|
||||
|
||||
static struct wl_resource * create_and_send_primary_offer (MetaWaylandDataDevicePrimaryLegacy *data_device,
|
||||
struct wl_resource *target);
|
||||
|
||||
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)
|
||||
{
|
||||
wl_list_remove (wl_resource_get_link (resource));
|
||||
}
|
||||
|
||||
static void
|
||||
default_destructor (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
set_selection_source (MetaWaylandDataDevicePrimaryLegacy *data_device,
|
||||
MetaSelectionSource *selection_source)
|
||||
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
meta_selection_set_owner (meta_display_get_selection (display),
|
||||
META_SELECTION_PRIMARY,
|
||||
selection_source);
|
||||
g_set_object (&data_device->owner, selection_source);
|
||||
}
|
||||
|
||||
static void
|
||||
unset_selection_source (MetaWaylandDataDevicePrimaryLegacy *data_device)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
if (!data_device->owner)
|
||||
return;
|
||||
|
||||
meta_selection_unset_owner (meta_display_get_selection (display),
|
||||
META_SELECTION_PRIMARY,
|
||||
data_device->owner);
|
||||
g_clear_object (&data_device->owner);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_source_destroyed (gpointer data,
|
||||
GObject *object_was_here)
|
||||
{
|
||||
MetaWaylandDataDevicePrimaryLegacy *data_device = data;
|
||||
|
||||
data_device->data_source = NULL;
|
||||
unset_selection_source (data_device);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_device_primary_legacy_set_selection (MetaWaylandDataDevicePrimaryLegacy *data_device,
|
||||
MetaWaylandDataSource *source,
|
||||
uint32_t serial)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_legacy_data_device);
|
||||
MetaSelectionSource *selection_source;
|
||||
|
||||
g_assert (!source || META_IS_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY (source));
|
||||
|
||||
if (data_device->data_source &&
|
||||
data_device->serial - serial < UINT32_MAX / 2)
|
||||
return;
|
||||
|
||||
if (data_device->data_source)
|
||||
{
|
||||
g_object_weak_unref (G_OBJECT (data_device->data_source),
|
||||
primary_source_destroyed,
|
||||
data_device);
|
||||
}
|
||||
|
||||
data_device->data_source = source;
|
||||
data_device->serial = serial;
|
||||
|
||||
if (source)
|
||||
{
|
||||
meta_wayland_data_source_set_seat (source, seat);
|
||||
g_object_weak_ref (G_OBJECT (source),
|
||||
primary_source_destroyed,
|
||||
data_device);
|
||||
|
||||
selection_source = meta_selection_source_wayland_new (source);
|
||||
}
|
||||
else
|
||||
{
|
||||
selection_source = g_object_new (META_TYPE_SELECTION_SOURCE_MEMORY, NULL);
|
||||
}
|
||||
|
||||
set_selection_source (data_device, selection_source);
|
||||
g_object_unref (selection_source);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_device_set_selection (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *source_resource,
|
||||
uint32_t serial)
|
||||
{
|
||||
MetaWaylandDataDevicePrimaryLegacy *data_device = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_legacy_data_device);
|
||||
MetaWaylandDataSource *source = NULL;
|
||||
|
||||
if (source_resource)
|
||||
source = wl_resource_get_user_data (source_resource);
|
||||
|
||||
if (wl_resource_get_client (resource) !=
|
||||
meta_wayland_keyboard_get_focus_client (seat->keyboard))
|
||||
return;
|
||||
|
||||
meta_wayland_data_device_primary_legacy_set_selection (data_device, source, serial);
|
||||
}
|
||||
|
||||
static const struct gtk_primary_selection_device_interface primary_device_interface = {
|
||||
primary_device_set_selection,
|
||||
default_destructor,
|
||||
};
|
||||
|
||||
static void
|
||||
owner_changed_cb (MetaSelection *selection,
|
||||
MetaSelectionType selection_type,
|
||||
MetaSelectionSource *new_owner,
|
||||
MetaWaylandDataDevicePrimaryLegacy *data_device)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaWaylandSeat *seat = compositor->seat;
|
||||
struct wl_resource *data_device_resource;
|
||||
struct wl_client *focus_client;
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||
if (!focus_client)
|
||||
return;
|
||||
|
||||
if (selection_type == META_SELECTION_PRIMARY)
|
||||
{
|
||||
wl_resource_for_each (data_device_resource, &data_device->focus_resource_list)
|
||||
{
|
||||
struct wl_resource *offer = NULL;
|
||||
|
||||
if (new_owner)
|
||||
{
|
||||
offer = create_and_send_primary_offer (data_device,
|
||||
data_device_resource);
|
||||
}
|
||||
|
||||
gtk_primary_selection_device_send_selection (data_device_resource,
|
||||
offer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_owners_changed_handler_connected (MetaWaylandDataDevicePrimaryLegacy *data_device)
|
||||
{
|
||||
if (data_device->selection_owner_signal_id != 0)
|
||||
return;
|
||||
|
||||
data_device->selection_owner_signal_id =
|
||||
g_signal_connect (meta_display_get_selection (meta_get_display ()),
|
||||
"owner-changed",
|
||||
G_CALLBACK (owner_changed_cb), data_device);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_device_manager_create_source (struct wl_client *client,
|
||||
struct wl_resource *manager_resource,
|
||||
guint32 id)
|
||||
{
|
||||
struct wl_resource *source_resource;
|
||||
|
||||
source_resource =
|
||||
wl_resource_create (client, >k_primary_selection_source_interface,
|
||||
wl_resource_get_version (manager_resource),
|
||||
id);
|
||||
meta_wayland_data_source_primary_legacy_new (source_resource);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_device_manager_get_device (struct wl_client *client,
|
||||
struct wl_resource *manager_resource,
|
||||
guint32 id,
|
||||
struct wl_resource *seat_resource)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||
struct wl_resource *cr;
|
||||
|
||||
cr = wl_resource_create (client, >k_primary_selection_device_interface,
|
||||
wl_resource_get_version (manager_resource), id);
|
||||
wl_resource_set_implementation (cr, &primary_device_interface,
|
||||
&seat->primary_legacy_data_device, unbind_resource);
|
||||
wl_list_insert (&seat->primary_legacy_data_device.resource_list,
|
||||
wl_resource_get_link (cr));
|
||||
|
||||
ensure_owners_changed_handler_connected (&seat->primary_legacy_data_device);
|
||||
}
|
||||
|
||||
static const struct gtk_primary_selection_device_manager_interface primary_manager_interface = {
|
||||
primary_device_manager_create_source,
|
||||
primary_device_manager_get_device,
|
||||
default_destructor,
|
||||
};
|
||||
|
||||
static void
|
||||
bind_primary_manager (struct wl_client *client,
|
||||
void *data,
|
||||
uint32_t version,
|
||||
uint32_t id)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, >k_primary_selection_device_manager_interface,
|
||||
version, id);
|
||||
wl_resource_set_implementation (resource, &primary_manager_interface, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_device_primary_legacy_manager_init (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
if (wl_global_create (compositor->wayland_display,
|
||||
>k_primary_selection_device_manager_interface,
|
||||
1, NULL, bind_primary_manager) == NULL)
|
||||
g_error ("Could not create data_device");
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_device_primary_legacy_init (MetaWaylandDataDevicePrimaryLegacy *data_device)
|
||||
{
|
||||
wl_list_init (&data_device->resource_list);
|
||||
wl_list_init (&data_device->focus_resource_list);
|
||||
}
|
||||
|
||||
static struct wl_resource *
|
||||
create_and_send_primary_offer (MetaWaylandDataDevicePrimaryLegacy *data_device,
|
||||
struct wl_resource *target)
|
||||
{
|
||||
MetaWaylandDataOffer *offer;
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
struct wl_resource *resource;
|
||||
GList *mimetypes, *l;
|
||||
|
||||
mimetypes = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||
META_SELECTION_PRIMARY);
|
||||
if (!mimetypes)
|
||||
return NULL;
|
||||
|
||||
offer = meta_wayland_data_offer_primary_legacy_new (target);
|
||||
resource = meta_wayland_data_offer_get_resource (offer);
|
||||
|
||||
gtk_primary_selection_device_send_data_offer (target, resource);
|
||||
|
||||
for (l = mimetypes; l; l = l->next)
|
||||
gtk_primary_selection_offer_send_offer (resource, l->data);
|
||||
|
||||
g_list_free_full (mimetypes, g_free);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_device_primary_legacy_set_keyboard_focus (MetaWaylandDataDevicePrimaryLegacy *data_device)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_legacy_data_device);
|
||||
struct wl_client *focus_client;
|
||||
struct wl_resource *data_device_resource;
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||
|
||||
if (focus_client == data_device->focus_client)
|
||||
return;
|
||||
|
||||
data_device->focus_client = focus_client;
|
||||
move_resources (&data_device->resource_list,
|
||||
&data_device->focus_resource_list);
|
||||
|
||||
if (!focus_client)
|
||||
return;
|
||||
|
||||
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_primary_offer (data_device, data_device_resource);
|
||||
gtk_primary_selection_device_send_selection (data_device_resource, offer);
|
||||
}
|
||||
}
|
55
src/wayland/meta-wayland-data-device-primary-legacy.h
Normal file
55
src/wayland/meta-wayland-data-device-primary-legacy.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright © 2008 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef META_WAYLAND_DATA_DEVICE_PRIMARY_LEGACY_H
|
||||
#define META_WAYLAND_DATA_DEVICE_PRIMARY_LEGACY_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <wayland-server.h>
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
#include "meta/meta-selection-source.h"
|
||||
#include "wayland/meta-wayland-data-offer.h"
|
||||
#include "wayland/meta-wayland-data-source.h"
|
||||
#include "wayland/meta-wayland-types.h"
|
||||
|
||||
struct _MetaWaylandDataDevicePrimaryLegacy
|
||||
{
|
||||
uint32_t serial;
|
||||
MetaWaylandDataSource *data_source;
|
||||
struct wl_list resource_list;
|
||||
struct wl_list focus_resource_list;
|
||||
struct wl_client *focus_client;
|
||||
|
||||
guint selection_owner_signal_id;
|
||||
|
||||
MetaSelectionSource *owner;
|
||||
};
|
||||
|
||||
void meta_wayland_data_device_primary_legacy_manager_init (MetaWaylandCompositor *compositor);
|
||||
|
||||
void meta_wayland_data_device_primary_legacy_init (MetaWaylandDataDevicePrimaryLegacy *data_device);
|
||||
|
||||
void meta_wayland_data_device_primary_legacy_set_keyboard_focus (MetaWaylandDataDevicePrimaryLegacy *data_device);
|
||||
|
||||
#endif /* META_WAYLAND_DATA_DEVICE_PRIMARY_LEGACY_H */
|
353
src/wayland/meta-wayland-data-device-primary.c
Normal file
353
src/wayland/meta-wayland-data-device-primary.c
Normal file
@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* The file is based on src/data-device.c from Weston */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "wayland/meta-wayland-data-device-primary.h"
|
||||
|
||||
#include "compositor/meta-dnd-actor-private.h"
|
||||
#include "meta/meta-selection-source-memory.h"
|
||||
#include "wayland/meta-selection-source-wayland-private.h"
|
||||
#include "wayland/meta-wayland-data-offer-primary.h"
|
||||
#include "wayland/meta-wayland-data-source-primary.h"
|
||||
#include "wayland/meta-wayland-dnd-surface.h"
|
||||
#include "wayland/meta-wayland-pointer.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#include "wayland/meta-wayland-seat.h"
|
||||
|
||||
#include "primary-selection-unstable-v1-server-protocol.h"
|
||||
|
||||
static struct wl_resource * create_and_send_primary_offer (MetaWaylandDataDevicePrimary *data_device,
|
||||
struct wl_resource *target);
|
||||
|
||||
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)
|
||||
{
|
||||
wl_list_remove (wl_resource_get_link (resource));
|
||||
}
|
||||
|
||||
static void
|
||||
default_destructor (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
set_selection_source (MetaWaylandDataDevicePrimary *data_device,
|
||||
MetaSelectionSource *selection_source)
|
||||
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
meta_selection_set_owner (meta_display_get_selection (display),
|
||||
META_SELECTION_PRIMARY,
|
||||
selection_source);
|
||||
g_set_object (&data_device->owner, selection_source);
|
||||
}
|
||||
|
||||
static void
|
||||
unset_selection_source (MetaWaylandDataDevicePrimary *data_device)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
if (!data_device->owner)
|
||||
return;
|
||||
|
||||
meta_selection_unset_owner (meta_display_get_selection (display),
|
||||
META_SELECTION_PRIMARY,
|
||||
data_device->owner);
|
||||
g_clear_object (&data_device->owner);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_source_destroyed (gpointer data,
|
||||
GObject *object_was_here)
|
||||
{
|
||||
MetaWaylandDataDevicePrimary *data_device = data;
|
||||
|
||||
data_device->data_source = NULL;
|
||||
unset_selection_source (data_device);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_device_primary_set_selection (MetaWaylandDataDevicePrimary *data_device,
|
||||
MetaWaylandDataSource *source,
|
||||
uint32_t serial)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device);
|
||||
MetaSelectionSource *selection_source;
|
||||
|
||||
g_assert (!source || META_IS_WAYLAND_DATA_SOURCE_PRIMARY (source));
|
||||
|
||||
if (data_device->data_source &&
|
||||
data_device->serial - serial < UINT32_MAX / 2)
|
||||
return;
|
||||
|
||||
if (data_device->data_source)
|
||||
{
|
||||
g_object_weak_unref (G_OBJECT (data_device->data_source),
|
||||
primary_source_destroyed,
|
||||
data_device);
|
||||
}
|
||||
|
||||
data_device->data_source = source;
|
||||
data_device->serial = serial;
|
||||
|
||||
if (source)
|
||||
{
|
||||
meta_wayland_data_source_set_seat (source, seat);
|
||||
g_object_weak_ref (G_OBJECT (source),
|
||||
primary_source_destroyed,
|
||||
data_device);
|
||||
|
||||
selection_source = meta_selection_source_wayland_new (source);
|
||||
}
|
||||
else
|
||||
{
|
||||
selection_source = g_object_new (META_TYPE_SELECTION_SOURCE_MEMORY, NULL);
|
||||
}
|
||||
|
||||
set_selection_source (data_device, selection_source);
|
||||
g_object_unref (selection_source);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_device_set_selection (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *source_resource,
|
||||
uint32_t serial)
|
||||
{
|
||||
MetaWaylandDataDevicePrimary *data_device = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device);
|
||||
MetaWaylandDataSource *source = NULL;
|
||||
|
||||
if (source_resource)
|
||||
source = wl_resource_get_user_data (source_resource);
|
||||
|
||||
if (wl_resource_get_client (resource) !=
|
||||
meta_wayland_keyboard_get_focus_client (seat->keyboard))
|
||||
return;
|
||||
|
||||
meta_wayland_data_device_primary_set_selection (data_device, source, serial);
|
||||
}
|
||||
|
||||
static const struct zwp_primary_selection_device_v1_interface primary_device_interface = {
|
||||
primary_device_set_selection,
|
||||
default_destructor,
|
||||
};
|
||||
|
||||
static void
|
||||
owner_changed_cb (MetaSelection *selection,
|
||||
MetaSelectionType selection_type,
|
||||
MetaSelectionSource *new_owner,
|
||||
MetaWaylandDataDevicePrimary *data_device)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaWaylandSeat *seat = compositor->seat;
|
||||
struct wl_resource *data_device_resource;
|
||||
struct wl_client *focus_client;
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||
if (!focus_client)
|
||||
return;
|
||||
|
||||
if (selection_type == META_SELECTION_PRIMARY)
|
||||
{
|
||||
wl_resource_for_each (data_device_resource, &data_device->focus_resource_list)
|
||||
{
|
||||
struct wl_resource *offer = NULL;
|
||||
|
||||
if (new_owner)
|
||||
{
|
||||
offer = create_and_send_primary_offer (data_device,
|
||||
data_device_resource);
|
||||
}
|
||||
|
||||
zwp_primary_selection_device_v1_send_selection (data_device_resource,
|
||||
offer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_owners_changed_handler_connected (MetaWaylandDataDevicePrimary *data_device)
|
||||
{
|
||||
if (data_device->selection_owner_signal_id != 0)
|
||||
return;
|
||||
|
||||
data_device->selection_owner_signal_id =
|
||||
g_signal_connect (meta_display_get_selection (meta_get_display ()),
|
||||
"owner-changed",
|
||||
G_CALLBACK (owner_changed_cb), data_device);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_device_manager_create_source (struct wl_client *client,
|
||||
struct wl_resource *manager_resource,
|
||||
guint32 id)
|
||||
{
|
||||
struct wl_resource *source_resource;
|
||||
|
||||
source_resource =
|
||||
wl_resource_create (client, &zwp_primary_selection_source_v1_interface,
|
||||
wl_resource_get_version (manager_resource),
|
||||
id);
|
||||
meta_wayland_data_source_primary_new (source_resource);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_device_manager_get_device (struct wl_client *client,
|
||||
struct wl_resource *manager_resource,
|
||||
guint32 id,
|
||||
struct wl_resource *seat_resource)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||
struct wl_resource *cr;
|
||||
|
||||
cr = wl_resource_create (client, &zwp_primary_selection_device_v1_interface,
|
||||
wl_resource_get_version (manager_resource), id);
|
||||
wl_resource_set_implementation (cr, &primary_device_interface,
|
||||
&seat->primary_data_device, unbind_resource);
|
||||
wl_list_insert (&seat->primary_data_device.resource_list, wl_resource_get_link (cr));
|
||||
|
||||
ensure_owners_changed_handler_connected (&seat->primary_data_device);
|
||||
}
|
||||
|
||||
static const struct zwp_primary_selection_device_manager_v1_interface primary_manager_interface = {
|
||||
primary_device_manager_create_source,
|
||||
primary_device_manager_get_device,
|
||||
default_destructor,
|
||||
};
|
||||
|
||||
static void
|
||||
bind_primary_manager (struct wl_client *client,
|
||||
void *data,
|
||||
uint32_t version,
|
||||
uint32_t id)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, &zwp_primary_selection_device_manager_v1_interface,
|
||||
version, id);
|
||||
wl_resource_set_implementation (resource, &primary_manager_interface, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_device_primary_manager_init (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
if (wl_global_create (compositor->wayland_display,
|
||||
&zwp_primary_selection_device_manager_v1_interface,
|
||||
1, NULL, bind_primary_manager) == NULL)
|
||||
g_error ("Could not create data_device");
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_device_primary_init (MetaWaylandDataDevicePrimary *data_device)
|
||||
{
|
||||
wl_list_init (&data_device->resource_list);
|
||||
wl_list_init (&data_device->focus_resource_list);
|
||||
}
|
||||
|
||||
static struct wl_resource *
|
||||
create_and_send_primary_offer (MetaWaylandDataDevicePrimary *data_device,
|
||||
struct wl_resource *target)
|
||||
{
|
||||
MetaWaylandDataOffer *offer;
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
struct wl_resource *resource;
|
||||
GList *mimetypes, *l;
|
||||
|
||||
mimetypes = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||
META_SELECTION_PRIMARY);
|
||||
if (!mimetypes)
|
||||
return NULL;
|
||||
|
||||
offer = meta_wayland_data_offer_primary_new (target);
|
||||
resource = meta_wayland_data_offer_get_resource (offer);
|
||||
|
||||
zwp_primary_selection_device_v1_send_data_offer (target, resource);
|
||||
|
||||
for (l = mimetypes; l; l = l->next)
|
||||
zwp_primary_selection_offer_v1_send_offer (resource, l->data);
|
||||
|
||||
g_list_free_full (mimetypes, g_free);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_device_primary_set_keyboard_focus (MetaWaylandDataDevicePrimary *data_device)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_container_of (data_device, seat, primary_data_device);
|
||||
struct wl_client *focus_client;
|
||||
struct wl_resource *data_device_resource;
|
||||
|
||||
focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard);
|
||||
|
||||
if (focus_client == data_device->focus_client)
|
||||
return;
|
||||
|
||||
data_device->focus_client = focus_client;
|
||||
move_resources (&data_device->resource_list,
|
||||
&data_device->focus_resource_list);
|
||||
|
||||
if (!focus_client)
|
||||
return;
|
||||
|
||||
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_primary_offer (data_device, data_device_resource);
|
||||
zwp_primary_selection_device_v1_send_selection (data_device_resource, offer);
|
||||
}
|
||||
}
|
55
src/wayland/meta-wayland-data-device-primary.h
Normal file
55
src/wayland/meta-wayland-data-device-primary.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright © 2008 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef META_WAYLAND_DATA_DEVICE_PRIMARY_H
|
||||
#define META_WAYLAND_DATA_DEVICE_PRIMARY_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <wayland-server.h>
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
#include "meta/meta-selection-source.h"
|
||||
#include "wayland/meta-wayland-data-offer.h"
|
||||
#include "wayland/meta-wayland-data-source.h"
|
||||
#include "wayland/meta-wayland-types.h"
|
||||
|
||||
struct _MetaWaylandDataDevicePrimary
|
||||
{
|
||||
uint32_t serial;
|
||||
MetaWaylandDataSource *data_source;
|
||||
struct wl_list resource_list;
|
||||
struct wl_list focus_resource_list;
|
||||
struct wl_client *focus_client;
|
||||
|
||||
guint selection_owner_signal_id;
|
||||
|
||||
MetaSelectionSource *owner;
|
||||
};
|
||||
|
||||
void meta_wayland_data_device_primary_manager_init (MetaWaylandCompositor *compositor);
|
||||
|
||||
void meta_wayland_data_device_primary_init (MetaWaylandDataDevicePrimary *data_device);
|
||||
|
||||
void meta_wayland_data_device_primary_set_keyboard_focus (MetaWaylandDataDevicePrimary *data_device);
|
||||
|
||||
#endif /* META_WAYLAND_DATA_DEVICE_PRIMARY_H */
|
File diff suppressed because it is too large
Load Diff
@ -28,42 +28,20 @@
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
#include "meta/meta-selection-source.h"
|
||||
#include "wayland/meta-wayland-data-offer.h"
|
||||
#include "wayland/meta-wayland-data-source.h"
|
||||
#include "wayland/meta-wayland-types.h"
|
||||
|
||||
typedef struct _MetaWaylandDragGrab MetaWaylandDragGrab;
|
||||
typedef struct _MetaWaylandDataSourceFuncs MetaWaylandDataSourceFuncs;
|
||||
|
||||
#define META_TYPE_WAYLAND_DATA_SOURCE (meta_wayland_data_source_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (MetaWaylandDataSource, meta_wayland_data_source,
|
||||
META, WAYLAND_DATA_SOURCE, GObject);
|
||||
|
||||
struct _MetaWaylandDataSourceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* send) (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type,
|
||||
gint fd);
|
||||
void (* target) (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type);
|
||||
void (* cancel) (MetaWaylandDataSource *source);
|
||||
|
||||
void (* action) (MetaWaylandDataSource *source,
|
||||
uint32_t action);
|
||||
void (* drop_performed) (MetaWaylandDataSource *source);
|
||||
void (* drag_finished) (MetaWaylandDataSource *source);
|
||||
};
|
||||
|
||||
struct _MetaWaylandDataDevice
|
||||
{
|
||||
uint32_t selection_serial;
|
||||
uint32_t primary_serial;
|
||||
MetaWaylandDataSource *selection_data_source;
|
||||
MetaWaylandDataSource *dnd_data_source;
|
||||
MetaWaylandDataSource *primary_data_source;
|
||||
struct wl_listener selection_data_source_listener;
|
||||
struct wl_list resource_list;
|
||||
struct wl_list primary_resource_list;
|
||||
struct wl_list focus_resource_list;
|
||||
MetaWaylandDragGrab *current_grab;
|
||||
struct wl_client *focus_client;
|
||||
|
||||
@ -89,42 +67,7 @@ void meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_de
|
||||
void meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
|
||||
MetaWaylandDataSource *source,
|
||||
guint32 serial);
|
||||
void meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device,
|
||||
MetaWaylandDataSource *source,
|
||||
guint32 serial);
|
||||
|
||||
gboolean meta_wayland_data_source_add_mime_type (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type);
|
||||
|
||||
gboolean meta_wayland_data_source_has_mime_type (const MetaWaylandDataSource *source,
|
||||
const gchar *mime_type);
|
||||
|
||||
struct wl_array *
|
||||
meta_wayland_data_source_get_mime_types (const MetaWaylandDataSource *source);
|
||||
|
||||
gboolean meta_wayland_data_source_has_target (MetaWaylandDataSource *source);
|
||||
|
||||
void meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source,
|
||||
gboolean has_target);
|
||||
|
||||
void meta_wayland_data_source_cancel (MetaWaylandDataSource *source);
|
||||
|
||||
void meta_wayland_data_source_send (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type,
|
||||
gint fd);
|
||||
|
||||
void meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source);
|
||||
|
||||
uint32_t meta_wayland_data_source_get_actions (MetaWaylandDataSource *source);
|
||||
uint32_t meta_wayland_data_source_get_user_action (MetaWaylandDataSource *source);
|
||||
uint32_t meta_wayland_data_source_get_current_action (MetaWaylandDataSource *source);
|
||||
|
||||
void meta_wayland_data_source_set_actions (MetaWaylandDataSource *source,
|
||||
uint32_t dnd_actions);
|
||||
void meta_wayland_data_source_set_user_action (MetaWaylandDataSource *source,
|
||||
uint32_t action);
|
||||
void meta_wayland_data_source_set_current_action (MetaWaylandDataSource *source,
|
||||
uint32_t action);
|
||||
void meta_wayland_data_device_unset_dnd_selection (MetaWaylandDataDevice *data_device);
|
||||
|
||||
const MetaWaylandDragDestFuncs *
|
||||
meta_wayland_data_device_get_drag_dest_funcs (void);
|
||||
|
139
src/wayland/meta-wayland-data-offer-primary-legacy.c
Normal file
139
src/wayland/meta-wayland-data-offer-primary-legacy.c
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-wayland-data-offer-primary-legacy.h"
|
||||
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <glib-unix.h>
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "core/display-private.h"
|
||||
#include "gtk-primary-selection-server-protocol.h"
|
||||
#include "wayland/meta-wayland-data-offer.h"
|
||||
|
||||
static void
|
||||
transfer_cb (MetaSelection *selection,
|
||||
GAsyncResult *res,
|
||||
GOutputStream *stream)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!meta_selection_transfer_finish (selection, res, &error))
|
||||
{
|
||||
g_warning ("Could not fetch selection data: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_output_stream_close (stream, NULL, NULL);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_offer_receive (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
const char *mime_type,
|
||||
int32_t fd)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
GOutputStream *stream;
|
||||
GList *mime_types;
|
||||
gboolean found;
|
||||
|
||||
mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||
META_SELECTION_PRIMARY);
|
||||
found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL;
|
||||
g_list_free_full (mime_types, g_free);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
close (fd);
|
||||
return;
|
||||
}
|
||||
|
||||
stream = g_unix_output_stream_new (fd, TRUE);
|
||||
meta_selection_transfer_async (meta_display_get_selection (display),
|
||||
META_SELECTION_PRIMARY,
|
||||
mime_type,
|
||||
-1,
|
||||
stream,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) transfer_cb,
|
||||
stream);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_offer_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static const struct gtk_primary_selection_offer_interface primary_offer_interface = {
|
||||
primary_offer_receive,
|
||||
primary_offer_destroy,
|
||||
};
|
||||
|
||||
static void
|
||||
destroy_primary_offer (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||
|
||||
if (offer->source)
|
||||
{
|
||||
if (offer == meta_wayland_data_source_get_current_offer (offer->source))
|
||||
{
|
||||
meta_wayland_data_source_cancel (offer->source);
|
||||
meta_wayland_data_source_set_current_offer (offer->source, NULL);
|
||||
}
|
||||
|
||||
g_object_remove_weak_pointer (G_OBJECT (offer->source),
|
||||
(gpointer *)&offer->source);
|
||||
offer->source = NULL;
|
||||
}
|
||||
|
||||
meta_display_sync_wayland_input_focus (meta_get_display ());
|
||||
g_slice_free (MetaWaylandDataOffer, offer);
|
||||
}
|
||||
|
||||
MetaWaylandDataOffer *
|
||||
meta_wayland_data_offer_primary_legacy_new (struct wl_resource *target)
|
||||
{
|
||||
MetaWaylandDataOffer *offer;
|
||||
|
||||
offer = g_slice_new0 (MetaWaylandDataOffer);
|
||||
offer->selection_type = META_SELECTION_PRIMARY;
|
||||
offer->resource = wl_resource_create (wl_resource_get_client (target),
|
||||
>k_primary_selection_offer_interface,
|
||||
wl_resource_get_version (target), 0);
|
||||
wl_resource_set_implementation (offer->resource,
|
||||
&primary_offer_interface,
|
||||
offer,
|
||||
destroy_primary_offer);
|
||||
return offer;
|
||||
}
|
31
src/wayland/meta-wayland-data-offer-primary-legacy.h
Normal file
31
src/wayland/meta-wayland-data-offer-primary-legacy.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef META_WAYLAND_DATA_OFFER_PRIMARY_LEGACY_H
|
||||
#define META_WAYLAND_DATA_OFFER_PRIMARY_LEGACY_H
|
||||
|
||||
#include "meta-wayland-data-offer.h"
|
||||
|
||||
MetaWaylandDataOffer * meta_wayland_data_offer_primary_legacy_new (struct wl_resource *target);
|
||||
|
||||
#endif /* META_WAYLAND_DATA_OFFER_PRIMARY_LEGACY_H */
|
139
src/wayland/meta-wayland-data-offer-primary.c
Normal file
139
src/wayland/meta-wayland-data-offer-primary.c
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-wayland-data-offer-primary.h"
|
||||
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <glib-unix.h>
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "core/display-private.h"
|
||||
#include "primary-selection-unstable-v1-server-protocol.h"
|
||||
#include "wayland/meta-wayland-data-offer.h"
|
||||
|
||||
static void
|
||||
transfer_cb (MetaSelection *selection,
|
||||
GAsyncResult *res,
|
||||
GOutputStream *stream)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!meta_selection_transfer_finish (selection, res, &error))
|
||||
{
|
||||
g_warning ("Could not fetch selection data: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_output_stream_close (stream, NULL, NULL);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_offer_receive (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
const char *mime_type,
|
||||
int32_t fd)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
GOutputStream *stream;
|
||||
GList *mime_types;
|
||||
gboolean found;
|
||||
|
||||
mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||
META_SELECTION_PRIMARY);
|
||||
found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL;
|
||||
g_list_free_full (mime_types, g_free);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
close (fd);
|
||||
return;
|
||||
}
|
||||
|
||||
stream = g_unix_output_stream_new (fd, TRUE);
|
||||
meta_selection_transfer_async (meta_display_get_selection (display),
|
||||
META_SELECTION_PRIMARY,
|
||||
mime_type,
|
||||
-1,
|
||||
stream,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) transfer_cb,
|
||||
stream);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_offer_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static const struct zwp_primary_selection_offer_v1_interface primary_offer_interface = {
|
||||
primary_offer_receive,
|
||||
primary_offer_destroy,
|
||||
};
|
||||
|
||||
static void
|
||||
destroy_primary_offer (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||
|
||||
if (offer->source)
|
||||
{
|
||||
if (offer == meta_wayland_data_source_get_current_offer (offer->source))
|
||||
{
|
||||
meta_wayland_data_source_cancel (offer->source);
|
||||
meta_wayland_data_source_set_current_offer (offer->source, NULL);
|
||||
}
|
||||
|
||||
g_object_remove_weak_pointer (G_OBJECT (offer->source),
|
||||
(gpointer *)&offer->source);
|
||||
offer->source = NULL;
|
||||
}
|
||||
|
||||
meta_display_sync_wayland_input_focus (meta_get_display ());
|
||||
g_slice_free (MetaWaylandDataOffer, offer);
|
||||
}
|
||||
|
||||
MetaWaylandDataOffer *
|
||||
meta_wayland_data_offer_primary_new (struct wl_resource *target)
|
||||
{
|
||||
MetaWaylandDataOffer *offer;
|
||||
|
||||
offer = g_slice_new0 (MetaWaylandDataOffer);
|
||||
offer->selection_type = META_SELECTION_PRIMARY;
|
||||
offer->resource = wl_resource_create (wl_resource_get_client (target),
|
||||
&zwp_primary_selection_offer_v1_interface,
|
||||
wl_resource_get_version (target), 0);
|
||||
wl_resource_set_implementation (offer->resource,
|
||||
&primary_offer_interface,
|
||||
offer,
|
||||
destroy_primary_offer);
|
||||
return offer;
|
||||
}
|
31
src/wayland/meta-wayland-data-offer-primary.h
Normal file
31
src/wayland/meta-wayland-data-offer-primary.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef META_WAYLAND_DATA_OFFER_PRIMARY_H
|
||||
#define META_WAYLAND_DATA_OFFER_PRIMARY_H
|
||||
|
||||
#include "meta-wayland-data-offer.h"
|
||||
|
||||
MetaWaylandDataOffer * meta_wayland_data_offer_primary_new (struct wl_resource *target);
|
||||
|
||||
#endif /* META_WAYLAND_DATA_OFFER_PRIMARY_H */
|
327
src/wayland/meta-wayland-data-offer.c
Normal file
327
src/wayland/meta-wayland-data-offer.c
Normal file
@ -0,0 +1,327 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <glib-unix.h>
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "meta/meta-selection.h"
|
||||
#include "wayland/meta-wayland-data-device.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
|
||||
#include "meta-wayland-data-offer.h"
|
||||
|
||||
#define ALL_ACTIONS (WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | \
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | \
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||
|
||||
static void
|
||||
data_offer_accept (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
guint32 serial,
|
||||
const char *mime_type)
|
||||
{
|
||||
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||
|
||||
/* FIXME: Check that client is currently focused by the input
|
||||
* device that is currently dragging this data source. Should
|
||||
* this be a wl_data_device request? */
|
||||
|
||||
if (offer->source)
|
||||
{
|
||||
meta_wayland_data_source_target (offer->source, mime_type);
|
||||
meta_wayland_data_source_set_has_target (offer->source,
|
||||
mime_type != NULL);
|
||||
}
|
||||
|
||||
offer->accepted = mime_type != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
transfer_cb (MetaSelection *selection,
|
||||
GAsyncResult *res,
|
||||
GOutputStream *stream)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!meta_selection_transfer_finish (selection, res, &error))
|
||||
{
|
||||
g_warning ("Could not fetch selection data: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_output_stream_close (stream, NULL, NULL);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
data_offer_receive (struct wl_client *client, struct wl_resource *resource,
|
||||
const char *mime_type, int32_t fd)
|
||||
{
|
||||
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
MetaSelectionType selection_type;
|
||||
GList *mime_types;
|
||||
gboolean found;
|
||||
|
||||
selection_type = offer->selection_type;
|
||||
mime_types = meta_selection_get_mimetypes (meta_display_get_selection (display),
|
||||
selection_type);
|
||||
found = g_list_find_custom (mime_types, mime_type, (GCompareFunc) g_strcmp0) != NULL;
|
||||
g_list_free_full (mime_types, g_free);
|
||||
|
||||
if (found)
|
||||
{
|
||||
GOutputStream *stream;
|
||||
|
||||
stream = g_unix_output_stream_new (fd, TRUE);
|
||||
meta_selection_transfer_async (meta_display_get_selection (display),
|
||||
selection_type,
|
||||
mime_type,
|
||||
-1,
|
||||
stream,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) transfer_cb,
|
||||
stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
close (fd);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
data_offer_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
data_offer_finish (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||
enum wl_data_device_manager_dnd_action current_action;
|
||||
|
||||
if (!offer->source ||
|
||||
offer != meta_wayland_data_source_get_current_offer (offer->source))
|
||||
return;
|
||||
|
||||
if (!offer->accepted || !offer->action_sent)
|
||||
{
|
||||
wl_resource_post_error (offer->resource,
|
||||
WL_DATA_OFFER_ERROR_INVALID_FINISH,
|
||||
"premature finish request");
|
||||
return;
|
||||
}
|
||||
|
||||
current_action = meta_wayland_data_source_get_current_action (offer->source);
|
||||
|
||||
if (current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE ||
|
||||
current_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||
{
|
||||
wl_resource_post_error (offer->resource,
|
||||
WL_DATA_OFFER_ERROR_INVALID_OFFER,
|
||||
"offer finished with an invalid action");
|
||||
return;
|
||||
}
|
||||
|
||||
meta_wayland_data_source_notify_finish (offer->source);
|
||||
}
|
||||
|
||||
static void
|
||||
data_offer_set_actions (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t dnd_actions,
|
||||
uint32_t preferred_action)
|
||||
{
|
||||
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||
|
||||
if (dnd_actions & ~(ALL_ACTIONS))
|
||||
{
|
||||
wl_resource_post_error (offer->resource,
|
||||
WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK,
|
||||
"invalid actions mask %x", dnd_actions);
|
||||
return;
|
||||
}
|
||||
|
||||
if (preferred_action &&
|
||||
(!(preferred_action & dnd_actions) ||
|
||||
__builtin_popcount (preferred_action) > 1))
|
||||
{
|
||||
wl_resource_post_error (offer->resource,
|
||||
WL_DATA_OFFER_ERROR_INVALID_ACTION,
|
||||
"invalid action %x", preferred_action);
|
||||
return;
|
||||
}
|
||||
|
||||
offer->dnd_actions = dnd_actions;
|
||||
offer->preferred_dnd_action = preferred_action;
|
||||
|
||||
meta_wayland_data_offer_update_action (offer);
|
||||
}
|
||||
|
||||
static const struct wl_data_offer_interface data_offer_interface = {
|
||||
data_offer_accept,
|
||||
data_offer_receive,
|
||||
data_offer_destroy,
|
||||
data_offer_finish,
|
||||
data_offer_set_actions,
|
||||
};
|
||||
|
||||
static void
|
||||
destroy_data_offer (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSeat *seat;
|
||||
|
||||
if (offer->source)
|
||||
{
|
||||
seat = meta_wayland_data_source_get_seat (offer->source);
|
||||
|
||||
if (offer == meta_wayland_data_source_get_current_offer (offer->source))
|
||||
{
|
||||
if (seat->data_device.dnd_data_source == offer->source)
|
||||
{
|
||||
if (wl_resource_get_version (offer->resource) <
|
||||
WL_DATA_OFFER_ACTION_SINCE_VERSION)
|
||||
meta_wayland_data_source_notify_finish (offer->source);
|
||||
else if (meta_wayland_data_source_get_drop_performed (offer->source))
|
||||
meta_wayland_data_source_cancel (offer->source);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_wayland_data_source_set_current_offer (offer->source, NULL);
|
||||
meta_wayland_data_source_set_has_target (offer->source, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_remove_weak_pointer (G_OBJECT (offer->source),
|
||||
(gpointer *)&offer->source);
|
||||
offer->source = NULL;
|
||||
}
|
||||
|
||||
meta_display_sync_wayland_input_focus (meta_get_display ());
|
||||
g_slice_free (MetaWaylandDataOffer, offer);
|
||||
}
|
||||
|
||||
MetaWaylandDataOffer *
|
||||
meta_wayland_data_offer_new (MetaSelectionType selection_type,
|
||||
MetaWaylandDataSource *source,
|
||||
struct wl_resource *target)
|
||||
{
|
||||
MetaWaylandDataOffer *offer;
|
||||
|
||||
offer = g_slice_new0 (MetaWaylandDataOffer);
|
||||
offer->selection_type = selection_type;
|
||||
offer->resource = wl_resource_create (wl_resource_get_client (target),
|
||||
&wl_data_offer_interface,
|
||||
wl_resource_get_version (target), 0);
|
||||
wl_resource_set_implementation (offer->resource,
|
||||
&data_offer_interface,
|
||||
offer,
|
||||
destroy_data_offer);
|
||||
if (source)
|
||||
{
|
||||
offer->source = source;
|
||||
g_object_add_weak_pointer (G_OBJECT (source), (gpointer *)&offer->source);
|
||||
}
|
||||
|
||||
return offer;
|
||||
}
|
||||
|
||||
static enum wl_data_device_manager_dnd_action
|
||||
data_offer_choose_action (MetaWaylandDataOffer *offer)
|
||||
{
|
||||
MetaWaylandDataSource *source = offer->source;
|
||||
uint32_t actions, user_action, available_actions;
|
||||
|
||||
if (wl_resource_get_version (offer->resource) <
|
||||
WL_DATA_OFFER_ACTION_SINCE_VERSION)
|
||||
return WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
||||
|
||||
meta_wayland_data_source_get_actions (source, &actions);
|
||||
user_action = meta_wayland_data_source_get_user_action (source);
|
||||
|
||||
available_actions = actions & offer->dnd_actions;
|
||||
|
||||
if (!available_actions)
|
||||
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
|
||||
|
||||
/* If the user is forcing an action, go for it */
|
||||
if ((user_action & available_actions) != 0)
|
||||
return user_action;
|
||||
|
||||
/* If the dest side has a preferred DnD action, use it */
|
||||
if ((offer->preferred_dnd_action & available_actions) != 0)
|
||||
return offer->preferred_dnd_action;
|
||||
|
||||
/* Use the first found action, in bit order */
|
||||
return 1 << (ffs (available_actions) - 1);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_offer_update_action (MetaWaylandDataOffer *offer)
|
||||
{
|
||||
enum wl_data_device_manager_dnd_action current_action, action;
|
||||
MetaWaylandDataSource *source;
|
||||
|
||||
if (!offer->source)
|
||||
return;
|
||||
|
||||
source = offer->source;
|
||||
current_action = meta_wayland_data_source_get_current_action (source);
|
||||
action = data_offer_choose_action (offer);
|
||||
|
||||
if (current_action == action)
|
||||
return;
|
||||
|
||||
meta_wayland_data_source_set_current_action (source, action);
|
||||
|
||||
if (!meta_wayland_data_source_get_in_ask (source) &&
|
||||
wl_resource_get_version (offer->resource) >=
|
||||
WL_DATA_OFFER_ACTION_SINCE_VERSION)
|
||||
{
|
||||
wl_data_offer_send_action (offer->resource, action);
|
||||
offer->action_sent = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
struct wl_resource *
|
||||
meta_wayland_data_offer_get_resource (MetaWaylandDataOffer *offer)
|
||||
{
|
||||
return offer->resource;
|
||||
}
|
||||
|
||||
MetaWaylandDataSource *
|
||||
meta_wayland_data_offer_get_source (MetaWaylandDataOffer *offer)
|
||||
{
|
||||
return offer->source;
|
||||
}
|
51
src/wayland/meta-wayland-data-offer.h
Normal file
51
src/wayland/meta-wayland-data-offer.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef META_WAYLAND_DATA_OFFER_H
|
||||
#define META_WAYLAND_DATA_OFFER_H
|
||||
|
||||
#include "meta/meta-selection.h"
|
||||
#include "wayland/meta-wayland-data-source.h"
|
||||
|
||||
struct _MetaWaylandDataOffer
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
MetaWaylandDataSource *source;
|
||||
struct wl_listener source_destroy_listener;
|
||||
gboolean accepted;
|
||||
gboolean action_sent;
|
||||
uint32_t dnd_actions;
|
||||
enum wl_data_device_manager_dnd_action preferred_dnd_action;
|
||||
MetaSelectionType selection_type;
|
||||
};
|
||||
|
||||
MetaWaylandDataOffer * meta_wayland_data_offer_new (MetaSelectionType selection_type,
|
||||
MetaWaylandDataSource *source,
|
||||
struct wl_resource *resource);
|
||||
|
||||
void meta_wayland_data_offer_update_action (MetaWaylandDataOffer *offer);
|
||||
|
||||
struct wl_resource * meta_wayland_data_offer_get_resource (MetaWaylandDataOffer *offer);
|
||||
MetaWaylandDataSource * meta_wayland_data_offer_get_source (MetaWaylandDataOffer *offer);
|
||||
|
||||
#endif /* META_WAYLAND_DATA_OFFER_H */
|
117
src/wayland/meta-wayland-data-source-primary-legacy.c
Normal file
117
src/wayland/meta-wayland-data-source-primary-legacy.c
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gtk-primary-selection-server-protocol.h"
|
||||
#include "wayland/meta-wayland-data-source-primary-legacy.h"
|
||||
|
||||
typedef struct _MetaWaylandDataSourcePrimaryLegacy
|
||||
{
|
||||
MetaWaylandDataSource parent;
|
||||
} MetaWaylandDataSourcePrimaryLegacy;
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandDataSourcePrimaryLegacy, meta_wayland_data_source_primary_legacy,
|
||||
META_TYPE_WAYLAND_DATA_SOURCE);
|
||||
|
||||
static void
|
||||
primary_source_offer (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
const char *type)
|
||||
{
|
||||
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||
|
||||
if (!meta_wayland_data_source_add_mime_type (source, type))
|
||||
wl_resource_post_no_memory (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_source_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static struct gtk_primary_selection_source_interface primary_source_interface = {
|
||||
primary_source_offer,
|
||||
primary_source_destroy,
|
||||
};
|
||||
|
||||
static void
|
||||
destroy_primary_source (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||
|
||||
meta_wayland_data_source_set_resource (source, NULL);
|
||||
g_object_unref (source);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_primary_legacy_send (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type,
|
||||
gint fd)
|
||||
{
|
||||
struct wl_resource *resource = meta_wayland_data_source_get_resource (source);
|
||||
|
||||
gtk_primary_selection_source_send_send (resource, mime_type, fd);
|
||||
close (fd);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_primary_legacy_cancel (MetaWaylandDataSource *source)
|
||||
{
|
||||
struct wl_resource *resource = meta_wayland_data_source_get_resource (source);
|
||||
|
||||
if (resource)
|
||||
gtk_primary_selection_source_send_cancelled (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_primary_legacy_init (MetaWaylandDataSourcePrimaryLegacy *source_primary)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_primary_legacy_class_init (MetaWaylandDataSourcePrimaryLegacyClass *klass)
|
||||
{
|
||||
MetaWaylandDataSourceClass *data_source_class =
|
||||
META_WAYLAND_DATA_SOURCE_CLASS (klass);
|
||||
|
||||
data_source_class->send = meta_wayland_data_source_primary_legacy_send;
|
||||
data_source_class->cancel = meta_wayland_data_source_primary_legacy_cancel;
|
||||
}
|
||||
|
||||
MetaWaylandDataSource *
|
||||
meta_wayland_data_source_primary_legacy_new (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataSource *source_primary =
|
||||
g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY, NULL);
|
||||
|
||||
meta_wayland_data_source_set_resource (source_primary, resource);
|
||||
wl_resource_set_implementation (resource, &primary_source_interface,
|
||||
source_primary, destroy_primary_source);
|
||||
|
||||
return source_primary;
|
||||
}
|
37
src/wayland/meta-wayland-data-source-primary-legacy.h
Normal file
37
src/wayland/meta-wayland-data-source-primary-legacy.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef META_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY_H
|
||||
#define META_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY_H
|
||||
|
||||
#include "meta-wayland-data-source.h"
|
||||
|
||||
#define META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY (meta_wayland_data_source_primary_legacy_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandDataSourcePrimaryLegacy,
|
||||
meta_wayland_data_source_primary_legacy,
|
||||
META, WAYLAND_DATA_SOURCE_PRIMARY_LEGACY,
|
||||
MetaWaylandDataSource);
|
||||
|
||||
MetaWaylandDataSource * meta_wayland_data_source_primary_legacy_new (struct wl_resource *resource);
|
||||
|
||||
#endif /* META_WAYLAND_DATA_SOURCE_PRIMARY_LEGACY_H */
|
117
src/wayland/meta-wayland-data-source-primary.c
Normal file
117
src/wayland/meta-wayland-data-source-primary.c
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "primary-selection-unstable-v1-server-protocol.h"
|
||||
#include "wayland/meta-wayland-data-source-primary.h"
|
||||
|
||||
typedef struct _MetaWaylandDataSourcePrimary
|
||||
{
|
||||
MetaWaylandDataSource parent;
|
||||
} MetaWaylandDataSourcePrimary;
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandDataSourcePrimary, meta_wayland_data_source_primary,
|
||||
META_TYPE_WAYLAND_DATA_SOURCE);
|
||||
|
||||
static void
|
||||
primary_source_offer (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
const char *type)
|
||||
{
|
||||
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||
|
||||
if (!meta_wayland_data_source_add_mime_type (source, type))
|
||||
wl_resource_post_no_memory (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
primary_source_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static struct zwp_primary_selection_source_v1_interface primary_source_interface = {
|
||||
primary_source_offer,
|
||||
primary_source_destroy,
|
||||
};
|
||||
|
||||
static void
|
||||
destroy_primary_source (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||
|
||||
meta_wayland_data_source_set_resource (source, NULL);
|
||||
g_object_unref (source);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_primary_send (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type,
|
||||
gint fd)
|
||||
{
|
||||
struct wl_resource *resource = meta_wayland_data_source_get_resource (source);
|
||||
|
||||
zwp_primary_selection_source_v1_send_send (resource, mime_type, fd);
|
||||
close (fd);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_primary_cancel (MetaWaylandDataSource *source)
|
||||
{
|
||||
struct wl_resource *resource = meta_wayland_data_source_get_resource (source);
|
||||
|
||||
if (resource)
|
||||
zwp_primary_selection_source_v1_send_cancelled (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_primary_init (MetaWaylandDataSourcePrimary *source_primary)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_primary_class_init (MetaWaylandDataSourcePrimaryClass *klass)
|
||||
{
|
||||
MetaWaylandDataSourceClass *data_source_class =
|
||||
META_WAYLAND_DATA_SOURCE_CLASS (klass);
|
||||
|
||||
data_source_class->send = meta_wayland_data_source_primary_send;
|
||||
data_source_class->cancel = meta_wayland_data_source_primary_cancel;
|
||||
}
|
||||
|
||||
MetaWaylandDataSource *
|
||||
meta_wayland_data_source_primary_new (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataSource *source_primary =
|
||||
g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY, NULL);
|
||||
|
||||
meta_wayland_data_source_set_resource (source_primary, resource);
|
||||
wl_resource_set_implementation (resource, &primary_source_interface,
|
||||
source_primary, destroy_primary_source);
|
||||
|
||||
return source_primary;
|
||||
}
|
37
src/wayland/meta-wayland-data-source-primary.h
Normal file
37
src/wayland/meta-wayland-data-source-primary.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef META_WAYLAND_DATA_SOURCE_PRIMARY_H
|
||||
#define META_WAYLAND_DATA_SOURCE_PRIMARY_H
|
||||
|
||||
#include "meta-wayland-data-source.h"
|
||||
|
||||
#define META_TYPE_WAYLAND_DATA_SOURCE_PRIMARY (meta_wayland_data_source_primary_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaWaylandDataSourcePrimary,
|
||||
meta_wayland_data_source_primary,
|
||||
META, WAYLAND_DATA_SOURCE_PRIMARY,
|
||||
MetaWaylandDataSource);
|
||||
|
||||
MetaWaylandDataSource * meta_wayland_data_source_primary_new (struct wl_resource *resource);
|
||||
|
||||
#endif /* META_WAYLAND_DATA_SOURCE_PRIMARY_H */
|
523
src/wayland/meta-wayland-data-source.c
Normal file
523
src/wayland/meta-wayland-data-source.c
Normal file
@ -0,0 +1,523 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "wayland/meta-wayland-data-source.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
|
||||
#define ALL_ACTIONS (WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | \
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | \
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
|
||||
|
||||
typedef struct _MetaWaylandDataSourcePrivate
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
MetaWaylandDataOffer *offer;
|
||||
struct wl_array mime_types;
|
||||
gboolean has_target;
|
||||
uint32_t dnd_actions;
|
||||
enum wl_data_device_manager_dnd_action user_dnd_action;
|
||||
enum wl_data_device_manager_dnd_action current_dnd_action;
|
||||
MetaWaylandSeat *seat;
|
||||
guint actions_set : 1;
|
||||
guint in_ask : 1;
|
||||
guint drop_performed : 1;
|
||||
} MetaWaylandDataSourcePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandDataSource, meta_wayland_data_source,
|
||||
G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_real_send (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type,
|
||||
gint fd)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
wl_data_source_send_send (priv->resource, mime_type, fd);
|
||||
close (fd);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_real_target (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
wl_data_source_send_target (priv->resource, mime_type);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_real_cancel (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
if (!priv->resource)
|
||||
return;
|
||||
|
||||
wl_data_source_send_cancelled (priv->resource);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_real_action (MetaWaylandDataSource *source,
|
||||
enum wl_data_device_manager_dnd_action action)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
if (wl_resource_get_version (priv->resource) >=
|
||||
WL_DATA_SOURCE_ACTION_SINCE_VERSION)
|
||||
wl_data_source_send_action (priv->resource, action);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_real_drop_performed (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
if (wl_resource_get_version (priv->resource) >=
|
||||
WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION)
|
||||
{
|
||||
priv->drop_performed = TRUE;
|
||||
wl_data_source_send_dnd_drop_performed (priv->resource);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_real_drag_finished (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
enum wl_data_device_manager_dnd_action action;
|
||||
|
||||
if (meta_wayland_data_source_get_in_ask (source))
|
||||
{
|
||||
action = meta_wayland_data_source_get_current_action (source);
|
||||
meta_wayland_data_source_real_action (source, action);
|
||||
}
|
||||
|
||||
if (wl_resource_get_version (priv->resource) >=
|
||||
WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION)
|
||||
wl_data_source_send_dnd_finished (priv->resource);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_finalize (GObject *object)
|
||||
{
|
||||
MetaWaylandDataSource *source = META_WAYLAND_DATA_SOURCE (object);
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
char **pos;
|
||||
|
||||
wl_array_for_each (pos, &priv->mime_types)
|
||||
g_free (*pos);
|
||||
wl_array_release (&priv->mime_types);
|
||||
|
||||
G_OBJECT_CLASS (meta_wayland_data_source_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_init (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
wl_array_init (&priv->mime_types);
|
||||
priv->current_dnd_action = -1;
|
||||
priv->drop_performed = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_data_source_class_init (MetaWaylandDataSourceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_wayland_data_source_finalize;
|
||||
|
||||
klass->send = meta_wayland_data_source_real_send;
|
||||
klass->target = meta_wayland_data_source_real_target;
|
||||
klass->cancel = meta_wayland_data_source_real_cancel;
|
||||
klass->action = meta_wayland_data_source_real_action;
|
||||
klass->drop_performed = meta_wayland_data_source_real_drop_performed;
|
||||
klass->drag_finished = meta_wayland_data_source_real_drag_finished;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
data_source_offer (struct wl_client *client,
|
||||
struct wl_resource *resource, const char *type)
|
||||
{
|
||||
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||
|
||||
if (!meta_wayland_data_source_add_mime_type (source, type))
|
||||
wl_resource_post_no_memory (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_destroy (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
data_source_set_actions (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t dnd_actions)
|
||||
{
|
||||
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
if (priv->actions_set)
|
||||
{
|
||||
wl_resource_post_error (priv->resource,
|
||||
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
|
||||
"cannot set actions more than once");
|
||||
return;
|
||||
}
|
||||
|
||||
if (dnd_actions & ~(ALL_ACTIONS))
|
||||
{
|
||||
wl_resource_post_error (priv->resource,
|
||||
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
|
||||
"invalid actions mask %x", dnd_actions);
|
||||
return;
|
||||
}
|
||||
|
||||
if (meta_wayland_data_source_get_seat (source))
|
||||
{
|
||||
wl_resource_post_error (priv->resource,
|
||||
WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
|
||||
"invalid action change after "
|
||||
"wl_data_device.start_drag");
|
||||
return;
|
||||
}
|
||||
|
||||
meta_wayland_data_source_set_actions (source, dnd_actions);
|
||||
}
|
||||
|
||||
static struct wl_data_source_interface data_source_interface = {
|
||||
data_source_offer,
|
||||
data_source_destroy,
|
||||
data_source_set_actions
|
||||
};
|
||||
|
||||
static void
|
||||
destroy_data_source (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||
|
||||
meta_wayland_data_source_set_resource (source, NULL);
|
||||
g_object_unref (source);
|
||||
}
|
||||
|
||||
MetaWaylandDataSource *
|
||||
meta_wayland_data_source_new (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataSource *source =
|
||||
g_object_new (META_TYPE_WAYLAND_DATA_SOURCE, NULL);
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
meta_wayland_data_source_set_resource (source, resource);
|
||||
wl_resource_set_implementation (resource, &data_source_interface,
|
||||
source, destroy_data_source);
|
||||
|
||||
if (wl_resource_get_version (resource) < WL_DATA_SOURCE_ACTION_SINCE_VERSION)
|
||||
{
|
||||
priv->dnd_actions = priv->user_dnd_action =
|
||||
WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
struct wl_resource *
|
||||
meta_wayland_data_source_get_resource (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
return priv->resource;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_set_resource (MetaWaylandDataSource *source,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
priv->resource = resource;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_data_source_get_in_ask (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
return priv->in_ask;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_update_in_ask (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
priv->in_ask =
|
||||
priv->current_dnd_action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_target (MetaWaylandDataSource *source,
|
||||
const char *mime_type)
|
||||
{
|
||||
if (META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->target)
|
||||
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->target (source, mime_type);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_send (MetaWaylandDataSource *source,
|
||||
const char *mime_type,
|
||||
int fd)
|
||||
{
|
||||
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->send (source, mime_type, fd);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_data_source_has_target (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
return priv->has_target;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_set_seat (MetaWaylandDataSource *source,
|
||||
MetaWaylandSeat *seat)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
priv->seat = seat;
|
||||
}
|
||||
|
||||
MetaWaylandSeat *
|
||||
meta_wayland_data_source_get_seat (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
return priv->seat;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source,
|
||||
gboolean has_target)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
priv->has_target = has_target;
|
||||
}
|
||||
|
||||
struct wl_array *
|
||||
meta_wayland_data_source_get_mime_types (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private ((MetaWaylandDataSource *)source);
|
||||
|
||||
return &priv->mime_types;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_cancel (MetaWaylandDataSource *source)
|
||||
{
|
||||
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->cancel (source);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_data_source_get_actions (MetaWaylandDataSource *source,
|
||||
uint32_t *dnd_actions)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
if (dnd_actions)
|
||||
*dnd_actions = priv->dnd_actions;
|
||||
|
||||
return priv->actions_set;
|
||||
}
|
||||
|
||||
enum wl_data_device_manager_dnd_action
|
||||
meta_wayland_data_source_get_user_action (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
if (!priv->seat)
|
||||
return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
|
||||
|
||||
return priv->user_dnd_action;
|
||||
}
|
||||
|
||||
enum wl_data_device_manager_dnd_action
|
||||
meta_wayland_data_source_get_current_action (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
return priv->current_dnd_action;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_set_current_offer (MetaWaylandDataSource *source,
|
||||
MetaWaylandDataOffer *offer)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
priv->offer = offer;
|
||||
}
|
||||
|
||||
MetaWaylandDataOffer *
|
||||
meta_wayland_data_source_get_current_offer (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
return priv->offer;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_set_current_action (MetaWaylandDataSource *source,
|
||||
enum wl_data_device_manager_dnd_action action)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
if (priv->current_dnd_action == action)
|
||||
return;
|
||||
|
||||
priv->current_dnd_action = action;
|
||||
|
||||
if (!meta_wayland_data_source_get_in_ask (source))
|
||||
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->action (source, action);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_set_actions (MetaWaylandDataSource *source,
|
||||
uint32_t dnd_actions)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
priv->dnd_actions = dnd_actions;
|
||||
priv->actions_set = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_set_user_action (MetaWaylandDataSource *source,
|
||||
uint32_t action)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
MetaWaylandDataOffer *offer;
|
||||
|
||||
if (priv->user_dnd_action == action)
|
||||
return;
|
||||
|
||||
priv->user_dnd_action = action;
|
||||
offer = meta_wayland_data_source_get_current_offer (source);
|
||||
|
||||
if (offer)
|
||||
meta_wayland_data_offer_update_action (offer);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_data_source_get_drop_performed (MetaWaylandDataSource *source)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
|
||||
return priv->drop_performed;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_notify_drop_performed (MetaWaylandDataSource *source)
|
||||
{
|
||||
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->drop_performed (source);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source)
|
||||
{
|
||||
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->drag_finished (source);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_data_source_add_mime_type (MetaWaylandDataSource *source,
|
||||
const char *mime_type)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
char **pos;
|
||||
|
||||
pos = wl_array_add (&priv->mime_types, sizeof (*pos));
|
||||
|
||||
if (pos)
|
||||
{
|
||||
*pos = g_strdup (mime_type);
|
||||
return *pos != NULL;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_data_source_has_mime_type (MetaWaylandDataSource *source,
|
||||
const char *mime_type)
|
||||
{
|
||||
MetaWaylandDataSourcePrivate *priv =
|
||||
meta_wayland_data_source_get_instance_private (source);
|
||||
char **p;
|
||||
|
||||
wl_array_for_each (p, &priv->mime_types)
|
||||
{
|
||||
if (g_strcmp0 (mime_type, *p) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
112
src/wayland/meta-wayland-data-source.h
Normal file
112
src/wayland/meta-wayland-data-source.h
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright © 2011 Kristian Høgsberg
|
||||
* 2020 Red Hat Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef META_WAYLAND_DATA_SOURCE_H
|
||||
#define META_WAYLAND_DATA_SOURCE_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <wayland-server.h>
|
||||
|
||||
#include "wayland/meta-wayland-types.h"
|
||||
|
||||
#define META_TYPE_WAYLAND_DATA_SOURCE (meta_wayland_data_source_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (MetaWaylandDataSource,
|
||||
meta_wayland_data_source,
|
||||
META, WAYLAND_DATA_SOURCE,
|
||||
GObject)
|
||||
|
||||
typedef struct _MetaWaylandDataSourceClass MetaWaylandDataSourceClass;
|
||||
|
||||
struct _MetaWaylandDataSourceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* send) (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type,
|
||||
gint fd);
|
||||
void (* target) (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type);
|
||||
void (* cancel) (MetaWaylandDataSource *source);
|
||||
|
||||
void (* action) (MetaWaylandDataSource *source,
|
||||
uint32_t action);
|
||||
void (* drop_performed) (MetaWaylandDataSource *source);
|
||||
void (* drag_finished) (MetaWaylandDataSource *source);
|
||||
};
|
||||
|
||||
MetaWaylandDataSource * meta_wayland_data_source_new (struct wl_resource *resource);
|
||||
|
||||
struct wl_resource * meta_wayland_data_source_get_resource (MetaWaylandDataSource *source);
|
||||
void meta_wayland_data_source_set_resource (MetaWaylandDataSource *source,
|
||||
struct wl_resource *resource);
|
||||
|
||||
gboolean meta_wayland_data_source_get_in_ask (MetaWaylandDataSource *source);
|
||||
void meta_wayland_data_source_update_in_ask (MetaWaylandDataSource *source);
|
||||
|
||||
void meta_wayland_data_source_target (MetaWaylandDataSource *source,
|
||||
const char *mime_type);
|
||||
void meta_wayland_data_source_send (MetaWaylandDataSource *source,
|
||||
const char *mime_type,
|
||||
int fd);
|
||||
void meta_wayland_data_source_cancel (MetaWaylandDataSource *source);
|
||||
|
||||
gboolean meta_wayland_data_source_has_target (MetaWaylandDataSource *source);
|
||||
|
||||
void meta_wayland_data_source_set_seat (MetaWaylandDataSource *source,
|
||||
MetaWaylandSeat *seat);
|
||||
MetaWaylandSeat * meta_wayland_data_source_get_seat (MetaWaylandDataSource *source);
|
||||
|
||||
void meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source,
|
||||
gboolean has_target);
|
||||
struct wl_array * meta_wayland_data_source_get_mime_types (MetaWaylandDataSource *source);
|
||||
gboolean meta_wayland_data_source_add_mime_type (MetaWaylandDataSource *source,
|
||||
const gchar *mime_type);
|
||||
gboolean meta_wayland_data_source_has_mime_type (MetaWaylandDataSource *source,
|
||||
const char *mime_type);
|
||||
|
||||
gboolean meta_wayland_data_source_get_actions (MetaWaylandDataSource *source,
|
||||
uint32_t *dnd_actions);
|
||||
void meta_wayland_data_source_set_actions (MetaWaylandDataSource *source,
|
||||
uint32_t dnd_actions);
|
||||
|
||||
enum wl_data_device_manager_dnd_action
|
||||
meta_wayland_data_source_get_current_action (MetaWaylandDataSource *source);
|
||||
void meta_wayland_data_source_set_current_action (MetaWaylandDataSource *source,
|
||||
enum wl_data_device_manager_dnd_action action);
|
||||
|
||||
enum wl_data_device_manager_dnd_action
|
||||
meta_wayland_data_source_get_user_action (MetaWaylandDataSource *source);
|
||||
void meta_wayland_data_source_set_user_action (MetaWaylandDataSource *source,
|
||||
uint32_t action);
|
||||
|
||||
MetaWaylandDataOffer *
|
||||
meta_wayland_data_source_get_current_offer (MetaWaylandDataSource *source);
|
||||
void meta_wayland_data_source_set_current_offer (MetaWaylandDataSource *source,
|
||||
MetaWaylandDataOffer *offer);
|
||||
|
||||
gboolean meta_wayland_data_source_get_drop_performed (MetaWaylandDataSource *source);
|
||||
|
||||
void meta_wayland_data_source_notify_drop_performed (MetaWaylandDataSource *source);
|
||||
void meta_wayland_data_source_notify_finish (MetaWaylandDataSource *source);
|
||||
|
||||
#endif /* META_WAYLAND_DATA_SOURCE_H */
|
@ -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;
|
||||
}
|
||||
|
@ -662,8 +662,6 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *window;
|
||||
MetaRectangle old_geometry;
|
||||
gboolean geometry_changed;
|
||||
|
||||
window = meta_wayland_surface_get_window (surface);
|
||||
if (!window)
|
||||
@ -672,8 +670,6 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
|
||||
return;
|
||||
}
|
||||
|
||||
old_geometry = xdg_surface_priv->geometry;
|
||||
|
||||
surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class);
|
||||
surface_role_class->apply_state (surface_role, pending);
|
||||
@ -688,13 +684,37 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
|
||||
meta_wayland_window_configuration_free (configuration);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_zxdg_toplevel_v6_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending)
|
||||
{
|
||||
MetaWaylandZxdgToplevelV6 *xdg_toplevel =
|
||||
META_WAYLAND_ZXDG_TOPLEVEL_V6 (surface_role);
|
||||
MetaWaylandZxdgSurfaceV6 *xdg_surface =
|
||||
META_WAYLAND_ZXDG_SURFACE_V6 (xdg_toplevel);
|
||||
MetaWaylandZxdgSurfaceV6Private *xdg_surface_priv =
|
||||
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *window;
|
||||
MetaRectangle old_geometry;
|
||||
gboolean geometry_changed;
|
||||
|
||||
window = meta_wayland_surface_get_window (surface);
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
if (!pending->newly_attached)
|
||||
return;
|
||||
|
||||
/* If the window disappeared the surface is not coming back. */
|
||||
if (!window)
|
||||
return;
|
||||
old_geometry = xdg_surface_priv->geometry;
|
||||
|
||||
surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class);
|
||||
surface_role_class->post_apply_state (surface_role, pending);
|
||||
|
||||
geometry_changed = !meta_rectangle_equal (&old_geometry, &xdg_surface_priv->geometry);
|
||||
|
||||
@ -734,7 +754,6 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
|
||||
wl_resource_post_error (surface->resource,
|
||||
ZXDG_SHELL_V6_ERROR_INVALID_SURFACE_STATE,
|
||||
"Invalid min/max size");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -832,6 +851,8 @@ meta_wayland_zxdg_toplevel_v6_class_init (MetaWaylandZxdgToplevelV6Class *klass)
|
||||
|
||||
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
surface_role_class->apply_state = meta_wayland_zxdg_toplevel_v6_apply_state;
|
||||
surface_role_class->post_apply_state =
|
||||
meta_wayland_zxdg_toplevel_v6_post_apply_state;
|
||||
surface_role_class->get_toplevel = meta_wayland_zxdg_toplevel_v6_get_toplevel;
|
||||
|
||||
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
||||
@ -964,12 +985,7 @@ meta_wayland_zxdg_popup_v6_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending)
|
||||
{
|
||||
MetaWaylandZxdgPopupV6 *xdg_popup = META_WAYLAND_ZXDG_POPUP_V6 (surface_role);
|
||||
MetaWaylandZxdgSurfaceV6 *xdg_surface =
|
||||
META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *window;
|
||||
|
||||
if (xdg_popup->setup.parent_surface)
|
||||
finish_popup_setup (xdg_popup);
|
||||
@ -977,12 +993,27 @@ meta_wayland_zxdg_popup_v6_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_popup_v6_parent_class);
|
||||
surface_role_class->apply_state (surface_role, pending);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_zxdg_popup_v6_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending)
|
||||
{
|
||||
MetaWaylandZxdgSurfaceV6 *xdg_surface =
|
||||
META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *window;
|
||||
|
||||
/* If the window disappeared the surface is not coming back. */
|
||||
window = meta_wayland_surface_get_window (surface);
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_popup_v6_parent_class);
|
||||
surface_role_class->post_apply_state (surface_role, pending);
|
||||
|
||||
if (!pending->newly_attached)
|
||||
return;
|
||||
|
||||
@ -1165,6 +1196,8 @@ meta_wayland_zxdg_popup_v6_class_init (MetaWaylandZxdgPopupV6Class *klass)
|
||||
|
||||
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
surface_role_class->apply_state = meta_wayland_zxdg_popup_v6_apply_state;
|
||||
surface_role_class->post_apply_state =
|
||||
meta_wayland_zxdg_popup_v6_post_apply_state;
|
||||
surface_role_class->get_toplevel = meta_wayland_zxdg_popup_v6_get_toplevel;
|
||||
|
||||
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
||||
@ -1331,8 +1364,6 @@ meta_wayland_zxdg_surface_v6_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
{
|
||||
MetaWaylandZxdgSurfaceV6 *xdg_surface =
|
||||
META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
|
||||
MetaWaylandShellSurface *shell_surface =
|
||||
META_WAYLAND_SHELL_SURFACE (xdg_surface);
|
||||
MetaWaylandZxdgSurfaceV6Private *priv =
|
||||
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
|
||||
MetaWaylandSurface *surface =
|
||||
@ -1370,8 +1401,18 @@ meta_wayland_zxdg_surface_v6_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
|
||||
if (surface->buffer_ref.buffer)
|
||||
priv->first_buffer_attached = TRUE;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_zxdg_surface_v6_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending)
|
||||
{
|
||||
MetaWaylandZxdgSurfaceV6 *xdg_surface =
|
||||
META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
|
||||
MetaWaylandZxdgSurfaceV6Private *priv =
|
||||
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
|
||||
MetaWaylandShellSurface *shell_surface =
|
||||
META_WAYLAND_SHELL_SURFACE (xdg_surface);
|
||||
|
||||
if (pending->has_new_geometry)
|
||||
{
|
||||
@ -1526,6 +1567,8 @@ meta_wayland_zxdg_surface_v6_class_init (MetaWaylandZxdgSurfaceV6Class *klass)
|
||||
|
||||
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
surface_role_class->apply_state = meta_wayland_zxdg_surface_v6_apply_state;
|
||||
surface_role_class->post_apply_state =
|
||||
meta_wayland_zxdg_surface_v6_post_apply_state;
|
||||
surface_role_class->assigned = meta_wayland_zxdg_surface_v6_assigned;
|
||||
|
||||
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "wayland/meta-wayland-seat.h"
|
||||
|
||||
#include "wayland/meta-wayland-data-device.h"
|
||||
#include "wayland/meta-wayland-data-device-primary-legacy.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#include "wayland/meta-wayland-tablet-seat.h"
|
||||
#include "wayland/meta-wayland-versions.h"
|
||||
@ -231,6 +232,8 @@ meta_wayland_seat_new (MetaWaylandCompositor *compositor,
|
||||
seat->gtk_text_input = meta_wayland_gtk_text_input_new (seat);
|
||||
|
||||
meta_wayland_data_device_init (&seat->data_device);
|
||||
meta_wayland_data_device_primary_init (&seat->primary_data_device);
|
||||
meta_wayland_data_device_primary_legacy_init (&seat->primary_legacy_data_device);
|
||||
|
||||
clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
meta_wayland_seat_update_capabilities (seat, clutter_seat);
|
||||
@ -431,6 +434,8 @@ meta_wayland_seat_set_input_focus (MetaWaylandSeat *seat,
|
||||
{
|
||||
meta_wayland_keyboard_set_focus (seat->keyboard, surface);
|
||||
meta_wayland_data_device_set_keyboard_focus (&seat->data_device);
|
||||
meta_wayland_data_device_primary_set_keyboard_focus (&seat->primary_data_device);
|
||||
meta_wayland_data_device_primary_legacy_set_keyboard_focus (&seat->primary_legacy_data_device);
|
||||
}
|
||||
|
||||
tablet_seat = meta_wayland_tablet_manager_ensure_seat (compositor->tablet_manager, seat);
|
||||
|
@ -26,6 +26,8 @@
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
#include "wayland/meta-wayland-data-device.h"
|
||||
#include "wayland/meta-wayland-data-device-primary.h"
|
||||
#include "wayland/meta-wayland-data-device-primary-legacy.h"
|
||||
#include "wayland/meta-wayland-input-device.h"
|
||||
#include "wayland/meta-wayland-keyboard.h"
|
||||
#include "wayland/meta-wayland-pointer.h"
|
||||
@ -45,6 +47,8 @@ struct _MetaWaylandSeat
|
||||
MetaWaylandTouch *touch;
|
||||
|
||||
MetaWaylandDataDevice data_device;
|
||||
MetaWaylandDataDevicePrimary primary_data_device;
|
||||
MetaWaylandDataDevicePrimaryLegacy primary_legacy_data_device;
|
||||
|
||||
MetaWaylandGtkTextInput *gtk_text_input;
|
||||
MetaWaylandTextInput *text_input;
|
||||
|
@ -275,7 +275,8 @@ meta_wayland_subsurface_notify_subsurface_state_changed (MetaWaylandSurfaceRole
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWaylandSurface *parent = surface->sub.parent;
|
||||
|
||||
return meta_wayland_surface_notify_subsurface_state_changed (parent);
|
||||
if (parent)
|
||||
return meta_wayland_surface_notify_subsurface_state_changed (parent);
|
||||
}
|
||||
|
||||
static double
|
||||
|
@ -113,6 +113,10 @@ static void
|
||||
meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending);
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending);
|
||||
|
||||
static gboolean
|
||||
meta_wayland_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaLogicalMonitor *logical_monitor);
|
||||
@ -757,8 +761,6 @@ cleanup:
|
||||
surface_state_signals[SURFACE_STATE_SIGNAL_APPLIED],
|
||||
0);
|
||||
|
||||
meta_wayland_surface_state_reset (state);
|
||||
|
||||
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
|
||||
{
|
||||
MetaWaylandSubsurface *subsurface;
|
||||
@ -782,6 +784,11 @@ cleanup:
|
||||
meta_window_actor_notify_damaged (toplevel_window_actor);
|
||||
}
|
||||
}
|
||||
|
||||
if (surface->role)
|
||||
meta_wayland_surface_role_post_apply_state (surface->role, state);
|
||||
|
||||
meta_wayland_surface_state_reset (state);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1696,6 +1703,17 @@ meta_wayland_surface_role_pre_apply_state (MetaWaylandSurfaceRole *surface_role
|
||||
klass->pre_apply_state (surface_role, pending);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *klass;
|
||||
|
||||
klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
|
||||
if (klass->post_apply_state)
|
||||
klass->post_apply_state (surface_role, pending);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending)
|
||||
|
@ -58,6 +58,8 @@ struct _MetaWaylandSurfaceRoleClass
|
||||
MetaWaylandSurfaceState *pending);
|
||||
void (*apply_state) (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending);
|
||||
void (*post_apply_state) (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending);
|
||||
gboolean (*is_on_logical_monitor) (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaLogicalMonitor *logical_monitor);
|
||||
MetaWaylandSurface * (*get_toplevel) (MetaWaylandSurfaceRole *surface_role);
|
||||
|
@ -37,6 +37,8 @@ typedef struct _MetaWaylandTouch MetaWaylandTouch;
|
||||
typedef struct _MetaWaylandDragDestFuncs MetaWaylandDragDestFuncs;
|
||||
typedef struct _MetaWaylandDataOffer MetaWaylandDataOffer;
|
||||
typedef struct _MetaWaylandDataDevice MetaWaylandDataDevice;
|
||||
typedef struct _MetaWaylandDataDevicePrimary MetaWaylandDataDevicePrimary;
|
||||
typedef struct _MetaWaylandDataDevicePrimaryLegacy MetaWaylandDataDevicePrimaryLegacy;
|
||||
|
||||
typedef struct _MetaWaylandTabletManager MetaWaylandTabletManager;
|
||||
typedef struct _MetaWaylandTabletSeat MetaWaylandTabletSeat;
|
||||
|
@ -744,8 +744,6 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *window;
|
||||
MetaRectangle old_geometry;
|
||||
gboolean geometry_changed;
|
||||
|
||||
window = meta_wayland_surface_get_window (surface);
|
||||
if (!window)
|
||||
@ -765,8 +763,6 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
return;
|
||||
}
|
||||
|
||||
old_geometry = xdg_surface_priv->geometry;
|
||||
|
||||
surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class);
|
||||
surface_role_class->apply_state (surface_role, pending);
|
||||
@ -780,17 +776,42 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
meta_wayland_window_configuration_free (configuration);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_xdg_toplevel_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending)
|
||||
{
|
||||
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
|
||||
MetaWaylandXdgSurfacePrivate *xdg_surface_priv =
|
||||
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||
MetaWindow *window;
|
||||
MetaRectangle old_geometry;
|
||||
MetaRectangle window_geometry;
|
||||
|
||||
gboolean geometry_changed;
|
||||
|
||||
window = meta_wayland_surface_get_window (surface);
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
old_geometry = xdg_surface_priv->geometry;
|
||||
|
||||
surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class);
|
||||
surface_role_class->post_apply_state (surface_role, pending);
|
||||
|
||||
if (!pending->newly_attached)
|
||||
return;
|
||||
|
||||
geometry_changed = !meta_rectangle_equal (&old_geometry, &xdg_surface_priv->geometry);
|
||||
window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface);
|
||||
geometry_changed = !meta_rectangle_equal (&old_geometry, &window_geometry);
|
||||
|
||||
if (geometry_changed || pending->has_acked_configure_serial)
|
||||
{
|
||||
MetaRectangle window_geometry;
|
||||
|
||||
window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface);
|
||||
meta_window_wayland_finish_move_resize (window, window_geometry, pending);
|
||||
}
|
||||
else if (pending->dx != 0 || pending->dy != 0)
|
||||
@ -821,7 +842,6 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
wl_resource_post_error (surface->resource,
|
||||
XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE,
|
||||
"Invalid min/max size");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -940,6 +960,7 @@ meta_wayland_xdg_toplevel_class_init (MetaWaylandXdgToplevelClass *klass)
|
||||
|
||||
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
surface_role_class->apply_state = meta_wayland_xdg_toplevel_apply_state;
|
||||
surface_role_class->post_apply_state = meta_wayland_xdg_toplevel_post_apply_state;
|
||||
surface_role_class->get_toplevel = meta_wayland_xdg_toplevel_get_toplevel;
|
||||
|
||||
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
||||
@ -1092,10 +1113,6 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *window;
|
||||
MetaRectangle buffer_rect;
|
||||
MetaWindow *parent_window;
|
||||
MetaRectangle parent_buffer_rect;
|
||||
|
||||
if (xdg_popup->setup.parent_surface)
|
||||
finish_popup_setup (xdg_popup);
|
||||
@ -1118,8 +1135,23 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
"Can't commit buffer to dismissed popup");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_xdg_popup_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending)
|
||||
{
|
||||
MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (surface_role);
|
||||
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_popup_parent_class);
|
||||
MetaWindow *window;
|
||||
MetaWindow *parent_window;
|
||||
MetaRectangle buffer_rect;
|
||||
MetaRectangle parent_buffer_rect;
|
||||
|
||||
/* If the window disappeared the surface is not coming back. */
|
||||
window = meta_wayland_surface_get_window (surface);
|
||||
if (!window)
|
||||
return;
|
||||
@ -1130,6 +1162,8 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
if (!surface->buffer_ref.buffer)
|
||||
return;
|
||||
|
||||
surface_role_class->post_apply_state (surface_role, pending);
|
||||
|
||||
if (pending->has_acked_configure_serial)
|
||||
{
|
||||
MetaRectangle window_geometry;
|
||||
@ -1326,6 +1360,7 @@ meta_wayland_xdg_popup_class_init (MetaWaylandXdgPopupClass *klass)
|
||||
|
||||
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
surface_role_class->apply_state = meta_wayland_xdg_popup_apply_state;
|
||||
surface_role_class->post_apply_state = meta_wayland_xdg_popup_post_apply_state;
|
||||
surface_role_class->get_toplevel = meta_wayland_xdg_popup_get_toplevel;
|
||||
|
||||
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
||||
@ -1504,8 +1539,6 @@ meta_wayland_xdg_surface_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending)
|
||||
{
|
||||
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
|
||||
MetaWaylandShellSurface *shell_surface =
|
||||
META_WAYLAND_SHELL_SURFACE (xdg_surface);
|
||||
MetaWaylandXdgSurfacePrivate *priv =
|
||||
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||
MetaWaylandSurface *surface =
|
||||
@ -1526,8 +1559,17 @@ meta_wayland_xdg_surface_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
|
||||
if (surface->buffer_ref.buffer)
|
||||
priv->first_buffer_attached = TRUE;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_xdg_surface_post_apply_state (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandSurfaceState *pending)
|
||||
{
|
||||
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
|
||||
MetaWaylandXdgSurfacePrivate *priv =
|
||||
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||
MetaWaylandShellSurface *shell_surface =
|
||||
META_WAYLAND_SHELL_SURFACE (surface_role);
|
||||
|
||||
if (pending->has_new_geometry)
|
||||
{
|
||||
@ -1680,6 +1722,7 @@ meta_wayland_xdg_surface_class_init (MetaWaylandXdgSurfaceClass *klass)
|
||||
|
||||
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
surface_role_class->apply_state = meta_wayland_xdg_surface_apply_state;
|
||||
surface_role_class->post_apply_state = meta_wayland_xdg_surface_post_apply_state;
|
||||
surface_role_class->assigned = meta_wayland_xdg_surface_assigned;
|
||||
|
||||
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
|
||||
|
@ -395,6 +395,8 @@ meta_wayland_init (void)
|
||||
|
||||
meta_wayland_outputs_init (compositor);
|
||||
meta_wayland_data_device_manager_init (compositor);
|
||||
meta_wayland_data_device_primary_manager_init (compositor);
|
||||
meta_wayland_data_device_primary_legacy_manager_init (compositor);
|
||||
meta_wayland_subsurfaces_init (compositor);
|
||||
meta_wayland_shell_init (compositor);
|
||||
meta_wayland_pointer_gestures_init (compositor);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user