Fixing panel placement when screen size was changed. Updating main menu to use MenuTooltip code.

When screen dimensions are shrinked, panel will be moved at the correct location but will not be resized correctly. Also,
when screen dimensions are changed again, increasing sizes, panel would not catch that. Here, 'the hack' is to track
root window dimension changes and react on that, since relaying on _NET_WORKAREA is not always good; struts dimentions affects workarea size.

Main menu now has tooltips, which is Comment value from .desktop files. Also, since XdgMenuReader directly plays with MenuItem,
MenuItem::init_extensions() is used to reset uncommon values.
This commit is contained in:
Sanel Zukan 2012-06-07 09:32:27 +00:00
parent db1ebec5d9
commit 59a16eff0e
4 changed files with 68 additions and 20 deletions

View File

@ -61,6 +61,9 @@ EDELIB_NS_USING_LIST(10, (list,
typedef list<Fl_Widget*> WidgetList; typedef list<Fl_Widget*> WidgetList;
typedef list<Fl_Widget*>::iterator WidgetListIt; typedef list<Fl_Widget*>::iterator WidgetListIt;
/* used only insid x_events */
static Panel *gpanel;
inline bool intersects(Fl_Widget *o1, Fl_Widget *o2) { inline bool intersects(Fl_Widget *o1, Fl_Widget *o2) {
return (MAX(o1->x(), o2->x()) <= MIN(o1->x() + o1->w(), o2->x() + o2->w()) && return (MAX(o1->x(), o2->x()) <= MIN(o1->x() + o1->w(), o2->x() + o2->w()) &&
MAX(o1->y(), o2->y()) <= MIN(o1->y() + o1->h(), o2->y() + o2->h())); MAX(o1->y(), o2->y()) <= MIN(o1->y() + o1->h(), o2->y() + o2->h()));
@ -97,6 +100,25 @@ static void make_me_dock(Fl_Window *win) {
netwm_window_set_type(fl_xid(win), NETWM_WINDOW_TYPE_DOCK); netwm_window_set_type(fl_xid(win), NETWM_WINDOW_TYPE_DOCK);
} }
static int x_events(int ev) {
/*
* This is quite stupid to do, but hopefully very reliable. When screen is resized
* root window was resized too and using those sizes, panel is placed. Tracking workarea changes
* isn't much of use, as setting struts dimensions will affect workarea dimension too.
*/
if(fl_xevent->type == ConfigureNotify &&
(fl_xevent->xconfigure.window == RootWindow(fl_display, fl_screen))) {
gpanel->update_size_and_pos(false, false,
fl_xevent->xconfigure.x,
fl_xevent->xconfigure.y,
fl_xevent->xconfigure.width,
fl_xevent->xconfigure.height);
}
/* let others receive the same event */
return 0;
}
/* horizontaly centers widget in the panel */ /* horizontaly centers widget in the panel */
static void center_widget_h(Fl_Widget *o, Panel *self) { static void center_widget_h(Fl_Widget *o, Panel *self) {
int ph, wy; int ph, wy;
@ -195,6 +217,8 @@ static void move_widget(Panel *self, Fl_Widget *o, int &sx, int &sy) {
#endif #endif
Panel::Panel() : PanelWindow(300, 30) { Panel::Panel() : PanelWindow(300, 30) {
gpanel = this;
clicked = 0; clicked = 0;
sx = sy = 0; sx = sy = 0;
vpos = PANEL_POSITION_BOTTOM; vpos = PANEL_POSITION_BOTTOM;
@ -338,20 +362,37 @@ void Panel::show(void) {
return; return;
} }
int X, Y, W, H;
fl_open_display();
/* /*
* hush known FLTK bug with XGetImage; a lot of errors will be print when menu icons goes * hush known FLTK bug with XGetImage; a lot of errors will be print when menu icons goes
* outside screen; this also make ede-panel, at some point, unresponsible * outside screen; this also make ede-panel, at some point, unresponsible
*/ */
XSetErrorHandler((XErrorHandler) xerror_handler); XSetErrorHandler((XErrorHandler) xerror_handler);
update_size_and_pos(true, true);
/* position it */ /* collect messages */
Fl::add_handler(x_events);
}
void Panel::hide(void) {
Fl::remove_handler(x_events);
save_config();
}
void Panel::update_size_and_pos(bool create_xid, bool update_strut) {
int X, Y, W, H;
/* figure out screen dimensions */
if(!netwm_workarea_get_size(X, Y, W, H)) if(!netwm_workarea_get_size(X, Y, W, H))
Fl::screen_xywh(X, Y, W, H); Fl::screen_xywh(X, Y, W, H);
update_size_and_pos(create_xid, update_strut, X, Y, W, H);
}
void Panel::update_size_and_pos(bool create_xid, bool update_strut, int X, int Y, int W, int H) {
/* do not update ourself if we screen sizes are the same */
if(screen_x == X && screen_y == Y && screen_w == W && screen_h == H)
return;
screen_x = X; screen_x = X;
screen_y = Y; screen_y = Y;
screen_w = W; screen_w = W;
@ -368,25 +409,26 @@ void Panel::show(void) {
size(W, DEFAULT_PANEL_H); size(W, DEFAULT_PANEL_H);
do_layout(); do_layout();
window_xid_create(this, make_me_dock);
if(create_xid) window_xid_create(this, make_me_dock);
/* position it, this is done after XID was created */ /* position it, this is done after XID was created */
if(vpos == PANEL_POSITION_BOTTOM) { if(vpos == PANEL_POSITION_BOTTOM) {
position(X, screen_h - h()); position(X, screen_h - h());
if(width_perc >= 100) if(width_perc >= 100 && update_strut) {
netwm_window_remove_strut(fl_xid(this));
netwm_window_set_strut(fl_xid(this), 0, 0, 0, h()); netwm_window_set_strut(fl_xid(this), 0, 0, 0, h());
}
} else { } else {
/* FIXME: this does not work well with edewm (nor pekwm). kwin do it correctly. */ /* FIXME: this does not work well with edewm (nor pekwm). kwin do it correctly. */
position(X, Y); position(X, Y);
if(width_perc >= 100) if(width_perc >= 100 && update_strut) {
netwm_window_remove_strut(fl_xid(this));
netwm_window_set_strut(fl_xid(this), 0, 0, h(), 0); netwm_window_set_strut(fl_xid(this), 0, 0, h(), 0);
}
} }
} }
void Panel::hide(void) {
save_config();
}
int Panel::handle(int e) { int Panel::handle(int e) {
switch(e) { switch(e) {
case FL_PUSH: case FL_PUSH:

View File

@ -54,6 +54,8 @@ public:
void show(void); void show(void);
void hide(void); void hide(void);
void update_size_and_pos(bool create_xid, bool update_strut);
void update_size_and_pos(bool create_xid, bool update_strut, int X, int Y, int W, int H);
int handle(int e); int handle(int e);
void load_applets(void); void load_applets(void);

View File

@ -84,9 +84,10 @@ public:
const char *get_id(void) { return id ? id->c_str() : NULL; } const char *get_id(void) { return id ? id->c_str() : NULL; }
unsigned int get_age(void) { return age; } unsigned int get_age(void) { return age; }
const char *get_name(void) { return name ? name->c_str() : NULL; } const char *get_name(void) { return name ? name->c_str() : NULL; }
const char *get_icon(void) { return icon ? icon->c_str() : NULL; } const char *get_icon(void) { return icon ? icon->c_str() : NULL; }
const char *get_exec(void) { return exec_cmd ? exec_cmd->c_str() : NULL; } const char *get_exec(void) { return exec_cmd ? exec_cmd->c_str() : NULL; }
const char *get_comment(void) { return comment ? comment->c_str() : NULL; }
}; };
/* remove duplicate items in the list, by looking at DesktopEntry id */ /* remove duplicate items in the list, by looking at DesktopEntry id */

View File

@ -916,7 +916,7 @@ static unsigned int construct_edelib_menu(MenuContextList &lst, MenuItem *mi, un
mi[pos].labelsize_ = FL_NORMAL_SIZE; mi[pos].labelsize_ = FL_NORMAL_SIZE;
mi[pos].labelcolor_ = FL_BLACK; mi[pos].labelcolor_ = FL_BLACK;
mi[pos].image(NULL); MenuItem::init_extensions(&mi[pos]);
/* set image for menu */ /* set image for menu */
if(cc->icon && IconLoader::inited()) { if(cc->icon && IconLoader::inited()) {
@ -952,13 +952,16 @@ static unsigned int construct_edelib_menu(MenuContextList &lst, MenuItem *mi, un
mi[pos].labelfont_ = FL_HELVETICA; mi[pos].labelfont_ = FL_HELVETICA;
mi[pos].labelsize_ = FL_NORMAL_SIZE; mi[pos].labelsize_ = FL_NORMAL_SIZE;
mi[pos].labelcolor_ = FL_BLACK; mi[pos].labelcolor_ = FL_BLACK;
mi[pos].image(NULL); MenuItem::init_extensions(&mi[pos]);
/* set image for menu item*/ /* set image for menu item*/
if((*ds)->get_icon() && IconLoader::inited()) { if((*ds)->get_icon() && IconLoader::inited()) {
Fl_Image *img = IconLoader::get((*ds)->get_icon(), ICON_SIZE_SMALL); Fl_Image *img = IconLoader::get((*ds)->get_icon(), ICON_SIZE_SMALL);
mi[pos].image(img); mi[pos].image(img);
} }
/* set tooltip if we have; it is actually a comment from .desktop file */
mi[pos].tooltip((*ds)->get_comment());
} }
} }
@ -973,11 +976,11 @@ static unsigned int construct_edelib_menu(MenuContextList &lst, MenuItem *mi, un
mi[pos].flags = 0; mi[pos].flags = 0;
mi[pos].shortcut_ = 0; mi[pos].shortcut_ = 0;
mi[pos].image(NULL);
mi[pos].labeltype_ = FL_NORMAL_LABEL; mi[pos].labeltype_ = FL_NORMAL_LABEL;
mi[pos].labelfont_ = FL_HELVETICA; mi[pos].labelfont_ = FL_HELVETICA;
mi[pos].labelsize_ = FL_NORMAL_SIZE; mi[pos].labelsize_ = FL_NORMAL_SIZE;
mi[pos].labelcolor_ = FL_BLACK; mi[pos].labelcolor_ = FL_BLACK;
MenuItem::init_extensions(&mi[pos]);
/* set callback and callback data to be current entry */ /* set callback and callback data to be current entry */
mi[pos].callback_ = logout_cb; mi[pos].callback_ = logout_cb;
@ -993,7 +996,7 @@ static unsigned int construct_edelib_menu(MenuContextList &lst, MenuItem *mi, un
/* end this menu */ /* end this menu */
mi[pos].text = NULL; mi[pos].text = NULL;
mi[pos].image(NULL); MenuItem::init_extensions(&mi[pos]);
//E_DEBUG("{0}\n"); //E_DEBUG("{0}\n");
@ -1026,7 +1029,7 @@ MenuItem *xdg_menu_load(void) {
* MenuItem does not have constructor, so everywhere where we access MenuItem object, image * MenuItem does not have constructor, so everywhere where we access MenuItem object, image
* member must be NULL-ed too * member must be NULL-ed too
*/ */
mi[pos].image(NULL); MenuItem::init_extensions(&mi[pos]);
E_ASSERT(pos <= sz + 2); E_ASSERT(pos <= sz + 2);
return mi; return mi;