diff --git a/ede-desktop/Utils.cpp b/ede-desktop/Utils.cpp index 55e12b5..bc94b63 100644 --- a/ede-desktop/Utils.cpp +++ b/ede-desktop/Utils.cpp @@ -10,21 +10,12 @@ * See COPYING for details. */ -#include // strrchr, strncpy, strlen -#include // CARD32 +#include #include #include #include "Utils.h" -Atom _XA_NET_WORKAREA = 0; -Atom _XA_NET_WM_WINDOW_TYPE = 0; -Atom _XA_NET_WM_WINDOW_TYPE_DESKTOP = 0; -Atom _XA_NET_NUMBER_OF_DESKTOPS = 0; -Atom _XA_NET_CURRENT_DESKTOP = 0; -Atom _XA_NET_DESKTOP_NAMES = 0; -Atom _XA_XROOTPMAP_ID = 0; - static int overlay_x = 0; static int overlay_y = 0; static int overlay_w = 0; @@ -34,156 +25,6 @@ static Fl_Window* overlay_drawable = NULL; static char dash_list[] = {1}; -void init_atoms(void) { - _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_DESKTOP = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE_DESKTOP", 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_XROOTPMAP_ID = XInternAtom(fl_display, "_XROOTPMAP_ID", False); -} - -bool net_get_workarea(int& x, int& y, int& w, int &h) { - 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 net_make_me_desktop(Fl_Window* w) { - /* - * xid() will return zero if window is not shown; - * make sure it is shown - */ - EASSERT(fl_xid(w)); - - /* - * Reminder for me (others possible): - * note '&_XA_NET_WM_WINDOW_TYPE_DESKTOP' conversion, since gcc will not report warning/error - * if placed '_XA_NET_WM_WINDOW_TYPE_DESKTOP' only. - * - * I lost two hours messing with this ! (gdb is unusefull in X world) - */ - XChangeProperty(fl_display, fl_xid(w), _XA_NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, - (unsigned char*)&_XA_NET_WM_WINDOW_TYPE_DESKTOP, sizeof(Atom)); -} - -int net_get_workspace_count(void) { - 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; -} - -// desktops are starting from 0 -int net_get_current_desktop(void) { - 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; -} - -// call on this XFreeStringList(names) -int net_get_workspace_names(char**& names) { - // 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; -} - -#if 0 -int net_get_workspace_names(char** names) { - Atom nd = XInternAtom(fl_display, "_NET_DESKTOP_NAMES", False); - Atom utf8_str = XInternAtom(fl_display, "UTF8_STRING", False); - Atom real; - int format; - unsigned long n, extra; - unsigned char* prop; - - int status = XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen), - nd, 0L, 0x7fffffff, False, utf8_str, &real, &format, &n, &extra, (unsigned char**)&prop); - - if(status != Success && !prop) - return 0; - - int alloc = 0; - if(real == utf8_str && format == 8) { - const char* p = (const char*)prop; - for(int i = 0, s = 0; i < n && alloc < MAX_DESKTOPS; i++, alloc++) { - if(p[i] == '\0') { - E_DEBUG("%c ", p[i]); - names[alloc] = strndup((p + s), i - s + 1); - s = i + 1; - } - } - } - - return alloc; -} -#endif - void draw_overlay_rect(void) { if(overlay_w <= 0 || overlay_h <= 0) return; @@ -203,7 +44,7 @@ void draw_overlay_rect(void) { XSetFunction(fl_display, fl_gc, GXcopy); - // set line to 0 again + /* set line to 0 again */ XSetLineAttributes(fl_display, fl_gc, 0, LineOnOffDash, CapButt, JoinMiter); } @@ -249,7 +90,7 @@ Pixmap create_mask(Fl_Image* img) { if(!img) return 0; - // no alpha + /* no alpha */ if(img->d() != 4) return 0; @@ -269,16 +110,16 @@ Pixmap create_mask(Fl_Image* img) { for(int y = 0; y < ih; y++) { for(int x = 0; x < iw; x++) { - // jump rgb and pick alpha + /* jump rgb and pick alpha */ src += 3; a = *src++; if(a < 128) { - // these are transparent + /* these are transparent */ XPutPixel(xim, x, y, 0); } else { - // these are opaque + /* these are opaque */ XPutPixel(xim, x, y, 1); } } diff --git a/ede-desktop/Utils.h b/ede-desktop/Utils.h index 3f8b6f2..03692b0 100644 --- a/ede-desktop/Utils.h +++ b/ede-desktop/Utils.h @@ -13,27 +13,10 @@ #ifndef __UTILS_H__ #define __UTILS_H__ -#include // Pixmap - +#include #include #include -extern Atom _XA_NET_WORKAREA; -extern Atom _XA_NET_WM_WINDOW_TYPE; -extern Atom _XA_NET_WM_WINDOW_TYPE_DESKTOP; -extern Atom _XA_NET_NUMBER_OF_DESKTOPS; -extern Atom _XA_NET_CURRENT_DESKTOP; -extern Atom _XA_NET_DESKTOP_NAMES; -extern Atom _XA_XROOTPMAP_ID; - -void init_atoms(void); - -int net_get_workspace_count(void); -int net_get_current_desktop(void); -bool net_get_workarea(int& x, int& y, int& w, int &h); -void net_make_me_desktop(Fl_Window* w); -int net_get_workspace_names(char**& names); - void draw_xoverlay(int x, int y, int w, int h); void clear_xoverlay(void); void set_xoverlay_drawable(Fl_Window* win); diff --git a/ede-desktop/Wallpaper.cpp b/ede-desktop/Wallpaper.cpp index 5b732a7..da0f197 100644 --- a/ede-desktop/Wallpaper.cpp +++ b/ede-desktop/Wallpaper.cpp @@ -360,6 +360,8 @@ void Wallpaper::set_rootpmap(void) { return; XImage* rootpmap_image = 0; + Atom _XA_XROOTPMAP_ID; + rootpmap_pixmap = create_xpixmap(image(), &rootpmap_image, rootpmap_pixmap, w(), h()); if(!rootpmap_pixmap) @@ -369,6 +371,8 @@ void Wallpaper::set_rootpmap(void) { if(rootpmap_image) XDestroyImage(rootpmap_image); + _XA_XROOTPMAP_ID = XInternAtom(fl_display, "_XROOTPMAP_ID", False); + XChangeProperty(fl_display, RootWindow(fl_display, fl_screen), _XA_XROOTPMAP_ID, XA_PIXMAP, 32, PropModeReplace, (unsigned char *)&rootpmap_pixmap, 1); } diff --git a/ede-desktop/ede-desktop.cpp b/ede-desktop/ede-desktop.cpp index b25c251..4dce11d 100644 --- a/ede-desktop/ede-desktop.cpp +++ b/ede-desktop/ede-desktop.cpp @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include "ede-desktop.h" #include "DesktopIcon.h" @@ -59,12 +61,24 @@ #undef MAX #define MAX(x,y) ((x) > (y) ? (x) : (y)) -/* - * Which widgets Fl::belowmouse() should skip. This should be updated - * when new non-icon child is added to Desktop window. +/* + * Which widgets Fl::belowmouse() should skip. + * This should be updated when new non-icon child is added to Desktop window */ #define NOT_SELECTABLE(widget) ((widget == this) || (widget == wallpaper) || (widget == dmenu)) +EDELIB_NS_USING(window_xid_create) +EDELIB_NS_USING(netwm_workspace_get_names) +EDELIB_NS_USING(netwm_workspace_free_names) +EDELIB_NS_USING(netwm_workspace_get_current) +EDELIB_NS_USING(netwm_workarea_get_size) +EDELIB_NS_USING(netwm_window_set_type) +EDELIB_NS_USING(netwm_callback_add) +EDELIB_NS_USING(netwm_callback_remove) +EDELIB_NS_USING(NETWM_WINDOW_TYPE_DESKTOP) +EDELIB_NS_USING(NETWM_CHANGED_CURRENT_WORKAREA) +EDELIB_NS_USING(NETWM_CHANGED_CURRENT_WORKSPACE) + static void background_conf_cb(Fl_Widget*, void*); static void icons_conf_cb(Fl_Widget*, void*); @@ -99,8 +113,8 @@ static void exit_signal(int signum) { running = false; } -static void restart_signal(int signum) { - E_DEBUG(E_STRLOC ": Restarting (got signal %d)\n", signum); +static void make_me_desktop(Fl_Window *win) { + netwm_window_set_type(fl_xid(win), NETWM_WINDOW_TYPE_DESKTOP); } static void dir_watch_cb(const char* dir, const char* changed, int flags, void* data) { @@ -120,20 +134,15 @@ static void icons_conf_cb(Fl_Widget*, void*) { edelib::run_async("ede-launch ede-desktop-conf --icons"); } -static int desktop_xmessage_handler(int event) { - if(fl_xevent->type == PropertyNotify) { - if(fl_xevent->xproperty.atom == _XA_NET_CURRENT_DESKTOP) { +static void desktop_message_handler(int action, Window xid, void *data) { + switch(action) { + case NETWM_CHANGED_CURRENT_WORKSPACE: Desktop::instance()->notify_desktop_changed(); - return 1; - } - - if(fl_xevent->xproperty.atom == _XA_NET_WORKAREA) { + break; + case NETWM_CHANGED_CURRENT_WORKAREA: Desktop::instance()->update_workarea(); - return 1; - } + break; } - - return 0; } Desktop::Desktop() : DESKTOP_WINDOW(0, 0, 100, 100, "") { @@ -181,7 +190,6 @@ Desktop::~Desktop() { void Desktop::init_internals(void) { edelib::String p; - init_atoms(); update_workarea(); /* @@ -265,15 +273,11 @@ Desktop* Desktop::instance(void) { return Desktop::pinstance; } -/* - * This function must be overriden so window can inform wm to see it as desktop. It will send data when window - * is created, but before is shown. - */ void Desktop::show(void) { - if(!shown()) { - Fl_X::make_xid(this); - net_make_me_desktop(this); - } + if(shown()) + return DESKTOP_WINDOW::show(); + + window_xid_create(this, make_me_desktop); } /* If someone intentionaly hide desktop then quit from it */ @@ -283,10 +287,11 @@ void Desktop::hide(void) { void Desktop::update_workarea(void) { int X, Y, W, H; - if(!net_get_workarea(X, Y, W, H)) { - E_DEBUG(E_STRLOC ": wm does not support _NET_WM_WORKAREA; using screen sizes...\n"); - X = Y = 0; + if(!netwm_workarea_get_size(X, Y, W, H)) { + E_DEBUG(E_STRLOC ": wm does not support _NET_WM_WORKAREA; using screen sizes...\n"); + + X = Y = 0; W = DisplayWidth(fl_display, fl_screen); H = DisplayHeight(fl_display, fl_screen); } @@ -754,17 +759,17 @@ void Desktop::select_in_area(void) { } void Desktop::notify_desktop_changed(void) { - int num = net_get_current_desktop(); + int num = netwm_workspace_get_current(); if(num == -1) return; char** names; - int ret = net_get_workspace_names(names); + int ret = netwm_workspace_get_names(names); if(!ret) return; if(num >= ret) { - XFreeStringList(names); + netwm_workspace_free_names(names); return; } @@ -1135,7 +1140,6 @@ int main() { signal(SIGTERM, exit_signal); signal(SIGKILL, exit_signal); signal(SIGINT, exit_signal); - signal(SIGHUP, restart_signal); srand(time(NULL)); @@ -1153,7 +1157,7 @@ int main() { /* XSelectInput will redirect PropertyNotify messages, which are listened for */ XSelectInput(fl_display, RootWindow(fl_display, fl_screen), PropertyChangeMask | StructureNotifyMask | ClientMessage); - Fl::add_handler(desktop_xmessage_handler); + netwm_callback_add(desktop_message_handler); while(running) Fl::wait();