Compare commits
16 Commits
wip/smcv/c
...
3.37.2
Author | SHA1 | Date | |
---|---|---|---|
f61d4b4e70 | |||
dcb42d3b25 | |||
59a2bff8e2 | |||
720360b07a | |||
9b39e37fee | |||
38104755a2 | |||
7abf0f1e2d | |||
0a37c32a72 | |||
9f121a211d | |||
c823b5ddba | |||
97175f8fa1 | |||
c5b1bdc0fe | |||
f8e2234ce5 | |||
38bbd9593b | |||
a3cc62c285 | |||
c3bf10d19a |
27
NEWS
27
NEWS
@ -1,3 +1,30 @@
|
||||
3.37.2
|
||||
======
|
||||
* Fix move-to-center keybinding with multiple monitors [Sergey; #1073]
|
||||
* Fix stuck buttons when a virtual device is destroyed [Carlos; !1239]
|
||||
* Use workarea when centering new windows [Akatsuki; #964]
|
||||
* Limit mipmap levels when rendering background [Daniel; !1003]
|
||||
* Broadcast clipboard/primary offers [Carlos; !1253]
|
||||
* Support primary-selection protocol from wayland-protocols [Carlos; !1255]
|
||||
* Fix monitor screen cast on X11 [Jonas Å.; !1251]
|
||||
* Support a "blank" cursor type [Florian; !1244]
|
||||
* Improve stage view damage tracking [Jonas Å.; !1237]
|
||||
* Implement touch-mode detecation for the X11 backend [Carlos; !1278]
|
||||
* Drop external keyboard detection from touch-mode heuristics [Carlos; !1277]
|
||||
* Optimize actor allocations [Jonas D.; !1247]
|
||||
* Fixed crashes [Daniel, Carlos, Jonas Å., Jonas D.; !1256, !1258, !1217, !1280]
|
||||
* Misc. bug fixes and cleanups [Christian, Jonas D., Olivier, Ting-Wei,
|
||||
Jonas Å., Marco, Corentin, Daniel, Robert, Niels, Florian, Simon; !1231,
|
||||
!1228, !1238, !1229, !1192, !1236, !1171, !1134, #1126, !1234, !1230, !1210,
|
||||
!1242, !1243, !1252, !1113, !1232, !1259, !1245, !1265, !1180, !1261, !788,
|
||||
!1264, !1235, !1218, !1150, !1274, !1271, !1279, !1283, !1272]
|
||||
|
||||
Contributors:
|
||||
Marco Trevisan (Treviño), Akatsuki, Jonas Dreßler, Olivier Fourdan,
|
||||
Carlos Garnacho, Niels De Graef, Ting-Wei Lan, Robert Mader, Simon McVittie,
|
||||
Florian Müllner, Corentin Noël, Christian Rauch, Daniel van Vugt,
|
||||
Sergey Zigachev, Jonas Ådahl
|
||||
|
||||
3.37.1
|
||||
======
|
||||
* Fix screencasting non-maximized windows [Jonas Å.; !1174]
|
||||
|
@ -2560,6 +2560,22 @@ clutter_actor_notify_if_geometry_changed (ClutterActor *self,
|
||||
g_object_thaw_notify (obj);
|
||||
}
|
||||
|
||||
static void
|
||||
absolute_allocation_changed (ClutterActor *actor)
|
||||
{
|
||||
actor->priv->needs_compute_resource_scale = TRUE;
|
||||
}
|
||||
|
||||
static ClutterActorTraverseVisitFlags
|
||||
absolute_allocation_changed_cb (ClutterActor *actor,
|
||||
int depth,
|
||||
gpointer user_data)
|
||||
{
|
||||
absolute_allocation_changed (actor);
|
||||
|
||||
return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* clutter_actor_set_allocation_internal:
|
||||
* @self: a #ClutterActor
|
||||
@ -2585,6 +2601,9 @@ clutter_actor_set_allocation_internal (ClutterActor *self,
|
||||
gboolean x1_changed, y1_changed, x2_changed, y2_changed;
|
||||
ClutterActorBox old_alloc = { 0, };
|
||||
|
||||
g_return_if_fail (!isnan (box->x1) && !isnan (box->x2) &&
|
||||
!isnan (box->y1) && !isnan (box->y2));
|
||||
|
||||
obj = G_OBJECT (self);
|
||||
|
||||
g_object_freeze_notify (obj);
|
||||
@ -2603,6 +2622,11 @@ clutter_actor_set_allocation_internal (ClutterActor *self,
|
||||
priv->needs_height_request = FALSE;
|
||||
priv->needs_allocation = FALSE;
|
||||
|
||||
priv->absolute_origin_changed |= x1_changed || y1_changed;
|
||||
|
||||
if (priv->absolute_origin_changed || x2_changed || y2_changed)
|
||||
absolute_allocation_changed (self);
|
||||
|
||||
if (x1_changed ||
|
||||
y1_changed ||
|
||||
x2_changed ||
|
||||
@ -10094,7 +10118,6 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
{
|
||||
ClutterActorBox old_allocation, real_allocation;
|
||||
gboolean origin_changed, size_changed;
|
||||
gboolean stage_allocation_changed;
|
||||
ClutterActorPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||
@ -10106,14 +10129,34 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!clutter_actor_is_visible (self))
|
||||
return;
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
priv->absolute_origin_changed = priv->parent
|
||||
? priv->parent->priv->absolute_origin_changed
|
||||
: FALSE;
|
||||
|
||||
if (!CLUTTER_ACTOR_IS_VISIBLE (self))
|
||||
{
|
||||
if (priv->absolute_origin_changed)
|
||||
{
|
||||
_clutter_actor_traverse (self,
|
||||
CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST,
|
||||
absolute_allocation_changed_cb,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
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
|
||||
@ -10142,49 +10185,46 @@ clutter_actor_allocate (ClutterActor *self,
|
||||
size_changed = (real_allocation.x2 != old_allocation.x2 ||
|
||||
real_allocation.y2 != old_allocation.y2);
|
||||
|
||||
priv->absolute_origin_changed = priv->parent
|
||||
? priv->parent->priv->absolute_origin_changed
|
||||
: FALSE;
|
||||
|
||||
priv->absolute_origin_changed |= origin_changed;
|
||||
|
||||
stage_allocation_changed = priv->absolute_origin_changed || size_changed;
|
||||
|
||||
/* If we get an allocation "out of the blue"
|
||||
* (we did not queue relayout), then we want to
|
||||
* ignore it. But if we have needs_allocation set,
|
||||
* we want to guarantee that allocate() virtual
|
||||
* method is always called, i.e. that queue_relayout()
|
||||
* always results in an allocate() invocation on
|
||||
* an actor.
|
||||
/* When needs_allocation is set but we didn't move nor resize, we still
|
||||
* want to call the allocate() vfunc because a child probably called
|
||||
* queue_relayout() and needs a new allocation.
|
||||
*
|
||||
* The optimization here is to avoid re-allocating
|
||||
* actors that did not queue relayout and were
|
||||
* not moved.
|
||||
* In case needs_allocation isn't set and we didn't move nor resize, we
|
||||
* can safely stop allocating, but we need to notify the sub-tree in case
|
||||
* our absolute origin changed.
|
||||
*/
|
||||
if (!priv->needs_allocation && !stage_allocation_changed)
|
||||
if (!priv->needs_allocation && !origin_changed && !size_changed)
|
||||
{
|
||||
if (priv->absolute_origin_changed)
|
||||
{
|
||||
_clutter_actor_traverse (self,
|
||||
CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST,
|
||||
absolute_allocation_changed_cb,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
CLUTTER_NOTE (LAYOUT, "No allocation needed");
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (CLUTTER_ACTOR_IS_MAPPED (self))
|
||||
self->priv->needs_paint_volume_update = TRUE;
|
||||
|
||||
if (stage_allocation_changed)
|
||||
priv->needs_compute_resource_scale = TRUE;
|
||||
|
||||
if (!stage_allocation_changed)
|
||||
if (!origin_changed && !size_changed)
|
||||
{
|
||||
/* If the actor didn't move but needs_allocation is set, we just
|
||||
* need to allocate the children */
|
||||
* need to allocate the children (see comment above) */
|
||||
clutter_actor_allocate_internal (self, &real_allocation);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
_clutter_actor_create_transition (self, obj_props[PROP_ALLOCATION],
|
||||
&priv->allocation,
|
||||
&real_allocation);
|
||||
|
||||
out:
|
||||
priv->absolute_origin_changed = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -50,11 +50,6 @@ ClutterStageWindow *_clutter_stage_get_window (ClutterStage
|
||||
void _clutter_stage_get_projection_matrix (ClutterStage *stage,
|
||||
CoglMatrix *projection);
|
||||
void _clutter_stage_dirty_projection (ClutterStage *stage);
|
||||
void _clutter_stage_set_viewport (ClutterStage *stage,
|
||||
float x,
|
||||
float y,
|
||||
float width,
|
||||
float height);
|
||||
void _clutter_stage_get_viewport (ClutterStage *stage,
|
||||
float *x,
|
||||
float *y,
|
||||
|
@ -189,6 +189,9 @@ static void capture_view_into (ClutterStage *stage,
|
||||
uint8_t *data,
|
||||
int stride);
|
||||
static void clutter_stage_update_view_perspective (ClutterStage *stage);
|
||||
static void clutter_stage_set_viewport (ClutterStage *stage,
|
||||
float width,
|
||||
float height);
|
||||
|
||||
static void clutter_container_iface_init (ClutterContainerIface *iface);
|
||||
|
||||
@ -619,7 +622,6 @@ clutter_stage_allocate (ClutterActor *self,
|
||||
{
|
||||
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
|
||||
ClutterActorBox alloc = CLUTTER_ACTOR_BOX_INIT_ZERO;
|
||||
float old_width, old_height;
|
||||
float new_width, new_height;
|
||||
float width, height;
|
||||
cairo_rectangle_int_t window_size;
|
||||
@ -628,10 +630,6 @@ clutter_stage_allocate (ClutterActor *self,
|
||||
if (priv->impl == NULL)
|
||||
return;
|
||||
|
||||
/* our old allocation */
|
||||
clutter_actor_get_allocation_box (self, &alloc);
|
||||
clutter_actor_box_get_size (&alloc, &old_width, &old_height);
|
||||
|
||||
/* the current allocation */
|
||||
clutter_actor_box_get_size (box, &width, &height);
|
||||
|
||||
@ -719,27 +717,11 @@ clutter_stage_allocate (ClutterActor *self,
|
||||
&override);
|
||||
}
|
||||
|
||||
/* reset the viewport if the allocation effectively changed */
|
||||
/* set the viewport to the new allocation */
|
||||
clutter_actor_get_allocation_box (self, &alloc);
|
||||
clutter_actor_box_get_size (&alloc, &new_width, &new_height);
|
||||
|
||||
if (CLUTTER_NEARBYINT (old_width) != CLUTTER_NEARBYINT (new_width) ||
|
||||
CLUTTER_NEARBYINT (old_height) != CLUTTER_NEARBYINT (new_height))
|
||||
{
|
||||
int real_width = CLUTTER_NEARBYINT (new_width);
|
||||
int real_height = CLUTTER_NEARBYINT (new_height);
|
||||
|
||||
_clutter_stage_set_viewport (CLUTTER_STAGE (self),
|
||||
0, 0,
|
||||
real_width,
|
||||
real_height);
|
||||
|
||||
/* Note: we don't assume that set_viewport will queue a full redraw
|
||||
* since it may bail-out early if something preemptively set the
|
||||
* viewport before the stage was really allocated its new size.
|
||||
*/
|
||||
queue_full_redraw (CLUTTER_STAGE (self));
|
||||
}
|
||||
clutter_stage_set_viewport (CLUTTER_STAGE (self), new_width, new_height);
|
||||
}
|
||||
|
||||
typedef struct _Vector4
|
||||
@ -2257,10 +2239,7 @@ clutter_stage_init (ClutterStage *self)
|
||||
g_signal_connect (self, "notify::min-height",
|
||||
G_CALLBACK (clutter_stage_notify_min_size), NULL);
|
||||
|
||||
_clutter_stage_set_viewport (self,
|
||||
0, 0,
|
||||
geom.width,
|
||||
geom.height);
|
||||
clutter_stage_set_viewport (self, geom.width, geom.height);
|
||||
|
||||
priv->paint_volume_stack =
|
||||
g_array_new (FALSE, FALSE, sizeof (ClutterPaintVolume));
|
||||
@ -2447,8 +2426,6 @@ _clutter_stage_dirty_projection (ClutterStage *stage)
|
||||
/*
|
||||
* clutter_stage_set_viewport:
|
||||
* @stage: A #ClutterStage
|
||||
* @x: The X postition to render the stage at, in window coordinates
|
||||
* @y: The Y position to render the stage at, in window coordinates
|
||||
* @width: The width to render the stage at, in window coordinates
|
||||
* @height: The height to render the stage at, in window coordinates
|
||||
*
|
||||
@ -2481,19 +2458,22 @@ _clutter_stage_dirty_projection (ClutterStage *stage)
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
void
|
||||
_clutter_stage_set_viewport (ClutterStage *stage,
|
||||
float x,
|
||||
float y,
|
||||
float width,
|
||||
float height)
|
||||
static void
|
||||
clutter_stage_set_viewport (ClutterStage *stage,
|
||||
float width,
|
||||
float height)
|
||||
{
|
||||
ClutterStagePrivate *priv;
|
||||
float x, y;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
|
||||
priv = stage->priv;
|
||||
|
||||
x = 0.f;
|
||||
y = 0.f;
|
||||
width = roundf (width);
|
||||
height = roundf (height);
|
||||
|
||||
if (x == priv->viewport[0] &&
|
||||
y == priv->viewport[1] &&
|
||||
|
@ -77,7 +77,7 @@ is_boolean_env_set (const char *variable)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
gboolean
|
||||
test_utils_init (TestFlags requirement_flags,
|
||||
TestFlags known_failure_flags)
|
||||
{
|
||||
@ -156,6 +156,8 @@ test_utils_init (TestFlags requirement_flags,
|
||||
g_print ("WARNING: Missing required feature[s] for this test\n");
|
||||
else if (known_failure)
|
||||
g_print ("WARNING: Test is known to fail\n");
|
||||
|
||||
return (!missing_requirement && !known_failure);
|
||||
}
|
||||
|
||||
void
|
||||
@ -250,7 +252,17 @@ void
|
||||
test_utils_check_pixel_rgb (CoglFramebuffer *test_fb,
|
||||
int x, int y, int r, int g, int b)
|
||||
{
|
||||
test_utils_check_pixel (test_fb, x, y, (r << 24) | (g << 16) | (b << 8));
|
||||
g_return_if_fail (r >= 0);
|
||||
g_return_if_fail (g >= 0);
|
||||
g_return_if_fail (b >= 0);
|
||||
g_return_if_fail (r <= 0xFF);
|
||||
g_return_if_fail (g <= 0xFF);
|
||||
g_return_if_fail (b <= 0xFF);
|
||||
|
||||
test_utils_check_pixel (test_fb, x, y,
|
||||
(((guint32) r) << 24) |
|
||||
(((guint32) g) << 16) |
|
||||
(((guint32) b) << 8));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -68,7 +68,7 @@ typedef enum
|
||||
extern CoglContext *test_ctx;
|
||||
extern CoglFramebuffer *test_fb;
|
||||
|
||||
void
|
||||
gboolean
|
||||
test_utils_init (TestFlags requirement_flags,
|
||||
TestFlags known_failure_flags);
|
||||
|
||||
|
@ -99,9 +99,9 @@ verify_texture (CoglTexture *texture, int size)
|
||||
};
|
||||
|
||||
test_utils_compare_pixel (p,
|
||||
(real_color.red << 24) |
|
||||
(real_color.green << 16) |
|
||||
(real_color.blue << 8) |
|
||||
(((guint32) real_color.red) << 24) |
|
||||
(((guint32) real_color.green) << 16) |
|
||||
(((guint32) real_color.blue) << 8) |
|
||||
opacity);
|
||||
g_assert_cmpint (p[3], ==, opacity);
|
||||
|
||||
|
@ -15,10 +15,17 @@
|
||||
G_STMT_START { \
|
||||
if (strcmp (#FUNC, argv[1]) == 0) \
|
||||
{ \
|
||||
test_utils_init (REQUIREMENTS, KNOWN_FAIL_REQUIREMENTS); \
|
||||
FUNC (); \
|
||||
test_utils_fini (); \
|
||||
exit (0); \
|
||||
if (test_utils_init (REQUIREMENTS, KNOWN_FAIL_REQUIREMENTS) \
|
||||
|| g_getenv ("COGL_TEST_TRY_EVERYTHING") != NULL) \
|
||||
{ \
|
||||
FUNC (); \
|
||||
test_utils_fini (); \
|
||||
exit (0); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
exit (1); \
|
||||
} \
|
||||
} \
|
||||
} G_STMT_END
|
||||
|
||||
@ -55,7 +62,7 @@ main (int argc, char **argv)
|
||||
ADD_TEST (test_pipeline_user_matrix, 0, 0);
|
||||
ADD_TEST (test_blend_strings, 0, 0);
|
||||
ADD_TEST (test_blend, 0, 0);
|
||||
ADD_TEST (test_premult, 0, TEST_KNOWN_FAILURE);
|
||||
ADD_TEST (test_premult, 0, 0);
|
||||
UNPORTED_TEST (test_readpixels);
|
||||
ADD_TEST (test_depth_test, 0, 0);
|
||||
ADD_TEST (test_backface_culling, 0, TEST_REQUIREMENT_NPOT);
|
||||
|
@ -50,6 +50,7 @@ make_texture (uint32_t color,
|
||||
CoglPixelFormat src_format,
|
||||
MakeTextureFlags flags)
|
||||
{
|
||||
static CoglUserDataKey bitmap_free_key;
|
||||
CoglTexture2D *tex_2d;
|
||||
guchar *tex_data = gen_tex_data (color);
|
||||
CoglBitmap *bmp = cogl_bitmap_new_for_data (test_ctx,
|
||||
@ -58,6 +59,10 @@ make_texture (uint32_t color,
|
||||
src_format,
|
||||
QUAD_WIDTH * 4,
|
||||
tex_data);
|
||||
cogl_object_set_user_data (COGL_OBJECT (bmp),
|
||||
&bitmap_free_key,
|
||||
tex_data,
|
||||
g_free);
|
||||
|
||||
tex_2d = cogl_texture_2d_new_from_bitmap (bmp);
|
||||
|
||||
@ -67,7 +72,6 @@ make_texture (uint32_t color,
|
||||
cogl_texture_set_premultiplied (tex_2d, FALSE);
|
||||
|
||||
cogl_object_unref (bmp);
|
||||
g_free (tex_data);
|
||||
|
||||
return tex_2d;
|
||||
}
|
||||
|
@ -36,10 +36,16 @@ main (int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
test_utils_init (unit_test->requirement_flags,
|
||||
unit_test->known_failure_flags);
|
||||
unit_test->run ();
|
||||
test_utils_fini ();
|
||||
|
||||
return 0;
|
||||
if (test_utils_init (unit_test->requirement_flags,
|
||||
unit_test->known_failure_flags)
|
||||
|| g_getenv ("COGL_TEST_TRY_EVERYTHING") != NULL)
|
||||
{
|
||||
unit_test->run ();
|
||||
test_utils_fini ();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
project('mutter', 'c',
|
||||
version: '3.37.1',
|
||||
version: '3.37.2',
|
||||
meson_version: '>= 0.50.0',
|
||||
license: 'GPLv2+'
|
||||
)
|
||||
|
@ -996,8 +996,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);
|
||||
|
@ -2168,6 +2168,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 stride;
|
||||
int offset;
|
||||
@ -2210,10 +2211,13 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
|
||||
if (!dmabuf_fb)
|
||||
return NULL;
|
||||
|
||||
return cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd,
|
||||
width, height, stride, offset, bpp,
|
||||
new_bo,
|
||||
(GDestroyNotify) gbm_bo_destroy);
|
||||
dmabuf_handle =
|
||||
cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd,
|
||||
width, height, stride, offset, bpp,
|
||||
new_bo,
|
||||
(GDestroyNotify) gbm_bo_destroy);
|
||||
cogl_object_unref (dmabuf_fb);
|
||||
return dmabuf_handle;
|
||||
}
|
||||
break;
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
|
@ -1380,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)
|
||||
{
|
||||
@ -1421,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)
|
||||
{
|
||||
@ -1465,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;
|
||||
@ -1503,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);
|
||||
@ -2553,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;
|
||||
|
@ -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
|
||||
|
@ -16,11 +16,11 @@ wait_reconfigure
|
||||
assert_position x/1 100 100
|
||||
|
||||
tile x/1 left
|
||||
wait
|
||||
wait_reconfigure
|
||||
assert_position x/1 0 0
|
||||
|
||||
untile x/1
|
||||
wait
|
||||
wait_reconfigure
|
||||
assert_position x/1 100 100
|
||||
|
||||
tile x/1 left
|
||||
@ -57,11 +57,11 @@ wait_reconfigure
|
||||
assert_position w/1 0 0
|
||||
|
||||
untile w/1
|
||||
wait
|
||||
wait_reconfigure
|
||||
assert_position w/1 100 100
|
||||
|
||||
tile w/1 left
|
||||
wait
|
||||
wait_reconfigure
|
||||
assert_position w/1 0 0
|
||||
|
||||
maximize w/1
|
||||
|
Reference in New Issue
Block a user