Added own_window_type panel
authorOle Christian Tvedt <olechrt@stud.ntnu.no>
Sat, 13 Jun 2009 21:36:28 +0000 (23:36 +0200)
committerBrenden Matthews <brenden@rty.ca>
Sat, 13 Jun 2009 23:46:09 +0000 (17:46 -0600)
The panel type reserves space along the edge of the
screen, just like regular DE panels, taskbars and the
like. I have tested it for several hours now with lots
of different settings, and it seems to be working fine.

Works especially well with alignment top_??? or
bottom_??? and single-line output. Something like
this:

  own_window yes
  own_window_type panel

  alignment bottom_left
  maximum_width 1680
  minimum_size 1680
  gap_x 0
  gap_y 0

  stippled_borders 1
  draw_borders yes

  update_interval 3.0

  TEXT
  $nodename $tab $freq_g ${color grey}GHz$color $tab $memperc% ${color grey}RAM$color $tab $cpu% ${color grey}CPU $tab etc...etc...$alignr${time %F %R}

The line after TEXT is supposed to be on one line,
just in case some channel has messed it up.

Signed-off-by: Brenden Matthews <brenden@rty.ca>

doc/config_settings.xml
src/conky.c
src/x11.c
src/x11.h

index fc5f8c1..5bca767 100644 (file)
                 <option>own_window_type</option>
             </command>
         </term>
-        <listitem>if own_window is yes, you may specify type
-        normal, desktop, dock or override (default: normal).
-        Desktop windows are special windows that have no window
-        decorations; are always visible on your desktop; do not
-        appear in your pager or taskbar; and are sticky across all
-        workspaces. Override windows are not under the control of
-        the window manager. Hints are ignored. This type of window
-        can be useful for certain situations. 
+        <listitem>if own_window is yes, you may specify type normal,
+        desktop, dock, panel or override (default: normal).  Desktop
+        windows are special windows that have no window decorations;
+        are always visible on your desktop; do not appear in your
+        pager or taskbar; and are sticky across all workspaces. Panel
+        windows reserve space along a desktop edge, just like panels
+        and taskbars, preventing maximized windows from overlapping
+        them. The edge is chosen based on the alignment
+        option. Override windows are not under the control of the
+        window manager. Hints are ignored. This type of window can be
+        useful for certain situations.
         <para /></listitem>
     </varlistentry>
     <varlistentry>
index cd21055..01e0338 100644 (file)
@@ -6945,6 +6945,8 @@ static void main_loop(void)
                                update_text_area();
 #ifdef OWN_WINDOW
                                if (own_window) {
+                                       int changed = 0;
+
                                        /* resize window if it isn't right size */
                                        if (!fixed_size
                                                && (text_width + border_inner_margin * 2 + border_outer_margin * 2 + border_width * 2 != window.width
@@ -6954,12 +6956,52 @@ static void main_loop(void)
                                                        XResizeWindow(display, window.window, window.width,
                                                                window.height);
                                                        set_transparent_background(window.window);
+
+                                                       changed++;
                                        }
 
                                        /* move window if it isn't in right position */
                                        if (!fixed_pos && (window.x != wx || window.y != wy)) {
                                                XMoveWindow(display, window.window, window.x, window.y);
+                                               changed++;
                                        }
+
+                                        /* update struts */
+                                        if (changed && window.type == TYPE_PANEL) {
+                                               int sidenum = -1;
+
+                                                fprintf(stderr, PACKAGE_NAME": defining struts\n");
+                                                fflush(stderr);
+
+                                               switch (text_alignment) {
+                                                       case TOP_LEFT:
+                                                       case TOP_RIGHT:
+                                                       case TOP_MIDDLE:
+                                                       {
+                                                               sidenum = 2;
+                                                               break;
+                                                       }
+                                                       case BOTTOM_LEFT:
+                                                       case BOTTOM_RIGHT:
+                                                       case BOTTOM_MIDDLE:
+                                                       {
+                                                               sidenum = 3;
+                                                               break;
+                                                       }
+                                                       case MIDDLE_LEFT:
+                                                       {
+                                                               sidenum = 0;
+                                                               break;
+                                                       }
+                                                       case MIDDLE_RIGHT:
+                                                       {
+                                                               sidenum = 1;
+                                                               break;
+                                                       }
+                                               }
+
+                                               set_struts(sidenum);
+                                        }
                                }
 #endif
 
@@ -8312,6 +8354,8 @@ static void load_config_file(const char *f)
                                } else if (strncmp(value, "dock", 4) == EQUAL) {
                                        window.type = TYPE_DOCK;
                                        text_alignment = TOP_LEFT;
+                               } else if (strncmp(value, "panel", 5) == EQUAL) {
+                                       window.type = TYPE_PANEL;
                                } else if (strncmp(value, "override", 8) == EQUAL) {
                                        window.type = TYPE_OVERRIDE;
                                } else {
index d66955d..5ee4446 100644 (file)
--- a/src/x11.c
+++ b/src/x11.c
@@ -278,8 +278,11 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour,
                        /* allow decorated windows to be given input focus by WM */
                        wmHint.input =
                                TEST_HINT(window.hints, HINT_UNDECORATED) ? False : True;
-                       wmHint.initial_state = ((window.type == TYPE_DOCK) ?
-                                               WithdrawnState : NormalState);
+                        if (window.type == TYPE_DOCK || window.type == TYPE_PANEL) {
+                               wmHint.initial_state = WithdrawnState;
+                        } else {
+                               wmHint.initial_state = NormalState;
+                        }
 
                        XmbSetWMProperties(display, window.window, window.title, NULL, argv,
                                argc, NULL, &wmHint, &classHint);
@@ -302,6 +305,11 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour,
                                                fprintf(stderr, PACKAGE_NAME": window type - dock\n");
                                                fflush(stderr);
                                                break;
+                                       case TYPE_PANEL:
+                                               prop = ATOM(_NET_WM_WINDOW_TYPE_DOCK);
+                                               fprintf(stderr, PACKAGE_NAME": window type - panel\n");
+                                               fflush(stderr);
+                                               break;
                                        case TYPE_NORMAL:
                                        default:
                                                prop = ATOM(_NET_WM_WINDOW_TYPE_NORMAL);
@@ -579,3 +587,76 @@ void update_x11info(void)
        current_info->x11.monitor.number = XScreenCount(display);
        current_info->x11.monitor.current = XDefaultScreen(display);
 }
