mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Importing systray applet. Not completed yet...
This commit is contained in:
parent
8f84854d4c
commit
706ef69bfa
@ -414,9 +414,11 @@ void Panel::load_applets(void) {
|
||||
"keyboard_layout.so",
|
||||
"cpu_monitor.so",
|
||||
"mem_monitor.so",
|
||||
"system_tray.so",
|
||||
0
|
||||
};
|
||||
|
||||
#if 0
|
||||
String dir = Resource::find_data("panel-applets");
|
||||
if(dir.empty())
|
||||
return;
|
||||
@ -428,7 +430,7 @@ void Panel::load_applets(void) {
|
||||
}
|
||||
|
||||
mgr.fill_group(this);
|
||||
#if 0
|
||||
#endif
|
||||
mgr.load("./applets/start-menu/start_menu.so");
|
||||
mgr.load("./applets/quick-launch/quick_launch.so");
|
||||
mgr.load("./applets/pager/pager.so");
|
||||
@ -437,6 +439,6 @@ void Panel::load_applets(void) {
|
||||
mgr.load("./applets/keyboard-layout/keyboard_layout.so");
|
||||
mgr.load("./applets/cpu-monitor/cpu_monitor.so");
|
||||
mgr.load("./applets/mem-monitor/mem_monitor.so");
|
||||
mgr.load("./applets/system-tray/system_tray.so");
|
||||
mgr.fill_group(this);
|
||||
#endif
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
#include <edelib/Window.h>
|
||||
#include "AppletManager.h"
|
||||
|
||||
#define EDE_PANEL_CAST_TO_PANEL(obj) ((Panel*)(obj))
|
||||
#define EDE_PANEL_GET_PANEL_OBJECT (EDE_PANEL_CAST_TO_PANEL(parent()))
|
||||
#define EDE_PANEL_CAST_TO_PANEL(obj) ((Panel*)(obj))
|
||||
#define EDE_PANEL_GET_PANEL_OBJECT(w) (EDE_PANEL_CAST_TO_PANEL(w->parent()))
|
||||
|
||||
EDELIB_NS_USING_AS(Window, PanelWindow)
|
||||
|
||||
@ -38,6 +38,8 @@ public:
|
||||
|
||||
int panel_w(void) { return w(); }
|
||||
int panel_h(void) { return h(); }
|
||||
|
||||
void relayout(void) { do_layout(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -18,4 +18,5 @@ SubInclude TOP ede-panel applets keyboard-layout ;
|
||||
SubInclude TOP ede-panel applets pager ;
|
||||
SubInclude TOP ede-panel applets quick-launch ;
|
||||
SubInclude TOP ede-panel applets start-menu ;
|
||||
SubInclude TOP ede-panel applets system-tray ;
|
||||
SubInclude TOP ede-panel applets taskbar ;
|
||||
|
13
ede-panel/applets/system-tray/Jamfile
Normal file
13
ede-panel/applets/system-tray/Jamfile
Normal file
@ -0,0 +1,13 @@
|
||||
#
|
||||
# $Id: Jamfile 2922 2009-11-05 15:18:51Z karijes $
|
||||
#
|
||||
# Part of Equinox Desktop Environment (EDE).
|
||||
# Copyright (c) 2011 EDE Authors.
|
||||
#
|
||||
# This program is licensed under terms of the
|
||||
# GNU General Public License version 2 or newer.
|
||||
# See COPYING for details.
|
||||
|
||||
SubDir TOP ede-panel applets system-tray ;
|
||||
|
||||
PanelApplet system_tray : Tray.cpp TrayWindow.cpp ;
|
184
ede-panel/applets/system-tray/Tray.cpp
Normal file
184
ede-panel/applets/system-tray/Tray.cpp
Normal file
@ -0,0 +1,184 @@
|
||||
#include <stdio.h>
|
||||
#define FL_LIBRARY 1
|
||||
#include <FL/Fl.H>
|
||||
#include <edelib/Debug.h>
|
||||
#include <edelib/Netwm.h>
|
||||
|
||||
#include "Applet.h"
|
||||
#include "Panel.h"
|
||||
#include "Tray.h"
|
||||
#include "TrayWindow.h"
|
||||
|
||||
#define SYSTEM_TRAY_REQUEST_DOCK 0
|
||||
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
|
||||
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
|
||||
|
||||
EDELIB_NS_USING(netwm_window_get_icon)
|
||||
EDELIB_NS_USING(netwm_window_get_title)
|
||||
|
||||
/* multiple tray's are not allowed anyways so this can work */
|
||||
Tray *curr_tray = 0;
|
||||
|
||||
static int handle_xevent(int e) {
|
||||
if(fl_xevent->type == ClientMessage && fl_xevent->xclient.message_type == curr_tray->get_opcode()) {
|
||||
if(fl_xevent->xclient.data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
|
||||
E_DEBUG(E_STRLOC ": Dock request for %i\n", fl_xevent->xclient.data.l[2]);
|
||||
curr_tray->embed_window(fl_xevent->xclient.data.l[2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(fl_xevent->xclient.data.l[1] == SYSTEM_TRAY_BEGIN_MESSAGE) {
|
||||
E_DEBUG(E_STRLOC ": SYSTEM_TRAY_BEGIN_MESSAGE\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(fl_xevent->xclient.data.l[1] == SYSTEM_TRAY_CANCEL_MESSAGE) {
|
||||
E_DEBUG(E_STRLOC ": SYSTEM_TRAY_CANCEL_MESSAGE\n");
|
||||
return true;
|
||||
}
|
||||
} else if(fl_xevent->type == DestroyNotify) {
|
||||
XDestroyWindowEvent xev = fl_xevent->xdestroywindow;
|
||||
curr_tray->unembed_window(xev.window);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Tray::Tray() : Fl_Group(0, 0, 5, 25), opcode(0) {
|
||||
box(FL_FLAT_BOX);
|
||||
color(FL_RED);
|
||||
register_notification_area();
|
||||
}
|
||||
|
||||
Tray::~Tray() {
|
||||
Atom sel;
|
||||
char sel_name[20];
|
||||
|
||||
snprintf(sel_name, sizeof(sel_name), "_NET_SYSTEM_TRAY_S%d", fl_screen);
|
||||
sel = XInternAtom(fl_display, sel_name, False);
|
||||
XSetSelectionOwner(fl_display, sel, None, CurrentTime);
|
||||
}
|
||||
|
||||
void Tray::register_notification_area(void) {
|
||||
Atom sel;
|
||||
char sel_name[20];
|
||||
|
||||
snprintf(sel_name, sizeof(sel_name), "_NET_SYSTEM_TRAY_S%d", fl_screen);
|
||||
sel = XInternAtom(fl_display, sel_name, False);
|
||||
if(XGetSelectionOwner(fl_display, sel)) {
|
||||
E_WARNING(E_STRLOC ": Notification area service is already provided by different program\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* register */
|
||||
XSetSelectionOwner(fl_display, sel, fl_message_window, CurrentTime);
|
||||
if(XGetSelectionOwner(fl_display, sel) != fl_message_window) {
|
||||
E_WARNING(E_STRLOC ": Unable to register notification area service\n");
|
||||
return;
|
||||
}
|
||||
|
||||
XClientMessageEvent xev;
|
||||
xev.type = ClientMessage;
|
||||
xev.message_type = XInternAtom(fl_display, "MANAGER", False);
|
||||
xev.format = 32;
|
||||
xev.data.l[0] = CurrentTime;
|
||||
xev.data.l[1] = sel;
|
||||
xev.data.l[2] = fl_message_window;
|
||||
xev.data.l[3] = xev.data.l[4] = 0;
|
||||
|
||||
XSendEvent(fl_display, RootWindow(fl_display, fl_screen), False, StructureNotifyMask, (XEvent*)&xev);
|
||||
|
||||
opcode = XInternAtom(fl_display, "_NET_SYSTEM_TRAY_OPCODE", False);
|
||||
message_data = XInternAtom(fl_display, "_NET_SYSTEM_TRAY_MESSAGE_DATA", False);
|
||||
|
||||
curr_tray = this;
|
||||
Fl::add_handler(handle_xevent);
|
||||
}
|
||||
|
||||
static int get_parent(Window id, Window *parent) {
|
||||
Window root, *children = 0;
|
||||
unsigned int nchildren;
|
||||
int s = XQueryTree(fl_display, id, &root, parent, &children, &nchildren);
|
||||
if(s && children);
|
||||
XFree(children);
|
||||
return s;
|
||||
}
|
||||
|
||||
void Tray::embed_window(Window id) {
|
||||
TrayWindow *win = new TrayWindow(25, 25);
|
||||
win->end();
|
||||
win->set_image(netwm_window_get_icon(id));
|
||||
win->set_tooltip(netwm_window_get_title(id));
|
||||
|
||||
add_to_tray(win);
|
||||
win->show();
|
||||
|
||||
XReparentWindow(fl_display, id, fl_xid(win), 0, 0);
|
||||
/* remove any pixmap from reparented window, so 'TrayWindow' can display own content */
|
||||
XSetWindowBackgroundPixmap(fl_display, id, None);
|
||||
|
||||
/* need to know when child dies */
|
||||
XSelectInput(fl_display, fl_xid(win), SubstructureNotifyMask);
|
||||
|
||||
WinInfo i;
|
||||
i.id = id;
|
||||
i.win = win;
|
||||
/* and to list */
|
||||
win_list.push_back(i);
|
||||
}
|
||||
|
||||
void Tray::unembed_window(Window id) {
|
||||
WinListIt it = win_list.begin(), ite = win_list.end();
|
||||
|
||||
for(; it != ite; ++it) {
|
||||
if((*it).id == id) {
|
||||
remove_from_tray((*it).win);
|
||||
win_list.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tray::add_to_tray(Fl_Widget *win) {
|
||||
win->position(x(), y());
|
||||
|
||||
insert(*win, 0);
|
||||
int W = w() + win->w() + 5;
|
||||
w(W);
|
||||
|
||||
EDE_PANEL_GET_PANEL_OBJECT(this)->relayout();
|
||||
}
|
||||
|
||||
void Tray::remove_from_tray(Fl_Widget *win) {
|
||||
remove(win);
|
||||
|
||||
int W = w() - win->w() - 5;
|
||||
w(W);
|
||||
|
||||
EDE_PANEL_GET_PANEL_OBJECT(this)->relayout();
|
||||
}
|
||||
|
||||
int Tray::handle(int e) {
|
||||
WinListIt it = win_list.begin(), ite = win_list.end();
|
||||
|
||||
for(; it != ite; ++it) {
|
||||
Fl_Window *n = (*it).win;
|
||||
if(Fl::event_x() >= n->x() && Fl::event_y() <= (n->x() + n->w()) &&
|
||||
Fl::event_y() >= n->y() && Fl::event_y() <= (n->y() + n->h()))
|
||||
{
|
||||
return n->handle(e);
|
||||
}
|
||||
}
|
||||
|
||||
return Fl_Group::handle(e);
|
||||
}
|
||||
|
||||
EDE_PANEL_APPLET_EXPORT (
|
||||
Tray,
|
||||
EDE_PANEL_APPLET_OPTION_ALIGN_RIGHT,
|
||||
"System Tray",
|
||||
"0.1",
|
||||
"empty",
|
||||
"Sanel Zukan, Vedran Ljubovic"
|
||||
)
|
36
ede-panel/applets/system-tray/Tray.h
Normal file
36
ede-panel/applets/system-tray/Tray.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef __TRAY_H__
|
||||
#define __TRAY_H__
|
||||
|
||||
#include <FL/Fl_Group.H>
|
||||
#include <FL/x.H>
|
||||
#include <edelib/List.h>
|
||||
|
||||
EDELIB_NS_USING(list)
|
||||
|
||||
struct WinInfo {
|
||||
Window id;
|
||||
Fl_Window *win;
|
||||
};
|
||||
|
||||
typedef list<WinInfo> WinList;
|
||||
typedef list<WinInfo>::iterator WinListIt;
|
||||
|
||||
class Tray : public Fl_Group {
|
||||
private:
|
||||
Atom opcode, message_data;
|
||||
WinList win_list;
|
||||
public:
|
||||
Tray();
|
||||
~Tray();
|
||||
void register_notification_area(void);
|
||||
Atom get_opcode(void) const { return opcode; }
|
||||
void embed_window(Window id);
|
||||
void unembed_window(Window id);
|
||||
|
||||
void add_to_tray(Fl_Widget *w);
|
||||
void remove_from_tray(Fl_Widget *w);
|
||||
|
||||
int handle(int e);
|
||||
};
|
||||
|
||||
#endif
|
58
ede-panel/applets/system-tray/TrayWindow.cpp
Normal file
58
ede-panel/applets/system-tray/TrayWindow.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include <FL/fl_draw.H>
|
||||
#include <edelib/Debug.h>
|
||||
#include "TrayWindow.h"
|
||||
|
||||
/* scale image by keeping aspect ratio */
|
||||
static Fl_RGB_Image *aspect_scale(Fl_RGB_Image *orig, int W, int H) {
|
||||
float aspect, neww, newh;
|
||||
|
||||
neww = (float)orig->w();
|
||||
newh = (float)orig->h();
|
||||
|
||||
if(neww > W) {
|
||||
aspect = (float)W / (float)neww;
|
||||
neww *= aspect;
|
||||
newh *= aspect;
|
||||
}
|
||||
|
||||
if(newh > H) {
|
||||
aspect = (float)H / (float)newh;
|
||||
neww *= aspect;
|
||||
newh *= aspect;
|
||||
}
|
||||
|
||||
return (Fl_RGB_Image*)orig->copy((int)neww, (int)newh);
|
||||
}
|
||||
|
||||
TrayWindow::TrayWindow(int W, int H) : Fl_Window(W, H), img(0) {
|
||||
box(FL_FLAT_BOX);
|
||||
}
|
||||
|
||||
void TrayWindow::set_image(Fl_RGB_Image *im) {
|
||||
E_RETURN_IF_FAIL(im != 0);
|
||||
|
||||
/* delete previous one */
|
||||
delete img;
|
||||
|
||||
/* do not use full w/h, but leave some room for few pixels around image */
|
||||
img = aspect_scale(im, w() - 2, h() - 2);
|
||||
}
|
||||
|
||||
void TrayWindow::draw(void) {
|
||||
Fl_Window::draw();
|
||||
if(img) {
|
||||
int X = w()/2 - img->w()/2;
|
||||
int Y = h()/2 - img->h()/2;
|
||||
img->draw(X, Y);
|
||||
}
|
||||
}
|
||||
|
||||
void TrayWindow::set_tooltip(char *t) {
|
||||
if(!t) {
|
||||
ttip.clear();
|
||||
tooltip(0);
|
||||
} else {
|
||||
ttip = t;
|
||||
tooltip(ttip.c_str());
|
||||
}
|
||||
}
|
22
ede-panel/applets/system-tray/TrayWindow.h
Normal file
22
ede-panel/applets/system-tray/TrayWindow.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef __TRAYWINDOW_H__
|
||||
#define __TRAYWINDOW_H__
|
||||
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <FL/Fl_Image.H>
|
||||
#include <edelib/String.h>
|
||||
|
||||
EDELIB_NS_USING(String)
|
||||
|
||||
/* window dedicated to displaying tray window with icon resized to window size */
|
||||
class TrayWindow : public Fl_Window {
|
||||
private:
|
||||
Fl_RGB_Image *img;
|
||||
String ttip;
|
||||
public:
|
||||
TrayWindow(int W, int H);
|
||||
void set_image(Fl_RGB_Image *im);
|
||||
void draw(void);
|
||||
void set_tooltip(char *t);
|
||||
};
|
||||
|
||||
#endif
|
@ -70,7 +70,7 @@ 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) {
|
||||
end();
|
||||
|
||||
panel = EDE_PANEL_GET_PANEL_OBJECT;
|
||||
panel = EDE_PANEL_GET_PANEL_OBJECT(this);
|
||||
|
||||
/* assure display is openned */
|
||||
fl_open_display();
|
||||
|
Loading…
Reference in New Issue
Block a user