-void event_property_notify (Window win, Atom at)
-{
-
- if (win == server.root_win) {
- if (!server.got_root_win) {
- XSelectInput (server.dsp, server.root_win, PropertyChangeMask|StructureNotifyMask);
- server.got_root_win = 1;
- }
-
- /* Change number of desktops */
- else if (at == server.atom._NET_NUMBER_OF_DESKTOPS) {
- config_taskbar();
- redraw(&panel.area);
- panel.refresh = 1;
- }
- /* Change desktop */
- else if (at == server.atom._NET_CURRENT_DESKTOP) {
- server.desktop = server_get_current_desktop ();
- if (panel.mode != MULTI_DESKTOP) panel.refresh = 1;
- }
- /* Window list */
- else if (at == server.atom._NET_CLIENT_LIST) {
- task_refresh_tasklist ();
- panel.refresh = 1;
- }
- /* Active */
- else if (at == server.atom._NET_ACTIVE_WINDOW) {
- Window w1 = window_get_active ();
- Task *t = task_get_task(w1);
- if (t) panel.task_active = t;
- else {
- Window w2;
- if (XGetTransientForHint(server.dsp, w1, &w2) != 0)
- if (w2) panel.task_active = task_get_task(w2);
- }
- panel.refresh = 1;
- }
- /* Wallpaper changed */
- else if (at == server.atom._XROOTPMAP_ID) {
- XFreePixmap (server.dsp, server.root_pmap);
- server.root_pmap = 0;
- redraw(&panel.area);
- panel.clock.area.redraw = 1;
- panel.refresh = 1;
- }
- }
- else {
- Task *tsk;
- tsk = task_get_task (win);
- if (!tsk) return;
- //printf("atom root_win = %s, %s\n", XGetAtomName(server.dsp, at), tsk->title);
-
- /* Window title changed */
- if (at == server.atom._NET_WM_VISIBLE_NAME || at == server.atom._NET_WM_NAME || at == server.atom.WM_NAME) {
- get_title(tsk);
- tsk->area.redraw = 1;
- panel.refresh = 1;
- }
- /* Iconic state */
- else if (at == server.atom.WM_STATE) {
- if (window_is_iconified (win))
- if (panel.task_active == tsk) panel.task_active = 0;
- }
- /* Window icon changed */
- else if (at == server.atom._NET_WM_ICON) {
- if (tsk->icon_data != 0) XFree (tsk->icon_data);
- tsk->area.redraw = 1;
- tsk->icon_data = 0;
- panel.refresh = 1;
- }
- /* Window desktop changed */
- else if (at == server.atom._NET_WM_DESKTOP) {
- add_task (tsk->win);
- remove_task (tsk);
- panel.refresh = 1;
- }
-
- if (!server.got_root_win) server.root_win = RootWindow (server.dsp, server.screen);
- }
+void event_button_press (XEvent *e)
+{
+ Panel *panel = get_panel(e->xany.window);
+ if (!panel) return;
+
+
+ if (wm_menu && !tint2_handles_click(panel, &e->xbutton) ) {
+ forward_click(e);
+ return;
+ }
+ task_drag = click_task(panel, e->xbutton.x, e->xbutton.y);
+
+ if (panel_layer == BOTTOM_LAYER)
+ XLowerWindow (server.dsp, panel->main_win);
+}
+
+void event_button_motion_notify (XEvent *e)
+{
+ Panel * panel = get_panel(e->xany.window);
+ if(!panel || !task_drag)
+ return;
+
+ // Find the taskbar on the event's location
+ Taskbar * event_taskbar = click_taskbar(panel, e->xbutton.x, e->xbutton.y);
+ if(event_taskbar == NULL)
+ return;
+
+ // Find the task on the event's location
+ Task * event_task = click_task(panel, e->xbutton.x, e->xbutton.y);
+
+ // If the event takes place on the same taskbar as the task being dragged
+ if(event_taskbar == task_drag->area.parent) {
+ // Swap the task_drag with the task on the event's location (if they differ)
+ if(event_task && event_task != task_drag) {
+ GSList * drag_iter = g_slist_find(event_taskbar->area.list, task_drag);
+ GSList * task_iter = g_slist_find(event_taskbar->area.list, event_task);
+ if(drag_iter && task_iter) {
+ gpointer temp = task_iter->data;
+ task_iter->data = drag_iter->data;
+ drag_iter->data = temp;
+ event_taskbar->area.resize = 1;
+ panel_refresh = 1;
+ task_dragged = 1;
+ }
+ }
+ }
+ else { // The event is on another taskbar than the task being dragged
+ if(task_drag->desktop == ALLDESKTOP || panel_mode != MULTI_DESKTOP)
+ return;
+
+ Taskbar * drag_taskbar = (Taskbar*)task_drag->area.parent;
+ drag_taskbar->area.list = g_slist_remove(drag_taskbar->area.list, task_drag);
+
+ if(event_taskbar->area.posx > drag_taskbar->area.posx || event_taskbar->area.posy > drag_taskbar->area.posy)
+ event_taskbar->area.list = g_slist_prepend(event_taskbar->area.list, task_drag);
+ else
+ event_taskbar->area.list = g_slist_append(event_taskbar->area.list, task_drag);
+
+ // Move task to other desktop (but avoid the 'Window desktop changed' code in 'event_property_notify')
+ task_drag->area.parent = event_taskbar;
+ task_drag->desktop = event_taskbar->desktop;
+
+ windows_set_desktop(task_drag->win, event_taskbar->desktop);
+
+ event_taskbar->area.resize = 1;
+ drag_taskbar->area.resize = 1;
+ task_dragged = 1;
+ panel_refresh = 1;
+ }
+}
+
+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);
+ if (panel_layer == BOTTOM_LAYER)
+ XLowerWindow (server.dsp, panel->main_win);
+ task_drag = 0;
+ return;
+ }
+
+ int action = TOGGLE_ICONIFY;
+ switch (e->xbutton.button) {
+ case 2:
+ action = mouse_middle;
+ break;
+ case 3:
+ action = mouse_right;
+ break;
+ case 4:
+ action = mouse_scroll_up;
+ break;
+ case 5:
+ action = mouse_scroll_down;
+ break;
+ case 6:
+ action = mouse_tilt_left;
+ break;
+ case 7:
+ action = mouse_tilt_right;
+ break;
+ }
+
+ if ( click_clock(panel, e->xbutton.x, e->xbutton.y)) {
+ clock_action(e->xbutton.button);
+ if (panel_layer == BOTTOM_LAYER)
+ XLowerWindow (server.dsp, panel->main_win);
+ task_drag = 0;
+ return;
+ }
+
+ if ( click_launcher(panel, e->xbutton.x, e->xbutton.y)) {
+ LauncherIcon *icon = click_launcher_icon(panel, e->xbutton.x, e->xbutton.y);
+ if (icon) {
+ launcher_action(icon);
+ }
+ task_drag = 0;
+ return;
+ }
+
+ Taskbar *tskbar;
+ if ( !(tskbar = click_taskbar(panel, e->xbutton.x, e->xbutton.y)) ) {
+ // TODO: check better solution to keep window below
+ if (panel_layer == BOTTOM_LAYER)
+ XLowerWindow (server.dsp, panel->main_win);
+ task_drag = 0;
+ return;
+ }
+
+ // drag and drop task
+ if (task_dragged) {
+ task_drag = 0;
+ task_dragged = 0;
+ return;
+ }
+
+ // switch desktop
+ if (panel_mode == MULTI_DESKTOP) {
+ if (tskbar->desktop != server.desktop && action != CLOSE && action != DESKTOP_LEFT && action != DESKTOP_RIGHT)
+ set_desktop (tskbar->desktop);
+ }
+
+ // action on task
+ window_action( click_task(panel, e->xbutton.x, e->xbutton.y), action);
+
+ // to keep window below
+ if (panel_layer == BOTTOM_LAYER)
+ XLowerWindow (server.dsp, panel->main_win);
+}
+
+
+void event_property_notify (XEvent *e)
+{
+ int i;
+ Task *tsk;
+ Window win = e->xproperty.window;
+ Atom at = e->xproperty.atom;
+
+ if (win == server.root_win) {
+ if (!server.got_root_win) {
+ XSelectInput (server.dsp, server.root_win, PropertyChangeMask|StructureNotifyMask);
+ server.got_root_win = 1;
+ }
+
+ // Change name of desktops
+ else if (at == server.atom._NET_DESKTOP_NAMES) {
+ printf("_NET_DESKTOP_NAMES\n");
+ panel_refresh = 1;
+ }
+ // Change number of desktops
+ else if (at == server.atom._NET_NUMBER_OF_DESKTOPS) {
+ if (!taskbar_enabled) return;
+ server.nb_desktop = server_get_number_of_desktop ();
+ cleanup_taskbar();
+ init_taskbar();
+ for (i=0 ; i < nb_panel ; i++) {
+ init_taskbar_panel(&panel1[i]);
+ set_panel_items_order(&panel1[i]);
+ visible_taskbar(&panel1[i]);
+ panel1[i].area.resize = 1;
+ }
+ task_refresh_tasklist();
+ active_task();
+ panel_refresh = 1;
+ }
+ // Change desktop
+ else if (at == server.atom._NET_CURRENT_DESKTOP) {
+ if (!taskbar_enabled) return;
+ int old_desktop = server.desktop;
+ server.desktop = server_get_current_desktop ();
+ for (i=0 ; i < nb_panel ; i++) {
+ Panel *panel = &panel1[i];
+ if (panel_mode == MULTI_DESKTOP && panel->g_taskbar.bg != panel->g_taskbar.bg_active) {
+ // redraw both taskbar
+ if (server.nb_desktop > old_desktop) {
+ // can happen if last desktop is deleted and we've been on the last desktop
+ panel->taskbar[old_desktop].area.bg = panel->g_taskbar.bg;
+ panel->taskbar[old_desktop].area.resize = 1;
+ }
+ panel->taskbar[server.desktop].area.bg = panel->g_taskbar.bg_active;
+ panel->taskbar[server.desktop].area.resize = 1;
+ panel_refresh = 1;
+ }
+ // check ALLDESKTOP task => resize taskbar
+ Taskbar *tskbar;
+ Task *tsk;
+ GSList *l;
+ if (server.nb_desktop > old_desktop) {
+ tskbar = &panel->taskbar[old_desktop];
+ for (l = tskbar->area.list; l ; l = l->next) {
+ tsk = l->data;
+ if (tsk->desktop == ALLDESKTOP) {
+ tsk->area.on_screen = 0;
+ tskbar->area.resize = 1;
+ panel_refresh = 1;
+ }
+ }
+ }
+ tskbar = &panel->taskbar[server.desktop];
+ for (l = tskbar->area.list; l ; l = l->next) {
+ tsk = l->data;
+ if (tsk->desktop == ALLDESKTOP) {
+ tsk->area.on_screen = 1;
+ tskbar->area.resize = 1;
+ }
+ }
+ if (panel_mode != MULTI_DESKTOP)
+ visible_taskbar(panel);
+ }
+ }
+ // Window list
+ else if (at == server.atom._NET_CLIENT_LIST) {
+ task_refresh_tasklist();
+ panel_refresh = 1;
+ }
+ // Change active
+ else if (at == server.atom._NET_ACTIVE_WINDOW) {
+ active_task();
+ panel_refresh = 1;
+ }
+ else if (at == server.atom._XROOTPMAP_ID) {
+ // change Wallpaper
+ for (i=0 ; i < nb_panel ; i++) {
+ set_panel_background(&panel1[i]);
+ }
+ panel_refresh = 1;
+ }
+ }
+ else {
+ tsk = task_get_task (win);
+ if (!tsk) {
+ if (at != server.atom._NET_WM_STATE)
+ return;
+ else {
+ // xfce4 sends _NET_WM_STATE after minimized to tray, so we need to check if window is mapped
+ // if it is mapped and not set as skip_taskbar, we must add it to our task list
+ XWindowAttributes wa;
+ XGetWindowAttributes(server.dsp, win, &wa);
+ if (wa.map_state == IsViewable && !window_is_skip_taskbar(win)) {
+ if ( (tsk = add_task(win)) )
+ panel_refresh = 1;
+ else
+ return;
+ }
+ else
+ return;
+ }
+ }
+ //printf("atom root_win = %s, %s\n", XGetAtomName(server.dsp, at), tsk->title);
+
+ // Window title changed
+ if (at == server.atom._NET_WM_VISIBLE_NAME || at == server.atom._NET_WM_NAME || at == server.atom.WM_NAME) {
+ get_title(tsk);
+ if (g_tooltip.mapped && (g_tooltip.area == (Area*)tsk)) {
+ tooltip_copy_text((Area*)tsk);
+ tooltip_update();
+ }
+ panel_refresh = 1;
+ }
+ // Demand attention
+ else if (at == server.atom._NET_WM_STATE) {
+ if (window_is_urgent (win)) {
+ add_urgent(tsk);
+ }
+ if (window_is_skip_taskbar(win)) {
+ remove_task( tsk );
+ panel_refresh = 1;
+ }
+ }
+ else if (at == server.atom.WM_STATE) {
+ // Iconic state
+ int state = (task_active && tsk->win == task_active->win ? TASK_ACTIVE : TASK_NORMAL);
+ if (window_is_iconified(win))
+ state = TASK_ICONIFIED;
+ set_task_state(tsk, state);
+ panel_refresh = 1;
+ }
+ // Window icon changed
+ else if (at == server.atom._NET_WM_ICON) {
+ get_icon(tsk);
+ panel_refresh = 1;
+ }
+ // Window desktop changed
+ else if (at == server.atom._NET_WM_DESKTOP) {
+ int desktop = window_get_desktop (win);
+ //printf(" Window desktop changed %d, %d\n", tsk->desktop, desktop);
+ // bug in windowmaker : send unecessary 'desktop changed' when focus changed
+ if (desktop != tsk->desktop) {
+ remove_task (tsk);
+ tsk = add_task (win);
+ active_task();
+ panel_refresh = 1;
+ }
+ }
+ else if (at == server.atom.WM_HINTS) {
+ XWMHints* wmhints = XGetWMHints(server.dsp, win);
+ if (wmhints && wmhints->flags & XUrgencyHint) {
+ add_urgent(tsk);
+ }
+ XFree(wmhints);
+ }
+
+ if (!server.got_root_win) server.root_win = RootWindow (server.dsp, server.screen);
+ }
+}
+
+
+void event_expose (XEvent *e)
+{
+ Panel *panel;
+ panel = get_panel(e->xany.window);
+ if (!panel) return;
+ // TODO : one panel_refresh per panel ?
+ panel_refresh = 1;