From f4fb078b79ed585b0ea3f26092321fbc1844db09 Mon Sep 17 00:00:00 2001 From: Andreas Fink Date: Mon, 28 Dec 2009 15:49:15 +0000 Subject: [PATCH] *fix* forward all clicks tint2 does not handle to the window manager, if wm_menu = 1 --- src/taskbar/task.c | 2 +- src/tint.c | 65 +++++++++++++++++++++++++++++++++++++--------- src/util/timer.c | 12 ++++++++- 3 files changed, 65 insertions(+), 14 deletions(-) diff --git a/src/taskbar/task.c b/src/taskbar/task.c index 21b741b..a569a99 100644 --- a/src/taskbar/task.c +++ b/src/taskbar/task.c @@ -531,7 +531,7 @@ void del_urgent(Task *tsk) int is_urgent(Task *tsk) { if (!tsk) - return; + return 0; GSList* urgent_task = urgent_list; while (urgent_task) { Task_urgent* t = urgent_task->data; diff --git a/src/tint.c b/src/tint.c index a91f8cc..fc471de 100644 --- a/src/tint.c +++ b/src/tint.c @@ -241,26 +241,61 @@ void window_action (Task *tsk, int action) } +int tint2_handles_click(Panel* panel, XButtonEvent* e) +{ + Task* task = click_task(panel, e->x, e->y); + if (task) { + if( (e->button == 1) + || (e->button == 2 && mouse_middle != 0) + || (e->button == 3 && mouse_right != 0) + || (e->button == 4 && mouse_scroll_up != 0) + || (e->button == 5 && mouse_scroll_down !=0) ) + { + return 1; + } + else + return 0; + } + // no task clicked --> check if taskbar clicked + Taskbar *tskbar = click_taskbar(panel, e->x, e->y); + if (tskbar && e->button == 1 && panel_mode == MULTI_DESKTOP) + return 1; + if (click_clock(panel, e->x, e->y)) { + if ( (e->button == 1 && clock_lclick_command) || (e->button == 2 && clock_rclick_command) ) + return 1; + else + return 0; + } + return 0; +} + + +void forward_click(XEvent* e) +{ + // forward the click to the desktop window (thanks conky) + XUngrabPointer(server.dsp, e->xbutton.time); + e->xbutton.window = server.root_win; + // icewm doesn't open under the mouse. + // and xfce doesn't open at all. + e->xbutton.x = e->xbutton.x_root; + e->xbutton.y = e->xbutton.y_root; + //printf("**** %d, %d\n", e->xbutton.x, e->xbutton.y); + //XSetInputFocus(server.dsp, e->xbutton.window, RevertToParent, e->xbutton.time); + XSendEvent(server.dsp, e->xbutton.window, False, ButtonPressMask, e); +} + + void event_button_press (XEvent *e) { Panel *panel = get_panel(e->xany.window); if (!panel) return; - task_drag = click_task(panel, e->xbutton.x, e->xbutton.y); - if (wm_menu && !task_drag && !click_clock(panel, e->xbutton.x, e->xbutton.y) && (e->xbutton.button != 1) ) { - // forward the click to the desktop window (thanks conky) - XUngrabPointer(server.dsp, e->xbutton.time); - e->xbutton.window = server.root_win; - // icewm doesn't open under the mouse. - // and xfce doesn't open at all. - e->xbutton.x = e->xbutton.x_root; - e->xbutton.y = e->xbutton.y_root; - //printf("**** %d, %d\n", e->xbutton.x, e->xbutton.y); - //XSetInputFocus(server.dsp, e->xbutton.window, RevertToParent, e->xbutton.time); - XSendEvent(server.dsp, e->xbutton.window, False, ButtonPressMask, e); + if (wm_menu && !tint2_handles_click(panel, &e->xbutton) ) { + forward_click(e); return; } + task_drag = click_task(panel, e->xbutton.x, e->xbutton.y); XLowerWindow (server.dsp, panel->main_win); } @@ -271,6 +306,12 @@ void event_button_release (XEvent *e) Panel *panel = get_panel(e->xany.window); if (!panel) return; + if (wm_menu && !tint2_handles_click(panel, &e->xbutton)) { + forward_click(e); + task_drag = 0; + return; + } + int action = TOGGLE_ICONIFY; switch (e->xbutton.button) { case 2: diff --git a/src/util/timer.c b/src/util/timer.c index 4da7cc3..8ffadc8 100644 --- a/src/util/timer.c +++ b/src/util/timer.c @@ -29,6 +29,15 @@ gint compare_timespecs(const struct timespec* t1, const struct timespec* t2); int timespec_subtract(struct timespec* result, struct timespec* x, struct timespec* y); +/** Implementation notes for timeouts: The timeouts are kept in a GSList sorted by their + * expiration time. + * That means that update_next_timeout() only have to consider the first timeout in the list, + * and callback_timeout_expired() only have to consider the timeouts as long as the expiration time + * is in the past to the current time. + * As time measurement we use clock_gettime(CLOCK_MONOTONIC) because this refers to a timer, which + * reference point lies somewhere in the past and cannot be changed, but just queried. +**/ + const struct timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)()) { struct timeout* t = malloc(sizeof(struct timeout)); @@ -71,7 +80,7 @@ void callback_timeout_expired() // it's time for the callback function t->_callback(); if (g_slist_find(timeout_list, t)) { - // if _callback() calls stop_timeout(t) the timeout 't' does not exist anymore + // if _callback() calls stop_timeout(t) the timeout 't' was freed and is not in the timeout_list timeout_list = g_slist_remove(timeout_list, t); if (t->interval_msec > 0) add_timeout_intern(t->interval_msec, t->interval_msec, t->_callback, t); @@ -87,6 +96,7 @@ void callback_timeout_expired() void stop_timeout(const struct timeout* t) { + // if not in the list, it was deleted in callback_timeout_expired if (g_slist_find(timeout_list, t)) { timeout_list = g_slist_remove(timeout_list, t); free((void*)t); -- 2.44.0