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.
- Check "override redirect" window flag
- You are trying
to destroy window which is already destroyed. Instead of using
event.xdestroywindow.event window id just delete your decoration
window. - 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:
- This isn't actually about
glXCreateContext(...)
. This is about an apparent timing bug in certain implementations of X. - 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
How to Join Multiple Txt Files into Based on Column
Overview/Reference Manual for Open Firmware Device Trees
Why Sigint Can Stop Bash in Terminal But Not via Kill -Int
Find Ip Address of My System for a Particular Interface with Shell Script (Bash)
Assembly Divisions and Floating Points
How Make /Var/Www Contents Editable by Ide
How to Correctly Nandwrite a Nanddump'Ed Dump with Oob
Moving a Git Repo to Another Server
How to Customize or Remove Extra Linux Kernel Version Details Shown at Boot
Cron Job Mysteriously Stopped Running
Numa-Aware Named Shared Memory for Linux
Cannot Get Qwindow::Fromwinid to Work Properly
Error While Running Parallel Make
Make for Compiling - All *.C Files in Folders & Subfolders in Project