diff -Nru mutter-46.0/.gitlab-ci/simple-junit-report.sh mutter-46.1/.gitlab-ci/simple-junit-report.sh --- mutter-46.0/.gitlab-ci/simple-junit-report.sh 1970-01-01 00:00:00.000000000 +0000 +++ mutter-46.1/.gitlab-ci/simple-junit-report.sh 2024-04-19 17:48:34.000000000 +0000 @@ -0,0 +1,18 @@ +#!/bin/bash +OUTFILE=$1 +NAME=$2 +MESSAGE=$3 + +cat >$OUTFILE < + + + + + + + +EOF + +# Also echo the message in stdout for good measure +echo $MESSAGE diff -Nru mutter-46.0/.gitlab-ci.yml mutter-46.1/.gitlab-ci.yml --- mutter-46.0/.gitlab-ci.yml 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/.gitlab-ci.yml 2024-04-19 17:48:34.000000000 +0000 @@ -237,6 +237,29 @@ - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME when: on_success +repo-sanity: + extends: + - .fdo.ci-fairy + stage: review + variables: + GIT_DEPTH: "1" + script: + - > + if [[ -z "$CI_REGISTRY_IMAGE" ]] ; + then + .gitlab-ci/simple-junit-report.sh check-junit-report.xml \ + repo-sanity "The container registry should be enabled in the project general settings panel at $CI_PROJECT_URL/edit" ; + exit 1 ; + fi + artifacts: + expire_in: 1 week + paths: + - check-junit-report.xml + reports: + junit: check-junit-report.xml + rules: + - !reference [.only-merge-requests, rules] + check-commit-log: extends: - .fdo.ci-fairy diff -Nru mutter-46.0/NEWS mutter-46.1/NEWS --- mutter-46.0/NEWS 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/NEWS 2024-04-19 17:48:34.000000000 +0000 @@ -1,3 +1,33 @@ +46.1 +==== +* Implement linux-drm-syncobj-v1 [Austin; !3300] +* Fix input lag on X11 nvidia [Daniel; !3685] +* Fix scanout on secondary GPUs [Michel; !3674] +* Don't apply max-render-time to secondary GPUs [Michel; !3689] +* Fix reusing single-pixel buffers [Jonas Å.; !3702] +* Improve scanout candidate check [Robert; !3699] +* Always use logical pixels for bounds [Sophie; !3698] +* Fix modifiers getting stuck during grabs [Carlos; !3704] +* Fix night-light on displays without EDID [Sebastian W.; !3673] +* Fix secondary GPU acceleration with nvidia driver [Jonas Å., Daniel; !3304] +* Fix some XWayland clients being partially click-through [Sebastian K.; !3697] +* Fix initial suspended state [Jonas Å.; !3475] +* Fixed crashes [Bilal, Jonas Å., Sebastian W., Daniel; + !3683, !3666, !3691, !3708, !3678] +* Misc. bug fixes and cleanups [Ray, Carlos, Bilal, Ivan, Barnabás, Jonas Å., + Jonas D., Michel; !3672, !3681, !3686, !3687, !3671, !3679, !3690, !3703, + !3695, !2946, !3696, !3710, !3644, !3707] + +Contributors: + Jonas Ådahl, Michel Dänzer, Jonas Dreßler, Bilal Elmoussaoui, Carlos Garnacho, + Sophie Herold, Sebastian Keller, Robert Mader, Athmane MOKRAOUI, + Ivan Molodetskikh, Barnabás Pőcze, Austin Shafer, Ray Strode, Daniel van Vugt, + Sebastian Wick + +Translators: + A S Alam [pa], Athmane MOKRAOUI [kab], Rachida SACI [kab], + Nathan Follens [nl], Gwan-gyeong Mun [ko], Fabio Tomat [fur] + 46.0 ==== * Fix duplicate scroll events over libei [Peter; !3637] diff -Nru mutter-46.0/clutter/clutter/clutter-main.c mutter-46.1/clutter/clutter/clutter-main.c --- mutter-46.0/clutter/clutter/clutter-main.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/clutter/clutter/clutter-main.c 2024-04-19 17:48:34.000000000 +0000 @@ -430,33 +430,6 @@ clutter_stage_emit_event (stage, event); } -static ClutterActor * -update_device_for_event (ClutterStage *stage, - ClutterEvent *event, - gboolean emit_crossing) -{ - ClutterInputDevice *device = clutter_event_get_device (event); - ClutterInputDevice *source_device = clutter_event_get_source_device (event); - ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); - ClutterDeviceUpdateFlags flags = CLUTTER_DEVICE_UPDATE_NONE; - graphene_point_t point; - uint32_t time_ms; - - clutter_event_get_coords (event, &point.x, &point.y); - time_ms = clutter_event_get_time (event); - - if (emit_crossing) - flags |= CLUTTER_DEVICE_UPDATE_EMIT_CROSSING; - - return clutter_stage_pick_and_update_device (stage, - device, - sequence, - source_device, - flags, - point, - time_ms); -} - static void maybe_remove_device_for_event (ClutterStage *stage, ClutterEvent *event, @@ -538,7 +511,7 @@ case CLUTTER_TOUCHPAD_HOLD: case CLUTTER_PROXIMITY_IN: case CLUTTER_SCROLL: - update_device_for_event (stage, event, TRUE); + clutter_stage_update_device_for_event (stage, event); break; default: break; diff -Nru mutter-46.0/clutter/clutter/clutter-mutter.h mutter-46.1/clutter/clutter/clutter-mutter.h --- mutter-46.0/clutter/clutter/clutter-mutter.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/clutter/clutter/clutter-mutter.h 2024-04-19 17:48:34.000000000 +0000 @@ -106,9 +106,6 @@ ClutterInputDevice *device, ClutterEventSequence *sequence, graphene_point_t *coords); -CLUTTER_EXPORT -void clutter_stage_repick_device (ClutterStage *stage, - ClutterInputDevice *device); CLUTTER_EXPORT void clutter_get_debug_flags (ClutterDebugFlag *debug_flags, diff -Nru mutter-46.0/clutter/clutter/clutter-stage-private.h mutter-46.1/clutter/clutter/clutter-stage-private.h --- mutter-46.0/clutter/clutter/clutter-stage-private.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/clutter/clutter/clutter-stage-private.h 2024-04-19 17:48:34.000000000 +0000 @@ -81,10 +81,6 @@ void _clutter_stage_maybe_setup_viewport (ClutterStage *stage, ClutterStageView *view); void clutter_stage_maybe_relayout (ClutterActor *stage); -GSList * clutter_stage_find_updated_devices (ClutterStage *stage, - ClutterStageView *view); -void clutter_stage_update_devices (ClutterStage *stage, - GSList *devices); void clutter_stage_finish_layout (ClutterStage *stage); CLUTTER_EXPORT @@ -111,13 +107,6 @@ void clutter_stage_remove_device_entry (ClutterStage *self, ClutterInputDevice *device, ClutterEventSequence *sequence); -ClutterActor * clutter_stage_pick_and_update_device (ClutterStage *stage, - ClutterInputDevice *device, - ClutterEventSequence *sequence, - ClutterInputDevice *source_device, - ClutterDeviceUpdateFlags flags, - graphene_point_t point, - uint32_t time_ms); void clutter_stage_unlink_grab (ClutterStage *self, ClutterGrab *grab); @@ -156,4 +145,10 @@ GPtrArray * clutter_stage_get_active_gestures_array (ClutterStage *self); +ClutterActor * clutter_stage_update_device_for_event (ClutterStage *stage, + ClutterEvent *event); + +void clutter_stage_update_devices_in_view (ClutterStage *stage, + ClutterStageView *view); + G_END_DECLS diff -Nru mutter-46.0/clutter/clutter/clutter-stage-view.c mutter-46.1/clutter/clutter/clutter-stage-view.c --- mutter-46.0/clutter/clutter/clutter-stage-view.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/clutter/clutter/clutter-stage-view.c 2024-04-19 17:48:34.000000000 +0000 @@ -869,7 +869,6 @@ clutter_stage_view_get_instance_private (view); ClutterStage *stage = priv->stage; ClutterStageWindow *stage_window = _clutter_stage_get_window (stage); - g_autoptr (GSList) devices = NULL; if (CLUTTER_ACTOR_IN_DESTRUCTION (stage)) return CLUTTER_FRAME_RESULT_IDLE; @@ -890,9 +889,6 @@ clutter_stage_finish_layout (stage); - if (priv->needs_update_devices) - devices = clutter_stage_find_updated_devices (stage, view); - _clutter_stage_window_prepare_frame (stage_window, view, frame); clutter_stage_emit_prepare_frame (stage, view, frame); @@ -913,8 +909,11 @@ _clutter_stage_window_finish_frame (stage_window, view, frame); - clutter_stage_update_devices (stage, devices); - priv->needs_update_devices = FALSE; + if (priv->needs_update_devices) + { + clutter_stage_update_devices_in_view (stage, view); + priv->needs_update_devices = FALSE; + } _clutter_run_repaint_functions (CLUTTER_REPAINT_FLAGS_POST_PAINT); clutter_stage_after_update (stage, view, frame); diff -Nru mutter-46.0/clutter/clutter/clutter-stage.c mutter-46.1/clutter/clutter/clutter-stage.c --- mutter-46.0/clutter/clutter/clutter-stage.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/clutter/clutter/clutter-stage.c 2024-04-19 17:48:34.000000000 +0000 @@ -182,6 +182,14 @@ float width, float height); +static ClutterActor * clutter_stage_pick_and_update_device (ClutterStage *stage, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + ClutterInputDevice *source_device, + ClutterDeviceUpdateFlags flags, + graphene_point_t point, + uint32_t time_ms); + G_DEFINE_TYPE_WITH_PRIVATE (ClutterStage, clutter_stage, CLUTTER_TYPE_ACTOR) static void @@ -891,35 +899,6 @@ clutter_stage_invalidate_devices (stage); } -GSList * -clutter_stage_find_updated_devices (ClutterStage *stage, - ClutterStageView *view) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - GSList *updating = NULL; - GHashTableIter iter; - gpointer value; - - g_hash_table_iter_init (&iter, priv->pointer_devices); - while (g_hash_table_iter_next (&iter, NULL, &value)) - { - PointerDeviceEntry *entry = value; - ClutterStageView *pointer_view; - - pointer_view = clutter_stage_get_view_at (stage, - entry->coords.x, - entry->coords.y); - if (!pointer_view) - continue; - if (pointer_view != view) - continue; - - updating = g_slist_prepend (updating, entry->device); - } - - return updating; -} - void clutter_stage_finish_layout (ClutterStage *stage) { @@ -954,33 +933,6 @@ g_warn_if_fail (!priv->actor_needs_immediate_relayout); } -void -clutter_stage_update_devices (ClutterStage *stage, - GSList *devices) -{ - ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); - GSList *l; - - COGL_TRACE_BEGIN_SCOPED (ClutterStageUpdateDevices, "Clutter::Stage::update_devices()"); - - for (l = devices; l; l = l->next) - { - ClutterInputDevice *device = l->data; - PointerDeviceEntry *entry = NULL; - - entry = g_hash_table_lookup (priv->pointer_devices, device); - g_assert (entry != NULL); - - clutter_stage_pick_and_update_device (stage, - device, - NULL, NULL, - CLUTTER_DEVICE_UPDATE_IGNORE_CACHE | - CLUTTER_DEVICE_UPDATE_EMIT_CROSSING, - entry->coords, - CLUTTER_CURRENT_TIME); - } -} - static void clutter_stage_real_queue_relayout (ClutterActor *self) { @@ -1623,7 +1575,21 @@ on_seat_unfocus_inhibited_changed (ClutterStage *stage, ClutterSeat *seat) { - clutter_stage_repick_device (stage, clutter_seat_get_pointer (seat)); + ClutterInputDevice *device; + graphene_point_t point = GRAPHENE_POINT_INIT_ZERO; + + device = clutter_seat_get_pointer (seat); + + if (!clutter_stage_get_device_coords (stage, device, NULL, &point)) + return; + + clutter_stage_pick_and_update_device (stage, + device, + NULL, NULL, + CLUTTER_DEVICE_UPDATE_IGNORE_CACHE | + CLUTTER_DEVICE_UPDATE_EMIT_CROSSING, + point, + CLUTTER_CURRENT_TIME); } static void @@ -3524,24 +3490,6 @@ } } -void -clutter_stage_repick_device (ClutterStage *stage, - ClutterInputDevice *device) -{ - graphene_point_t point = GRAPHENE_POINT_INIT_ZERO; - - if (!clutter_stage_get_device_coords (stage, device, NULL, &point)) - return; - - clutter_stage_pick_and_update_device (stage, - device, - NULL, NULL, - CLUTTER_DEVICE_UPDATE_IGNORE_CACHE | - CLUTTER_DEVICE_UPDATE_EMIT_CROSSING, - point, - CLUTTER_CURRENT_TIME); -} - static gboolean clutter_stage_check_in_clear_area (ClutterStage *stage, ClutterInputDevice *device, @@ -3568,7 +3516,7 @@ point.x, point.y); } -ClutterActor * +static ClutterActor * clutter_stage_pick_and_update_device (ClutterStage *stage, ClutterInputDevice *device, ClutterEventSequence *sequence, @@ -4605,3 +4553,60 @@ return priv->all_active_gestures; } + +ClutterActor * +clutter_stage_update_device_for_event (ClutterStage *stage, + ClutterEvent *event) +{ + ClutterInputDevice *device = clutter_event_get_device (event); + ClutterInputDevice *source_device = clutter_event_get_source_device (event); + ClutterEventSequence *sequence = clutter_event_get_event_sequence (event); + ClutterDeviceUpdateFlags flags; + graphene_point_t point; + uint32_t time_ms; + + clutter_event_get_coords (event, &point.x, &point.y); + time_ms = clutter_event_get_time (event); + + flags = CLUTTER_DEVICE_UPDATE_EMIT_CROSSING; + + return clutter_stage_pick_and_update_device (stage, + device, + sequence, + source_device, + flags, + point, + time_ms); +} + +void +clutter_stage_update_devices_in_view (ClutterStage *stage, + ClutterStageView *view) +{ + ClutterStagePrivate *priv = clutter_stage_get_instance_private (stage); + GHashTableIter iter; + gpointer value; + + g_hash_table_iter_init (&iter, priv->pointer_devices); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + PointerDeviceEntry *entry = value; + ClutterStageView *pointer_view; + + pointer_view = clutter_stage_get_view_at (stage, + entry->coords.x, + entry->coords.y); + if (!pointer_view) + continue; + if (pointer_view != view) + continue; + + clutter_stage_pick_and_update_device (stage, + entry->device, + NULL, NULL, + CLUTTER_DEVICE_UPDATE_IGNORE_CACHE | + CLUTTER_DEVICE_UPDATE_EMIT_CROSSING, + entry->coords, + CLUTTER_CURRENT_TIME); + } +} diff -Nru mutter-46.0/cogl/cogl/cogl-attribute-buffer.c mutter-46.1/cogl/cogl/cogl-attribute-buffer.c --- mutter-46.0/cogl/cogl/cogl-attribute-buffer.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/cogl-attribute-buffer.c 2024-04-19 17:48:34.000000000 +0000 @@ -51,13 +51,13 @@ CoglAttributeBuffer * cogl_attribute_buffer_new_with_size (CoglContext *context, - size_t bytes) + size_t bytes) { CoglAttributeBuffer *buffer; buffer = g_object_new (COGL_TYPE_ATTRIBUTE_BUFFER, "context", context, - "size", bytes, + "size", (uint64_t) bytes, "default-target", COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER, "update-hint", COGL_BUFFER_UPDATE_HINT_STATIC, NULL); @@ -67,8 +67,8 @@ CoglAttributeBuffer * cogl_attribute_buffer_new (CoglContext *context, - size_t bytes, - const void *data) + size_t bytes, + const void *data) { CoglAttributeBuffer *buffer; diff -Nru mutter-46.0/cogl/cogl/cogl-attribute-buffer.h mutter-46.1/cogl/cogl/cogl-attribute-buffer.h --- mutter-46.0/cogl/cogl/cogl-attribute-buffer.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/cogl-attribute-buffer.h 2024-04-19 17:48:34.000000000 +0000 @@ -92,7 +92,7 @@ */ COGL_EXPORT CoglAttributeBuffer * cogl_attribute_buffer_new_with_size (CoglContext *context, - size_t bytes); + size_t bytes); /** * cogl_attribute_buffer_new: @@ -122,7 +122,7 @@ */ COGL_EXPORT CoglAttributeBuffer * cogl_attribute_buffer_new (CoglContext *context, - size_t bytes, - const void *data); + size_t bytes, + const void *data); G_END_DECLS diff -Nru mutter-46.0/cogl/cogl/cogl-context-private.h mutter-46.1/cogl/cogl/cogl-context-private.h --- mutter-46.0/cogl/cogl/cogl-context-private.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/cogl-context-private.h 2024-04-19 17:48:34.000000000 +0000 @@ -311,3 +311,6 @@ void _cogl_context_set_current_modelview_entry (CoglContext *context, CoglMatrixEntry *entry); + +void +_cogl_context_update_sync (CoglContext *context); diff -Nru mutter-46.0/cogl/cogl/cogl-context.c mutter-46.1/cogl/cogl/cogl-context.c --- mutter-46.0/cogl/cogl/cogl-context.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/cogl-context.c 2024-04-19 17:48:34.000000000 +0000 @@ -463,6 +463,28 @@ context->current_modelview_entry = entry; } +void +_cogl_context_update_sync (CoglContext *context) +{ + const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); + + if (!winsys->update_sync) + return; + + winsys->update_sync (context); +} + +int +cogl_context_get_latest_sync_fd (CoglContext *context) +{ + const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); + + if (!winsys->get_sync_fd) + return -1; + + return winsys->get_sync_fd (context); +} + CoglGraphicsResetStatus cogl_get_graphics_reset_status (CoglContext *context) { diff -Nru mutter-46.0/cogl/cogl/cogl-context.h mutter-46.1/cogl/cogl/cogl-context.h --- mutter-46.0/cogl/cogl/cogl-context.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/cogl-context.h 2024-04-19 17:48:34.000000000 +0000 @@ -367,4 +367,18 @@ COGL_EXPORT int64_t cogl_context_get_gpu_time_ns (CoglContext *context); +/** + * cogl_context_get_latest_sync_fd + * @context: a #CoglContext pointer + * + * This function is used to get support for waiting on previous + * GPU work through sync fds. It will return a sync fd which will + * signal when the previous work has completed. + * + * Return value: sync fd for latest GPU submission if available, + * returns -1 if not. + */ +COGL_EXPORT int +cogl_context_get_latest_sync_fd (CoglContext *context); + G_END_DECLS diff -Nru mutter-46.0/cogl/cogl/cogl-index-buffer.c mutter-46.1/cogl/cogl/cogl-index-buffer.c --- mutter-46.0/cogl/cogl/cogl-index-buffer.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/cogl-index-buffer.c 2024-04-19 17:48:34.000000000 +0000 @@ -53,13 +53,14 @@ * indices buffer should be able to contain multiple ranges of indices * which the wiki design doesn't currently consider. */ CoglIndexBuffer * -cogl_index_buffer_new (CoglContext *context, size_t bytes) +cogl_index_buffer_new (CoglContext *context, + size_t bytes) { CoglIndexBuffer *indices; indices = g_object_new (COGL_TYPE_INDEX_BUFFER, "context", context, - "size", bytes, + "size", (uint64_t) bytes, "default-target", COGL_BUFFER_BIND_TARGET_INDEX_BUFFER, "update-hint", COGL_BUFFER_UPDATE_HINT_STATIC, NULL); diff -Nru mutter-46.0/cogl/cogl/cogl-index-buffer.h mutter-46.1/cogl/cogl/cogl-index-buffer.h --- mutter-46.0/cogl/cogl/cogl-index-buffer.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/cogl-index-buffer.h 2024-04-19 17:48:34.000000000 +0000 @@ -78,6 +78,6 @@ */ COGL_EXPORT CoglIndexBuffer * cogl_index_buffer_new (CoglContext *context, - size_t bytes); + size_t bytes); G_END_DECLS diff -Nru mutter-46.0/cogl/cogl/cogl-onscreen.c mutter-46.1/cogl/cogl/cogl-onscreen.c --- mutter-46.0/cogl/cogl/cogl-onscreen.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/cogl-onscreen.c 2024-04-19 17:48:34.000000000 +0000 @@ -325,6 +325,7 @@ { CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *context = cogl_framebuffer_get_context (framebuffer); CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen); g_return_if_fail (COGL_IS_ONSCREEN (framebuffer)); @@ -334,6 +335,9 @@ _cogl_framebuffer_flush_journal (framebuffer); + /* Update our "latest" sync fd to contain all previous work */ + _cogl_context_update_sync (context); + if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_FRAME))) cogl_framebuffer_finish (framebuffer); diff -Nru mutter-46.0/cogl/cogl/cogl-pixel-buffer.c mutter-46.1/cogl/cogl/cogl-pixel-buffer.c --- mutter-46.0/cogl/cogl/cogl-pixel-buffer.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/cogl-pixel-buffer.c 2024-04-19 17:48:34.000000000 +0000 @@ -63,15 +63,15 @@ static CoglPixelBuffer * _cogl_pixel_buffer_new (CoglContext *context, - size_t size, - const void *data, - GError **error) + size_t size, + const void *data, + GError **error) { CoglPixelBuffer *pixel_buffer; pixel_buffer = g_object_new (COGL_TYPE_PIXEL_BUFFER, "context", context, - "size", size, + "size", (uint64_t) size, "default-target", COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK, "update-hint", COGL_BUFFER_UPDATE_HINT_STATIC, NULL); @@ -94,8 +94,8 @@ CoglPixelBuffer * cogl_pixel_buffer_new (CoglContext *context, - size_t size, - const void *data) + size_t size, + const void *data) { GError *ignore_error = NULL; CoglPixelBuffer *buffer = diff -Nru mutter-46.0/cogl/cogl/cogl-pixel-buffer.h mutter-46.1/cogl/cogl/cogl-pixel-buffer.h --- mutter-46.0/cogl/cogl/cogl-pixel-buffer.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/cogl-pixel-buffer.h 2024-04-19 17:48:34.000000000 +0000 @@ -87,7 +87,7 @@ */ COGL_EXPORT CoglPixelBuffer * cogl_pixel_buffer_new (CoglContext *context, - size_t size, - const void *data); + size_t size, + const void *data); G_END_DECLS diff -Nru mutter-46.0/cogl/cogl/meson.build mutter-46.1/cogl/cogl/meson.build --- mutter-46.0/cogl/cogl/meson.build 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/meson.build 2024-04-19 17:48:34.000000000 +0000 @@ -407,6 +407,7 @@ install: true, ) libmutter_cogl_dep = declare_dependency( + sources: [cogl_enums[1]], dependencies: [cogl_deps], link_with: libmutter_cogl, ) diff -Nru mutter-46.0/cogl/cogl/winsys/cogl-onscreen-egl.c mutter-46.1/cogl/cogl/winsys/cogl-onscreen-egl.c --- mutter-46.0/cogl/cogl/winsys/cogl-onscreen-egl.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/winsys/cogl-onscreen-egl.c 2024-04-19 17:48:34.000000000 +0000 @@ -281,6 +281,27 @@ g_warning ("Error reported by eglSetDamageRegion"); } +void +cogl_onscreen_egl_maybe_create_timestamp_query (CoglOnscreen *onscreen, + CoglFrameInfo *info) +{ + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *context = cogl_framebuffer_get_context (framebuffer); + + if (!cogl_has_feature (context, COGL_FEATURE_ID_TIMESTAMP_QUERY)) + return; + + info->gpu_time_before_buffer_swap_ns = + cogl_context_get_gpu_time_ns (context); + info->cpu_time_before_buffer_swap_us = g_get_monotonic_time (); + + /* Set up a timestamp query for when all rendering will be finished. */ + info->timestamp_query = + cogl_framebuffer_create_timestamp_query (framebuffer); + + info->has_valid_gpu_rendering_duration = TRUE; +} + static void cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen, const int *rectangles, @@ -309,19 +330,6 @@ COGL_FRAMEBUFFER (onscreen), COGL_FRAMEBUFFER_STATE_BIND); - if (cogl_has_feature (context, COGL_FEATURE_ID_TIMESTAMP_QUERY)) - { - info->gpu_time_before_buffer_swap_ns = - cogl_context_get_gpu_time_ns (context); - info->cpu_time_before_buffer_swap_us = g_get_monotonic_time (); - - /* Set up a timestamp query for when all rendering will be finished. */ - info->timestamp_query = - cogl_framebuffer_create_timestamp_query (COGL_FRAMEBUFFER (onscreen)); - - info->has_valid_gpu_rendering_duration = TRUE; - } - if (n_rectangles && priv->pf_eglSwapBuffersWithDamage) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); diff -Nru mutter-46.0/cogl/cogl/winsys/cogl-onscreen-egl.h mutter-46.1/cogl/cogl/winsys/cogl-onscreen-egl.h --- mutter-46.0/cogl/cogl/winsys/cogl-onscreen-egl.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/winsys/cogl-onscreen-egl.h 2024-04-19 17:48:34.000000000 +0000 @@ -41,6 +41,10 @@ }; COGL_EXPORT void +cogl_onscreen_egl_maybe_create_timestamp_query (CoglOnscreen *onscreen, + CoglFrameInfo *info); + +COGL_EXPORT void cogl_onscreen_egl_set_egl_surface (CoglOnscreenEgl *onscreen_egl, EGLSurface egl_surface); diff -Nru mutter-46.0/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h mutter-46.1/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h --- mutter-46.0/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h 2024-04-19 17:48:34.000000000 +0000 @@ -162,6 +162,15 @@ (EGLDisplay dpy, EGLSyncKHR sync)) COGL_WINSYS_FEATURE_END () + +COGL_WINSYS_FEATURE_BEGIN (native_fence_sync, + "ANDROID\0", + "native_fence_sync\0", + COGL_EGL_WINSYS_FEATURE_NATIVE_FENCE_SYNC) +COGL_WINSYS_FEATURE_FUNCTION (EGLint, eglDupNativeFenceFD, + (EGLDisplay dpy, + EGLSyncKHR sync)) +COGL_WINSYS_FEATURE_END () #endif COGL_WINSYS_FEATURE_BEGIN (surfaceless_context, diff -Nru mutter-46.0/cogl/cogl/winsys/cogl-winsys-egl-private.h mutter-46.1/cogl/cogl/winsys/cogl-winsys-egl-private.h --- mutter-46.0/cogl/cogl/winsys/cogl-winsys-egl-private.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/winsys/cogl-winsys-egl-private.h 2024-04-19 17:48:34.000000000 +0000 @@ -101,6 +101,7 @@ COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT = 1L << 6, COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY = 1L << 7, COGL_EGL_WINSYS_FEATURE_NO_CONFIG_CONTEXT = 1L << 8, + COGL_EGL_WINSYS_FEATURE_NATIVE_FENCE_SYNC = 1L << 9, } CoglEGLWinsysFeature; typedef struct _CoglRendererEGL @@ -119,6 +120,9 @@ /* vtable for platform specific parts */ const CoglWinsysEGLVtable *platform_vtable; + /* Sync for latest submitted work */ + EGLSyncKHR sync; + /* Function pointers for EGL specific extensions */ #define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d) diff -Nru mutter-46.0/cogl/cogl/winsys/cogl-winsys-egl-x11.c mutter-46.1/cogl/cogl/winsys/cogl-winsys-egl-x11.c --- mutter-46.0/cogl/cogl/winsys/cogl-winsys-egl-x11.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/winsys/cogl-winsys-egl-x11.c 2024-04-19 17:48:34.000000000 +0000 @@ -243,6 +243,7 @@ xlib_renderer = _cogl_xlib_renderer_get_data (renderer); egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable; + egl_renderer->sync = EGL_NO_SYNC_KHR; if (!_cogl_xlib_renderer_connect (renderer, error)) goto error; diff -Nru mutter-46.0/cogl/cogl/winsys/cogl-winsys-egl.c mutter-46.1/cogl/cogl/winsys/cogl-winsys-egl.c --- mutter-46.0/cogl/cogl/winsys/cogl-winsys-egl.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/winsys/cogl-winsys-egl.c 2024-04-19 17:48:34.000000000 +0000 @@ -441,6 +441,9 @@ g_return_if_fail (egl_display != NULL); + if (egl_renderer->sync != EGL_NO_SYNC_KHR) + egl_renderer->pf_eglDestroySync (egl_renderer->edpy, egl_renderer->sync); + cleanup_context (display); if (egl_renderer->platform_vtable->display_destroy) @@ -573,6 +576,37 @@ renderer->pf_eglDestroySync (renderer->edpy, fence); } + +static int +_cogl_winsys_get_sync_fd (CoglContext *context) +{ + CoglRendererEGL *renderer = context->display->renderer->winsys; + int fd; + + if (!renderer->pf_eglDupNativeFenceFD) + return -1; + + fd = renderer->pf_eglDupNativeFenceFD (renderer->edpy, renderer->sync); + if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) + return -1; + + return fd; +} + +static void +_cogl_winsys_update_sync (CoglContext *context) +{ + CoglRendererEGL *renderer = context->display->renderer->winsys; + + if (!renderer->pf_eglDestroySync || !renderer->pf_eglCreateSync) + return; + + if (renderer->sync != EGL_NO_SYNC_KHR) + renderer->pf_eglDestroySync (renderer->edpy, renderer->sync); + + renderer->sync = renderer->pf_eglCreateSync (renderer->edpy, + EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); +} #endif static CoglWinsysVtable _cogl_winsys_vtable = @@ -595,6 +629,8 @@ .fence_add = _cogl_winsys_fence_add, .fence_is_complete = _cogl_winsys_fence_is_complete, .fence_destroy = _cogl_winsys_fence_destroy, + .get_sync_fd = _cogl_winsys_get_sync_fd, + .update_sync = _cogl_winsys_update_sync, #endif }; diff -Nru mutter-46.0/cogl/cogl/winsys/cogl-winsys-private.h mutter-46.1/cogl/cogl/winsys/cogl-winsys-private.h --- mutter-46.0/cogl/cogl/winsys/cogl-winsys-private.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/cogl/cogl/winsys/cogl-winsys-private.h 2024-04-19 17:48:34.000000000 +0000 @@ -141,6 +141,12 @@ (*fence_destroy) (CoglContext *ctx, void *fence); + void + (*update_sync) (CoglContext *ctx); + + int + (*get_sync_fd) (CoglContext *ctx); + } CoglWinsysVtable; typedef const CoglWinsysVtable *(*CoglWinsysVtableGetter) (void); diff -Nru mutter-46.0/config.h.meson mutter-46.1/config.h.meson --- mutter-46.0/config.h.meson 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/config.h.meson 2024-04-19 17:48:34.000000000 +0000 @@ -135,3 +135,6 @@ /* Supports malloc_trim */ #mesondefine HAVE_MALLOC_TRIM + +/* Supports eventfd */ +#mesondefine HAVE_EVENTFD diff -Nru mutter-46.0/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml mutter-46.1/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml --- mutter-46.0/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml 2024-04-19 17:48:34.000000000 +0000 @@ -396,8 +396,8 @@ @layout_mode current layout mode represents the way logical monitors are laid out on the screen. Possible modes include: - 1 : physical - 2 : logical + 1 : logical + 2 : physical With physical layout mode, each logical monitor has the same dimensions as the monitor modes of the associated monitors assigned to it, no diff -Nru mutter-46.0/debian/changelog mutter-46.1/debian/changelog --- mutter-46.0/debian/changelog 2024-04-18 20:01:26.000000000 +0000 +++ mutter-46.1/debian/changelog 2024-05-03 14:46:53.000000000 +0000 @@ -1,3 +1,36 @@ +mutter (46.1-2ubuntu1) oracular; urgency=medium + + * Merge with Debian (LP: #2064735). Remaining changes: + - Add x11-Add-support-for-fractional-scaling-using-Randr.patch + - Add window-Add-ability-to-override-the-edge-constraints.patch + + Make possible for extensions (such as Tiling Assistant) to override + window constraints + - Ignore test results on armhf & ppc64el + * Drop compositor-sync-ring-Allow-the-gpu_fence-to-be-moved.patch: + applied in new release + + -- Jeremy Bícha Fri, 03 May 2024 10:46:53 -0400 + +mutter (46.1-2) experimental; urgency=medium + + * Update libmutter-14-0.symbols for i386 + * Drop packaging references to Hurd since this is Linux-only + + -- Jeremy Bícha Mon, 29 Apr 2024 16:04:02 -0400 + +mutter (46.1-1) experimental; urgency=medium + + [ Jeremy Bícha ] + * New upstream release + * Update libmutter-14-0.symbols + * Update Breaks + * Drop Nvidia-secondary-GPU-copy-acceleration.patch: applied in new release + + [ Daniel van Vugt ] + * Update triple buffering patch + + -- Jeremy Bícha Mon, 29 Apr 2024 14:43:24 -0400 + mutter (46.0-1ubuntu9) noble; urgency=medium * Have mutter-common Breaks/Replaces recent magpie-common diff -Nru mutter-46.0/debian/control mutter-46.1/debian/control --- mutter-46.0/debian/control 2024-04-18 20:01:26.000000000 +0000 +++ mutter-46.1/debian/control 2024-05-03 14:46:53.000000000 +0000 @@ -50,7 +50,7 @@ libpixman-1-dev (>= 0.42), libsm-dev, libstartup-notification0-dev (>= 0.7), - libsysprof-6-dev [!hurd-i386 !i386], + libsysprof-6-dev [!i386], libsysprof-capture-4-dev (>= 3.40.1), libsystemd-dev (>= 212), libwacom-dev (>= 0.13), diff -Nru mutter-46.0/debian/libmutter-14-0.symbols mutter-46.1/debian/libmutter-14-0.symbols --- mutter-46.0/debian/libmutter-14-0.symbols 2024-04-18 20:01:26.000000000 +0000 +++ mutter-46.1/debian/libmutter-14-0.symbols 2024-05-03 14:46:53.000000000 +0000 @@ -868,6 +868,8 @@ meta_window_shape_ref@Base 43.0 meta_window_shape_to_region@Base 43.0 meta_window_shape_unref@Base 43.0 + meta_window_should_be_showing@Base 46.1 + meta_window_should_show@Base 46.1 meta_window_shove_titlebar_onscreen@Base 43.0 meta_window_showing_on_its_workspace@Base 43.0 meta_window_stick@Base 43.0 @@ -1892,7 +1894,6 @@ clutter_stage_pointing_input_foreach@Base 45~rc clutter_stage_process_event@Base 45~beta.1 clutter_stage_read_pixels@Base 43.0 - clutter_stage_repick_device@Base 43.0 clutter_stage_schedule_update@Base 43.0 clutter_stage_set_key_focus@Base 43.0 clutter_stage_set_title@Base 43.0 @@ -2227,6 +2228,7 @@ cogl_context_free_timestamp_query@Base 43.0 cogl_context_get_display@Base 43.0 cogl_context_get_gpu_time_ns@Base 43.0 + cogl_context_get_latest_sync_fd@Base 46.1 cogl_context_get_named_pipeline@Base 43.0 cogl_context_get_renderer@Base 43.0 cogl_context_get_type@Base 46~beta @@ -2409,6 +2411,7 @@ cogl_onscreen_dirty_closure_get_type@Base 46~beta cogl_onscreen_egl_get_egl_surface@Base 43.0 cogl_onscreen_egl_get_type@Base 43.0 + cogl_onscreen_egl_maybe_create_timestamp_query@Base 46.1 cogl_onscreen_egl_set_egl_surface@Base 43.0 cogl_onscreen_get_buffer_age@Base 43.0 cogl_onscreen_get_frame_counter@Base 43.0 @@ -2615,12 +2618,12 @@ cogl_texture_set_premultiplied@Base 43.0 cogl_texture_set_region@Base 43.0 cogl_texture_set_region_from_bitmap@Base 43.0 - (arch=!hurd-i386 !i386)cogl_trace_context@Base 43.0 - (arch=!hurd-i386 !i386)cogl_trace_describe@Base 43.0 - (arch=!hurd-i386 !i386)cogl_trace_end@Base 43.0 - cogl_trace_mark@Base 46~beta - (arch=!hurd-i386 !i386)cogl_trace_mutex@Base 43.0 - (arch=!hurd-i386 !i386)cogl_trace_thread_data@Base 43.0 + (arch=!i386)cogl_trace_context@Base 43.0 + (arch=!i386)cogl_trace_describe@Base 43.0 + (arch=!i386)cogl_trace_end@Base 43.0 + (arch=!i386)cogl_trace_mark@Base 46~beta + (arch=!i386)cogl_trace_mutex@Base 43.0 + (arch=!i386)cogl_trace_thread_data@Base 43.0 cogl_uint16_div_64k_to_half@Base 46~beta cogl_x11_onscreen_get_type@Base 43.0 cogl_x11_onscreen_get_x11_window@Base 43.0 @@ -2663,6 +2666,7 @@ mtk_rectangle_intersect@Base 45~rc mtk_rectangle_is_adjacent_to@Base 46~beta mtk_rectangle_new@Base 45~rc + mtk_rectangle_new_empty@Base 46.1 mtk_rectangle_overlap@Base 45~rc mtk_rectangle_scale_double@Base 46~beta mtk_rectangle_to_graphene_rect@Base 45~rc diff -Nru mutter-46.0/debian/patches/Nvidia-secondary-GPU-copy-acceleration.patch mutter-46.1/debian/patches/Nvidia-secondary-GPU-copy-acceleration.patch --- mutter-46.0/debian/patches/Nvidia-secondary-GPU-copy-acceleration.patch 2024-04-18 20:01:26.000000000 +0000 +++ mutter-46.1/debian/patches/Nvidia-secondary-GPU-copy-acceleration.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,390 +0,0 @@ -From: Daniel van Vugt -Date: Sun, 10 Mar 2024 17:51:35 +0800 -Subject: Nvidia secondary GPU copy acceleration - -This fixes three issues that were preventing GPU copies on the Nvidia -proprietary driver: - -1. `gbm_surface_create` fails with `ENOSYS` (`Function not implemented`) - unless you remove all flags. -2. Missing call to `glViewport` in `meta-renderer-native-gles3.c`. -3. Checking for `GL_OES_EGL_image_external` but then using - `GL_OES_EGL_image` semantics which Nvidia does not support. - -Origin: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3304 -Bug: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6221, - https://gitlab.gnome.org/GNOME/mutter/-/issues/2247, - https://gitlab.gnome.org/GNOME/mutter/-/issues/2551 -Bug-Ubuntu: https://launchpad.net/bugs/1970291 -Forwarded: yes -Last-Update: 2024-03-10 ---- - src/backends/meta-egl.c | 8 + - src/backends/meta-egl.h | 4 + - src/backends/native/meta-onscreen-native.c | 15 +- - src/backends/native/meta-renderer-native-gles3.c | 165 ++++++++++++++++++--- - src/backends/native/meta-renderer-native-gles3.h | 17 ++- - src/backends/native/meta-renderer-native-private.h | 1 + - src/backends/native/meta-renderer-native.c | 10 ++ - 7 files changed, 191 insertions(+), 29 deletions(-) - -diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c -index 9a57c52..2f8247b 100644 ---- a/src/backends/meta-egl.c -+++ b/src/backends/meta-egl.c -@@ -260,6 +260,14 @@ meta_egl_has_extensions (MetaEgl *egl, - return has_extensions; - } - -+const char * -+meta_egl_query_string (MetaEgl *egl, -+ EGLDisplay display, -+ EGLint name) -+{ -+ return eglQueryString (display, name); -+} -+ - gboolean - meta_egl_initialize (MetaEgl *egl, - EGLDisplay display, -diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h -index 09bee95..8b955c9 100644 ---- a/src/backends/meta-egl.h -+++ b/src/backends/meta-egl.h -@@ -47,6 +47,10 @@ gboolean meta_egl_has_extensions (MetaEgl *egl, - const char *first_extension, - ...); - -+const char * meta_egl_query_string (MetaEgl *egl, -+ EGLDisplay display, -+ EGLint name); -+ - gboolean meta_egl_initialize (MetaEgl *egl, - EGLDisplay display, - GError **error); -diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c -index 9617d00..3063b6c 100644 ---- a/src/backends/native/meta-onscreen-native.c -+++ b/src/backends/native/meta-onscreen-native.c -@@ -883,6 +883,9 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen, - COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferSecondaryGpu, - "copy_shared_framebuffer_gpu()"); - -+ if (renderer_gpu_data->secondary.needs_explicit_sync) -+ cogl_framebuffer_finish (COGL_FRAMEBUFFER (onscreen)); -+ - render_device = renderer_gpu_data->render_device; - egl_display = meta_render_device_get_egl_display (render_device); - -@@ -995,8 +998,7 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre - COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferPrimaryGpu, - "copy_shared_framebuffer_primary_gpu()"); - -- if (!secondary_gpu_state || -- secondary_gpu_state->egl_surface == EGL_NO_SURFACE) -+ if (!secondary_gpu_state) - return NULL; - - primary_gpu = meta_renderer_native_get_primary_gpu (renderer_native); -@@ -2624,6 +2626,15 @@ init_secondary_gpu_state_gpu_copy_mode (MetaRendererNative *renderer_nat - width, height, - format, - GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); -+ -+ if (!gbm_surface) -+ { -+ gbm_surface = gbm_surface_create (gbm_device, -+ width, height, -+ format, -+ 0); -+ } -+ - if (!gbm_surface) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, -diff --git a/src/backends/native/meta-renderer-native-gles3.c b/src/backends/native/meta-renderer-native-gles3.c -index cf27ba8..693db0a 100644 ---- a/src/backends/native/meta-renderer-native-gles3.c -+++ b/src/backends/native/meta-renderer-native-gles3.c -@@ -3,6 +3,7 @@ - /* - * Copyright (C) 2017 Red Hat - * Copyright (c) 2018 DisplayLink (UK) Ltd. -+ * Copyright (c) 2023 Canonical Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as -@@ -43,6 +44,127 @@ - #error "Somehow included OpenGL headers when we shouldn't have" - #endif - -+static GQuark -+get_quark_for_egl_context (EGLContext egl_context) -+{ -+ char key[128]; -+ -+ g_snprintf (key, sizeof key, "EGLContext %p", egl_context); -+ -+ return g_quark_from_string (key); -+} -+ -+static GLuint -+load_shader (const char *src, -+ GLenum type) -+{ -+ GLuint shader = glCreateShader (type); -+ -+ if (shader) -+ { -+ GLint compiled; -+ -+ glShaderSource (shader, 1, &src, NULL); -+ glCompileShader (shader); -+ glGetShaderiv (shader, GL_COMPILE_STATUS, &compiled); -+ if (!compiled) -+ { -+ GLchar log[1024]; -+ -+ glGetShaderInfoLog (shader, sizeof (log) - 1, NULL, log); -+ log[sizeof (log) - 1] = '\0'; -+ g_warning ("load_shader compile failed: %s", log); -+ glDeleteShader (shader); -+ shader = 0; -+ } -+ } -+ -+ return shader; -+} -+ -+static void -+ensure_shader_program (MetaGles3 *gles3) -+{ -+ static const char vertex_shader_source[] = -+ "#version 100\n" -+ "attribute vec2 position;\n" -+ "attribute vec2 texcoord;\n" -+ "varying vec2 v_texcoord;\n" -+ "\n" -+ "void main()\n" -+ "{\n" -+ " gl_Position = vec4(position, 0.0, 1.0);\n" -+ " v_texcoord = texcoord;\n" -+ "}\n"; -+ -+ static const char fragment_shader_source[] = -+ "#version 100\n" -+ "#extension GL_OES_EGL_image_external : require\n" -+ "precision mediump float;\n" -+ "uniform samplerExternalOES s_texture;\n" -+ "varying vec2 v_texcoord;\n" -+ "\n" -+ " void main()\n" -+ "{\n" -+ " gl_FragColor = texture2D(s_texture, v_texcoord);\n" -+ "}\n"; -+ -+ static const GLfloat box[] = -+ { /* position texcoord */ -+ -1.0f, +1.0f, 0.0f, 0.0f, -+ +1.0f, +1.0f, 1.0f, 0.0f, -+ +1.0f, -1.0f, 1.0f, 1.0f, -+ -1.0f, -1.0f, 0.0f, 1.0f, -+ }; -+ GLint linked; -+ GLuint vertex_shader, fragment_shader; -+ GLint position_attrib, texcoord_attrib; -+ GQuark shader_program_quark; -+ GLuint shader_program; -+ -+ shader_program_quark = get_quark_for_egl_context (eglGetCurrentContext ()); -+ if (g_object_get_qdata (G_OBJECT (gles3), shader_program_quark)) -+ return; -+ -+ shader_program = glCreateProgram (); -+ g_return_if_fail (shader_program); -+ g_object_set_qdata_full (G_OBJECT (gles3), -+ shader_program_quark, -+ GUINT_TO_POINTER (shader_program), -+ NULL); -+ -+ vertex_shader = load_shader (vertex_shader_source, GL_VERTEX_SHADER); -+ g_return_if_fail (vertex_shader); -+ fragment_shader = load_shader (fragment_shader_source, GL_FRAGMENT_SHADER); -+ g_return_if_fail (fragment_shader); -+ -+ GLBAS (gles3, glAttachShader, (shader_program, vertex_shader)); -+ GLBAS (gles3, glAttachShader, (shader_program, fragment_shader)); -+ GLBAS (gles3, glLinkProgram, (shader_program)); -+ GLBAS (gles3, glGetProgramiv, (shader_program, GL_LINK_STATUS, &linked)); -+ if (!linked) -+ { -+ GLchar log[1024]; -+ -+ glGetProgramInfoLog (shader_program, sizeof (log) - 1, NULL, log); -+ log[sizeof (log) - 1] = '\0'; -+ g_warning ("Link failed: %s", log); -+ return; -+ } -+ -+ GLBAS (gles3, glUseProgram, (shader_program)); -+ -+ position_attrib = glGetAttribLocation (shader_program, "position"); -+ GLBAS (gles3, glEnableVertexAttribArray, (position_attrib)); -+ GLBAS (gles3, glVertexAttribPointer, -+ (position_attrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof (GLfloat), box)); -+ -+ texcoord_attrib = glGetAttribLocation (shader_program, "texcoord"); -+ GLBAS (gles3, glEnableVertexAttribArray, (texcoord_attrib)); -+ GLBAS (gles3, glVertexAttribPointer, -+ (texcoord_attrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof (GLfloat), box + 2)); -+} -+ - static void - paint_egl_image (MetaGles3 *gles3, - EGLImageKHR egl_image, -@@ -50,39 +172,33 @@ paint_egl_image (MetaGles3 *gles3, - int height) - { - GLuint texture; -- GLuint framebuffer; - - meta_gles3_clear_error (gles3); -+ ensure_shader_program (gles3); - -- GLBAS (gles3, glGenFramebuffers, (1, &framebuffer)); -- GLBAS (gles3, glBindFramebuffer, (GL_READ_FRAMEBUFFER, framebuffer)); -+ GLBAS (gles3, glViewport, (0, 0, width, height)); - - GLBAS (gles3, glActiveTexture, (GL_TEXTURE0)); - GLBAS (gles3, glGenTextures, (1, &texture)); -- GLBAS (gles3, glBindTexture, (GL_TEXTURE_2D, texture)); -- GLEXT (gles3, glEGLImageTargetTexture2DOES, (GL_TEXTURE_2D, egl_image)); -- GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, -+ GLBAS (gles3, glBindTexture, (GL_TEXTURE_EXTERNAL_OES, texture)); -+ GLEXT (gles3, glEGLImageTargetTexture2DOES, (GL_TEXTURE_EXTERNAL_OES, -+ egl_image)); -+ GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES, -+ GL_TEXTURE_MAG_FILTER, - GL_NEAREST)); -- GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, -+ GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES, -+ GL_TEXTURE_MIN_FILTER, - GL_NEAREST)); -- GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, -+ GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES, -+ GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_EDGE)); -- GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, -+ GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES, -+ GL_TEXTURE_WRAP_T, - GL_CLAMP_TO_EDGE)); -- GLBAS (gles3, glTexParameteri, (GL_TEXTURE_2D, GL_TEXTURE_WRAP_R_OES, -- GL_CLAMP_TO_EDGE)); -- -- GLBAS (gles3, glFramebufferTexture2D, (GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, -- GL_TEXTURE_2D, texture, 0)); - -- GLBAS (gles3, glBindFramebuffer, (GL_READ_FRAMEBUFFER, framebuffer)); -- GLBAS (gles3, glBlitFramebuffer, (0, height, width, 0, -- 0, 0, width, height, -- GL_COLOR_BUFFER_BIT, -- GL_NEAREST)); -+ GLBAS (gles3, glDrawArrays, (GL_TRIANGLE_FAN, 0, 4)); - - GLBAS (gles3, glDeleteTextures, (1, &texture)); -- GLBAS (gles3, glDeleteFramebuffers, (1, &framebuffer)); - } - - gboolean -@@ -156,3 +272,12 @@ meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl, - - return TRUE; - } -+ -+void -+meta_renderer_native_gles3_forget_context (MetaGles3 *gles3, -+ EGLContext egl_context) -+{ -+ GQuark shader_program_quark = get_quark_for_egl_context (egl_context); -+ -+ g_object_set_qdata (G_OBJECT (gles3), shader_program_quark, NULL); -+} -diff --git a/src/backends/native/meta-renderer-native-gles3.h b/src/backends/native/meta-renderer-native-gles3.h -index 591ff82..f5791a1 100644 ---- a/src/backends/native/meta-renderer-native-gles3.h -+++ b/src/backends/native/meta-renderer-native-gles3.h -@@ -26,10 +26,13 @@ - #include "backends/meta-egl.h" - #include "backends/meta-gles3.h" - --gboolean meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl, -- MetaGles3 *gles3, -- EGLDisplay egl_display, -- EGLContext egl_context, -- EGLSurface egl_surface, -- struct gbm_bo *shared_bo, -- GError **error); -+gboolean meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl, -+ MetaGles3 *gles3, -+ EGLDisplay egl_display, -+ EGLContext egl_context, -+ EGLSurface egl_surface, -+ struct gbm_bo *shared_bo, -+ GError **error); -+ -+void meta_renderer_native_gles3_forget_context (MetaGles3 *gles3, -+ EGLContext egl_context); -diff --git a/src/backends/native/meta-renderer-native-private.h b/src/backends/native/meta-renderer-native-private.h -index 997fe6f..2d3fe19 100644 ---- a/src/backends/native/meta-renderer-native-private.h -+++ b/src/backends/native/meta-renderer-native-private.h -@@ -60,6 +60,7 @@ typedef struct _MetaRendererNativeGpuData - struct { - MetaSharedFramebufferCopyMode copy_mode; - gboolean has_EGL_EXT_image_dma_buf_import_modifiers; -+ gboolean needs_explicit_sync; - - /* For GPU blit mode */ - EGLContext egl_context; -diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c -index c32a6ca..884f1cc 100644 ---- a/src/backends/native/meta-renderer-native.c -+++ b/src/backends/native/meta-renderer-native.c -@@ -63,6 +63,7 @@ - #include "backends/native/meta-output-kms.h" - #include "backends/native/meta-render-device-gbm.h" - #include "backends/native/meta-render-device-surfaceless.h" -+#include "backends/native/meta-renderer-native-gles3.h" - #include "backends/native/meta-renderer-native-private.h" - #include "backends/native/meta-renderer-view-native.h" - #include "cogl/cogl.h" -@@ -136,6 +137,9 @@ meta_renderer_native_gpu_data_free (MetaRendererNativeGpuData *renderer_gpu_data - MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; - MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); - -+ meta_renderer_native_gles3_forget_context (renderer_native->gles3, -+ renderer_gpu_data->secondary.egl_context); -+ - meta_egl_destroy_context (egl, - egl_display, - renderer_gpu_data->secondary.egl_context, -@@ -1835,6 +1839,7 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data, - CoglContext *cogl_context; - CoglDisplay *cogl_display; - const char **missing_gl_extensions; -+ const char *egl_vendor; - - egl_display = meta_render_device_get_egl_display (render_device); - if (egl_display == EGL_NO_DISPLAY) -@@ -1901,6 +1906,11 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data, - meta_egl_has_extensions (egl, egl_display, NULL, - "EGL_EXT_image_dma_buf_import_modifiers", - NULL); -+ -+ egl_vendor = meta_egl_query_string (egl, egl_display, EGL_VENDOR); -+ if (!g_strcmp0 (egl_vendor, "NVIDIA")) -+ renderer_gpu_data->secondary.needs_explicit_sync = TRUE; -+ - ret = TRUE; - out: - maybe_restore_cogl_egl_api (renderer_native); diff -Nru mutter-46.0/debian/patches/compositor-sync-ring-Allow-the-gpu_fence-to-be-moved.patch mutter-46.1/debian/patches/compositor-sync-ring-Allow-the-gpu_fence-to-be-moved.patch --- mutter-46.0/debian/patches/compositor-sync-ring-Allow-the-gpu_fence-to-be-moved.patch 2024-04-18 20:01:26.000000000 +0000 +++ mutter-46.1/debian/patches/compositor-sync-ring-Allow-the-gpu_fence-to-be-moved.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -From: Daniel van Vugt -Date: Wed, 3 Apr 2024 16:58:13 +0800 -Subject: compositor/sync-ring: Allow the gpu_fence to be moved - -When the compositor inserts two waits in a frame, such as f606a4424a5afc, -the second insertion shouldn't break the ring's state machine as easily -as it does. We can instead merge the two GL waits into one by simply moving -the GL fence to the latest insertion. Each insertion still does its own X11 -sync though. - -Origin: Upstream commit 22689d722ab4e13ab272c3534f5d18a55c94084f -Bug: https://gitlab.gnome.org/GNOME/mutter/-/issues/3384 -Bug-Ubuntu: https://bugs.launchpad.net/bugs/2059847 ---- - src/compositor/meta-sync-ring.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/src/compositor/meta-sync-ring.c b/src/compositor/meta-sync-ring.c -index 8f5d1a0..1267dd4 100644 ---- a/src/compositor/meta-sync-ring.c -+++ b/src/compositor/meta-sync-ring.c -@@ -544,20 +544,29 @@ gboolean - meta_sync_ring_insert_wait (void) - { - MetaSyncRing *ring = meta_sync_ring_get (); -+ MetaSync *sync; - - if (!ring) - return FALSE; - - g_return_val_if_fail (ring->xdisplay != NULL, FALSE); - -- if (ring->current_sync->state != META_SYNC_STATE_READY) -+ sync = ring->current_sync; -+ -+ if (sync->state == META_SYNC_STATE_WAITING) -+ { -+ meta_gl_delete_sync (sync->gpu_fence); -+ sync->gpu_fence = 0; -+ sync->state = META_SYNC_STATE_READY; -+ } -+ else if (sync->state != META_SYNC_STATE_READY) - { - meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?"); - if (!meta_sync_ring_reboot (ring->xdisplay)) - return FALSE; - } - -- meta_sync_insert (ring->current_sync); -+ meta_sync_insert (sync); - - return TRUE; - } diff -Nru mutter-46.0/debian/patches/debian/Support-Dynamic-triple-double-buffering.patch mutter-46.1/debian/patches/debian/Support-Dynamic-triple-double-buffering.patch --- mutter-46.0/debian/patches/debian/Support-Dynamic-triple-double-buffering.patch 2024-04-18 20:01:26.000000000 +0000 +++ mutter-46.1/debian/patches/debian/Support-Dynamic-triple-double-buffering.patch 2024-05-03 14:46:53.000000000 +0000 @@ -22,9 +22,9 @@ Bug: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3760 Forwarded: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441 Applied-upstream: no, see also https://bugs.debian.org/1050020 -Last-Update: 2024-03-18 +Last-Update: 2024-04-29 --- - clutter/clutter/clutter-frame-clock.c | 352 +++++++++++++++++++++------ + clutter/clutter/clutter-frame-clock.c | 368 +++++++++++++++++++++++------ clutter/clutter/clutter-frame-clock.h | 11 +- clutter/clutter/clutter-frame-private.h | 1 + clutter/clutter/clutter-frame.c | 13 + @@ -32,6 +32,8 @@ clutter/clutter/clutter-stage-view.c | 11 +- cogl/cogl/cogl-onscreen-private.h | 5 +- cogl/cogl/cogl-onscreen.c | 8 + + meson.build | 1 - + po/pt.po | 142 +++++------ src/backends/meta-stage-impl.c | 2 + src/backends/native/meta-kms-impl-device.c | 4 +- src/backends/native/meta-kms.c | 9 + @@ -39,11 +41,15 @@ src/backends/native/meta-onscreen-native.c | 368 +++++++++++++++++++++++------ src/backends/native/meta-onscreen-native.h | 2 + src/backends/native/meta-renderer-native.c | 34 ++- + src/meson.build | 1 - src/tests/native-kms-render.c | 106 +++++++-- - 16 files changed, 762 insertions(+), 173 deletions(-) + src/wayland/meta-wayland-keyboard.c | 11 +- + src/wayland/meta-wayland-surface.c | 2 +- + src/wayland/meta-wayland-tablet-tool.c | 50 +++- + 22 files changed, 907 insertions(+), 251 deletions(-) diff --git a/clutter/clutter/clutter-frame-clock.c b/clutter/clutter/clutter-frame-clock.c -index 93e4c93..a6c7ece 100644 +index 93e4c93..b637fac 100644 --- a/clutter/clutter/clutter-frame-clock.c +++ b/clutter/clutter/clutter-frame-clock.c @@ -42,6 +42,15 @@ enum @@ -418,7 +424,33 @@ break; } -@@ -770,11 +892,18 @@ clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock) +@@ -753,6 +875,25 @@ clutter_frame_clock_uninhibit (ClutterFrameClock *frame_clock) + maybe_reschedule_update (frame_clock); + } + ++static gboolean ++want_triple_buffering (ClutterFrameClock *frame_clock) ++{ ++ switch (triple_buffering_mode) ++ { ++ case TRIPLE_BUFFERING_MODE_NEVER: ++ return FALSE; ++ case TRIPLE_BUFFERING_MODE_AUTO: ++ return frame_clock->mode == CLUTTER_FRAME_CLOCK_MODE_FIXED && ++ !(frame_clock->last_flip_hints & ++ CLUTTER_FRAME_HINT_DIRECT_SCANOUT_ATTEMPTED); ++ case TRIPLE_BUFFERING_MODE_ALWAYS: ++ return TRUE; ++ } ++ ++ g_assert_not_reached (); ++ return FALSE; ++} ++ + void + clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock) + { +@@ -770,11 +911,24 @@ clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock) case CLUTTER_FRAME_CLOCK_STATE_INIT: case CLUTTER_FRAME_CLOCK_STATE_IDLE: case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED: @@ -429,17 +461,23 @@ return; - case CLUTTER_FRAME_CLOCK_STATE_DISPATCHING: - case CLUTTER_FRAME_CLOCK_STATE_PENDING_PRESENTED: -+ case CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE: + case CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE_AND_SCHEDULED: -+ next_update_time_us = g_get_monotonic_time (); + frame_clock->state = + CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE_AND_SCHEDULED_NOW; + break; ++ case CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE: ++ if (want_triple_buffering (frame_clock)) ++ { ++ frame_clock->state = ++ CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE_AND_SCHEDULED_NOW; ++ break; ++ } ++ G_GNUC_FALLTHROUGH; + case CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_TWO: frame_clock->pending_reschedule = TRUE; frame_clock->pending_reschedule_now = TRUE; return; -@@ -803,13 +932,18 @@ clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock) +@@ -803,13 +957,17 @@ clutter_frame_clock_schedule_update_now (ClutterFrameClock *frame_clock) frame_clock->next_update_time_us = next_update_time_us; g_source_set_ready_time (frame_clock->source, next_update_time_us); @@ -453,13 +491,12 @@ + TripleBufferingMode current_mode = triple_buffering_mode; + + if (current_mode == TRIPLE_BUFFERING_MODE_AUTO && -+ (frame_clock->last_flip_hints & -+ CLUTTER_FRAME_HINT_DIRECT_SCANOUT_ATTEMPTED)) ++ !want_triple_buffering (frame_clock)) + current_mode = TRIPLE_BUFFERING_MODE_NEVER; if (frame_clock->inhibit_count > 0) { -@@ -825,12 +959,41 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock) +@@ -825,12 +983,33 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock) frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_SCHEDULED; return; case CLUTTER_FRAME_CLOCK_STATE_IDLE: @@ -479,14 +516,6 @@ + frame_clock->pending_reschedule = TRUE; + return; + case TRIPLE_BUFFERING_MODE_AUTO: -+ calculate_next_update_time_us (frame_clock, -+ &next_update_time_us, -+ &frame_clock->next_presentation_time_us, -+ &frame_clock->next_frame_deadline_us); -+ frame_clock->is_next_presentation_time_valid = -+ (frame_clock->next_presentation_time_us != 0); -+ frame_clock->has_next_frame_deadline = -+ (frame_clock->next_frame_deadline_us != 0); + frame_clock->state = + CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE_AND_SCHEDULED; + break; @@ -496,14 +525,14 @@ + frame_clock->is_next_presentation_time_valid = FALSE; + frame_clock->state = + CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE_AND_SCHEDULED; -+ break; ++ return; + } + break; + case CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_TWO: frame_clock->pending_reschedule = TRUE; return; } -@@ -859,7 +1022,6 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock) +@@ -859,7 +1038,6 @@ clutter_frame_clock_schedule_update (ClutterFrameClock *frame_clock) frame_clock->next_update_time_us = next_update_time_us; g_source_set_ready_time (frame_clock->source, next_update_time_us); @@ -511,7 +540,7 @@ } void -@@ -875,6 +1037,8 @@ clutter_frame_clock_set_mode (ClutterFrameClock *frame_clock, +@@ -875,6 +1053,8 @@ clutter_frame_clock_set_mode (ClutterFrameClock *frame_clock, { case CLUTTER_FRAME_CLOCK_STATE_INIT: case CLUTTER_FRAME_CLOCK_STATE_IDLE: @@ -520,7 +549,7 @@ break; case CLUTTER_FRAME_CLOCK_STATE_SCHEDULED: frame_clock->pending_reschedule = TRUE; -@@ -885,8 +1049,14 @@ clutter_frame_clock_set_mode (ClutterFrameClock *frame_clock, +@@ -885,8 +1065,14 @@ clutter_frame_clock_set_mode (ClutterFrameClock *frame_clock, frame_clock->pending_reschedule_now = TRUE; frame_clock->state = CLUTTER_FRAME_CLOCK_STATE_IDLE; break; @@ -537,7 +566,7 @@ break; } -@@ -922,7 +1092,7 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock, +@@ -922,7 +1108,7 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock, frame_clock->refresh_interval_us; lateness_us = time_us - ideal_dispatch_time_us; @@ -546,7 +575,7 @@ frame_clock->last_dispatch_lateness_us = 0; else frame_clock->last_dispatch_lateness_us = lateness_us; -@@ -943,10 +1113,27 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock, +@@ -943,10 +1129,27 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock, } #endif @@ -575,7 +604,7 @@ frame_count = frame_clock->frame_count++; -@@ -977,26 +1164,36 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock, +@@ -977,26 +1180,36 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock, result = iface->frame (frame_clock, frame, frame_clock->listener.user_data); COGL_TRACE_END (ClutterFrameClockFrame); @@ -625,7 +654,7 @@ } break; } -@@ -1029,21 +1226,31 @@ frame_clock_source_dispatch (GSource *source, +@@ -1029,21 +1242,31 @@ frame_clock_source_dispatch (GSource *source, } void @@ -662,7 +691,7 @@ if (frame_clock->got_measurements_last_frame) g_string_append_printf (string, " ="); -@@ -1210,8 +1417,6 @@ clutter_frame_clock_dispose (GObject *object) +@@ -1210,8 +1433,6 @@ clutter_frame_clock_dispose (GObject *object) { ClutterFrameClock *frame_clock = CLUTTER_FRAME_CLOCK (object); @@ -671,7 +700,7 @@ if (frame_clock->source) { g_signal_emit (frame_clock, signals[DESTROY], 0); -@@ -1235,6 +1440,15 @@ static void +@@ -1235,6 +1456,15 @@ static void clutter_frame_clock_class_init (ClutterFrameClockClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -765,10 +794,10 @@ + G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFrame, clutter_frame_unref) diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c -index b503ef8..1fbe3ae 100644 +index f5188e2..d53e377 100644 --- a/clutter/clutter/clutter-stage-view.c +++ b/clutter/clutter/clutter-stage-view.c -@@ -902,14 +902,21 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock, +@@ -898,14 +898,21 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock, _clutter_stage_window_redraw_view (stage_window, view, frame); @@ -806,10 +835,10 @@ +COGL_EXPORT unsigned int +cogl_onscreen_count_pending_frames (CoglOnscreen *onscreen); diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c -index f4b460a..3e3f73a 100644 +index afb648b..086be7e 100644 --- a/cogl/cogl/cogl-onscreen.c +++ b/cogl/cogl/cogl-onscreen.c -@@ -511,6 +511,14 @@ cogl_onscreen_pop_head_frame_info (CoglOnscreen *onscreen) +@@ -515,6 +515,14 @@ cogl_onscreen_pop_head_frame_info (CoglOnscreen *onscreen) return g_queue_pop_head (&priv->pending_frame_infos); } @@ -824,6 +853,364 @@ CoglFrameClosure * cogl_onscreen_add_frame_callback (CoglOnscreen *onscreen, CoglFrameCallback callback, +diff --git a/meson.build b/meson.build +index 131c19f..544b39c 100644 +--- a/meson.build ++++ b/meson.build +@@ -160,7 +160,6 @@ if have_x11_client + xkbfile_dep = dependency('xkbfile') + xkeyboard_config_dep = dependency('xkeyboard-config') + xkbcommon_x11_dep = dependency('xkbcommon-x11') +- xrender_dep = dependency('xrender') + x11_xcb_dep = dependency('x11-xcb') + xrandr_dep = dependency('xrandr', version: xrandr_req) + xcb_randr_dep = dependency('xcb-randr') +diff --git a/po/pt.po b/po/pt.po +index 88da880..c9968e9 100644 +--- a/po/pt.po ++++ b/po/pt.po +@@ -5,14 +5,14 @@ + # Pedro Albuquerque , 2015. + # Tiago Santos , 2016. + # Juliano de Souza Camargo , 2020. +-# Hugo Carvalho , 2020, 2021, 2022, 2023. ++# Hugo Carvalho , 2020, 2021, 2022, 2023, 2024. + # + msgid "" + msgstr "" + "Project-Id-Version: 3.10\n" +-"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" +-"POT-Creation-Date: 2023-07-16 01:41+0000\n" +-"PO-Revision-Date: 2023-08-04 17:11+0100\n" ++"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues/\n" ++"POT-Creation-Date: 2024-04-21 15:14+0000\n" ++"PO-Revision-Date: 2024-04-28 21:14+0100\n" + "Last-Translator: Hugo Carvalho \n" + "Language-Team: https://l10n.gnome.org/teams/pt/\n" + "Language: pt\n" +@@ -20,7 +20,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 3.3.2\n" ++"X-Generator: Poedit 3.4.2\n" + "X-DamnedLies-Scope: partial\n" + + #: data/50-mutter-navigation.xml:6 +@@ -251,11 +251,11 @@ msgstr "Maximizar janela verticalmente" + msgid "Maximize window horizontally" + msgstr "Maximizar janela horizontalmente" + +-#: data/50-mutter-windows.xml:41 data/org.gnome.mutter.gschema.xml.in:164 ++#: data/50-mutter-windows.xml:41 data/org.gnome.mutter.gschema.xml.in:167 + msgid "View split on left" + msgstr "Ver a divisão à esquerda" + +-#: data/50-mutter-windows.xml:45 data/org.gnome.mutter.gschema.xml.in:169 ++#: data/50-mutter-windows.xml:45 data/org.gnome.mutter.gschema.xml.in:172 + msgid "View split on right" + msgstr "Ver a divisão à direita" + +@@ -396,39 +396,43 @@ msgid "" + "space, while scaling monitor framebuffers instead of window content, to " + "manage HiDPI monitors. Does not require a restart. • “kms-modifiers” — makes " + "mutter always allocate scanout buffers with explicit modifiers, if supported " +-"by the driver. Requires a restart. • “rt-scheduler” — makes mutter request a " +-"low priority real-time scheduling. Requires a restart. • “autoclose-" +-"xwayland” — automatically terminates Xwayland if all relevant X11 clients " +-"are gone. Requires a restart." ++"by the driver. Requires a restart. • “autoclose-xwayland” — automatically " ++"terminates Xwayland if all relevant X11 clients are gone. Requires a " ++"restart. • “variable-refresh-rate” — makes mutter dynamically adjust the " ++"refresh rate of the monitor when applicable if supported by the monitor, GPU " ++"and DRM driver. Configurable in Settings. Requires a restart." + msgstr "" +-"Para ativar as funcionalidades experimentais, adicione a respetiva palavra-" +-"chave à lista. Se deve reiniciar o compositor após ativá-la, depende de cada " +-"funcionalidade. Qualquer funcionalidade experimental não necessita de estar " +-"disponível ou configurável. Não espere que adicionar algo nas definições " +-"seja mantido por tempo indeterminado. Atualmente as palavras-chave são: • " +-"“scale-monitor-framebuffer” — torna o mutter padrão para a disposição de " +-"monitores lógicos num espaço de coordenadas de pixel lógico, enquanto " +-"dimensiona os framebuffers do monitor em vez do conteúdo da janela, para " +-"gerir monitores HiDPI. Não requer um reinício. • “kms-modifiers” — faz o " +-"mutter publicitar sempre modificadores buffer. se suportado pelo " +-"controlador. Requer um reinício. - \"rt-scheduler\" - torna o pedido do " +-"mutter uma programação em tempo real de baixa prioridade. Requer um " +-"reinício. • “autoclose-xwayland” — Termina automaticamente o Xwayland se " +-"todos os clientes X11 relevantes desapareceram. Requer um reinício." +- +-#: data/org.gnome.mutter.gschema.xml.in:141 ++"Para ativar funcionalidades experimentais, adicione a palavra-chave " ++"caraterística à lista. O facto de a funcionalidade exigir o reinício do " ++"compositor depende da funcionalidade em causa. Não é necessário que qualquer " ++"recurso experimental ainda esteja disponível ou configurável. Não espere que " ++"adicionar algo nesta configuração seja à prova de futuro. Palavras-chave " ++"atualmente possíveis: - “scale-monitor-framebuffer” - torna o mutter padrão " ++"para a disposição de monitores lógicos em um espaço lógico de coordenadas de " ++"pixel, enquanto escala os framebuffers do monitor em vez do conteúdo da " ++"janela, para gerenciar monitores HiDPI. Não requer uma reinicialização. - " ++"“kms-modifiers” - faz com que o mutter sempre aloque buffers de \"scanout\" " ++"com modificadores explícitos, se suportados pelo controlador. Requer uma " ++"reinicialização. - “autoclose-xwayland” - termina automaticamente o Xwayland " ++"se todos os clientes X11 relevantes tiverem desaparecido. Requer um " ++"reinício. - “variable-refresh-rate” - faz com que o mutter ajuste " ++"dinamicamente a taxa de atualização do monitor quando aplicável, se " ++"suportado pelo monitor, GPU e driver DRM. Configurável em Definições. Requer " ++"uma reinicialização." ++ ++#: data/org.gnome.mutter.gschema.xml.in:144 + msgid "Modifier to use to locate the pointer" + msgstr "Modificador para localizar o cursor" + +-#: data/org.gnome.mutter.gschema.xml.in:142 ++#: data/org.gnome.mutter.gschema.xml.in:145 + msgid "This key will initiate the “locate pointer” action." + msgstr "Esta chave iniciará a ação “localizar cursor”." + +-#: data/org.gnome.mutter.gschema.xml.in:149 ++#: data/org.gnome.mutter.gschema.xml.in:152 + msgid "Timeout for check-alive ping" + msgstr "Expirou o teste de atividade" + +-#: data/org.gnome.mutter.gschema.xml.in:150 ++#: data/org.gnome.mutter.gschema.xml.in:153 + 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." +@@ -437,15 +441,15 @@ msgstr "" + "atividade de maneira que não seja detetado como inativo. Usar 0 desativará o " + "teste de atividade completamente." + +-#: data/org.gnome.mutter.gschema.xml.in:174 ++#: data/org.gnome.mutter.gschema.xml.in:177 + msgid "Switch monitor configurations" + msgstr "Alternar configurações de ecrã" + +-#: data/org.gnome.mutter.gschema.xml.in:179 ++#: data/org.gnome.mutter.gschema.xml.in:182 + msgid "Rotates the built-in monitor configuration" + msgstr "Alternar as configurações nativas do ecrã" + +-#: data/org.gnome.mutter.gschema.xml.in:184 ++#: data/org.gnome.mutter.gschema.xml.in:187 + msgid "Cancel any active input capture session" + msgstr "Cancelar qualquer sessão de captura de entrada ativa" + +@@ -603,26 +607,26 @@ msgstr "" + "configuração. O Xwayland precisa de ser reiniciado para que esta " + "configuração tenha efeito." + +-#: src/backends/meta-monitor.c:253 ++#: src/backends/meta-monitor.c:251 + msgid "Built-in display" + msgstr "Ecrã embutido" + +-#: src/backends/meta-monitor.c:280 ++#: src/backends/meta-monitor.c:278 + msgid "Unknown" + msgstr "Desconhecido" + +-#: src/backends/meta-monitor.c:282 ++#: src/backends/meta-monitor.c:280 + msgid "Unknown Display" + msgstr "Ecrã desconhecido" + +-#: src/backends/meta-monitor.c:290 ++#: src/backends/meta-monitor.c:288 + #, 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:298 ++#: src/backends/meta-monitor.c:296 + #, c-format + msgctxt "" + "This is a monitor vendor name followed by product/model name where size in " +@@ -634,78 +638,82 @@ msgstr "%s %s" + msgid "Bell event" + msgstr "Evento de campainha" + +-#: src/core/display.c:718 ++#: src/core/display.c:734 + msgid "Privacy Screen Enabled" + msgstr "Ecrã de privacidade ativado" + +-#: src/core/display.c:719 ++#: src/core/display.c:735 + msgid "Privacy Screen Disabled" + msgstr "Ecrã de privacidade desativado" + +-#: src/core/meta-context-main.c:581 ++#: src/core/meta-context-main.c:601 + msgid "Replace the running window manager" + msgstr "Substituir o gestor de janelas em execução" + +-#: src/core/meta-context-main.c:587 ++#: src/core/meta-context-main.c:607 + msgid "X Display to use" + msgstr "Ecrã X a utilizar" + +-#: src/core/meta-context-main.c:593 ++#: src/core/meta-context-main.c:613 + msgid "Disable connection to session manager" + msgstr "Desativar a ligação ao gestor de sessão" + +-#: src/core/meta-context-main.c:599 ++#: src/core/meta-context-main.c:619 + msgid "Specify session management ID" + msgstr "Especificar a ID de gestão de sessão" + +-#: src/core/meta-context-main.c:605 ++#: src/core/meta-context-main.c:625 + msgid "Initialize session from savefile" + msgstr "Inicializar a sessão a partir de um ficheiro de gravação de sessão" + +-#: src/core/meta-context-main.c:611 ++#: src/core/meta-context-main.c:631 + msgid "Make X calls synchronous" + msgstr "Fazer as chamadas X sincronamente" + +-#: src/core/meta-context-main.c:619 ++#: src/core/meta-context-main.c:639 + msgid "Run as a wayland compositor" + msgstr "Executar como compositor wayland" + +-#: src/core/meta-context-main.c:625 ++#: src/core/meta-context-main.c:645 + msgid "Run as a nested compositor" + msgstr "Executar como compositor aninhado" + +-#: src/core/meta-context-main.c:631 ++#: src/core/meta-context-main.c:651 + msgid "Run wayland compositor without starting Xwayland" + msgstr "Executar o compositor wayland sem a utilização do Xwayland" + +-#: src/core/meta-context-main.c:637 ++#: src/core/meta-context-main.c:657 + msgid "Specify Wayland display name to use" + msgstr "Especificar o nome do visor Wayland a utilizar" + +-#: src/core/meta-context-main.c:645 ++#: src/core/meta-context-main.c:665 + msgid "Run as a full display server, rather than nested" + msgstr "Executar como servidor de ecrã inteiro, em vez de aninhado" + +-#: src/core/meta-context-main.c:650 ++#: src/core/meta-context-main.c:670 + msgid "Run as a headless display server" + msgstr "Executar como um servidor sem monitor" + +-#: src/core/meta-context-main.c:655 ++#: src/core/meta-context-main.c:675 + msgid "Add persistent virtual monitor (WxH or WxH@R)" + msgstr "Adicionar monitor virtual persistente (WxH ou WxH@R)" + +-#: src/core/meta-context-main.c:667 ++#: src/core/meta-context-main.c:687 + msgid "Run with X11 backend" + msgstr "Executar com a infira-estrutura X11" + +-#: src/core/meta-context-main.c:673 ++#: src/core/meta-context-main.c:693 + msgid "Profile performance using trace instrumentation" + msgstr "Desempenho do perfil utilizando instrumentação de rastreio" + ++#: src/core/meta-context-main.c:699 ++msgid "Enable debug control D-Bus interface" ++msgstr "Ativar o controlo de depuração da interface D-Bus" ++ + #. TRANSLATORS: This string refers to a button that switches between + #. * different modes. + #. +-#: src/core/meta-pad-action-mapper.c:861 ++#: src/core/meta-pad-action-mapper.c:826 + #, c-format + msgid "Mode Switch (Group %d)" + msgstr "Alteração de modo (Grupo %d)" +@@ -713,16 +721,16 @@ msgstr "Alteração de modo (Grupo %d)" + #. TRANSLATORS: This string refers to an action, cycles drawing tablets' + #. * mapping through the available outputs. + #. +-#: src/core/meta-pad-action-mapper.c:884 ++#: src/core/meta-pad-action-mapper.c:848 + msgid "Switch monitor" + msgstr "Alternar monitor" + +-#: src/core/meta-pad-action-mapper.c:886 ++#: src/core/meta-pad-action-mapper.c:850 + msgid "Show on-screen help" + msgstr "Mostrar ajuda no ecrã" + + #. Translators: this string will appear in Sysprof +-#: src/core/meta-profiler.c:111 src/core/meta-profiler.c:301 ++#: src/core/meta-profiler.c:109 src/core/meta-profiler.c:299 + msgid "Compositor" + msgstr "Compositor" + +@@ -734,7 +742,7 @@ msgstr "Imprimir a versão" + msgid "Mutter plugin to use" + msgstr "Extensão Mutter a utilizar" + +-#: src/core/prefs.c:1843 ++#: src/core/prefs.c:1842 + #, c-format + msgid "Workspace %d" + msgstr "Área de trabalho %d" +@@ -743,16 +751,16 @@ msgstr "Área de trabalho %d" + msgid "Mutter was compiled without support for verbose mode" + msgstr "O Mutter foi compilado sem suporte para modo verbose" + +-#: src/core/workspace.c:541 ++#: src/core/workspace.c:510 + msgid "Workspace switched" + msgstr "Área de trabalho alterada" + +-#: src/wayland/meta-wayland-tablet-pad.c:530 ++#: src/wayland/meta-wayland-tablet-pad.c:532 + #, c-format + msgid "Mode Switch: Mode %d" + msgstr "Alteração de Modo: Modo %d" + +-#: src/x11/meta-x11-display.c:708 ++#: src/x11/meta-x11-display.c:723 + #, c-format + msgid "" + "Display “%s” already has a window manager; try using the --replace option to " +@@ -761,19 +769,19 @@ msgstr "" + "O ecrã “%s” já tem um gestor de janelas; tente utilizar a opção --replace " + "para substituir o gestor de janelas atual." + +-#: src/x11/meta-x11-display.c:1073 ++#: src/x11/meta-x11-display.c:1088 + #, c-format + msgid "Failed to open X Window System display “%s”" + msgstr "Falha ao abrir ecrã “%s” do sistema Janelas X" + +-#: src/x11/meta-x11-display.c:1219 ++#: src/x11/meta-x11-display.c:1268 + #, c-format + msgid "Screen %d on display “%s” is invalid" + msgstr "Ecrã %d no monitor “%s” é inválido" + + #. This probably means that a non-WM compositor like xcompmgr is running; + #. * we have no way to get it to exit +-#: src/x11/meta-x11-display.c:2550 ++#: src/x11/meta-x11-display.c:2547 + #, c-format + msgid "" + "Another compositing manager is already running on screen %i on display “%s”." +@@ -785,7 +793,7 @@ msgstr "" + msgid "Format %s not supported" + msgstr "O formato “%s” não é suportado" + +-#: src/x11/window-props.c:548 ++#: src/x11/window-props.c:528 + #, c-format + msgid "%s (on %s)" + msgstr "%s (em %s)" diff --git a/src/backends/meta-stage-impl.c b/src/backends/meta-stage-impl.c index 7aa2443..727e1a5 100644 --- a/src/backends/meta-stage-impl.c @@ -902,10 +1289,10 @@ MetaKmsFlags flags, GError **error); diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c -index e40b03f..9617d00 100644 +index 1a31f04..9836663 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c -@@ -75,7 +75,7 @@ typedef struct _MetaOnscreenNativeSecondaryGpuState +@@ -76,7 +76,7 @@ typedef struct _MetaOnscreenNativeSecondaryGpuState struct { MetaDrmBufferDumb *current_dumb_fb; @@ -914,7 +1301,7 @@ } cpu; gboolean noted_primary_gpu_copy_ok; -@@ -97,9 +97,13 @@ struct _MetaOnscreenNative +@@ -98,9 +98,13 @@ struct _MetaOnscreenNative struct { struct gbm_surface *surface; MetaDrmBuffer *current_fb; @@ -928,7 +1315,7 @@ } gbm; #ifdef HAVE_EGL_DEVICE -@@ -124,6 +128,16 @@ struct _MetaOnscreenNative +@@ -125,6 +129,16 @@ struct _MetaOnscreenNative gulong privacy_screen_changed_handler_id; gulong color_space_changed_handler_id; gulong hdr_metadata_changed_handler_id; @@ -945,7 +1332,7 @@ }; G_DEFINE_TYPE (MetaOnscreenNative, meta_onscreen_native, -@@ -131,44 +145,42 @@ G_DEFINE_TYPE (MetaOnscreenNative, meta_onscreen_native, +@@ -132,44 +146,42 @@ G_DEFINE_TYPE (MetaOnscreenNative, meta_onscreen_native, static GQuark blit_source_quark = 0; @@ -1006,7 +1393,7 @@ } static void -@@ -206,7 +218,7 @@ meta_onscreen_native_notify_frame_complete (CoglOnscreen *onscreen) +@@ -207,7 +219,7 @@ meta_onscreen_native_notify_frame_complete (CoglOnscreen *onscreen) info = cogl_onscreen_pop_head_frame_info (onscreen); @@ -1015,7 +1402,7 @@ _cogl_onscreen_notify_frame_sync (onscreen, info); _cogl_onscreen_notify_complete (onscreen, info); -@@ -242,6 +254,7 @@ notify_view_crtc_presented (MetaRendererView *view, +@@ -243,6 +255,7 @@ notify_view_crtc_presented (MetaRendererView *view, meta_onscreen_native_notify_frame_complete (onscreen); meta_onscreen_native_swap_drm_fb (onscreen); @@ -1023,7 +1410,7 @@ } static void -@@ -291,15 +304,13 @@ page_flip_feedback_ready (MetaKmsCrtc *kms_crtc, +@@ -292,15 +305,13 @@ page_flip_feedback_ready (MetaKmsCrtc *kms_crtc, CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (CLUTTER_STAGE_VIEW (view)); CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); @@ -1040,7 +1427,7 @@ } static void -@@ -349,7 +360,8 @@ page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc, +@@ -350,7 +361,8 @@ page_flip_feedback_discarded (MetaKmsCrtc *kms_crtc, frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC; meta_onscreen_native_notify_frame_complete (onscreen); @@ -1050,7 +1437,7 @@ } static const MetaKmsPageFlipListenerVtable page_flip_listener_vtable = { -@@ -410,18 +422,41 @@ custom_egl_stream_page_flip (gpointer custom_page_flip_data, +@@ -411,18 +423,41 @@ custom_egl_stream_page_flip (gpointer custom_page_flip_data, } #endif /* HAVE_EGL_DEVICE */ @@ -1096,9 +1483,9 @@ apply_transform (MetaCrtcKms *crtc_kms, MetaKmsPlaneAssignment *kms_plane_assignment, @@ -521,13 +556,21 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, - graphene_rect_t src_rect; - MtkRectangle dst_rect; - + switch (renderer_gpu_data->mode) + { + case META_RENDERER_NATIVE_MODE_GBM: - buffer = onscreen_native->gbm.next_fb; + g_set_object (&onscreen_native->gbm.posted_fb, + onscreen_native->gbm.next_fb); @@ -1121,7 +1508,7 @@ &dst_rect); } else -@@ -915,12 +958,17 @@ static MetaDrmBufferDumb * +@@ -918,12 +961,17 @@ static MetaDrmBufferDumb * secondary_gpu_get_next_dumb_buffer (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state) { MetaDrmBufferDumb *current_dumb_fb; @@ -1143,7 +1530,7 @@ } static MetaDrmBuffer * -@@ -1253,10 +1301,17 @@ swap_buffer_result_feedback (const MetaKmsFeedback *kms_feedback, +@@ -1255,10 +1303,17 @@ swap_buffer_result_feedback (const MetaKmsFeedback *kms_feedback, g_warning ("Page flip failed: %s", error->message); frame_info = cogl_onscreen_peek_head_frame_info (onscreen); @@ -1164,7 +1551,7 @@ } static const MetaKmsResultListenerVtable swap_buffer_result_listener_vtable = { -@@ -1277,30 +1332,35 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, +@@ -1279,32 +1334,37 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; @@ -1173,12 +1560,14 @@ - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; MetaGpuKms *render_gpu = onscreen_native->render_gpu; MetaDeviceFile *render_device_file; ClutterFrame *frame = user_data; - MetaFrameNative *frame_native = meta_frame_native_from_frame (frame); - MetaKmsUpdate *kms_update; CoglOnscreenClass *parent_class; + gboolean create_timestamp_query = TRUE; gboolean egl_context_changed = FALSE; - MetaPowerSave power_save_mode; g_autoptr (GError) error = NULL; @@ -1209,7 +1598,7 @@ secondary_gpu_fb = update_secondary_gpu_state_pre_swap_buffers (onscreen, rectangles, -@@ -1359,7 +1419,17 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, +@@ -1379,7 +1439,17 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, switch (renderer_gpu_data->mode) { case META_RENDERER_NATIVE_MODE_GBM: @@ -1228,7 +1617,7 @@ if (onscreen_native->secondary_gpu_state) g_set_object (&onscreen_native->gbm.next_fb, secondary_gpu_fb); else -@@ -1373,6 +1443,9 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, +@@ -1404,6 +1474,9 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, #endif } @@ -1238,7 +1627,7 @@ /* * If we changed EGL context, cogl will have the wrong idea about what is * current, making it fail to set it when it needs to. Avoid that by making -@@ -1382,12 +1455,78 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, +@@ -1413,12 +1486,78 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, if (egl_context_changed) _cogl_winsys_egl_ensure_current (cogl_display); @@ -1319,7 +1708,7 @@ kms_update = meta_frame_native_ensure_kms_update (frame_native, kms_device); meta_kms_update_add_result_listener (kms_update, -@@ -1402,15 +1541,13 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, +@@ -1433,15 +1572,13 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, onscreen_native->crtc, kms_update, META_KMS_ASSIGN_PLANE_FLAG_NONE, @@ -1337,7 +1726,7 @@ return; } -@@ -1430,8 +1567,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, +@@ -1461,8 +1598,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, kms_update = meta_frame_native_steal_kms_update (frame_native); meta_renderer_native_queue_mode_set_update (renderer_native, kms_update); @@ -1346,7 +1735,7 @@ return; } else if (meta_renderer_native_has_pending_mode_set (renderer_native)) -@@ -1445,8 +1580,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, +@@ -1476,8 +1611,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, meta_frame_native_steal_kms_update (frame_native); meta_renderer_native_post_mode_set_updates (renderer_native); @@ -1355,7 +1744,7 @@ return; } break; -@@ -1462,8 +1595,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, +@@ -1493,8 +1626,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, kms_update); meta_renderer_native_post_mode_set_updates (renderer_native); @@ -1364,7 +1753,7 @@ return; } break; -@@ -1478,7 +1609,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, +@@ -1509,7 +1640,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, kms_update = meta_frame_native_steal_kms_update (frame_native); meta_kms_device_post_update (kms_device, kms_update, META_KMS_UPDATE_FLAG_NONE); @@ -1372,7 +1761,7 @@ } gboolean -@@ -1549,7 +1679,7 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback, +@@ -1580,7 +1710,7 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback, g_warning ("Direct scanout page flip failed: %s", error->message); @@ -1381,7 +1770,7 @@ onscreen); clutter_stage_view_add_redraw_clip (view, NULL); clutter_stage_view_schedule_update_now (view); -@@ -1559,7 +1689,7 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback, +@@ -1590,7 +1720,7 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback, frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC; meta_onscreen_native_notify_frame_complete (onscreen); @@ -1390,7 +1779,7 @@ } static const MetaKmsResultListenerVtable scanout_result_listener_vtable = { -@@ -1611,6 +1741,18 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, +@@ -1642,6 +1772,18 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen, return FALSE; } @@ -1409,7 +1798,7 @@ renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, render_gpu); -@@ -1726,11 +1868,7 @@ meta_onscreen_native_before_redraw (CoglOnscreen *onscreen, +@@ -1757,11 +1899,7 @@ meta_onscreen_native_before_redraw (CoglOnscreen *onscreen, ClutterFrame *frame) { MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); @@ -1421,7 +1810,7 @@ maybe_update_frame_sync (onscreen_native, frame); } -@@ -1846,22 +1984,79 @@ meta_onscreen_native_finish_frame (CoglOnscreen *onscreen, +@@ -1877,22 +2015,79 @@ meta_onscreen_native_finish_frame (CoglOnscreen *onscreen, MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc); MetaFrameNative *frame_native = meta_frame_native_from_frame (frame); MetaKmsUpdate *kms_update; @@ -1509,7 +1898,7 @@ meta_kms_update_add_result_listener (kms_update, &finish_frame_result_listener_vtable, NULL, -@@ -1884,7 +2079,19 @@ meta_onscreen_native_finish_frame (CoglOnscreen *onscreen, +@@ -1915,7 +2110,19 @@ meta_onscreen_native_finish_frame (CoglOnscreen *onscreen, meta_kms_update_set_flushing (kms_update, kms_crtc); meta_kms_device_post_update (kms_device, kms_update, META_KMS_UPDATE_FLAG_NONE); @@ -1530,7 +1919,7 @@ } static gboolean -@@ -2790,8 +2997,11 @@ meta_onscreen_native_dispose (GObject *object) +@@ -2830,8 +3037,11 @@ meta_onscreen_native_dispose (GObject *object) { case META_RENDERER_NATIVE_MODE_GBM: g_clear_object (&onscreen_native->gbm.next_fb); @@ -1543,7 +1932,7 @@ break; case META_RENDERER_NATIVE_MODE_SURFACELESS: g_assert_not_reached (); -@@ -2825,6 +3035,10 @@ meta_onscreen_native_dispose (GObject *object) +@@ -2865,6 +3075,10 @@ meta_onscreen_native_dispose (GObject *object) g_clear_object (&onscreen_native->output); g_clear_object (&onscreen_native->crtc); @@ -1568,10 +1957,10 @@ MetaRendererView *view); diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c -index 7b64ff3..c32a6ca 100644 +index aa76d01..3c22b4e 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c -@@ -726,12 +726,18 @@ static gboolean +@@ -731,12 +731,18 @@ static gboolean dummy_power_save_page_flip_cb (gpointer user_data) { MetaRendererNative *renderer_native = user_data; @@ -1592,7 +1981,7 @@ renderer_native->power_save_page_flip_source_id = 0; return G_SOURCE_REMOVE; -@@ -743,6 +749,9 @@ meta_renderer_native_queue_power_save_page_flip (MetaRendererNative *renderer_na +@@ -748,6 +754,9 @@ meta_renderer_native_queue_power_save_page_flip (MetaRendererNative *renderer_na { const unsigned int timeout_ms = 100; @@ -1602,7 +1991,7 @@ if (!renderer_native->power_save_page_flip_source_id) { renderer_native->power_save_page_flip_source_id = -@@ -1524,6 +1533,26 @@ detach_onscreens (MetaRenderer *renderer) +@@ -1529,6 +1538,26 @@ detach_onscreens (MetaRenderer *renderer) } } @@ -1629,7 +2018,7 @@ static void meta_renderer_native_rebuild_views (MetaRenderer *renderer) { -@@ -1534,6 +1563,7 @@ meta_renderer_native_rebuild_views (MetaRenderer *renderer) +@@ -1539,6 +1568,7 @@ meta_renderer_native_rebuild_views (MetaRenderer *renderer) MetaRendererClass *parent_renderer_class = META_RENDERER_CLASS (meta_renderer_native_parent_class); @@ -1637,6 +2026,18 @@ meta_kms_discard_pending_page_flips (kms); g_hash_table_remove_all (renderer_native->mode_set_updates); +diff --git a/src/meson.build b/src/meson.build +index 05df3bf..3060b28 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -115,7 +115,6 @@ if have_x11 + xkbfile_dep, + xkeyboard_config_dep, + xkbcommon_x11_dep, +- xrender_dep, + x11_xcb_dep, + xcb_randr_dep, + xcb_res_dep, diff --git a/src/tests/native-kms-render.c b/src/tests/native-kms-render.c index f5ebc23..2f870fd 100644 --- a/src/tests/native-kms-render.c @@ -1880,3 +2281,148 @@ .loop = g_main_loop_new (NULL, FALSE), }; +diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c +index 80c772a..3c741a0 100644 +--- a/src/wayland/meta-wayland-keyboard.c ++++ b/src/wayland/meta-wayland-keyboard.c +@@ -77,6 +77,7 @@ struct _MetaWaylandKeyboard + struct wl_array pressed_keys; + GHashTable *key_down_serials; + uint32_t last_key_up_serial; ++ uint32_t last_key_up; + + MetaWaylandXkbInfo xkb_info; + enum xkb_state_component mods_changed; +@@ -279,6 +280,13 @@ meta_wayland_keyboard_broadcast_key (MetaWaylandKeyboard *keyboard, + + serial = meta_wayland_input_device_next_serial (input_device); + ++ if (keyboard->last_key_up) ++ { ++ g_hash_table_remove (keyboard->key_down_serials, ++ GUINT_TO_POINTER (keyboard->last_key_up)); ++ keyboard->last_key_up = 0; ++ } ++ + if (state) + { + g_hash_table_insert (keyboard->key_down_serials, +@@ -288,9 +296,8 @@ meta_wayland_keyboard_broadcast_key (MetaWaylandKeyboard *keyboard, + } + else + { +- g_hash_table_remove (keyboard->key_down_serials, +- GUINT_TO_POINTER (key)); + keyboard->last_key_up_serial = serial; ++ keyboard->last_key_up = key; + } + + wl_resource_for_each (resource, &keyboard->focus_resource_list) +diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c +index 6dc5006..64d9408 100644 +--- a/src/wayland/meta-wayland-surface.c ++++ b/src/wayland/meta-wayland-surface.c +@@ -2457,7 +2457,7 @@ committed_state_handle_highest_scale_monitor (MetaWaylandSurface *surface) + transform = meta_wayland_surface_get_output_transform (surface); + if (transform != surface->preferred_transform) + { +- wl_surface_send_preferred_buffer_transform (surface->resource, ceiled_scale); ++ wl_surface_send_preferred_buffer_transform (surface->resource, transform); + surface->preferred_transform = transform; + } + } +diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c +index 5d83383..c262391 100644 +--- a/src/wayland/meta-wayland-tablet-tool.c ++++ b/src/wayland/meta-wayland-tablet-tool.c +@@ -64,9 +64,14 @@ struct _MetaWaylandTabletTool + + float grab_x, grab_y; + ++ gulong current_surface_destroyed_handler_id; ++ + MetaWaylandTablet *current_tablet; + }; + ++static void meta_wayland_tablet_tool_set_current_surface (MetaWaylandTabletTool *tool, ++ MetaWaylandSurface *surface); ++ + static MetaBackend * + backend_from_tool (MetaWaylandTabletTool *tool) + { +@@ -453,6 +458,7 @@ meta_wayland_tablet_tool_free (MetaWaylandTabletTool *tool) + { + struct wl_resource *resource, *next; + ++ meta_wayland_tablet_tool_set_current_surface (tool, NULL); + meta_wayland_tablet_tool_set_focus (tool, NULL, NULL); + meta_wayland_tablet_tool_set_cursor_surface (tool, NULL); + g_clear_object (&tool->cursor_renderer); +@@ -595,10 +601,41 @@ meta_wayland_tablet_tool_account_button (MetaWaylandTabletTool *tool, + } + + static void +-sync_focus_surface (MetaWaylandTabletTool *tool, +- const ClutterEvent *event) ++current_surface_destroyed (MetaWaylandSurface *surface, ++ MetaWaylandTabletTool *tool) + { +- meta_wayland_tablet_tool_set_focus (tool, tool->current, event); ++ meta_wayland_tablet_tool_set_current_surface (tool, NULL); ++} ++ ++static void ++meta_wayland_tablet_tool_set_current_surface (MetaWaylandTabletTool *tool, ++ MetaWaylandSurface *surface) ++{ ++ MetaWaylandTabletSeat *tablet_seat; ++ MetaWaylandInput *input; ++ ++ if (tool->current == surface) ++ return; ++ ++ if (tool->current) ++ { ++ g_clear_signal_handler (&tool->current_surface_destroyed_handler_id, ++ tool->current); ++ tool->current = NULL; ++ } ++ ++ if (surface) ++ { ++ tool->current = surface; ++ tool->current_surface_destroyed_handler_id = ++ g_signal_connect (surface, "destroy", ++ G_CALLBACK (current_surface_destroyed), ++ tool); ++ } ++ ++ tablet_seat = tool->seat; ++ input = meta_wayland_seat_get_input (tablet_seat->seat); ++ meta_wayland_input_invalidate_focus (input, tool->device, NULL); + } + + static void +@@ -607,6 +644,7 @@ repick_for_event (MetaWaylandTabletTool *tool, + { + MetaBackend *backend = backend_from_tool (tool); + ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); ++ MetaWaylandSurface *surface; + ClutterActor *actor; + + actor = clutter_stage_get_device_actor (stage, +@@ -614,11 +652,11 @@ repick_for_event (MetaWaylandTabletTool *tool, + clutter_event_get_event_sequence (for_event)); + + if (META_IS_SURFACE_ACTOR_WAYLAND (actor)) +- tool->current = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor)); ++ surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor)); + else +- tool->current = NULL; ++ surface = NULL; + +- sync_focus_surface (tool, for_event); ++ meta_wayland_tablet_tool_set_current_surface (tool, surface); + meta_wayland_tablet_tool_update_cursor_surface (tool); + } + diff -Nru mutter-46.0/debian/patches/series mutter-46.1/debian/patches/series --- mutter-46.0/debian/patches/series 2024-04-18 20:01:26.000000000 +0000 +++ mutter-46.1/debian/patches/series 2024-05-03 14:46:53.000000000 +0000 @@ -6,7 +6,5 @@ workarounds/tests-Skip-thread-priority-test.patch workarounds/Mark-several-additional-tests-as-flaky.patch workarounds/kms-crtc-Increase-default-deadline-evasion-to-1000-micros.patch -Nvidia-secondary-GPU-copy-acceleration.patch ubuntu/x11-Add-support-for-fractional-scaling-using-Randr.patch ubuntu/window-Add-ability-to-override-the-edge-constraints.patch -compositor-sync-ring-Allow-the-gpu_fence-to-be-moved.patch diff -Nru mutter-46.0/meson.build mutter-46.1/meson.build --- mutter-46.0/meson.build 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/meson.build 2024-04-19 17:48:34.000000000 +0000 @@ -1,5 +1,5 @@ project('mutter', 'c', - version: '46.0', + version: '46.1', meson_version: '>= 0.60.0', license: 'GPLv2+' ) @@ -541,6 +541,8 @@ cc.compiles('void main (void) { __builtin_ffsl (0); __builtin_popcountl (0); }') +have_eventfd = cc.has_header('sys/eventfd.h') + cdata = configuration_data() cdata.set_quoted('GETTEXT_PACKAGE', gettext_package) cdata.set_quoted('VERSION', meson.project_version()) @@ -573,6 +575,7 @@ cdata.set('HAVE_PANGO_FT2', have_pango_ft2) cdata.set('HAVE_TIMERFD', have_timerfd) cdata.set('HAVE_MALLOC_TRIM', have_malloc_trim) +cdata.set('HAVE_EVENTFD', have_eventfd) if have_x11_client xkb_base = xkeyboard_config_dep.get_variable('xkb_base') diff -Nru mutter-46.0/mtk/mtk/mtk-rectangle.c mutter-46.1/mtk/mtk/mtk-rectangle.c --- mutter-46.0/mtk/mtk/mtk-rectangle.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/mtk/mtk/mtk-rectangle.c 2024-04-19 17:48:34.000000000 +0000 @@ -65,6 +65,12 @@ return rect; } +MtkRectangle * +mtk_rectangle_new_empty (void) +{ + return g_new0 (MtkRectangle, 1); +} + /** * mtk_rectangle_area: * @rect: A rectangle diff -Nru mutter-46.0/mtk/mtk/mtk-rectangle.h mutter-46.1/mtk/mtk/mtk-rectangle.h --- mutter-46.0/mtk/mtk/mtk-rectangle.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/mtk/mtk/mtk-rectangle.h 2024-04-19 17:48:34.000000000 +0000 @@ -86,6 +86,9 @@ int width, int height); +MTK_EXPORT +MtkRectangle * mtk_rectangle_new_empty (void); + /* Basic comparison functions */ MTK_EXPORT int mtk_rectangle_area (const MtkRectangle *rect); @@ -149,3 +152,5 @@ MTK_EXPORT gboolean mtk_rectangle_is_adjacent_to (const MtkRectangle *rect, const MtkRectangle *other); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MtkRectangle, mtk_rectangle_free) diff -Nru mutter-46.0/po/LINGUAS mutter-46.1/po/LINGUAS --- mutter-46.0/po/LINGUAS 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/po/LINGUAS 2024-04-19 17:48:34.000000000 +0000 @@ -47,6 +47,7 @@ it ja ka +kab kk kn ko diff -Nru mutter-46.0/po/fur.po mutter-46.1/po/fur.po --- mutter-46.0/po/fur.po 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/po/fur.po 2024-04-19 17:48:34.000000000 +0000 @@ -6,9 +6,9 @@ msgid "" msgstr "" "Project-Id-Version: mutter master\n" -"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" -"POT-Creation-Date: 2023-07-16 01:41+0000\n" -"PO-Revision-Date: 2023-07-20 23:48+0200\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues/\n" +"POT-Creation-Date: 2024-03-02 12:22+0000\n" +"PO-Revision-Date: 2024-04-18 10:09+0200\n" "Last-Translator: Fabio T. \n" "Language-Team: Friulian \n" "Language: fur\n" @@ -16,7 +16,7 @@ "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Editor: HaiPO 1.4 beta\n" -"X-Generator: Poedit 3.2.2\n" +"X-Generator: Poedit 3.4.2\n" #: data/50-mutter-navigation.xml:6 msgid "Navigation" @@ -246,11 +246,11 @@ msgid "Maximize window horizontally" msgstr "Slargje il barcon par orizontâl" -#: data/50-mutter-windows.xml:41 data/org.gnome.mutter.gschema.xml.in:164 +#: data/50-mutter-windows.xml:41 data/org.gnome.mutter.gschema.xml.in:167 msgid "View split on left" msgstr "Slargje dividint ae çampe" -#: data/50-mutter-windows.xml:45 data/org.gnome.mutter.gschema.xml.in:169 +#: data/50-mutter-windows.xml:45 data/org.gnome.mutter.gschema.xml.in:172 msgid "View split on right" msgstr "Slargje dividint ae drete" @@ -390,10 +390,11 @@ "space, while scaling monitor framebuffers instead of window content, to " "manage HiDPI monitors. Does not require a restart. • “kms-modifiers” — makes " "mutter always allocate scanout buffers with explicit modifiers, if supported " -"by the driver. Requires a restart. • “rt-scheduler” — makes mutter request a " -"low priority real-time scheduling. Requires a restart. • “autoclose-" -"xwayland” — automatically terminates Xwayland if all relevant X11 clients " -"are gone. Requires a restart." +"by the driver. Requires a restart. • “autoclose-xwayland” — automatically " +"terminates Xwayland if all relevant X11 clients are gone. Requires a " +"restart. • “variable-refresh-rate” — makes mutter dynamically adjust the " +"refresh rate of the monitor when applicable if supported by the monitor, GPU " +"and DRM driver. Configurable in Settings. Requires a restart." msgstr "" "Par abilitâ lis funzionalitâts sperimentâls, zonte la peraule clâf de " "funzionalitât ae liste. Il fat che la funzionalitât e vedi bisugne di tornâ " @@ -406,25 +407,26 @@ "scjalâts i framebuffers dai visôrs invezit che il contignût dal barcon; dut " "chest par gjestî i visôrs HiDPI. Nol covente tornâ a inviâ. • “kms-" "modifiers” — al fâs in mût che mutter al publicizi simpri modificadôrs di " -"memorie tampon valits su Wayland. Al covente tornâ a inviâ. • “rt-scheduler” " -"— al fâs in mût che mutter al domandi une programazion in timp reâl a " -"prioritât basse. Al covente tornâ a inviâ. • “autoclose-xwayland” — al " -"termine in automatic Xwayland se ducj i clients X11 a son lâts. Nol covente " -"tornâ a inviâ." +"memorie tampon valits se supuartât dal driver. Al covente tornâ a inviâ. • " +"“autoclose-xwayland” — al termine in automatic Xwayland se ducj i clients " +"X11 a son lâts. Al covente tornâ a inviâ. • “variable-refresh-rate” — al fâs " +"in mût che mutter al justi in maniere dinamiche la frecuence di inzornament " +"dal visôr là che al pues se il visôr, la GPU e il driver DRM lu supuartin. " +"Al è configurabil tes Impostazions. Al covente tornâ a inviâ." -#: data/org.gnome.mutter.gschema.xml.in:141 +#: data/org.gnome.mutter.gschema.xml.in:144 msgid "Modifier to use to locate the pointer" msgstr "Modificadôr di doprâ par localizâ il pontadôr" -#: data/org.gnome.mutter.gschema.xml.in:142 +#: data/org.gnome.mutter.gschema.xml.in:145 msgid "This key will initiate the “locate pointer” action." msgstr "Cheste clâf e inizializerâ la azion “localize pontadôr”." -#: data/org.gnome.mutter.gschema.xml.in:149 +#: data/org.gnome.mutter.gschema.xml.in:152 msgid "Timeout for check-alive ping" msgstr "Timp scjadût pal control di sorevivence dal ping" -#: data/org.gnome.mutter.gschema.xml.in:150 +#: data/org.gnome.mutter.gschema.xml.in:153 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." @@ -433,15 +435,15 @@ "richieste di ping, par fâ in mût che nol vegni identificât tant che " "inglaçât. Doprant 0 si disabilitarà dal dut il control di sorevivence." -#: data/org.gnome.mutter.gschema.xml.in:174 +#: data/org.gnome.mutter.gschema.xml.in:177 msgid "Switch monitor configurations" msgstr "Cambie configurazions visôr" -#: data/org.gnome.mutter.gschema.xml.in:179 +#: data/org.gnome.mutter.gschema.xml.in:182 msgid "Rotates the built-in monitor configuration" msgstr "Al volte la configurazion dal visôr integrât" -#: data/org.gnome.mutter.gschema.xml.in:184 +#: data/org.gnome.mutter.gschema.xml.in:187 msgid "Cancel any active input capture session" msgstr "Anule cualsisei session di acuisizion di input ative" @@ -599,26 +601,26 @@ "modifiche di cheste impostazion e necessite il tornâ a inviâ Xwayland par fâ " "in mût che e sedi efetive." -#: src/backends/meta-monitor.c:253 +#: src/backends/meta-monitor.c:251 msgid "Built-in display" msgstr "Display integrât" -#: src/backends/meta-monitor.c:280 +#: src/backends/meta-monitor.c:278 msgid "Unknown" msgstr "No cognossût" -#: src/backends/meta-monitor.c:282 +#: src/backends/meta-monitor.c:280 msgid "Unknown Display" msgstr "Display no cognossût" -#: src/backends/meta-monitor.c:290 +#: src/backends/meta-monitor.c:288 #, 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:298 +#: src/backends/meta-monitor.c:296 #, c-format msgctxt "" "This is a monitor vendor name followed by product/model name where size in " @@ -630,78 +632,82 @@ msgid "Bell event" msgstr "Event cjampane" -#: src/core/display.c:718 +#: src/core/display.c:734 msgid "Privacy Screen Enabled" msgstr "Schermade di riservatece abilitât" -#: src/core/display.c:719 +#: src/core/display.c:735 msgid "Privacy Screen Disabled" msgstr "Schermade di riservatece disabilitât" -#: src/core/meta-context-main.c:581 +#: src/core/meta-context-main.c:601 msgid "Replace the running window manager" msgstr "Rimplace il window manager in vore" -#: src/core/meta-context-main.c:587 +#: src/core/meta-context-main.c:607 msgid "X Display to use" msgstr "Display X di doprâ" -#: src/core/meta-context-main.c:593 +#: src/core/meta-context-main.c:613 msgid "Disable connection to session manager" msgstr "Disabilite la conession al gjestôr de session" -#: src/core/meta-context-main.c:599 +#: src/core/meta-context-main.c:619 msgid "Specify session management ID" msgstr "Specifiche il ID di gjestion session" -#: src/core/meta-context-main.c:605 +#: src/core/meta-context-main.c:625 msgid "Initialize session from savefile" msgstr "Inizialize session da file salvât" -#: src/core/meta-context-main.c:611 +#: src/core/meta-context-main.c:631 msgid "Make X calls synchronous" msgstr "Fâs lis clamadis X sincronis" -#: src/core/meta-context-main.c:619 +#: src/core/meta-context-main.c:639 msgid "Run as a wayland compositor" msgstr "Eseguìs come compositor wayland" -#: src/core/meta-context-main.c:625 +#: src/core/meta-context-main.c:645 msgid "Run as a nested compositor" msgstr "Eseguìs come compositor nidiât" -#: src/core/meta-context-main.c:631 +#: src/core/meta-context-main.c:651 msgid "Run wayland compositor without starting Xwayland" msgstr "Eseguìs il compositôr di wayland cence inviâ Xwayland" -#: src/core/meta-context-main.c:637 +#: src/core/meta-context-main.c:657 msgid "Specify Wayland display name to use" msgstr "Specifiche il non dal display Wayland di doprâ" -#: src/core/meta-context-main.c:645 +#: src/core/meta-context-main.c:665 msgid "Run as a full display server, rather than nested" msgstr "Eseguìs come servidôr display complet, invezit che nidiât" -#: src/core/meta-context-main.c:650 +#: src/core/meta-context-main.c:670 msgid "Run as a headless display server" msgstr "Eseguìs come servidôr di visualizazion cence visôr" -#: src/core/meta-context-main.c:655 +#: src/core/meta-context-main.c:675 msgid "Add persistent virtual monitor (WxH or WxH@R)" msgstr "Zonte monitor virtuâl persistent (LxA o LxA@I)" -#: src/core/meta-context-main.c:667 +#: src/core/meta-context-main.c:687 msgid "Run with X11 backend" msgstr "Eseguìs cul backend X11" -#: src/core/meta-context-main.c:673 +#: src/core/meta-context-main.c:693 msgid "Profile performance using trace instrumentation" msgstr "Profile lis prestazions doprant une strumentazion par tignî di voli" +#: src/core/meta-context-main.c:699 +msgid "Enable debug control D-Bus interface" +msgstr "Abilite la interface D-Bus pal control dal debug" + #. TRANSLATORS: This string refers to a button that switches between #. * different modes. #. -#: src/core/meta-pad-action-mapper.c:861 +#: src/core/meta-pad-action-mapper.c:826 #, c-format msgid "Mode Switch (Group %d)" msgstr "Cambie mût (Grup %d)" @@ -709,16 +715,16 @@ #. TRANSLATORS: This string refers to an action, cycles drawing tablets' #. * mapping through the available outputs. #. -#: src/core/meta-pad-action-mapper.c:884 +#: src/core/meta-pad-action-mapper.c:848 msgid "Switch monitor" msgstr "Cambie visôr" -#: src/core/meta-pad-action-mapper.c:886 +#: src/core/meta-pad-action-mapper.c:850 msgid "Show on-screen help" msgstr "Mostre jutori a schermi" #. Translators: this string will appear in Sysprof -#: src/core/meta-profiler.c:111 src/core/meta-profiler.c:301 +#: src/core/meta-profiler.c:109 src/core/meta-profiler.c:299 msgid "Compositor" msgstr "Composidôr" @@ -730,7 +736,7 @@ msgid "Mutter plugin to use" msgstr "Plugin Mutter di doprâ" -#: src/core/prefs.c:1843 +#: src/core/prefs.c:1842 #, c-format msgid "Workspace %d" msgstr "Spazi di lavôr %d" @@ -739,16 +745,16 @@ msgid "Mutter was compiled without support for verbose mode" msgstr "Mutter al è stât compilât cence supuart pal mût prolìs" -#: src/core/workspace.c:541 +#: src/core/workspace.c:510 msgid "Workspace switched" msgstr "Spazi di lavôr cambiât" -#: src/wayland/meta-wayland-tablet-pad.c:530 +#: src/wayland/meta-wayland-tablet-pad.c:532 #, c-format msgid "Mode Switch: Mode %d" msgstr "Cambie mût: mût %d" -#: src/x11/meta-x11-display.c:708 +#: src/x11/meta-x11-display.c:723 #, c-format msgid "" "Display “%s” already has a window manager; try using the --replace option to " @@ -757,19 +763,19 @@ "Il display “%s” al à za un window manager; prove dopre la opzion --replace " "par rimplaçâ chel atuâl." -#: src/x11/meta-x11-display.c:1073 +#: src/x11/meta-x11-display.c:1088 #, c-format msgid "Failed to open X Window System display “%s”" msgstr "Impussibil vierzi il display “%s” di X Window System" -#: src/x11/meta-x11-display.c:1219 +#: src/x11/meta-x11-display.c:1268 #, c-format msgid "Screen %d on display “%s” is invalid" msgstr "Schermi %d su display “%s” no valit" #. This probably means that a non-WM compositor like xcompmgr is running; #. * we have no way to get it to exit -#: src/x11/meta-x11-display.c:2550 +#: src/x11/meta-x11-display.c:2538 #, c-format msgid "" "Another compositing manager is already running on screen %i on display “%s”." @@ -782,7 +788,7 @@ msgid "Format %s not supported" msgstr "Il formât %s nol è supuartât" -#: src/x11/window-props.c:548 +#: src/x11/window-props.c:528 #, c-format msgid "%s (on %s)" msgstr "%s (su %s)" diff -Nru mutter-46.0/po/kab.po mutter-46.1/po/kab.po --- mutter-46.0/po/kab.po 1970-01-01 00:00:00.000000000 +0000 +++ mutter-46.1/po/kab.po 2024-04-19 17:48:34.000000000 +0000 @@ -0,0 +1,793 @@ +# Kabyle translation for mutter. +# Copyright (C) 2024 mutter's COPYRIGHT HOLDER +# This file is distributed under the same license as the mutter package. +# FIRST AUTHOR , YEAR. +# ButterflyOfFire , 2024. +# +msgid "" +msgstr "" +"Project-Id-Version: mutter main\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues/\n" +"POT-Creation-Date: 2024-04-04 12:25+0000\n" +"PO-Revision-Date: 2024-04-08 06:56+0200\n" +"Last-Translator: sa\n" +"Language-Team: Kabyle <>\n" +"Language: kab\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n>1;\n" +"X-DL-Team: kab\n" +"X-DL-Module: mutter\n" +"X-DL-Branch: main\n" +"X-DL-Domain: po\n" +"X-DL-State: Translating\n" +"X-Generator: Poedit 3.4.2\n" + +#: data/50-mutter-navigation.xml:6 +msgid "Navigation" +msgstr "Tunigin" + +#: data/50-mutter-navigation.xml:9 +msgid "Move window to workspace 1" +msgstr "Smutti asfaylu ɣer tallunt umahil tis 1" + +#: data/50-mutter-navigation.xml:12 +msgid "Move window to workspace 2" +msgstr "Smutti asfaylu ɣer tallunt umahil tis 2" + +#: data/50-mutter-navigation.xml:15 +msgid "Move window to workspace 3" +msgstr "Smutti asfaylu ɣer tallunt umahil tis 3" + +#: data/50-mutter-navigation.xml:18 +msgid "Move window to workspace 4" +msgstr "Smutti asfaylu ɣer tallunt umahil tis 3" + +#: data/50-mutter-navigation.xml:21 +msgid "Move window to last workspace" +msgstr "Smutti asfaylu ɣer tallunt umahil" + +#: data/50-mutter-navigation.xml:24 +msgid "Move window one workspace to the left" +msgstr "Ssiweḍ asfaylu yiwet n tallunt n umahil yellan ɣer tama tazelmaḍt" + +#: data/50-mutter-navigation.xml:27 +msgid "Move window one workspace to the right" +msgstr "Ssiweḍ asfaylu yiwet n tallunt n umahil yellan ɣer tama tayeffust" + +#: data/50-mutter-navigation.xml:31 +msgid "Move window one workspace up" +msgstr "Ssiweḍ asfaylu yiwet n tallunt n umahil yellan d asawen" + +#: data/50-mutter-navigation.xml:35 +msgid "Move window one workspace down" +msgstr "Ssiweḍ asfaylu yiwet n tallunt n umahil yellan d akessar" + +#: data/50-mutter-navigation.xml:38 +msgid "Move window one monitor to the left" +msgstr "Senkez asfaylu s yiwen usefrak ɣer uzelmaḍ" + +#: data/50-mutter-navigation.xml:41 +msgid "Move window one monitor to the right" +msgstr "Senkez asfaylu s yiwen usefrak ɣer uyeffus" + +#: data/50-mutter-navigation.xml:44 +msgid "Move window one monitor up" +msgstr "Senkez asfaylu s yiwen usefrak d asawen" + +#: data/50-mutter-navigation.xml:47 +msgid "Move window one monitor down" +msgstr "Senkez asfaylu s yiwen usefrak d akessar" + +#: data/50-mutter-navigation.xml:51 +msgid "Switch applications" +msgstr "Senfel isnasen" + +#: data/50-mutter-navigation.xml:56 +msgid "Switch to previous application" +msgstr "Uɣal ɣer usnas yezrin" + +#: data/50-mutter-navigation.xml:60 +msgid "Switch windows" +msgstr "Senfel isfuyla" + +#: data/50-mutter-navigation.xml:65 +msgid "Switch to previous window" +msgstr "Uɣal ɣer usfaylu yezrin" + +#: data/50-mutter-navigation.xml:69 +msgid "Switch windows of an application" +msgstr "Senfel isfuyla n usnas" + +#: data/50-mutter-navigation.xml:74 +msgid "Switch to previous window of an application" +msgstr "Uɣal ɣer usfaylu yezrin n usnas" + +#: data/50-mutter-navigation.xml:78 +msgid "Switch system controls" +msgstr "Senfel isenqaden n unagraw" + +#: data/50-mutter-navigation.xml:83 +msgid "Switch to previous system control" +msgstr "Uɣal ɣer usenqad n unagraw yezrin" + +#: data/50-mutter-navigation.xml:87 +msgid "Switch windows directly" +msgstr "Senfel srid isfuyla" + +#: data/50-mutter-navigation.xml:92 +msgid "Switch directly to previous window" +msgstr "Uɣam srid ɣer usfaylu yezrin" + +#: data/50-mutter-navigation.xml:96 +msgid "Switch windows of an app directly" +msgstr "Senfel srid isfuyla n usnas" + +#: data/50-mutter-navigation.xml:101 +msgid "Switch directly to previous window of an app" +msgstr "Uɣal srid usfaylu yezrin n usnas" + +#: data/50-mutter-navigation.xml:105 +msgid "Switch system controls directly" +msgstr "Senfel srid isenqaden n ungraw" + +#: data/50-mutter-navigation.xml:110 +msgid "Switch directly to previous system control" +msgstr "Uɣal srid ɣer usenqad n ungraw yezrin" + +#: data/50-mutter-navigation.xml:113 +msgid "Hide all normal windows" +msgstr "Ffer akk isfuyla imugna" + +#: data/50-mutter-navigation.xml:116 +msgid "Switch to workspace 1" +msgstr "Ddu ɣer tallunt n umahil tis 1" + +#: data/50-mutter-navigation.xml:119 +msgid "Switch to workspace 2" +msgstr "Ddu ɣer tallunt n umahil tis 2" + +#: data/50-mutter-navigation.xml:122 +msgid "Switch to workspace 3" +msgstr "Ddu ɣer tallunt n umahil tis 3" + +#: data/50-mutter-navigation.xml:125 +msgid "Switch to workspace 4" +msgstr "Ddu ɣer tallunt n umahil tis 4" + +#: data/50-mutter-navigation.xml:128 +msgid "Switch to last workspace" +msgstr "Ddu ɣer tallunt n umahil taneggarut" + +#: data/50-mutter-navigation.xml:131 +msgid "Switch to workspace on the left" +msgstr "Ddu ɣer tallunt n umahil deg tama taẓelmaḍt" + +#: data/50-mutter-navigation.xml:134 +msgid "Switch to workspace on the right" +msgstr "Ddu ɣer tallunt n umahil deg tama tayeffust" + +#: data/50-mutter-navigation.xml:138 +msgid "Switch to workspace above" +msgstr "Ddu ɣer tallunt n umahil ufella" + +#: data/50-mutter-navigation.xml:142 +msgid "Switch to workspace below" +msgstr "Ddu ɣer tallunt n umahil wadda" + +#: data/50-mutter-system.xml:6 data/50-mutter-wayland.xml:6 +msgid "System" +msgstr "Anagraw" + +#: data/50-mutter-system.xml:8 +msgid "Show the run command prompt" +msgstr "Sken aneftay n tladna n uselkem" + +#: data/50-mutter-wayland.xml:8 +msgid "Restore the keyboard shortcuts" +msgstr "Err-d inegzumen n unasiw" + +#: data/50-mutter-windows.xml:6 +msgid "Windows" +msgstr "Isfuyla" + +#: data/50-mutter-windows.xml:8 +msgid "Activate the window menu" +msgstr "Rmed umuɣ n usfaylu" + +#: data/50-mutter-windows.xml:10 +msgid "Toggle fullscreen mode" +msgstr "Ldi/Mdel askar n ugdil aččuran" + +#: data/50-mutter-windows.xml:12 +msgid "Toggle maximization state" +msgstr "Ldi/Mdel addad n usumɣer" + +#: data/50-mutter-windows.xml:14 +msgid "Maximize window" +msgstr "Semɣer asfaylu" + +#: data/50-mutter-windows.xml:16 +msgid "Restore window" +msgstr "Err-d asfaylu" + +#: data/50-mutter-windows.xml:18 +msgid "Close window" +msgstr "Mdel asfaylu" + +#: data/50-mutter-windows.xml:20 +msgid "Hide window" +msgstr "Ffer asfaylu" + +#: data/50-mutter-windows.xml:22 +msgid "Move window" +msgstr "Senkez asfaylu" + +#: data/50-mutter-windows.xml:24 +msgid "Resize window" +msgstr "Semsawi teɣzi n usfaylu" + +#: data/50-mutter-windows.xml:27 +msgid "Toggle window on all workspaces or one" +msgstr "Ldi/Mdel asfaylu deg meṛṛa tallunin n umahil neɣ deg yiwet kan" + +#: data/50-mutter-windows.xml:29 +msgid "Raise window if covered, otherwise lower it" +msgstr "Sali asfaylu ma yella iɣumm, neɣ ṣbb-it" + +#: data/50-mutter-windows.xml:31 +msgid "Raise window above other windows" +msgstr "Sezmer asfaylu yellan nnig yisfuyla niḍen" + +#: data/50-mutter-windows.xml:33 +msgid "Lower window below other windows" +msgstr "Asfaylu n wadda ddaw n yisfuyla niḍen" + +#: data/50-mutter-windows.xml:35 +msgid "Maximize window vertically" +msgstr "Semɣer asfaylu s wudem ubdid" + +#: data/50-mutter-windows.xml:37 +msgid "Maximize window horizontally" +msgstr "Semɣer asfaylu s wudem aglawan" + +#: data/50-mutter-windows.xml:41 data/org.gnome.mutter.gschema.xml.in:167 +msgid "View split on left" +msgstr "Sken beṭṭu ɣer uzelmaḍ" + +#: data/50-mutter-windows.xml:45 data/org.gnome.mutter.gschema.xml.in:172 +msgid "View split on right" +msgstr "Sken beṭṭu ɣer uyeffus" + +#: data/org.gnome.mutter.gschema.xml.in:15 +msgid "Modifier to use for extended window management operations" +msgstr "Aneglam ara yettwasqedcen i temhilin ɣezzifen n usefrek n yisfuyla" + +#: data/org.gnome.mutter.gschema.xml.in:16 +msgid "" +"This key will initiate the “overlay”, which is a combination window overview " +"and application launching system. The default is intended to be the “Windows " +"key” on PC hardware. It’s expected that this binding either the default or " +"set to the empty string." +msgstr "" +"Tasarut-a ad twennez \"asembibbi\", d anagraw n usuddes n teskant n yisfuyla " +"akked uskar n usnas. Azal amezwer d \"tasarut n Windows\" ɣef warrum PC. " +"Yetturaǧu tasarut-a ad tettusbadu s wudem amezwer neɣ ad tettusbadu ɣer " +"uzrir ilem." + +#: data/org.gnome.mutter.gschema.xml.in:28 +msgid "Attach modal dialogs" +msgstr "Seddu idiwenniyen iskaranen" + +#: data/org.gnome.mutter.gschema.xml.in:29 +msgid "" +"When true, instead of having independent titlebars, modal dialogs appear " +"attached to the titlebar of the parent window and are moved together with " +"the parent window." +msgstr "" +"Mi ara yili d tidet, deg wadeg n yifeggagen n yizwal ilelliyen, idiwenniyen " +"iskaranen ad d-banen ddan deg ufeggag n uzwel n usfaylu maraw, ad " +"ttwasnekzen akken akkedd usfaylu amaraw." + +#: data/org.gnome.mutter.gschema.xml.in:38 +msgid "Enable edge tiling when dropping windows on screen edges" +msgstr "Rmed aburset n tamiwin mi ara tserseḍ isfuyla ɣef tamiwin n ugdil" + +#: data/org.gnome.mutter.gschema.xml.in:39 +msgid "" +"If enabled, dropping windows on vertical screen edges maximizes them " +"vertically and resizes them horizontally to cover half of the available " +"area. Dropping windows on the top screen edge maximizes them completely." +msgstr "" +"Ma yella tettwarmed textiṛt-a, tarusi yisfuyla ɣef tamiwin tiratakin n ugdil " +"ad ttwasmeɣren s wudem aglawan, akken ara ččaren azgen n temnaḍt i yellan. " +"Azuɣer n yisfuyla ɣef tama tafellayt n ugdil ad ten-issemɣer s wudem ummid." + +#: data/org.gnome.mutter.gschema.xml.in:48 +msgid "Workspaces are managed dynamically" +msgstr "Tallunin n umahil ttwasefrakent s wudem asmussan" + +#: data/org.gnome.mutter.gschema.xml.in:49 +msgid "" +"Determines whether workspaces are managed dynamically or whether there’s a " +"static number of workspaces (determined by the num-workspaces key in org." +"gnome.desktop.wm.preferences)." +msgstr "" +"Yettguccul ma yella tallunin n umahil ttwasefrakent s wudem asmussan neɣ ma " +"yella amḍan udmis n tallunin n umahil (yettwaguccel s tsarut num-workspaces " +"deg org.gnome.desktop.wm.preferences)." + +#: data/org.gnome.mutter.gschema.xml.in:58 +msgid "Workspaces only on primary" +msgstr "Tallunin n umahil ɣef umezwaru kan" + +#: data/org.gnome.mutter.gschema.xml.in:59 +msgid "" +"Determines whether workspace switching should happen for windows on all " +"monitors or only for windows on the primary monitor." +msgstr "" +"Yesguccul ma yella tallunin n umahil ttwasefrakent s wudem asmussan neɣ ma " +"yella amḍan udmis n tallunin n umahil (yettwaguccel s tsarut num-workspaces " +"deg org.gnome.desktop.wm.preferences)." + +#: data/org.gnome.mutter.gschema.xml.in:67 +msgid "Delay focus changes until the pointer stops moving" +msgstr "Saẓey isenfal n usaḍes alamma asewwar ad iḥbes asenkez" + +#: data/org.gnome.mutter.gschema.xml.in:68 +msgid "" +"If set to true, and the focus mode is either “sloppy” or “mouse” then the " +"focus will not be changed immediately when entering a window, but only after " +"the pointer stops moving." +msgstr "" +"Ma yella yettusbadu s tidet, askar asaḍes \"sloppy\" neɣ \"d taɣerdayt\", " +"asiḍes ur yettwasenfal ara mi ara d-yekcem usfaylu, maca ma yeḥbes kan " +"usewwar asenkez." + +#: data/org.gnome.mutter.gschema.xml.in:78 +msgid "Draggable border width" +msgstr "Tehri n tama yettwazuɣaren" + +#: data/org.gnome.mutter.gschema.xml.in:79 +msgid "" +"The amount of total draggable borders. If the theme’s visible borders are " +"not enough, invisible borders will be added to meet this value." +msgstr "" +"Tasmekta tasemdayt n tamiwin i izmeren ad tettwaszuɣarent. Ma yella tamiwin " +"ibanen n usentel d timagdazin, tamiwin ur nban ara ad ttwarnunt i wakken ad " +"yaweḍ wazal-nni." + +#: data/org.gnome.mutter.gschema.xml.in:88 +msgid "Auto maximize nearly monitor sized windows" +msgstr "Asemɣer awurman i yisfuyla n teɣzi i iqerben ɣer teɣzi n ugdil" + +#: data/org.gnome.mutter.gschema.xml.in:89 +msgid "" +"If enabled, new windows that are initially the size of the monitor " +"automatically get maximized." +msgstr "" +"Ma yella yettwarmed, isfuyla imaynuten i yesεan teɣzi am tin n ugdil " +"yettnernin s wudem awurman." + +#: data/org.gnome.mutter.gschema.xml.in:97 +msgid "Place new windows in the center" +msgstr "Sers isfuyla imaynuten deg tlemmast" + +#: data/org.gnome.mutter.gschema.xml.in:98 +msgid "" +"When true, the new windows will always be put in the center of the active " +"screen of the monitor." +msgstr "" +"Ma yella d tidet, isfuyla imaynuten zgan ttuɣalen deg tlemmast n ugdil urmid " +"n usefrak." + +#: data/org.gnome.mutter.gschema.xml.in:107 +msgid "Enable experimental features" +msgstr "Rmed timahilin tirmitanin" + +#: data/org.gnome.mutter.gschema.xml.in:108 +msgid "" +"To enable experimental features, add the feature keyword to the list. " +"Whether the feature requires restarting the compositor depends on the given " +"feature. Any experimental feature is not required to still be available, or " +"configurable. Don’t expect adding anything in this setting to be future " +"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. • “kms-modifiers” — makes " +"mutter always allocate scanout buffers with explicit modifiers, if supported " +"by the driver. Requires a restart. • “autoclose-xwayland” — automatically " +"terminates Xwayland if all relevant X11 clients are gone. Requires a " +"restart. • “variable-refresh-rate” — makes mutter dynamically adjust the " +"refresh rate of the monitor when applicable if supported by the monitor, GPU " +"and DRM driver. Configurable in Settings. Requires a restart." +msgstr "" +"I urmad n tmahilin tirmitanin, rnu awal n tsarut n tmahilt ɣer tebdart. " +"Allus n usenker n usuddas yettwasra almend n tmahilt i d-yettwamudden. Ur " +"tettwasra ara kra n tmahilt tarmitant ad teqqim tella kan neɣ tezmer ad " +"tettuswal. Mačči yal timerna n kra deg uɣewwar-a yeskanay-d imal. Awalen n " +"tsura yettwaqbalen akka tura: • “scale-monitor-framebuffer” — yettarra " +"mutter ad yesεu s wudem amezwer isefraken imeẓẓulen deg wadeg ameẓẓul n " +"yimsidag n yipiksilen, lawan n usemɣer n yikataren n usefrak deg wadeg n " +"ugbur n usfaylu, i usefrek n HiDPI. Ur yesra allus n usenker. • “kms-" +"modifiers” — yettarra mutter yezga yettḥerri aḥrazen n uḍummu s yisenfalayen " +"iflayanen, ma yella yettwasefrak sɣur unuḍaf. Yesra allus n usenkar. • " +"“autoclose-xwayland” — yettfakk s wudem awurman Xwayland ma yella akk " +"imsaɣen X11 yesεan azal ruḥen. Yesra allus n usenker. • “variable-refresh-" +"rate” — yettarra mutter yezmer ad isemsawi s wudem asmussan aktum n usismeḍ " +"n usefrak, ma yella tettunefk tegnit, ma yella yettwasefrak sɣur usefrak, " +"GPU akked unuḍaf DRM. Yettwaswal deg yiɣewwaren. Yesra alluas n usenker." + +#: data/org.gnome.mutter.gschema.xml.in:144 +msgid "Modifier to use to locate the pointer" +msgstr "Senfel ara yettwasqedcen i usideg n usewwaṛ" + +#: data/org.gnome.mutter.gschema.xml.in:145 +msgid "This key will initiate the “locate pointer” action." +msgstr "Tasarut-a ad twennez tigawt n \"usideg n usewwaṛ\"." + +#: data/org.gnome.mutter.gschema.xml.in:152 +msgid "Timeout for check-alive ping" +msgstr "Tanzagt n keffu n ping n usenqed" + +#: data/org.gnome.mutter.gschema.xml.in:153 +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 "" +"Amḍan n yiliten tsinin i yesεa umsaɣ i wakken ad yerr ɣef ussuter ping akken " +"ur yettuneḥsab ara yegres. Aseqdec n 0 yesnusuy s wudem ummid asenqed n " +"tiltin n umsaɣ." + +#: data/org.gnome.mutter.gschema.xml.in:177 +msgid "Switch monitor configurations" +msgstr "Senfel tiwila n usefrak" + +#: data/org.gnome.mutter.gschema.xml.in:182 +msgid "Rotates the built-in monitor configuration" +msgstr "Sezzi tawila n usefrak usliɣ" + +#: data/org.gnome.mutter.gschema.xml.in:187 +msgid "Cancel any active input capture session" +msgstr "Sefsex akk n tɣimiyin n tuṭṭfa n unekcum yettwaremden" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:12 +msgid "Switch to VT 1" +msgstr "Ddu ɣer VT 1" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:16 +msgid "Switch to VT 2" +msgstr "Ddu ɣer VT 2" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:20 +msgid "Switch to VT 3" +msgstr "Ddu ɣer VT 3" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:24 +msgid "Switch to VT 4" +msgstr "Ddu ɣer VT 4" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:28 +msgid "Switch to VT 5" +msgstr "Ddu ɣer VT 5" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:32 +msgid "Switch to VT 6" +msgstr "Ddu ɣer VT 6" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:36 +msgid "Switch to VT 7" +msgstr "Ddu ɣer VT 7" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:40 +msgid "Switch to VT 8" +msgstr "Ddu ɣer VT 8" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:44 +msgid "Switch to VT 9" +msgstr "Ddu ɣer VT 9" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:48 +msgid "Switch to VT 10" +msgstr "Ddu ɣer VT 10" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:52 +msgid "Switch to VT 11" +msgstr "Ddu ɣer VT 11" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:56 +msgid "Switch to VT 12" +msgstr "Ddu ɣer VT 12" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:60 +msgid "Re-enable shortcuts" +msgstr "Ales armad n yinegzumen n unasiw" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:70 +msgid "Allow X11 grabs to lock keyboard focus with Xwayland" +msgstr "Sireg tuṭṭfiwin X11 ad sekkṛent afukus n unasiw s Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:71 +msgid "" +"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 " +"allowed in key “xwayland-grab-access-rules”." +msgstr "" +"Asireg n usezzi n meṛṛa tidyanin n unasiw ɣer yisfuyla X11 \"override " +"redirect\" s uzuɣer lawan n uselkem deg Xwayland. Taxtiṛt-a tettaǧǧa imsaɣen " +"X11 azuɣer n usfaylu \"override redirect\" (ur nremmes ara asiḍes n unasiw) " +"akked useqdec n uzuɣer i uḥettem n meṛṛa tidyanin n unasiw ɣer usfaylu-a. " +"Taxtiṛt-a ur tettwaseqdac ara s waṭas, ur txeddem kra i yisfuyla X11 i " +"izemren ad remsen asiḍes n unasiw deg tegnatin timugna. I uzuɣer n X11 ad " +"tettwaṭṭef deg Wayland, amsaɣ ilaq ad yazen daɣen X11 ClientMessage ɣer " +"usfaylu aẓar neɣ ad yili seg yisnasen yettwasirgen deg tsarut “xwayland-grab-" +"access-rules”." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:90 +msgid "Xwayland applications allowed to issue keyboard grabs" +msgstr "Isnasen Xwayland ttusirgent ad gent tuṭṭfiwin n unasiw" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:91 +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 " +"resource class of a given X11 window can be obtained using the command " +"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. " +"Values starting with “!” are denied, which has precedence over the list of " +"values allowed, to revoke applications from the default system list. The " +"default system list includes the following applications: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by " +"using the specific keyboard shortcut defined by the keybinding key “restore-" +"shortcuts”." +msgstr "" +"Bder ismawen n yiɣbula neɣ ismilen n yiɣbula n yisfuyla X11 yettwasirgen neɣ " +"uhu, ad gen tuṭṭfiwin n unasiw X11 deg Wayland. Isem neɣ asmel n uɣbalu n " +"usfaylu X11 i yettwamudden zemren ad d-ttwawin s useqdec n tladna “xprop " +"WM_CLASS”. Isekkilen imcettlen “*” akked ijukiṛen “?” deg wazalen " +"yettwasferken. Azalen i ibeddun s \"!\" ttwagin, i yellan deg tebdart " +"yettwasirgen yakan, i usefsex n yisnasen seg tebdart n unagraw amezwer. " +"Tabdart n unagraw amezwer deg-s isnasen-a: " +"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Iseqdacen zemren ad sḥebsen tira " +"yellan yakan s useqdec n unegzum n unasiw uzzig yettusbadun s tsarut n " +"tuqqna \"restore-shortcuts\"." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:116 +msgid "Disable selected X extensions in Xwayland" +msgstr "Sens isiɣzaf X i yettwafernen deg Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:117 +msgid "" +"This option disables the selected X extensions in Xwayland if Xwayland was " +"built with support for those X extensions. This option has no effect if " +"Xwayland was built without support for the selected extensions. Xwayland " +"needs to be restarted for this setting to take effect." +msgstr "" +"Taxtiṛt-a tesnusuy isiɣzaf X i yettwafernen deg Xwayland ma yella Xwayland " +"yebna s usefrek i yisiɣzaf-a X. Taxtiṛt-a ur d-tgellu s wecemma ma yella " +"Xwayland yebna war asefrek n yisiɣzaf i yettwafernen. Xwayland yesra ad " +"yales asenker i uɣewwar-a i wakken ad yeddu." + +#: data/org.gnome.mutter.wayland.gschema.xml.in:130 +msgid "Allow X11 clients with a different endianness to connect to Xwayland" +msgstr "Sireg imsaɣen X11 s at taggara yemgaraden i tuqqna ɣer Xwayland" + +#: data/org.gnome.mutter.wayland.gschema.xml.in:131 +msgid "" +"Allow connections from clients with an endianness different to that of " +"Xwayland. The X server byte-swapping code is a huge attack surface, much of " +"that code in Xwayland is prone to security issues. The use-case of byte-" +"swapped clients is very niche, and disabled by default in Xwayland. Enable " +"this option to instruct Xwayland to accept connections from X11 clients with " +"a different endianness. This option has no effect if Xwayland does not " +"support the command line option +byteswappedclients/-byteswappedclients to " +"control that setting. Xwayland needs to be restarted for this setting to " +"take effect." +msgstr "" +"Asireg n tuqqniwin seg yimsaɣen ideg endianness yemgarad ɣef win n Xwayland. " +"Tangalt n umyibedel n yibiten n uqeddac X d tajumma meqqren n uzḍam, amur " +"ameqqran seg tengalt-a deg Xwayland yezmer ad yesεu uguren n tɣellist. " +"Addaden n useqdec n yimsaɣen yettmyibeddalen ibiten drus maḍi, yettwasens s " +"wudem amezwer deg Xwayland. Armad n textiṛt-a i ussuter deg Xwayland aqbal n " +"tuqqniwin n yimsaɣen X11 s endianness yemgaraden. Taxtiṛt-a ur txeddem " +"acemma ma yella Xwayland ur yessefrak ara taxtiṛt n yizirig n tiludna " +"+byteswappedclients/-byteswappedclients i usenqed n uɣewwar-a. Xwayland " +"yesra ad yales asenker i uɣewwar-a i wakken ad yeṭṭef." + +#: src/backends/meta-monitor.c:251 +msgid "Built-in display" +msgstr "Agdil usliɣ" + +#: src/backends/meta-monitor.c:278 +msgid "Unknown" +msgstr "Arussin" + +#: src/backends/meta-monitor.c:280 +msgid "Unknown Display" +msgstr "Agdil arussin" + +#: src/backends/meta-monitor.c:288 +#, 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:296 +#, c-format +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" + +#: src/core/bell.c:193 +msgid "Bell event" +msgstr "Tadyant n unayna" + +#: src/core/display.c:734 +msgid "Privacy Screen Enabled" +msgstr "Agdil n tbaḍnit yermed" + +#: src/core/display.c:735 +msgid "Privacy Screen Disabled" +msgstr "Agdil n tbaḍnit yensa" + +#: src/core/meta-context-main.c:601 +msgid "Replace the running window manager" +msgstr "Semselsi amsefrak n usfaylu yettwaselkamen" + +#: src/core/meta-context-main.c:607 +msgid "X Display to use" +msgstr "Taskant X ara yettusqedcen" + +#: src/core/meta-context-main.c:613 +msgid "Disable connection to session manager" +msgstr "Sens tuqqna i umsefrak n tɣimit" + +#: src/core/meta-context-main.c:619 +msgid "Specify session management ID" +msgstr "Asulay n usefrek n tɣimit tuzzigt" + +#: src/core/meta-context-main.c:625 +msgid "Initialize session from savefile" +msgstr "Wennez tiɣimit seg ufaylu i yettwaskelsen" + +#: src/core/meta-context-main.c:631 +msgid "Make X calls synchronous" +msgstr "Err isawalen X mtawan" + +#: src/core/meta-context-main.c:639 +msgid "Run as a wayland compositor" +msgstr "Selkem am umsuddas Wayland" + +#: src/core/meta-context-main.c:645 +msgid "Run as a nested compositor" +msgstr "Selkem am umsuddas yemyekcamen" + +#: src/core/meta-context-main.c:651 +msgid "Run wayland compositor without starting Xwayland" +msgstr "Selkem amsuddas wayland war asenker n Xwayland" + +#: src/core/meta-context-main.c:657 +msgid "Specify Wayland display name to use" +msgstr "Sded agdil Wayland i useqdec" + +#: src/core/meta-context-main.c:665 +msgid "Run as a full display server, rather than nested" +msgstr "Selkem am uqeddac n uskan aččuran, deg wadeg n umyikcam" + +#: src/core/meta-context-main.c:670 +msgid "Run as a headless display server" +msgstr "Selkem am uqeddac n uskan war aqerru" + +#: src/core/meta-context-main.c:675 +msgid "Add persistent virtual monitor (WxH or WxH@R)" +msgstr "Rnu asefrak uhlis amaɣlal (WxH neɣ WxH@R)" + +#: src/core/meta-context-main.c:687 +msgid "Run with X11 backend" +msgstr "Selkem s ugdil n deffir X11" + +#: src/core/meta-context-main.c:693 +msgid "Profile performance using trace instrumentation" +msgstr "Timellit n umaɣnu s useqdec n ifecka n uḍfar" + +#: src/core/meta-context-main.c:699 +msgid "Enable debug control D-Bus interface" +msgstr "Rmed agrudem D-Bus n usenqed n tseɣtayt" + +#. TRANSLATORS: This string refers to a button that switches between +#. * different modes. +#. +#: src/core/meta-pad-action-mapper.c:826 +#, c-format +msgid "Mode Switch (Group %d)" +msgstr "Asenfel n uskar (Agraw %d)" + +#. TRANSLATORS: This string refers to an action, cycles drawing tablets' +#. * mapping through the available outputs. +#. +#: src/core/meta-pad-action-mapper.c:848 +msgid "Switch monitor" +msgstr "Senfel asefrak" + +#: src/core/meta-pad-action-mapper.c:850 +msgid "Show on-screen help" +msgstr "Sken tallalt ɣef ugdil" + +#. Translators: this string will appear in Sysprof +#: src/core/meta-profiler.c:109 src/core/meta-profiler.c:299 +msgid "Compositor" +msgstr "Amsuddas" + +#: src/core/mutter.c:74 +msgid "Print version" +msgstr "Sken lqem" + +#: src/core/mutter.c:80 +msgid "Mutter plugin to use" +msgstr "Azegrir Mutter ara yettwasqedcen" + +#: src/core/prefs.c:1842 +#, c-format +msgid "Workspace %d" +msgstr "Tallunt n umahil %d" + +#: src/core/util.c:139 +msgid "Mutter was compiled without support for verbose mode" +msgstr "Mutter yettwasefsu war asefrek n uskar ɣezzifen" + +#: src/core/workspace.c:510 +msgid "Workspace switched" +msgstr "Tallunt n umahil tettwasenfel" + +#: src/wayland/meta-wayland-tablet-pad.c:532 +#, c-format +msgid "Mode Switch: Mode %d" +msgstr "Asenfel n uskar: Askar %d" + +#: src/x11/meta-x11-display.c:723 +#, c-format +msgid "" +"Display “%s” already has a window manager; try using the --replace option to " +"replace the current window manager." +msgstr "" +"Sken \"%s\" yesεa yakan asefrak n usfaylu; εreḍ seqdec taxtiṛt --replace i " +"usemselsi n usefrak n yisfuyla amiran." + +#: src/x11/meta-x11-display.c:1088 +#, c-format +msgid "Failed to open X Window System display “%s”" +msgstr "Yecceḍ ulday n uskan n n yifuyla X Window \"%s\"" + +#: src/x11/meta-x11-display.c:1268 +#, c-format +msgid "Screen %d on display “%s” is invalid" +msgstr "Agdil %d ɣef uskan \"%s\" d arameɣtu" + +#. This probably means that a non-WM compositor like xcompmgr is running; +#. * we have no way to get it to exit +#: src/x11/meta-x11-display.c:2547 +#, c-format +msgid "" +"Another compositing manager is already running on screen %i on display “%s”." +msgstr "" +"Asefrak niḍen n usuddes yella yakan yettwaselkam ɣef ugdil %i ɣef uskan " +"\"%s\"." + +#: src/x11/meta-x11-selection-input-stream.c:475 +#, c-format +msgid "Format %s not supported" +msgstr "Amasal %s ur yettwasefrak ara" + +#: src/x11/window-props.c:528 +#, c-format +msgid "%s (on %s)" +msgstr "%s (ɣef %s)" diff -Nru mutter-46.0/po/ko.po mutter-46.1/po/ko.po --- mutter-46.0/po/ko.po 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/po/ko.po 2024-04-19 17:48:34.000000000 +0000 @@ -7,7 +7,7 @@ # # Updated in mutter: # Changwoo Ryu , 2011-2017. -# Gwan-gyeong Mun , 2018-2023. +# Gwan-gyeong Mun , 2018-2024. # # # 주의: @@ -17,8 +17,8 @@ msgid "" msgstr "" "Project-Id-Version: mutter\n" -"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" -"POT-Creation-Date: 2023-08-23 16:49+0000\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues/\n" +"POT-Creation-Date: 2024-03-11 11:31+0000\n" "PO-Revision-Date: 2023-03-15 18:43+0200\n" "Last-Translator: Gwan-gyeong Mun \n" "Language-Team: GNOME Korea \n" @@ -257,11 +257,11 @@ msgid "Maximize window horizontally" msgstr "창을 가로 방향으로 최대화" -#: data/50-mutter-windows.xml:41 data/org.gnome.mutter.gschema.xml.in:164 +#: data/50-mutter-windows.xml:41 data/org.gnome.mutter.gschema.xml.in:167 msgid "View split on left" msgstr "왼쪽 나눔창 보기" -#: data/50-mutter-windows.xml:45 data/org.gnome.mutter.gschema.xml.in:169 +#: data/50-mutter-windows.xml:45 data/org.gnome.mutter.gschema.xml.in:172 msgid "View split on right" msgstr "오른쪽 나눔창 보기" @@ -394,10 +394,11 @@ "space, while scaling monitor framebuffers instead of window content, to " "manage HiDPI monitors. Does not require a restart. • “kms-modifiers” — makes " "mutter always allocate scanout buffers with explicit modifiers, if supported " -"by the driver. Requires a restart. • “rt-scheduler” — makes mutter request a " -"low priority real-time scheduling. Requires a restart. • “autoclose-" -"xwayland” — automatically terminates Xwayland if all relevant X11 clients " -"are gone. Requires a restart." +"by the driver. Requires a restart. • “autoclose-xwayland” — automatically " +"terminates Xwayland if all relevant X11 clients are gone. Requires a " +"restart. • “variable-refresh-rate” — makes mutter dynamically adjust the " +"refresh rate of the monitor when applicable if supported by the monitor, GPU " +"and DRM driver. Configurable in Settings. Requires a restart." msgstr "" "실험적인 기능을 사용하려면, 해당 기능 키워드를 목록에 추가하십시오. 기능에 따" "라 컴포지터를 다시 시작해야 할 수도 있습니다. 실험적인 기능은 사용할 수 없을 " @@ -407,24 +408,25 @@ "를 배치하고, HiDPI 모니터를 관리하기 위해 창 내용 대신 모니터 프레임 버퍼를 " "스케일링합니다. 재시작은 필요하지 않습니다. • “kms-modifiers” — 드라이버에서 " "지원하는 경우 머터가 항상 명시적 한정자를 사용하여 스캔아웃 버퍼를 할당 합니" -"다. 재시작이 필요합니다. • “rt-scheduler” — 머터 요청을 우선순위가 낮은 실시" -"간 스케줄링으로 만듭니다. 재시작이 필요합니다. • “autoclose-xwayland” — 모든 " -"X11 관련 클라이언트가 종료되면 X웨일랜드를 자동으로 종료합니다. 재시작이 필요" -"하지 않습니다." +"다. 재시작이 필요합니다. • “autoclose-xwayland” — 모든 X11 관련 클라이언트가 " +"종료되면 X웨일랜드를 자동으로 종료합니다. 재시작이 필요하지 않습니다. • " +"“variable-refresh-rate” — 모니터, GPU 및 DRM 드라이버에서 지원하는 경우 모니" +"터의 새로 고침 빈도를 동적으로 조정합니다. 설정에서 구성 가능하며, 재시작이 " +"필요합니다." -#: data/org.gnome.mutter.gschema.xml.in:141 +#: data/org.gnome.mutter.gschema.xml.in:144 msgid "Modifier to use to locate the pointer" msgstr "포인터 위치 찾기에 사용할 키" -#: data/org.gnome.mutter.gschema.xml.in:142 +#: data/org.gnome.mutter.gschema.xml.in:145 msgid "This key will initiate the “locate pointer” action." msgstr "이 키는 “포인터 위치 찾기” 동작을 합니다." -#: data/org.gnome.mutter.gschema.xml.in:149 +#: data/org.gnome.mutter.gschema.xml.in:152 msgid "Timeout for check-alive ping" msgstr "활성 확인 핑 시간 초과" -#: data/org.gnome.mutter.gschema.xml.in:150 +#: data/org.gnome.mutter.gschema.xml.in:153 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." @@ -432,15 +434,15 @@ "중지된 것으로 감지되지 않도록 클라이언트가 핑 요청에 응답해야 하는 시간 (밀리" "초). 0을 사용하면 활성 확인이 완전히 비활성화됩니다." -#: data/org.gnome.mutter.gschema.xml.in:174 +#: data/org.gnome.mutter.gschema.xml.in:177 msgid "Switch monitor configurations" msgstr "모니터 설정 전환" -#: data/org.gnome.mutter.gschema.xml.in:179 +#: data/org.gnome.mutter.gschema.xml.in:182 msgid "Rotates the built-in monitor configuration" msgstr "내장된 모니터 설정을 돌아가면서 전환합니다" -#: data/org.gnome.mutter.gschema.xml.in:184 +#: data/org.gnome.mutter.gschema.xml.in:187 msgid "Cancel any active input capture session" msgstr "활성화된 입력 캡처 세션 취소" @@ -587,26 +589,26 @@ "byteswappedclients을 지원하지 않는 경우 효과가 없습니다. 이 설정을 적용하려" "면 X웨일랜드를 다시 시작해야 합니다." -#: src/backends/meta-monitor.c:253 +#: src/backends/meta-monitor.c:251 msgid "Built-in display" msgstr "내장 디스플레이" -#: src/backends/meta-monitor.c:280 +#: src/backends/meta-monitor.c:278 msgid "Unknown" msgstr "알 수 없음" -#: src/backends/meta-monitor.c:282 +#: src/backends/meta-monitor.c:280 msgid "Unknown Display" msgstr "알 수 없는 디스플레이" -#: src/backends/meta-monitor.c:290 +#: src/backends/meta-monitor.c:288 #, 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:298 +#: src/backends/meta-monitor.c:296 #, c-format msgctxt "" "This is a monitor vendor name followed by product/model name where size in " @@ -618,78 +620,82 @@ msgid "Bell event" msgstr "삑소리 이벤트" -#: src/core/display.c:723 +#: src/core/display.c:734 msgid "Privacy Screen Enabled" msgstr "사생활 보호 화면 사용" -#: src/core/display.c:724 +#: src/core/display.c:735 msgid "Privacy Screen Disabled" msgstr "사생활 보호 화면 해제" -#: src/core/meta-context-main.c:581 +#: src/core/meta-context-main.c:601 msgid "Replace the running window manager" msgstr "실행 중인 창 관리자를 바꿉니다" -#: src/core/meta-context-main.c:587 +#: src/core/meta-context-main.c:607 msgid "X Display to use" msgstr "사용할 X 디스플레이" -#: src/core/meta-context-main.c:593 +#: src/core/meta-context-main.c:613 msgid "Disable connection to session manager" msgstr "세션 관리자와 연결 하지 않습니다" -#: src/core/meta-context-main.c:599 +#: src/core/meta-context-main.c:619 msgid "Specify session management ID" msgstr "세션 관리 ID를 지정합니다" -#: src/core/meta-context-main.c:605 +#: src/core/meta-context-main.c:625 msgid "Initialize session from savefile" msgstr "저장 파일에서 세션을 초기화 합니다" -#: src/core/meta-context-main.c:611 +#: src/core/meta-context-main.c:631 msgid "Make X calls synchronous" msgstr "동기 X 호출을 합니다" -#: src/core/meta-context-main.c:619 +#: src/core/meta-context-main.c:639 msgid "Run as a wayland compositor" msgstr "웨일랜드 컴포지터로 실행합니다" -#: src/core/meta-context-main.c:625 +#: src/core/meta-context-main.c:645 msgid "Run as a nested compositor" msgstr "중첩 컴포지터로 실행합니다" -#: src/core/meta-context-main.c:631 +#: src/core/meta-context-main.c:651 msgid "Run wayland compositor without starting Xwayland" msgstr "웨일랜드 컴포지터를 X웨일랜드 시작없이 실행합니다" -#: src/core/meta-context-main.c:637 +#: src/core/meta-context-main.c:657 msgid "Specify Wayland display name to use" msgstr "사용할 웨일랜드 디스플레이 이름 지정" -#: src/core/meta-context-main.c:645 +#: src/core/meta-context-main.c:665 msgid "Run as a full display server, rather than nested" msgstr "전체 디스플레이 서버로 실행, 중첩 컴포지터가 아님" -#: src/core/meta-context-main.c:650 +#: src/core/meta-context-main.c:670 msgid "Run as a headless display server" msgstr "헤드리스 디스플레이 서버로 실행" -#: src/core/meta-context-main.c:655 +#: src/core/meta-context-main.c:675 msgid "Add persistent virtual monitor (WxH or WxH@R)" msgstr "영구적인 가상 모니터 추가 (WxH or WxH@R)" -#: src/core/meta-context-main.c:667 +#: src/core/meta-context-main.c:687 msgid "Run with X11 backend" msgstr "X11 백 엔드로 실행 합니다" -#: src/core/meta-context-main.c:673 +#: src/core/meta-context-main.c:693 msgid "Profile performance using trace instrumentation" msgstr "추적 계측을 사용한 성능 프로파일" +#: src/core/meta-context-main.c:699 +msgid "Enable debug control D-Bus interface" +msgstr "디버깅 제어 D-Bus 인터페이스 사용" + #. TRANSLATORS: This string refers to a button that switches between #. * different modes. #. -#: src/core/meta-pad-action-mapper.c:807 +#: src/core/meta-pad-action-mapper.c:826 #, c-format msgid "Mode Switch (Group %d)" msgstr "모드 전환 (그룹 %d)" @@ -697,16 +703,16 @@ #. TRANSLATORS: This string refers to an action, cycles drawing tablets' #. * mapping through the available outputs. #. -#: src/core/meta-pad-action-mapper.c:829 +#: src/core/meta-pad-action-mapper.c:848 msgid "Switch monitor" msgstr "모니터 전환" -#: src/core/meta-pad-action-mapper.c:831 +#: src/core/meta-pad-action-mapper.c:850 msgid "Show on-screen help" msgstr "화면 도움말 표시" #. Translators: this string will appear in Sysprof -#: src/core/meta-profiler.c:111 src/core/meta-profiler.c:301 +#: src/core/meta-profiler.c:109 src/core/meta-profiler.c:299 msgid "Compositor" msgstr "컴포지터" @@ -718,7 +724,7 @@ msgid "Mutter plugin to use" msgstr "사용할 머터 플러그인" -#: src/core/prefs.c:1843 +#: src/core/prefs.c:1842 #, c-format msgid "Workspace %d" msgstr "작업 공간 %d" @@ -727,16 +733,16 @@ msgid "Mutter was compiled without support for verbose mode" msgstr "머터가 자세한 정보 표시 모드를 지원하지 않게 컴파일되었습니다" -#: src/core/workspace.c:535 +#: src/core/workspace.c:510 msgid "Workspace switched" msgstr "작업 공간 전환" -#: src/wayland/meta-wayland-tablet-pad.c:534 +#: src/wayland/meta-wayland-tablet-pad.c:532 #, c-format msgid "Mode Switch: Mode %d" msgstr "모드 전환: 모드 %d" -#: src/x11/meta-x11-display.c:708 +#: src/x11/meta-x11-display.c:723 #, c-format msgid "" "Display “%s” already has a window manager; try using the --replace option to " @@ -745,19 +751,19 @@ "디스플레이 “%s”에 이미 창 관리자가 있습니다. 현재 창 관리자를 바꾸려면 --" "replace 옵션을 써보십시오." -#: src/x11/meta-x11-display.c:1073 +#: src/x11/meta-x11-display.c:1088 #, c-format msgid "Failed to open X Window System display “%s”" msgstr "X 윈도 시스템 디스플레이 “%s”을(를) 여는데 실패하였습니다" -#: src/x11/meta-x11-display.c:1219 +#: src/x11/meta-x11-display.c:1268 #, c-format msgid "Screen %d on display “%s” is invalid" msgstr "디스플레이 “%2$s”의 화면 %1$d은(는) 잘못되었습니다" #. This probably means that a non-WM compositor like xcompmgr is running; #. * we have no way to get it to exit -#: src/x11/meta-x11-display.c:2540 +#: src/x11/meta-x11-display.c:2547 #, c-format msgid "" "Another compositing manager is already running on screen %i on display “%s”." @@ -771,7 +777,7 @@ msgstr "%s 형식은 지원하지 않습니다" # <창제목> (on <기계>) -#: src/x11/window-props.c:548 +#: src/x11/window-props.c:528 #, c-format msgid "%s (on %s)" msgstr "%s (%s에서)" diff -Nru mutter-46.0/po/nl.po mutter-46.1/po/nl.po --- mutter-46.0/po/nl.po 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/po/nl.po 2024-04-19 17:48:34.000000000 +0000 @@ -10,8 +10,8 @@ msgstr "" "Project-Id-Version: mutter\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues/\n" -"POT-Creation-Date: 2024-02-12 13:12+0000\n" -"PO-Revision-Date: 2024-02-18 17:09+0100\n" +"POT-Creation-Date: 2024-03-16 16:36+0000\n" +"PO-Revision-Date: 2024-03-31 12:12+0200\n" "Last-Translator: Nathan Follens \n" "Language-Team: GNOME-NL https://matrix.to/#/#nl:gnome.org\n" "Language: nl\n" @@ -250,19 +250,19 @@ msgid "Maximize window horizontally" msgstr "Venster horizontaal maximaliseren" -#: data/50-mutter-windows.xml:41 data/org.gnome.mutter.gschema.xml.in:160 +#: data/50-mutter-windows.xml:41 data/org.gnome.mutter.gschema.xml.in:167 msgid "View split on left" msgstr "Weergave gesplitst op links" -#: data/50-mutter-windows.xml:45 data/org.gnome.mutter.gschema.xml.in:165 +#: data/50-mutter-windows.xml:45 data/org.gnome.mutter.gschema.xml.in:172 msgid "View split on right" msgstr "Weergave gesplitst op rechts" -#: data/org.gnome.mutter.gschema.xml.in:14 +#: data/org.gnome.mutter.gschema.xml.in:15 msgid "Modifier to use for extended window management operations" msgstr "Controletoets voor uitgebreide vensterbeheerfunctionaliteit" -#: data/org.gnome.mutter.gschema.xml.in:15 +#: data/org.gnome.mutter.gschema.xml.in:16 msgid "" "This key will initiate the “overlay”, which is a combination window overview " "and application launching system. The default is intended to be the “Windows " @@ -274,11 +274,11 @@ "toets’ en de bedoeling is dat deze sneltoets ofwel de standaardwaarde bevat " "ofwel leeggemaakt is." -#: data/org.gnome.mutter.gschema.xml.in:27 +#: data/org.gnome.mutter.gschema.xml.in:28 msgid "Attach modal dialogs" msgstr "Blokkerende dialoogvensters vastmaken" -#: data/org.gnome.mutter.gschema.xml.in:28 +#: data/org.gnome.mutter.gschema.xml.in:29 msgid "" "When true, instead of having independent titlebars, modal dialogs appear " "attached to the titlebar of the parent window and are moved together with " @@ -288,11 +288,11 @@ "maar vastgekoppeld aan het achterliggende venster en bewegen daardoor ook " "mee met het achterliggende venster." -#: data/org.gnome.mutter.gschema.xml.in:37 +#: data/org.gnome.mutter.gschema.xml.in:38 msgid "Enable edge tiling when dropping windows on screen edges" msgstr "Randtegels inschakelen bij het slepen van vensters naar schermranden" -#: data/org.gnome.mutter.gschema.xml.in:38 +#: data/org.gnome.mutter.gschema.xml.in:39 msgid "" "If enabled, dropping windows on vertical screen edges maximizes them " "vertically and resizes them horizontally to cover half of the available " @@ -303,11 +303,11 @@ "schermgrootte brengen. Het laten vallen van vensters op de bovenrand van het " "scherm maximaliseert ze helemaal." -#: data/org.gnome.mutter.gschema.xml.in:47 +#: data/org.gnome.mutter.gschema.xml.in:48 msgid "Workspaces are managed dynamically" msgstr "Werkbladen worden dynamisch beheerd" -#: data/org.gnome.mutter.gschema.xml.in:48 +#: data/org.gnome.mutter.gschema.xml.in:49 msgid "" "Determines whether workspaces are managed dynamically or whether there’s a " "static number of workspaces (determined by the num-workspaces key in org." @@ -317,11 +317,11 @@ "werkbladen is (gegeven door de sleutel num-workspaces in org.gnome.desktop." "wm.preferences)." -#: data/org.gnome.mutter.gschema.xml.in:57 +#: data/org.gnome.mutter.gschema.xml.in:58 msgid "Workspaces only on primary" msgstr "Werkbladen alleen voor primaire venster" -#: data/org.gnome.mutter.gschema.xml.in:58 +#: data/org.gnome.mutter.gschema.xml.in:59 msgid "" "Determines whether workspace switching should happen for windows on all " "monitors or only for windows on the primary monitor." @@ -329,11 +329,11 @@ "Geeft aan of wisselen van werkblad voor vensters op alle schermen of alleen " "voor vensters op het hoofdscherm moet gebeuren." -#: data/org.gnome.mutter.gschema.xml.in:66 +#: data/org.gnome.mutter.gschema.xml.in:67 msgid "Delay focus changes until the pointer stops moving" msgstr "Aandacht vertragen totdat de muispijl stopt met bewegen" -#: data/org.gnome.mutter.gschema.xml.in:67 +#: data/org.gnome.mutter.gschema.xml.in:68 msgid "" "If set to true, and the focus mode is either “sloppy” or “mouse” then the " "focus will not be changed immediately when entering a window, but only after " @@ -343,11 +343,11 @@ "‘mouse’, dan zal de aandacht niet direct veranderd worden bij het binnengaan " "van een venster, maar slechts wanneer de muispijl stopt met bewegen." -#: data/org.gnome.mutter.gschema.xml.in:77 +#: data/org.gnome.mutter.gschema.xml.in:78 msgid "Draggable border width" msgstr "Sleepbare randbreedte" -#: data/org.gnome.mutter.gschema.xml.in:78 +#: data/org.gnome.mutter.gschema.xml.in:79 msgid "" "The amount of total draggable borders. If the theme’s visible borders are " "not enough, invisible borders will be added to meet this value." @@ -356,11 +356,11 @@ "onvoldoende zijn, worden onzichtbare randen toegevoegd om deze waarde te " "bereiken." -#: data/org.gnome.mutter.gschema.xml.in:87 +#: data/org.gnome.mutter.gschema.xml.in:88 msgid "Auto maximize nearly monitor sized windows" msgstr "Vensters van bijna-monitorformaat auto-maximaliseren" -#: data/org.gnome.mutter.gschema.xml.in:88 +#: data/org.gnome.mutter.gschema.xml.in:89 msgid "" "If enabled, new windows that are initially the size of the monitor " "automatically get maximized." @@ -368,11 +368,11 @@ "Indien ingeschakeld, worden vensters die initieel ongeveer even groot zijn " "als de monitor automatisch gemaximaliseerd." -#: data/org.gnome.mutter.gschema.xml.in:96 +#: data/org.gnome.mutter.gschema.xml.in:97 msgid "Place new windows in the center" msgstr "Plaats nieuwe vensters in het midden" -#: data/org.gnome.mutter.gschema.xml.in:97 +#: data/org.gnome.mutter.gschema.xml.in:98 msgid "" "When true, the new windows will always be put in the center of the active " "screen of the monitor." @@ -380,11 +380,11 @@ "Indien waar zullen nieuwe vensters steeds in het midden van het actieve " "scherm van de monitor geplaatst worden." -#: data/org.gnome.mutter.gschema.xml.in:106 +#: data/org.gnome.mutter.gschema.xml.in:107 msgid "Enable experimental features" msgstr "Experimentele functies inschakelen" -#: data/org.gnome.mutter.gschema.xml.in:107 +#: data/org.gnome.mutter.gschema.xml.in:108 msgid "" "To enable experimental features, add the feature keyword to the list. " "Whether the feature requires restarting the compositor depends on the given " @@ -396,7 +396,10 @@ "manage HiDPI monitors. Does not require a restart. • “kms-modifiers” — makes " "mutter always allocate scanout buffers with explicit modifiers, if supported " "by the driver. Requires a restart. • “autoclose-xwayland” — automatically " -"terminates Xwayland if all relevant X11 clients are gone. Requires a restart." +"terminates Xwayland if all relevant X11 clients are gone. Requires a " +"restart. • “variable-refresh-rate” — makes mutter dynamically adjust the " +"refresh rate of the monitor when applicable if supported by the monitor, GPU " +"and DRM driver. Configurable in Settings. Requires a restart." msgstr "" "Voeg het sleutelwoord van een experimentele functie toe aan de lijst om deze " "in te schakelen. Of de compositor herstart moet worden vooraleer de functie " @@ -411,21 +414,25 @@ "scanoutbuffers steeds toewijst met uitdrukkelijke modifiers, indien dit " "ondersteund wordt door het stuurprogramma. Hiervoor is opnieuw opstarten " "vereist. • “autoclose-xwayland” — beëindigt Xwayland automatisch wanneer er " -"geen relevante X11-cliënten meer zijn. Hiervoor is opnieuw opstarten vereist." +"geen relevante X11-cliënten meer zijn. Hiervoor is opnieuw opstarten " +"vereist. • “variable-refresh-rate” — laat mutter de verversingsfrequentie " +"van het beeldscherm dynamisch aanpassen wanneer van toepassing en wanneer " +"het beeldscherm, de GPU en het DRM-stuurprogramma dit ondersteunt. " +"Instelbaar via Instellingen. Hiervoor is opnieuw opstarten vereist." -#: data/org.gnome.mutter.gschema.xml.in:137 +#: data/org.gnome.mutter.gschema.xml.in:144 msgid "Modifier to use to locate the pointer" msgstr "Controletoets om de muispijl te lokaliseren" -#: data/org.gnome.mutter.gschema.xml.in:138 +#: data/org.gnome.mutter.gschema.xml.in:145 msgid "This key will initiate the “locate pointer” action." msgstr "Deze sleutel activeert de actie ‘muispijl lokaliseren’." -#: data/org.gnome.mutter.gschema.xml.in:145 +#: data/org.gnome.mutter.gschema.xml.in:152 msgid "Timeout for check-alive ping" msgstr "Time-out voor levenscontroleping" -#: data/org.gnome.mutter.gschema.xml.in:146 +#: data/org.gnome.mutter.gschema.xml.in:153 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." @@ -434,15 +441,15 @@ "verzoek om niet als bevroren beschouwd te worden. Stel dit in op 0 om de " "levenscontrole volledig uit te schakelen." -#: data/org.gnome.mutter.gschema.xml.in:170 +#: data/org.gnome.mutter.gschema.xml.in:177 msgid "Switch monitor configurations" msgstr "Tussen beeldschermconfiguraties schakelen" -#: data/org.gnome.mutter.gschema.xml.in:175 +#: data/org.gnome.mutter.gschema.xml.in:182 msgid "Rotates the built-in monitor configuration" msgstr "Roteert de ingebouwde beeldschermconfiguratie" -#: data/org.gnome.mutter.gschema.xml.in:180 +#: data/org.gnome.mutter.gschema.xml.in:187 msgid "Cancel any active input capture session" msgstr "Alle actieve sessies voor opvang van invoer annuleren" @@ -632,76 +639,76 @@ msgid "Bell event" msgstr "Bel-gebeurtenis" -#: src/core/display.c:733 +#: src/core/display.c:734 msgid "Privacy Screen Enabled" msgstr "Privacyscherm ingeschakeld" -#: src/core/display.c:734 +#: src/core/display.c:735 msgid "Privacy Screen Disabled" msgstr "Privacyscherm uitgeschakeld" -#: src/core/meta-context-main.c:594 +#: src/core/meta-context-main.c:601 msgid "Replace the running window manager" msgstr "De huidige toepassing voor vensterbeheer vervangen" -#: src/core/meta-context-main.c:600 +#: src/core/meta-context-main.c:607 msgid "X Display to use" msgstr "De te gebruiken X-weergave" -#: src/core/meta-context-main.c:606 +#: src/core/meta-context-main.c:613 msgid "Disable connection to session manager" msgstr "Schakel de verbinding met het sessiebeheer uit" -#: src/core/meta-context-main.c:612 +#: src/core/meta-context-main.c:619 msgid "Specify session management ID" msgstr "Bepaal de ID van het sessiebeheer" -#: src/core/meta-context-main.c:618 +#: src/core/meta-context-main.c:625 msgid "Initialize session from savefile" msgstr "Initialiseer de sessie middels een opslagbestand" -#: src/core/meta-context-main.c:624 +#: src/core/meta-context-main.c:631 msgid "Make X calls synchronous" msgstr "X-aanroepen synchroon maken" -#: src/core/meta-context-main.c:632 +#: src/core/meta-context-main.c:639 msgid "Run as a wayland compositor" msgstr "Uitvoeren als een wayland compositor" -#: src/core/meta-context-main.c:638 +#: src/core/meta-context-main.c:645 msgid "Run as a nested compositor" msgstr "Uitvoeren als een geneste compositor" -#: src/core/meta-context-main.c:644 +#: src/core/meta-context-main.c:651 msgid "Run wayland compositor without starting Xwayland" msgstr "Wayland-compositor uitvoeren zonder Xwayland te starten" -#: src/core/meta-context-main.c:650 +#: src/core/meta-context-main.c:657 msgid "Specify Wayland display name to use" msgstr "Bepaal de te gebruiken Wayland-weergavenaam" -#: src/core/meta-context-main.c:658 +#: src/core/meta-context-main.c:665 msgid "Run as a full display server, rather than nested" msgstr "Uitvoeren als een volledige displayserver, in plaats van genest" -#: src/core/meta-context-main.c:663 +#: src/core/meta-context-main.c:670 msgid "Run as a headless display server" msgstr "Uitvoeren als een ‘headless’ displayserver" -#: src/core/meta-context-main.c:668 +#: src/core/meta-context-main.c:675 msgid "Add persistent virtual monitor (WxH or WxH@R)" msgstr "Blijvend virtueel beeldscherm toevoegen (BxH of BxH@V)" -#: src/core/meta-context-main.c:680 +#: src/core/meta-context-main.c:687 msgid "Run with X11 backend" msgstr "Uitvoeren met X11-backend" # Onduidelijk of 'profile' hier een naamwoord of werkwoord is - Nathan -#: src/core/meta-context-main.c:686 +#: src/core/meta-context-main.c:693 msgid "Profile performance using trace instrumentation" msgstr "Prestaties profileren met trace-hulpmiddelen" -#: src/core/meta-context-main.c:692 +#: src/core/meta-context-main.c:699 msgid "Enable debug control D-Bus interface" msgstr "Debugbesturing van D-Bus-interface inschakelen" @@ -737,7 +744,7 @@ msgid "Mutter plugin to use" msgstr "Te gebruiken Mutter-plug-in" -#: src/core/prefs.c:1843 +#: src/core/prefs.c:1842 #, c-format msgid "Workspace %d" msgstr "Werkblad %d" @@ -746,7 +753,7 @@ msgid "Mutter was compiled without support for verbose mode" msgstr "Mutter is gecompileerd zonder ondersteuning voor verbose-mode" -#: src/core/workspace.c:511 +#: src/core/workspace.c:510 msgid "Workspace switched" msgstr "Werkblad gewisseld" @@ -776,7 +783,7 @@ #. This probably means that a non-WM compositor like xcompmgr is running; #. * we have no way to get it to exit -#: src/x11/meta-x11-display.c:2539 +#: src/x11/meta-x11-display.c:2547 #, c-format msgid "" "Another compositing manager is already running on screen %i on display “%s”." @@ -789,7 +796,7 @@ msgid "Format %s not supported" msgstr "Formaat %s wordt niet ondersteund" -#: src/x11/window-props.c:524 +#: src/x11/window-props.c:528 #, c-format msgid "%s (on %s)" msgstr "%s (op %s)" diff -Nru mutter-46.0/po/pa.po mutter-46.1/po/pa.po --- mutter-46.0/po/pa.po 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/po/pa.po 2024-04-19 17:48:34.000000000 +0000 @@ -5,23 +5,23 @@ # # Amanpreet_Singh , 2004. # Amanpreet Singh Alam , 2004. -# A S Alam , 2006. +# SPDX-FileCopyrightText: 2006, 2024 A S Alam # A S Alam , 2007, 2009, 2010, 2011, 2021, 2023. # ASB , 2007. # Amanpreet Singh Alam , 2009, 2012, 2013, 2014, 2015, 2017, 2020. msgid "" msgstr "" "Project-Id-Version: metacity.gnome-2-26\n" -"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n" -"POT-Creation-Date: 2023-07-15 01:02+0000\n" -"PO-Revision-Date: 2023-09-02 08:25-0700\n" -"Last-Translator: A S Alam \n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues/\n" +"POT-Creation-Date: 2024-03-02 12:22+0000\n" +"PO-Revision-Date: 2024-03-18 08:12-0500\n" +"Last-Translator: A S Alam \n" "Language-Team: Punjabi \n" "Language: pa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Lokalize 23.04.3\n" +"X-Generator: Lokalize 23.08.5\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "\n" @@ -162,22 +162,18 @@ msgstr "ਪਿਛਲੇ ਵਰਕਸਪੇਸ ਵਿੱਚ ਜਾਓ" #: data/50-mutter-navigation.xml:131 -#| msgid "Move to workspace on the left" msgid "Switch to workspace on the left" msgstr "ਖੱਬੇ ਪਾਸੇ ਆਲੇ ਵਰਕਸਪੇਸ ਉੱਤੇ ਜਾਓ" #: data/50-mutter-navigation.xml:134 -#| msgid "Move to workspace on the right" msgid "Switch to workspace on the right" msgstr "ਸੱਜੇ ਪਾਸੇ ਆਲੇ ਵਰਕਸਪੇਸ ਉੱਤੇ ਜਾਓ" #: data/50-mutter-navigation.xml:138 -#| msgid "Switch to workspace 1" msgid "Switch to workspace above" msgstr "ਉੱਤਲੇ ਵਰਕਸਪੇਸ ਉੱਤੇ ਜਾਓ" #: data/50-mutter-navigation.xml:142 -#| msgid "Switch to workspace 1" msgid "Switch to workspace below" msgstr "ਹੇਠਲੇ ਵਰਕਸਪੇਸ ਉੱਤੇ ਜਾਓ" @@ -257,11 +253,11 @@ msgid "Maximize window horizontally" msgstr "ਵਿੰਡੋ ਲੇਟਵੇਂ ਰੂਪ ਵਿੱਚ ਵੱਧੋ-ਵੱਧ" -#: data/50-mutter-windows.xml:41 data/org.gnome.mutter.gschema.xml.in:164 +#: data/50-mutter-windows.xml:41 data/org.gnome.mutter.gschema.xml.in:167 msgid "View split on left" msgstr "ਖੱਬੇ ਪਾਸੇ ਵੰਡ ਵੇਖੋ" -#: data/50-mutter-windows.xml:45 data/org.gnome.mutter.gschema.xml.in:169 +#: data/50-mutter-windows.xml:45 data/org.gnome.mutter.gschema.xml.in:172 msgid "View split on right" msgstr "ਸੱਜੇ ਪਾਸੇ ਵੰਡ ਵੇਖੋ" @@ -404,13 +400,12 @@ #| "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. • “rt-scheduler” — makes mutter request a low priority real-time " -#| "scheduling. The executable or user must have CAP_SYS_NICE. Requires a " -#| "restart. • “dma-buf-screen-sharing\" — enables DMA buffered screen " -#| "sharing. This is already enabled by default when using the i915 driver, " -#| "but disabled for everything else. Requires a restart. • “autoclose-" -#| "xwayland” — automatically terminates Xwayland if all relevant X11 clients " -#| "are gone. Does not require a restart." +#| "restart. • “kms-modifiers” — makes mutter always allocate scanout buffers " +#| "with explicit modifiers, if supported by the driver. Requires a restart. " +#| "• “rt-scheduler” — makes mutter request a low priority real-time " +#| "scheduling. Requires a restart. • “autoclose-xwayland” — automatically " +#| "terminates Xwayland if all relevant X11 clients are gone. Requires a " +#| "restart." msgid "" "To enable experimental features, add the feature keyword to the list. " "Whether the feature requires restarting the compositor depends on the given " @@ -421,10 +416,11 @@ "space, while scaling monitor framebuffers instead of window content, to " "manage HiDPI monitors. Does not require a restart. • “kms-modifiers” — makes " "mutter always allocate scanout buffers with explicit modifiers, if supported " -"by the driver. Requires a restart. • “rt-scheduler” — makes mutter request a " -"low priority real-time scheduling. Requires a restart. • “autoclose-" -"xwayland” — automatically terminates Xwayland if all relevant X11 clients " -"are gone. Requires a restart." +"by the driver. Requires a restart. • “autoclose-xwayland” — automatically " +"terminates Xwayland if all relevant X11 clients are gone. Requires a " +"restart. • “variable-refresh-rate” — makes mutter dynamically adjust the " +"refresh rate of the monitor when applicable if supported by the monitor, GPU " +"and DRM driver. Configurable in Settings. Requires a restart." msgstr "" "ਤਜਰਬੇ ਅਧੀਨ ਫ਼ੀਚਰ ਸਮਰੱਥ ਕਰਨ ਲਈ, ਫੀਚਰ ਕੀਵਰਡ ਸੂਚੀ ਵਿੱਚ ਜੋੜੋ। ਕੀ ਫ਼ੀਚਰ ਲਈ" " ਕੰਪੋਜ਼ੀਟਰ ਮੁੜ-ਚਾਲੂ " @@ -437,24 +433,29 @@ "ਲਾਜ਼ੀਕਲ ਮਾਨੀਟਰਾਂ ਦੇ ਖਾਕੇ ਲਈ ਮਟਰ ਨੂੰ ਮੂਲ ਬਣਾਉਣਾ, ਜਦੋਂ ਕਿ HiDPI ਮਾਨੀਟਰਾਂ ਦੇ" " ਇੰਤਜ਼ਾਮ ਲਈ ਵਿੰਡੋ " "ਸਮੱਗਰੀ ਦੀ ਬਜਾਏ ਸਕੇਲਿੰਗ ਮਾਨੀਟਰ ਫਰੇਮਬਰਫ਼ ਹੋਣ। ਮੁੜ-ਚਾਲੂ ਕਰਨ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ। •" -" “kms-modifiers” — ਜੇ ਡਰਾਇਵਰ ਰਾਹੀਂ ਸਹਾਇਕ ਹੋਵੇ ਤਾਂ ਮਟਰ ਖਾਸ ਸੋਧਕਾਂ ਲਈ ਸਕੈਨ-ਆਉਟ" -" ਬਫ਼ਰ ਹਮੇਸ਼ਾਂ ਜਾਰੀ ਕਰਦਾ ਹੈ। ਮੁੜ-ਚਾਲੂ ਕਰਨ ਦੀ ਲੋੜ ਹੈ। • “autoclose-xwayland” — ਜੇ" -" ਸਾਰੇ ਵਾਜਬ X11 ਕਲਾਈਂਟ ਖਤਮ ਹੋ ਜਾਣ ਤਾਂ ਆਪਣੇ-ਆਪ Xwayland ਨੂੰ ਖਤਮ ਕਰਦਾ ਹੈ।" -" ਮੁੜ-ਚਾਲੂ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।" +" “kms-" +"modifiers” — ਜੇ ਡਰਾਇਵਰ ਰਾਹੀਂ ਸਹਾਇਕ ਹੋਵੇ ਤਾਂ ਮਟਰ ਖਾਸ ਸੋਧਕਾਂ ਲਈ ਸਕੈਨ-ਆਉਟ ਬਫ਼ਰ" +" ਹਮੇਸ਼ਾਂ ਜਾਰੀ " +"ਕਰਦਾ ਹੈ। ਮੁੜ-ਚਾਲੂ ਕਰਨ ਦੀ ਲੋੜ ਹੈ। • “autoclose-xwayland” — ਜੇ ਸਾਰੇ ਵਾਜਬ X11" +" ਕਲਾਈਂਟ " +"ਖਤਮ ਹੋ ਜਾਣ ਤਾਂ ਆਪਣੇ-ਆਪ Xwayland ਨੂੰ ਖਤਮ ਕਰਦਾ ਹੈ। ਮੁੜ-ਚਾਲੂ ਕਰਨ ਦੀ ਲੋੜ ਹੈ। •" +" “variable-refresh-rate” — ਜੇ ਮਾਨੀਟਰ, GPU ਅਤੇ DRM ਡਰਾਇਵਰ ਸਹਾਇਕ ਹੋਣ ਤਾਂ ਮਟਰ" +" ਮਾਨੀਟਰ ਦੇ ਡਾਇਨੈਮਿਕ ਰੂਪ ਵਿੱਚ ਰੀ-ਫਰੈਸ਼ ਰੇਟ ਨੂੰ ਅਡਜੱਸਟ ਕਰ ਸਕਦਾ ਹੈ। ਸੈਟਿੰਗਾਂ ਵਿੱਚ" +" ਸੰਰਚਨਾ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ। ਮੁੜ-ਚਾਲੂ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।" -#: data/org.gnome.mutter.gschema.xml.in:141 +#: data/org.gnome.mutter.gschema.xml.in:144 msgid "Modifier to use to locate the pointer" msgstr "ਪੁਆਇੰਟਰ ਲੱਭਣ ਲਈ ਵਰਤਣ ਵਾਸਤੇ ਸੋਧਣ" -#: data/org.gnome.mutter.gschema.xml.in:142 +#: data/org.gnome.mutter.gschema.xml.in:145 msgid "This key will initiate the “locate pointer” action." msgstr "ਇਹ ਕੁੰਜੀ “ਪੁਆਇੰਟਰ ਲੱਭੋ“ ਕਾਰਵਾਈ ਸ਼ੁਰੂ ਕਰਦੀ ਹੈ।" -#: data/org.gnome.mutter.gschema.xml.in:149 +#: data/org.gnome.mutter.gschema.xml.in:152 msgid "Timeout for check-alive ping" msgstr "ਚੈਕ-ਸਰਗਰਮ ਪਿੰਗ ਲਈ ਸਮਾਂ-ਅੰਤਰਾਲ" -#: data/org.gnome.mutter.gschema.xml.in:150 +#: data/org.gnome.mutter.gschema.xml.in:153 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." @@ -464,15 +465,15 @@ "ਜਕੜਿਆ ਨਾ ਖੋਜਿਆ ਜਾਵੇ। 0 ਵਰਤਣ ਨਾਲ ਸਰਗਰਮੀ ਦੀ ਜਾਂਚ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਅਸਮਰੱਥ ਕੀਤਾ" " ਜਾਵੇਗਾ।" -#: data/org.gnome.mutter.gschema.xml.in:174 +#: data/org.gnome.mutter.gschema.xml.in:177 msgid "Switch monitor configurations" msgstr "ਮਾਨੀਟਰ ਸੰਰਚਨਾ ਨੂੰ ਬਦਲੋ" -#: data/org.gnome.mutter.gschema.xml.in:179 +#: data/org.gnome.mutter.gschema.xml.in:182 msgid "Rotates the built-in monitor configuration" msgstr "ਬਿਲਟ-ਇਨ ਮਾਨੀਟਰ ਸੰਰਚਨਾ ਨੂੰ ਘੁੰਮਾਓ" -#: data/org.gnome.mutter.gschema.xml.in:184 +#: data/org.gnome.mutter.gschema.xml.in:187 msgid "Cancel any active input capture session" msgstr "ਕਿਸੇ ਵੀ ਸਰਗਰਮ ਇਨਪੁਟ ਸਕਰੀਨ ਕੈਪਚਰ ਕਰਨ ਵਾਲੇ ਸ਼ੈਸ਼ਨ ਨੂੰ ਰੱਦ ਕਰੋ" @@ -614,7 +615,8 @@ msgid "Allow X11 clients with a different endianness to connect to Xwayland" msgstr "" "ਵੱਖਰੀ ਏਂਡੀਨੈਸਸ (endianess) ਵਾਲੇ X11 ਵਾਲੇ ਕਲਾਈਂਟਾਂ ਨੂੰ Xwayland ਨਾਲ ਕਨੈਕਟ ਹੋਣ" -" ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ" +" ਦੀ ਇਜਾਜ਼ਤ " +"ਦਿਓ" #: data/org.gnome.mutter.wayland.gschema.xml.in:131 msgid "" @@ -629,26 +631,26 @@ "take effect." msgstr "" -#: src/backends/meta-monitor.c:253 +#: src/backends/meta-monitor.c:251 msgid "Built-in display" msgstr "ਬਿਲਟ-ਇਨ ਡਿਸਪਲੇਅ" -#: src/backends/meta-monitor.c:280 +#: src/backends/meta-monitor.c:278 msgid "Unknown" msgstr "ਅਣਜਾਣ" -#: src/backends/meta-monitor.c:282 +#: src/backends/meta-monitor.c:280 msgid "Unknown Display" msgstr "ਅਣਜਾਣ ਡਿਸਪਲੇਅ" -#: src/backends/meta-monitor.c:290 +#: src/backends/meta-monitor.c:288 #, 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:298 +#: src/backends/meta-monitor.c:296 #, c-format msgctxt "" "This is a monitor vendor name followed by product/model name where size in " @@ -660,78 +662,82 @@ msgid "Bell event" msgstr "ਘੰਟੀ ਈਵੈਂਟ" -#: src/core/display.c:718 +#: src/core/display.c:734 msgid "Privacy Screen Enabled" msgstr "ਪਰਦੇਦਾਰੀ ਸਕਰੀਨ ਸਮਰੱਥ ਹੈ" -#: src/core/display.c:719 +#: src/core/display.c:735 msgid "Privacy Screen Disabled" msgstr "ਪਰਦੇਦਾਰੀ ਸਕਰੀਨ ਅਸਮਰੱਥ ਹੈ" -#: src/core/meta-context-main.c:581 +#: src/core/meta-context-main.c:601 msgid "Replace the running window manager" msgstr "ਚੱਲ ਰਹੇ ਵਿੰਡੋ ਮੈਨੇਜਰ ਨੂੰ ਬਦਲੋ" -#: src/core/meta-context-main.c:587 +#: src/core/meta-context-main.c:607 msgid "X Display to use" msgstr "ਵਰਤਣ ਲਈ X ਡਿਸਪਲੇਅ" -#: src/core/meta-context-main.c:593 +#: src/core/meta-context-main.c:613 msgid "Disable connection to session manager" msgstr "ਸ਼ੈਸ਼ਨ ਮੈਨੇਜਰ ਨਾਲ ਕੁਨੈਕਸ਼ਨ ਅਯੋਗ" -#: src/core/meta-context-main.c:599 +#: src/core/meta-context-main.c:619 msgid "Specify session management ID" msgstr "ਸ਼ੈਸ਼ਨ ਪਰਬੰਧਨ ID ਦਿਓ" -#: src/core/meta-context-main.c:605 +#: src/core/meta-context-main.c:625 msgid "Initialize session from savefile" msgstr "ਸੰਭਾਲੀ ਫਾਇਲ ਤੋਂ ਸ਼ੈਸ਼ਨ ਸ਼ੁਰੂ" -#: src/core/meta-context-main.c:611 +#: src/core/meta-context-main.c:631 msgid "Make X calls synchronous" msgstr "X ਕਾਲ ਸੈਕਰੋਨਸ ਬਣਾਓ" -#: src/core/meta-context-main.c:619 +#: src/core/meta-context-main.c:639 msgid "Run as a wayland compositor" msgstr "ਵੇਲੈਂਡ ਕੰਪੋਜ਼ਰ ਵਜੋਂ ਚਲਾਓ" -#: src/core/meta-context-main.c:625 +#: src/core/meta-context-main.c:645 msgid "Run as a nested compositor" msgstr "ਨੈਸਟਡ ਕੰਪੋਜ਼ਰ ਵਜੋਂ ਚਲਾਓ" -#: src/core/meta-context-main.c:631 +#: src/core/meta-context-main.c:651 msgid "Run wayland compositor without starting Xwayland" msgstr "Xwayland ਸ਼ੁਰੂ ਕੀਤੇ ਬਿਨਾਂ ਵੇਲੈਂਡ ਕੰਪੋਜ਼ੀਟਰ ਚਲਾਓ" -#: src/core/meta-context-main.c:637 +#: src/core/meta-context-main.c:657 msgid "Specify Wayland display name to use" msgstr "ਵਰਤਣ ਲਈ ਵੇਅਲੈਂਡ ਡਿਸਪਲੇਅ ਨਾਂ ਦਿਓ" -#: src/core/meta-context-main.c:645 +#: src/core/meta-context-main.c:665 msgid "Run as a full display server, rather than nested" msgstr "ਅੰਦਰੂਨੀ ਰੂਪ ਵਿੱਚ ਚਲਾਉਣ ਦੀ ਬਜਾਏ ਪੂਰੇ ਡਿਸਪਲੇਅ ਸਰਵਰ ਵਜੋਂ ਚਲਾਓ" -#: src/core/meta-context-main.c:650 +#: src/core/meta-context-main.c:670 msgid "Run as a headless display server" msgstr "ਹੈੱਡਲੈੱਸ ਡਿਸਪਲੇਅ ਸਰਵਰ ਵਜੋਂ ਚਲਾਓ" -#: src/core/meta-context-main.c:655 +#: src/core/meta-context-main.c:675 msgid "Add persistent virtual monitor (WxH or WxH@R)" msgstr "ਸਥਿਰ ਵਰਚੁਅਲ ਮਾਨੀਟਰ ਜੋੜੋ (WxH or WxH@R)" -#: src/core/meta-context-main.c:667 +#: src/core/meta-context-main.c:687 msgid "Run with X11 backend" msgstr "X11 ਬੈਕਐਡ ਨਾਲ ਚਲਾਓ" -#: src/core/meta-context-main.c:673 +#: src/core/meta-context-main.c:693 msgid "Profile performance using trace instrumentation" msgstr "ਟਰੇਸ ਸਾਧਨ ਵਰਤ ਕੇ ਕਾਰਗੁਜ਼ਾਰੀ ਦਾ ਪਰੋਫ਼ਾਇਲ ਬਣਾਓ" +#: src/core/meta-context-main.c:699 +msgid "Enable debug control D-Bus interface" +msgstr "ਡੀਬੱਗ ਕੰਟਰੋਲ ਡੀ-ਬੱਸ ਇੰਟਰਫੇਸ ਸਮਰੱਥ ਕਰੋ" + #. TRANSLATORS: This string refers to a button that switches between #. * different modes. #. -#: src/core/meta-pad-action-mapper.c:861 +#: src/core/meta-pad-action-mapper.c:826 #, c-format msgid "Mode Switch (Group %d)" msgstr "ਮੋਡ ਬਦਲੋ (ਗਰੁੱਪ %d)" @@ -739,16 +745,16 @@ #. TRANSLATORS: This string refers to an action, cycles drawing tablets' #. * mapping through the available outputs. #. -#: src/core/meta-pad-action-mapper.c:884 +#: src/core/meta-pad-action-mapper.c:848 msgid "Switch monitor" msgstr "ਮਾਨੀਟਰ ਨੂੰ ਬਦਲੋ" -#: src/core/meta-pad-action-mapper.c:886 +#: src/core/meta-pad-action-mapper.c:850 msgid "Show on-screen help" msgstr "ਆਨ-ਸਕਰੀਨ ਮਦਦ ਵੇਖੋ" #. Translators: this string will appear in Sysprof -#: src/core/meta-profiler.c:111 src/core/meta-profiler.c:301 +#: src/core/meta-profiler.c:109 src/core/meta-profiler.c:299 msgid "Compositor" msgstr "ਕੰਪੋਜੀਟਰ" @@ -760,7 +766,7 @@ msgid "Mutter plugin to use" msgstr "ਵਰਤਣ ਲਈ ਮੁੱਟਰ ਪਲੱਗਇਨ" -#: src/core/prefs.c:1843 +#: src/core/prefs.c:1842 #, c-format msgid "Workspace %d" msgstr "ਵਰਕਸਪੇਸ %d" @@ -769,17 +775,16 @@ msgid "Mutter was compiled without support for verbose mode" msgstr "ਮੱਟਰ, ਵਰਬੋਜ਼ ਮੋਡ ਲਈ ਸਹਾਰੇ ਤੋਂ ਬਿਨਾਂ ਕੰਪਾਇਲ ਹੋਇਆ" -#: src/core/workspace.c:541 -#| msgid "Workspace %s%d" +#: src/core/workspace.c:510 msgid "Workspace switched" msgstr "ਵਰਕਸਪੇਸ ਬਦਲਿਆ" -#: src/wayland/meta-wayland-tablet-pad.c:530 +#: src/wayland/meta-wayland-tablet-pad.c:532 #, c-format msgid "Mode Switch: Mode %d" msgstr "ਮੋਡ ਬਦਲੋ: ਮੋਡ %d" -#: src/x11/meta-x11-display.c:708 +#: src/x11/meta-x11-display.c:723 #, c-format msgid "" "Display “%s” already has a window manager; try using the --replace option to " @@ -789,19 +794,19 @@ " ਬਦਲਣ ਲਈ --replace ਚੋਣ " "ਵਰਤ ਕੇ ਦੇਖੋ।" -#: src/x11/meta-x11-display.c:1073 +#: src/x11/meta-x11-display.c:1088 #, c-format msgid "Failed to open X Window System display “%s”" msgstr "X ਵਿੰਡੋ ਸਿਸਟਮ ਡਿਸਪਲੇਅ ”%s” ਨੂੰ ਖੋਲਣ ਵਿੱਚ ਅਸਮਰਥ" -#: src/x11/meta-x11-display.c:1219 +#: src/x11/meta-x11-display.c:1268 #, c-format msgid "Screen %d on display “%s” is invalid" msgstr "ਡਿਸਪਲੇਅ ”%2$s” ਉੱਤੇ ਸਕਰੀਨ %1$d ਗਲਤ ਹੈ" #. This probably means that a non-WM compositor like xcompmgr is running; #. * we have no way to get it to exit -#: src/x11/meta-x11-display.c:2550 +#: src/x11/meta-x11-display.c:2538 #, c-format msgid "" "Another compositing manager is already running on screen %i on display “%s”." @@ -814,7 +819,7 @@ msgid "Format %s not supported" msgstr "ਫਾਰਮੈਟ %s ਸਹਾਇਕ ਨਹੀਂ ਹੈ" -#: src/x11/window-props.c:548 +#: src/x11/window-props.c:528 #, c-format msgid "%s (on %s)" msgstr "%s (%s ਉੱਤੇ)" @@ -2463,3 +2468,4 @@ #~ msgid "Theme file %s did not contain a root element" #~ msgstr "ਥੀਮ ਫਾਇਲ %s root ਐਲੀਮੈਂਟ ਵਿੱਚ ਸ਼ਾਮਿਲ ਨਹੀਂ ਸੀ" + diff -Nru mutter-46.0/src/backends/meta-color-device.c mutter-46.1/src/backends/meta-color-device.c --- mutter-46.0/src/backends/meta-color-device.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/backends/meta-color-device.c 2024-04-19 17:48:34.000000000 +0000 @@ -963,56 +963,62 @@ create_device_profile_from_edid (MetaColorDevice *color_device, GTask *task) { - const MetaEdidInfo *edid_info; + const MetaEdidInfo *edid_info = + meta_monitor_get_edid_info (color_device->monitor); + GenerateProfileData *data = g_task_get_task_data (task); + g_autoptr (CdIcc) cd_icc = NULL; + g_autoptr (GBytes) bytes = NULL; + g_autofree char *file_md5_checksum = NULL; + g_autoptr (GError) error = NULL; - edid_info = meta_monitor_get_edid_info (color_device->monitor); if (edid_info) { - g_autoptr (CdIcc) cd_icc = NULL; - GBytes *bytes; - g_autoptr (GError) error = NULL; - GenerateProfileData *data = g_task_get_task_data (task); - const char *file_path = data->file_path; - g_autofree char *file_md5_checksum = NULL; - meta_topic (META_DEBUG_COLOR, "Generating ICC profile for '%s' from EDID", meta_color_device_get_id (color_device)); cd_icc = create_icc_profile_from_edid (color_device, - edid_info, file_path, + edid_info, data->file_path, &error); - if (!cd_icc) - { - g_task_return_error (task, g_steal_pointer (&error)); - g_object_unref (task); - return; - } - - bytes = cd_icc_save_data (cd_icc, CD_ICC_SAVE_FLAGS_NONE, &error); - if (!bytes) - { - g_task_return_error (task, g_steal_pointer (&error)); - g_object_unref (task); - return; - } - - file_md5_checksum = g_compute_checksum_for_bytes (G_CHECKSUM_MD5, bytes); - cd_icc_add_metadata (cd_icc, CD_PROFILE_METADATA_FILE_CHECKSUM, - file_md5_checksum); - - data->color_calibration = - meta_color_calibration_new (cd_icc, NULL); - data->cd_icc = g_steal_pointer (&cd_icc); - data->bytes = bytes; - save_icc_profile (file_path, task); } else { - g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, - "No EDID available"); + meta_topic (META_DEBUG_COLOR, + "Generating sRGB ICC profile for '%s' because EDID is missing", + meta_color_device_get_id (color_device)); + + cd_icc = cd_icc_new (); + + if (!cd_icc_create_default_full (cd_icc, + CD_ICC_LOAD_FLAGS_PRIMARIES, + &error)) + g_clear_object (&cd_icc); + } + + if (!cd_icc) + { + g_task_return_error (task, g_steal_pointer (&error)); + g_object_unref (task); + return; + } + + bytes = cd_icc_save_data (cd_icc, CD_ICC_SAVE_FLAGS_NONE, &error); + if (!bytes) + { + g_task_return_error (task, g_steal_pointer (&error)); g_object_unref (task); + return; } + + file_md5_checksum = g_compute_checksum_for_bytes (G_CHECKSUM_MD5, bytes); + cd_icc_add_metadata (cd_icc, CD_PROFILE_METADATA_FILE_CHECKSUM, + file_md5_checksum); + + data->color_calibration = + meta_color_calibration_new (cd_icc, NULL); + data->cd_icc = g_steal_pointer (&cd_icc); + data->bytes = g_steal_pointer (&bytes); + save_icc_profile (data->file_path, task); } static void diff -Nru mutter-46.0/src/backends/meta-egl.c mutter-46.1/src/backends/meta-egl.c --- mutter-46.0/src/backends/meta-egl.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/backends/meta-egl.c 2024-04-19 17:48:34.000000000 +0000 @@ -260,6 +260,14 @@ return has_extensions; } +const char * +meta_egl_query_string (MetaEgl *egl, + EGLDisplay display, + EGLint name) +{ + return eglQueryString (display, name); +} + gboolean meta_egl_initialize (MetaEgl *egl, EGLDisplay display, diff -Nru mutter-46.0/src/backends/meta-egl.h mutter-46.1/src/backends/meta-egl.h --- mutter-46.0/src/backends/meta-egl.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/backends/meta-egl.h 2024-04-19 17:48:34.000000000 +0000 @@ -47,6 +47,10 @@ const char *first_extension, ...); +const char * meta_egl_query_string (MetaEgl *egl, + EGLDisplay display, + EGLint name); + gboolean meta_egl_initialize (MetaEgl *egl, EGLDisplay display, GError **error); diff -Nru mutter-46.0/src/backends/native/meta-cursor-renderer-native.c mutter-46.1/src/backends/native/meta-cursor-renderer-native.c --- mutter-46.0/src/backends/native/meta-cursor-renderer-native.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/backends/native/meta-cursor-renderer-native.c 2024-04-19 17:48:34.000000000 +0000 @@ -454,7 +454,8 @@ GError **error) { struct gbm_bo *bo; - uint8_t buf[4 * cursor_width * cursor_height]; + uint32_t bo_stride; + uint8_t *buf; int i; MetaDrmBufferFlags flags; MetaDrmBufferGbm *buffer_gbm; @@ -476,10 +477,16 @@ return NULL; } - memset (buf, 0, sizeof (buf)); + bo_stride = gbm_bo_get_stride (bo); + buf = g_alloca0 (bo_stride * cursor_height); + for (i = 0; i < height; i++) - memcpy (buf + i * 4 * cursor_width, pixels + i * stride, width * 4); - if (gbm_bo_write (bo, buf, cursor_width * cursor_height * 4) != 0) + { + memcpy (buf + i * bo_stride, + pixels + i * stride, + MIN (bo_stride, stride)); + } + if (gbm_bo_write (bo, buf, bo_stride * cursor_height) != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Failed write to gbm_bo: %s", g_strerror (errno)); diff -Nru mutter-46.0/src/backends/native/meta-drm-buffer-gbm.c mutter-46.1/src/backends/native/meta-drm-buffer-gbm.c --- mutter-46.0/src/backends/native/meta-drm-buffer-gbm.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/backends/native/meta-drm-buffer-gbm.c 2024-04-19 17:48:34.000000000 +0000 @@ -186,7 +186,7 @@ return FALSE; } - return meta_drm_buffer_gbm_ensure_fb_id (META_DRM_BUFFER (buffer_gbm), error); + return TRUE; } MetaDrmBufferGbm * diff -Nru mutter-46.0/src/backends/native/meta-drm-buffer.c mutter-46.1/src/backends/native/meta-drm-buffer.c --- mutter-46.0/src/backends/native/meta-drm-buffer.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/backends/native/meta-drm-buffer.c 2024-04-19 17:48:34.000000000 +0000 @@ -28,7 +28,7 @@ #include "backends/native/meta-device-pool.h" #include "backends/native/meta-kms-utils.h" -#include "common/meta-cogl-drm-formats.h" +#include "common/meta-drm-format-helpers.h" #include "meta-private-enum-types.h" diff -Nru mutter-46.0/src/backends/native/meta-onscreen-native.c mutter-46.1/src/backends/native/meta-onscreen-native.c --- mutter-46.0/src/backends/native/meta-onscreen-native.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/backends/native/meta-onscreen-native.c 2024-04-19 17:48:34.000000000 +0000 @@ -51,6 +51,7 @@ #include "backends/native/meta-renderer-native-private.h" #include "cogl/cogl.h" #include "common/meta-cogl-drm-formats.h" +#include "common/meta-drm-format-helpers.h" typedef enum _MetaSharedFramebufferImportStatus { @@ -505,6 +506,8 @@ MetaGpuKms *gpu_kms; MetaDrmBuffer *buffer; MetaKmsPlaneAssignment *plane_assignment; + graphene_rect_t src_rect; + MtkRectangle dst_rect; COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs, "Meta::OnscreenNative::flip_crtc()"); @@ -518,9 +521,6 @@ switch (renderer_gpu_data->mode) { case META_RENDERER_NATIVE_MODE_GBM: - graphene_rect_t src_rect; - MtkRectangle dst_rect; - buffer = onscreen_native->gbm.next_fb; if (onscreen_native->gbm.next_scanout) @@ -840,6 +840,9 @@ COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferSecondaryGpu, "copy_shared_framebuffer_gpu()"); + if (renderer_gpu_data->secondary.needs_explicit_sync) + cogl_framebuffer_finish (COGL_FRAMEBUFFER (onscreen)); + render_device = renderer_gpu_data->render_device; egl_display = meta_render_device_get_egl_display (render_device); @@ -947,8 +950,7 @@ COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferPrimaryGpu, "copy_shared_framebuffer_primary_gpu()"); - if (!secondary_gpu_state || - secondary_gpu_state->egl_surface == EGL_NO_SURFACE) + if (!secondary_gpu_state) return NULL; primary_gpu = meta_renderer_native_get_primary_gpu (renderer_native); @@ -1282,12 +1284,14 @@ MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; MetaGpuKms *render_gpu = onscreen_native->render_gpu; MetaDeviceFile *render_device_file; ClutterFrame *frame = user_data; MetaFrameNative *frame_native = meta_frame_native_from_frame (frame); MetaKmsUpdate *kms_update; CoglOnscreenClass *parent_class; + gboolean create_timestamp_query = TRUE; gboolean egl_context_changed = FALSE; MetaPowerSave power_save_mode; g_autoptr (GError) error = NULL; @@ -1306,6 +1310,22 @@ rectangles, n_rectangles); + secondary_gpu_state = onscreen_native->secondary_gpu_state; + if (secondary_gpu_state) + { + MetaRendererNativeGpuData *secondary_gpu_data; + + secondary_gpu_data = + meta_renderer_native_get_gpu_data (renderer_native, + secondary_gpu_state->gpu_kms); + if (secondary_gpu_data->secondary.copy_mode == + META_SHARED_FRAMEBUFFER_COPY_MODE_SECONDARY_GPU) + create_timestamp_query = FALSE; + } + + if (create_timestamp_query) + cogl_onscreen_egl_maybe_create_timestamp_query (onscreen, frame_info); + parent_class = COGL_ONSCREEN_CLASS (meta_onscreen_native_parent_class); parent_class->swap_buffers_with_damage (onscreen, rectangles, @@ -1364,6 +1384,17 @@ g_set_object (&onscreen_native->gbm.next_fb, secondary_gpu_fb); else g_set_object (&onscreen_native->gbm.next_fb, primary_gpu_fb); + + if (!meta_drm_buffer_ensure_fb_id (onscreen_native->gbm.next_fb, &error)) + { + g_warning ("Failed to ensure KMS FB ID on %s: %s", + meta_device_file_get_path (render_device_file), + error->message); + + frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC; + meta_onscreen_native_notify_frame_complete (onscreen); + return; + } break; case META_RENDERER_NATIVE_MODE_SURFACELESS: break; @@ -2417,6 +2448,15 @@ width, height, format, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + + if (!gbm_surface) + { + gbm_surface = gbm_surface_create (gbm_device, + width, height, + format, + 0); + } + if (!gbm_surface) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, diff -Nru mutter-46.0/src/backends/native/meta-renderer-native-gles3.c mutter-46.1/src/backends/native/meta-renderer-native-gles3.c --- mutter-46.0/src/backends/native/meta-renderer-native-gles3.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/backends/native/meta-renderer-native-gles3.c 2024-04-19 17:48:34.000000000 +0000 @@ -3,6 +3,7 @@ /* * Copyright (C) 2017 Red Hat * Copyright (c) 2018 DisplayLink (UK) Ltd. + * Copyright (c) 2023 Canonical Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -34,6 +35,7 @@ #include "backends/meta-egl-ext.h" #include "backends/meta-gles3.h" #include "backends/meta-gles3-table.h" +#include "meta/meta-debug.h" /* * GL/gl.h being included may conflict with gl3.h on some architectures. @@ -43,17 +45,240 @@ #error "Somehow included OpenGL headers when we shouldn't have" #endif +typedef struct _ContextData +{ + GArray *buffer_support; + GLuint shader_program; +} ContextData; + +typedef struct +{ + uint32_t drm_format; + uint64_t drm_modifier; + gboolean can_blit; +} BufferTypeSupport; + static void -paint_egl_image (MetaGles3 *gles3, - EGLImageKHR egl_image, - int width, - int height) +context_data_free (ContextData *context_data) +{ + g_array_free (context_data->buffer_support, TRUE); + g_free (context_data); +} + +static GQuark +get_quark_for_egl_context (EGLContext egl_context) +{ + char key[128]; + + g_snprintf (key, sizeof key, "EGLContext %p", egl_context); + + return g_quark_from_string (key); +} + +static gboolean +can_blit_buffer (ContextData *context_data, + MetaEgl *egl, + EGLDisplay egl_display, + uint32_t drm_format, + uint64_t drm_modifier) +{ + EGLint num_modifiers; + EGLuint64KHR *modifiers; + EGLBoolean *external_only; + g_autoptr (GError) error = NULL; + int i; + gboolean can_blit; + BufferTypeSupport support; + + can_blit = drm_modifier == DRM_FORMAT_MOD_LINEAR; + + for (i = 0; i < context_data->buffer_support->len; i++) + { + BufferTypeSupport *support = + &g_array_index (context_data->buffer_support, BufferTypeSupport, i); + + if (support->drm_format == drm_format && + support->drm_modifier == drm_modifier) + return support->can_blit; + } + + if (!meta_egl_has_extensions (egl, egl_display, NULL, + "EGL_EXT_image_dma_buf_import_modifiers", + NULL)) + { + meta_topic (META_DEBUG_RENDER, + "No support for EGL_EXT_image_dma_buf_import_modifiers, " + "assuming blitting linearly will still work."); + goto out; + } + + if (!meta_egl_query_dma_buf_modifiers (egl, egl_display, + drm_format, 0, NULL, NULL, + &num_modifiers, &error)) + { + meta_topic (META_DEBUG_RENDER, + "Failed to query supported DMA buffer modifiers (%s), " + "assuming blitting linearly will still work.", + error->message); + goto out; + } + + if (num_modifiers == 0) + goto out; + + modifiers = g_alloca0 (sizeof (EGLuint64KHR) * num_modifiers); + external_only = g_alloca0 (sizeof (EGLBoolean) * num_modifiers); + if (!meta_egl_query_dma_buf_modifiers (egl, egl_display, + drm_format, num_modifiers, + modifiers, external_only, + &num_modifiers, &error)) + { + g_warning ("Failed to requery supported DMA buffer modifiers: %s", + error->message); + can_blit = FALSE; + goto out; + } + + can_blit = FALSE; + for (i = 0; i < num_modifiers; i++) + { + if (drm_modifier == modifiers[i]) + { + can_blit = !external_only[i]; + goto out; + } + } + +out: + support = (BufferTypeSupport) { + .drm_format = drm_format, + .drm_modifier = drm_modifier, + .can_blit = can_blit, + }; + g_array_append_val (context_data->buffer_support, support); + return can_blit; +} + +static GLuint +load_shader (const char *src, + GLenum type) +{ + GLuint shader = glCreateShader (type); + + if (shader) + { + GLint compiled; + + glShaderSource (shader, 1, &src, NULL); + glCompileShader (shader); + glGetShaderiv (shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) + { + GLchar log[1024]; + + glGetShaderInfoLog (shader, sizeof (log) - 1, NULL, log); + log[sizeof (log) - 1] = '\0'; + g_warning ("load_shader compile failed: %s", log); + glDeleteShader (shader); + shader = 0; + } + } + + return shader; +} + +static void +ensure_shader_program (ContextData *context_data, + MetaGles3 *gles3) +{ + static const char vertex_shader_source[] = + "#version 100\n" + "attribute vec2 position;\n" + "attribute vec2 texcoord;\n" + "varying vec2 v_texcoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position, 0.0, 1.0);\n" + " v_texcoord = texcoord;\n" + "}\n"; + + static const char fragment_shader_source[] = + "#version 100\n" + "#extension GL_OES_EGL_image_external : require\n" + "precision mediump float;\n" + "uniform samplerExternalOES s_texture;\n" + "varying vec2 v_texcoord;\n" + "\n" + " void main()\n" + "{\n" + " gl_FragColor = texture2D(s_texture, v_texcoord);\n" + "}\n"; + + static const GLfloat box[] = + { /* position texcoord */ + -1.0f, +1.0f, 0.0f, 0.0f, + +1.0f, +1.0f, 1.0f, 0.0f, + +1.0f, -1.0f, 1.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 1.0f, + }; + GLint linked; + GLuint vertex_shader, fragment_shader; + GLint position_attrib, texcoord_attrib; + GLuint shader_program; + + if (context_data->shader_program) + return; + + shader_program = glCreateProgram (); + g_return_if_fail (shader_program); + context_data->shader_program = shader_program; + + vertex_shader = load_shader (vertex_shader_source, GL_VERTEX_SHADER); + g_return_if_fail (vertex_shader); + fragment_shader = load_shader (fragment_shader_source, GL_FRAGMENT_SHADER); + g_return_if_fail (fragment_shader); + + GLBAS (gles3, glAttachShader, (shader_program, vertex_shader)); + GLBAS (gles3, glAttachShader, (shader_program, fragment_shader)); + GLBAS (gles3, glLinkProgram, (shader_program)); + GLBAS (gles3, glGetProgramiv, (shader_program, GL_LINK_STATUS, &linked)); + if (!linked) + { + GLchar log[1024]; + + glGetProgramInfoLog (shader_program, sizeof (log) - 1, NULL, log); + log[sizeof (log) - 1] = '\0'; + g_warning ("Link failed: %s", log); + return; + } + + GLBAS (gles3, glUseProgram, (shader_program)); + + position_attrib = glGetAttribLocation (shader_program, "position"); + GLBAS (gles3, glEnableVertexAttribArray, (position_attrib)); + GLBAS (gles3, glVertexAttribPointer, + (position_attrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof (GLfloat), box)); + + texcoord_attrib = glGetAttribLocation (shader_program, "texcoord"); + GLBAS (gles3, glEnableVertexAttribArray, (texcoord_attrib)); + GLBAS (gles3, glVertexAttribPointer, + (texcoord_attrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof (GLfloat), box + 2)); +} + +static void +blit_egl_image (MetaGles3 *gles3, + EGLImageKHR egl_image, + int width, + int height) { GLuint texture; GLuint framebuffer; meta_gles3_clear_error (gles3); + GLBAS (gles3, glViewport, (0, 0, width, height)); + GLBAS (gles3, glGenFramebuffers, (1, &framebuffer)); GLBAS (gles3, glBindFramebuffer, (GL_READ_FRAMEBUFFER, framebuffer)); @@ -85,6 +310,43 @@ GLBAS (gles3, glDeleteFramebuffers, (1, &framebuffer)); } +static void +paint_egl_image (ContextData *context_data, + MetaGles3 *gles3, + EGLImageKHR egl_image, + int width, + int height) +{ + GLuint texture; + + meta_gles3_clear_error (gles3); + ensure_shader_program (context_data, gles3); + + GLBAS (gles3, glViewport, (0, 0, width, height)); + + GLBAS (gles3, glActiveTexture, (GL_TEXTURE0)); + GLBAS (gles3, glGenTextures, (1, &texture)); + GLBAS (gles3, glBindTexture, (GL_TEXTURE_EXTERNAL_OES, texture)); + GLEXT (gles3, glEGLImageTargetTexture2DOES, (GL_TEXTURE_EXTERNAL_OES, + egl_image)); + GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES, + GL_TEXTURE_MAG_FILTER, + GL_NEAREST)); + GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES, + GL_TEXTURE_MIN_FILTER, + GL_NEAREST)); + GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES, + GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE)); + GLBAS (gles3, glTexParameteri, (GL_TEXTURE_EXTERNAL_OES, + GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE)); + + GLBAS (gles3, glDrawArrays, (GL_TRIANGLE_FAN, 0, 4)); + + GLBAS (gles3, glDeleteTextures, (1, &texture)); +} + gboolean meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl, MetaGles3 *gles3, @@ -105,6 +367,28 @@ uint32_t format; EGLImageKHR egl_image; gboolean use_modifiers; + GQuark context_data_quark; + ContextData *context_data; + gboolean can_blit; + + context_data_quark = get_quark_for_egl_context (egl_context); + context_data = g_object_get_qdata (G_OBJECT (gles3), context_data_quark); + if (!context_data) + { + context_data = g_new0 (ContextData, 1); + context_data->buffer_support = g_array_new (FALSE, FALSE, + sizeof (BufferTypeSupport)); + + g_object_set_qdata_full (G_OBJECT (gles3), + context_data_quark, + context_data, + (GDestroyNotify) context_data_free); + } + + can_blit = can_blit_buffer (context_data, + egl, egl_display, + gbm_bo_get_format (shared_bo), + gbm_bo_get_modifier (shared_bo)); shared_bo_fd = gbm_bo_get_fd (shared_bo); if (shared_bo_fd < 0) @@ -150,9 +434,21 @@ if (!egl_image) return FALSE; - paint_egl_image (gles3, egl_image, width, height); + if (can_blit) + blit_egl_image (gles3, egl_image, width, height); + else + paint_egl_image (context_data, gles3, egl_image, width, height); meta_egl_destroy_image (egl, egl_display, egl_image, NULL); return TRUE; } + +void +meta_renderer_native_gles3_forget_context (MetaGles3 *gles3, + EGLContext egl_context) +{ + GQuark context_data_quark = get_quark_for_egl_context (egl_context); + + g_object_set_qdata (G_OBJECT (gles3), context_data_quark, NULL); +} diff -Nru mutter-46.0/src/backends/native/meta-renderer-native-gles3.h mutter-46.1/src/backends/native/meta-renderer-native-gles3.h --- mutter-46.0/src/backends/native/meta-renderer-native-gles3.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/backends/native/meta-renderer-native-gles3.h 2024-04-19 17:48:34.000000000 +0000 @@ -26,10 +26,13 @@ #include "backends/meta-egl.h" #include "backends/meta-gles3.h" -gboolean meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl, - MetaGles3 *gles3, - EGLDisplay egl_display, - EGLContext egl_context, - EGLSurface egl_surface, - struct gbm_bo *shared_bo, - GError **error); +gboolean meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl, + MetaGles3 *gles3, + EGLDisplay egl_display, + EGLContext egl_context, + EGLSurface egl_surface, + struct gbm_bo *shared_bo, + GError **error); + +void meta_renderer_native_gles3_forget_context (MetaGles3 *gles3, + EGLContext egl_context); diff -Nru mutter-46.0/src/backends/native/meta-renderer-native-private.h mutter-46.1/src/backends/native/meta-renderer-native-private.h --- mutter-46.0/src/backends/native/meta-renderer-native-private.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/backends/native/meta-renderer-native-private.h 2024-04-19 17:48:34.000000000 +0000 @@ -60,6 +60,7 @@ struct { MetaSharedFramebufferCopyMode copy_mode; gboolean has_EGL_EXT_image_dma_buf_import_modifiers; + gboolean needs_explicit_sync; /* For GPU blit mode */ EGLContext egl_context; diff -Nru mutter-46.0/src/backends/native/meta-renderer-native.c mutter-46.1/src/backends/native/meta-renderer-native.c --- mutter-46.0/src/backends/native/meta-renderer-native.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/backends/native/meta-renderer-native.c 2024-04-19 17:48:34.000000000 +0000 @@ -63,10 +63,12 @@ #include "backends/native/meta-output-kms.h" #include "backends/native/meta-render-device-gbm.h" #include "backends/native/meta-render-device-surfaceless.h" +#include "backends/native/meta-renderer-native-gles3.h" #include "backends/native/meta-renderer-native-private.h" #include "backends/native/meta-renderer-view-native.h" #include "cogl/cogl.h" #include "common/meta-cogl-drm-formats.h" +#include "common/meta-drm-format-helpers.h" #include "core/boxes-private.h" #ifdef HAVE_EGL_DEVICE @@ -136,6 +138,9 @@ MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); + meta_renderer_native_gles3_forget_context (renderer_native->gles3, + renderer_gpu_data->secondary.egl_context); + meta_egl_destroy_context (egl, egl_display, renderer_gpu_data->secondary.egl_context, @@ -1805,6 +1810,7 @@ CoglContext *cogl_context; CoglDisplay *cogl_display; const char **missing_gl_extensions; + const char *egl_vendor; egl_display = meta_render_device_get_egl_display (render_device); if (egl_display == EGL_NO_DISPLAY) @@ -1871,6 +1877,11 @@ meta_egl_has_extensions (egl, egl_display, NULL, "EGL_EXT_image_dma_buf_import_modifiers", NULL); + + egl_vendor = meta_egl_query_string (egl, egl_display, EGL_VENDOR); + if (!g_strcmp0 (egl_vendor, "NVIDIA")) + renderer_gpu_data->secondary.needs_explicit_sync = TRUE; + ret = TRUE; out: maybe_restore_cogl_egl_api (renderer_native); diff -Nru mutter-46.0/src/backends/x11/nested/meta-stage-x11-nested.c mutter-46.1/src/backends/x11/nested/meta-stage-x11-nested.c --- mutter-46.0/src/backends/x11/nested/meta-stage-x11-nested.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/backends/x11/nested/meta-stage-x11-nested.c 2024-04-19 17:48:34.000000000 +0000 @@ -186,6 +186,8 @@ } frame_info = cogl_frame_info_new (context, 0); + cogl_onscreen_egl_maybe_create_timestamp_query (stage_x11->onscreen, + frame_info); cogl_onscreen_swap_buffers (stage_x11->onscreen, frame_info, frame); if (!clutter_frame_has_result (frame)) diff -Nru mutter-46.0/src/common/meta-cogl-drm-formats.c mutter-46.1/src/common/meta-cogl-drm-formats.c --- mutter-46.0/src/common/meta-cogl-drm-formats.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/common/meta-cogl-drm-formats.c 2024-04-19 17:48:34.000000000 +0000 @@ -24,40 +24,6 @@ #include "common/meta-cogl-drm-formats.h" - -/** - * meta_drm_format_to_string: - * @tmp: temporary buffer - * @drm_format: DRM fourcc pixel format - * - * Returns a pointer to a string naming the given pixel format, - * usually a pointer to the temporary buffer but not always. - * Invalid formats may return nonsense names. - * - * When calling this, allocate one MetaDrmFormatBuf on the stack to - * be used as the temporary buffer. - */ -const char * -meta_drm_format_to_string (MetaDrmFormatBuf *tmp, - uint32_t drm_format) -{ - int i; - - if (drm_format == DRM_FORMAT_INVALID) - return "INVALID"; - - G_STATIC_ASSERT (sizeof (tmp->s) == 5); - for (i = 0; i < 4; i++) - { - char c = (drm_format >> (i * 8)) & 0xff; - tmp->s[i] = g_ascii_isgraph (c) ? c : '.'; - } - - tmp->s[i] = 0; - - return tmp->s; -} - const MetaFormatInfo * meta_format_info_from_drm_format (uint32_t drm_format) { diff -Nru mutter-46.0/src/common/meta-cogl-drm-formats.h mutter-46.1/src/common/meta-cogl-drm-formats.h --- mutter-46.0/src/common/meta-cogl-drm-formats.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/common/meta-cogl-drm-formats.h 2024-04-19 17:48:34.000000000 +0000 @@ -29,14 +29,6 @@ G_BEGIN_DECLS -typedef struct _MetaDrmFormatBuf -{ - char s[5]; -} MetaDrmFormatBuf; - -const char * meta_drm_format_to_string (MetaDrmFormatBuf *tmp, - uint32_t drm_format); - typedef struct _MetaFormatInfo { uint32_t drm_format; diff -Nru mutter-46.0/src/common/meta-drm-format-helpers.c mutter-46.1/src/common/meta-drm-format-helpers.c --- mutter-46.0/src/common/meta-drm-format-helpers.c 1970-01-01 00:00:00.000000000 +0000 +++ mutter-46.1/src/common/meta-drm-format-helpers.c 2024-04-19 17:48:34.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 Georges Basile Stavracas Neto + * Copyright (C) 2023 Collabora Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include "config.h" + +#include "common/meta-drm-format-helpers.h" + +#include +#include + +/** + * meta_drm_format_to_string: + * @tmp: temporary buffer + * @drm_format: DRM fourcc pixel format + * + * Returns a pointer to a string naming the given pixel format, + * usually a pointer to the temporary buffer but not always. + * Invalid formats may return nonsense names. + * + * When calling this, allocate one MetaDrmFormatBuf on the stack to + * be used as the temporary buffer. + */ +const char * +meta_drm_format_to_string (MetaDrmFormatBuf *tmp, + uint32_t drm_format) +{ + int i; + + if (drm_format == DRM_FORMAT_INVALID) + return "INVALID"; + + G_STATIC_ASSERT (sizeof (tmp->s) == 5); + for (i = 0; i < 4; i++) + { + char c = (drm_format >> (i * 8)) & 0xff; + tmp->s[i] = g_ascii_isgraph (c) ? c : '.'; + } + + tmp->s[i] = 0; + + return tmp->s; +} diff -Nru mutter-46.0/src/common/meta-drm-format-helpers.h mutter-46.1/src/common/meta-drm-format-helpers.h --- mutter-46.0/src/common/meta-drm-format-helpers.h 1970-01-01 00:00:00.000000000 +0000 +++ mutter-46.1/src/common/meta-drm-format-helpers.h 2024-04-19 17:48:34.000000000 +0000 @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 Georges Basile Stavracas Neto + * Copyright (C) 2023 Collabora Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#pragma once + +#include + +typedef struct _MetaDrmFormatBuf +{ + char s[5]; +} MetaDrmFormatBuf; + +const char * meta_drm_format_to_string (MetaDrmFormatBuf *tmp, + uint32_t drm_format); diff -Nru mutter-46.0/src/compositor/edge-resistance.c mutter-46.1/src/compositor/edge-resistance.c --- mutter-46.0/src/compositor/edge-resistance.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/compositor/edge-resistance.c 2024-04-19 17:48:34.000000000 +0000 @@ -29,17 +29,6 @@ #include "core/meta-workspace-manager-private.h" #include "core/workspace-private.h" -/* A simple macro for whether a given window's edges are potentially - * relevant for resistance/snapping during a move/resize operation - */ -#define WINDOW_EDGES_RELEVANT(window, display) \ - meta_window_should_be_showing (window) && \ - (!meta_compositor_get_current_window_drag (display->compositor) || \ - window != meta_window_drag_get_window (meta_compositor_get_current_window_drag (display->compositor))) && \ - window->type != META_WINDOW_DESKTOP && \ - window->type != META_WINDOW_MENU && \ - window->type != META_WINDOW_SPLASHSCREEN - typedef struct _MetaEdgeResistanceData MetaEdgeResistanceData; struct _MetaEdgeResistanceData @@ -52,6 +41,29 @@ static GQuark edge_resistance_data_quark = 0; +static gboolean +is_window_relevant_for_edges (MetaWindow *window) +{ + MetaWindowDrag *drag; + + if (!meta_window_should_be_showing (window)) + return FALSE; + + drag = meta_compositor_get_current_window_drag (window->display->compositor); + if (drag && window == meta_window_drag_get_window (drag)) + return FALSE; + + switch (window->type) + { + case META_WINDOW_DESKTOP: + case META_WINDOW_MENU: + case META_WINDOW_SPLASHSCREEN: + return FALSE; + default: + return TRUE; + } +} + /* !WARNING!: this function can return invalid indices (namely, either -1 or * edges->len); this is by design, but you need to remember this. */ @@ -879,12 +891,13 @@ compute_resistance_and_snapping_edges (MetaWindowDrag *window_drag) { MetaEdgeResistanceData *edge_data; - GList *stacked_windows; - GList *cur_window_iter; - GList *edges; + GList *l; /* Lists of window positions (rects) and their relative stacking positions */ int stack_position; - GSList *obscuring_windows, *window_stacking; + g_autoslist (MtkRectangle) obscuring_windows = NULL; + g_autoptr (GList) stacked_windows = NULL; + g_autoptr (GSList) window_stacking = NULL; + g_autoptr (GList) edges = NULL; /* The portions of the above lists that still remain at the stacking position * in the layer that we are working on */ @@ -910,16 +923,16 @@ * those below it instead of going both ways, we also need to keep a * counter list. Messy, I know. */ - obscuring_windows = window_stacking = NULL; - cur_window_iter = stacked_windows; stack_position = 0; - while (cur_window_iter != NULL) + for (l = stacked_windows; l; l = l->next) { - MetaWindow *cur_window = cur_window_iter->data; - if (WINDOW_EDGES_RELEVANT (cur_window, display)) + MetaWindow *cur_window = l->data; + + if (is_window_relevant_for_edges (cur_window)) { MtkRectangle *new_rect; - new_rect = g_new (MtkRectangle, 1); + + new_rect = mtk_rectangle_new_empty (); meta_window_get_frame_rect (cur_window, new_rect); obscuring_windows = g_slist_prepend (obscuring_windows, new_rect); window_stacking = @@ -927,7 +940,6 @@ } stack_position++; - cur_window_iter = cur_window_iter->next; } /* Put 'em in bottom to top order */ rem_windows = obscuring_windows = g_slist_reverse (obscuring_windows); @@ -940,18 +952,17 @@ */ edges = NULL; stack_position = 0; - cur_window_iter = stacked_windows; - while (cur_window_iter != NULL) + for (l = stacked_windows; l; l = l->next) { + MetaWindow *cur_window = l->data; MtkRectangle cur_rect; - MetaWindow *cur_window = cur_window_iter->data; meta_window_get_frame_rect (cur_window, &cur_rect); /* Check if we want to use this window's edges for edge * resistance (note that dock edges are considered screen edges * which are handled separately */ - if (WINDOW_EDGES_RELEVANT (cur_window, display) && + if (is_window_relevant_for_edges (cur_window) && cur_window->type != META_WINDOW_DOCK) { GList *new_edges; @@ -1035,17 +1046,8 @@ } stack_position++; - cur_window_iter = cur_window_iter->next; } - /* - * 4th: Free the extra memory not needed and sort the list - */ - g_list_free (stacked_windows); - /* Free the memory used by the obscuring windows/docks lists */ - g_slist_free (window_stacking); - g_slist_free_full (obscuring_windows, g_free); - /* Sort the list. FIXME: Should I bother with this sorting? I just * sort again later in cache_edges() anyway... */ @@ -1060,7 +1062,6 @@ edges, workspace_manager->active_workspace->monitor_edges, workspace_manager->active_workspace->screen_edges); - g_list_free (edges); return edge_data; } diff -Nru mutter-46.0/src/compositor/meta-sync-ring.c mutter-46.1/src/compositor/meta-sync-ring.c --- mutter-46.0/src/compositor/meta-sync-ring.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/compositor/meta-sync-ring.c 2024-04-19 17:48:34.000000000 +0000 @@ -544,20 +544,29 @@ meta_sync_ring_insert_wait (void) { MetaSyncRing *ring = meta_sync_ring_get (); + MetaSync *sync; if (!ring) return FALSE; g_return_val_if_fail (ring->xdisplay != NULL, FALSE); - if (ring->current_sync->state != META_SYNC_STATE_READY) + sync = ring->current_sync; + + if (sync->state == META_SYNC_STATE_WAITING) + { + meta_gl_delete_sync (sync->gpu_fence); + sync->gpu_fence = 0; + sync->state = META_SYNC_STATE_READY; + } + else if (sync->state != META_SYNC_STATE_READY) { meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?"); if (!meta_sync_ring_reboot (ring->xdisplay)) return FALSE; } - meta_sync_insert (ring->current_sync); + meta_sync_insert (sync); return TRUE; } diff -Nru mutter-46.0/src/compositor/meta-window-actor-wayland.c mutter-46.1/src/compositor/meta-window-actor-wayland.c --- mutter-46.0/src/compositor/meta-window-actor-wayland.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/compositor/meta-window-actor-wayland.c 2024-04-19 17:48:34.000000000 +0000 @@ -350,7 +350,7 @@ ClutterActor *child_actor; ClutterActorIter iter; MetaSurfaceActor *topmost_surface_actor = NULL; - int n_mapped_surfaces = 0; + int n_visible_surface_actors = 0; MetaWindow *window; ClutterActorBox window_box; ClutterActorBox surface_box; @@ -365,11 +365,17 @@ clutter_actor_iter_init (&iter, surface_container); while (clutter_actor_iter_next (&iter, &child_actor)) { + MetaSurfaceActor *surface_actor; + if (!clutter_actor_is_mapped (child_actor)) continue; - topmost_surface_actor = META_SURFACE_ACTOR (child_actor); - n_mapped_surfaces++; + surface_actor = META_SURFACE_ACTOR (child_actor); + if (meta_surface_actor_is_obscured (surface_actor)) + continue; + + topmost_surface_actor = surface_actor; + n_visible_surface_actors++; } if (!topmost_surface_actor) @@ -380,10 +386,10 @@ } window = meta_window_actor_get_meta_window (actor); - if (meta_window_is_fullscreen (window) && n_mapped_surfaces == 1) + if (meta_window_is_fullscreen (window) && n_visible_surface_actors == 1) return topmost_surface_actor; - if (meta_window_is_fullscreen (window) && n_mapped_surfaces == 2) + if (meta_window_is_fullscreen (window) && n_visible_surface_actors == 2) { MetaSurfaceActorWayland *bg_surface_actor = NULL; MetaWaylandSurface *bg_surface; @@ -393,10 +399,16 @@ clutter_actor_iter_init (&iter, surface_container); while (clutter_actor_iter_next (&iter, &child_actor)) { + MetaSurfaceActor *surface_actor; + if (!clutter_actor_is_mapped (child_actor)) continue; - bg_surface_actor = META_SURFACE_ACTOR_WAYLAND (child_actor); + surface_actor = META_SURFACE_ACTOR (child_actor); + if (meta_surface_actor_is_obscured (surface_actor)) + continue; + + bg_surface_actor = META_SURFACE_ACTOR_WAYLAND (surface_actor); break; } g_assert (bg_surface_actor); diff -Nru mutter-46.0/src/core/constraints.c mutter-46.1/src/core/constraints.c --- mutter-46.0/src/core/constraints.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/core/constraints.c 2024-04-19 17:48:34.000000000 +0000 @@ -1154,6 +1154,9 @@ meta_window_get_placement_rule (window)) return TRUE; + if (window->fullscreen) + return TRUE; + /* We want to center the dialog on the parent, including the decorations for both of them. info->current is in client X window coordinates, so we need to convert them to frame coordinates, apply the centering and then diff -Nru mutter-46.0/src/core/display-private.h mutter-46.1/src/core/display-private.h --- mutter-46.0/src/core/display-private.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/core/display-private.h 2024-04-19 17:48:34.000000000 +0000 @@ -154,6 +154,7 @@ GBytes *saved_clipboard; gchar *saved_clipboard_mimetype; MetaSelection *selection; + GCancellable *saved_clipboard_cancellable; }; struct _MetaDisplayClass diff -Nru mutter-46.0/src/core/frame.c mutter-46.1/src/core/frame.c --- mutter-46.0/src/core/frame.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/core/frame.c 2024-04-19 17:48:34.000000000 +0000 @@ -274,7 +274,7 @@ int format, res; Atom type; unsigned long nitems, bytes_after; - unsigned char *data; + unsigned char *data = NULL; if (!frame->xwindow) return; @@ -290,10 +290,8 @@ &nitems, &bytes_after, (unsigned char **) &data); - if (mtk_x11_error_trap_pop_with_return (x11_display->xdisplay) != Success) - return; - - if (res == Success && nitems == 4) + if (mtk_x11_error_trap_pop_with_return (x11_display->xdisplay) == Success && + res == Success && nitems == 4) { borders->invisible = (MetaFrameBorder) { ((long *) data)[0], @@ -302,6 +300,10 @@ ((long *) data)[3], }; } + else + { + borders->invisible = (MetaFrameBorder) { 0, 0, 0, 0 }; + } g_clear_pointer (&data, XFree); @@ -316,10 +318,8 @@ &nitems, &bytes_after, (unsigned char **) &data); - if (mtk_x11_error_trap_pop_with_return (x11_display->xdisplay) != Success) - return; - - if (res == Success && nitems == 4) + if (mtk_x11_error_trap_pop_with_return (x11_display->xdisplay) == Success && + res == Success && nitems == 4) { borders->visible = (MetaFrameBorder) { ((long *) data)[0], @@ -328,6 +328,10 @@ ((long *) data)[3], }; } + else + { + borders->visible = (MetaFrameBorder) { 0, 0, 0, 0 }; + } g_clear_pointer (&data, XFree); diff -Nru mutter-46.0/src/core/meta-clipboard-manager.c mutter-46.1/src/core/meta-clipboard-manager.c --- mutter-46.0/src/core/meta-clipboard-manager.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/core/meta-clipboard-manager.c 2024-04-19 17:48:34.000000000 +0000 @@ -65,23 +65,23 @@ static void transfer_cb (MetaSelection *selection, GAsyncResult *result, - GOutputStream *output) + GOutputStream *output_stream) { MetaDisplay *display = meta_selection_get_display (selection); - GError *error = NULL; + g_autoptr (GOutputStream) output = output_stream; + g_autoptr (GError) error = NULL; if (!meta_selection_transfer_finish (selection, result, &error)) { - g_warning ("Failed to store clipboard: %s", error->message); - g_error_free (error); - g_object_unref (output); + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to store clipboard: %s", error->message); + return; } g_output_stream_close (output, NULL, NULL); display->saved_clipboard = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (output)); - g_object_unref (output); } static void @@ -104,6 +104,8 @@ /* New selection source, find the best mimetype in order to * keep a copy of it. */ + g_cancellable_cancel (display->saved_clipboard_cancellable); + g_clear_object (&display->saved_clipboard_cancellable); g_clear_object (&display->selection_source); g_clear_pointer (&display->saved_clipboard_mimetype, g_free); g_clear_pointer (&display->saved_clipboard, g_bytes_unref); @@ -126,7 +128,7 @@ } } - if (best_idx < 0) + if (!best) { g_list_free_full (mimetypes, g_free); return; @@ -135,12 +137,13 @@ display->saved_clipboard_mimetype = g_strdup (best); g_list_free_full (mimetypes, g_free); output = g_memory_output_stream_new_resizable (); + display->saved_clipboard_cancellable = g_cancellable_new (); meta_selection_transfer_async (selection, META_SELECTION_CLIPBOARD, display->saved_clipboard_mimetype, transfer_size, output, - NULL, + display->saved_clipboard_cancellable, (GAsyncReadyCallback) transfer_cb, output); } @@ -149,6 +152,8 @@ g_autoptr (GError) error = NULL; g_autoptr (MetaSelectionSource) new_source = NULL; + g_assert (display->saved_clipboard_mimetype != NULL); + /* Old owner is gone, time to take over */ new_source = meta_selection_source_memory_new (display->saved_clipboard_mimetype, display->saved_clipboard, @@ -180,6 +185,8 @@ { MetaSelection *selection; + g_cancellable_cancel (display->saved_clipboard_cancellable); + g_clear_object (&display->saved_clipboard_cancellable); g_clear_object (&display->selection_source); g_clear_pointer (&display->saved_clipboard, g_bytes_unref); g_clear_pointer (&display->saved_clipboard_mimetype, g_free); diff -Nru mutter-46.0/src/core/window-private.h mutter-46.1/src/core/window-private.h --- mutter-46.0/src/core/window-private.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/core/window-private.h 2024-04-19 17:48:34.000000000 +0000 @@ -684,9 +684,12 @@ gboolean meta_window_should_be_showing_on_workspace (MetaWindow *window, MetaWorkspace *workspace); -/* Return whether the window should be currently mapped */ +META_EXPORT_TEST gboolean meta_window_should_be_showing (MetaWindow *window); +META_EXPORT_TEST +gboolean meta_window_should_show (MetaWindow *window); + void meta_window_update_struts (MetaWindow *window); /* gets position we need to set to stay in current position, diff -Nru mutter-46.0/src/core/window.c mutter-46.1/src/core/window.c --- mutter-46.0/src/core/window.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/core/window.c 2024-04-19 17:48:34.000000000 +0000 @@ -168,6 +168,8 @@ MetaTileMode mode); static void update_edge_constraints (MetaWindow *window); +static void set_hidden_suspended_state (MetaWindow *window); + static void initable_iface_init (GInitableIface *initable_iface); typedef struct _MetaWindowPrivate @@ -713,9 +715,6 @@ static void meta_window_init (MetaWindow *window) { - MetaWindowPrivate *priv = meta_window_get_instance_private (window); - - priv->suspend_state = META_WINDOW_SUSPEND_STATE_SUSPENDED; window->stamp = next_window_stamp++; meta_prefs_add_listener (prefs_changed_callback, window); window->is_alive = TRUE; @@ -991,6 +990,7 @@ meta_window_constructed (GObject *object) { MetaWindow *window = META_WINDOW (object); + MetaWindowPrivate *priv = meta_window_get_instance_private (window); MetaDisplay *display = window->display; MetaContext *context = meta_display_get_context (display); MetaBackend *backend = meta_context_get_backend (context); @@ -1343,6 +1343,11 @@ !window->initially_iconic) unminimize_window_and_all_transient_parents (window); + /* There is a slim chance we'll hit time out before a extremely slow client + * managed to become active, but unlikely enough. */ + priv->suspend_state = META_WINDOW_SUSPEND_STATE_HIDDEN; + set_hidden_suspended_state (window); + window->constructing = FALSE; } @@ -1690,9 +1695,8 @@ return TRUE; } -gboolean -meta_window_should_be_showing_on_workspace (MetaWindow *window, - MetaWorkspace *workspace) +static gboolean +meta_window_is_showable (MetaWindow *window) { #ifdef HAVE_WAYLAND if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND && @@ -1704,12 +1708,72 @@ window->decorated && !window->frame) return FALSE; - /* Windows should be showing if they're located on the - * workspace and they're showing on their own workspace. */ + return TRUE; +} + +/** + * meta_window_should_show_on_workspace: + * + * Tells whether a window should be showing on the passed workspace, without + * taking into account whether it can immediately be shown. Whether it can be + * shown or not depends on what windowing system it was created from. + * + * Returns: %TRUE if the window should show. + */ +static gboolean +meta_window_should_show_on_workspace (MetaWindow *window, + MetaWorkspace *workspace) +{ return (meta_window_located_on_workspace (window, workspace) && meta_window_showing_on_its_workspace (window)); } +/** + * meta_window_should_show: + * + * Tells whether a window should be showing on the current workspace, without + * taking into account whether it can immediately be shown. Whether it can be + * shown or not depends on what windowing system it was created from. + * + * Returns: %TRUE if the window should show. + */ +gboolean +meta_window_should_show (MetaWindow *window) +{ + MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; + MetaWorkspace *active_workspace = workspace_manager->active_workspace; + + return meta_window_should_show_on_workspace (window, active_workspace); +} + +/** + * meta_window_should_be_showing_on_workspace: + * + * Tells whether a window should be showing on the passed workspace, while + * taking whether it can be immediately be shown. Whether it can be shown or + * not depends on what windowing system it was created from. + * + * Returns: %TRUE if the window should and can be shown. + */ +gboolean +meta_window_should_be_showing_on_workspace (MetaWindow *window, + MetaWorkspace *workspace) +{ + if (!meta_window_is_showable (window)) + return FALSE; + + return meta_window_should_show_on_workspace (window, workspace); +} + +/** + * meta_window_should_be_showing: + * + * Tells whether a window should be showing on the current workspace, while + * taking whether it can be immediately be shown. Whether it can be shown or + * not depends on what windowing system it was created from. + * + * Returns: %TRUE if the window should and can be shown. + */ gboolean meta_window_should_be_showing (MetaWindow *window) { @@ -2106,6 +2170,19 @@ } static void +set_hidden_suspended_state (MetaWindow *window) +{ + MetaWindowPrivate *priv = meta_window_get_instance_private (window); + + priv->suspend_state = META_WINDOW_SUSPEND_STATE_HIDDEN; + g_return_if_fail (!priv->suspend_timoeut_id); + priv->suspend_timoeut_id = + g_timeout_add_seconds (SUSPEND_HIDDEN_TIMEOUT_S, + enter_suspend_state_cb, + window); +} + +static void update_suspend_state (MetaWindow *window) { MetaWindowPrivate *priv = meta_window_get_instance_private (window); @@ -2122,13 +2199,8 @@ } else if (priv->suspend_state == META_WINDOW_SUSPEND_STATE_ACTIVE) { - priv->suspend_state = META_WINDOW_SUSPEND_STATE_HIDDEN; + set_hidden_suspended_state (window); g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_SUSPEND_STATE]); - g_return_if_fail (!priv->suspend_timoeut_id); - priv->suspend_timoeut_id = - g_timeout_add_seconds (SUSPEND_HIDDEN_TIMEOUT_S, - enter_suspend_state_cb, - window); } } @@ -2227,7 +2299,7 @@ window->has_maximize_func) { MtkRectangle work_area; - meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area); + meta_window_get_work_area_current_monitor (window, &work_area); /* Automaximize windows that map with a size > MAX_UNMAXIMIZED_WINDOW_AREA of the work area */ if (window->rect.width * window->rect.height > work_area.width * work_area.height * MAX_UNMAXIMIZED_WINDOW_AREA) { @@ -3101,7 +3173,7 @@ MtkRectangle old_frame_rect, old_buffer_rect; gboolean has_target_size; - meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area); + meta_window_get_work_area_current_monitor (window, &work_area); meta_window_get_frame_rect (window, &old_frame_rect); meta_window_get_buffer_rect (window, &old_buffer_rect); @@ -5837,9 +5909,7 @@ meta_window_get_work_area_current_monitor (MetaWindow *window, MtkRectangle *area) { - meta_window_get_work_area_for_monitor (window, - window->monitor->number, - area); + meta_window_get_work_area_for_logical_monitor (window, window->monitor, area); } /** diff -Nru mutter-46.0/src/meson.build mutter-46.1/src/meson.build --- mutter-46.0/src/meson.build 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/meson.build 2024-04-19 17:48:34.000000000 +0000 @@ -579,6 +579,8 @@ 'core/meta-service-channel.h', 'wayland/meta-cursor-sprite-wayland.c', 'wayland/meta-cursor-sprite-wayland.h', + 'wayland/meta-drm-timeline.c', + 'wayland/meta-drm-timeline.h', 'wayland/meta-pointer-confinement-wayland.c', 'wayland/meta-pointer-confinement-wayland.h', 'wayland/meta-pointer-lock-wayland.c', @@ -633,6 +635,8 @@ 'wayland/meta-wayland-keyboard.h', 'wayland/meta-wayland-legacy-xdg-foreign.c', 'wayland/meta-wayland-legacy-xdg-foreign.h', + 'wayland/meta-wayland-linux-drm-syncobj.c', + 'wayland/meta-wayland-linux-drm-syncobj.h', 'wayland/meta-wayland-outputs.c', 'wayland/meta-wayland-outputs.h', 'wayland/meta-wayland-pointer.c', @@ -869,6 +873,8 @@ mutter_sources += [ 'common/meta-cogl-drm-formats.c', 'common/meta-cogl-drm-formats.h', + 'common/meta-drm-format-helpers.c', + 'common/meta-drm-format-helpers.h', ] endif @@ -1077,6 +1083,7 @@ ['xdg-output', 'unstable', 'v1', ], ['xdg-shell', 'stable', ], ['xwayland-keyboard-grab', 'unstable', 'v1', ], + ['linux-drm-syncobj-v1', 'private', ], ] if have_wayland_eglstream wayland_eglstream_protocols_dir = wayland_eglstream_protocols_dep.get_variable('pkgdatadir') diff -Nru mutter-46.0/src/meta/common.h mutter-46.1/src/meta/common.h --- mutter-46.0/src/meta/common.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/meta/common.h 2024-04-19 17:48:34.000000000 +0000 @@ -27,6 +27,7 @@ #include #include "clutter/clutter.h" +#include "meta/meta-base.h" #include "meta/meta-enums.h" /** @@ -42,8 +43,6 @@ /* Replacement for X11 CurrentTime */ #define META_CURRENT_TIME 0L -#define META_EXPORT __attribute__((visibility("default"))) extern - #define MAX_BUTTONS_PER_CORNER META_BUTTON_FUNCTION_LAST /* Keep array size in sync with MAX_BUTTONS_PER_CORNER */ diff -Nru mutter-46.0/src/meta/meson.build mutter-46.1/src/meta/meson.build --- mutter-46.0/src/meta/meson.build 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/meta/meson.build 2024-04-19 17:48:34.000000000 +0000 @@ -9,6 +9,7 @@ 'keybindings.h', 'main.h', 'meta-backend.h', + 'meta-base.h', 'meta-background.h', 'meta-background-actor.h', 'meta-background-content.h', @@ -17,6 +18,7 @@ 'meta-close-dialog.h', 'meta-cursor-tracker.h', 'meta-context.h', + 'meta-debug.h', 'meta-dnd.h', 'meta-enums.h', 'meta-idle-monitor.h', diff -Nru mutter-46.0/src/meta/meta-base.h mutter-46.1/src/meta/meta-base.h --- mutter-46.0/src/meta/meta-base.h 1970-01-01 00:00:00.000000000 +0000 +++ mutter-46.1/src/meta/meta-base.h 2024-04-19 17:48:34.000000000 +0000 @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2005 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#pragma once + +#define META_EXPORT __attribute__((visibility("default"))) extern diff -Nru mutter-46.0/src/meta/meta-debug.h mutter-46.1/src/meta/meta-debug.h --- mutter-46.0/src/meta/meta-debug.h 1970-01-01 00:00:00.000000000 +0000 +++ mutter-46.1/src/meta/meta-debug.h 2024-04-19 17:48:34.000000000 +0000 @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2001 Havoc Pennington + * Copyright (C) 2005 Elijah Newren + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#pragma once + +#include "meta/meta-base.h" + +/** + * MetaDebugTopic: + * @META_DEBUG_VERBOSE: verbose logging + * @META_DEBUG_FOCUS: focus + * @META_DEBUG_WORKAREA: workarea + * @META_DEBUG_STACK: stack + * @META_DEBUG_SM: session management + * @META_DEBUG_EVENTS: events + * @META_DEBUG_WINDOW_STATE: window state + * @META_DEBUG_WINDOW_OPS: window operations + * @META_DEBUG_GEOMETRY: geometry + * @META_DEBUG_PLACEMENT: window placement + * @META_DEBUG_PING: ping + * @META_DEBUG_KEYBINDINGS: keybindings + * @META_DEBUG_SYNC: sync + * @META_DEBUG_STARTUP: startup + * @META_DEBUG_PREFS: preferences + * @META_DEBUG_GROUPS: groups + * @META_DEBUG_RESIZING: resizing + * @META_DEBUG_SHAPES: shapes + * @META_DEBUG_EDGE_RESISTANCE: edge resistance + * @META_DEBUG_WAYLAND: Wayland + * @META_DEBUG_KMS: kernel mode setting + * @META_DEBUG_SCREEN_CAST: screencasting + * @META_DEBUG_REMOTE_DESKTOP: remote desktop + * @META_DEBUG_BACKEND: backend + * @META_DEBUG_RENDER: native backend rendering + * @META_DEBUG_COLOR: color management + * @META_DEBUG_INPUT_EVENTS: input events + * @META_DEBUG_EIS: eis state + */ +typedef enum +{ + META_DEBUG_VERBOSE = -1, + META_DEBUG_FOCUS = 1 << 0, + META_DEBUG_WORKAREA = 1 << 1, + META_DEBUG_STACK = 1 << 2, + META_DEBUG_SM = 1 << 3, + META_DEBUG_EVENTS = 1 << 4, + META_DEBUG_WINDOW_STATE = 1 << 5, + META_DEBUG_WINDOW_OPS = 1 << 6, + META_DEBUG_GEOMETRY = 1 << 7, + META_DEBUG_PLACEMENT = 1 << 8, + META_DEBUG_PING = 1 << 9, + META_DEBUG_KEYBINDINGS = 1 << 10, + META_DEBUG_SYNC = 1 << 11, + META_DEBUG_STARTUP = 1 << 12, + META_DEBUG_PREFS = 1 << 13, + META_DEBUG_GROUPS = 1 << 14, + META_DEBUG_RESIZING = 1 << 15, + META_DEBUG_SHAPES = 1 << 16, + META_DEBUG_EDGE_RESISTANCE = 1 << 17, + META_DEBUG_DBUS = 1 << 18, + META_DEBUG_INPUT = 1 << 19, + META_DEBUG_WAYLAND = 1 << 20, + META_DEBUG_KMS = 1 << 21, + META_DEBUG_SCREEN_CAST = 1 << 22, + META_DEBUG_REMOTE_DESKTOP = 1 << 23, + META_DEBUG_BACKEND = 1 << 24, + META_DEBUG_RENDER = 1 << 25, + META_DEBUG_COLOR = 1 << 26, + META_DEBUG_INPUT_EVENTS = 1 << 27, + META_DEBUG_EIS = 1 << 28, +} MetaDebugTopic; + +META_EXPORT +gboolean meta_is_topic_enabled (MetaDebugTopic topic); + +/* To disable verbose mode, we make these functions into no-ops */ +#ifdef WITH_VERBOSE_MODE + +const char * meta_topic_to_string (MetaDebugTopic topic); + +META_EXPORT +void meta_log (const char *format, ...) G_GNUC_PRINTF (1, 2); + +#define meta_topic(debug_topic, ...) \ + G_STMT_START \ + { \ + if (meta_is_topic_enabled (debug_topic)) \ + { \ + g_autofree char *_topic_message = NULL; \ +\ + _topic_message = g_strdup_printf (__VA_ARGS__); \ + meta_log ("%s: %s", meta_topic_to_string (debug_topic), \ + _topic_message); \ + } \ + } \ + G_STMT_END + +#define meta_verbose(...) meta_topic (META_DEBUG_VERBOSE, __VA_ARGS__) + +#else + +# ifdef G_HAVE_ISO_VARARGS +# define meta_verbose(...) +# define meta_topic(...) +# elif defined(G_HAVE_GNUC_VARARGS) +# define meta_verbose(format...) +# define meta_topic(format...) +# else +# error "This compiler does not support varargs macros and thus verbose mode can't be disabled meaningfully" +# endif + +#endif /* !WITH_VERBOSE_MODE */ diff -Nru mutter-46.0/src/meta/util.h mutter-46.1/src/meta/util.h --- mutter-46.0/src/meta/util.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/meta/util.h 2024-04-19 17:48:34.000000000 +0000 @@ -26,6 +26,7 @@ #include #include "meta/common.h" +#include "meta/meta-debug.h" #include "meta/meta-later.h" META_EXPORT @@ -47,71 +48,6 @@ ...) G_GNUC_PRINTF (1, 2) G_GNUC_NORETURN G_ANALYZER_NORETURN; /** - * MetaDebugTopic: - * @META_DEBUG_VERBOSE: verbose logging - * @META_DEBUG_FOCUS: focus - * @META_DEBUG_WORKAREA: workarea - * @META_DEBUG_STACK: stack - * @META_DEBUG_SM: session management - * @META_DEBUG_EVENTS: events - * @META_DEBUG_WINDOW_STATE: window state - * @META_DEBUG_WINDOW_OPS: window operations - * @META_DEBUG_GEOMETRY: geometry - * @META_DEBUG_PLACEMENT: window placement - * @META_DEBUG_PING: ping - * @META_DEBUG_KEYBINDINGS: keybindings - * @META_DEBUG_SYNC: sync - * @META_DEBUG_STARTUP: startup - * @META_DEBUG_PREFS: preferences - * @META_DEBUG_GROUPS: groups - * @META_DEBUG_RESIZING: resizing - * @META_DEBUG_SHAPES: shapes - * @META_DEBUG_EDGE_RESISTANCE: edge resistance - * @META_DEBUG_WAYLAND: Wayland - * @META_DEBUG_KMS: kernel mode setting - * @META_DEBUG_SCREEN_CAST: screencasting - * @META_DEBUG_REMOTE_DESKTOP: remote desktop - * @META_DEBUG_BACKEND: backend - * @META_DEBUG_RENDER: native backend rendering - * @META_DEBUG_COLOR: color management - * @META_DEBUG_INPUT_EVENTS: input events - * @META_DEBUG_EIS: eis state - */ -typedef enum -{ - META_DEBUG_VERBOSE = -1, - META_DEBUG_FOCUS = 1 << 0, - META_DEBUG_WORKAREA = 1 << 1, - META_DEBUG_STACK = 1 << 2, - META_DEBUG_SM = 1 << 3, - META_DEBUG_EVENTS = 1 << 4, - META_DEBUG_WINDOW_STATE = 1 << 5, - META_DEBUG_WINDOW_OPS = 1 << 6, - META_DEBUG_GEOMETRY = 1 << 7, - META_DEBUG_PLACEMENT = 1 << 8, - META_DEBUG_PING = 1 << 9, - META_DEBUG_KEYBINDINGS = 1 << 10, - META_DEBUG_SYNC = 1 << 11, - META_DEBUG_STARTUP = 1 << 12, - META_DEBUG_PREFS = 1 << 13, - META_DEBUG_GROUPS = 1 << 14, - META_DEBUG_RESIZING = 1 << 15, - META_DEBUG_SHAPES = 1 << 16, - META_DEBUG_EDGE_RESISTANCE = 1 << 17, - META_DEBUG_DBUS = 1 << 18, - META_DEBUG_INPUT = 1 << 19, - META_DEBUG_WAYLAND = 1 << 20, - META_DEBUG_KMS = 1 << 21, - META_DEBUG_SCREEN_CAST = 1 << 22, - META_DEBUG_REMOTE_DESKTOP = 1 << 23, - META_DEBUG_BACKEND = 1 << 24, - META_DEBUG_RENDER = 1 << 25, - META_DEBUG_COLOR = 1 << 26, - META_DEBUG_INPUT_EVENTS = 1 << 27, - META_DEBUG_EIS = 1 << 28, -} MetaDebugTopic; - -/** * MetaDebugPaintFlag: * @META_DEBUG_PAINT_NONE: default * @META_DEBUG_PAINT_OPAQUE_REGION: paint opaque regions @@ -123,9 +59,6 @@ } MetaDebugPaintFlag; META_EXPORT -gboolean meta_is_topic_enabled (MetaDebugTopic topic); - -META_EXPORT void meta_add_verbose_topic (MetaDebugTopic topic); META_EXPORT @@ -155,44 +88,6 @@ META_EXPORT char* meta_g_utf8_strndup (const gchar *src, gsize n); -/* To disable verbose mode, we make these functions into no-ops */ -#ifdef WITH_VERBOSE_MODE - -const char * meta_topic_to_string (MetaDebugTopic topic); - -META_EXPORT -void meta_log (const char *format, ...) G_GNUC_PRINTF (1, 2); - -#define meta_topic(debug_topic, ...) \ - G_STMT_START \ - { \ - if (meta_is_topic_enabled (debug_topic)) \ - { \ - g_autofree char *_topic_message = NULL; \ -\ - _topic_message = g_strdup_printf (__VA_ARGS__); \ - meta_log ("%s: %s", meta_topic_to_string (debug_topic), \ - _topic_message); \ - } \ - } \ - G_STMT_END - -#define meta_verbose(...) meta_topic (META_DEBUG_VERBOSE, __VA_ARGS__) - -#else - -# ifdef G_HAVE_ISO_VARARGS -# define meta_verbose(...) -# define meta_topic(...) -# elif defined(G_HAVE_GNUC_VARARGS) -# define meta_verbose(format...) -# define meta_topic(format...) -# else -# error "This compiler does not support varargs macros and thus verbose mode can't be disabled meaningfully" -# endif - -#endif /* !WITH_VERBOSE_MODE */ - typedef enum { META_LOCALE_DIRECTION_LTR, diff -Nru mutter-46.0/src/tests/meta-wayland-test-driver.c mutter-46.1/src/tests/meta-wayland-test-driver.c --- mutter-46.0/src/tests/meta-wayland-test-driver.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/meta-wayland-test-driver.c 2024-04-19 17:48:34.000000000 +0000 @@ -163,6 +163,41 @@ } static void +on_window_shown (MetaWindow *window, + struct wl_resource *callback) +{ + g_signal_handlers_disconnect_by_data (window, callback); + wl_callback_send_done (callback, 0); +} + +static void +sync_window_shown (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWindow *window = meta_wayland_surface_get_window (surface); + struct wl_resource *callback; + + g_assert_nonnull (surface); + g_assert_nonnull (window); + + callback = wl_resource_create (client, &wl_callback_interface, 1, id); + + if (meta_window_is_hidden (window)) + { + g_signal_connect (meta_wayland_surface_get_window (surface), + "shown", G_CALLBACK (on_window_shown), + callback); + } + else + { + wl_callback_send_done (callback, 0); + } +} + +static void sync_point (struct wl_client *client, struct wl_resource *resource, uint32_t sequence, @@ -217,6 +252,7 @@ static const struct test_driver_interface meta_test_driver_interface = { sync_actor_destroy, sync_effects_completed, + sync_window_shown, sync_point, verify_view, }; diff -Nru mutter-46.0/src/tests/mtk/region-tests.c mutter-46.1/src/tests/mtk/region-tests.c --- mutter-46.0/src/tests/mtk/region-tests.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/mtk/region-tests.c 2024-04-19 17:48:34.000000000 +0000 @@ -26,7 +26,7 @@ { g_autoptr (MtkRegion) r1 = NULL; - r1 = mtk_region_create_rectangle (mtk_rectangle_new (0, 0, 100, 100)); + r1 = mtk_region_create_rectangle (&MTK_RECTANGLE_INIT (0, 0, 100, 100)); g_assert (!mtk_region_contains_point (r1, 200, 200)); g_assert (mtk_region_contains_point (r1, 50, 50)); diff -Nru mutter-46.0/src/tests/protocol/test-driver.xml mutter-46.1/src/tests/protocol/test-driver.xml --- mutter-46.0/src/tests/protocol/test-driver.xml 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/protocol/test-driver.xml 2024-04-19 17:48:34.000000000 +0000 @@ -11,6 +11,11 @@ + + + + + Binary files /tmp/tmpb6jtsu6r/mnObuSKbF5/mutter-46.0/src/tests/ref-tests/wayland_buffer_single-pixel-buffer_7.ref.png and /tmp/tmpb6jtsu6r/luFdu2vYj3/mutter-46.1/src/tests/ref-tests/wayland_buffer_single-pixel-buffer_7.ref.png differ Binary files /tmp/tmpb6jtsu6r/mnObuSKbF5/mutter-46.0/src/tests/ref-tests/wayland_buffer_single-pixel-buffer_8.ref.png and /tmp/tmpb6jtsu6r/luFdu2vYj3/mutter-46.1/src/tests/ref-tests/wayland_buffer_single-pixel-buffer_8.ref.png differ diff -Nru mutter-46.0/src/tests/wayland-test-clients/buffer-transform.c mutter-46.1/src/tests/wayland-test-clients/buffer-transform.c --- mutter-46.0/src/tests/wayland-test-clients/buffer-transform.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/buffer-transform.c 2024-04-19 17:48:34.000000000 +0000 @@ -22,11 +22,6 @@ #include "wayland-test-client-utils.h" -static WaylandDisplay *display; -static struct wl_surface *surface; -static struct xdg_surface *xdg_surface; -static struct xdg_toplevel *xdg_toplevel; - static gboolean waiting_for_configure = FALSE; static gboolean fullscreen = 0; static uint32_t window_width = 0; @@ -88,7 +83,9 @@ }; static void -draw_main (gboolean rotated) +draw_main (WaylandDisplay *display, + struct wl_surface *surface, + gboolean rotated) { static uint32_t color0 = 0xffffffff; static uint32_t color1 = 0xff00ffff; @@ -139,20 +136,22 @@ } static void -wait_for_configure (void) +wait_for_configure (WaylandDisplay *display) { waiting_for_configure = TRUE; while (waiting_for_configure || window_width == 0) - { - if (wl_display_dispatch (display->display) == -1) - exit (EXIT_FAILURE); - } + wayland_display_dispatch (display); } int main (int argc, char **argv) { + g_autoptr (WaylandDisplay) display = NULL; + struct xdg_toplevel *xdg_toplevel; + struct xdg_surface *xdg_surface; + struct wl_surface *surface; + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); surface = wl_compositor_create_surface (display->compositor); @@ -163,9 +162,9 @@ xdg_toplevel_set_fullscreen(xdg_toplevel, NULL); wl_surface_commit (surface); - wait_for_configure (); + wait_for_configure (display); - draw_main (FALSE); + draw_main (display, surface, FALSE); wl_surface_commit (surface); wait_for_effects_completed (display, surface); @@ -185,7 +184,7 @@ wl_surface_commit (surface); wait_for_view_verified (display, 3); - draw_main (TRUE); + draw_main (display, surface, TRUE); wl_surface_set_buffer_transform (surface, WL_OUTPUT_TRANSFORM_90); wl_surface_commit (surface); wait_for_view_verified (display, 4); @@ -202,7 +201,5 @@ wl_surface_commit (surface); wait_for_view_verified (display, 7); - g_clear_object (&display); - return EXIT_SUCCESS; } diff -Nru mutter-46.0/src/tests/wayland-test-clients/dma-buf-scanout.c mutter-46.1/src/tests/wayland-test-clients/dma-buf-scanout.c --- mutter-46.0/src/tests/wayland-test-clients/dma-buf-scanout.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/dma-buf-scanout.c 2024-04-19 17:48:34.000000000 +0000 @@ -55,11 +55,7 @@ WINDOW_STATE_FULLSCREEN, } WindowState; -static WaylandDisplay *display; - static struct wl_surface *surface; -static struct xdg_surface *xdg_surface; -static struct xdg_toplevel *xdg_toplevel; static GList *active_buffers; @@ -84,7 +80,7 @@ }; static void -init_surface (void) +init_surface (struct xdg_toplevel *xdg_toplevel) { xdg_toplevel_set_title (xdg_toplevel, "dma-buf-scanout-test"); xdg_toplevel_set_fullscreen (xdg_toplevel, NULL); @@ -92,8 +88,9 @@ } static void -draw_main (int width, - int height) +draw_main (WaylandDisplay *display, + int width, + int height) { WaylandBuffer *buffer; DmaBufFormat *format; @@ -140,9 +137,11 @@ int32_t height, struct wl_array *states) { + WaylandDisplay *display; g_assert (width > 0 || prev_width > 0); g_assert (height > 0 || prev_width > 0); + display = user_data; if (width > 0 && height > 0) { prev_width = width; @@ -156,7 +155,7 @@ window_state = parse_xdg_toplevel_state (states); - draw_main (width, height); + draw_main (display, width, height); } static void @@ -196,6 +195,7 @@ struct xdg_surface *xdg_surface, uint32_t serial) { + WaylandDisplay *display = user_data; struct wl_callback *frame_callback; xdg_surface_ack_configure (xdg_surface, serial); @@ -223,6 +223,10 @@ main (int argc, char **argv) { + g_autoptr (WaylandDisplay) display = NULL; + struct xdg_toplevel *xdg_toplevel; + struct xdg_surface *xdg_surface; + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); g_signal_connect (display, "sync-event", G_CALLBACK (on_sync_event), NULL); wl_display_roundtrip (display->display); @@ -230,21 +234,17 @@ surface = wl_compositor_create_surface (display->compositor); xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, surface); - xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL); + xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, display); xdg_toplevel = xdg_surface_get_toplevel (xdg_surface); - xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL); + xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, display); - init_surface (); + init_surface (xdg_toplevel); running = TRUE; while (running) - { - if (wl_display_dispatch (display->display) == -1) - return EXIT_FAILURE; - } + wayland_display_dispatch (display); g_list_free_full (active_buffers, (GDestroyNotify) g_object_unref); - g_object_unref (display); return EXIT_SUCCESS; } diff -Nru mutter-46.0/src/tests/wayland-test-clients/fractional-scale.c mutter-46.1/src/tests/wayland-test-clients/fractional-scale.c --- mutter-46.0/src/tests/wayland-test-clients/fractional-scale.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/fractional-scale.c 2024-04-19 17:48:34.000000000 +0000 @@ -23,12 +23,8 @@ #include "wayland-test-client-utils.h" -static WaylandDisplay *display; static struct wl_surface *surface; -static struct xdg_surface *xdg_surface; -static struct xdg_toplevel *xdg_toplevel; static struct wp_viewport *viewport; -static struct wp_fractional_scale_v1 *fractional_scale_obj; static gboolean running; static gboolean waiting_for_configure; @@ -43,6 +39,8 @@ struct wl_callback *callback, uint32_t time) { + WaylandDisplay *display = data; + wl_callback_destroy (callback); test_driver_sync_point (display->test_driver, sync_point++, NULL); } @@ -52,7 +50,7 @@ }; static void -maybe_redraw (void) +maybe_redraw (WaylandDisplay *display) { struct wl_callback *callback; uint32_t buffer_width; @@ -72,7 +70,7 @@ wp_viewport_set_destination (viewport, logical_width, logical_height); callback = wl_surface_frame (surface); - wl_callback_add_listener (callback, &frame_listener, NULL); + wl_callback_add_listener (callback, &frame_listener, display); wl_surface_commit (surface); @@ -112,10 +110,11 @@ struct xdg_surface *xdg_surface, uint32_t serial) { + WaylandDisplay *display = data; xdg_surface_ack_configure (xdg_surface, serial); waiting_for_configure = FALSE; - maybe_redraw (); + maybe_redraw (display); } static const struct xdg_surface_listener xdg_surface_listener = { @@ -126,6 +125,7 @@ struct wp_fractional_scale_v1 *fractional_scale_obj, uint32_t wire_scale) { + WaylandDisplay *display = data; float new_fractional_buffer_scale; new_fractional_buffer_scale = wire_scale / 120.0; @@ -136,7 +136,7 @@ fractional_buffer_scale = new_fractional_buffer_scale; waiting_for_scale = FALSE; - maybe_redraw (); + maybe_redraw (display); } static const struct wp_fractional_scale_v1_listener fractional_scale_listener = { @@ -147,11 +147,16 @@ main (int argc, char **argv) { + g_autoptr (WaylandDisplay) display = NULL; + struct xdg_toplevel *xdg_toplevel; + struct xdg_surface *xdg_surface; + struct wp_fractional_scale_v1 *fractional_scale_obj; + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); surface = wl_compositor_create_surface (display->compositor); xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, surface); - xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL); + xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, display); xdg_toplevel = xdg_surface_get_toplevel (xdg_surface); xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL); xdg_toplevel_set_title (xdg_toplevel, "fractional-scale"); @@ -163,7 +168,7 @@ surface); wp_fractional_scale_v1_add_listener (fractional_scale_obj, &fractional_scale_listener, - NULL); + display); wl_surface_commit (surface); @@ -172,10 +177,7 @@ running = TRUE; while (running) - { - if (wl_display_dispatch (display->display) == -1) - return EXIT_FAILURE; - } + wayland_display_dispatch (display); wl_display_roundtrip (display->display); diff -Nru mutter-46.0/src/tests/wayland-test-clients/fullscreen.c mutter-46.1/src/tests/wayland-test-clients/fullscreen.c --- mutter-46.0/src/tests/wayland-test-clients/fullscreen.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/fullscreen.c 2024-04-19 17:48:34.000000000 +0000 @@ -24,11 +24,7 @@ #include "wayland-test-client-utils.h" -static WaylandDisplay *display; - static struct wl_surface *surface; -static struct xdg_surface *xdg_surface; -static struct xdg_toplevel *xdg_toplevel; static gboolean running; @@ -58,6 +54,8 @@ struct xdg_surface *xdg_surface, uint32_t serial) { + WaylandDisplay *display = data; + draw_surface (display, surface, 10, 10, 0x1f109f20); xdg_surface_ack_configure (xdg_surface, serial); wl_surface_commit (surface); @@ -81,12 +79,16 @@ main (int argc, char **argv) { + g_autoptr (WaylandDisplay) display = NULL; + struct xdg_toplevel *xdg_toplevel; + struct xdg_surface *xdg_surface; + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); g_signal_connect (display, "sync-event", G_CALLBACK (on_sync_event), NULL); surface = wl_compositor_create_surface (display->compositor); xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, surface); - xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL); + xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, display); xdg_toplevel = xdg_surface_get_toplevel (xdg_surface); xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL); xdg_toplevel_set_title (xdg_toplevel, "fullscreen"); @@ -95,10 +97,7 @@ running = TRUE; while (running) - { - if (wl_display_dispatch (display->display) == -1) - return EXIT_FAILURE; - } + wayland_display_dispatch (display); wl_display_roundtrip (display->display); diff -Nru mutter-46.0/src/tests/wayland-test-clients/idle-inhibit.c mutter-46.1/src/tests/wayland-test-clients/idle-inhibit.c --- mutter-46.0/src/tests/wayland-test-clients/idle-inhibit.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/idle-inhibit.c 2024-04-19 17:48:34.000000000 +0000 @@ -24,7 +24,6 @@ #include "idle-inhibit-unstable-v1-client-protocol.h" -static WaylandDisplay *display; struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager; static void @@ -59,7 +58,8 @@ char **argv) { struct wl_registry *registry; - WaylandSurface *surface; + g_autoptr (WaylandDisplay) display = NULL; + g_autoptr (WaylandSurface) surface = NULL; struct zwp_idle_inhibitor_v1 *inhibitor; display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); diff -Nru mutter-46.0/src/tests/wayland-test-clients/invalid-subsurfaces.c mutter-46.1/src/tests/wayland-test-clients/invalid-subsurfaces.c --- mutter-46.0/src/tests/wayland-test-clients/invalid-subsurfaces.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/invalid-subsurfaces.c 2024-04-19 17:48:34.000000000 +0000 @@ -24,33 +24,16 @@ #include "wayland-test-client-utils.h" -static WaylandDisplay *display; - -static void -connect_to_display (void) -{ - g_assert_null (display); - - display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_NONE); - g_assert_nonnull (display); -} - -static void -clean_up_display (void) -{ - g_clear_object (&display); -} - static void test_circular_subsurfaces1 (void) { + g_autoptr (WaylandDisplay) display = NULL; struct wl_surface *surface1; struct wl_subsurface *subsurface1; struct wl_surface *surface2; struct wl_subsurface *subsurface2; - connect_to_display (); - + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_NONE); surface1 = wl_compositor_create_surface (display->compositor); surface2 = wl_compositor_create_surface (display->compositor); g_assert_nonnull (surface1); @@ -66,13 +49,12 @@ g_assert_nonnull (subsurface2); g_assert_cmpint (wl_display_roundtrip (display->display), ==, -1); - - clean_up_display (); } static void test_circular_subsurfaces2 (void) { + g_autoptr (WaylandDisplay) display = NULL; struct wl_surface *surface1; struct wl_subsurface *subsurface1; struct wl_surface *surface2; @@ -80,7 +62,7 @@ struct wl_surface *surface3; struct wl_subsurface *subsurface3; - connect_to_display (); + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_NONE); surface1 = wl_compositor_create_surface (display->compositor); surface2 = wl_compositor_create_surface (display->compositor); @@ -103,8 +85,6 @@ g_assert_nonnull (subsurface3); g_assert_cmpint (wl_display_roundtrip (display->display), ==, -1); - - clean_up_display (); } int diff -Nru mutter-46.0/src/tests/wayland-test-clients/invalid-xdg-shell-actions.c mutter-46.1/src/tests/wayland-test-clients/invalid-xdg-shell-actions.c --- mutter-46.0/src/tests/wayland-test-clients/invalid-xdg-shell-actions.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/invalid-xdg-shell-actions.c 2024-04-19 17:48:34.000000000 +0000 @@ -22,23 +22,19 @@ #include "wayland-test-client-utils.h" -static WaylandDisplay *display; - static struct wl_surface *surface; -static struct xdg_surface *xdg_surface; -static struct xdg_toplevel *xdg_toplevel; static gboolean running; static void -init_surface (void) +init_surface (struct xdg_toplevel *xdg_toplevel) { xdg_toplevel_set_title (xdg_toplevel, "bogus window geometry"); wl_surface_commit (surface); } static void -draw_main (void) +draw_main (WaylandDisplay *display) { draw_surface (display, surface, 700, 500, 0xff00ff00); } @@ -69,13 +65,14 @@ struct xdg_surface *xdg_surface, uint32_t serial) { + WaylandDisplay *display = data; static gboolean sent_invalid_once = FALSE; if (sent_invalid_once) return; xdg_surface_set_window_geometry (xdg_surface, 0, 0, 0, 0); - draw_main (); + draw_main (display); wl_surface_commit (surface); sent_invalid_once = TRUE; @@ -91,15 +88,19 @@ static void test_empty_window_geometry (void) { + g_autoptr (WaylandDisplay) display = NULL; + struct xdg_toplevel *xdg_toplevel; + struct xdg_surface *xdg_surface; + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_NONE); surface = wl_compositor_create_surface (display->compositor); xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, surface); - xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL); + xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, display); xdg_toplevel = xdg_surface_get_toplevel (xdg_surface); xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL); - init_surface (); + init_surface (xdg_toplevel); running = TRUE; while (running) @@ -110,7 +111,6 @@ g_clear_pointer (&xdg_toplevel, xdg_toplevel_destroy); g_clear_pointer (&xdg_surface, xdg_surface_destroy); - g_clear_object (&display); } int diff -Nru mutter-46.0/src/tests/wayland-test-clients/kms-cursor-hotplug-helper.c mutter-46.1/src/tests/wayland-test-clients/kms-cursor-hotplug-helper.c --- mutter-46.0/src/tests/wayland-test-clients/kms-cursor-hotplug-helper.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/kms-cursor-hotplug-helper.c 2024-04-19 17:48:34.000000000 +0000 @@ -23,33 +23,28 @@ #include "wayland-test-client-utils.h" -static WaylandDisplay *display; - -static struct wl_registry *wl_registry; static struct wl_seat *wl_seat; static struct wl_pointer *wl_pointer; static uint32_t enter_serial; static struct wl_surface *surface; -static struct xdg_surface *xdg_surface; -static struct xdg_toplevel *xdg_toplevel; struct wl_surface *cursor_surface; -struct wl_cursor_theme *cursor_theme; struct wl_cursor *cursor; struct wl_cursor *cursor2; static gboolean running; static void -init_surface (void) +init_surface (struct xdg_toplevel *xdg_toplevel) { xdg_toplevel_set_title (xdg_toplevel, "kms-cursor-hotplug-helper"); wl_surface_commit (surface); } static void -draw_main (int width, - int height) +draw_main (WaylandDisplay *display, + int width, + int height) { draw_surface (display, surface, width, height, 0xff00ff00); } @@ -89,7 +84,9 @@ struct xdg_surface *xdg_surface, uint32_t serial) { - draw_main (100, 100); + WaylandDisplay *display = data; + + draw_main (display, 100, 100); xdg_surface_ack_configure (xdg_surface, serial); wl_surface_commit (surface); } @@ -251,6 +248,12 @@ main (int argc, char **argv) { + g_autoptr (WaylandDisplay) display = NULL; + struct wl_registry *wl_registry; + struct xdg_toplevel *xdg_toplevel; + struct xdg_surface *xdg_surface; + struct wl_cursor_theme *cursor_theme; + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); wl_registry = wl_display_get_registry (display->display); wl_registry_add_listener (wl_registry, ®istry_listener, display); @@ -260,7 +263,7 @@ surface = wl_compositor_create_surface (display->compositor); xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, surface); - xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL); + xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, display); xdg_toplevel = xdg_surface_get_toplevel (xdg_surface); xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL); @@ -271,15 +274,12 @@ g_assert_nonnull (cursor); g_assert_nonnull (cursor2); - init_surface (); + init_surface (xdg_toplevel); wl_surface_commit (surface); running = TRUE; while (running) - { - if (wl_display_dispatch (display->display) == -1) - return EXIT_FAILURE; - } + wayland_display_dispatch (display); return EXIT_SUCCESS; } diff -Nru mutter-46.0/src/tests/wayland-test-clients/meson.build mutter-46.1/src/tests/wayland-test-clients/meson.build --- mutter-46.0/src/tests/wayland-test-clients/meson.build 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/meson.build 2024-04-19 17:48:34.000000000 +0000 @@ -67,6 +67,9 @@ 'name': 'subsurface-reparenting', }, { + 'name': 'toplevel-show-states', + }, + { 'name': 'xdg-activation', }, { @@ -79,6 +82,9 @@ 'name': 'xdg-toplevel-bounds', }, { + 'name': 'xdg-toplevel-suspended', + }, + { 'name': 'ycbcr', }, ] diff -Nru mutter-46.0/src/tests/wayland-test-clients/service-client.c mutter-46.1/src/tests/wayland-test-clients/service-client.c --- mutter-46.0/src/tests/wayland-test-clients/service-client.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/service-client.c 2024-04-19 17:48:34.000000000 +0000 @@ -88,10 +88,7 @@ wl_surface_commit (surface->wl_surface); while (last_sync_event != 1) - { - if (wl_display_dispatch (display->display) == -1) - return EXIT_FAILURE; - } + wayland_display_dispatch (display); g_object_unref (surface); g_object_unref (display); diff -Nru mutter-46.0/src/tests/wayland-test-clients/single-pixel-buffer.c mutter-46.1/src/tests/wayland-test-clients/single-pixel-buffer.c --- mutter-46.0/src/tests/wayland-test-clients/single-pixel-buffer.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/single-pixel-buffer.c 2024-04-19 17:48:34.000000000 +0000 @@ -22,13 +22,7 @@ #include "wayland-test-client-utils.h" -static WaylandDisplay *display; -static struct wl_surface *surface; -static struct xdg_surface *xdg_surface; -static struct xdg_toplevel *xdg_toplevel; static struct wl_buffer *buffer; -static struct wl_surface *subsurface_surface; -static struct wl_subsurface *subsurface; static gboolean waiting_for_configure = FALSE; static gboolean fullscreen = 0; @@ -91,14 +85,11 @@ }; static void -wait_for_configure (void) +wait_for_configure (WaylandDisplay *display) { waiting_for_configure = TRUE; while (waiting_for_configure || window_width == 0) - { - if (wl_display_dispatch (display->display) == -1) - exit (EXIT_FAILURE); - } + wayland_display_dispatch (display); } static void @@ -114,21 +105,24 @@ }; static void -wait_for_buffer_released (void) +wait_for_buffer_released (WaylandDisplay *display) { while (buffer) - { - if (wl_display_dispatch (display->display) == -1) - g_error ("%s: Failed to dispatch Wayland display", __func__); - } + wayland_display_dispatch (display); } int main (int argc, char **argv) { + g_autoptr (WaylandDisplay) display = NULL; struct wp_viewport *viewport; struct wp_viewport *subsurface_viewport; + struct xdg_toplevel *xdg_toplevel; + struct xdg_surface *xdg_surface; + struct wl_surface *subsurface_surface; + struct wl_subsurface *subsurface; + struct wl_surface *surface; display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); @@ -140,7 +134,7 @@ xdg_toplevel_set_fullscreen (xdg_toplevel, NULL); wl_surface_commit (surface); - wait_for_configure (); + wait_for_configure (display); viewport = wp_viewporter_get_viewport (display->viewporter, surface); wp_viewport_set_destination (viewport, window_width, window_height); @@ -157,7 +151,7 @@ wait_for_effects_completed (display, surface); wait_for_view_verified (display, 0); - wait_for_buffer_released (); + wait_for_buffer_released (display); subsurface_surface = wl_compositor_create_surface (display->compositor); subsurface = wl_subcompositor_get_subsurface (display->subcompositor, @@ -184,7 +178,7 @@ wl_surface_commit (subsurface_surface); wait_for_view_verified (display, 1); - wait_for_buffer_released (); + wait_for_buffer_released (display); buffer = wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, @@ -197,7 +191,7 @@ wl_surface_commit (subsurface_surface); wait_for_view_verified (display, 0); - wait_for_buffer_released (); + wait_for_buffer_released (display); buffer = wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, @@ -210,7 +204,7 @@ wl_surface_commit (subsurface_surface); wait_for_view_verified (display, 2); - wait_for_buffer_released (); + wait_for_buffer_released (display); buffer = wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, @@ -223,7 +217,7 @@ wl_surface_commit (subsurface_surface); wait_for_view_verified (display, 3); - wait_for_buffer_released (); + wait_for_buffer_released (display); buffer = wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, @@ -236,7 +230,7 @@ wl_surface_commit (subsurface_surface); wait_for_view_verified (display, 4); - wait_for_buffer_released (); + wait_for_buffer_released (display); buffer = wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, @@ -249,7 +243,7 @@ wl_surface_commit (subsurface_surface); wait_for_view_verified (display, 5); - wait_for_buffer_released (); + wait_for_buffer_released (display); buffer = wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, @@ -262,9 +256,43 @@ wl_surface_commit (subsurface_surface); wait_for_view_verified (display, 6); - wait_for_buffer_released (); + wait_for_buffer_released (display); + + /* Test reuse */ + + buffer = + wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (display->single_pixel_mgr, + 0x70707070, + 0x00000000, + 0x70707070, + 0x70707070); + wl_surface_attach (subsurface_surface, buffer, 0, 0); + wl_surface_commit (subsurface_surface); + wait_for_view_verified (display, 7); + + wl_subsurface_destroy (subsurface); + wl_surface_destroy (subsurface_surface); + + subsurface_surface = wl_compositor_create_surface (display->compositor); + subsurface = wl_subcompositor_get_subsurface (display->subcompositor, + subsurface_surface, + surface); + wl_subsurface_set_desync (subsurface); + wl_subsurface_set_position (subsurface, 30, 30); + wl_surface_commit (surface); + + subsurface_viewport = wp_viewporter_get_viewport (display->viewporter, + subsurface_surface); + wp_viewport_set_destination (subsurface_viewport, + window_width - 60, + window_height - 60); + + wl_buffer_add_listener (buffer, &buffer_listener, NULL); + wl_surface_attach (subsurface_surface, buffer, 0, 0); + wl_surface_commit (subsurface_surface); + wait_for_view_verified (display, 8); - g_clear_object (&display); + wait_for_buffer_released (display); return EXIT_SUCCESS; } diff -Nru mutter-46.0/src/tests/wayland-test-clients/subsurface-corner-cases.c mutter-46.1/src/tests/wayland-test-clients/subsurface-corner-cases.c --- mutter-46.0/src/tests/wayland-test-clients/subsurface-corner-cases.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/subsurface-corner-cases.c 2024-04-19 17:48:34.000000000 +0000 @@ -22,12 +22,6 @@ #include "wayland-test-client-utils.h" -static WaylandDisplay *display; -static struct wl_surface *toplevel_surface, *child_surface, *grandchild_surface; -static struct wl_subsurface *child, *grandchild; -static struct xdg_surface *xdg_surface; -static struct xdg_toplevel *xdg_toplevel; - static gboolean waiting_for_configure = FALSE; static gboolean fullscreen = 0; static uint32_t window_width = 0; @@ -75,7 +69,8 @@ }; static void -draw_toplevel (void) +draw_toplevel (WaylandDisplay *display, + struct wl_surface *toplevel_surface) { draw_surface (display, toplevel_surface, window_width, window_height, @@ -97,7 +92,8 @@ }; static void -draw_child (void) +draw_child (WaylandDisplay *display, + struct wl_surface *child_surface) { draw_surface (display, child_surface, window_width / 2, window_height / 2, @@ -105,7 +101,8 @@ } static void -draw_grandchild (void) +draw_grandchild (WaylandDisplay *display, + struct wl_surface *grandchild_surface) { draw_surface (display, grandchild_surface, window_width / 2, window_height / 2, @@ -113,20 +110,23 @@ } static void -wait_for_configure (void) +wait_for_configure (WaylandDisplay *display) { waiting_for_configure = TRUE; while (waiting_for_configure || window_width == 0) - { - if (wl_display_dispatch (display->display) == -1) - exit (EXIT_FAILURE); - } + wayland_display_dispatch (display); } int main (int argc, char **argv) { + g_autoptr (WaylandDisplay) display = NULL; + struct xdg_toplevel *xdg_toplevel; + struct xdg_surface *xdg_surface; + struct wl_surface *toplevel_surface, *child_surface, *grandchild_surface; + struct wl_subsurface *child, *grandchild; + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); toplevel_surface = wl_compositor_create_surface (display->compositor); @@ -138,9 +138,9 @@ xdg_toplevel_set_fullscreen (xdg_toplevel, NULL); wl_surface_commit (toplevel_surface); - wait_for_configure (); + wait_for_configure (display); - draw_toplevel (); + draw_toplevel (display, toplevel_surface); wl_surface_commit (toplevel_surface); wait_for_effects_completed (display, toplevel_surface); @@ -148,7 +148,7 @@ child = wl_subcompositor_get_subsurface (display->subcompositor, child_surface, toplevel_surface); - draw_child (); + draw_child (display, child_surface); wl_surface_commit (child_surface); /* No toplevel commit → sub-surface must not be mapped yet */ wait_for_view_verified (display, 0); @@ -174,7 +174,7 @@ /* Toplevel commit → sub-surface must be unmapped */ wait_for_view_verified (display, 5); - draw_child (); + draw_child (display, child_surface); wl_surface_commit (child_surface); wl_subsurface_set_desync (child); wl_surface_attach (child_surface, NULL, 0, 0); @@ -182,7 +182,7 @@ /* Desync sub-surface must have been unmapped */ wait_for_view_verified (display, 6); - draw_child (); + draw_child (display, child_surface); wl_surface_commit (child_surface); wl_subsurface_set_sync (child); wl_subsurface_destroy (child); @@ -192,7 +192,7 @@ child = wl_subcompositor_get_subsurface (display->subcompositor, child_surface, toplevel_surface); - draw_child (); + draw_child (display, child_surface); wl_surface_commit (child_surface); /* No toplevel commit → sub-surface must not be mapped yet */ wait_for_view_verified (display, 8); @@ -209,7 +209,7 @@ child = wl_subcompositor_get_subsurface (display->subcompositor, child_surface, toplevel_surface); - draw_child (); + draw_child (display, child_surface); wl_surface_commit (child_surface); wl_surface_commit (toplevel_surface); /* New sub-surface → placement below toplevel must not have taken effect */ @@ -219,7 +219,7 @@ grandchild = wl_subcompositor_get_subsurface (display->subcompositor, grandchild_surface, child_surface); - draw_grandchild (); + draw_grandchild (display, grandchild_surface); wl_subsurface_set_position (grandchild, window_width / 4, window_height / 4); wl_surface_commit (grandchild_surface); wl_surface_commit (child_surface); @@ -236,7 +236,7 @@ grandchild = wl_subcompositor_get_subsurface (display->subcompositor, grandchild_surface, child_surface); - draw_grandchild (); + draw_grandchild (display, grandchild_surface); wl_subsurface_set_position (grandchild, window_width / 4, window_height / 4); wl_surface_commit (grandchild_surface); wl_surface_commit (child_surface); @@ -244,7 +244,5 @@ /* New grandchild must be placed above its parent */ wait_for_view_verified (display, 14); - g_clear_object (&display); - return EXIT_SUCCESS; } diff -Nru mutter-46.0/src/tests/wayland-test-clients/subsurface-parent-unmapped.c mutter-46.1/src/tests/wayland-test-clients/subsurface-parent-unmapped.c --- mutter-46.0/src/tests/wayland-test-clients/subsurface-parent-unmapped.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/subsurface-parent-unmapped.c 2024-04-19 17:48:34.000000000 +0000 @@ -23,36 +23,32 @@ #include "wayland-test-client-utils.h" -static WaylandDisplay *display; -static struct wl_registry *registry; static struct wl_seat *seat; static struct wl_pointer *pointer; static struct wl_surface *toplevel_surface; static struct xdg_surface *toplevel_xdg_surface; -static struct xdg_toplevel *xdg_toplevel; static struct wl_surface *popup_surface; static struct xdg_surface *popup_xdg_surface; static struct xdg_popup *xdg_popup; static struct wl_surface *subsurface_surface; -static struct wl_subsurface *subsurface; static void -draw_main (void) +draw_main (WaylandDisplay *display) { draw_surface (display, toplevel_surface, 200, 200, 0xff00ffff); } static void -draw_popup (void) +draw_popup (WaylandDisplay *display) { draw_surface (display, popup_surface, 100, 100, 0xff005500); } static void -draw_subsurface (void) +draw_subsurface (WaylandDisplay *display) { draw_surface (display, subsurface_surface, 100, 50, 0xff001f00); } @@ -83,8 +79,10 @@ struct xdg_surface *xdg_surface, uint32_t serial) { + WaylandDisplay *display = data; + xdg_surface_ack_configure (xdg_surface, serial); - draw_main (); + draw_main (display); wl_surface_commit (toplevel_surface); wl_display_flush (display->display); } @@ -125,6 +123,8 @@ struct wl_callback *callback, uint32_t time) { + WaylandDisplay *display = data; + wl_callback_destroy (callback); test_driver_sync_point (display->test_driver, 0, popup_surface); } @@ -138,16 +138,17 @@ struct xdg_surface *xdg_surface, uint32_t serial) { + WaylandDisplay *display = data; struct wl_callback *frame_callback; - draw_popup (); + draw_popup (display); - draw_subsurface (); + draw_subsurface (display); wl_surface_commit (subsurface_surface); xdg_surface_ack_configure (xdg_surface, serial); frame_callback = wl_surface_frame (popup_surface); - wl_callback_add_listener (frame_callback, &frame_listener, NULL); + wl_callback_add_listener (frame_callback, &frame_listener, display); wl_surface_commit (popup_surface); wl_display_flush (display->display); } @@ -164,6 +165,7 @@ uint32_t button, uint32_t state) { + WaylandDisplay *display = data; struct xdg_positioner *positioner; static int click_count = 0; @@ -174,7 +176,7 @@ popup_xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, popup_surface); xdg_surface_add_listener (popup_xdg_surface, - &popup_xdg_surface_listener, NULL); + &popup_xdg_surface_listener, display); positioner = xdg_wm_base_create_positioner (display->xdg_wm_base); xdg_positioner_set_size (positioner, 100, 100); xdg_positioner_set_anchor_rect (positioner, 0, 0, 1, 1); @@ -219,10 +221,12 @@ struct wl_seat *wl_seat, enum wl_seat_capability caps) { + WaylandDisplay *display = data; + if (caps & WL_SEAT_CAPABILITY_POINTER) { pointer = wl_seat_get_pointer (wl_seat); - wl_pointer_add_listener (pointer, &pointer_listener, NULL); + wl_pointer_add_listener (pointer, &pointer_listener, display); } } @@ -263,10 +267,12 @@ const char *interface, uint32_t version) { + WaylandDisplay *display = data; + if (strcmp (interface, "wl_seat") == 0) { seat = wl_registry_bind (registry, id, &wl_seat_interface, 1); - wl_seat_add_listener (seat, &seat_listener, NULL); + wl_seat_add_listener (seat, &seat_listener, display); } } @@ -286,12 +292,17 @@ main (int argc, char **argv) { + g_autoptr (WaylandDisplay) display = NULL; + struct wl_registry *registry; + struct xdg_toplevel *xdg_toplevel; + struct wl_subsurface *subsurface; + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); g_signal_connect (display, "sync-event", G_CALLBACK (on_sync_event), NULL); registry = wl_display_get_registry (display->display); - wl_registry_add_listener (registry, ®istry_listener, NULL); + wl_registry_add_listener (registry, ®istry_listener, display); wl_display_roundtrip (display->display); wl_display_roundtrip (display->display); @@ -311,7 +322,7 @@ toplevel_xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, toplevel_surface); xdg_surface_add_listener (toplevel_xdg_surface, - &toplevel_xdg_surface_listener, NULL); + &toplevel_xdg_surface_listener, display); xdg_toplevel = xdg_surface_get_toplevel (toplevel_xdg_surface); xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL); xdg_toplevel_set_title (xdg_toplevel, "subsurface-parent-unmapped"); @@ -326,12 +337,7 @@ wl_subsurface_set_desync (subsurface); while (TRUE) - { - if (wl_display_dispatch (display->display) == -1) - return EXIT_FAILURE; - } - - g_clear_object (&display); + wayland_display_dispatch (display); return EXIT_SUCCESS; } diff -Nru mutter-46.0/src/tests/wayland-test-clients/subsurface-remap-toplevel.c mutter-46.1/src/tests/wayland-test-clients/subsurface-remap-toplevel.c --- mutter-46.0/src/tests/wayland-test-clients/subsurface-remap-toplevel.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/subsurface-remap-toplevel.c 2024-04-19 17:48:34.000000000 +0000 @@ -32,13 +32,9 @@ STATE_WAIT_FOR_FRAME_2 } State; -static WaylandDisplay *display; - static struct wl_surface *surface; -static struct xdg_surface *xdg_surface; static struct xdg_toplevel *xdg_toplevel; -static struct wl_surface *subsurface_surface; static struct wl_subsurface *subsurface; static struct wl_callback *frame_callback; @@ -72,7 +68,7 @@ }; static void -reset_surface (void) +reset_surface (WaylandDisplay *display) { struct wl_callback *callback; @@ -86,13 +82,14 @@ } static void -draw_main (void) +draw_main (WaylandDisplay *display) { draw_surface (display, surface, 700, 500, 0xff00ff00); } static void -draw_subsurface (void) +draw_subsurface (WaylandDisplay *display, + struct wl_surface *subsurface_surface) { draw_surface (display, subsurface_surface, 500, 300, 0xff007f00); } @@ -123,10 +120,11 @@ struct wl_callback *callback, uint32_t time) { + WaylandDisplay *display = data; switch (state) { case STATE_WAIT_FOR_FRAME_1: - reset_surface (); + reset_surface (display); break; case STATE_WAIT_FOR_FRAME_2: exit (EXIT_SUCCESS); @@ -150,16 +148,17 @@ struct xdg_surface *xdg_surface, uint32_t serial) { + WaylandDisplay *display = data; switch (state) { case STATE_INIT: g_assert_not_reached (); case STATE_WAIT_FOR_CONFIGURE_1: - draw_main (); + draw_main (display); state = STATE_WAIT_FOR_FRAME_1; break; case STATE_WAIT_FOR_CONFIGURE_2: - draw_main (); + draw_main (display); state = STATE_WAIT_FOR_FRAME_2; break; case STATE_WAIT_FOR_ACTOR_DESTROYED: @@ -172,7 +171,7 @@ xdg_surface_ack_configure (xdg_surface, serial); frame_callback = wl_surface_frame (surface); - wl_callback_add_listener (frame_callback, &frame_listener, NULL); + wl_callback_add_listener (frame_callback, &frame_listener, display); wl_surface_commit (surface); wl_display_flush (display->display); } @@ -185,11 +184,15 @@ main (int argc, char **argv) { + g_autoptr (WaylandDisplay) display = NULL; + struct xdg_surface *xdg_surface; + struct wl_surface *subsurface_surface; + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); surface = wl_compositor_create_surface (display->compositor); xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, surface); - xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL); + xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, display); xdg_toplevel = xdg_surface_get_toplevel (xdg_surface); xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL); @@ -198,7 +201,7 @@ subsurface_surface, surface); wl_subsurface_set_position (subsurface, 100, 100); - draw_subsurface (); + draw_subsurface (display, subsurface_surface); wl_surface_commit (subsurface_surface); init_surface (); @@ -206,12 +209,7 @@ running = TRUE; while (running) - { - if (wl_display_dispatch (display->display) == -1) - return EXIT_FAILURE; - } - - g_clear_object (&display); + wayland_display_dispatch (display); return EXIT_SUCCESS; } diff -Nru mutter-46.0/src/tests/wayland-test-clients/subsurface-reparenting.c mutter-46.1/src/tests/wayland-test-clients/subsurface-reparenting.c --- mutter-46.0/src/tests/wayland-test-clients/subsurface-reparenting.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/subsurface-reparenting.c 2024-04-19 17:48:34.000000000 +0000 @@ -34,8 +34,6 @@ STATE_WAIT_FOR_FRAME_3 } State; -static WaylandDisplay *display; - static struct wl_surface *surface; static struct xdg_surface *xdg_surface; static struct xdg_toplevel *xdg_toplevel; @@ -47,16 +45,16 @@ static State state; -static void init_surfaces (void); +static void init_surfaces (WaylandDisplay *display); static void -draw_main (void) +draw_main (WaylandDisplay *display) { draw_surface (display, surface, 700, 500, 0xff00ff00); } static void -draw_subsurface (void) +draw_subsurface (WaylandDisplay *display) { draw_surface (display, subsurface_surface, 500, 300, 0xff007f00); } @@ -87,10 +85,11 @@ struct wl_callback *callback, uint32_t serial) { + WaylandDisplay *display = data; g_assert_cmpint (state, ==, STATE_WAIT_FOR_ACTOR_DESTROYED); wl_subsurface_destroy (subsurface); - init_surfaces (); + init_surfaces (display); state = STATE_WAIT_FOR_CONFIGURE_2; wl_callback_destroy (callback); @@ -101,12 +100,12 @@ }; static void -reset_surface (void) +reset_surface (WaylandDisplay *display) { struct wl_callback *callback; callback = test_driver_sync_actor_destroyed (display->test_driver, surface); - wl_callback_add_listener (callback, &actor_destroy_listener, NULL); + wl_callback_add_listener (callback, &actor_destroy_listener, display); xdg_toplevel_destroy (xdg_toplevel); xdg_surface_destroy (xdg_surface); @@ -120,10 +119,12 @@ struct wl_callback *callback, uint32_t time) { + WaylandDisplay *display = data; + switch (state) { case STATE_WAIT_FOR_FRAME_1: - reset_surface (); + reset_surface (display); break; case STATE_WAIT_FOR_FRAME_2: exit (EXIT_SUCCESS); @@ -141,16 +142,18 @@ struct xdg_surface *xdg_surface, uint32_t serial) { + WaylandDisplay *display = data; + switch (state) { case STATE_INIT: g_assert_not_reached (); case STATE_WAIT_FOR_CONFIGURE_1: - draw_main (); + draw_main (display); state = STATE_WAIT_FOR_FRAME_1; break; case STATE_WAIT_FOR_CONFIGURE_2: - draw_main (); + draw_main (display); state = STATE_WAIT_FOR_FRAME_2; break; default: @@ -160,7 +163,7 @@ xdg_surface_ack_configure (xdg_surface, serial); frame_callback = wl_surface_frame (surface); - wl_callback_add_listener (frame_callback, &frame_listener, NULL); + wl_callback_add_listener (frame_callback, &frame_listener, display); wl_surface_commit (surface); wl_display_flush (display->display); } @@ -170,11 +173,11 @@ }; static void -init_surfaces (void) +init_surfaces (WaylandDisplay *display) { surface = wl_compositor_create_surface (display->compositor); xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, surface); - xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL); + xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, display); xdg_toplevel = xdg_surface_get_toplevel (xdg_surface); xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL); xdg_toplevel_set_title (xdg_toplevel, "subsurface-reparenting-test"); @@ -190,20 +193,18 @@ main (int argc, char **argv) { + g_autoptr (WaylandDisplay) display = NULL; display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); subsurface_surface = wl_compositor_create_surface (display->compositor); - draw_subsurface (); + draw_subsurface (display); wl_surface_commit (subsurface_surface); - init_surfaces (); + init_surfaces (display); state = STATE_WAIT_FOR_CONFIGURE_1; while (TRUE) - { - if (wl_display_dispatch (display->display) == -1) - return EXIT_FAILURE; - } + wayland_display_dispatch (display); return EXIT_SUCCESS; } diff -Nru mutter-46.0/src/tests/wayland-test-clients/toplevel-show-states.c mutter-46.1/src/tests/wayland-test-clients/toplevel-show-states.c --- mutter-46.0/src/tests/wayland-test-clients/toplevel-show-states.c 1970-01-01 00:00:00.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/toplevel-show-states.c 2024-04-19 17:48:34.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2024 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "config.h" + +#include +#include + +#include "wayland-test-client-utils.h" + +static gboolean running; + +static void +on_surface_painted (WaylandDisplay *display, + WaylandSurface *surface) +{ + test_driver_sync_point (display->test_driver, 1, NULL); + wl_display_roundtrip (display->display); + running = FALSE; +} + +int +main (int argc, + char **argv) +{ + g_autoptr (WaylandDisplay) display = NULL; + g_autoptr (WaylandSurface) surface = NULL; + + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER | + WAYLAND_DISPLAY_CAPABILITY_XDG_SHELL_V6); + surface = wayland_surface_new (display, "showing-states", 100, 100, 0xffffffff); + wl_surface_commit (surface->wl_surface); + + test_driver_sync_point (display->test_driver, 0, NULL); + wait_for_sync_event (display, 0); + + g_signal_connect (display, "surface-painted", + G_CALLBACK (on_surface_painted), NULL); + + running = TRUE; + while (running) + wayland_display_dispatch (display); + + return EXIT_SUCCESS; +} diff -Nru mutter-46.0/src/tests/wayland-test-clients/wayland-test-client-utils.c mutter-46.1/src/tests/wayland-test-clients/wayland-test-client-utils.c --- mutter-46.0/src/tests/wayland-test-clients/wayland-test-client-utils.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/wayland-test-client-utils.c 2024-04-19 17:48:34.000000000 +0000 @@ -38,11 +38,13 @@ enum { SYNC_EVENT, + SURFACE_PAINTED, N_SIGNALS }; static guint signals[N_SIGNALS]; static struct wl_callback *effects_complete_callback; +static struct wl_callback *window_shown_callback; static struct wl_callback *view_verification_callback; struct _WaylandBufferClass @@ -345,6 +347,9 @@ if (display->capabilities & WAYLAND_DISPLAY_CAPABILITY_XDG_SHELL_V4) xdg_wm_base_version = 4; + if (display->capabilities & + WAYLAND_DISPLAY_CAPABILITY_XDG_SHELL_V6) + xdg_wm_base_version = 6; g_assert_cmpint (version, >=, xdg_wm_base_version); @@ -424,6 +429,13 @@ wl_display_connect (NULL)); } +void +wayland_display_dispatch (WaylandDisplay *display) +{ + if (wl_display_dispatch (display->display) == -1) + g_error ("wl_display_dispatch failed"); +} + static void wayland_display_finalize (GObject *object) { @@ -452,6 +464,16 @@ G_TYPE_NONE, 1, G_TYPE_UINT); + + signals[SURFACE_PAINTED] = + g_signal_new ("surface-painted", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, + 1, + WAYLAND_TYPE_SURFACE); } static void @@ -487,9 +509,10 @@ struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, - struct wl_array *state) + struct wl_array *states) { WaylandSurface *surface = data; + uint32_t *p; if (width == 0) surface->width = surface->default_width; @@ -500,6 +523,16 @@ surface->height = surface->default_height; else surface->height = height; + + g_assert_null (surface->pending_state); + surface->pending_state = g_hash_table_new (NULL, NULL); + + wl_array_for_each (p, states) + { + uint32_t state = *p; + + g_hash_table_add (surface->pending_state, GUINT_TO_POINTER (state)); + } } static void @@ -509,9 +542,26 @@ g_assert_not_reached (); } +static void +handle_xdg_toplevel_bounds (void *data, + struct xdg_toplevel *xdg_toplevel, + int32_t width, + int32_t height) +{ +} + +static void +handle_xdg_toplevel_wm_capabilities (void *data, + struct xdg_toplevel *xdg_toplevel, + struct wl_array *capabilities) +{ +} + static const struct xdg_toplevel_listener xdg_toplevel_listener = { handle_xdg_toplevel_configure, handle_xdg_toplevel_close, + handle_xdg_toplevel_bounds, + handle_xdg_toplevel_wm_capabilities, }; static void @@ -520,14 +570,24 @@ uint32_t serial) { WaylandSurface *surface = data; + struct wl_region *opaque_region; draw_surface (surface->display, surface->wl_surface, surface->width, surface->height, surface->color); + opaque_region = wl_compositor_create_region (surface->display->compositor); + wl_region_add (opaque_region, 0, 0, surface->width, surface->height); + wl_surface_set_opaque_region (surface->wl_surface, opaque_region); + wl_region_destroy (opaque_region); xdg_surface_ack_configure (xdg_surface, serial); wl_surface_commit (surface->wl_surface); + + g_clear_pointer (&surface->current_state, g_hash_table_unref); + surface->current_state = g_steal_pointer (&surface->pending_state); + + g_signal_emit (surface->display, signals[SURFACE_PAINTED], 0, surface); } static const struct xdg_surface_listener xdg_surface_listener = { @@ -542,6 +602,8 @@ g_clear_pointer (&surface->xdg_toplevel, xdg_toplevel_destroy); g_clear_pointer (&surface->xdg_surface, xdg_surface_destroy); g_clear_pointer (&surface->wl_surface, wl_surface_destroy); + g_clear_pointer (&surface->pending_state, g_hash_table_unref); + g_clear_pointer (&surface->current_state, g_hash_table_unref); G_OBJECT_CLASS (wayland_surface_parent_class)->dispose (object); } @@ -587,6 +649,19 @@ return surface; } +gboolean +wayland_surface_has_state (WaylandSurface *surface, + enum xdg_toplevel_state state) +{ + return g_hash_table_contains (surface->current_state, GUINT_TO_POINTER (state)); +} + +void +wayland_surface_set_opaque (WaylandSurface *surface) +{ + surface->is_opaque = TRUE; +} + const char * lookup_property_value (WaylandDisplay *display, const char *name) @@ -618,10 +693,34 @@ NULL); while (effects_complete_callback) - { - if (wl_display_dispatch (display->display) == -1) - g_error ("%s: Failed to dispatch Wayland display", __func__); - } + wayland_display_dispatch (display); +} + +static void +window_shown (void *data, + struct wl_callback *callback, + uint32_t serial) +{ + wl_callback_destroy (callback); + window_shown_callback = NULL; +} + +static const struct wl_callback_listener window_shown_listener = { + window_shown, +}; + +void +wait_for_window_shown (WaylandDisplay *display, + struct wl_surface *surface) +{ + window_shown_callback = + test_driver_sync_window_shown (display->test_driver, surface); + wl_callback_add_listener (window_shown_callback, + &window_shown_listener, + NULL); + + while (window_shown_callback) + wayland_display_dispatch (display); } static void @@ -647,10 +746,7 @@ &view_verification_listener, NULL); while (view_verification_callback) - { - if (wl_display_dispatch (display->display) == -1) - g_error ("%s: Failed to dispatch Wayland display", __func__); - } + wayland_display_dispatch (display); } static void @@ -670,10 +766,7 @@ handler_id = g_signal_connect (display, "sync-event", G_CALLBACK (on_sync_event), NULL); while (expected_serial + 1 > display->sync_event_serial_next) - { - if (wl_display_dispatch (display->display) == -1) - g_error ("%s: Failed to dispatch Wayland display", __func__); - } + wayland_display_dispatch (display); g_signal_handler_disconnect (display, handler_id); } diff -Nru mutter-46.0/src/tests/wayland-test-clients/wayland-test-client-utils.h mutter-46.1/src/tests/wayland-test-clients/wayland-test-client-utils.h --- mutter-46.0/src/tests/wayland-test-clients/wayland-test-client-utils.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/wayland-test-client-utils.h 2024-04-19 17:48:34.000000000 +0000 @@ -18,6 +18,7 @@ WAYLAND_DISPLAY_CAPABILITY_NONE = 0, WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER = 1 << 0, WAYLAND_DISPLAY_CAPABILITY_XDG_SHELL_V4 = 1 << 1, + WAYLAND_DISPLAY_CAPABILITY_XDG_SHELL_V6 = 1 << 2, } WaylandDisplayCapabilities; typedef struct _DmaBufFormat @@ -62,18 +63,24 @@ typedef struct _WaylandSurface { + GObject parent; + WaylandDisplay *display; struct wl_surface *wl_surface; struct xdg_surface *xdg_surface; struct xdg_toplevel *xdg_toplevel; + GHashTable *pending_state; + GHashTable *current_state; + int default_width; int default_height; int width; int height; uint32_t color; + gboolean is_opaque; } WaylandSurface; #define WAYLAND_TYPE_SURFACE (wayland_surface_get_type ()) @@ -93,12 +100,19 @@ WaylandDisplay * wayland_display_new_full (WaylandDisplayCapabilities capabilities, struct wl_display *wayland_display); +void wayland_display_dispatch (WaylandDisplay *display); + WaylandSurface * wayland_surface_new (WaylandDisplay *display, const char *title, int default_width, int default_height, uint32_t color); +gboolean wayland_surface_has_state (WaylandSurface *surface, + enum xdg_toplevel_state state); + +void wayland_surface_set_opaque (WaylandSurface *surface); + void draw_surface (WaylandDisplay *display, struct wl_surface *surface, int width, @@ -111,6 +125,9 @@ void wait_for_effects_completed (WaylandDisplay *display, struct wl_surface *surface); +void wait_for_window_shown (WaylandDisplay *display, + struct wl_surface *surface); + void wait_for_view_verified (WaylandDisplay *display, int sequence); diff -Nru mutter-46.0/src/tests/wayland-test-clients/xdg-activation.c mutter-46.1/src/tests/wayland-test-clients/xdg-activation.c --- mutter-46.0/src/tests/wayland-test-clients/xdg-activation.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/xdg-activation.c 2024-04-19 17:48:34.000000000 +0000 @@ -24,18 +24,15 @@ #include "xdg-activation-v1-client-protocol.h" -static WaylandDisplay *display; -static struct wl_registry *registry; static struct xdg_activation_v1 *activation; static struct wl_surface *surface; -static struct xdg_surface *xdg_surface; -static struct xdg_toplevel *xdg_toplevel; static gboolean running; static void -init_surface (const char *token) +init_surface (struct xdg_toplevel *xdg_toplevel, + const char *token) { xdg_toplevel_set_title (xdg_toplevel, "startup notification client"); xdg_activation_v1_activate (activation, token, surface); @@ -43,7 +40,7 @@ } static void -draw_main (void) +draw_main (WaylandDisplay *display) { draw_surface (display, surface, 700, 500, 0xff00ff00); } @@ -74,7 +71,9 @@ struct xdg_surface *xdg_surface, uint32_t serial) { - draw_main (); + WaylandDisplay *display = data; + + draw_main (display); wl_surface_commit (surface); g_assert_cmpint (wl_display_roundtrip (display->display), !=, -1); @@ -126,7 +125,7 @@ }; static char * -get_token (void) +get_token (WaylandDisplay *display) { struct xdg_activation_token_v1 *token; char *token_string = NULL; @@ -151,6 +150,11 @@ static void test_startup_notifications (void) { + g_autoptr (WaylandDisplay) display = NULL; + struct wl_registry *registry; + struct xdg_toplevel *xdg_toplevel; + struct xdg_surface *xdg_surface; + g_autofree char *token = NULL; display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_NONE); @@ -162,22 +166,19 @@ wl_display_roundtrip (display->display); - token = get_token (); + token = get_token (display); surface = wl_compositor_create_surface (display->compositor); xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, surface); - xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL); + xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, display); xdg_toplevel = xdg_surface_get_toplevel (xdg_surface); xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL); - init_surface (token); + init_surface (xdg_toplevel, token); running = TRUE; while (running) - { - if (wl_display_dispatch (display->display) == -1) - return; - } + wayland_display_dispatch (display); wl_display_roundtrip (display->display); @@ -185,7 +186,6 @@ g_clear_pointer (&xdg_surface, xdg_surface_destroy); g_clear_pointer (&activation, xdg_activation_v1_destroy); g_clear_pointer (®istry, wl_registry_destroy); - g_clear_object (&display); } int diff -Nru mutter-46.0/src/tests/wayland-test-clients/xdg-apply-limits.c mutter-46.1/src/tests/wayland-test-clients/xdg-apply-limits.c --- mutter-46.0/src/tests/wayland-test-clients/xdg-apply-limits.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/xdg-apply-limits.c 2024-04-19 17:48:34.000000000 +0000 @@ -31,15 +31,9 @@ STATE_WAIT_FOR_FRAME_2 } State; -static WaylandDisplay *display; - static struct wl_surface *surface; -static struct xdg_surface *xdg_surface; static struct xdg_toplevel *xdg_toplevel; -static struct wl_surface *subsurface_surface; -static struct wl_subsurface *subsurface; - static struct wl_callback *frame_callback; static gboolean running; @@ -71,7 +65,7 @@ }; static void -reset_surface (void) +reset_surface (WaylandDisplay *display) { struct wl_callback *callback; @@ -89,13 +83,14 @@ } static void -draw_main (void) +draw_main (WaylandDisplay *display) { draw_surface (display, surface, 700, 500, 0xff00ff00); } static void -draw_subsurface (void) +draw_subsurface (WaylandDisplay *display, + struct wl_surface *subsurface_surface) { draw_surface (display, subsurface_surface, 500, 300, 0xff007f00); } @@ -126,10 +121,12 @@ struct wl_callback *callback, uint32_t time) { + WaylandDisplay *display = data; + switch (state) { case STATE_WAIT_FOR_FRAME_1: - reset_surface (); + reset_surface (display); test_driver_sync_point (display->test_driver, 1, NULL); break; case STATE_WAIT_FOR_FRAME_2: @@ -154,16 +151,18 @@ struct xdg_surface *xdg_surface, uint32_t serial) { + WaylandDisplay *display = data; + switch (state) { case STATE_INIT: g_assert_not_reached (); case STATE_WAIT_FOR_CONFIGURE_1: - draw_main (); + draw_main (display); state = STATE_WAIT_FOR_FRAME_1; break; case STATE_WAIT_FOR_CONFIGURE_2: - draw_main (); + draw_main (display); state = STATE_WAIT_FOR_FRAME_2; break; case STATE_WAIT_FOR_ACTOR_DESTROYED: @@ -176,7 +175,7 @@ xdg_surface_ack_configure (xdg_surface, serial); frame_callback = wl_surface_frame (surface); - wl_callback_add_listener (frame_callback, &frame_listener, NULL); + wl_callback_add_listener (frame_callback, &frame_listener, display); wl_surface_commit (surface); wl_display_flush (display->display); } @@ -189,11 +188,16 @@ main (int argc, char **argv) { + g_autoptr (WaylandDisplay) display = NULL; + struct xdg_surface *xdg_surface; + struct wl_surface *subsurface_surface; + struct wl_subsurface *subsurface; + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); surface = wl_compositor_create_surface (display->compositor); xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, surface); - xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL); + xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, display); xdg_toplevel = xdg_surface_get_toplevel (xdg_surface); xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL); @@ -202,7 +206,7 @@ subsurface_surface, surface); wl_subsurface_set_position (subsurface, 100, 100); - draw_subsurface (); + draw_subsurface (display, subsurface_surface); wl_surface_commit (subsurface_surface); init_surface (); @@ -217,10 +221,7 @@ running = TRUE; while (running) - { - if (wl_display_dispatch (display->display) == -1) - return EXIT_FAILURE; - } + wayland_display_dispatch (display); return EXIT_SUCCESS; } diff -Nru mutter-46.0/src/tests/wayland-test-clients/xdg-foreign.c mutter-46.1/src/tests/wayland-test-clients/xdg-foreign.c --- mutter-46.0/src/tests/wayland-test-clients/xdg-foreign.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/xdg-foreign.c 2024-04-19 17:48:34.000000000 +0000 @@ -24,8 +24,6 @@ #include "xdg-foreign-unstable-v1-client-protocol.h" #include "xdg-foreign-unstable-v2-client-protocol.h" -static WaylandDisplay *display; - static struct zxdg_exporter_v1 *exporter_v1; static struct zxdg_exporter_v2 *exporter_v2; static struct zxdg_importer_v1 *importer_v1; @@ -130,10 +128,11 @@ main (int argc, char **argv) { - g_autoptr (WaylandSurface) window1; - g_autoptr (WaylandSurface) window2; - g_autoptr (WaylandSurface) window3; - g_autoptr (WaylandSurface) window4; + g_autoptr (WaylandDisplay) display = NULL; + g_autoptr (WaylandSurface) window1 = NULL; + g_autoptr (WaylandSurface) window2 = NULL; + g_autoptr (WaylandSurface) window3 = NULL; + g_autoptr (WaylandSurface) window4 = NULL; g_autofree char *handle1 = NULL; g_autofree char *handle3 = NULL; struct wl_registry *registry; @@ -172,10 +171,7 @@ zxdg_exported_v2_add_listener (exported3, &exported_v2_listener, &handle3); while (!handle1 && !handle3) - { - if (wl_display_dispatch (display->display) == -1) - return EXIT_FAILURE; - } + wayland_display_dispatch (display); zxdg_importer_v2_import_toplevel (importer_v2, "don't crash on bogus handle"); zxdg_importer_v1_import (importer_v1, "don't crash on bogus handle"); @@ -217,12 +213,7 @@ zxdg_exported_v2_destroy (exported3); while (!imported1_destroyed || !imported3_destroyed) - { - if (wl_display_dispatch (display->display) == -1) - return EXIT_FAILURE; - } - - g_object_unref (display); + wayland_display_dispatch (display); return EXIT_SUCCESS; } diff -Nru mutter-46.0/src/tests/wayland-test-clients/xdg-toplevel-bounds.c mutter-46.1/src/tests/wayland-test-clients/xdg-toplevel-bounds.c --- mutter-46.0/src/tests/wayland-test-clients/xdg-toplevel-bounds.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/xdg-toplevel-bounds.c 2024-04-19 17:48:34.000000000 +0000 @@ -29,11 +29,7 @@ STATE_WAIT_FOR_FRAME_1, } State; -static WaylandDisplay *display; - static struct wl_surface *surface; -static struct xdg_surface *xdg_surface; -static struct xdg_toplevel *xdg_toplevel; static struct wl_callback *frame_callback; @@ -44,15 +40,16 @@ static int32_t pending_bounds_height; static void -init_surface (void) +init_surface (struct xdg_toplevel *xdg_toplevel) { xdg_toplevel_set_title (xdg_toplevel, "toplevel-bounds-test"); wl_surface_commit (surface); } static void -draw_main (int width, - int height) +draw_main (WaylandDisplay *display, + int width, + int height) { draw_surface (display, surface, width, height, 0xff00ff00); } @@ -94,6 +91,8 @@ struct wl_callback *callback, uint32_t time) { + WaylandDisplay *display = data; + switch (state) { case STATE_WAIT_FOR_FRAME_1: @@ -114,6 +113,8 @@ struct xdg_surface *xdg_surface, uint32_t serial) { + WaylandDisplay *display = data; + switch (state) { case STATE_INIT: @@ -122,7 +123,8 @@ g_assert (pending_bounds_width > 0); g_assert (pending_bounds_height > 0); - draw_main (pending_bounds_width - 10, + draw_main (display, + pending_bounds_width - 10, pending_bounds_height - 10); state = STATE_WAIT_FOR_FRAME_1; break; @@ -132,7 +134,7 @@ xdg_surface_ack_configure (xdg_surface, serial); frame_callback = wl_surface_frame (surface); - wl_callback_add_listener (frame_callback, &frame_listener, NULL); + wl_callback_add_listener (frame_callback, &frame_listener, display); wl_surface_commit (surface); wl_display_flush (display->display); } @@ -154,27 +156,28 @@ main (int argc, char **argv) { + g_autoptr (WaylandDisplay) display = NULL; + struct xdg_toplevel *xdg_toplevel; + struct xdg_surface *xdg_surface; + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER | WAYLAND_DISPLAY_CAPABILITY_XDG_SHELL_V4); g_signal_connect (display, "sync-event", G_CALLBACK (on_sync_event), NULL); surface = wl_compositor_create_surface (display->compositor); xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base, surface); - xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, NULL); + xdg_surface_add_listener (xdg_surface, &xdg_surface_listener, display); xdg_toplevel = xdg_surface_get_toplevel (xdg_surface); xdg_toplevel_add_listener (xdg_toplevel, &xdg_toplevel_listener, NULL); - init_surface (); + init_surface (xdg_toplevel); state = STATE_WAIT_FOR_CONFIGURE_1; wl_surface_commit (surface); running = TRUE; while (running) - { - if (wl_display_dispatch (display->display) == -1) - return EXIT_FAILURE; - } + wayland_display_dispatch (display); return EXIT_SUCCESS; } diff -Nru mutter-46.0/src/tests/wayland-test-clients/xdg-toplevel-suspended.c mutter-46.1/src/tests/wayland-test-clients/xdg-toplevel-suspended.c --- mutter-46.0/src/tests/wayland-test-clients/xdg-toplevel-suspended.c 1970-01-01 00:00:00.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/xdg-toplevel-suspended.c 2024-04-19 17:48:34.000000000 +0000 @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2024 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "config.h" + +#include +#include + +#include "wayland-test-client-utils.h" + +enum +{ + XDG_TOPLEVEL_SUSPENDED_COMMAND_NEXT_WORKSPACE = 0, + XDG_TOPLEVEL_SUSPENDED_COMMAND_PREV_WORKSPACE = 1, + XDG_TOPLEVEL_SUSPENDED_COMMAND_ACTIVATE_WINDOW = 2, +}; + +static void +wait_for_state (WaylandSurface *surface, + enum xdg_toplevel_state state) +{ + while (!wayland_surface_has_state (surface, state)) + wayland_display_dispatch (surface->display); +} + +static void +wait_for_no_state (WaylandSurface *surface, + enum xdg_toplevel_state state) +{ + while (wayland_surface_has_state (surface, state)) + wayland_display_dispatch (surface->display); +} + +static void +test_floating (WaylandDisplay *display) +{ + g_autoptr (WaylandSurface) surface = NULL; + + g_debug ("Testing suspended state when mapping floating"); + + surface = wayland_surface_new (display, __func__, 100, 100, 0xffffffff); + wl_surface_commit (surface->wl_surface); + + wait_for_window_shown (display, surface->wl_surface); + g_assert_false (wayland_surface_has_state (surface, + XDG_TOPLEVEL_STATE_SUSPENDED)); +} + +static void +test_maximized (WaylandDisplay *display) +{ + g_autoptr (WaylandSurface) surface = NULL; + + g_debug ("Testing suspended state when mapping maximized"); + + surface = wayland_surface_new (display, __func__, 100, 100, 0xffffffff); + xdg_toplevel_set_maximized (surface->xdg_toplevel); + wl_surface_commit (surface->wl_surface); + + wait_for_window_shown (display, surface->wl_surface); + g_assert_false (wayland_surface_has_state (surface, + XDG_TOPLEVEL_STATE_SUSPENDED)); +} + +static void +test_minimized (WaylandDisplay *display) +{ + g_autoptr (WaylandSurface) surface = NULL; + + g_debug ("Testing suspended state when mapping minimized"); + + surface = wayland_surface_new (display, __func__, 100, 100, 0xffffffff); + wl_surface_commit (surface->wl_surface); + + wait_for_window_shown (display, surface->wl_surface); + g_assert_false (wayland_surface_has_state (surface, + XDG_TOPLEVEL_STATE_SUSPENDED)); + + xdg_toplevel_set_minimized (surface->xdg_toplevel); + wait_for_state (surface, XDG_TOPLEVEL_STATE_SUSPENDED); +} + +static void +test_workspace_changes (WaylandDisplay *display) +{ + g_autoptr (WaylandSurface) surface = NULL; + + g_debug ("Testing suspended state when changing workspace"); + + surface = wayland_surface_new (display, __func__, 100, 100, 0xffffffff); + wl_surface_commit (surface->wl_surface); + + wait_for_window_shown (display, surface->wl_surface); + g_assert_false (wayland_surface_has_state (surface, + XDG_TOPLEVEL_STATE_SUSPENDED)); + + + test_driver_sync_point (display->test_driver, + XDG_TOPLEVEL_SUSPENDED_COMMAND_NEXT_WORKSPACE, + NULL); + + wait_for_state (surface, XDG_TOPLEVEL_STATE_SUSPENDED); + + test_driver_sync_point (display->test_driver, + XDG_TOPLEVEL_SUSPENDED_COMMAND_PREV_WORKSPACE, + NULL); + + wait_for_no_state (surface, XDG_TOPLEVEL_STATE_SUSPENDED); +} + +static void +test_obstructed (WaylandDisplay *display) +{ + g_autoptr (WaylandSurface) surface = NULL; + g_autoptr (WaylandSurface) cover_surface = NULL; + + g_debug ("Testing suspended state when obstructed"); + + surface = wayland_surface_new (display, __func__, + 100, 100, 0xffffffff); + wl_surface_commit (surface->wl_surface); + + wait_for_window_shown (display, surface->wl_surface); + g_assert_false (wayland_surface_has_state (surface, + XDG_TOPLEVEL_STATE_SUSPENDED)); + + cover_surface = wayland_surface_new (display, "obstruction", + 100, 100, 0xffffffff); + xdg_toplevel_set_maximized (cover_surface->xdg_toplevel); + wl_surface_commit (cover_surface->wl_surface); + + wait_for_window_shown (display, cover_surface->wl_surface); + test_driver_sync_point (display->test_driver, + XDG_TOPLEVEL_SUSPENDED_COMMAND_ACTIVATE_WINDOW, + cover_surface->wl_surface); + + wait_for_state (surface, XDG_TOPLEVEL_STATE_SUSPENDED); + + g_clear_object (&cover_surface); + + wait_for_no_state (surface, XDG_TOPLEVEL_STATE_SUSPENDED); +} + +int +main (int argc, + char **argv) +{ + g_autoptr (WaylandDisplay) display = NULL; + g_autoptr (WaylandSurface) surface = NULL; + + display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER | + WAYLAND_DISPLAY_CAPABILITY_XDG_SHELL_V6); + + test_floating (display); + test_maximized (display); + test_minimized (display); + test_workspace_changes (display); + test_obstructed (display); + + return EXIT_SUCCESS; +} diff -Nru mutter-46.0/src/tests/wayland-test-clients/ycbcr.c mutter-46.1/src/tests/wayland-test-clients/ycbcr.c --- mutter-46.0/src/tests/wayland-test-clients/ycbcr.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-test-clients/ycbcr.c 2024-04-19 17:48:34.000000000 +0000 @@ -24,8 +24,6 @@ #include "wayland-test-client-utils.h" -static WaylandDisplay *display; - static struct wl_surface *surface; static struct xdg_surface *xdg_surface; static struct xdg_toplevel *xdg_toplevel; @@ -63,8 +61,9 @@ float *out_cr); static void -draw (uint32_t drm_format, - ShaderFunc shader) +draw (WaylandDisplay *display, + uint32_t drm_format, + ShaderFunc shader) { WaylandBuffer *buffer; uint8_t *planes[4]; @@ -180,20 +179,18 @@ }; static void -wait_for_configure (void) +wait_for_configure (WaylandDisplay *display) { waiting_for_configure = TRUE; while (waiting_for_configure) - { - if (wl_display_dispatch (display->display) == -1) - exit (EXIT_FAILURE); - } + wayland_display_dispatch (display); } int main (int argc, char **argv) { + g_autoptr (WaylandDisplay) display = NULL; display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER); surface = wl_compositor_create_surface (display->compositor); @@ -205,27 +202,25 @@ xdg_toplevel_set_fullscreen (xdg_toplevel, NULL); wl_surface_commit (surface); - wait_for_configure (); + wait_for_configure (display); - draw (DRM_FORMAT_YUYV, shader_luma_gradient); + draw (display, DRM_FORMAT_YUYV, shader_luma_gradient); wl_surface_commit (surface); wait_for_effects_completed (display, surface); wait_for_view_verified (display, 0); - draw (DRM_FORMAT_YUYV, shader_color_gradient); + draw (display, DRM_FORMAT_YUYV, shader_color_gradient); wl_surface_commit (surface); wait_for_view_verified (display, 1); - draw (DRM_FORMAT_YUV420, shader_luma_gradient); + draw (display, DRM_FORMAT_YUV420, shader_luma_gradient); wl_surface_commit (surface); wait_for_view_verified (display, 2); - draw (DRM_FORMAT_YUV420, shader_color_gradient); + draw (display, DRM_FORMAT_YUV420, shader_color_gradient); wl_surface_commit (surface); wait_for_view_verified (display, 3); g_clear_pointer (&xdg_toplevel, xdg_toplevel_destroy); g_clear_pointer (&xdg_surface, xdg_surface_destroy); - - g_clear_object (&display); } diff -Nru mutter-46.0/src/tests/wayland-unit-tests.c mutter-46.1/src/tests/wayland-unit-tests.c --- mutter-46.0/src/tests/wayland-unit-tests.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/tests/wayland-unit-tests.c 2024-04-19 17:48:34.000000000 +0000 @@ -845,6 +845,97 @@ } static void +toplevel_show_states (void) +{ + MetaWaylandTestClient *wayland_test_client; + MetaWindow *window; + + wayland_test_client = + meta_wayland_test_client_new (test_context, "toplevel-show-states"); + + wait_for_sync_point (0); + window = find_client_window ("showing-states"); + + g_assert_true (meta_window_should_show (window)); + g_assert_false (meta_window_should_be_showing (window)); + + meta_wayland_test_driver_emit_sync_event (test_driver, 0); + wait_for_sync_point (1); + + g_assert_true (meta_window_should_show (window)); + g_assert_true (meta_window_should_be_showing (window)); + + meta_wayland_test_client_finish (wayland_test_client); +} + +enum +{ + XDG_TOPLEVEL_SUSPENDED_COMMAND_NEXT_WORKSPACE = 0, + XDG_TOPLEVEL_SUSPENDED_COMMAND_PREV_WORKSPACE = 1, + XDG_TOPLEVEL_SUSPENDED_COMMAND_ACTIVATE_WINDOW = 2, +}; + +static void +on_toplevel_suspended_sync_point (MetaWaylandTestDriver *test_driver, + unsigned int sequence, + struct wl_resource *surface_resource, + struct wl_client *wl_client) +{ + MetaDisplay *display = meta_context_get_display (test_context); + MetaWorkspaceManager *workspace_manager = + meta_display_get_workspace_manager (display); + MetaWorkspace *current_workspace; + int index; + MetaWorkspace *workspace; + MetaWaylandSurface *surface; + uint32_t now_ms; + + current_workspace = + meta_workspace_manager_get_active_workspace (workspace_manager); + index = meta_workspace_index (current_workspace); + switch (sequence) + { + case XDG_TOPLEVEL_SUSPENDED_COMMAND_NEXT_WORKSPACE: + workspace = + meta_workspace_manager_get_workspace_by_index (workspace_manager, + index + 1); + now_ms = meta_display_get_current_time_roundtrip (display); + meta_workspace_activate (workspace, now_ms); + break; + case XDG_TOPLEVEL_SUSPENDED_COMMAND_PREV_WORKSPACE: + workspace = + meta_workspace_manager_get_workspace_by_index (workspace_manager, + index - 1); + now_ms = meta_display_get_current_time_roundtrip (display); + meta_workspace_activate (workspace, now_ms); + break; + case XDG_TOPLEVEL_SUSPENDED_COMMAND_ACTIVATE_WINDOW: + surface = wl_resource_get_user_data (surface_resource); + now_ms = meta_display_get_current_time_roundtrip (display); + meta_window_activate (meta_wayland_surface_get_window (surface), now_ms); + break; + } +} + +static void +toplevel_suspended (void) +{ + MetaWaylandTestClient *wayland_test_client; + gulong sync_point_id; + + sync_point_id = + g_signal_connect (test_driver, "sync-point", + G_CALLBACK (on_toplevel_suspended_sync_point), + NULL); + + wayland_test_client = + meta_wayland_test_client_new (test_context, "xdg-toplevel-suspended"); + meta_wayland_test_client_finish (wayland_test_client); + + g_signal_handler_disconnect (test_driver, sync_point_id); +} + +static void on_before_tests (void) { MetaWaylandCompositor *compositor = @@ -921,6 +1012,10 @@ #endif g_test_add_func ("/wayland/xdg-foreign/set-parent-of", xdg_foreign_set_parent_of); + g_test_add_func ("/wayland/toplevel/show-states", + toplevel_show_states); + g_test_add_func ("/wayland/toplevel/suspended", + toplevel_suspended); } int diff -Nru mutter-46.0/src/wayland/meta-drm-timeline.c mutter-46.1/src/wayland/meta-drm-timeline.c --- mutter-46.0/src/wayland/meta-drm-timeline.c 1970-01-01 00:00:00.000000000 +0000 +++ mutter-46.1/src/wayland/meta-drm-timeline.c 2024-04-19 17:48:34.000000000 +0000 @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2023 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Written by: + * Austin Shafer + */ + +/** + * MetaDrmTimeline + * + * MetaDrmTimeline is a helper for handling DRM syncobj operations. It + * can import DRM syncobjs and export eventfds at a particular point. + * + * This is heavily inspired by wlroot's wlr_render_timeline, written by + * Simon Ser. + */ + +#include "config.h" + +#include +#include +#include +#ifdef HAVE_EVENTFD +#include +#endif + +#include "meta/util.h" +#include "wayland/meta-drm-timeline.h" + +enum +{ + PROP_0, + + PROP_DRM_FD, + PROP_SYNCOBJ_FD, + + N_PROPS +}; + +typedef struct _MetaDrmTimeline +{ + GObject parent; + + int drm; + int drm_syncobj_fd; + uint32_t drm_syncobj; +} MetaDrmTimeline; + +static GParamSpec *obj_props[N_PROPS]; + +static void initable_iface_init (GInitableIface *initable_iface); + +G_DEFINE_FINAL_TYPE_WITH_CODE (MetaDrmTimeline, meta_drm_timeline, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + initable_iface_init)) + +static void +meta_drm_timeline_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaDrmTimeline *timeline = META_DRM_TIMELINE (object); + + switch (prop_id) + { + case PROP_DRM_FD: + g_value_set_int (value, timeline->drm); + break; + case PROP_SYNCOBJ_FD: + g_value_set_int (value, timeline->drm_syncobj_fd); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_drm_timeline_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaDrmTimeline *timeline = META_DRM_TIMELINE (object); + int fd; + + switch (prop_id) + { + case PROP_DRM_FD: + fd = g_value_get_int (value); + timeline->drm = fcntl (fd, F_DUPFD_CLOEXEC, 0); + break; + case PROP_SYNCOBJ_FD: + fd = g_value_get_int (value); + timeline->drm_syncobj_fd = fcntl (fd, F_DUPFD_CLOEXEC, 0); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +meta_drm_timeline_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + MetaDrmTimeline *timeline = META_DRM_TIMELINE (initable); + + if (drmSyncobjFDToHandle (timeline->drm, + timeline->drm_syncobj_fd, + &timeline->drm_syncobj) != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Failed to import DRM syncobj"); + return FALSE; + } + + return TRUE; +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_iface->init = meta_drm_timeline_initable_init; +} + +MetaDrmTimeline * +meta_drm_timeline_import_syncobj (int fd, + int drm_syncobj, + GError **error) +{ + MetaDrmTimeline *timeline = g_initable_new (META_TYPE_DRM_TIMELINE, + NULL, error, + "drm-fd", fd, + "syncobj-fd", drm_syncobj, + NULL); + + return timeline; +} + +int +meta_drm_timeline_get_eventfd (MetaDrmTimeline *timeline, + uint64_t sync_point, + GError **error) +{ + g_autofd int fd = -1; + +#ifdef HAVE_EVENTFD + fd = eventfd (0, EFD_CLOEXEC); + if (fd < 0) + return -1; + + if (drmSyncobjEventfd (timeline->drm, timeline->drm_syncobj, + sync_point, fd, 0) != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "DRM_IOCTL_SYNCOBJ_EVENTFD: Failed to export eventfd"); + return -1; + } +#endif + + return g_steal_fd (&fd); +} + +gboolean +meta_drm_timeline_set_sync_point (MetaDrmTimeline *timeline, + uint64_t sync_point, + int sync_fd, + GError **error) +{ + uint32_t tmp; + + /* Import our syncfd at a new release point */ + if (drmSyncobjCreate (timeline->drm, 0, &tmp) != 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "Failed to create temporary syncobj"); + return FALSE; + } + + if (drmSyncobjImportSyncFile (timeline->drm, tmp, sync_fd) != 0) + goto end; + + if (drmSyncobjTransfer (timeline->drm, timeline->drm_syncobj, + sync_point, tmp, 0, 0) != 0) + goto end; + + drmSyncobjDestroy (timeline->drm, tmp); + return TRUE; + +end: + drmSyncobjDestroy (timeline->drm, tmp); + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "Failed to import syncfd at specified point"); + return FALSE; +} + +static void +meta_drm_timeline_finalize (GObject *object) +{ + MetaDrmTimeline *timeline = META_DRM_TIMELINE (object); + + drmSyncobjDestroy (timeline->drm, timeline->drm_syncobj); + g_clear_fd (&timeline->drm_syncobj_fd, NULL); + g_clear_fd (&timeline->drm, NULL); + + G_OBJECT_CLASS (meta_drm_timeline_parent_class)->finalize (object); +} + +static void +meta_drm_timeline_init (MetaDrmTimeline *timeline) +{ + timeline->drm = -1; + timeline->drm_syncobj_fd = -1; + timeline->drm_syncobj = -1; +} + +static void +meta_drm_timeline_class_init (MetaDrmTimelineClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = meta_drm_timeline_get_property; + object_class->set_property = meta_drm_timeline_set_property; + object_class->finalize = meta_drm_timeline_finalize; + + obj_props[PROP_DRM_FD] = + g_param_spec_int ("drm-fd", + NULL, + NULL, + 0, INT_MAX, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + obj_props[PROP_SYNCOBJ_FD] = + g_param_spec_int ("syncobj-fd", + NULL, + NULL, + 0, INT_MAX, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPS, obj_props); +} diff -Nru mutter-46.0/src/wayland/meta-drm-timeline.h mutter-46.1/src/wayland/meta-drm-timeline.h --- mutter-46.0/src/wayland/meta-drm-timeline.h 1970-01-01 00:00:00.000000000 +0000 +++ mutter-46.1/src/wayland/meta-drm-timeline.h 2024-04-19 17:48:34.000000000 +0000 @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2023 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Written by: + * Austin Shafer + */ + +#pragma once + +#include +#include +#include + +#define META_TYPE_DRM_TIMELINE (meta_drm_timeline_get_type ()) +G_DECLARE_FINAL_TYPE (MetaDrmTimeline, meta_drm_timeline, + META, DRM_TIMELINE, GObject); + +typedef struct _MetaDrmTimeline MetaDrmTimeline; + +MetaDrmTimeline * meta_drm_timeline_create (int fd, + GError **error); + +MetaDrmTimeline * meta_drm_timeline_import_syncobj (int fd, + int drm_syncobj, + GError **error); + +int meta_drm_timeline_get_eventfd (MetaDrmTimeline *timeline, + uint64_t sync_point, + GError **error); + +gboolean meta_drm_timeline_set_sync_point (MetaDrmTimeline *timeline, + uint64_t sync_point, + int sync_fd, + GError **error); diff -Nru mutter-46.0/src/wayland/meta-wayland-buffer.c mutter-46.1/src/wayland/meta-wayland-buffer.c --- mutter-46.0/src/wayland/meta-wayland-buffer.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-buffer.c 2024-04-19 17:48:34.000000000 +0000 @@ -49,6 +49,7 @@ #include "wayland/meta-wayland-buffer.h" #include +#include #include "backends/meta-backend-private.h" #include "clutter/clutter.h" @@ -57,7 +58,10 @@ #include "wayland/meta-wayland-dma-buf.h" #include "wayland/meta-wayland-private.h" #include "common/meta-cogl-drm-formats.h" +#include "common/meta-drm-format-helpers.h" #include "compositor/meta-multi-texture-format-private.h" +#include "wayland/meta-drm-timeline.h" +#include "wayland/meta-wayland-linux-drm-syncobj.h" #ifdef HAVE_NATIVE_BACKEND #include "backends/native/meta-drm-buffer-gbm.h" @@ -711,12 +715,43 @@ void meta_wayland_buffer_dec_use_count (MetaWaylandBuffer *buffer) { + MetaContext *context = meta_wayland_compositor_get_context (buffer->compositor); + MetaBackend *backend = meta_context_get_backend (context); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + MetaWaylandSyncPoint *sync_point; + g_autoptr(GError) error = NULL; + g_autofd int sync_fd = -1; + g_return_if_fail (buffer->use_count > 0); buffer->use_count--; if (buffer->use_count == 0 && buffer->resource) - wl_buffer_send_release (buffer->resource); + { + wl_buffer_send_release (buffer->resource); + + sync_fd = cogl_context_get_latest_sync_fd (cogl_context); + if (sync_fd < 0) + { + meta_topic (META_DEBUG_WAYLAND, "Invalid Sync Fd returned by COGL"); + return; + } + + for (int i = 0; i < buffer->release_points->len; i++) + { + sync_point = g_ptr_array_index (buffer->release_points, i); + if (!meta_wayland_sync_timeline_set_sync_point (sync_point->timeline, + sync_point->sync_point, + sync_fd, + &error)) + { + g_warning ("Failed to import sync point: %s", error->message); + } + } + g_ptr_array_remove_range (buffer->release_points, 0, + buffer->release_points->len); + } } gboolean @@ -980,6 +1015,7 @@ clear_tainted_scanout_onscreens (buffer); g_clear_pointer (&buffer->tainted_scanout_onscreens, g_hash_table_unref); + g_clear_pointer (&buffer->release_points, g_ptr_array_unref); g_clear_object (&buffer->egl_image.texture); #ifdef HAVE_WAYLAND_EGLSTREAM @@ -998,6 +1034,7 @@ static void meta_wayland_buffer_init (MetaWaylandBuffer *buffer) { + buffer->release_points = g_ptr_array_new_with_free_func (g_object_unref); } static void @@ -1090,7 +1127,9 @@ drm_format = shm_to_drm_format (possible_formats[i]); format_info = meta_format_info_from_drm_format (drm_format); - g_assert (format_info); + + if (!format_info) + continue; if (!context_supports_format (cogl_context, format_info)) continue; diff -Nru mutter-46.0/src/wayland/meta-wayland-buffer.h mutter-46.1/src/wayland/meta-wayland-buffer.h --- mutter-46.0/src/wayland/meta-wayland-buffer.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-buffer.h 2024-04-19 17:48:34.000000000 +0000 @@ -79,6 +79,8 @@ } single_pixel; GHashTable *tainted_scanout_onscreens; + + GPtrArray *release_points; }; #define META_TYPE_WAYLAND_BUFFER (meta_wayland_buffer_get_type ()) diff -Nru mutter-46.0/src/wayland/meta-wayland-data-device-primary.c mutter-46.1/src/wayland/meta-wayland-data-device-primary.c --- mutter-46.0/src/wayland/meta-wayland-data-device-primary.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-data-device-primary.c 2024-04-19 17:48:34.000000000 +0000 @@ -182,7 +182,7 @@ source = wl_resource_get_user_data (source_resource); if (wl_resource_get_client (resource) != - meta_wayland_keyboard_get_focus_client (seat->keyboard)) + meta_wayland_seat_get_input_focus_client (seat)) { if (source) meta_wayland_data_source_cancel (source); @@ -211,7 +211,7 @@ struct wl_resource *data_device_resource; struct wl_client *focus_client; - focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); + focus_client = meta_wayland_seat_get_input_focus_client (seat); if (!focus_client) return; @@ -348,13 +348,13 @@ } void -meta_wayland_data_device_primary_set_keyboard_focus (MetaWaylandDataDevicePrimary *data_device) +meta_wayland_data_device_primary_sync_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); + focus_client = meta_wayland_seat_get_input_focus_client (seat); if (focus_client == data_device->focus_client) return; diff -Nru mutter-46.0/src/wayland/meta-wayland-data-device-primary.h mutter-46.1/src/wayland/meta-wayland-data-device-primary.h --- mutter-46.0/src/wayland/meta-wayland-data-device-primary.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-data-device-primary.h 2024-04-19 17:48:34.000000000 +0000 @@ -52,4 +52,4 @@ void meta_wayland_data_device_primary_init (MetaWaylandDataDevicePrimary *data_device, MetaWaylandSeat *seat); -void meta_wayland_data_device_primary_set_keyboard_focus (MetaWaylandDataDevicePrimary *data_device); +void meta_wayland_data_device_primary_sync_focus (MetaWaylandDataDevicePrimary *data_device); diff -Nru mutter-46.0/src/wayland/meta-wayland-data-device.c mutter-46.1/src/wayland/meta-wayland-data-device.c --- mutter-46.0/src/wayland/meta-wayland-data-device.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-data-device.c 2024-04-19 17:48:34.000000000 +0000 @@ -1062,7 +1062,7 @@ } if (wl_resource_get_client (resource) != - meta_wayland_keyboard_get_focus_client (seat->keyboard)) + meta_wayland_seat_get_input_focus_client (seat)) { if (source) meta_wayland_data_source_cancel (source); @@ -1106,7 +1106,7 @@ struct wl_resource *data_device_resource; struct wl_client *focus_client; - focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); + focus_client = meta_wayland_seat_get_input_focus_client (seat); if (!focus_client) return; @@ -1249,13 +1249,13 @@ } void -meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device) +meta_wayland_data_device_sync_focus (MetaWaylandDataDevice *data_device) { MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device); struct wl_client *focus_client; struct wl_resource *data_device_resource; - focus_client = meta_wayland_keyboard_get_focus_client (seat->keyboard); + focus_client = meta_wayland_seat_get_input_focus_client (seat); if (focus_client == data_device->focus_client) return; diff -Nru mutter-46.0/src/wayland/meta-wayland-data-device.h mutter-46.1/src/wayland/meta-wayland-data-device.h --- mutter-46.0/src/wayland/meta-wayland-data-device.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-data-device.h 2024-04-19 17:48:34.000000000 +0000 @@ -59,7 +59,7 @@ MetaWaylandSeat * meta_wayland_data_device_get_seat (MetaWaylandDataDevice *data_device); -void meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device); +void meta_wayland_data_device_sync_focus (MetaWaylandDataDevice *data_device); MetaWaylandDragGrab * meta_wayland_data_device_get_current_grab (MetaWaylandDataDevice *data_device); diff -Nru mutter-46.0/src/wayland/meta-wayland-dma-buf.c mutter-46.1/src/wayland/meta-wayland-dma-buf.c --- mutter-46.0/src/wayland/meta-wayland-dma-buf.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-dma-buf.c 2024-04-19 17:48:34.000000000 +0000 @@ -51,11 +51,13 @@ #include "cogl/cogl-egl.h" #include "cogl/cogl.h" #include "common/meta-cogl-drm-formats.h" +#include "common/meta-drm-format-helpers.h" #include "compositor/meta-multi-texture-format-private.h" #include "meta/meta-backend.h" #include "wayland/meta-wayland-buffer.h" #include "wayland/meta-wayland-private.h" #include "wayland/meta-wayland-versions.h" +#include "wayland/meta-wayland-linux-drm-syncobj.h" #ifdef HAVE_NATIVE_BACKEND #include "backends/native/meta-drm-buffer-gbm.h" @@ -1044,6 +1046,39 @@ return &source->base; } + +GSource * +meta_wayland_drm_syncobj_create_source (MetaWaylandBuffer *buffer, + MetaWaylandSyncobjTimeline *timeline, + uint64_t sync_point, + MetaWaylandDmaBufSourceDispatch dispatch, + gpointer user_data) +{ + MetaWaylandDmaBufSource *source = NULL; + g_autofd int sync_fd = -1; + g_autoptr(GError) error = NULL; + + sync_fd = meta_wayland_sync_timeline_get_eventfd (timeline, sync_point, &error); + if (sync_fd < 0) + { + g_warning ("Failed to get sync fd: %s", error->message); + return NULL; + } + + if (is_fd_readable (sync_fd)) + { + return NULL; + } + + source = create_source (buffer, dispatch, user_data); + if (!source) + return NULL; + + source->fd_tags[0] = g_source_add_unix_fd (&source->base, sync_fd, G_IO_IN); + source->owned_sync_fd[0] = g_steal_fd (&sync_fd); + + return &source->base; +} static void buffer_params_create_common (struct wl_client *client, diff -Nru mutter-46.0/src/wayland/meta-wayland-dma-buf.h mutter-46.1/src/wayland/meta-wayland-dma-buf.h --- mutter-46.0/src/wayland/meta-wayland-dma-buf.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-dma-buf.h 2024-04-19 17:48:34.000000000 +0000 @@ -63,6 +63,13 @@ MetaWaylandDmaBufSourceDispatch dispatch, gpointer user_data); +GSource * +meta_wayland_drm_syncobj_create_source (MetaWaylandBuffer *buffer, + MetaWaylandSyncobjTimeline *timeline, + uint64_t sync_point, + MetaWaylandDmaBufSourceDispatch dispatch, + gpointer user_data); + CoglScanout * meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandBuffer *buffer, CoglOnscreen *onscreen, diff -Nru mutter-46.0/src/wayland/meta-wayland-keyboard.c mutter-46.1/src/wayland/meta-wayland-keyboard.c --- mutter-46.0/src/wayland/meta-wayland-keyboard.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-keyboard.c 2024-04-19 17:48:34.000000000 +0000 @@ -74,13 +74,9 @@ struct wl_listener focus_surface_listener; uint32_t focus_serial; - uint32_t key_down_keycode; - uint32_t key_down_serial; - - uint32_t key_up_keycode; - uint32_t key_up_serial; - struct wl_array pressed_keys; + GHashTable *key_down_serials; + uint32_t last_key_up_serial; MetaWaylandXkbInfo xkb_info; enum xkb_state_component mods_changed; @@ -285,13 +281,16 @@ if (state) { - keyboard->key_down_serial = serial; - keyboard->key_down_keycode = key; + g_hash_table_insert (keyboard->key_down_serials, + GUINT_TO_POINTER (key), + GUINT_TO_POINTER (serial)); + keyboard->last_key_up_serial = 0; } else { - keyboard->key_up_serial = serial; - keyboard->key_up_keycode = key; + g_hash_table_remove (keyboard->key_down_serials, + GUINT_TO_POINTER (key)); + keyboard->last_key_up_serial = serial; } wl_resource_for_each (resource, &keyboard->focus_resource_list) @@ -548,6 +547,8 @@ wl_array_init (&keyboard->pressed_keys); + keyboard->key_down_serials = g_hash_table_new (NULL, NULL); + g_signal_connect (keyboard->settings, "changed", G_CALLBACK (settings_changed), keyboard); @@ -588,6 +589,9 @@ wl_list_remove (&keyboard->focus_resource_list); wl_list_init (&keyboard->focus_resource_list); + g_clear_pointer (&keyboard->key_down_serials, g_hash_table_unref); + keyboard->last_key_up_serial = 0; + wl_array_release (&keyboard->pressed_keys); g_clear_object (&keyboard->settings); @@ -791,6 +795,8 @@ wl_list_remove (&keyboard->focus_surface_listener.link); keyboard->focus_surface = NULL; + g_hash_table_remove_all (keyboard->key_down_serials); + keyboard->last_key_up_serial = 0; } if (surface != NULL) @@ -824,15 +830,6 @@ } } -struct wl_client * -meta_wayland_keyboard_get_focus_client (MetaWaylandKeyboard *keyboard) -{ - if (keyboard->focus_surface) - return wl_resource_get_client (keyboard->focus_surface->resource); - else - return NULL; -} - static void keyboard_release (struct wl_client *client, struct wl_resource *resource) @@ -891,9 +888,20 @@ meta_wayland_keyboard_can_popup (MetaWaylandKeyboard *keyboard, uint32_t serial) { - return (keyboard->key_down_serial == serial || - ((keyboard->key_down_keycode == keyboard->key_up_keycode) && - keyboard->key_up_serial == serial)); + GHashTableIter iter; + gpointer value; + + if (keyboard->last_key_up_serial == serial) + return TRUE; + + g_hash_table_iter_init (&iter, keyboard->key_down_serials); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + if (GPOINTER_TO_UINT (value) == serial) + return TRUE; + } + + return FALSE; } static void diff -Nru mutter-46.0/src/wayland/meta-wayland-keyboard.h mutter-46.1/src/wayland/meta-wayland-keyboard.h --- mutter-46.0/src/wayland/meta-wayland-keyboard.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-keyboard.h 2024-04-19 17:48:34.000000000 +0000 @@ -71,8 +71,6 @@ void meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, MetaWaylandSurface *surface); -struct wl_client * meta_wayland_keyboard_get_focus_client (MetaWaylandKeyboard *keyboard); - void meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard, struct wl_client *client, struct wl_resource *seat_resource, diff -Nru mutter-46.0/src/wayland/meta-wayland-linux-drm-syncobj.c mutter-46.1/src/wayland/meta-wayland-linux-drm-syncobj.c --- mutter-46.0/src/wayland/meta-wayland-linux-drm-syncobj.c 1970-01-01 00:00:00.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-linux-drm-syncobj.c 2024-04-19 17:48:34.000000000 +0000 @@ -0,0 +1,637 @@ +/* + * Copyright (C) 2023 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Written by: + * Austin Shafer + */ + +#include "config.h" + +#include "backends/native/meta-backend-native-types.h" +#include "backends/native/meta-device-pool.h" +#include "backends/native/meta-renderer-native.h" +#include "meta/util.h" +#include "wayland/meta-wayland-buffer.h" +#include "wayland/meta-wayland-linux-drm-syncobj.h" +#include "wayland/meta-wayland-private.h" +#include +#include + +typedef struct _MetaWaylandDrmSyncobjManager +{ + GObject parent; + + int drm; +} MetaWaylandDrmSyncobjManager; + +typedef struct _MetaWaylandSyncobjSurface +{ + GObject parent; + + struct wl_resource *resource; + MetaWaylandSurface *surface; + gulong surface_destroy_handler_id; +} MetaWaylandSyncobjSurface; + +typedef struct _MetaWaylandSyncobjTimeline +{ + GObject parent; + + MetaDrmTimeline *drm_timeline; +} MetaWaylandSyncobjTimeline; + +#define META_TYPE_WAYLAND_DRM_SYNCOBJ_MANAGER (meta_wayland_drm_syncobj_manager_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandDrmSyncobjManager, meta_wayland_drm_syncobj_manager, + META, WAYLAND_DRM_SYNCOBJ_MANAGER, GObject) + +#define META_TYPE_WAYLAND_SYNCOBJ_SURFACE (meta_wayland_syncobj_surface_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandSyncobjSurface, meta_wayland_syncobj_surface, + META, WAYLAND_SYNCOBJ_SURFACE, GObject) + +#define META_TYPE_WAYLAND_SYNCOBJ_TIMELINE (meta_wayland_syncobj_timeline_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandSyncobjTimeline, meta_wayland_syncobj_timeline, + META, WAYLAND_SYNCOBJ_TIMELINE, GObject) + +#define META_TYPE_WAYLAND_DRM_SYNCOBJ_MANAGER (meta_wayland_drm_syncobj_manager_get_type ()) +G_DEFINE_FINAL_TYPE (MetaWaylandDrmSyncobjManager, meta_wayland_drm_syncobj_manager, + G_TYPE_OBJECT) + +#define META_TYPE_WAYLAND_SYNCOBJ_SURFACE (meta_wayland_syncobj_surface_get_type ()) +G_DEFINE_FINAL_TYPE (MetaWaylandSyncobjSurface, meta_wayland_syncobj_surface, + G_TYPE_OBJECT) + +#define META_TYPE_WAYLAND_SYNCOBJ_TIMELINE (meta_wayland_syncobj_timeline_get_type ()) +G_DEFINE_FINAL_TYPE (MetaWaylandSyncobjTimeline, meta_wayland_syncobj_timeline, + G_TYPE_OBJECT) + +G_DEFINE_FINAL_TYPE (MetaWaylandSyncPoint, meta_wayland_sync_point, G_TYPE_OBJECT); + +static GQuark quark_syncobj_surface; + +static void +meta_wayland_sync_point_set (MetaWaylandSyncPoint **sync_point_ptr, + MetaWaylandSyncobjTimeline *syncobj_timeline, + uint32_t point_hi, + uint32_t point_lo) +{ + MetaWaylandSyncPoint *sync_point; + + if (!*sync_point_ptr) + *sync_point_ptr = g_object_new (META_TYPE_WAYLAND_SYNC_POINT, NULL); + + sync_point = *sync_point_ptr; + g_set_object (&sync_point->timeline, syncobj_timeline); + sync_point->sync_point = (uint64_t)point_hi << 32 | point_lo; +} + +static void +meta_wayland_sync_point_finalize (GObject *object) +{ + MetaWaylandSyncPoint *sync = META_WAYLAND_SYNC_POINT (object); + + g_object_unref (sync->timeline); + + G_OBJECT_CLASS (meta_wayland_sync_point_parent_class)->finalize (object); +} + +static void +meta_wayland_sync_point_init (MetaWaylandSyncPoint *sync) +{ +} + +static void +meta_wayland_sync_point_class_init (MetaWaylandSyncPointClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_wayland_sync_point_finalize; +} + +static void +syncobj_timeline_handle_resource_destroy (struct wl_resource *resource) +{ + MetaWaylandSyncobjTimeline *syncobj_timeline = + wl_resource_get_user_data (resource); + g_object_unref (syncobj_timeline); +} + +static void +meta_wayland_syncobj_timeline_finalize (GObject *object) +{ + MetaWaylandSyncobjTimeline *syncobj_timeline = + META_WAYLAND_SYNCOBJ_TIMELINE (object); + + g_clear_object (&syncobj_timeline->drm_timeline); + + G_OBJECT_CLASS (meta_wayland_syncobj_timeline_parent_class)->finalize (object); +} + +static void +meta_wayland_syncobj_timeline_class_init (MetaWaylandSyncobjTimelineClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_wayland_syncobj_timeline_finalize; +} + +static void +meta_wayland_syncobj_timeline_init (MetaWaylandSyncobjTimeline *syncobj_timeline) +{ + syncobj_timeline->drm_timeline = NULL; +} + +static void +syncobj_timeline_handle_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static const struct wp_linux_drm_syncobj_timeline_v1_interface + syncobj_timeline_implementation = +{ + syncobj_timeline_handle_destroy, +}; + +gboolean +meta_wayland_sync_timeline_set_sync_point (MetaWaylandSyncobjTimeline *timeline, + uint64_t sync_point, + int sync_fd, + GError **error) +{ + return meta_drm_timeline_set_sync_point (timeline->drm_timeline, + sync_point, + sync_fd, + error); +} + +int +meta_wayland_sync_timeline_get_eventfd (MetaWaylandSyncobjTimeline *timeline, + uint64_t sync_point, + GError **error) +{ + return meta_drm_timeline_get_eventfd (timeline->drm_timeline, + sync_point, + error); +} + +static void +syncobj_surface_handle_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +syncobj_surface_handle_set_acquire_point (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *timeline_resource, + uint32_t point_hi, + uint32_t point_lo) +{ + MetaWaylandSyncobjSurface *syncobj_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = syncobj_surface->surface; + MetaWaylandSyncobjTimeline *syncobj_timeline = + wl_resource_get_user_data (timeline_resource); + + if (!surface) + { + wl_resource_post_error (resource, + WP_LINUX_DRM_SYNCOBJ_SURFACE_V1_ERROR_NO_SURFACE, + "Underlying surface object has been destroyed"); + return; + } + + meta_wayland_sync_point_set (&surface->pending_state->drm_syncobj.acquire, + syncobj_timeline, + point_hi, + point_lo); +} + +static void syncobj_surface_handle_set_release_point (struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *timeline_resource, + uint32_t point_hi, + uint32_t point_lo) +{ + MetaWaylandSyncobjSurface *syncobj_surface = wl_resource_get_user_data (resource); + MetaWaylandSurface *surface = syncobj_surface->surface; + MetaWaylandSyncobjTimeline *syncobj_timeline = + wl_resource_get_user_data (timeline_resource); + + if (!surface) + { + wl_resource_post_error (resource, + WP_LINUX_DRM_SYNCOBJ_SURFACE_V1_ERROR_NO_SURFACE, + "Underlying surface object has been destroyed"); + return; + } + + meta_wayland_sync_point_set (&surface->pending_state->drm_syncobj.release, + syncobj_timeline, + point_hi, + point_lo); +} + +static const struct wp_linux_drm_syncobj_surface_v1_interface + syncobj_surface_implementation = +{ + syncobj_surface_handle_destroy, + syncobj_surface_handle_set_acquire_point, + syncobj_surface_handle_set_release_point, +}; + +static void +syncobj_surface_resource_destroyed (MetaWaylandSurface *surface, + MetaWaylandSyncobjSurface *syncobj_surface) +{ + g_clear_signal_handler (&syncobj_surface->surface_destroy_handler_id, + syncobj_surface->surface); + + g_object_set_qdata (G_OBJECT (syncobj_surface->surface), + quark_syncobj_surface, + NULL); + + syncobj_surface->surface = NULL; +} + +static void +syncobj_surface_destructor (struct wl_resource *resource) +{ + MetaWaylandSyncobjSurface *syncobj_surface = + wl_resource_get_user_data (resource); + + if (syncobj_surface->surface) + syncobj_surface_resource_destroyed (syncobj_surface->surface, syncobj_surface); + + g_object_unref (syncobj_surface); +} + +static void +meta_wayland_syncobj_surface_class_init (MetaWaylandSyncobjSurfaceClass *klass) +{ +} + +static void +meta_wayland_syncobj_surface_init (MetaWaylandSyncobjSurface *syncobj_surface) +{ +} + +static void +drm_syncobj_manager_handle_destroy (struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy (resource); +} + +static void +drm_syncobj_manager_handle_get_surface (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource) +{ + MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandSyncobjSurface *syncobj_surface = + g_object_get_qdata (G_OBJECT (surface), quark_syncobj_surface); + struct wl_resource *sync_resource; + + if (syncobj_surface) + { + wl_resource_post_error (surface_resource, + WP_LINUX_DRM_SYNCOBJ_MANAGER_V1_ERROR_SURFACE_EXISTS, + "DRM Syncobj surface object already created for surface %d", + wl_resource_get_id (surface_resource)); + return; + } + + sync_resource = + wl_resource_create (client, + &wp_linux_drm_syncobj_surface_v1_interface, + wl_resource_get_version (resource), + id); + if (sync_resource == NULL) + { + wl_resource_post_no_memory (resource); + return; + } + + syncobj_surface = g_object_new (META_TYPE_WAYLAND_SYNCOBJ_SURFACE, NULL); + syncobj_surface->surface = surface; + syncobj_surface->surface_destroy_handler_id = + g_signal_connect (surface, + "destroy", + G_CALLBACK (syncobj_surface_resource_destroyed), + syncobj_surface); + + g_object_set_qdata (G_OBJECT (surface), + quark_syncobj_surface, + syncobj_surface); + + wl_resource_set_implementation (sync_resource, + &syncobj_surface_implementation, + syncobj_surface, + syncobj_surface_destructor); + syncobj_surface->resource = sync_resource; +} + +static void +drm_syncobj_manager_handle_import_timeline (struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + int drm_syncobj_fd) +{ + MetaWaylandDrmSyncobjManager *drm_syncobj = wl_resource_get_user_data (resource); + g_autoptr (GError) error = NULL; + g_autoptr (MetaDrmTimeline) drm_timeline = NULL; + g_autoptr (MetaWaylandSyncobjTimeline) syncobj_timeline = NULL; + struct wl_resource *timeline_resource; + + drm_timeline = meta_drm_timeline_import_syncobj (drm_syncobj->drm, + drm_syncobj_fd, + &error); + close (drm_syncobj_fd); + if (!drm_timeline) + { + wl_resource_post_error (resource, + WP_LINUX_DRM_SYNCOBJ_MANAGER_V1_ERROR_INVALID_TIMELINE, + "Failed to import DRM syncobj: %s", + error->message); + return; + } + + syncobj_timeline = g_object_new (META_TYPE_WAYLAND_SYNCOBJ_TIMELINE, NULL); + + timeline_resource = wl_resource_create (client, + &wp_linux_drm_syncobj_timeline_v1_interface, + wl_resource_get_version (resource), + id); + if (timeline_resource == NULL) + { + wl_resource_post_no_memory (resource); + return; + } + + syncobj_timeline->drm_timeline = g_steal_pointer (&drm_timeline); + wl_resource_set_implementation (timeline_resource, + &syncobj_timeline_implementation, + g_steal_pointer (&syncobj_timeline), + syncobj_timeline_handle_resource_destroy); +} + +static const struct wp_linux_drm_syncobj_manager_v1_interface + drm_syncobj_manager_implementation = +{ + drm_syncobj_manager_handle_destroy, + drm_syncobj_manager_handle_get_surface, + drm_syncobj_manager_handle_import_timeline, +}; + +static void +meta_wayland_drm_syncobj_manager_finalize (GObject *object) +{ + MetaWaylandDrmSyncobjManager *drm_syncobj = + META_WAYLAND_DRM_SYNCOBJ_MANAGER (object); + + g_clear_fd (&drm_syncobj->drm, NULL); + + G_OBJECT_CLASS (meta_wayland_drm_syncobj_manager_parent_class)->finalize (object); +} + +static void +meta_wayland_drm_syncobj_manager_class_init (MetaWaylandDrmSyncobjManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_wayland_drm_syncobj_manager_finalize; + + quark_syncobj_surface = g_quark_from_static_string ("drm-syncobj-quark"); +} + +static void +meta_wayland_drm_syncobj_manager_init (MetaWaylandDrmSyncobjManager *drm_syncobj) +{ + drm_syncobj->drm = -1; +} + +static void +drm_syncobj_manager_bind (struct wl_client *client, + void *user_data, + uint32_t version, + uint32_t id) +{ + MetaWaylandDrmSyncobjManager *drm_syncobj_manager = user_data; + struct wl_resource *resource; + + resource = wl_resource_create (client, + &wp_linux_drm_syncobj_manager_v1_interface, + version, + id); + wl_resource_set_implementation (resource, + &drm_syncobj_manager_implementation, + drm_syncobj_manager, + NULL); +} + +static MetaWaylandDrmSyncobjManager * +meta_wayland_drm_syncobj_manager_new (MetaWaylandCompositor *compositor, + GError **error) +{ + MetaContext *context = + meta_wayland_compositor_get_context (compositor); + MetaBackend *backend = meta_context_get_backend (context); + MetaEgl *egl = meta_backend_get_egl (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); + EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context); + MetaWaylandDrmSyncobjManager *drm_syncobj_manager; + EGLDeviceEXT egl_device; + g_autofd int drm_fd = -1; + EGLAttrib attrib; + uint64_t timeline_supported = false; + const char *device_path = NULL; + + g_assert (backend && egl && clutter_backend && cogl_context && egl_display); + + if (!meta_egl_query_display_attrib (egl, egl_display, + EGL_DEVICE_EXT, &attrib, + error)) + return NULL; + + egl_device = (EGLDeviceEXT) attrib; + + if (meta_egl_egl_device_has_extensions (egl, egl_device, NULL, + "EGL_EXT_device_drm_render_node", + NULL)) + { + if (!meta_egl_query_device_string (egl, egl_device, + EGL_DRM_RENDER_NODE_FILE_EXT, + &device_path, error)) + return NULL; + } + + if (!device_path && + meta_egl_egl_device_has_extensions (egl, egl_device, NULL, + "EGL_EXT_device_drm", + NULL)) + { + if (!meta_egl_query_device_string (egl, egl_device, + EGL_DRM_DEVICE_FILE_EXT, + &device_path, error)) + return NULL; + } + + if (!device_path) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "Failed to find EGL device to initialize linux-drm-syncobj-v1"); + return NULL; + } + + drm_fd = open (device_path, O_RDWR | O_CLOEXEC); + if (drm_fd < 0) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Failed to open DRM device %s", + device_path); + return NULL; + } + + if (drmGetCap (drm_fd, DRM_CAP_SYNCOBJ_TIMELINE, &timeline_supported) != 0 + || !timeline_supported) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "Failed to check DRM syncobj timeline capability"); + return NULL; + } + +#ifdef HAVE_EVENTFD + if (drmSyncobjEventfd (drm_fd, 0, 0, -1, 0) != -1 || errno != ENOENT) +#endif + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "drmSyncobjEventfd failed: linux-drm-syncobj requires eventfd support"); + return NULL; + } + + drm_syncobj_manager = g_object_new (META_TYPE_WAYLAND_DRM_SYNCOBJ_MANAGER, NULL); + drm_syncobj_manager->drm = g_steal_fd (&drm_fd); + + if (!wl_global_create (compositor->wayland_display, + &wp_linux_drm_syncobj_manager_v1_interface, + 1, + drm_syncobj_manager, + drm_syncobj_manager_bind)) + { + g_error ("Failed to create wp_linux_drm_syncobj_manager_v1_interface global"); + } + + return drm_syncobj_manager; +} + +void +meta_wayland_drm_syncobj_init (MetaWaylandCompositor *compositor) +{ + g_autoptr (GError) error = NULL; + MetaWaylandDrmSyncobjManager *manager = + meta_wayland_drm_syncobj_manager_new (compositor, &error); + + if (!manager) + { + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) + { + meta_topic (META_DEBUG_WAYLAND, "Disabling explicit sync: %s", + error->message); + } + else + { + g_warning ("Failed to create linux-drm-syncobj-manager: %s", + error->message); + } + return; + } + + g_object_set_data_full (G_OBJECT (compositor), "-meta-wayland-drm-syncobj-manager", + manager, + g_object_unref); +} + +/* + * Validate that the appropriate acquire and release points have been set + * for this surface. + */ +bool +meta_wayland_surface_explicit_sync_validate (MetaWaylandSurface *surface, + MetaWaylandSurfaceState *state) +{ + MetaWaylandSyncobjSurface *syncobj_surface = g_object_get_qdata (G_OBJECT (surface), + quark_syncobj_surface); + + if (!syncobj_surface) + return TRUE; + + if (state->buffer) + { + if (state->buffer->type != META_WAYLAND_BUFFER_TYPE_DMA_BUF) + { + wl_resource_post_error (syncobj_surface->resource, + WP_LINUX_DRM_SYNCOBJ_SURFACE_V1_ERROR_UNSUPPORTED_BUFFER, + "Explicit Sync only supported on dmabuf buffers"); + return FALSE; + } + + if (!state->drm_syncobj.acquire) + { + wl_resource_post_error (syncobj_surface->resource, + WP_LINUX_DRM_SYNCOBJ_SURFACE_V1_ERROR_NO_ACQUIRE_POINT, + "No Acquire point provided"); + return FALSE; + } + + if (!state->drm_syncobj.release) + { + wl_resource_post_error (syncobj_surface->resource, + WP_LINUX_DRM_SYNCOBJ_SURFACE_V1_ERROR_NO_RELEASE_POINT, + "No Release point provided"); + return FALSE; + } + + if (state->drm_syncobj.acquire->timeline == state->drm_syncobj.release->timeline && + state->drm_syncobj.acquire->sync_point >= state->drm_syncobj.release->sync_point) + { + wl_resource_post_error (syncobj_surface->resource, + WP_LINUX_DRM_SYNCOBJ_SURFACE_V1_ERROR_CONFLICTING_POINTS, + "Invalid Release and Acquire point combination"); + return FALSE; + } + } + else if (state->drm_syncobj.acquire || state->drm_syncobj.release) + { + wl_resource_post_error (syncobj_surface->resource, + WP_LINUX_DRM_SYNCOBJ_SURFACE_V1_ERROR_NO_BUFFER, + "Release or Acquire point set but no buffer attached"); + return FALSE; + } + + return TRUE; +} diff -Nru mutter-46.0/src/wayland/meta-wayland-linux-drm-syncobj.h mutter-46.1/src/wayland/meta-wayland-linux-drm-syncobj.h --- mutter-46.0/src/wayland/meta-wayland-linux-drm-syncobj.h 1970-01-01 00:00:00.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-linux-drm-syncobj.h 2024-04-19 17:48:34.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Written by: + * Austin Shafer + */ + +#pragma once + +#include + +#include "wayland/meta-wayland-types.h" +#include "wayland/meta-drm-timeline.h" + +#include "linux-drm-syncobj-v1-server-protocol.h" + +#define META_TYPE_WAYLAND_SYNC_POINT (meta_wayland_sync_point_get_type ()) +G_DECLARE_FINAL_TYPE (MetaWaylandSyncPoint, + meta_wayland_sync_point, + META, WAYLAND_SYNC_POINT, + GObject) + +typedef struct _MetaWaylandSyncPoint { + GObject parent; + + MetaWaylandSyncobjTimeline *timeline; + uint64_t sync_point; +} MetaWaylandSyncPoint; + +bool +meta_wayland_surface_explicit_sync_validate (MetaWaylandSurface *surface, + MetaWaylandSurfaceState *state); + +void +meta_wayland_drm_syncobj_init (MetaWaylandCompositor *compositor); + +gboolean +meta_wayland_sync_timeline_set_sync_point (MetaWaylandSyncobjTimeline *timeline, + uint64_t sync_point, + int sync_fd, + GError **error); + +int +meta_wayland_sync_timeline_get_eventfd (MetaWaylandSyncobjTimeline *timeline, + uint64_t sync_point, + GError **error); diff -Nru mutter-46.0/src/wayland/meta-wayland-seat.c mutter-46.1/src/wayland/meta-wayland-seat.c --- mutter-46.0/src/wayland/meta-wayland-seat.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-seat.c 2024-04-19 17:48:34.000000000 +0000 @@ -224,8 +224,8 @@ if (meta_wayland_seat_has_keyboard (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_sync_focus (&seat->data_device); + meta_wayland_data_device_primary_sync_focus (&seat->primary_data_device); meta_wayland_tablet_seat_set_pad_focus (seat->tablet_seat, surface); meta_wayland_text_input_set_focus (seat->text_input, surface); } @@ -531,6 +531,8 @@ meta_wayland_seat_set_input_focus (MetaWaylandSeat *seat, MetaWaylandSurface *surface) { + ClutterSeat *clutter_seat; + if (seat->input_focus == surface) return; @@ -551,16 +553,10 @@ seat); } - if (meta_wayland_seat_has_keyboard (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_tablet_seat_set_pad_focus (seat->tablet_seat, surface); - - meta_wayland_text_input_set_focus (seat->text_input, surface); + clutter_seat = clutter_backend_get_default_seat (clutter_get_default_backend ()); + meta_wayland_input_invalidate_focus (seat->input_handler, + clutter_seat_get_keyboard (clutter_seat), + NULL); } MetaWaylandSurface * @@ -724,3 +720,12 @@ return NULL; } + +struct wl_client * +meta_wayland_seat_get_input_focus_client (MetaWaylandSeat *seat) +{ + if (seat->input_focus) + return wl_resource_get_client (seat->input_focus->resource); + else + return NULL; +} diff -Nru mutter-46.0/src/wayland/meta-wayland-seat.h mutter-46.1/src/wayland/meta-wayland-seat.h --- mutter-46.0/src/wayland/meta-wayland-seat.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-seat.h 2024-04-19 17:48:34.000000000 +0000 @@ -98,3 +98,5 @@ MetaWaylandSurface * meta_wayland_seat_get_current_surface (MetaWaylandSeat *seat, ClutterInputDevice *device, ClutterEventSequence *sequence); + +struct wl_client * meta_wayland_seat_get_input_focus_client (MetaWaylandSeat *seat); diff -Nru mutter-46.0/src/wayland/meta-wayland-single-pixel-buffer.c mutter-46.1/src/wayland/meta-wayland-single-pixel-buffer.c --- mutter-46.0/src/wayland/meta-wayland-single-pixel-buffer.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-single-pixel-buffer.c 2024-04-19 17:48:34.000000000 +0000 @@ -122,7 +122,10 @@ CoglTexture *tex_2d; if (buffer->single_pixel.texture) - return TRUE; + { + *texture = g_object_ref (buffer->single_pixel.texture); + return TRUE; + } data[0] = single_pixel_buffer->b / (UINT32_MAX / 0xff); data[1] = single_pixel_buffer->g / (UINT32_MAX / 0xff); diff -Nru mutter-46.0/src/wayland/meta-wayland-surface-private.h mutter-46.1/src/wayland/meta-wayland-surface-private.h --- mutter-46.0/src/wayland/meta-wayland-surface-private.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-surface-private.h 2024-04-19 17:48:34.000000000 +0000 @@ -29,6 +29,7 @@ #include "meta/meta-wayland-surface.h" #include "wayland/meta-wayland-pointer-constraints.h" #include "wayland/meta-wayland-types.h" +#include "wayland/meta-wayland-linux-drm-syncobj.h" #define META_TYPE_WAYLAND_SURFACE_ROLE (meta_wayland_surface_role_get_type ()) G_DECLARE_DERIVABLE_TYPE (MetaWaylandSurfaceRole, meta_wayland_surface_role, @@ -128,6 +129,12 @@ /* xdg_popup */ MetaWaylandXdgPositioner *xdg_positioner; uint32_t xdg_popup_reposition_token; + + /* Explicit Synchronization */ + struct { + MetaWaylandSyncPoint *acquire; + MetaWaylandSyncPoint *release; + } drm_syncobj; }; struct _MetaWaylandDragDestFuncs diff -Nru mutter-46.0/src/wayland/meta-wayland-surface.c mutter-46.1/src/wayland/meta-wayland-surface.c --- mutter-46.0/src/wayland/meta-wayland-surface.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-surface.c 2024-04-19 17:48:34.000000000 +0000 @@ -48,6 +48,7 @@ #include "wayland/meta-wayland-viewporter.h" #include "wayland/meta-wayland-xdg-shell.h" #include "wayland/meta-window-wayland.h" +#include "wayland/meta-wayland-linux-drm-syncobj.h" #ifdef HAVE_XWAYLAND #include "wayland/meta-xwayland-private.h" @@ -446,6 +447,9 @@ wl_list_init (&state->presentation_feedback_list); state->xdg_popup_reposition_token = 0; + + state->drm_syncobj.acquire = NULL; + state->drm_syncobj.release = NULL; } static void @@ -466,6 +470,8 @@ MetaWaylandFrameCallback *cb, *next; g_clear_object (&state->texture); + g_clear_object (&state->drm_syncobj.acquire); + g_clear_object (&state->drm_syncobj.release); g_clear_pointer (&state->surface_damage, mtk_region_unref); g_clear_pointer (&state->buffer_damage, mtk_region_unref); @@ -630,6 +636,11 @@ to->xdg_positioner = g_steal_pointer (&from->xdg_positioner); to->xdg_popup_reposition_token = from->xdg_popup_reposition_token; } + + g_set_object (&to->drm_syncobj.acquire, from->drm_syncobj.acquire); + g_clear_object (&from->drm_syncobj.acquire); + g_set_object (&to->drm_syncobj.release, from->drm_syncobj.release); + g_clear_object (&from->drm_syncobj.release); } static void @@ -914,6 +925,7 @@ MetaWaylandBuffer *buffer = pending->buffer; MetaWaylandTransaction *transaction; MetaWaylandSurface *subsurface_surface; + MetaWaylandSyncPoint *release_point = pending->drm_syncobj.release; COGL_TRACE_BEGIN_SCOPED (MetaWaylandSurfaceCommit, "Meta::WaylandSurface::commit()"); @@ -921,6 +933,9 @@ if (pending->scale > 0) surface->committed_state.scale = pending->scale; + if (!meta_wayland_surface_explicit_sync_validate (surface, pending)) + return; + if (buffer) { g_autoptr (GError) error = NULL; @@ -946,6 +961,9 @@ pending->texture = g_object_ref (surface->committed_state.texture); + if (release_point) + g_ptr_array_add (buffer->release_points, g_object_ref (release_point)); + g_object_ref (buffer); meta_wayland_buffer_inc_use_count (buffer); } diff -Nru mutter-46.0/src/wayland/meta-wayland-touch.c mutter-46.1/src/wayland/meta-wayland-touch.c --- mutter-46.0/src/wayland/meta-wayland-touch.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-touch.c 2024-04-19 17:48:34.000000000 +0000 @@ -270,6 +270,9 @@ touch_info->slot_serial = meta_wayland_input_device_next_serial (input_device); + + if (event_type == CLUTTER_TOUCH_BEGIN) + touch->latest_touch_down_serial = touch_info->slot_serial; } touch_get_relative_coordinates (touch, touch_info->touch_surface->surface, @@ -524,6 +527,8 @@ touch->touches = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) touch_info_free); + touch->latest_touch_down_serial = 0; + wl_list_init (&touch->resource_list); } @@ -534,6 +539,8 @@ g_clear_pointer (&touch->touch_surfaces, g_hash_table_unref); g_clear_pointer (&touch->touches, g_hash_table_unref); + + touch->latest_touch_down_serial = 0; } void @@ -559,8 +566,10 @@ if (!touch->touches) return FALSE; - g_hash_table_iter_init (&iter, touch->touches); + if (touch->latest_touch_down_serial == serial) + return TRUE; + g_hash_table_iter_init (&iter, touch->touches); while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &touch_info)) { if (touch_info->slot_serial == serial) diff -Nru mutter-46.0/src/wayland/meta-wayland-touch.h mutter-46.1/src/wayland/meta-wayland-touch.h --- mutter-46.0/src/wayland/meta-wayland-touch.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-touch.h 2024-04-19 17:48:34.000000000 +0000 @@ -40,6 +40,8 @@ struct wl_list resource_list; + uint32_t latest_touch_down_serial; + guint queued_frame_id; GHashTable *touch_surfaces; /* HT of MetaWaylandSurface->MetaWaylandTouchSurface */ GHashTable *touches; /* HT of sequence->MetaWaylandTouchInfo */ diff -Nru mutter-46.0/src/wayland/meta-wayland-transaction.c mutter-46.1/src/wayland/meta-wayland-transaction.c --- mutter-46.0/src/wayland/meta-wayland-transaction.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-transaction.c 2024-04-19 17:48:34.000000000 +0000 @@ -26,6 +26,7 @@ #include "wayland/meta-wayland.h" #include "wayland/meta-wayland-buffer.h" #include "wayland/meta-wayland-dma-buf.h" +#include "wayland/meta-wayland-linux-drm-syncobj.h" #define META_WAYLAND_TRANSACTION_NONE ((void *)(uintptr_t) G_MAXSIZE) @@ -314,6 +315,17 @@ meta_wayland_transaction_maybe_apply (transaction); } +static void +ensure_buf_sources (MetaWaylandTransaction *transaction) +{ + if (!transaction->buf_sources) + { + transaction->buf_sources = + g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) g_source_destroy); + } +} + static gboolean meta_wayland_transaction_add_dma_buf_source (MetaWaylandTransaction *transaction, MetaWaylandBuffer *buffer) @@ -330,12 +342,35 @@ if (!source) return FALSE; - if (!transaction->buf_sources) - { - transaction->buf_sources = - g_hash_table_new_full (NULL, NULL, NULL, - (GDestroyNotify) g_source_destroy); - } + ensure_buf_sources (transaction); + + g_hash_table_insert (transaction->buf_sources, buffer, source); + g_source_attach (source, NULL); + g_source_unref (source); + + return TRUE; +} + +static gboolean +meta_wayland_transaction_add_drm_syncobj_source (MetaWaylandTransaction *transaction, + MetaWaylandBuffer *buffer, + MetaWaylandSyncPoint *acquire) +{ + GSource *source; + + if (transaction->buf_sources && + g_hash_table_contains (transaction->buf_sources, buffer)) + return FALSE; + + source = meta_wayland_drm_syncobj_create_source (buffer, + acquire->timeline, + acquire->sync_point, + meta_wayland_transaction_dma_buf_dispatch, + transaction); + if (!source) + return FALSE; + + ensure_buf_sources (transaction); g_hash_table_insert (transaction->buf_sources, buffer, source); g_source_attach (source, NULL); @@ -382,8 +417,11 @@ { MetaWaylandBuffer *buffer = entry->state->buffer; - if (buffer && - meta_wayland_transaction_add_dma_buf_source (transaction, buffer)) + if ((entry->state->drm_syncobj.acquire && + meta_wayland_transaction_add_drm_syncobj_source (transaction, buffer, + entry->state->drm_syncobj.acquire)) + || (buffer && + meta_wayland_transaction_add_dma_buf_source (transaction, buffer))) maybe_apply = FALSE; if (entry->state->subsurface_placement_ops) diff -Nru mutter-46.0/src/wayland/meta-wayland-types.h mutter-46.1/src/wayland/meta-wayland-types.h --- mutter-46.0/src/wayland/meta-wayland-types.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-types.h 2024-04-19 17:48:34.000000000 +0000 @@ -60,6 +60,8 @@ typedef struct _MetaWaylandDmaBufManager MetaWaylandDmaBufManager; +typedef struct _MetaWaylandSyncobjTimeline MetaWaylandSyncobjTimeline; + typedef struct _MetaWaylandXdgPositioner MetaWaylandXdgPositioner; typedef struct _MetaXWaylandManager MetaXWaylandManager; diff -Nru mutter-46.0/src/wayland/meta-wayland-window-configuration.c mutter-46.1/src/wayland/meta-wayland-window-configuration.c --- mutter-46.0/src/wayland/meta-wayland-window-configuration.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-window-configuration.c 2024-04-19 17:48:34.000000000 +0000 @@ -100,14 +100,15 @@ MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new_empty (int bounds_width, - int bounds_height) + int bounds_height, + int scale) { MetaWaylandWindowConfiguration *configuration; configuration = g_new0 (MetaWaylandWindowConfiguration, 1); *configuration = (MetaWaylandWindowConfiguration) { .serial = ++global_serial_counter, - .scale = 1, + .scale = scale, .bounds_width = bounds_width, .bounds_height = bounds_height, }; diff -Nru mutter-46.0/src/wayland/meta-wayland-window-configuration.h mutter-46.1/src/wayland/meta-wayland-window-configuration.h --- mutter-46.0/src/wayland/meta-wayland-window-configuration.h 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-window-configuration.h 2024-04-19 17:48:34.000000000 +0000 @@ -68,6 +68,7 @@ int scale); MetaWaylandWindowConfiguration * meta_wayland_window_configuration_new_empty (int bounds_width, - int bounds_height); + int bounds_height, + int scale); void meta_wayland_window_configuration_free (MetaWaylandWindowConfiguration *configuration); diff -Nru mutter-46.0/src/wayland/meta-wayland-xdg-shell.c mutter-46.1/src/wayland/meta-wayland-xdg-shell.c --- mutter-46.0/src/wayland/meta-wayland-xdg-shell.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland-xdg-shell.c 2024-04-19 17:48:34.000000000 +0000 @@ -869,6 +869,9 @@ MetaWaylandWindowConfiguration *configuration; int bounds_width; int bounds_height; + int geometry_scale; + + geometry_scale = meta_window_wayland_get_geometry_scale (window); if (!meta_window_calculate_bounds (window, &bounds_width, &bounds_height)) { @@ -878,7 +881,8 @@ configuration = meta_wayland_window_configuration_new_empty (bounds_width, - bounds_height); + bounds_height, + geometry_scale); meta_wayland_xdg_toplevel_send_configure (xdg_toplevel, configuration); meta_wayland_window_configuration_free (configuration); return; diff -Nru mutter-46.0/src/wayland/meta-wayland.c mutter-46.1/src/wayland/meta-wayland.c --- mutter-46.0/src/wayland/meta-wayland.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/wayland/meta-wayland.c 2024-04-19 17:48:34.000000000 +0000 @@ -57,6 +57,7 @@ #include "wayland/meta-wayland-tablet-manager.h" #include "wayland/meta-wayland-transaction.h" #include "wayland/meta-wayland-xdg-foreign.h" +#include "wayland/meta-wayland-linux-drm-syncobj.h" #ifdef HAVE_XWAYLAND #include "wayland/meta-wayland-x11-interop.h" @@ -868,6 +869,7 @@ meta_wayland_activation_init (compositor); meta_wayland_transaction_init (compositor); meta_wayland_idle_inhibit_init (compositor); + meta_wayland_drm_syncobj_init (compositor); #ifdef HAVE_WAYLAND_EGLSTREAM { diff -Nru mutter-46.0/src/wayland/protocol/linux-drm-syncobj-v1.xml mutter-46.1/src/wayland/protocol/linux-drm-syncobj-v1.xml --- mutter-46.0/src/wayland/protocol/linux-drm-syncobj-v1.xml 1970-01-01 00:00:00.000000000 +0000 +++ mutter-46.1/src/wayland/protocol/linux-drm-syncobj-v1.xml 2024-04-19 17:48:34.000000000 +0000 @@ -0,0 +1,261 @@ + + + + Copyright 2016 The Chromium Authors. + Copyright 2017 Intel Corporation + Copyright 2018 Collabora, Ltd + Copyright 2021 Simon Ser + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol allows clients to request explicit synchronization for + buffers. It is tied to the Linux DRM synchronization object framework. + + Synchronization refers to co-ordination of pipelined operations performed + on buffers. Most GPU clients will schedule an asynchronous operation to + render to the buffer, then immediately send the buffer to the compositor + to be attached to a surface. + + With implicit synchronization, ensuring that the rendering operation is + complete before the compositor displays the buffer is an implementation + detail handled by either the kernel or userspace graphics driver. + + By contrast, with explicit synchronization, DRM synchronization object + timeline points mark when the asynchronous operations are complete. When + submitting a buffer, the client provides a timeline point which will be + waited on before the compositor accesses the buffer, and another timeline + point that the compositor will signal when it no longer needs to access the + buffer contents for the purposes of the surface commit. + + Linux DRM synchronization objects are documented at: + https://dri.freedesktop.org/docs/drm/gpu/drm-mm.html#drm-sync-objects + + Warning! The protocol described in this file is currently in the testing + phase. Backward compatible changes may be added together with the + corresponding interface version bump. Backward incompatible changes can + only be done by creating a new major version of the extension. + + + + + This global is a factory interface, allowing clients to request + explicit synchronization for buffers on a per-surface basis. + + See wp_linux_drm_syncobj_surface_v1 for more information. + + + + + Destroy this explicit synchronization factory object. Other objects + shall not be affected by this request. + + + + + + + + + + + Instantiate an interface extension for the given wl_surface to provide + explicit synchronization. + + If the given wl_surface already has an explicit synchronization object + associated, the surface_exists protocol error is raised. + + Graphics APIs, like EGL or Vulkan, that manage the buffer queue and + commits of a wl_surface themselves, are likely to be using this + extension internally. If a client is using such an API for a + wl_surface, it should not directly use this extension on that surface, + to avoid raising a surface_exists protocol error. + + + + + + + + Import a DRM synchronization object timeline. + + If the FD cannot be imported, the invalid_timeline error is raised. + + + + + + + + + This object represents an explicit synchronization object timeline + imported by the client to the compositor. + + + + + Destroy the synchronization object timeline. Other objects are not + affected by this request, in particular timeline points set by + set_acquire_point and set_release_point are not unset. + + + + + + + This object is an add-on interface for wl_surface to enable explicit + synchronization. + + Each surface can be associated with only one object of this interface at + any time. + + Explicit synchronization is guaranteed to be supported for buffers + created with any version of the linux-dmabuf protocol. Compositors are + free to support explicit synchronization for additional buffer types. + If at surface commit time the attached buffer does not support explicit + synchronization, an unsupported_buffer error is raised. + + As long as the wp_linux_drm_syncobj_surface_v1 object is alive, the + compositor may ignore implicit synchronization for buffers attached and + committed to the wl_surface. The delivery of wl_buffer.release events + for buffers attached to the surface becomes undefined. + + Clients must set both acquire and release points if and only if a + non-null buffer is attached in the same surface commit. See the + no_buffer, no_acquire_point and no_release_point protocol errors. + + If at surface commit time the acquire and release DRM syncobj timelines + are identical, the acquire point value must be strictly less than the + release point value, or else the conflicting_points protocol error is + raised. + + + + + Destroy this surface synchronization object. + + Any timeline point set by this object with set_acquire_point or + set_release_point since the last commit may be discarded by the + compositor. Any timeline point set by this object before the last + commit will not be affected. + + + + + + + + + + + + + + + Set the timeline point that must be signalled before the compositor may + sample from the buffer attached with wl_surface.attach. + + The 64-bit unsigned value combined from point_hi and point_lo is the + point value. + + The acquire point is double-buffered state, and will be applied on the + next wl_surface.commit request for the associated surface. Thus, it + applies only to the buffer that is attached to the surface at commit + time. + + If an acquire point has already been attached during the same commit + cycle, the new point replaces the old one. + + If the associated wl_surface was destroyed, a no_surface error is + raised. + + If at surface commit time there is a pending acquire timeline point set + but no pending buffer attached, a no_buffer error is raised. If at + surface commit time there is a pending buffer attached but no pending + acquire timeline point set, the no_acquire_point protocol error is + raised. + + + + + + + + + Set the timeline point that must be signalled by the compositor when it + has finished its usage of the buffer attached with wl_surface.attach + for the relevant commit. + + Once the timeline point is signaled, and assuming the associated buffer + is not pending release from other wl_surface.commit requests, no + additional explicit or implicit synchronization with the compositor is + required to safely re-use the buffer. + + Note that clients cannot rely on the release point being always + signaled after the acquire point: compositors may release buffers + without ever reading from them. In addition, the compositor may use + different presentation paths for different commits, which may have + different release behavior. As a result, the compositor may signal the + release points in a different order than the client committed them. + + Because signaling a timeline point also signals every previous point, + it is generally not safe to use the same timeline object for the + release points of multiple buffers. The out-of-order signaling + described above may lead to a release point being signaled before the + compositor has finished reading. To avoid this, it is strongly + recommended that each buffer should use a separate timeline for its + release points. + + The 64-bit unsigned value combined from point_hi and point_lo is the + point value. + + The release point is double-buffered state, and will be applied on the + next wl_surface.commit request for the associated surface. Thus, it + applies only to the buffer that is attached to the surface at commit + time. + + If a release point has already been attached during the same commit + cycle, the new point replaces the old one. + + If the associated wl_surface was destroyed, a no_surface error is + raised. + + If at surface commit time there is a pending release timeline point set + but no pending buffer attached, a no_buffer error is raised. If at + surface commit time there is a pending buffer attached but no pending + release timeline point set, the no_release_point protocol error is + raised. + + + + + + + diff -Nru mutter-46.0/src/x11/window-x11.c mutter-46.1/src/x11/window-x11.c --- mutter-46.0/src/x11/window-x11.c 2024-03-16 13:43:07.000000000 +0000 +++ mutter-46.1/src/x11/window-x11.c 2024-04-19 17:48:34.000000000 +0000 @@ -2458,8 +2458,8 @@ else if (n_rects == 1 && (rects[0].x == 0 && rects[0].y == 0 && - rects[0].width == priv->client_rect.width && - rects[0].height == priv->client_rect.height)) + rects[0].width == window->buffer_rect.width && + rects[0].height == window->buffer_rect.height)) { /* This is the bounding region case. Keep the * region as NULL. */ @@ -2476,21 +2476,20 @@ if (region != NULL) { - MtkRectangle client_area; + MtkRectangle bounding_rect; - client_area.x = 0; - client_area.y = 0; - client_area.width = window->buffer_rect.width; - client_area.height = window->buffer_rect.height; + bounding_rect.x = 0; + bounding_rect.y = 0; + bounding_rect.width = window->buffer_rect.width; + bounding_rect.height = window->buffer_rect.height; /* The shape we get back from the client may have coordinates * outside of the frame. The X SHAPE Extension requires that * the overall shape the client provides never exceeds the * "bounding rectangle" of the window -- the shape that the - * window would have gotten if it was unshaped. In our case, - * this is simply the client area. + * window would have gotten if it was unshaped. */ - mtk_region_intersect_rectangle (region, &client_area); + mtk_region_intersect_rectangle (region, &bounding_rect); } meta_window_set_input_region (window, region);