X11 Configurenotify() Always Returning X,Y = (0,0)

X11 ConfigureNotify() always returning x,y = (0,0)

Your window manager is responsible for both phenomena.

The first one is because of reparenting. The WM can reparent top-level windows, so that they are no longer direct children of the root. It does so to create window decorations and the like. Your window becomes a child, or a grandchild, of the decorations window. For this reason, relative positions of top-level windows are useless. You need absolute positions. Use XTranslateCoordinates to obtain them.

The second one is because the WM just knows better. No, really. It's the WM. It's supposed to be smart. It belongs to the user. The user (at least in theory) configures his WM however he sees fit. Application writers shouldn't care. If the user wants his window to always appear centered, then so be it. If he wants them appear at random positions, it's his choice.

In rare circumstances windows should appear at fixed positions, and such windows should nearly always be override-redirect.

In yet more rare circumstances you must position a managed window at known coordinates. In such cases, see this answer to a related question (shameless plug: it's mine). You want to specify PPosition and PSize.

XChangeProperty() always fails

Most xlib functions always return 1 and you should use error handlers to check for errors. See XChangeProperty implementation - note return 1 at the end.

Your code works just fine:

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>

static void
change_prop(Display *display, Window window)
{
unsigned char some_text[40] = "hello world!";
int retval;
Atom my_atom;

my_atom = XInternAtom(display, "PERSONAL_PROPERTY", False);
if (my_atom == None)
{
printf("### failed to create atom with name PERSONAL_PROPERTY\n");
return;
}

retval = XChangeProperty(display, /* connection to x server */
window, /* window whose property we want to change */
my_atom, /* property name */
XA_STRING, /* type of property */
8, /* format of prop; can be 8, 16, 32 */
PropModeReplace,
some_text, /* actual data */
10 /* number of elements */
);

printf("###### XChangeProperty() reted %d\n", retval);
}

int main()
{

Display *dis;
Window win;

dis = XOpenDisplay(NULL);
win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 1, 1, 500, 500, \
0, BlackPixel (dis, 0), BlackPixel(dis, 0));
XMapWindow(dis, win);
printf("window %i\n", (int)win);
change_prop(dis, win);

XFlush(dis);
sleep(50);
return(0);
}

result:

09:48 tmp $ g++ prop.cpp /usr/X11/lib/libX11.dylib
09:48 tmp $ ./a.out
window 6291457
###### XChangeProperty() reted 1

xprop result:

09:48 tmp $ xprop -id 6291457
WM_STATE(WM_STATE):
window state: Normal
icon window: 0x0
_NET_WM_STATE(ATOM) =
_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_FULLSCREEN, _NET_WM_ACTION_CLOSE
PERSONAL_PROPERTY(STRING) = "hello worl"

XLIB Decoration questions

Read EWMH spec and you'll find answers to all questions.

  1. Check "override redirect" window flag
  2. You are trying
    to destroy window which is already destroyed. Instead of using
    event.xdestroywindow.event window id just delete your decoration
    window.
  3. Don't forget to add client window to save set if you are
    writing reparenting WM. That way if you kill wm application windows
    are not destroyed but reparented back to root window

XDeleteProperty returning BadRequest error

I found out looking at the Xlib source code, unless return code 1 is BadRequest exception, the return of XDeleteProperty is ALWAYS 1... good to know !

glXCreateContext Magically Maps Window

Investigating this has been difficult, but I've resolved it and the TL;DR is:

  1. This isn't actually about glXCreateContext(...). This is about an apparent timing bug in certain implementations of X.
  2. This issue was exposed by a workaround I had written on the basis of misinformation. The thing I wanted to do should instead be accomplished by means of a different workaround.

Description of Underlying Issues

When a window is created, the window manager wraps it in a new window, as long as the override redirect isn't set (attributes .override_redirect and flag CWOverrideRedirect on
window creation). This is so that it can do things like add a frame and buttons.

Unfortunately, the window manager can (and does, at least before the window is mapped) use this as an excuse to ignore behavior such as XMoveWindow(...). This has led to the misconception that one should map and then unmap the window so that the X server "knows about it".

This exposes the apparent bug. On the system in question (stock Ubuntu in VirtualBox), mapping and then unmapping the window immediately after causes the window to remain mapped.

I tried many things, such as putting XFlush(...) or XSync(...) calls around the map/unmap calls (which also allowed me to show that glXCreateContext(...) is not at issue). However, what finally got it to work as-expected was to add sleeps. A delay of 0.1 seconds made the window appear and disappear. A delay of 0.01 seconds made the window remain mapped. This was rather frustrating to figure out (I had the aforementioned getchar()s and printf(...)s, and this introduced enough latency while debugging that the problem couldn't be reproduced).

The following (probably non-minimal) code works as-written, but removing the nanosleep(...) calls will cause the problem:

struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 200000000;

XFlush(_display);
nanosleep(&ts, nullptr);
XMapWindow(display, window);
XFlush(display);
nanosleep(&ts, nullptr);
XUnmapWindow(display, window);
XFlush(_display);

Presumably the delay allows catching up to the map/unmap events or something. I'm not sure this is a full-fledged bug, but it's certainly a usability defect. (If this gives you enough information to explain what's going on here, feel free to edit this answer.)

However, as-mentioned, this workaround is based on a misconception! The X server already knows about the new window. It's just flagrantly ignoring you. To fix this, we can hint to the windowing system that it shouldn't be so rude. Since this doesn't rely on map/unmap, the erroneous behavior doesn't happen anymore.



Related Topics



Leave a reply



Submit