Fixing issue with workspace change and window listing. Adding facility for reading configuration from applets: implemting options for configuring fixed layout in taskbar tabs and showing buttons from all desktops.

This commit is contained in:
Sanel Zukan 2014-11-28 01:47:31 +00:00
parent 002bd6b2e7
commit f0c50eeebf
7 changed files with 154 additions and 71 deletions

View File

@ -21,6 +21,9 @@
#ifndef __APPLET_H__
#define __APPLET_H__
#include <edelib/Resource.h>
EDELIB_NS_USING_AS(Resource, PanelResource)
class Fl_Widget;
/* stored version in each applet shared library in case interface get changed */
@ -40,15 +43,6 @@ enum {
EDE_PANEL_APPLET_OPTION_ALIGN_RIGHT = (1 << 4)
};
struct AppletInfo {
const char *name;
const char *klass_name;
const char *version;
const char *icon;
const char *author;
unsigned long options;
};
/*
* each applet want to inherit this class if would like to exchange data with panel
* NOTE: new things could be added in future, but that will be reflected through EDE_PANEL_APPLET_INTERFACE_VERSION
@ -59,6 +53,23 @@ public:
AppletWidget(int X, int Y, int W, int H, const char *l = 0) : T(X, Y, W, H, l) {
T::type(EDE_PANEL_APPLET_TYPE);
}
virtual ~AppletWidget() { }
/*
* Override this method to access panel configuration. Note that 'PanelResource' object
* will be destroyed after applets are loaded, so do not hold reference to this address.
*/
virtual void configure(PanelResource *conf) { }
};
struct AppletInfo {
const char *name;
const char *klass_name;
const char *version;
const char *icon;
const char *author;
unsigned long options;
};
/* module stuff */

View File

