Why window without borders is always on top - c

I'm trying to create window without borders (popup?) in xlib. I'm using this code:
#include <stdio.h>
#include <X11/Xlib.h>
int main( int argc, char **argv )
{
Display *display = NULL;
Window window;
XSetWindowAttributes attribs;
display = XOpenDisplay( NULL );
if( !display )
{
printf( "Cannot to open display." );
return 1;
}
attribs.override_redirect = 1;
window = XCreateWindow( display, RootWindow(display, 0), 20, 20, 400, 300, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attribs );
XSetWindowBackground( display, window, 0x00F0FF );
XClearWindow( display, window );
XMapWindow( display, window );
XFlush( display );
getchar( );
return 0;
}
It creating window without borders, but this window is always on top.
The question is: Why and what to do in xlib to display it as a normal window.

That's how override-redirect windows are meant to behave. They are designed for implementing pop-up menus and similar windows which are transient and stay above other windows.
If that's not what you want, do not use override-redirect flag. Instead, use WM hints. See here for the full list of hints. You want to tell your WM which window type you have (_NET_WM_WINDOW_TYPE_TOOLBAR etc), not how it's decorated. See here for a usage example.
If that's still not what you want, use the (somewhat outdated) Motif WM hints. See for example here.

Related

Cant fin definition of XMapWindow() in Xlib headers

So i have this simple code that draws a small window using X11
int main(int, char*[])
{
Display* display = XOpenDisplay(NULL);
Window window = XCreateSimpleWindow(
display, XDefaultRootWindow(display),
100, 100, 200, 200, 4, 0, 0);
XEvent event;
XMapWindow(display, window);
XSelectInput(display, window, KeyPressMask | ButtonPressMask | ExposureMask);
while (True) {
XNextEvent(display, &event);
}
return 0;
}
Everything works fine, the window its drawed without problems.
The thing is i really want to understand how X11 works so im reading the source code of the headers but im unable to find the difinition for XMapWindow() i need help.
This was the only similutede i could find in the Xlib.h header file.
extern int XMapWindow(
Display* /* display */,
Window /* w */
);
You can find the implementation of XMapWindow() in the libX11 sources, specifically in src/MapWindow.c:XMapWindow().
It boils down to some locking, and a _XGetRequest(dpy, X_MapWindow, SIZEOF(xResourceReq)) call. That is defined in src/XlibInt.c:_XGetRequest(), and as you can guess by the name, adds the X_MapWindow request to the request queue sent to the X server.
How the X server (which manages the actual display) acts on that, is up to that X server implementation.

override_redirect Xlib window attribute does nothing

I want to create a non-resizable window for my little game engine. I found out that override_redirect attribute set to true is exactly what I need. So I wrote my sample program:
#include <X11/Xlib.h>
#include <unistd.h>
Display *display;
Window window;
Visual *visual;
XSetWindowAttributes attributes;
int depth;
int screen;
int main(){
display = XOpenDisplay(NULL);
screen = DefaultScreen(display);
visual = DefaultVisual(display,screen);
depth = DefaultDepth(display,screen);
attributes.background_pixel = XWhitePixel(display,screen);
attributes.override_redirect = True;
window = XCreateWindow( display,XRootWindow(display,screen),
200, 200, 350, 200, 5, depth, InputOutput,
visual ,CWBackPixel, &attributes);
XSelectInput(display,window,ExposureMask | KeyPressMask) ;
XMapWindow(display, window);
XFlush(display);
sleep(10);
return 0;
}
However, my window is resizable and there is a title bar on the top of it. How can I get rid of those and why doesn't this code work as intended?
How can I get rid of those and why doesn't this code work as intended?
You forgot to set the CWOverrideRedirect bit in the bitmask:
CWBackPixel means that the background_pixel element in the attributes structure is considered.
You must use CWBackPixel|CWOverrideRedirect if both the elements background_pixel and override_redirect shall be considered:
attributes.background_pixel = XWhitePixel(display,screen);
attributes.override_redirect = True;
window = XCreateWindow( display,XRootWindow(display,screen),
200, 200, 350, 200, 5, depth, InputOutput,
visual, CWBackPixel|CWOverrideRedirect, &attributes);

Border/Titlebar not properly displaying in SDL OSX

