Use wm specific code from edelib.

This commit is contained in:
Sanel Zukan 2009-12-17 15:16:35 +00:00
parent 31fbe5bc06
commit bbbb00fdca
7 changed files with 79 additions and 697 deletions

View File

@ -10,13 +10,7 @@
SubDir TOP ede-panel ;
# make it as library, so applets can use it too
ObjectC++Flags Netwm.cpp : $(GLOBALFLAGS) -fPIC $(FLTKINCLUDE) $(EDELIBINCLUDE) ;
StaticLibrary libnetwm : Netwm.cpp ;
NETWMLIB = -L$(SUBDIR) -lnetwm ;
EdeProgram ede-panel : Panel.cpp AppletManager.cpp ede-panel.cpp ;
LinkAgainst ede-panel : $(NETWMLIB) ;
if $(OS) != "SOLARIS" {
# also must use this flag (on anything but Solaris) or program will crash
@ -40,7 +34,7 @@ rule PanelApplet
Main $(target) : $(>) ;
ObjectC++Flags $(>) : $(GLOBALFLAGS) -fPIC $(FLTKINCLUDE) -I [ FDirName $(TOP) ede-panel ] $(EDELIBINCLUDE) ;
LinkAgainst $(target) : $(NETWMLIB) $(3) $(EDELIBLIB) $(EDELIB_GUI_LIB) $(FLTKLIB) $(STDLIB) ;
LinkAgainst $(target) : $(3) $(EDELIBLIB) $(EDELIB_GUI_LIB) $(FLTKLIB) $(STDLIB) ;
LINKFLAGS on $(target) = $(linker_stuff) [ on $(target) return $(LINKFLAGS) ] ;
InstallProgram $(EDE_PANEL_APPLETS_DIR) : $(target) ;

View File

@ -1,564 +0,0 @@
#include <string.h>
#include <X11/Xproto.h>
#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/Fl_Window.H>
#include <edelib/Debug.h>
#include <edelib/List.h>
#include "Netwm.h"
EDELIB_NS_USING(list)
struct NetwmCallbackData {
NetwmCallback cb;
void *data;
};
typedef list<NetwmCallbackData> CbList;
typedef list<NetwmCallbackData>::iterator CbListIt;
static CbList callback_list;
static bool input_selected = false;
static Atom _XA_NET_WORKAREA;
static Atom _XA_NET_WM_WINDOW_TYPE;
static Atom _XA_NET_WM_WINDOW_TYPE_DOCK;
static Atom _XA_NET_WM_WINDOW_TYPE_DESKTOP;
static Atom _XA_NET_WM_WINDOW_TYPE_SPLASH;
static Atom _XA_NET_WM_STRUT;
static Atom _XA_NET_NUMBER_OF_DESKTOPS;
static Atom _XA_NET_CURRENT_DESKTOP;
static Atom _XA_NET_DESKTOP_NAMES;
static Atom _XA_NET_CLIENT_LIST;
static Atom _XA_NET_WM_DESKTOP;
static Atom _XA_NET_WM_NAME;
static Atom _XA_NET_WM_VISIBLE_NAME;
static Atom _XA_NET_ACTIVE_WINDOW;
static Atom _XA_NET_CLOSE_WINDOW;
static Atom _XA_WM_STATE;
static Atom _XA_NET_WM_STATE;
static Atom _XA_NET_WM_STATE_MAXIMIZED_HORZ;
static Atom _XA_NET_WM_STATE_MAXIMIZED_VERT;
static Atom _XA_EDE_WM_ACTION;
static Atom _XA_EDE_WM_RESTORE_SIZE;
/* this macro is set in xlib when X-es provides UTF-8 extension (since XFree86 4.0.2) */
#if X_HAVE_UTF8_STRING
static Atom _XA_UTF8_STRING;
#else
# define _XA_UTF8_STRING XA_STRING
#endif
static short atoms_inited = 0;
static void init_atoms_once(void) {
if(atoms_inited)
return;
_XA_NET_WORKAREA = XInternAtom(fl_display, "_NET_WORKAREA", False);
_XA_NET_WM_WINDOW_TYPE = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE", False);
_XA_NET_WM_WINDOW_TYPE_DOCK = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE_DOCK", False);
_XA_NET_WM_WINDOW_TYPE_SPLASH = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE_SPLASH", False);
_XA_NET_WM_WINDOW_TYPE_DESKTOP = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
_XA_NET_WM_STRUT = XInternAtom(fl_display, "_NET_WM_STRUT", False);
_XA_NET_NUMBER_OF_DESKTOPS = XInternAtom(fl_display, "_NET_NUMBER_OF_DESKTOPS", False);
_XA_NET_CURRENT_DESKTOP = XInternAtom(fl_display, "_NET_CURRENT_DESKTOP", False);
_XA_NET_DESKTOP_NAMES = XInternAtom(fl_display, "_NET_DESKTOP_NAMES", False);
_XA_NET_CLIENT_LIST = XInternAtom(fl_display, "_NET_CLIENT_LIST", False);
_XA_NET_WM_DESKTOP = XInternAtom(fl_display, "_NET_WM_DESKTOP", False);
_XA_NET_WM_NAME = XInternAtom(fl_display, "_NET_WM_NAME", False);
_XA_NET_WM_VISIBLE_NAME = XInternAtom(fl_display, "_NET_WM_VISIBLE_NAME", False);
_XA_NET_ACTIVE_WINDOW = XInternAtom(fl_display, "_NET_ACTIVE_WINDOW", False);
_XA_NET_CLOSE_WINDOW = XInternAtom(fl_display, "_NET_CLOSE_WINDOW", False);
_XA_WM_STATE = XInternAtom(fl_display, "WM_STATE", False);
_XA_NET_WM_STATE = XInternAtom(fl_display, "_NET_WM_STATE", False);
_XA_NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(fl_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
_XA_NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(fl_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
_XA_EDE_WM_ACTION = XInternAtom(fl_display, "_EDE_WM_ACTION", False);
_XA_EDE_WM_RESTORE_SIZE = XInternAtom(fl_display, "_EDE_WM_RESTORE_SIZE", False);
#ifdef X_HAVE_UTF8_STRING
_XA_UTF8_STRING = XInternAtom(fl_display, "UTF8_STRING", False);
#endif
atoms_inited = 1;
}
static int xevent_handler(int e) {
if(fl_xevent->type == PropertyNotify) {
int action = -1;
/* E_DEBUG("==> %s\n", XGetAtomName(fl_display, fl_xevent->xproperty.atom)); */
if(fl_xevent->xproperty.atom == _XA_NET_NUMBER_OF_DESKTOPS)
action = NETWM_CHANGED_WORKSPACE_COUNT;
else if(fl_xevent->xproperty.atom == _XA_NET_DESKTOP_NAMES)
action = NETWM_CHANGED_WORKSPACE_NAMES;
else if(fl_xevent->xproperty.atom == _XA_NET_CURRENT_DESKTOP)
action = NETWM_CHANGED_CURRENT_WORKSPACE;
else if(fl_xevent->xproperty.atom == _XA_NET_WORKAREA)
action = NETWM_CHANGED_CURRENT_WORKAREA;
else if(fl_xevent->xproperty.atom == _XA_NET_ACTIVE_WINDOW)
action = NETWM_CHANGED_ACTIVE_WINDOW;
else if(fl_xevent->xproperty.atom == _XA_NET_WM_NAME || fl_xevent->xproperty.atom == XA_WM_NAME)
action = NETWM_CHANGED_WINDOW_NAME;
else if(fl_xevent->xproperty.atom == _XA_NET_WM_VISIBLE_NAME)
action = NETWM_CHANGED_WINDOW_VISIBLE_NAME;
else if(fl_xevent->xproperty.atom == _XA_NET_WM_DESKTOP)
action = NETWM_CHANGED_WINDOW_DESKTOP;
else if(fl_xevent->xproperty.atom == _XA_NET_CLIENT_LIST)
action = NETWM_CHANGED_WINDOW_LIST;
else
action = -1;
if(action >= 0 && !callback_list.empty()) {
Window xid = fl_xevent->xproperty.window;
/* TODO: locking here */
CbListIt it = callback_list.begin(), it_end = callback_list.end();
for(; it != it_end; ++it) {
/* execute callback */
(*it).cb(action, xid, (*it).data);
}
}
}
return 0;
}
void netwm_callback_add(NetwmCallback cb, void *data) {
E_RETURN_IF_FAIL(cb != NULL);
fl_open_display();
init_atoms_once();
/* to catch _XA_NET_CURRENT_DESKTOP and such events */
if(!input_selected) {
XSelectInput(fl_display, RootWindow(fl_display, fl_screen), PropertyChangeMask | StructureNotifyMask);
input_selected = true;
}
NetwmCallbackData cb_data;
cb_data.cb = cb;
cb_data.data = data;
callback_list.push_back(cb_data);
Fl::remove_handler(xevent_handler);
Fl::add_handler(xevent_handler);
}
void netwm_callback_remove(NetwmCallback cb) {
if(callback_list.empty())
return;
CbListIt it = callback_list.begin(), it_end = callback_list.end();
while(it != it_end) {
if(cb == (*it).cb) {
it = callback_list.erase(it);
} else {
/* continue, in case the same callback is put multiple times */
++it;
}
}
}
bool netwm_get_workarea(int& x, int& y, int& w, int &h) {
init_atoms_once();
Atom real;
int format;
unsigned long n, extra;
unsigned char* prop;
x = y = w = h = 0;
int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
_XA_NET_WORKAREA, 0L, 0x7fffffff, False, XA_CARDINAL, &real, &format, &n, &extra, (unsigned char**)&prop);
if(status != Success)
return false;
CARD32* val = (CARD32*)prop;
if(val) {
x = val[0];
y = val[1];
w = val[2];
h = val[3];
XFree((char*)val);
return true;
}
return false;
}
void netwm_make_me_dock(Fl_Window *win) {
init_atoms_once();
XChangeProperty(fl_display, fl_xid(win), _XA_NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace,
(unsigned char*)&_XA_NET_WM_WINDOW_TYPE_DOCK, sizeof(Atom));
}
void netwm_set_window_strut(Fl_Window *win, int left, int right, int top, int bottom) {
init_atoms_once();
CARD32 strut[4] = { left, right, top, bottom };
XChangeProperty(fl_display, fl_xid(win), _XA_NET_WM_STRUT, XA_CARDINAL, 32,
PropModeReplace, (unsigned char*)&strut, sizeof(CARD32) * 4);
}
int netwm_get_workspace_count(void) {
init_atoms_once();
Atom real;
int format;
unsigned long n, extra;
unsigned char* prop;
int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
_XA_NET_NUMBER_OF_DESKTOPS, 0L, 0x7fffffff, False, XA_CARDINAL, &real, &format, &n, &extra,
(unsigned char**)&prop);
if(status != Success || !prop)
return -1;
int ns = int(*(long*)prop);
XFree(prop);
return ns;
}
/* change current workspace */
void netwm_change_workspace(int n) {
init_atoms_once();
XEvent xev;
Window root_win = RootWindow(fl_display, fl_screen);
memset(&xev, 0, sizeof(xev));
xev.xclient.type = ClientMessage;
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.window = root_win;
xev.xclient.display = fl_display;
xev.xclient.message_type = _XA_NET_CURRENT_DESKTOP;
xev.xclient.format = 32;
xev.xclient.data.l[0] = (long)n;
xev.xclient.data.l[1] = CurrentTime;
XSendEvent (fl_display, root_win, False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
XSync(fl_display, True);
}
int netwm_get_current_workspace(void) {
init_atoms_once();
Atom real;
int format;
unsigned long n, extra;
unsigned char* prop;
int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
_XA_NET_CURRENT_DESKTOP, 0L, 0x7fffffff, False, XA_CARDINAL, &real, &format, &n, &extra,
(unsigned char**)&prop);
if(status != Success || !prop)
return -1;
int ns = int(*(long*)prop);
XFree(prop);
return ns;
}
int netwm_get_workspace_names(char**& names) {
init_atoms_once();
/* FIXME: add _NET_SUPPORTING_WM_CHECK and _NET_SUPPORTED ??? */
XTextProperty wnames;
XGetTextProperty(fl_display, RootWindow(fl_display, fl_screen), &wnames, _XA_NET_DESKTOP_NAMES);
/* if wm does not understainds _NET_DESKTOP_NAMES this is not set */
if(!wnames.nitems || !wnames.value)
return 0;
int nsz;
/*
* FIXME: Here should as alternative Xutf8TextPropertyToTextList since
* many wm's set UTF8_STRING property. Below is XA_STRING and for UTF8_STRING
* will fail.
*/
if(!XTextPropertyToStringList(&wnames, &names, &nsz)) {
XFree(wnames.value);
return 0;
}
XFree(wnames.value);
return nsz;
}
int netwm_get_mapped_windows(Window **windows) {
init_atoms_once();
Atom real;
int format;
unsigned long n, extra;
unsigned char* prop = 0;
int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
_XA_NET_CLIENT_LIST, 0L, 0x7fffffff, False, XA_WINDOW, &real, &format, &n, &extra,
(unsigned char**)&prop);
if(status != Success || !prop)
return -1;
*windows = (Window*)prop;
return n;
}
int netwm_get_window_workspace(Window win) {
E_RETURN_VAL_IF_FAIL(win >= 0, -1);
init_atoms_once();
Atom real;
int format;
unsigned long n, extra;
unsigned char* prop = 0;
int status = XGetWindowProperty(fl_display, win,
_XA_NET_WM_DESKTOP, 0L, 0x7fffffff, False, XA_CARDINAL, &real, &format, &n, &extra,
(unsigned char**)&prop);
if(status != Success || !prop)
return -1;
//int ns = int(*(long*)prop);
unsigned long desk = (unsigned long)(*(long*)prop);
XFree(prop);
/* sticky */
if(desk == 0xFFFFFFFF || desk == 0xFFFFFFFE)
return -1;
return desk;
}
int netwm_manageable_window(Window win) {
init_atoms_once();
Atom real;
int format;
unsigned long n, extra;
unsigned char* prop = 0;
int status = XGetWindowProperty(fl_display, win,
_XA_NET_WM_WINDOW_TYPE, 0L, sizeof(Atom), False, XA_ATOM, &real, &format, &n, &extra,
(unsigned char**)&prop);
if(status != Success || !prop)
return -1;
Atom type = *(Atom*)prop;
XFree(prop);
if(type == _XA_NET_WM_WINDOW_TYPE_DESKTOP ||
type == _XA_NET_WM_WINDOW_TYPE_SPLASH ||
type == _XA_NET_WM_WINDOW_TYPE_DOCK)
{
return 0;
}
return 1;
}
char *netwm_get_window_title(Window win) {
init_atoms_once();
XTextProperty xtp;
char *title = NULL, *ret = NULL;
Atom real;
int format;
unsigned long n, extra;
unsigned char* prop = 0;
int status = XGetWindowProperty(fl_display, win,
_XA_NET_WM_NAME, 0L, 0x7fffffff, False, _XA_UTF8_STRING , &real, &format, &n, &extra,
(unsigned char**)&prop);
if(status == Success && prop) {
title = (char *)prop;
ret = strdup(title);
XFree(prop);
} else {
/* try WM_NAME */
if(!XGetWMName(fl_display, win, &xtp))
return NULL;
if(xtp.encoding == XA_STRING) {
ret = strdup((const char*)xtp.value);
} else {
#if X_HAVE_UTF8_STRING
char **lst;
int lst_sz;
status = Xutf8TextPropertyToTextList(fl_display, &xtp, &lst, &lst_sz);
if(status == Success && lst_sz > 0) {
ret = strdup((const char*)*lst);
XFreeStringList(lst);
} else {
ret = strdup((const char*)xtp.value);
}
#else
ret = strdup((const char*)tp.value);
#endif
}
XFree(xtp.value);
}
return ret;
}
Window netwm_get_active_window(void) {
init_atoms_once();
Atom real;
int format;
unsigned long n, extra;
unsigned char* prop = 0;
int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
_XA_NET_ACTIVE_WINDOW, 0L, sizeof(Atom), False, XA_WINDOW, &real, &format, &n, &extra,
(unsigned char**)&prop);
if(status != Success || !prop)
return -1;
int ret = int(*(long*)prop);
XFree(prop);
return (Window)ret;
}
void netwm_set_active_window(Window win) {
init_atoms_once();
XEvent xev;
memset(&xev, 0, sizeof(xev));
xev.xclient.type = ClientMessage;
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.window = win;
xev.xclient.display = fl_display;
xev.xclient.message_type = _XA_NET_ACTIVE_WINDOW;
xev.xclient.format = 32;
xev.xclient.data.l[0] = (long)win;
xev.xclient.data.l[1] = CurrentTime;
XSendEvent (fl_display, RootWindow(fl_display, fl_screen), False,
SubstructureRedirectMask | SubstructureNotifyMask, &xev);
XSync(fl_display, True);
}
void netwm_maximize_window(Window win) {
init_atoms_once();
XEvent xev;
memset(&xev, 0, sizeof(xev));
xev.xclient.type = ClientMessage;
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.window = win;
xev.xclient.display = fl_display;
xev.xclient.message_type = _XA_NET_WM_STATE;
xev.xclient.format = 32;
xev.xclient.data.l[0] = 0;
xev.xclient.data.l[1] = _XA_NET_WM_STATE_MAXIMIZED_HORZ;
xev.xclient.data.l[2] = _XA_NET_WM_STATE_MAXIMIZED_VERT;
XSendEvent (fl_display, RootWindow(fl_display, fl_screen), False,
SubstructureRedirectMask | SubstructureNotifyMask, &xev);
XSync(fl_display, True);
}
void netwm_close_window(Window win) {
init_atoms_once();
XEvent xev;
memset(&xev, 0, sizeof(xev));
xev.xclient.type = ClientMessage;
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.window = win;
xev.xclient.display = fl_display;
xev.xclient.message_type = _XA_NET_CLOSE_WINDOW;
xev.xclient.format = 32;
xev.xclient.data.l[0] = (long)win;
xev.xclient.data.l[1] = CurrentTime;
XSendEvent (fl_display, RootWindow(fl_display, fl_screen), False,
SubstructureRedirectMask | SubstructureNotifyMask, &xev);
XSync(fl_display, True);
}
void wm_ede_restore_window(Window win) {
init_atoms_once();
XEvent xev;
memset(&xev, 0, sizeof(xev));
xev.xclient.type = ClientMessage;
xev.xclient.serial = 0;
xev.xclient.send_event = True;
xev.xclient.window = win;
xev.xclient.display = fl_display;
xev.xclient.message_type = _XA_EDE_WM_ACTION;
xev.xclient.format = 32;
xev.xclient.data.l[0] = _XA_EDE_WM_RESTORE_SIZE;
xev.xclient.data.l[1] = CurrentTime;
XSendEvent (fl_display, RootWindow(fl_display, fl_screen), False,
SubstructureRedirectMask | SubstructureNotifyMask, &xev);
XSync(fl_display, True);
}
WmStateValue wm_get_window_state(Window win) {
init_atoms_once();
Atom real;
int format;
unsigned long n, extra;
unsigned char* prop = 0;
int status = XGetWindowProperty(fl_display, win,
_XA_WM_STATE, 0L, sizeof(Atom), False, _XA_WM_STATE, &real, &format, &n, &extra,
(unsigned char**)&prop);
if(status != Success || !prop)
return WM_STATE_NONE;
WmStateValue ret = WmStateValue(*(long*)prop);
XFree(prop);
return ret;
}
void wm_set_window_state(Window win, WmStateValue state) {
E_RETURN_IF_FAIL((int)state > 0);
if(state == WM_STATE_WITHDRAW) {
XWithdrawWindow(fl_display, win, fl_screen);
XSync(fl_display, True);
} else if(state == WM_STATE_ICONIC) {
XIconifyWindow(fl_display, win, fl_screen);
XSync(fl_display, True);
}
/* nothing for WM_STATE_NORMAL */
}

