all repos — tint2 @ 3bdb0e03f2b74188a4e0207c46f326ea347e7e39

fork of the tint2 desktop panel for my custom setup - only minimized windows across all desktops for the taskbar

#643 Hide/unhide programatically
Chris Lee @klee93
commit

3bdb0e03f2b74188a4e0207c46f326ea347e7e39

parent

78313502d3b26c217f5583a23ef571bc9e0edc45

5 files changed, 157 insertions(+), 16 deletions(-)

jump to
M src/main.csrc/main.c

@@ -389,9 +389,9 @@ {

Panel *panel = get_panel(e->xany.window); if (panel && panel_autohide) { if (e->type == EnterNotify) - autohide_trigger_show(panel); + autohide_trigger_show(panel, e->xany.send_event); else if (e->type == LeaveNotify) - autohide_trigger_hide(panel); + autohide_trigger_hide(panel, e->xany.send_event); if (panel->is_hidden) { if (e->type == ClientMessage && e->xclient.message_type == server.atom.XdndPosition) { hidden_panel_shown_for_dnd = TRUE;
M src/panel.csrc/panel.c

@@ -316,7 +316,7 @@ XMapWindow(server.display, p->main_win);

} if (panel_autohide) - autohide_trigger_hide(p); + autohide_trigger_hide(p, false); } taskbar_refresh_tasklist();

@@ -1139,26 +1139,27 @@ set_panel_window_geometry(panel);

schedule_panel_redraw(); } -void autohide_trigger_show(Panel *p) +void autohide_trigger_show(Panel *p, bool forced) { if (!p) return; - change_timer(&p->autohide_timer, true, panel_autohide_show_timeout, 0, autohide_show, p); + change_timer(&p->autohide_timer, true, forced ? 0 : panel_autohide_show_timeout, 0, autohide_show, p); } -void autohide_trigger_hide(Panel *p) +void autohide_trigger_hide(Panel *p, bool forced) { if (!p) return; - Window root, child; - int xr, yr, xw, yw; - unsigned int mask; - if (XQueryPointer(server.display, p->main_win, &root, &child, &xr, &yr, &xw, &yw, &mask)) - if (child) - return; // mouse over one of the system tray icons - - change_timer(&p->autohide_timer, true, panel_autohide_hide_timeout, 0, autohide_hide, p); + if (!forced) { + Window root, child; + int xr, yr, xw, yw; + unsigned int mask; + if (XQueryPointer(server.display, p->main_win, &root, &child, &xr, &yr, &xw, &yw, &mask)) + if (child) + return; // mouse over one of the system tray icons + } + change_timer(&p->autohide_timer, true, forced ? 0 : panel_autohide_hide_timeout, 0, autohide_hide, p); } void shrink_panel(Panel *panel)
M src/panel.hsrc/panel.h

@@ -203,8 +203,8 @@ Button *click_button(Panel *panel, int x, int y);

void autohide_show(void *p); void autohide_hide(void *p); -void autohide_trigger_show(Panel *p); -void autohide_trigger_hide(Panel *p); +void autohide_trigger_show(Panel *p, bool forced); +void autohide_trigger_hide(Panel *p, bool forced); const char *get_default_font();
A src/tint2-send/Makefile

@@ -0,0 +1,12 @@

+ifeq ($(PREFIX),) + PREFIX := /usr/local +endif + +tint2-send: tint2-send.c + $(CC) tint2-send.c -lX11 -o tint2-send + +install: tint2-send + install -m 755 tint2-send $(DESTDIR)/$(PREFIX)/bin/ + +clean: + rm -f tint2-send
A src/tint2-send/tint2-send.c

@@ -0,0 +1,128 @@

+#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xatom.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +static Display *display = 0; + +/* From wmctrl */ +char *get_property(Window window, Atom xa_prop_type, const char *prop_name) { + Atom xa_prop_name = XInternAtom(display, prop_name, False); + + Atom xa_ret_type; + int ret_format; + unsigned long ret_nitems; + unsigned long ret_bytes_after; + unsigned long tmp_size; + unsigned char *ret_prop; + if (XGetWindowProperty(display, window, xa_prop_name, 0, 1024, + False, xa_prop_type, &xa_ret_type, &ret_format, + &ret_nitems, &ret_bytes_after, &ret_prop) != Success) { + return NULL; + } + + if (xa_ret_type != xa_prop_type) { + XFree(ret_prop); + return NULL; + } + + /* Correct 64 Architecture implementation of 32 bit data */ + tmp_size = (ret_format / 8) * ret_nitems; + if (ret_format == 32) + tmp_size *= sizeof(long) / 4; + + char *ret = (char *)calloc(1, tmp_size + 1); + memcpy(ret, ret_prop, tmp_size); + + XFree(ret_prop); + return ret; +} + +int is_tint2(Window window) +{ + XWindowAttributes attr = {}; + if (!XGetWindowAttributes(display, window, &attr)) + return 0; + if (attr.map_state != IsViewable) + return 0; + + char *wm_class = get_property(window, XA_STRING, "WM_NAME"); + if (!wm_class) { + return 0; + } + int class_match = 0; + if (strcmp(wm_class, "tint2") == 0) { + class_match = 1; + } + free(wm_class); + return class_match; +} + +void handle_tint2_window(Window window, void *arg) +{ + if (!is_tint2(window)) + return; + char *action = (char *)arg; + if (strcmp(action, "show") == 0) { + fprintf(stderr, "Showing tint2 window: %lx\n", window); + XEvent event = {}; + event.xcrossing.type = EnterNotify; + event.xcrossing.window = window; + event.xcrossing.mode = NotifyNormal; + event.xcrossing.detail = NotifyVirtual; + event.xcrossing.same_screen = True; + XSendEvent(display, window, False, 0, &event); + XFlush(display); + } else if (strcmp(action, "hide") == 0) { + fprintf(stderr, "Hiding tint2 window: %lx\n", window); + XEvent event = {}; + event.xcrossing.type = LeaveNotify; + event.xcrossing.window = window; + event.xcrossing.mode = NotifyNormal; + event.xcrossing.detail = NotifyVirtual; + event.xcrossing.same_screen = True; + XSendEvent(display, window, False, 0, &event); + XFlush(display); + } else { + fprintf(stderr, "Error: unknown action %s\n", action); + } +} + +typedef void window_callback_t(Window window, void *arg); + +void walk_windows(Window node, window_callback_t *callback, void *arg) +{ + callback(node, arg); + Window root = 0; + Window parent = 0; + Window *children = 0; + unsigned int nchildren = 0; + if (!XQueryTree(display, node, + &root, &parent, &children, &nchildren)) { + return; + } + for (unsigned int i = 0; i < nchildren; i++) { + walk_windows(children[i], callback, arg); + } +} + +int main(int argc, char **argv) +{ + display = XOpenDisplay(NULL); + if (!display ) { + fprintf(stderr, "Failed to open X11 connection\n"); + exit(1); + } + + argc--, argv++; + if (!argc) { + fprintf(stderr, "Usage: tint2-show show\n"); + exit(1); + } + char *action = argv[0]; + walk_windows(DefaultRootWindow(display), handle_tint2_window, action); + + return 0; +}