#643 Hide/unhide programatically

This commit is contained in:
Chris Lee 2020-06-27 12:02:00 +00:00
parent 78313502d3
commit 3bdb0e03f2
5 changed files with 157 additions and 16 deletions

View file

@ -389,9 +389,9 @@ gboolean handle_x_event_autohide(XEvent *e)
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;

View file

@ -316,7 +316,7 @@ void init_panel()
}
if (panel_autohide)
autohide_trigger_hide(p);
autohide_trigger_hide(p, false);
}
taskbar_refresh_tasklist();
@ -1139,26 +1139,27 @@ void autohide_hide(void *p)
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)

View file

@ -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();

12
src/tint2-send/Makefile Normal file
View file

@ -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

128
src/tint2-send/tint2-send.c Normal file
View file

@ -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;
}