mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
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:
parent
002bd6b2e7
commit
f0c50eeebf
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,16 +546,14 @@ 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) {
|
||||
@ -526,6 +572,7 @@ int Panel::handle(int e) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
case FL_RELEASE:
|
||||
cursor(FL_CURSOR_DEFAULT);
|
||||
@ -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 */
|
||||
|
@ -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(); }
|
||||
|
@ -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);
|
||||
@ -187,19 +192,25 @@ void Taskbar::update_task_buttons(void) {
|
||||
|
||||
/* create button */
|
||||
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);
|
||||
/* 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);
|
||||
|
||||
need_full_redraw = true;
|
||||
if(visible_on_current_workspace(ws)) {
|
||||
//need_full_redraw = true;
|
||||
b->show();
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,7 +222,7 @@ 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;
|
||||
|
@ -22,29 +22,34 @@
|
||||
#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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user