View File

@ -1,89 +0,0 @@
#ifndef __NETWM_H__
#define __NETWM_H__
#include <X11/Xlib.h>
/* NETWM helpers for panel and applets */
class Fl_Window;
enum {
NETWM_CHANGED_WORKSPACE_COUNT,
NETWM_CHANGED_WORKSPACE_NAMES,
NETWM_CHANGED_CURRENT_WORKSPACE,
NETWM_CHANGED_CURRENT_WORKAREA,
NETWM_CHANGED_ACTIVE_WINDOW,
NETWM_CHANGED_WINDOW_NAME,
NETWM_CHANGED_WINDOW_VISIBLE_NAME,
NETWM_CHANGED_WINDOW_DESKTOP,
NETWM_CHANGED_WINDOW_LIST
};
enum WmStateValue {
WM_STATE_NONE = -1,
WM_STATE_WITHDRAW = 0,
WM_STATE_NORMAL = 1,
WM_STATE_ICONIC = 3
};
typedef void (*NetwmCallback)(int action, Window xid, void *data);
/* register callback for NETWM_* changes */
void netwm_callback_add(NetwmCallback cb, void *data = 0);
/* remove callback if exists */
void netwm_callback_remove(NetwmCallback cb);
/* get current workare set by window manager; return false if fails */
bool netwm_get_workarea(int& x, int& y, int& w, int &h);
/* make 'dock' type from given window */
void netwm_make_me_dock(Fl_Window *win);
/* resize area by setting offsets to each side; 'win' will be outside that area */
void netwm_set_window_strut(Fl_Window *win, int left, int right, int top, int bottom);
/* return number of workspaces */
int netwm_get_workspace_count(void);
/* change current workspace */
void netwm_change_workspace(int n);
/* current visible workspace; workspaces are starting from 0 */
int netwm_get_current_workspace(void);
/* workspace names; return number of allocated ones; call on this XFreeStringList(names) */
int netwm_get_workspace_names(char**& names);
/* get a list of mapped windows; returns number in the list, or -1 if fails; call XFree when done */
int netwm_get_mapped_windows(Window **windows);
/* returns -2 on error, -1 on sticky, else is desktop */
int netwm_get_window_workspace(Window win);
/* return 1 if given window is manageable (desktop/dock/splash types are not manageable) */
int netwm_manageable_window(Window win);
/* return window title or NULL if fails; call free() on returned string */
char *netwm_get_window_title(Window win);
/* return ID of currently focused window; if fails, return -1 */
Window netwm_get_active_window(void);
/* try to focus given window */
void netwm_set_active_window(Window win);
/* maximize window */
void netwm_maximize_window(Window win);
/* close window */
void netwm_close_window(Window win);
/* edewm specific: restore window to previous state */
void wm_ede_restore_window(Window win);
/* not part of NETWM, but helpers until _NET_WM_STATE_* is implemented */
WmStateValue wm_get_window_state(Window win);
void wm_set_window_state(Window win, WmStateValue state);
#endif