I was just following lazyfoo's SDL tutorial and I ran the sample code as shown here:
#include <SDL2/SDL.h>
#include <stdio.h>
//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
int main( int argc, char* args[] )
{
//The window we'll be rendering to
SDL_Window* window = NULL;
//The surface contained by the window
SDL_Surface* screenSurface = NULL;
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "Failed to initialise SDL! SDL_Error: %s\n", SDL_GetError() );
}
else
{
//Create window
window = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if( window == NULL )
{
printf( "Failed to create window! SDL_Error: %s\n", SDL_GetError() );
}
else
{
//Get window surface
screenSurface = SDL_GetWindowSurface( window );
//Fill the surface white
SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 255, 0, 0 ) );
//Update the surface
SDL_UpdateWindowSurface( window );
//Wait two seconds
SDL_Delay( 2000 );
}
}
//Destroy window
SDL_DestroyWindow( window );
//Quit SDL subsystems
SDL_Quit();
return 0;
}
But for some reason no real border or title bar is being shown, it just displays a white screen. I tried using
SDL_SetWindowBordered but it did nothing. Next I set the background colour to red and from this image you can see there is a titlebar but there is no close or minimize button.
Does anyone know why this is happening. Is it just me or is it a problem with mac's?
Since getting rid of SDL_Delay seemed to help, I will try to elaborate a little. If we look at the code of SDL_Delay we can see that it basically does two things:
if nanosleep() can be utilized, it does sleep for a time interval;
else, it runs in an infinite while loop, checking how much time has passed # each iteration, and breaking out of the loop after enough time has passed.
Now, I must say that I have never personally coded for osx, so I do not know how exactly does it draw it's windows. However I can assume that for some reason SDL_Delay in your code gets called (and effectively blocks the thread it's called from) before the OS manages to draw the header of the window, and after the delay finishes you immediately destroy the window yourself, thus the header is never properly drawn.
I know that the answer is already solved, but for anyone who wants a simple solution.
Example:
SDL_Delay(4000);
would turn into
for(int i = 0; i < 4000; i++){
SDL_PumpEvents();
SDL_Delay(1);
}
Actually this has nothing to do with SDL_Delay() at all.
I tested it out, and it seems that on OSX the title-bar only updates each time the events are polled or pumped.
This means that SDL_Delay() blocks the title-bar rendering process if it prevents you from pumping events.
To fix this just call SDL_PumpEvents() every millisecond or so:
for(int i = 0; i < time_to_sleep; i++){
SDL_PumpEvents();
SDL_Delay(1);
}

Simple C Program that creates 2 X11 windows

I want to create 2 windows in linux that I'll later draw in from a separate thread. I currently have a non-deterministic bug where the second window that I create sometimes doesn't get created (no errors though).
Here is the code.
static void create_x_window(Display *display, Window *win, int width, int height)
{
int screen_num = DefaultScreen(display);
unsigned long background = WhitePixel(display, screen_num);
unsigned long border = BlackPixel(display, screen_num);
*win = XCreateSimpleWindow(display, DefaultRootWindow(display), /* display, parent */
0,0, /* x, y */
width, height, /* width, height */
2, border, /* border width & colour */
background); /* background colour */
XSelectInput(display, *win, ButtonPressMask|StructureNotifyMask);
XMapWindow(display, *win);
}
int main(void) {
XInitThreads(); // prevent threaded XIO errors
local_display = XOpenDisplay(":0.0");
Window self_win, remote_win;
XEvent self_event, remote_event;
create_x_window(local_display, &remote_win, 640,480);
// this line flushes buffer and blocks so that the window doesn't crash for a reason i dont know yet
XNextEvent(local_display, &remote_event);
create_x_window(local_display, &self_win, 320, 240);
// this line flushes buffer and blocks so that the window doesn't crash for a reason i dont know yet
XNextEvent(local_display, &self_event);
while (1) {
}
return 0;
}
I don't really care for capturing input in the windows, but I found a tutorial that had XSelectInput and XNextEvent (in an event loop) and I was having trouble making this work without either.
It's not a bug, it's a feature. You left out the event loop.
Although you cleverly called XNextEvent twice, the X protocol is asynchronous so the server may still be setting up the actual window while you call XNextEvent, so there is nothing to do.
Tutorial here.

Xlib: window is created in wrong position

I have simple xlib program which creates window. I think it has to show window on the upper-left corner of the screen because I pass 0, 0 to XCreateSimpleWindow function, but it's in upper-middle side. Why ?
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char* argv[])
{
Display* display;
int screen_num;
Window win;
unsigned int display_width,display_height;
unsigned int width, height;
char *display_name = getenv("DISPLAY");
display = XOpenDisplay(display_name);
screen_num = DefaultScreen(display);
display_width = DisplayWidth(display, screen_num);
display_height = DisplayHeight(display, screen_num);
width = (display_width / 3);
height = (display_height / 3);
win = XCreateSimpleWindow(display, RootWindow(display, screen_num), 0, 0, width, height, 1, BlackPixel(display, screen_num), WhitePixel(display, screen_num));
XMapWindow(display, win);
XSync(display, False);
while(1) { }
}
The top level windows are placed (and dimensioned) by the window manager which does whatever it suit it. Often the size is respected but the position not (in order to leave place for decoration, in order to respect placement policy of leaving toolbars clear, ...)
Try on a display without a window manager if you want your request to be respected (use VNC or similar to get such a display, don't try to use your desktop like this)

Resources