A window should stay on top of all other windows. Is this somehow possible with plain x11/xlib? Googling for "Always on top" and "x11" / "xlib" didn't return anything useful.
I'd avoid toolkits like GTK+, if somehow possible.
I'm using Ubuntu with gnome desktop. In the window menu, there's an option "Always On Top". Is this provided by the X server or the window manager? If the second is the case, is there a general function that can be called for nearly any wm? Or how to do this in an "X11-generic" way?
XSelectInput(this->display, this->window,
ButtonPressMask |
StructureNotifyMask |
ExposureMask |
KeyPressMask |
PropertyChangeMask |
VisibilityChangeMask );
// ...
// In a loop:
if (XPending(this->display) >= 0)
{
XNextEvent(this->display, &ev);
switch(ev.type) {
// ...
case VisibilityNotify:
XRaiseWindow(this->display, this->window);
XFlush(this->display);
break;
// ...
}
}
But the eventhandling and raising nearly never gets executed even my mask is correct?!
#define _NET_WM_STATE_REMOVE 0 // remove/unset property
#define _NET_WM_STATE_ADD 1 // add/set property
#define _NET_WM_STATE_TOGGLE 2 // toggle property
...
...
Atom wmStateAbove = XInternAtom( display, "_NET_WM_STATE_ABOVE", 1 );
if( wmStateAbove != None ) {
printf( "_NET_WM_STATE_ABOVE has atom of %ld\n", (long)wmStateAbove );
} else {
printf( "ERROR: cannot find atom for _NET_WM_STATE_ABOVE !\n" );
}
Atom wmNetWmState = XInternAtom( display, "_NET_WM_STATE", 1 );
if( wmNetWmState != None ) {
printf( "_NET_WM_STATE has atom of %ld\n", (long)wmNetWmState );
} else {
printf( "ERROR: cannot find atom for _NET_WM_STATE !\n" );
}
// set window always on top hint
if( wmStateAbove != None ) {
XClientMessageEvent xclient;
memset( &xclient, 0, sizeof (xclient) );
//
//window = the respective client window
//message_type = _NET_WM_STATE
//format = 32
//data.l[0] = the action, as listed below
//data.l[1] = first property to alter
//data.l[2] = second property to alter
//data.l[3] = source indication (0-unk,1-normal app,2-pager)
//other data.l[] elements = 0
//
xclient.type = ClientMessage;
xclient.window = mywin; // GDK_WINDOW_XID(window);
xclient.message_type = wmNetWmState; //gdk_x11_get_xatom_by_name_for_display( display, "_NET_WM_STATE" );
xclient.format = 32;
xclient.data.l[0] = _NET_WM_STATE_ADD; // add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
xclient.data.l[1] = wmStateAbove; //gdk_x11_atom_to_xatom_for_display (display, state1);
xclient.data.l[2] = 0; //gdk_x11_atom_to_xatom_for_display (display, state2);
xclient.data.l[3] = 0;
xclient.data.l[4] = 0;
//gdk_wmspec_change_state( FALSE, window,
// gdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
// GDK_NONE );
XSendEvent( display,
//mywin - wrong, not app window, send to root window!
root, // !! DefaultRootWindow( display ) !!!
False,
SubstructureRedirectMask | SubstructureNotifyMask,
(XEvent *)&xclient );
}