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: 29,447
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,589

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.


pkgshackscfgblag

Offline

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

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,447
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

#7 2021-04-22 13:50:38

NUIL
Member
Registered: 2021-04-22
Posts: 7

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

Hi, I have come into similar issue, here is my code:

#include <X11/Xlib.h>

int main()
{
  Display *dpy = XOpenDisplay(NULL);
  int screen = DefaultScreen(dpy);
  Window root = RootWindow(dpy, screen);
  XSetWindowBackground(dpy, root, 0);
  XClearWindow(dpy, root);
  return 0;
}

It will just not change background.
How do I fix it?

Offline

#8 2021-04-22 19:13:59

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

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

NUIL, there are most likely other process maintaining the root window (and redrawing it after your code runs) - but you've told us nothing about your setup.  In any case, this is actually a totally different issue and should be it's own thread rather than necrobumping a solved thread.


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

Online

#9 2021-04-22 22:04:13

WorMzy
Forum Moderator
From: Scotland
Registered: 2010-06-16
Posts: 11,787
Website

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

As noted, please do not necrobump.

https://gitlab.archlinux.org/archlinux/ … ro-bumping

Closing.


Sakura:-
Mobo: MSI MAG X570S TORPEDO MAX // Processor: AMD Ryzen 9 5950X @4.9GHz // GFX: AMD Radeon RX 5700 XT // RAM: 32GB (4x 8GB) Corsair DDR4 (@ 3000MHz) // Storage: 1x 3TB HDD, 6x 1TB SSD, 2x 120GB SSD, 1x 275GB M2 SSD

Making lemonade from lemons since 2015.

Offline

Board footer

Powered by FluxBB