@ -141,7 +141,7 @@ void AppletManager::clear(Panel *p) {
* Must be called so widget can actually be added to FLTK parent. Widgets will be created and
* added to the group.
*/
void AppletManager::fill_group(Panel *p) {
void AppletManager::fill_group(Panel *p, PanelResource *res) {
AListIter it = applet_list.begin(), ite = applet_list.end();
AppletData *applet;
@ -150,6 +150,15 @@ void AppletManager::fill_group(Panel *p) {
/* allocate memory for widget and append it to the group */
applet->awidget = applet->create_func();
/* call configuration function if needed */
if(res && applet->awidget->type() == EDE_PANEL_APPLET_TYPE) {
/* a hackery to make compiler happy */
typedef AppletWidget<Fl_Widget> AW;
AW *tmp = (AW*)(applet->awidget);
tmp->configure(res);
}
p->add(applet->awidget);
}
}

View File

@ -29,8 +29,8 @@ class Panel;
class Fl_Widget;
struct AppletData;
typedef edelib::list<AppletData*> AList;
typedef edelib::list<AppletData*>::iterator AListIter;
typedef EDELIB_NS_PREPEND(list<AppletData*>) AList;
typedef EDELIB_NS_PREPEND(list<AppletData*>::iterator) AListIter;
class AppletManager {
private:
@ -38,7 +38,7 @@ private:
public:
bool load(const char *path);
void clear(Panel *p);
void fill_group(Panel *p);
void fill_group(Panel *p, PanelResource *res);
void unfill_group(Panel *p);
bool get_applet_options(Fl_Widget *o, unsigned long &opts);

View File

@ -30,7 +30,6 @@
#include <edelib/Debug.h>
#include <edelib/List.h>
#include <edelib/WindowXid.h>
#include <edelib/Resource.h>
#include <edelib/Util.h>
#include <edelib/Netwm.h>
#include <edelib/Directory.h>
@ -233,7 +232,7 @@ Panel::Panel() : PanelWindow(300, 30, "ede-panel") {
screen_x = screen_y = screen_w = screen_h = screen_h_half = 0;
width_perc = 100;
can_move_widgets = false;
can_drag = true;
can_drag = false;
box(FL_UP_BOX);
read_config();
@ -273,9 +272,9 @@ void Panel::read_config(void) {
char buf[128];
if(r.get("Panel", "applets", buf, sizeof(buf)))
load_applets(buf);
load_applets(buf, &r);
else
load_applets();
load_applets(0, &r);
}
void Panel::save_config(void) {
@ -482,14 +481,63 @@ void Panel::update_size_and_pos(bool create_xid, bool update_strut, int X, int Y
}
}
#define PANEL_DRAG_KEY (Fl::event_state() == FL_ALT)
int Panel::handle(int e) {
#if 0
can_drag = PANEL_DRAG_KEY;
switch(e) {
case FL_PUSH:
if(can_drag) {
return 1;
}
/* fallthrough */
case FL_DRAG:
if(can_drag) {
cursor(FL_CURSOR_MOVE);
/* snap it to the top or bottom, depending on pressed mouse location */
if(Fl::event_y_root() <= screen_h_half && y() > screen_h_half) {
position(x(), screen_y);
if(width_perc >= 100)
set_strut(PANEL_STRUT_TOP);
vpos = PANEL_POSITION_TOP;
}
if(Fl::event_y_root() > screen_h_half && y() < screen_h_half) {
position(x(), screen_h - h());
if(width_perc >= 100)
set_strut(PANEL_STRUT_BOTTOM);
vpos = PANEL_POSITION_BOTTOM;
}
return 1;
}
/* fallthrough */
case FL_RELEASE:
if(can_drag) {
return 1;
}
/* fallthrough */
case FL_KEYBOARD:
/* do not quit on Esc key */
if(Fl::event_key() == FL_Escape)
return 1;
/* fallthrough */
}
#endif
return Fl_Window::handle(e);
#if 0
switch(e) {
case FL_PUSH:
clicked = Fl::belowmouse();
if(clicked == this)
clicked = 0;
else if(clicked && clicked->takesevents())
else if(clicked && Fl::event_inside(clicked) && clicked->takesevents())
clicked->handle(e);
/* record push position for possible child drag */
@ -498,33 +546,32 @@ int Panel::handle(int e) {
return 1;
case FL_DRAG: {
if(!can_drag) return 1;
/* are moving the panel; only vertical moving is supported */
cursor(FL_CURSOR_MOVE);
/* send drag events to children and do not drag panel in the mean time */
if(clicked && clicked != this) {
clicked->handle(e);
return 0;
}
if(clicked && clicked != this && Fl::event_inside(clicked) && clicked->takesevents()) {
cursor(FL_CURSOR_MOVE);
return clicked->handle(e);
} else {
printf("XXXy %p %p\n", clicked, this);
if(!can_drag) return 1;
cursor(FL_CURSOR_MOVE);
/* snap it to the top or bottom, depending on pressed mouse location */
if(Fl::event_y_root() <= screen_h_half && y() > screen_h_half) {
position(x(), screen_y);
if(width_perc >= 100)
set_strut(PANEL_STRUT_TOP);
vpos = PANEL_POSITION_TOP;
}
if(Fl::event_y_root() > screen_h_half && y() < screen_h_half) {
position(x(), screen_h - h());
if(width_perc >= 100)
set_strut(PANEL_STRUT_BOTTOM);
vpos = PANEL_POSITION_BOTTOM;
}
/* snap it to the top or bottom, depending on pressed mouse location */
if(Fl::event_y_root() <= screen_h_half && y() > screen_h_half) {
position(x(), screen_y);
if(width_perc >= 100)
set_strut(PANEL_STRUT_TOP);
vpos = PANEL_POSITION_TOP;
}
return 1;
if(Fl::event_y_root() > screen_h_half && y() < screen_h_half) {
position(x(), screen_h - h());
if(width_perc >= 100)
set_strut(PANEL_STRUT_BOTTOM);
vpos = PANEL_POSITION_BOTTOM;
}
return 1;
}
}
case FL_RELEASE:
@ -543,11 +590,11 @@ int Panel::handle(int e) {
return 1;
/* fallthrough */
}
return Fl_Window::handle(e);
#endif
}
void Panel::load_applets(const char *applets) {
void Panel::load_applets(const char *applets, PanelResource *res) {
mgr.clear(this);
/*
@ -604,7 +651,7 @@ void Panel::load_applets(const char *applets) {
}
free(dup);
mgr.fill_group(this);
mgr.fill_group(this, res);
}
/* TODO: can be better */

View File

@ -68,7 +68,7 @@ public:
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);
void load_applets(const char *applets = 0);
void load_applets(const char *applets, PanelResource *res = 0);
int panel_w(void) { return w(); }
int panel_h(void) { return h(); }

View File

@ -1,7 +1,7 @@
/*
* $Id$
*
* Copyright (C) 2012-2013 Sanel Zukan
* Copyright (C) 2012-2014 Sanel Zukan
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -100,12 +100,8 @@ 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) {
Taskbar::Taskbar() : WidgetGroup(0, 0, 40, 25), curr_active(NULL), prev_active(NULL) {
end();
//box(FL_FLAT_BOX);
//color(FL_RED);
fixed_layout = false;
ignore_workspace_value = false;
@ -119,6 +115,15 @@ Taskbar::~Taskbar() {
netwm_callback_remove(net_event_cb);
}
void Taskbar::configure(Resource *res) {
E_RETURN_IF_FAIL(res != NULL);
res->get("Taskbar", "fixed_layout", fixed_layout, false);
res->get("Taskbar", "all_desktops", ignore_workspace_value, false);
if(visible()) update_task_buttons();
}
void Taskbar::update_task_buttons(void) {
Window *wins;
int ws, nwins = netwm_window_get_all_mapped(&wins);
@ -127,10 +132,10 @@ void Taskbar::update_task_buttons(void) {
if(children() > 0) clear();
return;
}
TaskButton *b;
bool need_full_redraw = false;
for(int i = 0, found; i < children(); i++) {
found = 0;
b = (TaskButton*)child(i);
@ -187,19 +192,25 @@ void Taskbar::update_task_buttons(void) {
/* create button */
ws = netwm_window_get_workspace(wins[i]);
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);
/* mark it hidden by default */
b->hide();
/* catch the name changes */
XSelectInput(fl_display, wins[i], PropertyChangeMask | StructureNotifyMask);
b->callback((Fl_Callback*)button_cb, this);
/* add it to our list */
add(b);
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);
b->callback((Fl_Callback*)button_cb, this);
add(b);
need_full_redraw = true;
//need_full_redraw = true;
b->show();
}
}
@ -211,9 +222,9 @@ void Taskbar::update_task_buttons(void) {
}
void Taskbar::update_workspace_change(void) {
if(children() < 1) return;
if(!children()) return;
current_workspace = netwm_workspace_get_current();
TaskButton *b;
for(int i = 0; i < children(); i++) {
b = (TaskButton*)child(i);

View File

@ -22,28 +22,33 @@
#define __TASKBAR_H__
#include <FL/Fl_Group.H>
#include <edelib/Resource.h>
#include "Applet.h"
EDELIB_NS_USING(Resource)
/* if button should be on visible on all workspaces */
#define ALL_WORKSPACES -1
class TaskButton;
typedef AppletWidget<Fl_Group> WidgetGroup;
class Taskbar : public Fl_Group {
class Taskbar : public WidgetGroup {
public:
TaskButton *curr_active, *prev_active;
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);
return (ignore_workspace_value == true) || (ws == ALL_WORKSPACES) || (ws == current_workspace);
}
public:
Taskbar();
~Taskbar();
void configure(Resource *res);
void update_task_buttons(void);
void update_workspace_change(void);