You are not logged in.

#1 2020-03-14 01:49:27

Portal
Member
Registered: 2019-03-11
Posts: 48

[SOLVED] XSetWindowBackground only works when the window is unmapped?

I am finally working on my own wm, but the XSetWindowBackground is causing me troubles. The following code does not work,

void switchToCursorless(XEvent *ev)
{
	mode=0;
	
	XSetWindowBackground(screen->dpy,cursorless_mode->win,active_col.pixel);
	XSetWindowBackground(screen->dpy, cursor_mode->win, bar_color.pixel);
	
}

The backgrounds of the windows are not changing at all. The function is indeed being called, as I had put a printf statement in there. I made a few modifications, and, to my surprise, the following new version is changing the backgrounds correctly,

void switchToCursorless(XEvent *ev)
{
	mode=0;
	XUnmapWindow(screen->dpy, cursor_mode->win);
	XUnmapWindow(screen->dpy, cursorless_mode->win);
	XSetWindowBackground(screen->dpy,cursorless_mode->win,active_col.pixel);
	XSetWindowBackground(screen->dpy, cursor_mode->win, bar_color.pixel);
	XMapWindow(screen->dpy, cursor_mode->win);
	XMapWindow(screen->dpy, cursorless_mode->win);
	drawTextCenter(screen,cursorless_mode,"1");
	drawTextCenter(screen,cursor_mode,"2");
}

It seems that the function only works when the window is unmapped, but this is never mentioned anywhere in the manual,

To set the background of a window to a given pixel, use XSetWindowBackground.
XSetWindowBackground (display, w, background_pixel)
Display *display;
Window w;
unsigned long background_pixel;
display       Specifies the connection to the X server.
w       Specifies the window.
background_pixel       Specifies the pixel that is to be used for the background.
The XSetWindowBackground function sets the background of the window to the specified pixel
value. Changing the background does not cause the window contents to be changed. XSetWin-
dowBackground uses a pixmap of undefined size filled with the pixel value you passed. If you
try to change the background of an InputOnly window, a BadMatch error results.

Is this really how the function works, or is there something else wrong in the other parts of my code? There have been some strange, unexpected behaviours in my program, and I was wondering if this mapping/unmapping method has something to do with it.
I am also open to other ways of changing background colors... I would appreciate if someone can tell me any.

Last edited by Portal (2020-03-14 20:52:57)

Offline

#2 2020-03-14 02:55:05

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 22,831
Website

Re: [SOLVED] XSetWindowBackground only works when the window is unmapped?

Portal wrote:

It seems that the function only works when the window is unmapped, but this is never mentioned anywhere in the manual,

... Changing the background does not cause the window contents to be changed.

A call to XFlush might be sufficient, though I doubt it.  You'll need to XClearWindow and/or redraw any of the content.

This has nothing to do with (un)mapping the window.  Unmapping and remapping the window does, however, trigger a redraw, and that is what is necessary.

Last edited by Trilby (2020-03-14 02:57:39)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Online

#3 2020-03-14 06:19:18

Portal
Member
Registered: 2019-03-11
Posts: 48

Re: [SOLVED] XSetWindowBackground only works when the window is unmapped?

It works now! Thanks for the insights. As you suggested, I added some XClearWindow calls and redrew some of my elements,

void switchToCursorless(XEvent *ev)
{
	mode=0;

	XSetWindowBackground(screen->dpy,cursorless_mode->win,active_col.pixel);
	XSetWindowBackground(screen->dpy, cursor_mode->win, bar_color.pixel);
	XClearWindow(screen->dpy,cursorless_mode->win);
	XClearWindow(screen->dpy,cursor_mode->win);
	drawTextCenter(screen,cursorless_mode,"1");
	drawTextCenter(screen,cursor_mode,"2");

	//XFlush(screen->dpy); XFlush alone doesn't seem to do the job
}

However, I still have no idea why the above code works... Can you elaborate a bit more on

Tribly wrote:

You'll need to XClearWindow and/or redraw any of the content

? I am having trouble relating

Changing the background does not cause the window contents to be changed

to your suggestions.

Offline

#4 2020-03-14 09:05:04

ayekat
Member
Registered: 2011-01-17
Posts: 1,371
Website

Re: [SOLVED] XSetWindowBackground only works when the window is unmapped?

The way I understand it, the X server simply treats a window as a single-layered pixmap, and no information is retained about which pixels are part of the "foreground" and which pixels are part of the "background".

It's only when a window is redrawn (or "cleared"), that the X server can apply meta-information like "this is the background colour" and "this is the foreground colour". As soon as the pixels have been mapped, they are just a pixel with a colour.


{,META,RE}PKGBUILDSpacman-hacks (includes makemetapkg and remakepkg) │ dotfiles

Offline

#5 2020-03-14 13:00:52

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 22,831
Website

Re: [SOLVED] XSetWindowBackground only works when the window is unmapped?

Ayekat is correct.  An analogy would be a paint program - e.g., gimp: you have a foreground and background color setting that are used when you use several of the painting tools.  If you have the foreground color set to red, and you draw on the canvas, you get a red line.  If you then change the foreground setting to blue, that previously drawn red line doesn't change color.  If it did, it'd make the program not so useful.  Changing the foreground color in the color picker does not cause the image contents to be changed.

Just the same, if the background is white, and you use the eraser tool, it leave white behind wherever you use it.  If you then change the background to black, the previously erased areas do not change color - only future erasures will result in black.  Because changing the brackground color does not cause the image contents to be changed - only future drawing/erasing is effected.

Now with X11 drawing, there is a foreground and background color just like in the paint programs.  You'll often want to draw several colors on a window.  To do so, you can set the foreground color, draw some elements, change the foreground color, then draw other elements.  Changing the foreground color does not cause the previously-drawn window contents to be changed.  You'll also have a background color that will be used with some drawing functions (clear/erase most notably, but there are others).  But changing this setting only effects future calls to these functions as changing the background does not cause the window contents to be changed.

Last edited by Trilby (2020-03-14 13:06:07)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Online

#6 2020-03-14 20:53:34

Portal
Member
Registered: 2019-03-11
Posts: 48

Re: [SOLVED] XSetWindowBackground only works when the window is unmapped?

Thanks for the help guys. I would've been stuck otherwise.

Offline

Board footer

Powered by FluxBB