Reset master to testing content
This commit is contained in:
1 parent
0f2587b719
commit
42afa2a56c
1483 files changed
+145308
-938069
No files matched your search
@@ -0,0 +1,106 @@
|
||||
// Copyright (c) 2026 Storm Dragon
|
||||
// Authors: Storm Dragon, Angus Kola
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "commands_native.h"
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <string.h>
|
||||
|
||||
static int steam_active_window(Display *display, Window *window) {
|
||||
Atom type; int format;
|
||||
unsigned long count, remaining;
|
||||
unsigned char *data = NULL;
|
||||
int known = XGetWindowProperty(display, DefaultRootWindow(display), XInternAtom(display, "_NET_ACTIVE_WINDOW", False),
|
||||
0, 1, False, XA_WINDOW, &type, &format, &count, &remaining, &data) == Success &&
|
||||
data != NULL && type == XA_WINDOW && format == 32 && count == 1;
|
||||
if (known) *window = ((Window *)data)[0];
|
||||
if (data != NULL) XFree(data);
|
||||
return known;
|
||||
}
|
||||
|
||||
static int steam_window_pid(Display *display, Window window) {
|
||||
Atom type; int format;
|
||||
unsigned long count, remaining;
|
||||
unsigned char *data = NULL;
|
||||
int pid = 0;
|
||||
if (XGetWindowProperty(display, window, XInternAtom(display, "_NET_WM_PID", False),
|
||||
0, 1, False, XA_CARDINAL, &type, &format, &count,
|
||||
&remaining, &data) == Success && data != NULL &&
|
||||
type == XA_CARDINAL && format == 32 && count == 1) {
|
||||
pid = (int)((unsigned long *)data)[0];
|
||||
}
|
||||
if (data != NULL) XFree(data);
|
||||
return pid;
|
||||
}
|
||||
|
||||
static int steam_wrapper(Display *display, Window window) {
|
||||
XClassHint hint = {0};
|
||||
int matches = XGetClassHint(display, window, &hint) &&
|
||||
hint.res_name != NULL && hint.res_class != NULL &&
|
||||
strcmp(hint.res_name, "steamwebhelper") == 0 && strcmp(hint.res_class, "steam") == 0;
|
||||
if (hint.res_name != NULL) XFree(hint.res_name);
|
||||
if (hint.res_class != NULL) XFree(hint.res_class);
|
||||
return matches;
|
||||
}
|
||||
|
||||
static int steam_browser_child(Display *display, Window wrapper, int pid, Window child) {
|
||||
XWindowAttributes attributes;
|
||||
if (child == None || child == PointerRoot || child == wrapper ||
|
||||
!XGetWindowAttributes(display, child, &attributes) || attributes.map_state != IsViewable ||
|
||||
attributes.class != InputOutput || steam_window_pid(display, child) != pid) return 0;
|
||||
for (int depth = 0; depth < 32; depth++) {
|
||||
Window root, parent, *children = NULL;
|
||||
unsigned int count;
|
||||
if (!XQueryTree(display, child, &root, &parent, &children, &count)) return 0;
|
||||
if (children != NULL) XFree(children);
|
||||
if (parent == wrapper) return 1;
|
||||
if (parent == None || parent == root) return 0;
|
||||
child = parent;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
CommandFocusSample cthulhu_read_command_focus(Display *display, int steam_enabled) {
|
||||
CommandFocusSample result = {0};
|
||||
SteamFocusSample *sample = &result.steam;
|
||||
cthulhu_x11_begin_read(display);
|
||||
result.xterm = cthulhu_focus_metadata_unchecked(display, steam_enabled ? sample : NULL);
|
||||
if (sample->steam) {
|
||||
sample->pid = steam_window_pid(display, sample->window);
|
||||
sample->steam = sample->pid > 0;
|
||||
int revert;
|
||||
XGetInputFocus(display, &sample->focus, &revert);
|
||||
if (sample->steam) sample->innerFocus = steam_browser_child(display, sample->window, sample->pid, sample->focus);
|
||||
}
|
||||
if (cthulhu_x11_end_read(display)) result = (CommandFocusSample){0};
|
||||
return result;
|
||||
}
|
||||
|
||||
int cthulhu_restore_steam_focus(Display *display, Window wrapper, int pid, Window target) {
|
||||
cthulhu_x11_begin_read(display);
|
||||
int restored = 0, revert;
|
||||
Window focus, active = None;
|
||||
XGetInputFocus(display, &focus, &revert);
|
||||
char heldKeys[32];
|
||||
XQueryKeymap(display, heldKeys);
|
||||
int keyHeld = 0;
|
||||
for (int i = 0; i < 32; i++) keyHeld |= heldKeys[i];
|
||||
if (!keyHeld && focus == wrapper && steam_active_window(display, &active) && active == wrapper &&
|
||||
steam_wrapper(display, wrapper) &&
|
||||
steam_window_pid(display, wrapper) == pid && steam_browser_child(display, wrapper, pid, target)) {
|
||||
// Recheck foreground immediately before changing input focus: cached
|
||||
// children must never pull keyboard input out of a different client.
|
||||
if (steam_active_window(display, &active) && active == wrapper) {
|
||||
XGetInputFocus(display, &focus, &revert);
|
||||
if (focus == wrapper) {
|
||||
XSetInputFocus(display, target, RevertToParent, CurrentTime);
|
||||
XSync(display, False);
|
||||
XGetInputFocus(display, &focus, &revert);
|
||||
restored = focus == target;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cthulhu_x11_end_read(display)) restored = 0;
|
||||
return restored;
|
||||
}
|
||||
Reference in new issue
Block a user