Compare commits
14 Commits
citadel
...
wip/3v1n0/
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9056fb00b0 | ||
![]() |
0503ecaf84 | ||
![]() |
dec20d13e1 | ||
![]() |
0242c1a527 | ||
![]() |
8652ec9ee2 | ||
![]() |
4c607164fd | ||
![]() |
08f920606e | ||
![]() |
ef3ea0a59c | ||
![]() |
a5f360cb9e | ||
![]() |
26cb0a5a75 | ||
![]() |
7c89167644 | ||
![]() |
984d27f050 | ||
![]() |
5b13372fd4 | ||
![]() |
4334534742 |
@ -2,10 +2,45 @@ image: registry.gitlab.gnome.org/gnome/mutter/master:v1
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
|
||||
build-mutter:
|
||||
stage: build
|
||||
script:
|
||||
- meson . build -Degl_device=true -Dwayland_eglstream=true
|
||||
- meson . build -Degl_device=true -Dwayland_eglstream=true -Dheadless_tests=enabled
|
||||
- ninja -C build
|
||||
- ninja -C build install
|
||||
- meson test -v -C build --suite headless
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - build
|
||||
|
||||
# test-cogl:
|
||||
# stage: test
|
||||
# dependencies:
|
||||
# - build-mutter
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - build
|
||||
# script:
|
||||
# - meson test -v -C build --suite cogl-headless
|
||||
|
||||
# test-clutter:
|
||||
# stage: test
|
||||
# dependencies:
|
||||
# - build-mutter
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - build
|
||||
# script:
|
||||
# - meson test -v -C build --suite clutter-headless
|
||||
|
||||
# test-mutter:
|
||||
# stage: test
|
||||
# dependencies:
|
||||
# - build-mutter
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - build
|
||||
# script:
|
||||
# - meson test -v -C build --suite mutter-headless
|
||||
|
@ -7,5 +7,8 @@ RUN dnf -y update && dnf -y upgrade && \
|
||||
# Until Fedora catches up with meson build-deps
|
||||
dnf install -y meson xorg-x11-server-Xorg gnome-settings-daemon-devel egl-wayland-devel xorg-x11-server-Xwayland && \
|
||||
|
||||
# To enable testing headless
|
||||
dnf install -y xorg-x11-server-Xvfb && \
|
||||
|
||||
dnf install -y intltool redhat-rpm-config make && \
|
||||
dnf clean all
|
||||
|
@ -78,7 +78,18 @@ foreach test : clutter_conform_tests
|
||||
install: false,
|
||||
)
|
||||
|
||||
test('clutter/conform/@0@'.format(test), test_executable,
|
||||
test(test, test_executable,
|
||||
suite: ['clutter', 'clutter/conform'],
|
||||
env: test_env
|
||||
)
|
||||
|
||||
if have_headless_tests
|
||||
test(test, xvfb,
|
||||
args: test_executable,
|
||||
suite: ['clutter-headless', 'clutter-headless/conform', 'headless'],
|
||||
env: test_env,
|
||||
is_parallel: false,
|
||||
timeout: 60,
|
||||
)
|
||||
endif
|
||||
endforeach
|
||||
|
@ -95,7 +95,8 @@ cogl_conform_unit_tests = custom_target('cogl-tests-conform-unit-tests',
|
||||
install: false,
|
||||
)
|
||||
|
||||
test('cogl/conform', cogl_run_tests,
|
||||
test('conform', cogl_run_tests,
|
||||
suite: ['cogl'],
|
||||
args: [
|
||||
cogl_config_env,
|
||||
libmutter_cogl_test_conformance,
|
||||
@ -104,3 +105,17 @@ test('cogl/conform', cogl_run_tests,
|
||||
is_parallel: false,
|
||||
timeout: 60,
|
||||
)
|
||||
|
||||
if have_headless_tests
|
||||
test('conform', xvfb,
|
||||
suite: ['cogl-headless', 'headless'],
|
||||
args: [
|
||||
cogl_run_tests.path(),
|
||||
cogl_config_env,
|
||||
libmutter_cogl_test_conformance,
|
||||
cogl_conform_unit_tests
|
||||
],
|
||||
is_parallel: false,
|
||||
timeout: 500,
|
||||
)
|
||||
endif
|
||||
|
@ -32,11 +32,22 @@ cogl_unit_unit_tests = custom_target('cogl-tests-unit-unit-tests',
|
||||
install: false,
|
||||
)
|
||||
|
||||
test('cogl/unit', cogl_run_tests,
|
||||
args: [
|
||||
cogl_config_env,
|
||||
libmutter_cogl_test_unit,
|
||||
cogl_unit_unit_tests
|
||||
],
|
||||
cogl_unit_test_args = [
|
||||
cogl_config_env,
|
||||
libmutter_cogl_test_unit,
|
||||
cogl_unit_unit_tests
|
||||
]
|
||||
test('unit', cogl_run_tests,
|
||||
suite: ['cogl'],
|
||||
args: cogl_unit_test_args,
|
||||
is_parallel: false,
|
||||
)
|
||||
|
||||
if have_headless_tests
|
||||
test('unit', xvfb,
|
||||
suite: ['cogl-headless', 'headless'],
|
||||
args: [ cogl_run_tests.path() ] + cogl_unit_test_args,
|
||||
is_parallel: false,
|
||||
timeout: 90,
|
||||
)
|
||||
endif
|
||||
|
20
meson.build
20
meson.build
@ -245,6 +245,26 @@ if have_tests
|
||||
endif
|
||||
endif
|
||||
|
||||
headless_tests_option = get_option('headless_tests')
|
||||
have_headless_tests = not headless_tests_option.disabled()
|
||||
if have_headless_tests
|
||||
if not have_tests and not have_cogl_tests and not have_clutter_tests
|
||||
have_headless_tests = false
|
||||
if headless_tests_option.enabled()
|
||||
error('Headless tests are enabled, but no other test suite is')
|
||||
endif
|
||||
endif
|
||||
if have_headless_tests
|
||||
xvfb = find_program('xvfb-run', required: headless_tests_option.enabled())
|
||||
have_headless_tests = xvfb.found()
|
||||
endif
|
||||
endif
|
||||
if have_headless_tests
|
||||
headless_tests_suite = ['headless']
|
||||
else
|
||||
headless_tests_suite = []
|
||||
endif
|
||||
|
||||
required_functions = [
|
||||
'ffs',
|
||||
'clz',
|
||||
|
@ -123,6 +123,12 @@ option('tests',
|
||||
description: 'Enable mutter tests'
|
||||
)
|
||||
|
||||
option('headless_tests',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Enable mutter headless tests'
|
||||
)
|
||||
|
||||
option('verbose',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
|
@ -15,6 +15,9 @@ dist_stacking_DATA = \
|
||||
$(srcdir)/tests/stacking/basic-x11.metatest \
|
||||
$(srcdir)/tests/stacking/basic-wayland.metatest \
|
||||
$(srcdir)/tests/stacking/closed-transient.metatest \
|
||||
$(srcdir)/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest \
|
||||
$(srcdir)/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest \
|
||||
$(srcdir)/tests/stacking/closed-transient-no-input-parent.metatest \
|
||||
$(srcdir)/tests/stacking/minimized.metatest \
|
||||
$(srcdir)/tests/stacking/mixed-windows.metatest \
|
||||
$(srcdir)/tests/stacking/set-parent.metatest \
|
||||
|
@ -1214,10 +1214,7 @@ get_default_focus_window (MetaStack *stack,
|
||||
if (window->unmaps_pending > 0)
|
||||
continue;
|
||||
|
||||
if (window->unmanaging)
|
||||
continue;
|
||||
|
||||
if (!(window->input || window->take_focus))
|
||||
if (!meta_window_is_focusable (window))
|
||||
continue;
|
||||
|
||||
if (!meta_window_should_be_showing (window))
|
||||
|
@ -570,6 +570,7 @@ struct _MetaWindowClass
|
||||
ClutterInputDevice *source);
|
||||
gboolean (*shortcuts_inhibited) (MetaWindow *window,
|
||||
ClutterInputDevice *source);
|
||||
gboolean (*is_focusable) (MetaWindow *window);
|
||||
gboolean (*is_stackable) (MetaWindow *window);
|
||||
gboolean (*are_updates_frozen) (MetaWindow *window);
|
||||
};
|
||||
@ -664,6 +665,8 @@ void meta_window_update_unfocused_button_grabs (MetaWindow *window);
|
||||
void meta_window_set_focused_internal (MetaWindow *window,
|
||||
gboolean focused);
|
||||
|
||||
gboolean meta_window_is_focusable (MetaWindow *window);
|
||||
|
||||
void meta_window_current_workspace_changed (MetaWindow *window);
|
||||
|
||||
void meta_window_show_menu (MetaWindow *window,
|
||||
|
@ -2205,7 +2205,7 @@ window_state_on_map (MetaWindow *window,
|
||||
/* don't initially focus windows that are intended to not accept
|
||||
* focus
|
||||
*/
|
||||
if (!(window->input || window->take_focus))
|
||||
if (!meta_window_is_focusable (window))
|
||||
{
|
||||
*takes_focus = FALSE;
|
||||
return;
|
||||
@ -8512,6 +8512,15 @@ meta_window_shortcuts_inhibited (MetaWindow *window,
|
||||
return META_WINDOW_GET_CLASS (window)->shortcuts_inhibited (window, source);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_window_is_focusable (MetaWindow *window)
|
||||
{
|
||||
if (window->unmanaging)
|
||||
return FALSE;
|
||||
|
||||
return META_WINDOW_GET_CLASS (window)->is_focusable (window);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_window_is_stackable (MetaWindow *window)
|
||||
{
|
||||
|
@ -87,6 +87,12 @@ typedef struct _MetaWorkspaceLogicalMonitorData
|
||||
MetaRectangle logical_monitor_work_area;
|
||||
} MetaWorkspaceLogicalMonitorData;
|
||||
|
||||
typedef struct _MetaWorkspaceFocusableAncestorData
|
||||
{
|
||||
MetaWorkspace *workspace;
|
||||
MetaWindow **win;
|
||||
} MetaWorkspaceFocusableAncestorData;
|
||||
|
||||
static MetaWorkspaceLogicalMonitorData *
|
||||
meta_workspace_get_logical_monitor_data (MetaWorkspace *workspace,
|
||||
MetaLogicalMonitor *logical_monitor)
|
||||
@ -1328,13 +1334,21 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
record_ancestor (MetaWindow *window,
|
||||
void *data)
|
||||
find_focusable_ancestor (MetaWindow *window,
|
||||
void *data)
|
||||
{
|
||||
MetaWindow **result = data;
|
||||
MetaWorkspaceFocusableAncestorData *mwfa = data;
|
||||
MetaWindow **result = mwfa->win;
|
||||
|
||||
*result = window;
|
||||
return FALSE; /* quit with the first ancestor we find */
|
||||
if (meta_window_is_focusable (window) &&
|
||||
meta_window_located_on_workspace (window, mwfa->workspace) &&
|
||||
meta_window_showing_on_its_workspace (window))
|
||||
{
|
||||
*result = window;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Focus ancestor of not_this_one if there is one */
|
||||
@ -1355,12 +1369,10 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
|
||||
/* First, check to see if we need to focus an ancestor of a window */
|
||||
if (not_this_one)
|
||||
{
|
||||
MetaWindow *ancestor;
|
||||
ancestor = NULL;
|
||||
meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor);
|
||||
if (ancestor != NULL &&
|
||||
meta_window_located_on_workspace (ancestor, workspace) &&
|
||||
meta_window_showing_on_its_workspace (ancestor))
|
||||
MetaWindow *ancestor = NULL;
|
||||
MetaWorkspaceFocusableAncestorData mwfa = { workspace, &ancestor };
|
||||
meta_window_foreach_ancestor (not_this_one, find_focusable_ancestor, &mwfa);
|
||||
if (ancestor != NULL)
|
||||
{
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Focusing %s, ancestor of %s\n",
|
||||
|
@ -191,8 +191,7 @@ main (int argc, char *argv[])
|
||||
META_TYPE_BACKEND_TEST);
|
||||
meta_wayland_override_display_name ("mutter-test-display");
|
||||
|
||||
meta_init ();
|
||||
meta_register_with_session ();
|
||||
test_meta_init ();
|
||||
|
||||
g_idle_add (run_tests, NULL);
|
||||
|
||||
|
@ -22,6 +22,7 @@ test_client = executable('mutter-test-client',
|
||||
dependencies: [
|
||||
gtk3_dep,
|
||||
gio_unix_dep,
|
||||
x11_dep,
|
||||
xext_dep,
|
||||
],
|
||||
install: false,
|
||||
@ -81,32 +82,73 @@ headless_start_test = executable('mutter-headless-start-test',
|
||||
install: false,
|
||||
)
|
||||
|
||||
stacking_tests = files([
|
||||
'stacking/basic-x11.metatest',
|
||||
'stacking/basic-wayland.metatest',
|
||||
'stacking/minimized.metatest',
|
||||
'stacking/mixed-windows.metatest',
|
||||
'stacking/set-parent.metatest',
|
||||
'stacking/override-redirect.metatest',
|
||||
])
|
||||
stacking_tests = [
|
||||
'basic-x11',
|
||||
'basic-wayland',
|
||||
'client-side-decorated',
|
||||
'closed-transient',
|
||||
'closed-transient-no-input-no-take-focus-parent',
|
||||
'closed-transient-no-input-no-take-focus-parents',
|
||||
'closed-transient-no-input-parent',
|
||||
'minimized',
|
||||
'mixed-windows',
|
||||
'set-parent',
|
||||
'override-redirect',
|
||||
'set-parent-exported',
|
||||
]
|
||||
|
||||
test('mutter/stacking', test_runner,
|
||||
env: test_env,
|
||||
args: [
|
||||
stacking_tests,
|
||||
],
|
||||
is_parallel: false,
|
||||
timeout: 60,
|
||||
)
|
||||
foreach stacking_test: stacking_tests
|
||||
test(stacking_test, test_runner,
|
||||
suite: ['mutter/stacking'],
|
||||
env: test_env,
|
||||
args: [
|
||||
files(join_paths('stacking', stacking_test + '.metatest')),
|
||||
],
|
||||
is_parallel: false,
|
||||
timeout: 60,
|
||||
)
|
||||
if have_headless_tests
|
||||
test(stacking_test, xvfb,
|
||||
suite: ['mutter-headless', 'mutter-headless/stacking', 'headless'],
|
||||
env: test_env,
|
||||
args: [
|
||||
test_runner,
|
||||
files(join_paths('stacking', stacking_test + '.metatest')),
|
||||
],
|
||||
is_parallel: false,
|
||||
timeout: 60,
|
||||
)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
test('mutter/unit', unit_tests,
|
||||
test('normal', unit_tests,
|
||||
suite: ['mutter/unit'],
|
||||
env: test_env,
|
||||
is_parallel: false,
|
||||
timeout: 60,
|
||||
)
|
||||
|
||||
test('mutter/unit/headless-start', headless_start_test,
|
||||
test('headless-start', headless_start_test,
|
||||
suite: ['mutter/unit'],
|
||||
env: test_env,
|
||||
is_parallel: false,
|
||||
timeout: 60,
|
||||
)
|
||||
|
||||
if have_headless_tests
|
||||
test('normal', xvfb,
|
||||
args: unit_tests,
|
||||
suite: ['mutter-headless', 'mutter-headless/unit', 'headless'],
|
||||
env: test_env,
|
||||
is_parallel: false,
|
||||
timeout: 60,
|
||||
)
|
||||
|
||||
test('headless-start', xvfb,
|
||||
args: headless_start_test,
|
||||
suite: ['mutter-headless', 'mutter-headless/unit', 'headless'],
|
||||
env: test_env,
|
||||
is_parallel: false,
|
||||
timeout: 60,
|
||||
)
|
||||
endif
|
||||
|
@ -0,0 +1,25 @@
|
||||
new_client 1 x11
|
||||
create 1/1
|
||||
show 1/1
|
||||
wait
|
||||
|
||||
create 1/2 csd
|
||||
set_parent 1/2 1
|
||||
take_focus 1/2 false
|
||||
accept_focus 1/2 false
|
||||
show 1/2
|
||||
wait
|
||||
|
||||
create 1/3 csd
|
||||
set_parent 1/3 2
|
||||
show 1/3
|
||||
wait
|
||||
|
||||
assert_focused 1/3
|
||||
assert_stacking 1/1 1/2 1/3
|
||||
|
||||
destroy 1/3
|
||||
wait
|
||||
|
||||
assert_focused 1/1
|
||||
assert_stacking 1/1 1/2
|
@ -0,0 +1,32 @@
|
||||
new_client 2 x11
|
||||
create 2/1
|
||||
show 2/1
|
||||
wait
|
||||
|
||||
new_client 1 x11
|
||||
create 1/1
|
||||
accept_focus 1/1 false
|
||||
take_focus 1/1 false
|
||||
show 1/1
|
||||
wait
|
||||
|
||||
create 1/2 csd
|
||||
set_parent 1/2 1
|
||||
take_focus 1/2 false
|
||||
accept_focus 1/2 false
|
||||
show 1/2
|
||||
wait
|
||||
|
||||
create 1/3 csd
|
||||
set_parent 1/3 2
|
||||
show 1/3
|
||||
wait
|
||||
|
||||
assert_focused 1/3
|
||||
assert_stacking 2/1 1/1 1/2 1/3
|
||||
|
||||
destroy 1/3
|
||||
wait
|
||||
|
||||
assert_stacking 1/1 1/2 2/1
|
||||
assert_focused 2/1
|
29
src/tests/stacking/closed-transient-no-input-parent.metatest
Normal file
29
src/tests/stacking/closed-transient-no-input-parent.metatest
Normal file
@ -0,0 +1,29 @@
|
||||
new_client 2 x11
|
||||
create 2/1
|
||||
show 2/1
|
||||
wait
|
||||
|
||||
new_client 1 x11
|
||||
create 1/1
|
||||
show 1/1
|
||||
wait
|
||||
|
||||
create 1/2 csd
|
||||
set_parent 1/2 1
|
||||
accept_focus 1/2 false
|
||||
show 1/2
|
||||
wait
|
||||
|
||||
create 1/3 csd
|
||||
set_parent 1/3 2
|
||||
show 1/3
|
||||
wait
|
||||
|
||||
assert_focused 1/3
|
||||
assert_stacking 2/1 1/1 1/2 1/3
|
||||
|
||||
destroy 1/3
|
||||
wait
|
||||
|
||||
assert_focused 1/1
|
||||
assert_stacking 2/1 1/1 1/2
|
@ -196,6 +196,74 @@ process_line (const char *line)
|
||||
NULL))
|
||||
g_print ("Fail to export handle for window id %s", argv[2]);
|
||||
}
|
||||
else if (strcmp (argv[0], "accept_focus") == 0)
|
||||
{
|
||||
if (argc != 3)
|
||||
{
|
||||
g_print ("usage: %s <window-id> [true|false]", argv[0]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
GtkWidget *window = lookup_window (argv[1]);
|
||||
if (!window)
|
||||
{
|
||||
g_print ("unknown window %s", argv[1]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
gboolean enabled = g_ascii_strcasecmp (argv[2], "true") == 0;
|
||||
gtk_window_set_accept_focus (GTK_WINDOW (window), enabled);
|
||||
}
|
||||
else if (strcmp (argv[0], "take_focus") == 0)
|
||||
{
|
||||
if (argc != 3)
|
||||
{
|
||||
g_print ("usage: %s <window-id> [true|false]", argv[0]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
GtkWidget *window = lookup_window (argv[1]);
|
||||
if (!window)
|
||||
{
|
||||
g_print ("unknown window %s", argv[1]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (wayland)
|
||||
{
|
||||
g_print ("%s not supported under wayland", argv[0]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
GdkDisplay *display = gdk_display_get_default ();
|
||||
GdkWindow *gdkwindow = gtk_widget_get_window (window);
|
||||
Display *xdisplay = gdk_x11_display_get_xdisplay (display);
|
||||
Window xwindow = GDK_WINDOW_XID (gdkwindow);
|
||||
Atom wm_take_focus = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
|
||||
gboolean add = g_ascii_strcasecmp(argv[2], "true") == 0;
|
||||
Atom *protocols = NULL;
|
||||
Atom *new_protocols;
|
||||
int n_protocols = 0;
|
||||
int i, n = 0;
|
||||
|
||||
gdk_display_sync (display);
|
||||
XGetWMProtocols (xdisplay, xwindow, &protocols, &n_protocols);
|
||||
new_protocols = g_malloc0 (sizeof (Atom) * (n_protocols + (add ? 1 : 0)));
|
||||
|
||||
for (i = 0; i < n_protocols; ++i)
|
||||
{
|
||||
if (protocols[i] != wm_take_focus)
|
||||
new_protocols[n++] = protocols[i];
|
||||
}
|
||||
|
||||
if (add)
|
||||
new_protocols[n++] = wm_take_focus;
|
||||
|
||||
XSetWMProtocols (xdisplay, xwindow, new_protocols, n);
|
||||
|
||||
XFree (new_protocols);
|
||||
XFree (protocols);
|
||||
}
|
||||
else if (strcmp (argv[0], "show") == 0)
|
||||
{
|
||||
if (argc != 2)
|
||||
|
@ -237,6 +237,38 @@ test_case_assert_stacking (TestCase *test,
|
||||
return *error == NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
test_case_assert_focused (TestCase *test,
|
||||
const char *expected_window,
|
||||
GError **error)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
if (!display->focus_window)
|
||||
{
|
||||
if (g_ascii_strcasecmp (expected_window, "null") != 0 &&
|
||||
g_ascii_strcasecmp (expected_window, "none") != 0 &&
|
||||
g_strcmp0 (expected_window, "0") != 0)
|
||||
{
|
||||
g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED,
|
||||
"focus: expected='%s', actual='NONE'", expected_window);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *focused = display->focus_window->title;
|
||||
if (g_str_has_prefix (focused, "test/"))
|
||||
focused += 5;
|
||||
|
||||
if (g_strcmp0 (focused, expected_window) != 0)
|
||||
g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED,
|
||||
"stacking: expected='%s', actual='%s'",
|
||||
expected_window, focused);
|
||||
}
|
||||
|
||||
return *error == NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
test_case_check_xserver_stacking (TestCase *test,
|
||||
GError **error)
|
||||
@ -398,6 +430,44 @@ test_case_do (TestCase *test,
|
||||
if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
|
||||
return FALSE;
|
||||
|
||||
if (!test_client_do (client, error,
|
||||
argv[0], window_id,
|
||||
argv[2],
|
||||
NULL))
|
||||
return FALSE;
|
||||
}
|
||||
else if (strcmp (argv[0], "accept_focus") == 0)
|
||||
{
|
||||
if (argc != 3 ||
|
||||
(g_ascii_strcasecmp (argv[2], "true") != 0 &&
|
||||
g_ascii_strcasecmp (argv[2], "false") != 0))
|
||||
BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]",
|
||||
argv[0]);
|
||||
|
||||
TestClient *client;
|
||||
const char *window_id;
|
||||
if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
|
||||
return FALSE;
|
||||
|
||||
if (!test_client_do (client, error,
|
||||
argv[0], window_id,
|
||||
argv[2],
|
||||
NULL))
|
||||
return FALSE;
|
||||
}
|
||||
else if (strcmp (argv[0], "take_focus") == 0)
|
||||
{
|
||||
if (argc != 3 ||
|
||||
(g_ascii_strcasecmp (argv[2], "true") != 0 &&
|
||||
g_ascii_strcasecmp (argv[2], "false") != 0))
|
||||
BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]",
|
||||
argv[0]);
|
||||
|
||||
TestClient *client;
|
||||
const char *window_id;
|
||||
if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
|
||||
return FALSE;
|
||||
|
||||
if (!test_client_do (client, error,
|
||||
argv[0], window_id,
|
||||
argv[2],
|
||||
@ -485,6 +555,11 @@ test_case_do (TestCase *test,
|
||||
if (!test_case_check_xserver_stacking (test, error))
|
||||
return FALSE;
|
||||
}
|
||||
else if (strcmp (argv[0], "assert_focused") == 0)
|
||||
{
|
||||
if (!test_case_assert_focused (test, argv[1], error))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
BAD_COMMAND("Unknown command %s", argv[0]);
|
||||
@ -799,8 +874,7 @@ main (int argc, char **argv)
|
||||
meta_plugin_manager_load (test_get_plugin_name ());
|
||||
meta_wayland_override_display_name ("mutter-test-display");
|
||||
|
||||
meta_init ();
|
||||
meta_register_with_session ();
|
||||
test_meta_init ();
|
||||
|
||||
RunTestsInfo info;
|
||||
info.tests = (char **)tests->pdata;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "tests/test-utils.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <meta/main.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "core/display-private.h"
|
||||
@ -94,6 +95,21 @@ test_init (int *argc,
|
||||
ensure_test_client_path (*argc, *argv);
|
||||
}
|
||||
|
||||
void
|
||||
test_meta_init ()
|
||||
{
|
||||
GLogLevelFlags log_flags;
|
||||
|
||||
/* Accept warnings in mutter initialization, as `failed to bind` one */
|
||||
log_flags = g_log_set_always_fatal (G_LOG_FATAL_MASK);
|
||||
g_log_set_always_fatal (log_flags & ~G_LOG_LEVEL_WARNING);
|
||||
|
||||
meta_init ();
|
||||
meta_register_with_session ();
|
||||
|
||||
g_log_set_always_fatal (log_flags);
|
||||
}
|
||||
|
||||
AsyncWaiter *
|
||||
async_waiter_new (void)
|
||||
{
|
||||
|
@ -43,6 +43,8 @@ typedef struct _TestClient TestClient;
|
||||
void test_init (int *argc,
|
||||
char ***argv);
|
||||
|
||||
void test_meta_init (void);
|
||||
|
||||
gboolean async_waiter_alarm_filter (AsyncWaiter *waiter,
|
||||
MetaX11Display *x11_display,
|
||||
XSyncAlarmNotifyEvent *event);
|
||||
|
@ -265,8 +265,7 @@ main (int argc, char *argv[])
|
||||
META_TYPE_BACKEND_TEST);
|
||||
meta_wayland_override_display_name ("mutter-test-display");
|
||||
|
||||
meta_init ();
|
||||
meta_register_with_session ();
|
||||
test_meta_init ();
|
||||
|
||||
g_idle_add (run_tests, NULL);
|
||||
|
||||
|
@ -141,7 +141,7 @@ static void
|
||||
meta_window_wayland_focus (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
if (window->input)
|
||||
if (meta_window_is_focusable (window))
|
||||
meta_x11_display_set_input_focus_window (window->display->x11_display,
|
||||
window,
|
||||
FALSE,
|
||||
@ -585,6 +585,12 @@ meta_window_wayland_shortcuts_inhibited (MetaWindow *window,
|
||||
return meta_wayland_compositor_is_shortcuts_inhibited (compositor, source);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_window_wayland_is_focusable (MetaWindow *window)
|
||||
{
|
||||
return window->input;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_window_wayland_is_stackable (MetaWindow *window)
|
||||
{
|
||||
@ -618,6 +624,7 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
|
||||
window_class->get_client_pid = meta_window_wayland_get_client_pid;
|
||||
window_class->force_restore_shortcuts = meta_window_wayland_force_restore_shortcuts;
|
||||
window_class->shortcuts_inhibited = meta_window_wayland_shortcuts_inhibited;
|
||||
window_class->is_focusable = meta_window_wayland_is_focusable;
|
||||
window_class->is_stackable = meta_window_wayland_is_stackable;
|
||||
window_class->are_updates_frozen = meta_window_wayland_are_updates_frozen;
|
||||
}
|
||||
|
@ -752,8 +752,7 @@ meta_window_x11_focus (MetaWindow *window,
|
||||
* Still, we have to do this or keynav breaks for these windows.
|
||||
*/
|
||||
if (window->frame &&
|
||||
(window->shaded ||
|
||||
!(window->input || window->take_focus)))
|
||||
(window->shaded || !meta_window_is_focusable (window)))
|
||||
{
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Focusing frame of %s\n", window->desc);
|
||||
@ -790,13 +789,27 @@ meta_window_x11_focus (MetaWindow *window,
|
||||
* Normally, we want to just leave the focus undisturbed until
|
||||
* the window responds to WM_TAKE_FOCUS, but if we're unmanaging
|
||||
* the current focus window we *need* to move the focus away, so
|
||||
* we focus the no_focus_window now (and set
|
||||
* display->focus_window to that) before sending WM_TAKE_FOCUS.
|
||||
* we focus the default focus window excluding this one,
|
||||
* before sending WM_TAKE_FOCUS.
|
||||
*/
|
||||
if (window->display->focus_window != NULL &&
|
||||
window->display->focus_window->unmanaging)
|
||||
meta_x11_display_focus_the_no_focus_window (window->display->x11_display,
|
||||
timestamp);
|
||||
{
|
||||
MetaWindow *focus_window = window;
|
||||
MetaWorkspace *workspace = window->workspace;
|
||||
|
||||
do
|
||||
{
|
||||
focus_window = meta_stack_get_default_focus_window (workspace->display->stack,
|
||||
workspace,
|
||||
focus_window);
|
||||
}
|
||||
while (!(!focus_window || focus_window->input ||
|
||||
(focus_window->frame && focus_window->shaded)));
|
||||
|
||||
if (focus_window)
|
||||
meta_window_x11_focus (focus_window, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
request_take_focus (window, timestamp);
|
||||
@ -1627,6 +1640,12 @@ meta_window_x11_shortcuts_inhibited (MetaWindow *window,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_window_x11_is_focusable (MetaWindow *window)
|
||||
{
|
||||
return window->input || window->take_focus;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_window_x11_is_stackable (MetaWindow *window)
|
||||
{
|
||||
@ -1669,6 +1688,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass)
|
||||
window_class->get_client_pid = meta_window_x11_get_client_pid;
|
||||
window_class->force_restore_shortcuts = meta_window_x11_force_restore_shortcuts;
|
||||
window_class->shortcuts_inhibited = meta_window_x11_shortcuts_inhibited;
|
||||
window_class->is_focusable = meta_window_x11_is_focusable;
|
||||
window_class->is_stackable = meta_window_x11_is_stackable;
|
||||
window_class->are_updates_frozen = meta_window_x11_are_updates_frozen;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user