+
+/* reserve window manager space */
+void set_struts(int sidenum)
+{
+       Atom strut;
+       if ((strut = ATOM(_NET_WM_STRUT)) != None) {
+               /* reserve space at left, right, top, bottom */
+               signed long sizes[12] = {0};
+               int i;
+
+               /* define strut depth */
+               switch (sidenum) {
+                       case 0:
+                       {
+                               /* left side */
+                               sizes[0] = window.x + window.width;
+                               break;
+                       }
+                       case 1:
+                       {
+                               /* right side */
+                               sizes[1] = display_width - window.x;
+                               break;
+                       }
+                       case 2:
+                       {
+                               /* top side */
+                               sizes[2] = window.y + window.height;
+                               break;
+                       }
+                       case 3:
+                       {
+                               /* bottom side */
+                               sizes[3] = display_height - window.y;
+                               break;
+                       }
+               }
+
+               /* define partial strut length */
+               if (sidenum <= 1) {
+                       sizes[4 + (sidenum*2)] = window.y;
+                       sizes[5 + (sidenum*2)] = window.y + window.height;
+               } else if (sidenum <= 3) {
+                       sizes[4 + (sidenum*2)] = window.x;
+                       sizes[5 + (sidenum*2)] = window.x + window.width;
+               }
+
+               /* check constraints */
+               for (i = 0; i < 12; i++) {
+                       if (sizes[i] < 0) {
+                               sizes[i] = 0;
+                       } else {
+                               if (i <= 1 || i >= 8) {
+                                       if (sizes[i] > display_width) {
+                                               sizes[i] = display_width;
+                                       }
+                               } else {
+                                       if (sizes[i] > display_height) {
+                                               sizes[i] = display_height;
+                                       }
+                               }
+                       }
+               }
+
+               XChangeProperty(display, window.window, strut, XA_CARDINAL, 32,
+                               PropModeReplace, (unsigned char *) &sizes, 4);
+
+               if ((strut = ATOM(_NET_WM_STRUT_PARTIAL)) != None) {
+                       XChangeProperty(display, window.window, strut, XA_CARDINAL, 32,
+                                       PropModeReplace, (unsigned char *) &sizes, 12);
+               }
+       }
+}
index 45b209d..e3b037c 100644 (file)
--- a/src/x11.h
+++ b/src/x11.h
@@ -20,6 +20,7 @@
 enum _window_type {
        TYPE_NORMAL = 0,
        TYPE_DOCK,
+       TYPE_PANEL,
        TYPE_DESKTOP,
        TYPE_OVERRIDE
 };
@@ -84,6 +85,7 @@ void destroy_window(void);
 void create_gc(void);
 void set_transparent_background(Window win);
 long get_x11_color(const char *);
+void set_struts(int);
 
 #endif /*X11_H_*/
 #endif /* X11 */