all repos — fluxbox @ 5fec1906cc4faf83ec2424aa48c2a050b0254d15

custom fork of the fluxbox windowmanager

cache the root pixmap (per screen)
simonb simonb
commit

5fec1906cc4faf83ec2424aa48c2a050b0254d15

parent

c6c7788405b8f6f5990e4ff9a69123d13b1487f4

4 files changed, 124 insertions(+), 34 deletions(-)

jump to
M ChangeLogChangeLog

@@ -1,6 +1,9 @@

(Format: Year/Month/Day) Changes for 0.9.13 *05/05/10: + * Cache root pixmap, watch for property changes (Simon) + (previously was checked EVERY time = lots) + FbTk/FbPixmap.hh/cc fluxbox.cc * minor tweak to configure.in (thanx php-coder) *05/05/09: * Fix for fbrun and completion (thanx Vadim)
M src/FbTk/FbPixmap.ccsrc/FbTk/FbPixmap.cc

@@ -24,6 +24,7 @@

#include "FbPixmap.hh" #include "App.hh" #include "GContext.hh" +#include "Transparent.hh" #include <X11/Xutil.h> #include <X11/Xatom.h>

@@ -33,6 +34,22 @@

using namespace std; namespace FbTk { + +Pixmap *FbPixmap::m_root_pixmaps = 0; + +const char* FbPixmap::root_prop_ids[] = { + "_XROOTPMAP_ID", + "_XSETROOT_ID", + 0 +}; + +// same number as in root_prop_ids +Atom FbPixmap::root_prop_atoms[] = { + None, + None, + None +}; + FbPixmap::FbPixmap():m_pm(0), m_width(0), m_height(0),

@@ -297,53 +314,107 @@ m_depth = 0;

return ret; } +void FbPixmap::rootwinPropertyNotify(int screen_num, Atom atom) { + if (!FbTk::Transparent::haveRender()) + return; + + checkAtoms(); + for (int i=0; root_prop_ids[i] != 0; ++i) { + if (root_prop_atoms[i] == atom) { + Pixmap root_pm = None; + Atom real_type; + int real_format; + unsigned long items_read, items_left; + unsigned long *data; + + unsigned int prop = 0; + if (XGetWindowProperty(display(), + RootWindow(display(), i), + root_prop_atoms[i], + 0l, 1l, + False, XA_PIXMAP, + &real_type, &real_format, + &items_read, &items_left, + (unsigned char **) &data) == Success) { + if (real_format == 32 && items_read == 1) { + root_pm = (Pixmap) (*data); + } + XFree(data); + if (root_pm != None) + setRootPixmap(screen_num, root_pm); + } + break; + } + } +} + +void FbPixmap::setRootPixmap(int screen_num, Pixmap pm) { + if (!m_root_pixmaps) { + m_root_pixmaps = new Pixmap[ScreenCount(display())]; + } + + m_root_pixmaps[screen_num] = pm; +} + Pixmap FbPixmap::getRootPixmap(int screen_num) { + if (!FbTk::Transparent::haveRender()) + return None; - Atom real_type; - int real_format; - unsigned long items_read, items_left; - unsigned long *data; + if (!m_root_pixmaps) { + int numscreens = ScreenCount(display()); + for (int i=0; i < numscreens; ++i) { + Atom real_type; + int real_format; + unsigned long items_read, items_left; + unsigned long *data; - unsigned int prop = 0; - static const char* prop_ids[] = { - "_XROOTPMAP_ID", - "_XSETROOT_ID", - 0 - }; - static bool print_error = true; // print error_message only once - static const char* error_message = { "\n\n !!! WARNING WARNING WARNING WARNING !!!!!\n" + unsigned int prop = 0; + + static bool print_error = true; // print error_message only once + static const char* error_message = { "\n\n !!! WARNING WARNING WARNING WARNING !!!!!\n" " if you experience problems with transparency:\n" " you are using a wallpapersetter that \n" " uses _XSETROOT_ID .. which we do not support.\n" " consult 'fbsetbg -i' or try any other wallpapersetter\n" " that uses _XROOTPMAP_ID !\n" " !!! WARNING WARNING WARNING WARNING !!!!!!\n\n" - }; + }; - Pixmap root_pm = None; - for (prop = 0; prop_ids[prop]; prop++) { - if (XGetWindowProperty(display(), - RootWindow(display(), screen_num), - XInternAtom(display(), prop_ids[prop], False), - 0l, 1l, - False, XA_PIXMAP, - &real_type, &real_format, - &items_read, &items_left, - (unsigned char **) &data) == Success) { - if (real_format == 32 && items_read == 1) { - if (print_error && strcmp(prop_ids[prop], "_XSETROOT_ID") == 0) { - cerr<<error_message; - print_error = false; - } else - root_pm = (Pixmap) (*data); + Pixmap root_pm = None; + for (prop = 0; root_prop_ids[prop]; prop++) { + checkAtoms(); + if (XGetWindowProperty(display(), + RootWindow(display(), i), + root_prop_atoms[i], + 0l, 1l, + False, XA_PIXMAP, + &real_type, &real_format, + &items_read, &items_left, + (unsigned char **) &data) == Success) { + if (real_format == 32 && items_read == 1) { + if (print_error && strcmp(root_prop_ids[prop], "_XSETROOT_ID") == 0) { + cerr<<error_message; + print_error = false; + } else + root_pm = (Pixmap) (*data); + } + XFree(data); + if (root_pm != None) + break; + } } - XFree(data); - if (root_pm != None) - break; + setRootPixmap(i, root_pm); } } + return m_root_pixmaps[screen_num]; +} - return root_pm; +void FbPixmap::checkAtoms() { + for (int i=0; root_prop_ids[i] != 0; ++i) { + if (root_prop_atoms[i] == None) { + root_prop_atoms[i] = XInternAtom(display(), root_prop_ids[i], False); + } + } } void FbPixmap::free() {
M src/FbTk/FbPixmap.hhsrc/FbTk/FbPixmap.hh

@@ -69,6 +69,7 @@ inline unsigned int height() const { return m_height; }

inline int depth() const { return m_depth; } static Pixmap getRootPixmap(int screen_num); + static void FbPixmap::rootwinPropertyNotify(int screen_num, Atom atom); void create(Drawable src, unsigned int width, unsigned int height,

@@ -79,6 +80,14 @@ void free();

Pixmap m_pm; unsigned int m_width, m_height; int m_depth; + + /// Functions relating to the maintenance of root window pixmap caching + static void checkAtoms(); + static void setRootPixmap(int screen_num, Pixmap pm); + // array of pixmaps: 1 per screen + static Pixmap *m_root_pixmaps; + static const char *root_prop_ids[]; + static Atom root_prop_atoms[]; }; } // end namespace FbTk
M src/fluxbox.ccsrc/fluxbox.cc

@@ -657,8 +657,15 @@ } else if (e->type == EnterNotify ||

e->type == LeaveNotify) { m_last_time = e->xcrossing.time; m_mousescreen = searchScreen(e->xcrossing.root); - } else if (e->type == PropertyNotify) + } else if (e->type == PropertyNotify) { m_last_time = e->xproperty.time; + // check transparency atoms if it's a root pm + + BScreen *screen = searchScreen(e->xproperty.window); + if (screen) { + FbTk::FbPixmap::rootwinPropertyNotify(screen->screenNumber(), e->xproperty.atom); + } + } // we need to check focus out for menus before // we call FbTk eventhandler