refactored desktop info code so that its only called on X property events; TO DO...
authorCesare Tirabassi <norsetto@ubuntu.com>
Tue, 14 Jul 2009 14:57:51 +0000 (16:57 +0200)
committerCesare Tirabassi <norsetto@ubuntu.com>
Tue, 14 Jul 2009 14:57:51 +0000 (16:57 +0200)
src/conky.c
src/conky.h
src/x11.c
src/x11.h

index 59a371b..b2e5f39 100644 (file)
@@ -1090,6 +1090,10 @@ static void free_text_objects(struct text_object *root, int internal)
                                  free(info.x11.desktop.name);
                                  info.x11.desktop.name = NULL;
                                }
+                               if(info.x11.desktop.all_names) {
+                                 free(info.x11.desktop.all_names);
+                                 info.x11.desktop.all_names = NULL;
+                               }
                                break;
 #endif /* X11 */
                }
@@ -7111,6 +7115,14 @@ static void main_loop(void)
                                                break;
                                        }
 
+                                       case PropertyNotify:
+                                       {
+                                               if ( ev.xproperty.state == PropertyNewValue ) {
+                                                       get_x11_desktop_info( ev.xproperty.display, ev.xproperty.atom );
+                                               }
+                                               break;
+                                       }
+
 #ifdef OWN_WINDOW
                                        case ReparentNotify:
                                                /* set background to ParentRelative for all parents */
@@ -7713,6 +7725,8 @@ static void set_default_configurations(void)
        info.x11.monitor.current = 0;
        info.x11.desktop.current = 1; 
        info.x11.desktop.number = 1;
+       info.x11.desktop.nitems = 0;
+       info.x11.desktop.all_names = NULL; 
        info.x11.desktop.name = NULL; 
 #endif /* X11 */
 
index 69e6720..59e0dcc 100644 (file)
@@ -150,6 +150,8 @@ struct monitor_info {
 struct desktop_info {
         int current;
         int number;
+        unsigned int nitems;
+        char *all_names;
         char *name;
 };
 
index eb0cf1f..95e1acd 100644 (file)
--- a/src/x11.c
+++ b/src/x11.c
@@ -80,6 +80,8 @@ void init_X11(const char *disp)
        display_width = DisplayWidth(display, screen);
        display_height = DisplayHeight(display, screen);
 
+       get_x11_desktop_info(display, 0);
+
        update_workarea();
 }
 
@@ -478,9 +480,9 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour,
        } */
 #endif
 
