diff options
author | dec05eba <dec05eba@protonmail.com> | 2025-01-06 20:54:12 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2025-01-06 20:54:12 +0100 |
commit | cb64ba2b372246bc6a12cfc2622fd87e219dc4ce (patch) | |
tree | ed9a6782e7f7e107fdce621f2d2532872b33b5d0 | |
parent | e5199c55121aabfd845c4c1c76e14eb350627e91 (diff) |
Reapply "Do dumb shit hacks to get focused monitor on gnome and sway"
This reverts commit e5199c55121aabfd845c4c1c76e14eb350627e91.
-rw-r--r-- | src/main.cpp | 126 |
1 files changed, 117 insertions, 9 deletions
diff --git a/src/main.cpp b/src/main.cpp index 363aacf..9afa257 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -179,14 +179,36 @@ static mgl::vec2i get_cursor_position(Display *dpy) { return root_pos; } -static mgl::vec2i create_window_get_center_position(Display *display) { - const int size = 16; +typedef struct { + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long input_mode; + unsigned long status; +} MotifHints; + +#define MWM_HINTS_DECORATIONS 2 + +#define MWM_DECOR_NONE 0 +#define MWM_DECOR_ALL 1 + +static void window_set_decorations_visible(Display *display, Window window, bool visible) { + const Atom motif_wm_hints_atom = XInternAtom(display, "_MOTIF_WM_HINTS", False); + MotifHints motif_hints; + memset(&motif_hints, 0, sizeof(motif_hints)); + motif_hints.flags = MWM_HINTS_DECORATIONS; + motif_hints.decorations = visible ? MWM_DECOR_ALL : MWM_DECOR_NONE; + XChangeProperty(display, window, motif_wm_hints_atom, motif_wm_hints_atom, 32, PropModeReplace, (unsigned char*)&motif_hints, sizeof(motif_hints) / sizeof(long)); +} + +static bool create_window_get_center_position_kde(Display *display, mgl::vec2i &position) { + const int size = 1; XSetWindowAttributes window_attr; window_attr.event_mask = StructureNotifyMask; window_attr.background_pixel = 0; const Window window = XCreateWindow(display, DefaultRootWindow(display), 0, 0, size, size, 0, CopyFromParent, InputOutput, CopyFromParent, CWBackPixel | CWEventMask, &window_attr); if(!window) - return {0, 0}; + return false; const Atom net_wm_window_type_atom = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); const Atom net_wm_window_type_notification_atom = XInternAtom(display, "_NET_WM_WINDOW_TYPE_NOTIFICATION", False); @@ -203,12 +225,14 @@ static mgl::vec2i create_window_get_center_position(Display *display) { const unsigned long opacity = (unsigned long)(0xFFFFFFFFul * alpha); XChangeProperty(display, window, net_wm_window_opacity, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&opacity, 1L); + window_set_decorations_visible(display, window, false); + XSizeHints *size_hints = XAllocSizeHints(); size_hints->width = size; - size_hints->min_width = size; - size_hints->max_width = size; size_hints->height = size; + size_hints->min_width = size; size_hints->min_height = size; + size_hints->max_width = size; size_hints->max_height = size; size_hints->flags = PSize | PMinSize | PMaxSize; XSetWMNormalHints(display, window, size_hints); @@ -217,8 +241,8 @@ static mgl::vec2i create_window_get_center_position(Display *display) { XMapWindow(display, window); XFlush(display); + bool got_data = false; const int x_fd = XConnectionNumber(display); - mgl::vec2i window_pos; XEvent xev; while(true) { struct pollfd poll_fd; @@ -235,16 +259,100 @@ static mgl::vec2i create_window_get_center_position(Display *display) { XNextEvent(display, &xev); if(xev.type == ConfigureNotify) { - window_pos.x = xev.xconfigure.x + xev.xconfigure.width / 2; - window_pos.y = xev.xconfigure.y + xev.xconfigure.height / 2; + got_data = xev.xconfigure.x > 0 && xev.xconfigure.y > 0; + position.x = xev.xconfigure.x + xev.xconfigure.width / 2; + position.y = xev.xconfigure.y + xev.xconfigure.height / 2; + break; + } + } + + XDestroyWindow(display, window); + XFlush(display); + + return got_data; +} + +static bool create_window_get_center_position_gnome(Display *display, mgl::vec2i &position) { + const int size = 32; + XSetWindowAttributes window_attr; + window_attr.event_mask = StructureNotifyMask | ExposureMask; + window_attr.background_pixel = 0; + const Window window = XCreateWindow(display, DefaultRootWindow(display), 0, 0, size, size, 0, CopyFromParent, InputOutput, CopyFromParent, CWBackPixel | CWEventMask, &window_attr); + if(!window) + return false; + + const Atom net_wm_window_opacity = XInternAtom(display, "_NET_WM_WINDOW_OPACITY", False); + const double alpha = 0.0; + const unsigned long opacity = (unsigned long)(0xFFFFFFFFul * alpha); + XChangeProperty(display, window, net_wm_window_opacity, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&opacity, 1L); + + window_set_decorations_visible(display, window, false); + + XSizeHints *size_hints = XAllocSizeHints(); + size_hints->width = size; + size_hints->height = size; + size_hints->min_width = size; + size_hints->min_height = size; + size_hints->max_width = size; + size_hints->max_height = size; + size_hints->flags = PSize | PMinSize | PMaxSize; + XSetWMNormalHints(display, window, size_hints); + XFree(size_hints); + + XMapWindow(display, window); + XFlush(display); + + bool got_data = false; + const int x_fd = XConnectionNumber(display); + XEvent xev; + while(true) { + struct pollfd poll_fd; + poll_fd.fd = x_fd; + poll_fd.events = POLLIN; + poll_fd.revents = 0; + const int fds_ready = poll(&poll_fd, 1, 1000); + if(fds_ready == 0) { + fprintf(stderr, "Error: timed out waiting for MapNotify/ConfigureNotify after XCreateWindow\n"); break; + } else if(fds_ready == -1 || !(poll_fd.revents & POLLIN)) { + continue; + } + + XNextEvent(display, &xev); + if(xev.type == MapNotify) { + int x = 0; + int y = 0; + Window w = None; + XTranslateCoordinates(display, window, DefaultRootWindow(display), 0, 0, &x, &y, &w); + + got_data = x > 0 && y > 0; + position.x = x + size / 2; + position.y = y + size / 2; + if(got_data) + break; + } else if(xev.type == ConfigureNotify) { + got_data = xev.xconfigure.x > 0 && xev.xconfigure.y > 0; + position.x = xev.xconfigure.x + xev.xconfigure.width / 2; + position.y = xev.xconfigure.y + xev.xconfigure.height / 2; + if(got_data) + break; } } XDestroyWindow(display, window); XFlush(display); - return window_pos; + return got_data; +} + +static mgl::vec2i create_window_get_center_position(Display *display) { + mgl::vec2i pos; + if(!create_window_get_center_position_kde(display, pos)) { + pos.x = 0; + pos.y = 0; + create_window_get_center_position_gnome(display, pos); + } + return pos; } int main(int argc, char **argv) { |