mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Use wm specific code from edelib.
This commit is contained in:
@ -10,13 +10,7 @@
|
|||||||
|
|
||||||
SubDir TOP ede-panel ;
|
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 ;
|
EdeProgram ede-panel : Panel.cpp AppletManager.cpp ede-panel.cpp ;
|
||||||
LinkAgainst ede-panel : $(NETWMLIB) ;
|
|
||||||
|
|
||||||
if $(OS) != "SOLARIS" {
|
if $(OS) != "SOLARIS" {
|
||||||
# also must use this flag (on anything but Solaris) or program will crash
|
# also must use this flag (on anything but Solaris) or program will crash
|
||||||
@ -40,7 +34,7 @@ rule PanelApplet
|
|||||||
Main $(target) : $(>) ;
|
Main $(target) : $(>) ;
|
||||||
ObjectC++Flags $(>) : $(GLOBALFLAGS) -fPIC $(FLTKINCLUDE) -I [ FDirName $(TOP) ede-panel ] $(EDELIBINCLUDE) ;
|
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) ] ;
|
LINKFLAGS on $(target) = $(linker_stuff) [ on $(target) return $(LINKFLAGS) ] ;
|
||||||
|
|
||||||
InstallProgram $(EDE_PANEL_APPLETS_DIR) : $(target) ;
|
InstallProgram $(EDE_PANEL_APPLETS_DIR) : $(target) ;
|
||||||
|
@ -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 */
|
|
||||||
}
|
|
@ -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
|
|
@ -9,9 +9,9 @@
|
|||||||
#include <edelib/WindowXid.h>
|
#include <edelib/WindowXid.h>
|
||||||
#include <edelib/Resource.h>
|
#include <edelib/Resource.h>
|
||||||
#include <edelib/Util.h>
|
#include <edelib/Util.h>
|
||||||
|
#include <edelib/Netwm.h>
|
||||||
|
|
||||||
#include "Panel.h"
|
#include "Panel.h"
|
||||||
#include "Netwm.h"
|
|
||||||
|
|
||||||
/* empty space from left and right panel border */
|
/* empty space from left and right panel border */
|
||||||
#define INITIAL_SPACING 5
|
#define INITIAL_SPACING 5
|
||||||
@ -32,10 +32,19 @@ EDELIB_NS_USING(Resource)
|
|||||||
EDELIB_NS_USING(String)
|
EDELIB_NS_USING(String)
|
||||||
EDELIB_NS_USING(window_xid_create)
|
EDELIB_NS_USING(window_xid_create)
|
||||||
EDELIB_NS_USING(build_filename)
|
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*> WidgetList;
|
||||||
typedef list<Fl_Widget*>::iterator WidgetListIt;
|
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) {
|
static int xerror_handler(Display *d, XErrorEvent *e) {
|
||||||
if(e->request_code == X_GetImage)
|
if(e->request_code == X_GetImage)
|
||||||
return 0;
|
return 0;
|
||||||
@ -63,9 +72,8 @@ static int xerror_handler(Display *d, XErrorEvent *e) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool intersects(Fl_Widget *o1, Fl_Widget *o2) {
|
static void make_me_dock(Fl_Window *win) {
|
||||||
return (MAX(o1->x(), o2->x()) <= MIN(o1->x() + o1->w(), o2->x() + o2->w()) &&
|
netwm_window_set_type(fl_xid(win), NETWM_WINDOW_TYPE_DOCK);
|
||||||
MAX(o1->y(), o2->y()) <= MIN(o1->y() + o1->h(), o2->y() + o2->h()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* horizontaly centers widget in the panel */
|
/* horizontaly centers widget in the panel */
|
||||||
@ -310,7 +318,7 @@ void Panel::show(void) {
|
|||||||
XSetErrorHandler((XErrorHandler) xerror_handler);
|
XSetErrorHandler((XErrorHandler) xerror_handler);
|
||||||
|
|
||||||
/* position it */
|
/* 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);
|
Fl::screen_xywh(X, Y, W, H);
|
||||||
|
|
||||||
screen_x = X;
|
screen_x = X;
|
||||||
@ -323,16 +331,16 @@ void Panel::show(void) {
|
|||||||
size(W, DEFAULT_PANEL_H);
|
size(W, DEFAULT_PANEL_H);
|
||||||
|
|
||||||
do_layout();
|
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 */
|
/* position it, this is done after XID was created */
|
||||||
if(vpos == PANEL_POSITION_BOTTOM) {
|
if(vpos == PANEL_POSITION_BOTTOM) {
|
||||||
position(screen_x, screen_h - h());
|
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 {
|
} 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(screen_x, screen_y);
|
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 */
|
/* snap it to the top or bottom, depending on pressed mouse location */
|
||||||
if(Fl::event_y_root() <= screen_h_half && y() > screen_h_half) {
|
if(Fl::event_y_root() <= screen_h_half && y() > screen_h_half) {
|
||||||
position(screen_x, screen_y);
|
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;
|
vpos = PANEL_POSITION_TOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Fl::event_y_root() > screen_h_half && y() < screen_h_half) {
|
if(Fl::event_y_root() > screen_h_half && y() < screen_h_half) {
|
||||||
position(screen_x, screen_h - h());
|
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;
|
vpos = PANEL_POSITION_BOTTOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,23 @@
|
|||||||
#include "Applet.h"
|
#include "Applet.h"
|
||||||
#include "Netwm.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <FL/Fl_Group.H>
|
#include <FL/Fl_Group.H>
|
||||||
#include <FL/Fl.H>
|
#include <FL/Fl.H>
|
||||||
#include <edelib/Debug.h>
|
#include <edelib/Debug.h>
|
||||||
|
#include <edelib/Netwm.h>
|
||||||
|
|
||||||
#include "PagerButton.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 {
|
class Pager : public Fl_Group {
|
||||||
public:
|
public:
|
||||||
Pager();
|
Pager();
|
||||||
@ -22,7 +31,7 @@ static void box_cb(Fl_Widget*, void *b) {
|
|||||||
|
|
||||||
/* because workspaces in button labels are increased */
|
/* because workspaces in button labels are increased */
|
||||||
int s = pb->get_workspace_label() - 1;
|
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) {
|
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;
|
int nworkspaces, curr_workspace;
|
||||||
char **names = 0;
|
char **names = 0;
|
||||||
|
|
||||||
nworkspaces = netwm_get_workspace_count();
|
nworkspaces = netwm_workspace_get_count();
|
||||||
curr_workspace = netwm_get_current_workspace();
|
curr_workspace = netwm_workspace_get_current();
|
||||||
netwm_get_workspace_names(names);
|
netwm_workspace_get_names(names);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Resize group before childs, or they will be resized too, messing things up.
|
* 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;
|
X = bx->x() + bx->w() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFreeStringList(names);
|
netwm_workspace_free_names(names);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pager::workspace_changed(void) {
|
void Pager::workspace_changed(void) {
|
||||||
int c = netwm_get_current_workspace();
|
int c = netwm_workspace_get_current();
|
||||||
PagerButton *pb;
|
PagerButton *pb;
|
||||||
|
|
||||||
E_RETURN_IF_FAIL(c < children());
|
E_RETURN_IF_FAIL(c < children());
|
||||||
|
@ -7,15 +7,23 @@
|
|||||||
#include <edelib/Nls.h>
|
#include <edelib/Nls.h>
|
||||||
#include <edelib/MenuItem.h>
|
#include <edelib/MenuItem.h>
|
||||||
#include <edelib/IconLoader.h>
|
#include <edelib/IconLoader.h>
|
||||||
|
#include <edelib/Netwm.h>
|
||||||
|
|
||||||
#include "TaskButton.h"
|
#include "TaskButton.h"
|
||||||
#include "Taskbar.h"
|
#include "Taskbar.h"
|
||||||
#include "Netwm.h"
|
|
||||||
#include "icons/window.xpm"
|
#include "icons/window.xpm"
|
||||||
|
|
||||||
EDELIB_NS_USING(MenuItem)
|
EDELIB_NS_USING(MenuItem)
|
||||||
EDELIB_NS_USING(IconLoader)
|
EDELIB_NS_USING(IconLoader)
|
||||||
EDELIB_NS_USING(ICON_SIZE_TINY)
|
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);
|
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) {
|
static void close_cb(Fl_Widget*, void *b) {
|
||||||
TaskButton *bb = (TaskButton*)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 */
|
/* no need to redraw whole panel since taskbar elements are recreated again */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void restore_cb(Fl_Widget*, void *b) {
|
static void restore_cb(Fl_Widget*, void *b) {
|
||||||
TaskButton *bb = (TaskButton*)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);
|
redraw_whole_panel(bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void minimize_cb(Fl_Widget*, void *b) {
|
static void minimize_cb(Fl_Widget*, void *b) {
|
||||||
TaskButton *bb = (TaskButton*)b;
|
TaskButton *bb = (TaskButton*)b;
|
||||||
|
|
||||||
if(wm_get_window_state(bb->get_window_xid()) != WM_STATE_ICONIC)
|
if(wm_window_get_state(bb->get_window_xid()) != WM_WINDOW_STATE_ICONIC)
|
||||||
wm_set_window_state(bb->get_window_xid(), WM_STATE_ICONIC);
|
wm_window_set_state(bb->get_window_xid(), WM_WINDOW_STATE_ICONIC);
|
||||||
|
|
||||||
redraw_whole_panel(bb);
|
redraw_whole_panel(bb);
|
||||||
}
|
}
|
||||||
@ -64,8 +72,8 @@ static void minimize_cb(Fl_Widget*, void *b) {
|
|||||||
static void maximize_cb(Fl_Widget*, void *b) {
|
static void maximize_cb(Fl_Widget*, void *b) {
|
||||||
TaskButton *bb = (TaskButton*)b;
|
TaskButton *bb = (TaskButton*)b;
|
||||||
|
|
||||||
netwm_set_active_window(bb->get_window_xid());
|
netwm_window_set_active(bb->get_window_xid());
|
||||||
netwm_maximize_window(bb->get_window_xid());
|
netwm_window_maximize(bb->get_window_xid());
|
||||||
|
|
||||||
redraw_whole_panel(bb);
|
redraw_whole_panel(bb);
|
||||||
}
|
}
|
||||||
@ -143,7 +151,7 @@ void TaskButton::display_menu(void) {
|
|||||||
void TaskButton::update_title_from_xid(void) {
|
void TaskButton::update_title_from_xid(void) {
|
||||||
E_RETURN_IF_FAIL(xid >= 0);
|
E_RETURN_IF_FAIL(xid >= 0);
|
||||||
|
|
||||||
char *title = netwm_get_window_title(xid);
|
char *title = netwm_window_get_title(xid);
|
||||||
if(!title) {
|
if(!title) {
|
||||||
label("...");
|
label("...");
|
||||||
tooltip("...");
|
tooltip("...");
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
#include <FL/Fl.H>
|
#include <FL/Fl.H>
|
||||||
#include <FL/Fl_Button.H>
|
#include <FL/Fl_Button.H>
|
||||||
#include <edelib/Debug.h>
|
#include <edelib/Debug.h>
|
||||||
|
#include <edelib/Netwm.h>
|
||||||
|
|
||||||
#include "Netwm.h"
|
|
||||||
#include "TaskButton.h"
|
#include "TaskButton.h"
|
||||||
#include "Taskbar.h"
|
#include "Taskbar.h"
|
||||||
#include "Panel.h"
|
#include "Panel.h"
|
||||||
@ -12,6 +12,22 @@
|
|||||||
#define DEFAULT_CHILD_W 175
|
#define DEFAULT_CHILD_W 175
|
||||||
#define DEFAULT_SPACING 5
|
#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) {
|
static void button_cb(TaskButton *b, void *t) {
|
||||||
Taskbar *tt = (Taskbar*)t;
|
Taskbar *tt = (Taskbar*)t;
|
||||||
|
|
||||||
@ -36,7 +52,7 @@ static void net_event_cb(int action, Window xid, void *data) {
|
|||||||
return;
|
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) {
|
if(action == NETWM_CHANGED_ACTIVE_WINDOW) {
|
||||||
Taskbar *tt = (Taskbar*)data;
|
Taskbar *tt = (Taskbar*)data;
|
||||||
tt->update_active_button();
|
tt->update_active_button();
|
||||||
@ -72,20 +88,20 @@ void Taskbar::create_task_buttons(void) {
|
|||||||
panel_redraw();
|
panel_redraw();
|
||||||
|
|
||||||
Window *wins;
|
Window *wins;
|
||||||
int nwins = netwm_get_mapped_windows(&wins);
|
int nwins = netwm_window_get_all_mapped(&wins);
|
||||||
|
|
||||||
if(nwins > 0) {
|
if(nwins > 0) {
|
||||||
TaskButton *b;
|
TaskButton *b;
|
||||||
int curr_workspace = netwm_get_current_workspace();
|
int curr_workspace = netwm_workspace_get_current();
|
||||||
|
|
||||||
for(int i = 0; i < nwins; i++) {
|
for(int i = 0; i < nwins; i++) {
|
||||||
if(!netwm_manageable_window(wins[i]))
|
if(!netwm_window_is_manageable(wins[i]))
|
||||||
continue;
|
continue;
|
||||||
/*
|
/*
|
||||||
* show window per workspace
|
* show window per workspace
|
||||||
* TODO: allow showing all windows in each 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 = new TaskButton(0, 0, DEFAULT_CHILD_W, 25);
|
||||||
b->set_window_xid(wins[i]);
|
b->set_window_xid(wins[i]);
|
||||||
b->update_title_from_xid();
|
b->update_title_from_xid();
|
||||||
@ -149,7 +165,7 @@ void Taskbar::update_active_button(int xid) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if(xid == -1) {
|
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 */
|
/* 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 clicked on activated button, it will be minimized, then next one will be activated */
|
||||||
if(b == curr_active) {
|
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 */
|
/* minimize if not so */
|
||||||
wm_set_window_state(xid, WM_STATE_ICONIC);
|
wm_window_set_state(xid, WM_WINDOW_STATE_ICONIC);
|
||||||
|
|
||||||
if(prev_active &&
|
if(prev_active &&
|
||||||
prev_active != b &&
|
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();
|
xid = prev_active->get_window_xid();
|
||||||
b = prev_active;
|
b = prev_active;
|
||||||
@ -190,7 +206,7 @@ void Taskbar::activate_window(TaskButton *b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* active or restore minimized */
|
/* active or restore minimized */
|
||||||
netwm_set_active_window(xid);
|
netwm_window_set_active(xid);
|
||||||
update_active_button(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) */
|
/* TODO: use stack for this (case when this can't handle: minimize three window, out of four on the workspace) */
|
||||||
|
Reference in New Issue
Block a user