-       XSelectInput(display, window.window, ExposureMask
+       XSelectInput(display, window.window, ExposureMask | PropertyChangeMask
 #ifdef OWN_WINDOW
-               | (own_window ? (StructureNotifyMask | PropertyChangeMask |
+               | (own_window ? (StructureNotifyMask |
                ButtonPressMask | ButtonReleaseMask) : 0)
 #endif
                );
@@ -557,73 +559,141 @@ void create_gc(void)
                GCFunction | GCGraphicsExposures, &values);
 }
 
-void update_x11info(void)
+//Get current desktop number
+static inline void get_x11_desktop_current(Display *display, Window root, Atom atom)
 {
-        Window root;
-       Atom actual_type, atom;
+        Atom actual_type;
        int actual_format;
        unsigned long nitems;
        unsigned long bytes_after;
        unsigned char *prop = NULL;
-
        struct information *current_info = &info;
-       current_info->x11.monitor.number = XScreenCount(display);
-       current_info->x11.monitor.current = XDefaultScreen(display);
 
-       root = RootWindow(display, current_info->x11.monitor.current);
+       if ( (XGetWindowProperty( display, root, atom,
+                                 0, 1L, False, XA_CARDINAL,
+                                 &actual_type, &actual_format, &nitems,
+                                 &bytes_after, &prop ) == Success ) &&
+            (actual_type == XA_CARDINAL) &&
+            (nitems == 1L) && (actual_format == 32) ) {
+         current_info->x11.desktop.current = prop[0]+1;
+       }
+       if(prop) {
+         XFree(prop);
+       }
+}
 
-       //Get current desktop number
-       if ((atom = XInternAtom(display, "_NET_CURRENT_DESKTOP", True)) != None) {
-         if ( (XGetWindowProperty( display, root, atom,
-                                   0, 1L, False, XA_CARDINAL,
-                                   &actual_type, &actual_format, &nitems,
-                                   &bytes_after, &prop ) == Success ) &&
-              (actual_type == XA_CARDINAL) &&
-              (nitems == 1L) ) {
-           current_info->x11.desktop.current = prop[0]+1;
-         }
+//Get total number of available desktops
+static inline void get_x11_desktop_number(Display *display, Window root, Atom atom)
+{
+        Atom actual_type;
+       int actual_format;
+       unsigned long nitems;
+       unsigned long bytes_after;
+       unsigned char *prop = NULL;
+       struct information *current_info = &info;
+
+       if ( (XGetWindowProperty( display, root, atom,
+                                 0, 1L, False, XA_CARDINAL,
+                                 &actual_type, &actual_format, &nitems,
+                                 &bytes_after, &prop ) == Success ) &&
+            (actual_type == XA_CARDINAL) &&
+            (nitems == 1L) && (actual_format == 32) ) {
+         current_info->x11.desktop.number = prop[0];
+       }
+       if(prop) {
+         XFree(prop);
        }
+}
+
+//Get all desktop names
+static inline void get_x11_desktop_names(Display *display, Window root, Atom atom)
+{
+        Atom actual_type;
+       int actual_format;
+       unsigned long nitems;
+       unsigned long bytes_after;
+       unsigned char *prop = NULL;
+       struct information *current_info = &info;
 
-       //Get total number of available desktops
-       if ((atom = XInternAtom(display, "_NET_NUMBER_OF_DESKTOPS", True)) != None) {
-         if ( (XGetWindowProperty( display, root, atom,
-                                   0, 1L, False, XA_CARDINAL,
-                                   &actual_type, &actual_format, &nitems,
-                                   &bytes_after, &prop ) == Success ) &&
-              (actual_type == XA_CARDINAL) &&
-              (nitems == 1L) ) {
-           current_info->x11.desktop.number = prop[0];
+       if ( (XGetWindowProperty( display, root, atom,
+                                 0, (~0L), False, ATOM(UTF8_STRING),
+                                 &actual_type, &actual_format, &nitems,
+                                 &bytes_after, &prop ) == Success ) &&
+            (actual_type == ATOM(UTF8_STRING)) &&
+            (nitems > 0L) && (actual_format == 8) ) {
+
+         if(current_info->x11.desktop.all_names) {
+           free(current_info->x11.desktop.all_names);
+           current_info->x11.desktop.all_names = NULL;
          }
+         current_info->x11.desktop.all_names = malloc(nitems*sizeof(char));
+         memcpy(current_info->x11.desktop.all_names, prop, nitems);
+         current_info->x11.desktop.nitems = nitems;
+       }
+       if(prop) {
+         XFree(prop);
        }
+}
 
-       //Get current desktop name
-       if ((atom = XInternAtom(display, "_NET_DESKTOP_NAMES", True)) != None) {
-         if ( (XGetWindowProperty( display, root, atom,
-                                   0, (~0L), False, ATOM(UTF8_STRING),
-                                   &actual_type, &actual_format, &nitems,
-                                   &bytes_after, &prop ) == Success ) &&
-              (actual_type == ATOM(UTF8_STRING)) &&
-              (nitems > 0L) ) {
-           unsigned int i = 0, j = 0;
-           int k = 0;
-           while ( i < nitems ) {
-             if ( prop[i++] == '\0' ) {
-               if ( ++k == current_info->x11.desktop.current ) {
-                 if(current_info->x11.desktop.name) {
-                   free(current_info->x11.desktop.name);
-                   current_info->x11.desktop.name = NULL;
-                 }
-                 current_info->x11.desktop.name = malloc(i-j);
-                 //desktop names can be empty but should always be not null
-                 strcpy( current_info->x11.desktop.name, (char *)&prop[j] );
-                 break;
-               }
-               j = i;
+//Get current desktop name
+static inline void get_x11_desktop_current_name(char *names)
+{
+       struct information *current_info = &info;
+       unsigned int i = 0, j = 0;
+       int k = 0;
+
+       while ( i < current_info->x11.desktop.nitems ) {
+         if ( names[i++] == '\0' ) {
+           if ( ++k == current_info->x11.desktop.current ) {
+             if (current_info->x11.desktop.name) {
+               free(current_info->x11.desktop.name);
+               current_info->x11.desktop.name = NULL;
              }
+             current_info->x11.desktop.name = malloc((i-j)*sizeof(char));
+             //desktop names can be empty but should always be not null
+             strcpy( current_info->x11.desktop.name, (char *)&names[j] );
+             break;
            }
+           j = i;
          }
        }
+}
+
+void get_x11_desktop_info(Display *display, Atom atom)
+{
+        Window root;
+       static Atom atom_current, atom_number, atom_names;
+       struct information *current_info = &info;
 
+       root = RootWindow(display, current_info->x11.monitor.current);
+
+       //Check if we initialise else retrieve changed property
+       if (atom == 0) {
+         atom_current = XInternAtom(display, "_NET_CURRENT_DESKTOP", True);
+         atom_number  = XInternAtom(display, "_NET_NUMBER_OF_DESKTOPS", True);
+         atom_names   = XInternAtom(display, "_NET_DESKTOP_NAMES", True);
+         get_x11_desktop_current(display, root, atom_current);
+         get_x11_desktop_number(display, root, atom_number);
+         get_x11_desktop_names(display, root, atom_names);
+         get_x11_desktop_current_name(current_info->x11.desktop.all_names);
+       } else {
+         if (atom == atom_current) {
+           get_x11_desktop_current(display, root, atom_current);
+           get_x11_desktop_current_name(current_info->x11.desktop.all_names);
+         } else if (atom == atom_number) {
+           get_x11_desktop_number(display, root, atom_number);
+         } else if (atom == atom_names) {
+           get_x11_desktop_names(display, root, atom_names);
+           get_x11_desktop_current_name(current_info->x11.desktop.all_names);
+         }
+       }
+}
+
+void update_x11info(void)
+{
+       struct information *current_info = &info;
+       current_info->x11.monitor.number = XScreenCount(display);
+       current_info->x11.monitor.current = XDefaultScreen(display);
 }
 
 #ifdef OWN_WINDOW
index 15c122a..9644f0f 100644 (file)
--- a/src/x11.h
+++ b/src/x11.h
@@ -89,6 +89,7 @@ void destroy_window(void);
 void create_gc(void);
 void set_transparent_background(Window win);
 long get_x11_color(const char *);
+void get_x11_desktop_info(Display *display, Atom atom);
 void set_struts(int);
 
 #endif /*X11_H_*/