mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Closing #212: Panel buttons are reodered on titlebar click.
By default, pekwm will reorder window list on input focus (probably to optimize things) and this would also reorder buttons inside taskbar. Also, on new window list, all panel buttons would be recreated again, causing many allocations and deallocations. Now, window list received from wm is compared agains internal window storage for diffs. Fixing this issue made removal some old edewm specific code and made panel nicely working under sawfish ;)
This commit is contained in:
parent
9751acdd9e
commit
fb708f76ed
@ -357,10 +357,7 @@ void Panel::do_layout(void) {
|
||||
}
|
||||
|
||||
void Panel::show(void) {
|
||||
if(shown()) {
|
||||
Fl_Window::show();
|
||||
return;
|
||||
}
|
||||
if(shown()) return;
|
||||
|
||||
/*
|
||||
* hush known FLTK bug with XGetImage; a lot of errors will be print when menu icons goes
|
||||
@ -375,10 +372,15 @@ void Panel::show(void) {
|
||||
|
||||
void Panel::hide(void) {
|
||||
Fl::remove_handler(x_events);
|
||||
netwm_window_remove_strut(fl_xid(this));
|
||||
|
||||
E_DEBUG("Panel::hide()\n");
|
||||
|
||||
/* strange; this is not called when panel goes out :S */
|
||||
mgr.clear();
|
||||
save_config();
|
||||
|
||||
Fl_Window::hide();
|
||||
}
|
||||
|
||||
void Panel::update_size_and_pos(bool create_xid, bool update_strut) {
|
||||
|
@ -44,6 +44,7 @@ static int handle_xevent(int e) {
|
||||
}
|
||||
} else if(fl_xevent->type == DestroyNotify) {
|
||||
XDestroyWindowEvent xev = fl_xevent->xdestroywindow;
|
||||
E_DEBUG(E_STRLOC ": Unock request for %i\n", fl_xevent->xclient.data.l[2]);
|
||||
curr_tray->unembed_window(xev.window);
|
||||
return false;
|
||||
} else if(fl_xevent->type == ConfigureNotify) {
|
||||
@ -67,6 +68,7 @@ static int validate_drawable(Display *d, Window xid) {
|
||||
}
|
||||
|
||||
Tray::Tray() : Fl_Group(0, 0, 1, 25), opcode(0) {
|
||||
//color(FL_RED);
|
||||
box(FL_FLAT_BOX);
|
||||
register_notification_area();
|
||||
}
|
||||
@ -87,6 +89,7 @@ void Tray::distribute_children(void) {
|
||||
Y = y();
|
||||
for(int i = 0; i < children(); i++) {
|
||||
child(i)->position(X, Y);
|
||||
E_DEBUG(E_STRLOC ": child %i at %i %i\n", i, child(i)->x(), child(i)->y());
|
||||
X += child(i)->w() + TRAY_ICONS_SPACE;
|
||||
}
|
||||
}
|
||||
|
@ -47,12 +47,10 @@ EDELIB_NS_USING(netwm_window_set_active)
|
||||
EDELIB_NS_USING(netwm_window_get_title)
|
||||
EDELIB_NS_USING(netwm_window_get_icon)
|
||||
EDELIB_NS_USING(netwm_window_set_state)
|
||||
EDELIB_NS_USING(wm_window_ede_restore)
|
||||
EDELIB_NS_USING(wm_window_get_state)
|
||||
EDELIB_NS_USING(wm_window_set_state)
|
||||
EDELIB_NS_USING(WM_WINDOW_STATE_ICONIC)
|
||||
EDELIB_NS_USING(NETWM_STATE_ACTION_TOGGLE)
|
||||
EDELIB_NS_USING(NETWM_STATE_ACTION_ADD)
|
||||
EDELIB_NS_USING(NETWM_STATE_MAXIMIZED)
|
||||
EDELIB_NS_USING(NETWM_STATE_HIDDEN)
|
||||
|
||||
static Fl_Pixmap image_window(window_xpm);
|
||||
|
||||
@ -83,25 +81,22 @@ static void close_cb(Fl_Widget*, void *b) {
|
||||
|
||||
static void restore_cb(Fl_Widget*, void *b) {
|
||||
TaskButton *bb = (TaskButton*)b;
|
||||
wm_window_ede_restore(bb->get_window_xid());
|
||||
|
||||
netwm_window_set_active(bb->get_window_xid());
|
||||
netwm_window_set_active(bb->get_window_xid(), 1);
|
||||
redraw_whole_panel(bb);
|
||||
}
|
||||
|
||||
static void minimize_cb(Fl_Widget*, void *b) {
|
||||
TaskButton *bb = (TaskButton*)b;
|
||||
|
||||
if(wm_window_get_state(bb->get_window_xid()) != WM_WINDOW_STATE_ICONIC)
|
||||
wm_window_set_state(bb->get_window_xid(), WM_WINDOW_STATE_ICONIC);
|
||||
|
||||
netwm_window_set_state(bb->get_window_xid(), NETWM_STATE_HIDDEN, NETWM_STATE_ACTION_ADD);
|
||||
redraw_whole_panel(bb);
|
||||
}
|
||||
|
||||
static void maximize_cb(Fl_Widget*, void *b) {
|
||||
TaskButton *bb = (TaskButton*)b;
|
||||
|
||||
netwm_window_set_active(bb->get_window_xid());
|
||||
netwm_window_set_active(bb->get_window_xid(), 1);
|
||||
netwm_window_set_state(bb->get_window_xid(), NETWM_STATE_MAXIMIZED, NETWM_STATE_ACTION_TOGGLE);
|
||||
|
||||
redraw_whole_panel(bb);
|
||||
|
@ -22,14 +22,15 @@
|
||||
#include <FL/Fl_Button.H>
|
||||
#include <edelib/Debug.h>
|
||||
#include <edelib/Netwm.h>
|
||||
#include <edelib/List.h>
|
||||
|
||||
#include "TaskButton.h"
|
||||
#include "Taskbar.h"
|
||||
#include "Panel.h"
|
||||
|
||||
#define DEFAULT_CHILD_W 175
|
||||
#define DEFAULT_SPACING 5
|
||||
|
||||
EDELIB_NS_USING(list)
|
||||
EDELIB_NS_USING(netwm_callback_add)
|
||||
EDELIB_NS_USING(netwm_callback_remove)
|
||||
EDELIB_NS_USING(netwm_window_get_all_mapped)
|
||||
@ -37,6 +38,7 @@ EDELIB_NS_USING(netwm_window_is_manageable)
|
||||
EDELIB_NS_USING(netwm_window_get_workspace)
|
||||
EDELIB_NS_USING(netwm_window_get_active)
|
||||
EDELIB_NS_USING(netwm_window_set_active)
|
||||
EDELIB_NS_USING(netwm_window_set_state)
|
||||
EDELIB_NS_USING(netwm_workspace_get_current)
|
||||
EDELIB_NS_USING(wm_window_set_state)
|
||||
EDELIB_NS_USING(wm_window_get_state)
|
||||
@ -46,6 +48,11 @@ EDELIB_NS_USING(NETWM_CHANGED_WINDOW_LIST)
|
||||
EDELIB_NS_USING(NETWM_CHANGED_WINDOW_NAME)
|
||||
EDELIB_NS_USING(NETWM_CHANGED_WINDOW_ICON)
|
||||
EDELIB_NS_USING(WM_WINDOW_STATE_ICONIC)
|
||||
EDELIB_NS_USING(NETWM_STATE_ACTION_TOGGLE)
|
||||
EDELIB_NS_USING(NETWM_STATE_HIDDEN)
|
||||
|
||||
typedef list<Window> WindowList;
|
||||
typedef list<Window>::iterator WindowListIt;
|
||||
|
||||
static void button_cb(TaskButton *b, void *t) {
|
||||
Taskbar *tt = (Taskbar*)t;
|
||||
@ -59,9 +66,16 @@ 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;
|
||||
tt->update_active_button();
|
||||
return;
|
||||
}
|
||||
|
||||
if(action == NETWM_CHANGED_CURRENT_WORKSPACE || action == NETWM_CHANGED_WINDOW_LIST) {
|
||||
Taskbar *tt = (Taskbar*)data;
|
||||
tt->create_task_buttons();
|
||||
tt->update_task_buttons();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -71,13 +85,6 @@ static void net_event_cb(int action, Window xid, void *data) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
tt->update_active_button();
|
||||
return;
|
||||
}
|
||||
|
||||
if(action == NETWM_CHANGED_WINDOW_ICON) {
|
||||
Taskbar *tt = (Taskbar*)data;
|
||||
tt->update_child_icon(xid);
|
||||
@ -85,11 +92,10 @@ static void net_event_cb(int action, Window xid, void *data) {
|
||||
}
|
||||
}
|
||||
|
||||
Taskbar::Taskbar() : Fl_Group(0, 0, 40, 25), curr_active(NULL), prev_active(NULL), panel(NULL) {
|
||||
Taskbar::Taskbar() : Fl_Group(0, 0, 40, 25), curr_active(NULL), prev_active(NULL) {
|
||||
end();
|
||||
|
||||
panel = EDE_PANEL_GET_PANEL_OBJECT(this);
|
||||
create_task_buttons();
|
||||
update_task_buttons();
|
||||
netwm_callback_add(net_event_cb, this);
|
||||
}
|
||||
|
||||
@ -97,30 +103,62 @@ Taskbar::~Taskbar() {
|
||||
netwm_callback_remove(net_event_cb);
|
||||
}
|
||||
|
||||
void Taskbar::create_task_buttons(void) {
|
||||
/* erase all current elements */
|
||||
if(children())
|
||||
clear();
|
||||
|
||||
/* also current/prev storage */
|
||||
curr_active = prev_active = NULL;
|
||||
|
||||
/* redraw it, in case no windows exists in this workspace */
|
||||
panel_redraw();
|
||||
|
||||
Window *wins, transient_prop_win;
|
||||
void Taskbar::update_task_buttons(void) {
|
||||
Window *wins;
|
||||
int nwins = netwm_window_get_all_mapped(&wins);
|
||||
|
||||
if(nwins > 0) {
|
||||
if(nwins < 1) {
|
||||
if(children() > 0) clear();
|
||||
return;
|
||||
}
|
||||
|
||||
TaskButton *b;
|
||||
int curr_workspace = netwm_workspace_get_current();
|
||||
bool need_full_redraw = false;
|
||||
|
||||
for(int i = 0; i < nwins; i++) {
|
||||
transient_prop_win = None;
|
||||
/*
|
||||
* first remove windows not available in list received by wm
|
||||
*
|
||||
* TODO: FLTK 1.3.x got new function remove(int index) which will make
|
||||
* faster removal, comparing to remove(Fl_Widget*)
|
||||
*/
|
||||
for(int i = 0, found; i < children(); i++) {
|
||||
found = 0;
|
||||
b = (TaskButton*)child(i);
|
||||
|
||||
if(!netwm_window_is_manageable(wins[i]))
|
||||
for(int j = 0; j < nwins; j++) {
|
||||
if(b->get_window_xid() == wins[j]) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
remove(b);
|
||||
/* Fl_Group does not call delete on remove() */
|
||||
delete b;
|
||||
need_full_redraw = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* now see which one needs to create */
|
||||
for(int i = 0, found; i < nwins; i++) {
|
||||
found = 0;
|
||||
|
||||
for(int j = 0; j < children(); j++) {
|
||||
b = (TaskButton*)child(j);
|
||||
|
||||
if(b->get_window_xid() == wins[i]) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(found || !netwm_window_is_manageable(wins[i]))
|
||||
continue;
|
||||
|
||||
Window transient_prop_win = None;
|
||||
|
||||
/*
|
||||
* see if it has WM_TRANSIENT_FOR hint set; transient_prop_win would point to parent window, but
|
||||
* parent should not be root window for this screen
|
||||
@ -132,10 +170,7 @@ void Taskbar::create_task_buttons(void) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* show window per workspace
|
||||
* TODO: allow showing all windows in each workspace
|
||||
*/
|
||||
/* TODO: allow showing all windows in each workspace */
|
||||
if(curr_workspace == netwm_window_get_workspace(wins[i])) {
|
||||
b = new TaskButton(0, 0, DEFAULT_CHILD_W, 25);
|
||||
b->set_window_xid(wins[i]);
|
||||
@ -144,17 +179,16 @@ void Taskbar::create_task_buttons(void) {
|
||||
|
||||
/* catch the name changes */
|
||||
XSelectInput(fl_display, wins[i], PropertyChangeMask | StructureNotifyMask);
|
||||
|
||||
b->callback((Fl_Callback*)button_cb, this);
|
||||
add(b);
|
||||
}
|
||||
}
|
||||
|
||||
XFree(wins);
|
||||
}
|
||||
|
||||
layout_children();
|
||||
update_active_button();
|
||||
update_active_button(!need_full_redraw);
|
||||
|
||||
if(need_full_redraw) panel_redraw();
|
||||
}
|
||||
|
||||
void Taskbar::resize(int X, int Y, int W, int H) {
|
||||
@ -193,7 +227,7 @@ void Taskbar::layout_children(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void Taskbar::update_active_button(int xid) {
|
||||
void Taskbar::update_active_button(bool do_redraw, int xid) {
|
||||
if(!children())
|
||||
return;
|
||||
|
||||
@ -212,7 +246,7 @@ void Taskbar::update_active_button(int xid) {
|
||||
o->box(FL_UP_BOX);
|
||||
}
|
||||
|
||||
redraw();
|
||||
if(do_redraw) redraw();
|
||||
}
|
||||
|
||||
void Taskbar::activate_window(TaskButton *b) {
|
||||
@ -239,7 +273,7 @@ void Taskbar::activate_window(TaskButton *b) {
|
||||
}
|
||||
|
||||
/* active or restore minimized */
|
||||
netwm_window_set_active(xid);
|
||||
netwm_window_set_active(xid, 1);
|
||||
update_active_button(xid);
|
||||
|
||||
/* TODO: use stack for this (case when this can't handle: minimize three window, out of four on the workspace) */
|
||||
@ -277,8 +311,7 @@ void Taskbar::update_child_icon(Window xid) {
|
||||
}
|
||||
|
||||
void Taskbar::panel_redraw(void) {
|
||||
E_RETURN_IF_FAIL(panel != NULL);
|
||||
panel->redraw();
|
||||
parent()->redraw();
|
||||
}
|
||||
|
||||
EDE_PANEL_APPLET_EXPORT (
|
||||
|
@ -25,23 +25,20 @@
|
||||
#include "Applet.h"
|
||||
|
||||
class TaskButton;
|
||||
class Panel;
|
||||
|
||||
class Taskbar : public Fl_Group {
|
||||
public:
|
||||
TaskButton *curr_active, *prev_active;
|
||||
Panel *panel;
|
||||
|
||||
public:
|
||||
Taskbar();
|
||||
~Taskbar();
|
||||
|
||||
void create_task_buttons(void);
|
||||
void update_task_buttons(void);
|
||||
|
||||
void resize(int X, int Y, int W, int H);
|
||||
void layout_children(void);
|
||||
|
||||
void update_active_button(int xid = -1);
|
||||
void update_active_button(bool do_redraw = true, int xid = -1);
|
||||
void activate_window(TaskButton *b);
|
||||
void update_child_title(Window xid);
|
||||
void update_child_icon(Window xid);
|
||||
|
@ -31,28 +31,22 @@
|
||||
#include "Panel.h"
|
||||
#include "AppletManager.h"
|
||||
|
||||
static bool running;
|
||||
static Panel *panel;
|
||||
|
||||
static void exit_signal(int signum) {
|
||||
running = false;
|
||||
if(panel) panel->hide();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
EDE_APPLICATION("ede-panel");
|
||||
panel = NULL;
|
||||
|
||||
signal(SIGTERM, exit_signal);
|
||||
signal(SIGKILL, exit_signal);
|
||||
signal(SIGINT, exit_signal);
|
||||
|
||||
Panel *panel = new Panel();
|
||||
panel = new Panel();
|
||||
panel->load_applets();
|
||||
panel->show();
|
||||
running = true;
|
||||
|
||||
while(running)
|
||||
Fl::wait();
|
||||
|
||||
/* so Panel::hide() can be called */
|
||||
panel->hide();
|
||||
return 0;
|
||||
return Fl::run();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user