X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fx11.c;h=a1ce8c01405e4beb5e441891cf1e920be79930bd;hb=04435790955e0671f512f7b180e7d8fadeb4ceff;hp=95e1acd7017afc5579c76d1ffe38fd4b75c8200a;hpb=7bbde2be738242e4301d56eb09a117d2932ed4f1;p=monky diff --git a/src/x11.c b/src/x11.c index 95e1acd..a1ce8c0 100644 --- a/src/x11.c +++ b/src/x11.c @@ -1,4 +1,7 @@ -/* Conky, a system monitor, based on torsmo +/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*- + * vim: ts=4 sw=4 noet ai cindent syntax=c + * + * Conky, a system monitor, based on torsmo * * Any original torsmo code is licensed under the BSD license * @@ -7,7 +10,7 @@ * Please see COPYING for details * * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen - * Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al. + * Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al. * (see AUTHORS) * All rights reserved. * @@ -41,13 +44,19 @@ #ifdef XFT #include -int use_xft = 0; +int use_xft; #endif #ifdef HAVE_XDBE int use_xdbe; #endif +#ifdef USE_ARGB +int use_argb_visual; +int have_argb_visual; +#endif /* USE_ARGB */ +int own_window_argb_value; + /* some basic X11 stuff */ Display *display = NULL; int display_width; @@ -61,6 +70,7 @@ int workarea[4]; /* Window stuff */ struct conky_window window; +char window_created = 0; /* local prototypes */ static void update_workarea(void); @@ -72,7 +82,7 @@ void init_X11(const char *disp) { if (!display) { if ((display = XOpenDisplay(disp)) == NULL) { - CRIT_ERR("can't open display: %s", XDisplayName(0)); + CRIT_ERR(NULL, NULL, "can't open display: %s", XDisplayName(disp)); } } @@ -118,14 +128,14 @@ static Window find_desktop_window(Window *p_root, Window *p_desktop) XQueryTree(display, root, &troot, &parent, &children, &n); for (i = 0; i < (int) n; i++) { if (XGetWindowProperty(display, children[i], ATOM(__SWM_VROOT), 0, 1, - False, XA_WINDOW, &type, &format, &nitems, &bytes, &buf) + False, XA_WINDOW, &type, &format, &nitems, &bytes, &buf) == Success && type == XA_WINDOW) { win = *(Window *) buf; XFree(buf); XFree(children); fprintf(stderr, - PACKAGE_NAME": desktop window (%lx) found from __SWM_VROOT property\n", - win); + PACKAGE_NAME": desktop window (%lx) found from __SWM_VROOT property\n", + win); fflush(stderr); *p_root = win; *p_desktop = win; @@ -153,8 +163,8 @@ static Window find_desktop_window(Window *p_root, Window *p_desktop) if (win != root) { fprintf(stderr, - PACKAGE_NAME": desktop window (%lx) is subwindow of root window (%lx)\n", - win, root); + PACKAGE_NAME": desktop window (%lx) is subwindow of root window (%lx)\n", + win, root); } else { fprintf(stderr, PACKAGE_NAME": desktop window (%lx) is root window\n", win); } @@ -167,11 +177,27 @@ static Window find_desktop_window(Window *p_root, Window *p_desktop) return win; } -/* sets background to ParentRelative for the Window and all parents */ -void set_transparent_background(Window win) +static int colour_set = -1; +/* if no argb visual is configured sets background to ParentRelative for the Window and all parents, + else real transparency is used */ +void set_transparent_background(Window win, int alpha) { - static int colour_set = -1; - + (void)alpha; /* disable warnings when unused */ + +#ifdef USE_ARGB + if (have_argb_visual) { + // real transparency + if (set_transparent) { + XSetWindowBackground(display, win, 0x00); + } else if (colour_set != background_colour) { + XSetWindowBackground(display, win, + background_colour | (alpha << 24)); + colour_set = background_colour; + } + } else { +#endif /* USE_ARGB */ + // pseudo transparency + if (set_transparent) { Window parent = win; unsigned int i; @@ -189,14 +215,52 @@ void set_transparent_background(Window win) XSetWindowBackground(display, win, background_colour); colour_set = background_colour; } - // XClearWindow(display, win); not sure why this was here +#ifdef USE_ARGB + } +#endif /* USE_ARGB */ } +#ifdef USE_ARGB +static int get_argb_visual(Visual** visual, int *depth) { + /* code from gtk project, gdk_screen_get_rgba_visual */ + XVisualInfo visual_template; + XVisualInfo *visual_list; + int nxvisuals = 0, i; + + visual_template.screen = screen; + visual_list = XGetVisualInfo (display, VisualScreenMask, + &visual_template, &nxvisuals); + for (i = 0; i < nxvisuals; i++) { + if (visual_list[i].depth == 32 && + (visual_list[i].red_mask == 0xff0000 && + visual_list[i].green_mask == 0x00ff00 && + visual_list[i].blue_mask == 0x0000ff)) { + *visual = visual_list[i].visual; + *depth = visual_list[i].depth; + DBGP("Found ARGB Visual"); + XFree(visual_list); + return 1; + } + } + // no argb visual available + DBGP("No ARGB Visual found"); + XFree(visual_list); + return 0; +} +#endif /* USE_ARGB */ + void destroy_window(void) { - XDestroyWindow(display, window.window); - XFreeGC(display, window.gc); +#ifdef XFT + if(window.xftdraw) { + XftDrawDestroy(window.xftdraw); + } +#endif + if(window.gc) { + XFreeGC(display, window.gc); + } memset(&window, 0, sizeof(struct conky_window)); + colour_set = -1; } void init_window(int own_window, int w, int h, int set_trans, int back_colour, @@ -207,12 +271,32 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, * happens but I bet the bug is somewhere here. */ set_transparent = set_trans; background_colour = back_colour; + window_created = 1; #ifdef OWN_WINDOW if (own_window) { + int depth = 0, flags; + Visual *visual = NULL; + if (!find_desktop_window(&window.root, &window.desktop)) { return; } + +#ifdef USE_ARGB + if (use_argb_visual && get_argb_visual(&visual, &depth)) { + have_argb_visual = 1; + window.visual = visual; + window.colourmap = XCreateColormap(display, + DefaultRootWindow(display), window.visual, AllocNone); + } else { +#endif /* USE_ARGB */ + window.visual = DefaultVisual(display, screen); + window.colourmap = DefaultColormap(display, screen); + depth = CopyFromParent; + visual = CopyFromParent; +#ifdef USE_ARGB + } +#endif /* USE_ARGB */ if (window.type == TYPE_OVERRIDE) { @@ -221,11 +305,21 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, XSetWindowAttributes attrs = { ParentRelative, 0L, 0, 0L, 0, 0, Always, 0L, 0L, False, StructureNotifyMask | ExposureMask, 0L, True, 0, 0 }; +#ifdef USE_ARGB + if (have_argb_visual) { + attrs.colormap = window.colourmap; + flags = CWBorderPixel | CWColormap | CWOverrideRedirect; + } else { +#endif /* USE_ARGB */ + flags = CWBackPixel | CWOverrideRedirect; +#ifdef USE_ARGB + } +#endif /* USE_ARGB */ /* Parent is desktop window (which might be a child of root) */ window.window = XCreateWindow(display, window.desktop, window.x, - window.y, w, h, 0, CopyFromParent, InputOutput, CopyFromParent, - CWBackPixel | CWOverrideRedirect, &attrs); + window.y, w, h, 0, depth, InputOutput, visual, + flags, &attrs); XLowerWindow(display, window.window); @@ -237,19 +331,30 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, * Process hints and buttons. */ XSetWindowAttributes attrs = { ParentRelative, 0L, 0, 0L, 0, 0, Always, 0L, 0L, False, StructureNotifyMask | ExposureMask | - ButtonPressMask | ButtonReleaseMask, 0L, False, 0, 0 }; + ButtonPressMask | ButtonReleaseMask, 0L, False, 0, 0 }; XClassHint classHint; XWMHints wmHint; Atom xa; +#ifdef USE_ARGB + if (have_argb_visual) { + attrs.colormap = window.colourmap; + flags = CWBorderPixel | CWColormap | CWOverrideRedirect; + } else { +#endif /* USE_ARGB */ + flags = CWBackPixel | CWOverrideRedirect; +#ifdef USE_ARGB + } +#endif /* USE_ARGB */ + if (window.type == TYPE_DOCK) { window.x = window.y = 0; } /* Parent is root window so WM can take control */ window.window = XCreateWindow(display, window.root, window.x, - window.y, w, h, 0, CopyFromParent, InputOutput, CopyFromParent, - CWBackPixel | CWOverrideRedirect, &attrs); + window.y, w, h, 0, depth, InputOutput, visual, + flags, &attrs); classHint.res_name = window.class_name; classHint.res_class = classHint.res_name; @@ -258,14 +363,15 @@ 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; - if (window.type == TYPE_DOCK || window.type == TYPE_PANEL) { + if (window.type == TYPE_DOCK || window.type == TYPE_PANEL) { wmHint.initial_state = WithdrawnState; - } else { + } else { wmHint.initial_state = NormalState; - } + } - XmbSetWMProperties(display, window.window, window.title, NULL, argv, - argc, NULL, &wmHint, &classHint); + XmbSetWMProperties(display, window.window, NULL, NULL, argv, + argc, NULL, &wmHint, &classHint); + XStoreName(display, window.window, window.title); /* Sets an empty WM_PROTOCOLS property */ XSetWMProtocols(display, window.window, NULL, 0); @@ -298,7 +404,7 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, break; } XChangeProperty(display, window.window, xa, XA_ATOM, 32, - PropModeReplace, (unsigned char *) &prop, 1); + PropModeReplace, (unsigned char *) &prop, 1); } /* Set desired hints */ @@ -306,27 +412,27 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, /* Window decorations */ if (TEST_HINT(window.hints, HINT_UNDECORATED)) { /* fprintf(stderr, PACKAGE_NAME": hint - undecorated\n"); - fflush(stderr); */ + fflush(stderr); */ xa = ATOM(_MOTIF_WM_HINTS); if (xa != None) { long prop[5] = { 2, 0, 0, 0, 0 }; XChangeProperty(display, window.window, xa, xa, 32, - PropModeReplace, (unsigned char *) prop, 5); + PropModeReplace, (unsigned char *) prop, 5); } } /* Below other windows */ if (TEST_HINT(window.hints, HINT_BELOW)) { /* fprintf(stderr, PACKAGE_NAME": hint - below\n"); - fflush(stderr); */ + fflush(stderr); */ xa = ATOM(_WIN_LAYER); if (xa != None) { long prop = 0; XChangeProperty(display, window.window, xa, XA_CARDINAL, 32, - PropModeAppend, (unsigned char *) &prop, 1); + PropModeAppend, (unsigned char *) &prop, 1); } xa = ATOM(_NET_WM_STATE); @@ -334,21 +440,21 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, Atom xa_prop = ATOM(_NET_WM_STATE_BELOW); XChangeProperty(display, window.window, xa, XA_ATOM, 32, - PropModeAppend, (unsigned char *) &xa_prop, 1); + PropModeAppend, (unsigned char *) &xa_prop, 1); } } /* Above other windows */ if (TEST_HINT(window.hints, HINT_ABOVE)) { /* fprintf(stderr, PACKAGE_NAME": hint - above\n"); - fflush(stderr); */ + fflush(stderr); */ xa = ATOM(_WIN_LAYER); if (xa != None) { long prop = 6; XChangeProperty(display, window.window, xa, XA_CARDINAL, 32, - PropModeAppend, (unsigned char *) &prop, 1); + PropModeAppend, (unsigned char *) &prop, 1); } xa = ATOM(_NET_WM_STATE); @@ -356,21 +462,21 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, Atom xa_prop = ATOM(_NET_WM_STATE_ABOVE); XChangeProperty(display, window.window, xa, XA_ATOM, 32, - PropModeAppend, (unsigned char *) &xa_prop, 1); + PropModeAppend, (unsigned char *) &xa_prop, 1); } } /* Sticky */ if (TEST_HINT(window.hints, HINT_STICKY)) { /* fprintf(stderr, PACKAGE_NAME": hint - sticky\n"); - fflush(stderr); */ + fflush(stderr); */ xa = ATOM(_NET_WM_DESKTOP); if (xa != None) { CARD32 xa_prop = 0xFFFFFFFF; XChangeProperty(display, window.window, xa, XA_CARDINAL, 32, - PropModeAppend, (unsigned char *) &xa_prop, 1); + PropModeAppend, (unsigned char *) &xa_prop, 1); } xa = ATOM(_NET_WM_STATE); @@ -378,54 +484,55 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, Atom xa_prop = ATOM(_NET_WM_STATE_STICKY); XChangeProperty(display, window.window, xa, XA_ATOM, 32, - PropModeAppend, (unsigned char *) &xa_prop, 1); + PropModeAppend, (unsigned char *) &xa_prop, 1); } } /* Skip taskbar */ if (TEST_HINT(window.hints, HINT_SKIP_TASKBAR)) { /* fprintf(stderr, PACKAGE_NAME": hint - skip_taskbar\n"); - fflush(stderr); */ + fflush(stderr); */ xa = ATOM(_NET_WM_STATE); if (xa != None) { Atom xa_prop = ATOM(_NET_WM_STATE_SKIP_TASKBAR); XChangeProperty(display, window.window, xa, XA_ATOM, 32, - PropModeAppend, (unsigned char *) &xa_prop, 1); + PropModeAppend, (unsigned char *) &xa_prop, 1); } } /* Skip pager */ if (TEST_HINT(window.hints, HINT_SKIP_PAGER)) { /* fprintf(stderr, PACKAGE_NAME": hint - skip_pager\n"); - fflush(stderr); */ + fflush(stderr); */ xa = ATOM(_NET_WM_STATE); if (xa != None) { Atom xa_prop = ATOM(_NET_WM_STATE_SKIP_PAGER); XChangeProperty(display, window.window, xa, XA_ATOM, 32, - PropModeAppend, (unsigned char *) &xa_prop, 1); + PropModeAppend, (unsigned char *) &xa_prop, 1); } } - } /* else { window.type != TYPE_OVERRIDE */ + } fprintf(stderr, PACKAGE_NAME": drawing to created window (0x%lx)\n", - window.window); + window.window); fflush(stderr); XMapWindow(display, window.window); - } else /* if (own_window) { */ -#endif - /* root / desktop window */ + } else +#endif /* OWN_WINDOW */ { XWindowAttributes attrs; if (!window.window) { window.window = find_desktop_window(&window.root, &window.desktop); } + window.visual = DefaultVisual(display, screen); + window.colourmap = DefaultColormap(display, screen); if (XGetWindowAttributes(display, window.window, &attrs)) { window.width = attrs.width; @@ -446,7 +553,7 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, use_xdbe = 0; } else { window.back_buffer = XdbeAllocateBackBufferName(display, - window.window, XdbeBackground); + window.window, XdbeBackground); if (window.back_buffer != None) { window.drawable = window.back_buffer; fprintf(stderr, PACKAGE_NAME": drawing to double buffer\n"); @@ -455,15 +562,13 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, } } if (!use_xdbe) { - ERR("failed to set up double buffer"); + NORM_ERR("failed to set up double buffer"); } } if (!use_xdbe) { fprintf(stderr, PACKAGE_NAME": drawing to single buffer\n"); } #endif - window.visual = DefaultVisual(display, DefaultScreen(display)); - window.colourmap = DefaultColormap(display, DefaultScreen(display)); #ifdef IMLIB2 { cimlib_init(display, window.drawable, window.visual, window.colourmap); @@ -471,21 +576,12 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, #endif /* IMLIB2 */ XFlush(display); - /* set_transparent_background(window.window); - * must be done after double buffer stuff? */ -#ifdef OWN_WINDOW - /* if (own_window) { - set_transparent_background(window.window); - XClearWindow(display, window.window); - } */ -#endif - XSelectInput(display, window.window, ExposureMask | PropertyChangeMask #ifdef OWN_WINDOW - | (own_window ? (StructureNotifyMask | - ButtonPressMask | ButtonReleaseMask) : 0) + | (own_window ? (StructureNotifyMask | + ButtonPressMask | ButtonReleaseMask) : 0) #endif - ); + ); } static Window find_subwindow(Window win, int w, int h) @@ -506,8 +602,8 @@ static Window find_subwindow(Window win, int w, int h) /* Window must be mapped and same size as display or * work space */ if (attrs.map_state != 0 && ((attrs.width == display_width - && attrs.height == display_height) - || (attrs.width == w && attrs.height == h))) { + && attrs.height == display_height) + || (attrs.width == w && attrs.height == h))) { win = children[j]; break; } @@ -523,32 +619,6 @@ static Window find_subwindow(Window win, int w, int h) return win; } -long get_x11_color(const char *name) -{ - XColor color; - - color.pixel = 0; - if (!XParseColor(display, DefaultColormap(display, screen), name, &color)) { - /* lets check if it's a hex colour with the # missing in front - * if yes, then do something about it */ - char newname[DEFAULT_TEXT_BUFFER_SIZE]; - - newname[0] = '#'; - strncpy(&newname[1], name, DEFAULT_TEXT_BUFFER_SIZE - 1); - /* now lets try again */ - if (!XParseColor(display, DefaultColormap(display, screen), &newname[0], - &color)) { - ERR("can't parse X color '%s'", name); - return 0xFF00FF; - } - } - if (!XAllocColor(display, DefaultColormap(display, screen), &color)) { - ERR("can't allocate X color '%s'", name); - } - - return (long) color.pixel; -} - void create_gc(void) { XGCValues values; @@ -556,82 +626,88 @@ void create_gc(void) values.graphics_exposures = 0; values.function = GXcopy; window.gc = XCreateGC(display, window.drawable, - GCFunction | GCGraphicsExposures, &values); + GCFunction | GCGraphicsExposures, &values); } //Get current desktop number -static inline void get_x11_desktop_current(Display *display, Window root, Atom atom) +static inline void get_x11_desktop_current(Display *current_display, Window root, Atom atom) { - Atom actual_type; + 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.current = prop[0]+1; + if (atom == None) return; + + if ( (XGetWindowProperty( current_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); + XFree(prop); } } //Get total number of available desktops -static inline void get_x11_desktop_number(Display *display, Window root, Atom atom) +static inline void get_x11_desktop_number(Display *current_display, Window root, Atom atom) { - Atom actual_type; + 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 (atom == None) return; + + if ( (XGetWindowProperty( current_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); + XFree(prop); } } //Get all desktop names -static inline void get_x11_desktop_names(Display *display, Window root, Atom atom) +static inline void get_x11_desktop_names(Display *current_display, Window root, Atom atom) { - Atom actual_type; + 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, (~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 (atom == None) return; + + if ( (XGetWindowProperty( current_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); + XFree(prop); } } @@ -643,55 +719,67 @@ static inline void get_x11_desktop_current_name(char *names) 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; - } + 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) +void get_x11_desktop_info(Display *current_display, Atom atom) { - Window root; + Window root; static Atom atom_current, atom_number, atom_names; struct information *current_info = &info; + XWindowAttributes window_attributes; - root = RootWindow(display, current_info->x11.monitor.current); + root = RootWindow(current_display, current_info->x11.monitor.current); - //Check if we initialise else retrieve changed property + /* 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); + atom_current = XInternAtom(current_display, "_NET_CURRENT_DESKTOP", True); + atom_number = XInternAtom(current_display, "_NET_NUMBER_OF_DESKTOPS", True); + atom_names = XInternAtom(current_display, "_NET_DESKTOP_NAMES", True); + get_x11_desktop_current(current_display, root, atom_current); + get_x11_desktop_number(current_display, root, atom_number); + get_x11_desktop_names(current_display, root, atom_names); + get_x11_desktop_current_name(current_info->x11.desktop.all_names); + + /* Set the PropertyChangeMask on the root window, if not set */ + XGetWindowAttributes(display, root, &window_attributes); + if (!(window_attributes.your_event_mask & PropertyChangeMask)) { + XSetWindowAttributes attributes; + attributes.event_mask = window_attributes.your_event_mask | PropertyChangeMask; + XChangeWindowAttributes(display, root, CWEventMask, &attributes); + XGetWindowAttributes(display, root, &window_attributes); + } } 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); - } + if (atom == atom_current) { + get_x11_desktop_current(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(current_display, root, atom_number); + } else if (atom == atom_names) { + get_x11_desktop_names(current_display, root, atom_names); + get_x11_desktop_current_name(current_info->x11.desktop.all_names); + } } } void update_x11info(void) { struct information *current_info = &info; + if (x_initialised != YES) + return; current_info->x11.monitor.number = XScreenCount(display); current_info->x11.monitor.current = XDefaultScreen(display); } @@ -709,29 +797,21 @@ void set_struts(int sidenum) /* 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 */ @@ -770,3 +850,17 @@ void set_struts(int sidenum) } } #endif /* OWN_WINDOW */ + +#ifdef HAVE_XDBE +void xdbe_swap_buffers(void) +{ + if (use_xdbe) { + XdbeSwapInfo swap; + + swap.swap_window = window.window; + swap.swap_action = XdbeBackground; + XdbeSwapBuffers(display, &swap, 1); + } +} +#endif /* HAVE_XDBE */ +