From 5fec1906cc4faf83ec2424aa48c2a050b0254d15 Mon Sep 17 00:00:00 2001 From: simonb <simonb> Date: Tue, 10 May 2005 16:29:00 +0000 Subject: cache the root pixmap (per screen) --- ChangeLog | 3 ++ src/FbTk/FbPixmap.cc | 141 ++++++++++++++++++++++++++++++++++++++------------- src/FbTk/FbPixmap.hh | 9 ++++ src/fluxbox.cc | 9 +++- 4 files changed, 126 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index 294c1db..81a6bd6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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) diff --git a/src/FbTk/FbPixmap.cc b/src/FbTk/FbPixmap.cc index b2937c3..ce28f0e 100644 --- a/src/FbTk/FbPixmap.cc +++ b/src/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> @@ -34,6 +35,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), m_depth(0) { @@ -297,53 +314,107 @@ Pixmap FbPixmap::release() { 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; + + 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; - 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() { diff --git a/src/FbTk/FbPixmap.hh b/src/FbTk/FbPixmap.hh index c8640a2..ca81cf4 100644 --- a/src/FbTk/FbPixmap.hh +++ b/src/FbTk/FbPixmap.hh @@ -69,6 +69,7 @@ public: 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 @@ private: 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 diff --git a/src/fluxbox.cc b/src/fluxbox.cc index 271d93f..f01224f 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -657,8 +657,15 @@ void Fluxbox::handleEvent(XEvent * const e) { 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 -- cgit v0.11.2