From 23e89dca08394fdc3e4732f543e59e53b051554e Mon Sep 17 00:00:00 2001 From: Ole Christian Tvedt Date: Sat, 13 Jun 2009 23:36:28 +0200 Subject: [PATCH] Added own_window_type panel 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 --- doc/config_settings.xml | 19 +++++---- src/conky.c | 44 +++++++++++++++++++++ src/x11.c | 85 ++++++++++++++++++++++++++++++++++++++++- src/x11.h | 2 + 4 files changed, 140 insertions(+), 10 deletions(-) diff --git a/doc/config_settings.xml b/doc/config_settings.xml index fc5f8c1a..5bca7674 100644 --- a/doc/config_settings.xml +++ b/doc/config_settings.xml @@ -577,14 +577,17 @@ - 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. + 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. diff --git a/src/conky.c b/src/conky.c index cd21055a..01e0338e 100644 --- a/src/conky.c +++ b/src/conky.c @@ -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 { diff --git a/src/x11.c b/src/x11.c index d66955d0..5ee44460 100644 --- 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); + } + } +} diff --git a/src/x11.h b/src/x11.h index 45b209d1..e3b037cb 100644 --- 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 */