Bug fixes for reclaiming focus.
This commit is contained in:
1 parent
ea509509e4
commit
52a3fddc77
6 files changed
+30
-43
No files matched your search
+13
-4
@@ -203,10 +203,19 @@ activation, then checks recovery of its native foreground and button focus.
|
||||
It also checks Linux focus, mismatched window-manager/keyboard focus, disabled
|
||||
windows, multiple visible applications, hidden windows, existing foreground,
|
||||
and repeated recovery. It also reproduces X11 focus on the launcher child
|
||||
with no Win32 foreground, as seen after AudioQuake exits: recovery must send
|
||||
Wine's activation notification even when X11 focus already selects that child.
|
||||
The fixture acknowledges ICCCM window visibility on
|
||||
the private display; the runner propagates the fixture's actual exit status.
|
||||
with no Win32 foreground, as seen after AudioQuake exits. Recovery must restore
|
||||
both Win32 activation/control focus and native keyboard focus, even when X11
|
||||
already selects that child. The fixture deliberately leaves `WM_STATE` unset,
|
||||
matching Wine's real virtual-desktop children. Adding a synthetic window-manager
|
||||
acknowledgement masks the failure: native `WM_TAKE_FOCUS` alone can otherwise be
|
||||
ignored while Wine awaits that state change. The runner propagates the fixture's
|
||||
actual exit status.
|
||||
|
||||
Recovery queues `SetWindowPos` activation on the application's own window
|
||||
thread and sets native X11 focus without changing its size or position. It
|
||||
does not wait on the application's window procedure. A dispatched request
|
||||
alone is not acceptance: the fixture then checks Win32 foreground and the
|
||||
restored button focus after the application processes activation.
|
||||
|
||||
After installing the updated helper and restarting the reader, open AudioQuake,
|
||||
play and close a game, then Tab and Shift+Tab through the launcher. Check speech
|
||||
|
||||
@@ -57,21 +57,6 @@ int main(int argc, char **argv) {
|
||||
if (!atomReply) return 2;
|
||||
const auto activeAtom = atomReply->atom;
|
||||
std::free(atomReply);
|
||||
constexpr char stateName[] = "WM_STATE";
|
||||
auto *stateReply = xcb_intern_atom_reply(connection,
|
||||
xcb_intern_atom(connection, 0, sizeof(stateName) - 1, stateName), nullptr);
|
||||
if (!stateReply) return 2;
|
||||
const auto stateAtom = stateReply->atom;
|
||||
std::free(stateReply);
|
||||
auto acknowledge = [&](HWND window) {
|
||||
const auto xid = static_cast<xcb_window_t>(reinterpret_cast<uintptr_t>(
|
||||
GetPropW(window, L"__wine_x11_whole_window")));
|
||||
const uint32_t state[] = {1, XCB_WINDOW_NONE}; // ICCCM NormalState.
|
||||
xcb_change_property(connection, XCB_PROP_MODE_REPLACE, xid,
|
||||
stateAtom, stateAtom, 32, 2, state);
|
||||
xcb_flush(connection);
|
||||
pump();
|
||||
};
|
||||
const auto linuxWindow = xcb_generate_id(connection);
|
||||
xcb_create_window(connection, XCB_COPY_FROM_PARENT, linuxWindow, screen->root,
|
||||
0, 0, 20, 20, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, 0, nullptr);
|
||||
@@ -97,7 +82,7 @@ int main(int argc, char **argv) {
|
||||
ShowWindow(launcher, SW_HIDE);
|
||||
pump();
|
||||
ShowWindow(launcher, SW_SHOWNOACTIVATE);
|
||||
acknowledge(launcher);
|
||||
pump();
|
||||
focus(linuxWindow, linuxWindow);
|
||||
ok &= check(!GetForegroundWindow(), "Linux focus clears Wine foreground");
|
||||
ok &= check(!restore_virtual_desktop_focus() && !GetForegroundWindow(), "Linux focus is never taken");
|
||||
@@ -111,7 +96,7 @@ int main(int argc, char **argv) {
|
||||
ok &= check(!restore_virtual_desktop_focus(), "disabled application is not activated");
|
||||
EnableWindow(launcher, TRUE);
|
||||
ShowWindow(other, SW_SHOWNOACTIVATE);
|
||||
acknowledge(other);
|
||||
pump();
|
||||
focus(linuxWindow, linuxWindow);
|
||||
focus(desktop, desktop);
|
||||
ok &= check(!restore_virtual_desktop_focus() && !GetForegroundWindow(), "ambiguous applications are not chosen");
|
||||
@@ -126,7 +111,7 @@ int main(int argc, char **argv) {
|
||||
ShowWindow(launcher, SW_HIDE);
|
||||
pump();
|
||||
ShowWindow(launcher, SW_SHOWNOACTIVATE);
|
||||
acknowledge(launcher);
|
||||
pump();
|
||||
focus(linuxWindow, linuxWindow);
|
||||
focus(desktop, desktop);
|
||||
ok &= check(restore_virtual_desktop_focus(), "later workspace return recovers again");
|
||||
@@ -134,14 +119,14 @@ int main(int argc, char **argv) {
|
||||
ShowWindow(launcher, SW_HIDE);
|
||||
pump();
|
||||
ShowWindow(launcher, SW_SHOWNOACTIVATE);
|
||||
acknowledge(launcher);
|
||||
pump();
|
||||
focus(linuxWindow, linuxWindow);
|
||||
const auto launcherXid = static_cast<xcb_window_t>(reinterpret_cast<uintptr_t>(
|
||||
GetPropW(launcher, L"__wine_x11_whole_window")));
|
||||
focus(launcherXid, linuxWindow);
|
||||
ok &= check(!restore_virtual_desktop_focus(), "focused child requires window manager desktop ownership");
|
||||
ShowWindow(other, SW_SHOWNOACTIVATE);
|
||||
acknowledge(other);
|
||||
pump();
|
||||
focus(launcherXid, desktop);
|
||||
ok &= check(!restore_virtual_desktop_focus(), "focused child does not bypass ambiguous applications");
|
||||
ShowWindow(other, SW_HIDE);
|
||||
|
||||
Reference in new issue
Block a user