View File

@ -9,9 +9,9 @@
#include <edelib/WindowXid.h>
#include <edelib/Resource.h>
#include <edelib/Util.h>
#include <edelib/Netwm.h>
#include "Panel.h"
#include "Netwm.h"
/* empty space from left and right panel border */
#define INITIAL_SPACING 5
@ -32,10 +32,19 @@ EDELIB_NS_USING(Resource)
EDELIB_NS_USING(String)
EDELIB_NS_USING(window_xid_create)
EDELIB_NS_USING(build_filename)
EDELIB_NS_USING(netwm_window_set_strut)
EDELIB_NS_USING(netwm_window_set_type)
EDELIB_NS_USING(netwm_workarea_get_size)
EDELIB_NS_USING(NETWM_WINDOW_TYPE_DOCK)
typedef list<Fl_Widget*> WidgetList;
typedef list<Fl_Widget*>::iterator WidgetListIt;
inline bool intersects(Fl_Widget *o1, Fl_Widget *o2) {
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()));
}
static int xerror_handler(Display *d, XErrorEvent *e) {
if(e->request_code == X_GetImage)
return 0;
@ -63,9 +72,8 @@ static int xerror_handler(Display *d, XErrorEvent *e) {
return 0;
}
inline bool intersects(Fl_Widget *o1, Fl_Widget *o2) {
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()));
static void make_me_dock(Fl_Window *win) {
netwm_window_set_type(fl_xid(win), NETWM_WINDOW_TYPE_DOCK);
}
/* horizontaly centers widget in the panel */
@ -310,7 +318,7 @@ void Panel::show(void) {
XSetErrorHandler((XErrorHandler) xerror_handler);
/* position it */
if(!netwm_get_workarea(X, Y, W, H))
if(!netwm_workarea_get_size(X, Y, W, H))
Fl::screen_xywh(X, Y, W, H);
screen_x = X;
@ -323,16 +331,16 @@ void Panel::show(void) {
size(W, DEFAULT_PANEL_H);
do_layout();
window_xid_create(this, netwm_make_me_dock);
window_xid_create(this, make_me_dock);
/* position it, this is done after XID was created */
if(vpos == PANEL_POSITION_BOTTOM) {
position(screen_x, screen_h - h());
netwm_set_window_strut(this, 0, 0, 0, h());
netwm_window_set_strut(fl_xid(this), 0, 0, 0, h());
} else {
/* FIXME: this does not work well with edewm (nor pekwm). kwin do it correctly. */
position(screen_x, screen_y);
netwm_set_window_strut(this, 0, 0, h(), 0);
netwm_window_set_strut(fl_xid(this), 0, 0, h(), 0);
}
}
@ -362,13 +370,13 @@ int Panel::handle(int e) {
/* 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(screen_x, screen_y);
netwm_set_window_strut(this, 0, 0, h(), 0);
netwm_window_set_strut(fl_xid(this), 0, 0, h(), 0);
vpos = PANEL_POSITION_TOP;
}
if(Fl::event_y_root() > screen_h_half && y() < screen_h_half) {
position(screen_x, screen_h - h());
netwm_set_window_strut(this, 0, 0, 0, h());
netwm_window_set_strut(fl_xid(this), 0, 0, 0, h());
vpos = PANEL_POSITION_BOTTOM;
}

View File

@ -1,14 +1,23 @@
#include "Applet.h"
#include "Netwm.h"
#include <string.h>
#include <FL/Fl_Group.H>
#include <FL/Fl.H>
#include <edelib/Debug.h>
#include <edelib/Netwm.h>
#include "PagerButton.h"
EDELIB_NS_USING(netwm_workspace_change)
EDELIB_NS_USING(netwm_workspace_get_current)
EDELIB_NS_USING(netwm_workspace_get_count)
EDELIB_NS_USING(netwm_workspace_get_names)
EDELIB_NS_USING(netwm_workspace_free_names)
EDELIB_NS_USING(netwm_callback_add)
EDELIB_NS_USING(netwm_callback_remove)
EDELIB_NS_USING(NETWM_CHANGED_CURRENT_WORKSPACE)
class Pager : public Fl_Group {
public:
Pager();
@ -22,7 +31,7 @@ static void box_cb(Fl_Widget*, void *b) {
/* because workspaces in button labels are increased */
int s = pb->get_workspace_label() - 1;
netwm_change_workspace(s);
netwm_workspace_change(s);
}
static void net_event_cb(int action, Window xid, void *data) {
@ -58,9 +67,9 @@ void Pager::init_workspace_boxes(void) {
int nworkspaces, curr_workspace;
char **names = 0;
nworkspaces = netwm_get_workspace_count();
curr_workspace = netwm_get_current_workspace();
netwm_get_workspace_names(names);
nworkspaces = netwm_workspace_get_count();
curr_workspace = netwm_workspace_get_current();
netwm_workspace_get_names(names);
/*
* Resize group before childs, or they will be resized too, messing things up.
@ -96,11 +105,11 @@ void Pager::init_workspace_boxes(void) {
X = bx->x() + bx->w() + 1;
}
XFreeStringList(names);
netwm_workspace_free_names(names);
}
void Pager::workspace_changed(void) {
int c = netwm_get_current_workspace();
int c = netwm_workspace_get_current();
PagerButton *pb;
E_RETURN_IF_FAIL(c < children());

View File

@ -7,15 +7,23 @@
#include <edelib/Nls.h>
#include <edelib/MenuItem.h>
#include <edelib/IconLoader.h>
#include <edelib/Netwm.h>
#include "TaskButton.h"
#include "Taskbar.h"
#include "Netwm.h"
#include "icons/window.xpm"
EDELIB_NS_USING(MenuItem)
EDELIB_NS_USING(IconLoader)
EDELIB_NS_USING(ICON_SIZE_TINY)
EDELIB_NS_USING(netwm_window_close)
EDELIB_NS_USING(netwm_window_set_active)
EDELIB_NS_USING(netwm_window_maximize)
EDELIB_NS_USING(netwm_window_get_title)
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)
static Fl_Pixmap image_window(window_xpm);
@ -40,23 +48,23 @@ static void redraw_whole_panel(TaskButton *b) {
static void close_cb(Fl_Widget*, void *b) {
TaskButton *bb = (TaskButton*)b;
netwm_close_window(bb->get_window_xid());
netwm_window_close(bb->get_window_xid());
/* no need to redraw whole panel since taskbar elements are recreated again */
}
static void restore_cb(Fl_Widget*, void *b) {
TaskButton *bb = (TaskButton*)b;
wm_ede_restore_window(bb->get_window_xid());
wm_window_ede_restore(bb->get_window_xid());
netwm_set_active_window(bb->get_window_xid());
netwm_window_set_active(bb->get_window_xid());
redraw_whole_panel(bb);
}
static void minimize_cb(Fl_Widget*, void *b) {
TaskButton *bb = (TaskButton*)b;
if(wm_get_window_state(bb->get_window_xid()) != WM_STATE_ICONIC)
wm_set_window_state(bb->get_window_xid(), WM_STATE_ICONIC);
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);
redraw_whole_panel(bb);
}
@ -64,8 +72,8 @@ static void minimize_cb(Fl_Widget*, void *b) {
static void maximize_cb(Fl_Widget*, void *b) {
TaskButton *bb = (TaskButton*)b;
netwm_set_active_window(bb->get_window_xid());
netwm_maximize_window(bb->get_window_xid());
netwm_window_set_active(bb->get_window_xid());
netwm_window_maximize(bb->get_window_xid());
redraw_whole_panel(bb);
}
@ -143,7 +151,7 @@ void TaskButton::display_menu(void) {
void TaskButton::update_title_from_xid(void) {
E_RETURN_IF_FAIL(xid >= 0);
char *title = netwm_get_window_title(xid);
char *title = netwm_window_get_title(xid);
if(!title) {
label("...");
tooltip("...");

View File

@ -3,8 +3,8 @@
#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <edelib/Debug.h>
#include <edelib/Netwm.h>
#include "Netwm.h"
#include "TaskButton.h"
#include "Taskbar.h"
#include "Panel.h"
@ -12,6 +12,22 @@
#define DEFAULT_CHILD_W 175
#define DEFAULT_SPACING 5
EDELIB_NS_USING(netwm_callback_add)
EDELIB_NS_USING(netwm_callback_remove)
EDELIB_NS_USING(netwm_window_get_all_mapped)
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_workspace_get_current)
EDELIB_NS_USING(wm_window_set_state)
EDELIB_NS_USING(wm_window_get_state)
EDELIB_NS_USING(NETWM_CHANGED_ACTIVE_WINDOW)
EDELIB_NS_USING(NETWM_CHANGED_CURRENT_WORKSPACE)
EDELIB_NS_USING(NETWM_CHANGED_WINDOW_LIST)
EDELIB_NS_USING(NETWM_CHANGED_WINDOW_NAME)
EDELIB_NS_USING(WM_WINDOW_STATE_ICONIC)
static void button_cb(TaskButton *b, void *t) {
Taskbar *tt = (Taskbar*)t;
@ -36,7 +52,7 @@ static void net_event_cb(int action, Window xid, void *data) {
return;
}
/* this is a message, so property is not changed and netwm_get_active_window() must be called */
/* 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();
@ -72,20 +88,20 @@ void Taskbar::create_task_buttons(void) {
panel_redraw();
Window *wins;
int nwins = netwm_get_mapped_windows(&wins);
int nwins = netwm_window_get_all_mapped(&wins);
if(nwins > 0) {
TaskButton *b;
int curr_workspace = netwm_get_current_workspace();
int curr_workspace = netwm_workspace_get_current();
for(int i = 0; i < nwins; i++) {
if(!netwm_manageable_window(wins[i]))
if(!netwm_window_is_manageable(wins[i]))
continue;
/*
* show window per workspace
* TODO: allow showing all windows in each workspace
*/
if(curr_workspace == netwm_get_window_workspace(wins[i])) {
if(curr_workspace == 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();
@ -149,7 +165,7 @@ void Taskbar::update_active_button(int xid) {
return;
if(xid == -1) {
xid = netwm_get_active_window();
xid = netwm_window_get_active();
/* TODO: make sure panel does not get 'active', or all buttons will be FL_UP_BOX */
}
@ -173,13 +189,13 @@ void Taskbar::activate_window(TaskButton *b) {
/* if clicked on activated button, it will be minimized, then next one will be activated */
if(b == curr_active) {
if(wm_get_window_state(xid) != WM_STATE_ICONIC) {
if(wm_window_get_state(xid) != WM_WINDOW_STATE_ICONIC) {
/* minimize if not so */
wm_set_window_state(xid, WM_STATE_ICONIC);
wm_window_set_state(xid, WM_WINDOW_STATE_ICONIC);
if(prev_active &&
prev_active != b &&
wm_get_window_state(prev_active->get_window_xid()) != WM_STATE_ICONIC)
wm_window_get_state(prev_active->get_window_xid()) != WM_WINDOW_STATE_ICONIC)
{
xid = prev_active->get_window_xid();
b = prev_active;
@ -190,7 +206,7 @@ void Taskbar::activate_window(TaskButton *b) {
}
/* active or restore minimized */
netwm_set_active_window(xid);
netwm_window_set_active(xid);
update_active_button(xid);
/* TODO: use stack for this (case when this can't handle: minimize three window, out of four on the workspace) */