diff --git a/ede-panel/applets/taskbar/TaskButton.cpp b/ede-panel/applets/taskbar/TaskButton.cpp index e3149cb..bb7e2e2 100644 --- a/ede-panel/applets/taskbar/TaskButton.cpp +++ b/ede-panel/applets/taskbar/TaskButton.cpp @@ -103,7 +103,9 @@ static void maximize_cb(Fl_Widget*, void *b) { redraw_whole_panel(bb); } -TaskButton::TaskButton(int X, int Y, int W, int H, const char *l) : Fl_Button(X, Y, W, H, l), xid(0), image_alloc(false) { +TaskButton::TaskButton(int X, int Y, int W, int H, const char *l) : Fl_Button(X, Y, W, H, l), + xid(0), wspace(0), image_alloc(false), net_wm_icon(0) +{ box(FL_UP_BOX); align(FL_ALIGN_INSIDE | FL_ALIGN_LEFT | FL_ALIGN_CLIP); diff --git a/ede-panel/applets/taskbar/TaskButton.h b/ede-panel/applets/taskbar/TaskButton.h index 2ae7a0e..14c5301 100644 --- a/ede-panel/applets/taskbar/TaskButton.h +++ b/ede-panel/applets/taskbar/TaskButton.h @@ -28,11 +28,11 @@ class TaskButton : public Fl_Button { private: /* window ID this button handles */ Window xid; + int wspace; bool image_alloc; Atom net_wm_icon; void clear_image(void); - public: TaskButton(int X, int Y, int W, int H, const char *l = 0); ~TaskButton(); @@ -45,6 +45,9 @@ public: void update_title_from_xid(void); void update_image_from_xid(void); + + void set_workspace(int s) { wspace = s; } + int get_workspace(void) { return wspace; } }; #endif diff --git a/ede-panel/applets/taskbar/Taskbar.cpp b/ede-panel/applets/taskbar/Taskbar.cpp index 98f9d5e..5e3e073 100644 --- a/ede-panel/applets/taskbar/Taskbar.cpp +++ b/ede-panel/applets/taskbar/Taskbar.cpp @@ -45,6 +45,7 @@ EDELIB_NS_USING(NETWM_CHANGED_CURRENT_WORKSPACE) EDELIB_NS_USING(NETWM_CHANGED_WINDOW_LIST) EDELIB_NS_USING(NETWM_CHANGED_WINDOW_NAME) EDELIB_NS_USING(NETWM_CHANGED_WINDOW_ICON) +EDELIB_NS_USING(NETWM_CHANGED_WINDOW_DESKTOP) EDELIB_NS_USING(WM_WINDOW_STATE_ICONIC) EDELIB_NS_USING(NETWM_STATE_ACTION_TOGGLE) EDELIB_NS_USING(NETWM_STATE_HIDDEN) @@ -60,7 +61,7 @@ static void button_cb(TaskButton *b, void *t) { static void net_event_cb(int action, Window xid, void *data) { E_RETURN_IF_FAIL(data != NULL); - + /* this is a message, so property is not changed and netwm_window_get_active() must be called */ if(action == NETWM_CHANGED_ACTIVE_WINDOW) { Taskbar *tt = (Taskbar*)data; @@ -91,11 +92,21 @@ static void net_event_cb(int action, Window xid, void *data) { tt->update_child_icon(xid); return; } + + if(action == NETWM_CHANGED_WINDOW_DESKTOP) { + Taskbar *tt = (Taskbar*)data; + tt->update_child_workspace(xid); + return; + } } Taskbar::Taskbar() : Fl_Group(0, 0, 40, 25), curr_active(NULL), prev_active(NULL) { end(); + fixed_layout = false; + ignore_workspace_value = false; + + current_workspace = netwm_workspace_get_current(); update_task_buttons(); netwm_callback_add(net_event_cb, this); @@ -107,7 +118,7 @@ Taskbar::~Taskbar() { void Taskbar::update_task_buttons(void) { Window *wins; - int nwins = netwm_window_get_all_mapped(&wins); + int ws, nwins = netwm_window_get_all_mapped(&wins); if(nwins < 1) { if(children() > 0) clear(); @@ -115,7 +126,6 @@ void Taskbar::update_task_buttons(void) { } TaskButton *b; - int curr_workspace = netwm_workspace_get_current(); bool need_full_redraw = false; for(int i = 0, found; i < children(); i++) { @@ -173,11 +183,13 @@ void Taskbar::update_task_buttons(void) { } /* create button */ - if(curr_workspace == netwm_window_get_workspace(wins[i])) { + ws = netwm_window_get_workspace(wins[i]); + if(visible_on_current_workspace(ws)) { b = new TaskButton(0, 0, DEFAULT_CHILD_W, 25); b->set_window_xid(wins[i]); b->update_title_from_xid(); b->update_image_from_xid(); + b->set_workspace(ws); /* catch the name changes */ XSelectInput(fl_display, wins[i], PropertyChangeMask | StructureNotifyMask); @@ -197,18 +209,12 @@ void Taskbar::update_task_buttons(void) { void Taskbar::update_workspace_change(void) { if(children() < 1) return; + current_workspace = netwm_workspace_get_current(); TaskButton *b; - int p, curr_workspace = netwm_workspace_get_current(); - for(int i = 0; i < children(); i++) { b = (TaskButton*)child(i); - /* - * get fresh value, as wm can change it without notification - * (e.g. pekwm window drag to different workspace) - */ - p = netwm_window_get_workspace(b->get_window_xid()); - (p == curr_workspace) ? b->show() : b->hide(); + visible_on_current_workspace(b->get_workspace()) ? b->show() : b->hide(); } layout_children(); @@ -352,6 +358,25 @@ void Taskbar::update_child_icon(Window xid) { } } +void Taskbar::update_child_workspace(Window xid) { + if(children() < 0) return; + + TaskButton *o; + for(int i = 0; i < children(); i++) { + o = (TaskButton*)child(i); + + if(o->get_window_xid() == xid) { + int ws = netwm_window_get_workspace(xid); + o->set_workspace(ws); + visible_on_current_workspace(ws) ? o->show() : o->hide(); + break; + } + } + + layout_children(); + redraw(); +} + void Taskbar::panel_redraw(void) { parent()->redraw(); } diff --git a/ede-panel/applets/taskbar/Taskbar.h b/ede-panel/applets/taskbar/Taskbar.h index 666b713..3a4e4f4 100644 --- a/ede-panel/applets/taskbar/Taskbar.h +++ b/ede-panel/applets/taskbar/Taskbar.h @@ -24,12 +24,23 @@ #include #include "Applet.h" +/* if button should be on visible on all workspaces */ +#define ALL_WORKSPACES -1 + class TaskButton; class Taskbar : public Fl_Group { public: TaskButton *curr_active, *prev_active; - bool fixed_layout; /* fixed or streched layout of buttons */ + bool fixed_layout; /* fixed or streched layout of buttons */ + bool ignore_workspace_value; /* should all windows be shown ignoring workspace value */ + + int current_workspace; + + bool visible_on_current_workspace(int ws) { + return ignore_workspace_value || (ws == ALL_WORKSPACES) || (ws == current_workspace); + } + public: Taskbar(); ~Taskbar(); @@ -44,6 +55,7 @@ public: void activate_window(TaskButton *b); void update_child_title(Window xid); void update_child_icon(Window xid); + void update_child_workspace(Window xid); void panel_redraw(void); };