Skip to content
Commits on Source (22)
build-aux
compile
config.h
config.h.in
ltmain.sh
missing
50-mutter-navigation.xml
50-mutter-system.xml
50-mutter-windows.xml
mutter.desktop
mutter-wayland.desktop
*.o
*.a
*.lo
*.la
.libs
*.swp
*.gir
*.typelib
*.gmo
*.make
*.log
*.trs
*~
POTFILES
Makevars.template
po/*.header
po/*.pot
po/*.sed
po/*.sin
Rules-quot
libmutter.pc
mutter
mutter-restart-helper
mutter-test-client
mutter-test-runner
mutter-test-unit-tests
mutter-test-headless-start-test
mutter-all.test
org.gnome.mutter.gschema.valid
org.gnome.mutter.gschema.xml
org.gnome.mutter.wayland.gschema.valid
org.gnome.mutter.wayland.gschema.xml
testasyncgetprop
testboxes
testgradient
INSTALL
meta-enum-types.[ch]
src/stamp-meta-enum-types.h
src/meta-dbus-display-config.[ch]
src/meta-dbus-idle-monitor.[ch]
src/meta-dbus-login1.[ch]
src/meta-dbus-remote-desktop.[ch]
src/meta-dbus-screen-cast.[ch]
src/gtk-primary-selection-protocol.c
src/gtk-primary-selection-server-protocol.h
src/gtk-shell-protocol.c
src/gtk-shell-server-protocol.h
src/xdg-shell-unstable-v*-protocol.c
src/xdg-shell-unstable-v*-server-protocol.h
src/pointer-gestures-unstable-v*-protocol.c
src/pointer-gestures-unstable-v*-server-protocol.h
src/relative-pointer-unstable-v*-protocol.c
src/relative-pointer-unstable-v*-server-protocol.h
src/pointer-constraints-unstable-v*-protocol.c
src/pointer-constraints-unstable-v*-server-protocol.h
src/xdg-foreign-unstable-v*-protocol.c
src/xdg-foreign-unstable-v*-server-protocol.h
src/xdg-output-unstable-v1-protocol.c
src/xdg-output-unstable-v1-server-protocol.h
src/xwayland-keyboard-grab-unstable-v1-protocol.c
src/xwayland-keyboard-grab-unstable-v1-server-protocol.h
src/tablet-unstable-v*-protocol.c
src/tablet-unstable-v*-server-protocol.h
src/text-input-unstable-v*-protocol.c
src/text-input-unstable-v*-server-protocol.h
src/keyboard-shortcuts-inhibit-unstable-v*-protocol.c
src/keyboard-shortcuts-inhibit-unstable-v*-server-protocol.h
src/linux-dmabuf-unstable-v*-protocol.c
src/linux-dmabuf-unstable-v*-server-protocol.h
src/xdg-shell-protocol.c
src/xdg-shell-server-protocol.h
src/wayland-eglstream-controller-server-protocol.h
src/meta/meta-version.h
src/libmutter-*.pc
doc/reference/*.args
doc/reference/*.bak
doc/reference/*.hierarchy
doc/reference/*.interfaces
doc/reference/*.prerequisites
doc/reference/*.signals
doc/reference/*.stamp
doc/reference/html/
doc/reference/xml/
doc/reference/meta-decl-list.txt
doc/reference/meta-decl.txt
doc/reference/meta-overrides.txt
doc/reference/meta-undeclared.txt
doc/reference/meta-undocumented.txt
doc/reference/meta-unused.txt
doc/reference/meta-docs.sgml
doc/reference/meta.types
.dirstamp
**/tags.*
build/
image: registry.gitlab.gnome.org/gnome/mutter/master:v3
stages:
- review
- build
- test
check-commit-log:
stage: review
variables:
GIT_DEPTH: "100"
script:
- ./.gitlab-ci/check-commit-log.sh
only:
- merge_requests
build-mutter:
stage: build
script:
- meson . build -Dbuildtype=debugoptimized -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr
- ninja -C build
- ninja -C build install
artifacts:
expire_in: 1 day
paths:
- build
only:
- merge_requests
- /^.*$/
build-without-opengl-and-glx:
stage: build
script:
- meson . build -Dbuildtype=debugoptimized -Dopengl=false -Dglx=false -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr
- ninja -C build
- ninja -C build install
artifacts:
expire_in: 1 day
paths:
- build
only:
- merge_requests
- /^.*$/
build-without-native-backend-and-wayland:
stage: build
script:
- meson . build -Dbuildtype=debugoptimized -Dnative_backend=false -Dudev=false -Dwayland=false -Dcore_tests=false --werror --prefix /usr
- ninja -C build
- ninja -C build install
artifacts:
expire_in: 1 day
paths:
- build
only:
- merge_requests
- /^.*$/
test-mutter:
stage: test
dependencies:
- build-mutter
variables:
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
GSETTINGS_SCHEMA_DIR: "$CI_PROJECT_DIR/build/data"
G_SLICE: "always-malloc"
MALLOC_CHECK_: "3"
NO_AT_BRIDGE: "1"
MALLOC_PERTURB_: "123"
script:
- dconf update
- mkdir -m 700 $XDG_RUNTIME_DIR
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
- >
dbus-run-session -- xvfb-run -s '+iglx -noreset'
meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --print-errorlogs --wrap catchsegv
only:
- merge_requests
- /^.*$/
can-build-gnome-shell:
stage: test
dependencies:
- build-mutter
before_script:
- meson install --no-rebuild -C build
script:
- .gitlab-ci/checkout-gnome-shell.sh
- meson gnome-shell gnome-shell/build --prefix /usr -Dman=false
- ninja -C gnome-shell/build install
only:
- merge_requests
- /^.*$/
# Rebuild and push with
#
# cd .gitlab-ci/
# podman build --format docker --no-cache -t registry.gitlab.gnome.org/gnome/mutter/master:v3 .
# podman push registry.gitlab.gnome.org/gnome/mutter/master:v3
#
FROM fedora:31
RUN dnf -y update && dnf -y upgrade && \
dnf install -y 'dnf-command(builddep)' && \
dnf install -y 'dnf-command(copr)' && \
dnf copr enable -y fmuellner/gnome-shell-ci && \
dnf copr enable -y jadahl/mutter-ci && \
dnf -y update && dnf -y upgrade && \
dnf builddep -y mutter && \
# Until Fedora catches up with new build-deps
dnf install -y 'pkgconfig(graphene-gobject-1.0)' 'pkgconfig(sysprof-capture-3)' && \
# For running unit tests
dnf install -y xorg-x11-server-Xvfb mesa-dri-drivers dbus dbus-x11 '*/xvfb-run' gdm-lib accountsservice-libs gnome-control-center && \
# GNOME Shell
dnf builddep -y gnome-shell --setopt=install_weak_deps=False && \
dnf remove -y gnome-bluetooth-libs-devel dbus-glib-devel upower-devel python3-devel && \
dnf remove -y --noautoremove mutter mutter-devel && \
dnf upgrade -y 'pkgconfig(libpipewire-0.3)' && \
dnf clean all
#!/usr/bin/env bash
if [ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
echo Cannot review non-merge request
exit 1
fi
git fetch $CI_MERGE_REQUEST_PROJECT_URL.git $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
branch_point=$(git merge-base HEAD FETCH_HEAD)
commits=$(git log --format='format:%H' $branch_point..$CI_COMMIT_SHA)
if [ -z "$commits" ]; then
echo Commit range empty
exit 1
fi
function commit_message_has_url() {
commit=$1
commit_message=$(git show -s --format='format:%b' $commit)
echo "$commit_message" | grep -qe "\($CI_MERGE_REQUEST_PROJECT_URL/\(-/\)\?\(issues\|merge_requests\)/[0-9]\+\|https://bugzilla.gnome.org/show_bug.cgi?id=[0-9]\+\)"
return $?
}
function commit_message_subject_is_compliant() {
commit=$1
commit_message_subject=$(git show -s --format='format:%s' $commit)
if echo "$commit_message_subject" | grep -qe "\(^meta-\|^Meta\)"; then
echo " - message subject should not be prefixed with 'meta-' or 'Meta'"
return 1
fi
if echo "$commit_message_subject" | grep -qe "\.[ch]:"; then
echo " - message subject prefix should not include .c, .h, etc."
return 1
fi
return 0
}
RET=0
for commit in $commits; do
commit_short=$(echo $commit | cut -c -8)
if ! commit_message_has_url $commit; then
echo "Commit $commit_short needs a merge request or issue URL"
exit 1
fi
errors=$(commit_message_subject_is_compliant $commit)
if [ $? != 0 ]; then
echo "Commit message for $commit_short is not compliant:"
echo "$errors"
RET=1
fi
done
exit $RET
#!/usr/bin/bash
gnome_shell_target=
git clone https://gitlab.gnome.org/GNOME/gnome-shell.git
if [ $? -ne 0 ]; then
echo Checkout failed
exit 1
fi
cd gnome-shell
if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
merge_request_remote=${CI_MERGE_REQUEST_SOURCE_PROJECT_URL//mutter/gnome-shell}
merge_request_branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
echo Looking for $merge_request_branch on remote ...
if git fetch -q $merge_request_remote $merge_request_branch 2>/dev/null; then
gnome_shell_target=FETCH_HEAD
else
gnome_shell_target=origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
echo Using $gnome_shell_target instead
fi
fi
if [ -z "$gnome_shell_target" ]; then
gnome_shell_target=$(git branch -r -l origin/$CI_COMMIT_REF_NAME)
gnome_shell_target=${gnome_shell_target:-origin/master}
echo Using $gnome_shell_target instead
fi
git checkout -q $gnome_shell_target
<!--
Please read https://wiki.gnome.org/Community/GettingInTouch/BugReportingGuidelines
first to ensure that you create a clear and specific issue.
-->
### Affected version
<!--
Provide at least the following information:
* Your OS and version
* Affected Mutter version
* Does this issue appear in XOrg and/or Wayland
-->
### Bug summary
<!--
Provide a short summary of the bug you encountered.
-->
### Steps to reproduce
<!--
1. Step one
2. Step two
3. ...
-->
### What happened
<!--
What did Mutter do that was unexpected?
-->
### What did you expect to happen
<!--
What did you expect Mutter to do?
-->
### Relevant logs, screenshots, screencasts etc.
<!--
If you have further information, such as technical documentation, logs,
screenshots or screencasts related, please provide them here.
If the bug is a crash, please obtain a stack trace with installed debug
symbols (at least for GNOME Shell and Mutter) and attach it to
this issue following the instructions on
https://wiki.gnome.org/Community/GettingInTouch/Bugzilla/GettingTraces.
-->
<!-- Do not remove the following line. -->
/label ~"1. Bug"
<!--
Please read https://wiki.gnome.org/Community/GettingInTouch/BugReportingGuidelines
first to ensure that you create a clear and specific issue.
-->
### Feature summary
<!--
Describe what you would like to be able to do with Mutter
that you currently cannot do.
-->
### How would you like it to work
<!--
If you can think of a way Mutter might be able to do this,
let us know here.
-->
### Relevant links, screenshots, screencasts etc.
<!--
If you have further information, such as technical documentation,
code, mockups or a similar feature in another window managers,
please provide them here.
-->
<!-- Do not remove the following line. -->
/label ~"1. Feature"
3.36.9
======
* Do not ping unmanaging windows [Florian; gnome-shell#2467]
* Improve freezes when switching workspace [Jonas Å.; !1616]
* Fix drag cancel animation when using geometry scaling [Robert; !1683]
* Fix stuck icon in DND operation between X11 and wayland [Carlos; !1720]
* Fix restoring focus to windows using globally active input [Olivier; !1716]
* Fix order in which subsurface placement operations are handled [Robert; !1768]
Contributors:
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Robert Mader, Florian Müllner
3.36.8
======
* Fix _NET_WM_FRAME_DRAWN timestamps [Jonas; !1360]
* Fix unwanted position changes on window resize
[Jonas, Olivier, Robert; !1477, !1495]
* Fix device configuration not being picked up on X11 [Carlos; !1553]
* Fix size hints with CSD [Christian, Olivier; !1598]
* Disable CRTCs if there is no monitor [Kai-Heng; !1561]
* Fixed crashes [Olivier, Robert, Jonas; !1529, !1534, #1521, !1563, !1653]
* Plugged memory leaks [Ray; !1225]
* Misc. bug fixes and cleanups [Olivier, Robert, Daniel, Carlos; !1575,
!1565, !1572, !1655]
Contributors:
Jonas Ådahl, Kai-Heng Feng, Olivier Fourdan, Carlos Garnacho, Robert Mader,
Christian Rauch, Ray Strode, Daniel van Vugt
3.36.7
======
* Fix Night Light updates after DPMS [Jonas, Benjamin; #1392]
......
project('mutter', 'c',
version: '3.36.7',
version: '3.36.9',
meson_version: '>= 0.50.0',
license: 'GPLv2+'
)
......
......@@ -303,6 +303,14 @@ meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager
if (!config)
{
if (!manager->in_init)
{
MetaBackend *backend = meta_get_backend ();
MetaRenderer *renderer = meta_backend_get_renderer (backend);
meta_renderer_native_reset_modes (META_RENDERER_NATIVE (renderer));
}
manager->screen_width = META_MONITOR_MANAGER_MIN_SCREEN_WIDTH;
manager->screen_height = META_MONITOR_MANAGER_MIN_SCREEN_HEIGHT;
meta_monitor_manager_rebuild (manager, NULL);
......
......@@ -2012,6 +2012,48 @@ retry:
}
}
static MetaKmsUpdate *
unset_disabled_crtcs (MetaBackend *backend,
MetaKms *kms)
{
MetaKmsUpdate *kms_update = NULL;
GList *l;
for (l = meta_backend_get_gpus (backend); l; l = l->next)
{
MetaGpu *gpu = l->data;
GList *k;
for (k = meta_gpu_get_crtcs (gpu); k; k = k->next)
{
MetaCrtc *crtc = k->data;
if (crtc->config)
continue;
kms_update = meta_kms_ensure_pending_update (kms);
meta_crtc_kms_set_mode (crtc, kms_update);
}
}
return kms_update;
}
static void
post_pending_update (MetaKms *kms)
{
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
kms_feedback = meta_kms_post_pending_update_sync (kms);
if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
{
const GError *error = meta_kms_feedback_get_error (kms_feedback);
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
g_warning ("Failed to post KMS update: %s", error->message);
}
}
static void
meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
const int *rectangles,
......@@ -2120,14 +2162,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
COGL_TRACE_BEGIN (MetaRendererNativePostKmsUpdate,
"Onscreen (post pending update)");
kms_feedback = meta_kms_post_pending_update_sync (kms);
if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
{
const GError *error = meta_kms_feedback_get_error (kms_feedback);
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
g_warning ("Failed to post KMS update: %s", error->message);
}
post_pending_update (kms);
COGL_TRACE_END (MetaRendererNativePostKmsUpdate);
}
......@@ -3180,41 +3215,12 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native)
if (renderer_native->pending_unset_disabled_crtcs)
{
GList *l;
for (l = meta_backend_get_gpus (backend); l; l = l->next)
{
MetaGpu *gpu = l->data;
GList *k;
for (k = meta_gpu_get_crtcs (gpu); k; k = k->next)
{
MetaCrtc *crtc = k->data;
if (crtc->config)
continue;
kms_update = meta_kms_ensure_pending_update (kms);
meta_crtc_kms_set_mode (crtc, kms_update);
}
}
kms_update = unset_disabled_crtcs (backend, kms);
renderer_native->pending_unset_disabled_crtcs = FALSE;
}
if (kms_update)
{
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
kms_feedback = meta_kms_post_pending_update_sync (kms);
if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
{
const GError *error = meta_kms_feedback_get_error (kms_feedback);
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
g_warning ("Failed to post KMS update: %s", error->message);
}
}
post_pending_update (kms);
}
int64_t
......@@ -3796,6 +3802,21 @@ on_power_save_mode_changed (MetaMonitorManager *monitor_manager,
meta_kms_discard_pending_page_flips (kms);
}
void
meta_renderer_native_reset_modes (MetaRendererNative *renderer_native)
{
MetaRenderer *renderer = META_RENDERER (renderer_native);
MetaBackend *backend = meta_renderer_get_backend (renderer);
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
MetaKms *kms = meta_backend_native_get_kms (backend_native);
MetaKmsUpdate *kms_update;
kms_update = unset_disabled_crtcs (backend, kms);
if (kms_update)
post_pending_update (kms);
}
static MetaGpuKms *
choose_primary_gpu_unchecked (MetaBackend *backend,
MetaRendererNative *renderer_native)
......
......@@ -55,4 +55,6 @@ void meta_renderer_native_finish_frame (MetaRendererNative *renderer_native);
int64_t meta_renderer_native_get_frame_counter (MetaRendererNative *renderer_native);
void meta_renderer_native_reset_modes (MetaRendererNative *renderer_native);
#endif /* META_RENDERER_NATIVE_H */
......@@ -453,6 +453,9 @@ apply_crtc_assignments (MetaMonitorManager *manager,
meta_crtc_unset_config (crtc);
}
if (!n_crtcs)
goto out;
g_assert (width > 0 && height > 0);
/* The 'physical size' of an X screen is meaningless if that screen
* can consist of many monitors. So just pick a size that make the
......@@ -549,6 +552,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
output->is_primary = FALSE;
}
out:
XUngrabServer (manager_xrandr->xdisplay);
XFlush (manager_xrandr->xdisplay);
}
......@@ -595,6 +599,9 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *mana
if (!config)
{
if (!manager->in_init)
apply_crtc_assignments (manager, TRUE, NULL, 0, NULL, 0);
meta_monitor_manager_xrandr_rebuild_derived (manager, NULL);
return TRUE;
}
......
......@@ -28,6 +28,7 @@
#include "config.h"
#include "compositor/meta-dnd-actor-private.h"
#include "compositor/meta-window-actor-private.h"
#include "clutter/clutter.h"
......@@ -206,16 +207,29 @@ meta_dnd_actor_drag_finish (MetaDnDActor *self,
if (CLUTTER_ACTOR_IS_VISIBLE (self->drag_origin))
{
MetaWindowActor *origin_actor;
float anchor_x, anchor_y;
graphene_point_t dest;
int origin_geometry_scale;
int feedback_geometry_scale;
clutter_actor_get_transformed_position (self->drag_origin,
&dest.x, &dest.y);
origin_actor = meta_window_actor_from_actor (self->drag_origin);
g_return_if_fail (origin_actor);
origin_geometry_scale =
meta_window_actor_get_geometry_scale (origin_actor);
meta_feedback_actor_get_anchor (META_FEEDBACK_ACTOR (self),
&anchor_x, &anchor_y);
feedback_geometry_scale =
meta_feedback_actor_get_geometry_scale (META_FEEDBACK_ACTOR (self));
dest.x += self->drag_start_x - anchor_x;
dest.y += self->drag_start_y - anchor_y;
dest.x += ((self->drag_start_x * origin_geometry_scale) -
(anchor_x * feedback_geometry_scale));
dest.y += ((self->drag_start_y * origin_geometry_scale) -
(anchor_y * feedback_geometry_scale));
clutter_actor_set_position (actor, dest.x, dest.y);
}
......
......@@ -62,4 +62,9 @@ void meta_feedback_actor_set_position (MetaFeedbackActor *self,
void meta_feedback_actor_update (MetaFeedbackActor *self,
const ClutterEvent *event);
void meta_feedback_actor_set_geometry_scale (MetaFeedbackActor *self,
int geometry_scale);
int meta_feedback_actor_get_geometry_scale (MetaFeedbackActor *self);
#endif /* META_FEEDBACK_ACTOR_PRIVATE_H */
......@@ -44,6 +44,8 @@ struct _MetaFeedbackActorPrivate
float anchor_y;
float pos_x;
float pos_y;
int geometry_scale;
};
G_DEFINE_TYPE_WITH_PRIVATE (MetaFeedbackActor, meta_feedback_actor, CLUTTER_TYPE_ACTOR)
......@@ -65,8 +67,10 @@ meta_feedback_actor_update_position (MetaFeedbackActor *self)
MetaFeedbackActorPrivate *priv = meta_feedback_actor_get_instance_private (self);
clutter_actor_set_position (CLUTTER_ACTOR (self),
priv->pos_x - priv->anchor_x,
priv->pos_y - priv->anchor_y);
priv->pos_x -
(priv->anchor_x * priv->geometry_scale),
priv->pos_y -
(priv->anchor_y * priv->geometry_scale));
}
static void
......@@ -249,3 +253,31 @@ meta_feedback_actor_update (MetaFeedbackActor *self,
clutter_event_get_position (event, &point);
meta_feedback_actor_set_position (self, point.x, point.y);
}
void
meta_feedback_actor_set_geometry_scale (MetaFeedbackActor *self,
int geometry_scale)
{
MetaFeedbackActorPrivate *priv =
meta_feedback_actor_get_instance_private (self);
CoglMatrix child_transform;
if (priv->geometry_scale == geometry_scale)
return;
priv->geometry_scale = geometry_scale;
cogl_matrix_init_identity (&child_transform);
cogl_matrix_scale (&child_transform, geometry_scale, geometry_scale, 1);
clutter_actor_set_child_transform (CLUTTER_ACTOR (self),
&child_transform);
}
int
meta_feedback_actor_get_geometry_scale (MetaFeedbackActor *self)
{
MetaFeedbackActorPrivate *priv =
meta_feedback_actor_get_instance_private (self);
return priv->geometry_scale;
}
......@@ -611,6 +611,7 @@ struct _MetaWindowClass
gboolean (*is_stackable) (MetaWindow *window);
gboolean (*can_ping) (MetaWindow *window);
gboolean (*are_updates_frozen) (MetaWindow *window);
gboolean (*is_focus_async) (MetaWindow *window);
MetaStackLayer (*calculate_layer) (MetaWindow *window);
......@@ -879,4 +880,5 @@ void meta_window_force_restore_shortcuts (MetaWindow *window,
gboolean meta_window_shortcuts_inhibited (MetaWindow *window,
ClutterInputDevice *source);
gboolean meta_window_is_stackable (MetaWindow *window);
gboolean meta_window_is_focus_async (MetaWindow *window);
#endif
......@@ -1796,6 +1796,7 @@ stackcmp (gconstpointer a, gconstpointer b)
static gboolean
idle_calc_showing (gpointer data)
{
MetaDisplay *display = meta_get_display ();
GSList *tmp;
GSList *copy;
GSList *should_show;
......@@ -1866,6 +1867,8 @@ idle_calc_showing (gpointer data)
tmp = tmp->next;
}
meta_stack_freeze (display->stack);
tmp = should_show;
while (tmp != NULL)
{
......@@ -1890,6 +1893,8 @@ idle_calc_showing (gpointer data)
tmp = tmp->next;
}
meta_stack_thaw (display->stack);
tmp = copy;
while (tmp != NULL)
{
......@@ -8324,6 +8329,9 @@ meta_window_handle_ungrabbed_event (MetaWindow *window,
gfloat x, y;
guint button;
if (window->unmanaging)
return;
if (event->type != CLUTTER_BUTTON_PRESS &&
event->type != CLUTTER_TOUCH_BEGIN)
return;
......@@ -8581,6 +8589,8 @@ meta_window_is_focusable (MetaWindow *window)
gboolean
meta_window_can_ping (MetaWindow *window)
{
g_return_val_if_fail (!window->unmanaging, FALSE);
return META_WINDOW_GET_CLASS (window)->can_ping (window);
}
......@@ -8590,6 +8600,12 @@ meta_window_is_stackable (MetaWindow *window)
return META_WINDOW_GET_CLASS (window)->is_stackable (window);
}
gboolean
meta_window_is_focus_async (MetaWindow *window)
{
return META_WINDOW_GET_CLASS (window)->is_focus_async (window);
}
MetaStackLayer
meta_window_calculate_layer (MetaWindow *window)
{
......
......@@ -1332,7 +1332,10 @@ find_focusable_ancestor (MetaWindow *window,
{
MetaWorkspaceFocusableAncestorData *data = user_data;
if (!window->unmanaging && meta_window_is_focusable (window) &&
if (!window->unmanaging &&
window->mapped &&
!window->hidden &&
meta_window_is_focusable (window) &&
meta_window_located_on_workspace (window, data->workspace) &&
meta_window_showing_on_its_workspace (window))
{
......@@ -1343,6 +1346,38 @@ find_focusable_ancestor (MetaWindow *window,
return TRUE;
}
static gboolean
try_to_set_focus_and_check (MetaWindow *window,
MetaWindow *not_this_one,
uint32_t timestamp)
{
meta_window_focus (window, timestamp);
/* meta_focus_window() will not change focus for clients using the
* "globally active input" model of input handling, hence defeating
* the assumption that focus should be changed for such windows.
* See https://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7
*/
if (meta_window_is_focus_async (window))
return TRUE;
/* meta_window_focus() does not guarantee that focus will end up
* where we expect, it can fail for various reasons, better check
* it did not actually changed or even left focus to the window we
* explicitly want to avoid.
*/
if (not_this_one &&
meta_display_get_focus_window (window->display) == not_this_one)
{
meta_warning ("Failed to focus window %s while avoiding %s",
window->desc, not_this_one->desc);
return FALSE;
}
return TRUE;
}
/* Focus ancestor of not_this_one if there is one */
static void
focus_ancestor_or_top_window (MetaWorkspace *workspace,
......@@ -1376,13 +1411,14 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
"Focusing %s, ancestor of %s\n",
ancestor->desc, not_this_one->desc);
meta_window_focus (ancestor, timestamp);
/* Also raise the window if in click-to-focus */
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
meta_window_raise (ancestor);
if (try_to_set_focus_and_check (ancestor, not_this_one, timestamp))
{
/* Also raise the window if in click-to-focus */
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
meta_window_raise (ancestor);
return;
return;
}
}
}
......@@ -1394,18 +1430,19 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
{
meta_topic (META_DEBUG_FOCUS,
"Focusing workspace MRU window %s\n", window->desc);
if (try_to_set_focus_and_check (window, not_this_one, timestamp))
{
/* Also raise the window if in click-to-focus */
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
meta_window_raise (window);
meta_window_focus (window, timestamp);
/* Also raise the window if in click-to-focus */
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
meta_window_raise (window);
}
else
{
meta_topic (META_DEBUG_FOCUS, "No MRU window to focus found; focusing no_focus_window.\n");
meta_display_unset_input_focus (workspace->display, timestamp);
return;
}
}
meta_topic (META_DEBUG_FOCUS,
"No MRU window to focus found; focusing no_focus_window.");
meta_display_unset_input_focus (workspace->display, timestamp);
}
/**
......
......@@ -352,6 +352,7 @@ drag_grab_motion (MetaWaylandPointerGrab *grab,
static void
data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
{
meta_wayland_drag_grab_set_source (drag_grab, NULL);
meta_wayland_drag_grab_set_focus (drag_grab, NULL);
if (drag_grab->drag_origin)
......@@ -366,8 +367,6 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
wl_list_remove (&drag_grab->drag_icon_listener.link);
}
meta_wayland_drag_grab_set_source (drag_grab, NULL);
if (drag_grab->feedback_actor)
{
clutter_actor_remove_all_children (drag_grab->feedback_actor);
......@@ -448,9 +447,6 @@ drag_grab_button (MetaWaylandPointerGrab *grab,
meta_wayland_data_source_has_target (source) &&
meta_wayland_data_source_get_current_action (source))
{
/* Detach the data source from the grab, it's meant to live longer */
meta_wayland_drag_grab_set_source (drag_grab, NULL);
meta_wayland_surface_drag_dest_drop (drag_grab->drag_focus);
meta_wayland_data_source_notify_drop_performed (source);
......@@ -501,6 +497,7 @@ keyboard_drag_grab_key (MetaWaylandKeyboardGrab *grab,
drag_grab = wl_container_of (grab, drag_grab, keyboard_grab);
meta_wayland_data_source_cancel (drag_grab->drag_data_source);
meta_wayland_data_source_set_current_offer (drag_grab->drag_data_source, NULL);
meta_dnd_actor_drag_finish (META_DND_ACTOR (drag_grab->feedback_actor), FALSE);
drag_grab->feedback_actor = NULL;
data_device_end_drag_grab (drag_grab);
......@@ -547,6 +544,7 @@ destroy_data_device_origin (struct wl_listener *listener, void *data)
drag_grab->drag_origin = NULL;
meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device, NULL);
unset_selection_source (&drag_grab->seat->data_device, META_SELECTION_DND);
meta_wayland_data_source_set_current_offer (drag_grab->drag_data_source, NULL);
data_device_end_drag_grab (drag_grab);
}
......