Home > Archive > Unix Programming > September 2005 > Why is background of simple X11 app transparent?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Why is background of simple X11 app transparent?
|
|
| Matt Garman 2005-09-15, 6:59 pm |
| I'm trying to learn X11 programming. I wrote a simple "hello world"
program.
For some reason, the background of the window I create is
transparent (as opposed to black or white, as I specify in my
graphics context).
The simple program is listed below.
Has anyone seen anything like this?
Thanks,
Matt
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
Display *dpy = NULL;
Window window;
char* display_name = NULL;
XFontStruct* font_info;
char* font_name = "fixed";
GC gc;
XGCValues values;
unsigned long valuemask = 0;
int screen_num = 0;
/* create display */
display_name = getenv("DISPLAY");
dpy = XOpenDisplay(display_name);
if (!dpy)
fprintf(stderr, "Can't open display '%s'!\n",
display_name);
screen_num = DefaultScreen(dpy);
/* create window */
window = XCreateWindow(dpy, DefaultRootWindow(dpy),
0, 0, 400, 400, 0, CopyFromParent, CopyFromParent,
CopyFromParent, 0, 0);
XMapWindow(dpy, window);
XFlush(dpy);
/* create graphics context (gc) */
gc = XCreateGC(dpy, window, valuemask, &values);
if (gc < 0) fprintf(stderr, "XCreateGC() failure!\n");
XSetForeground(dpy, gc, WhitePixel(dpy, screen_num));
XSetBackground(dpy, gc, BlackPixel(dpy, screen_num));
XSetLineAttributes(dpy, gc, 10, LineSolid, CapButt, JoinBevel);
XSetFillStyle(dpy, gc, FillSolid);
/* set font */
font_info = XLoadQueryFont(dpy, font_name);
if (!font_info)
fprintf(stderr, "XLoadQueryFont() failed for '%s'\n", font_name);
XSetFont(dpy, gc, font_info->fid);
XSync(dpy, False);
/* draw! draw! draw! */
XDrawString(dpy, window, gc, 40, 40, "Hello World", strlen("Hello World"));
XFillRectangle(dpy, window, gc, 60, 150, 50, 60);
XFlush(dpy);
sleep(10);
XCloseDisplay(dpy);
return 0;
}
--
Matt Garman
email at: http://raw-sewage.net/index.php?file=email
| |
| Måns Rullgård 2005-09-15, 6:59 pm |
| Matt Garman <fake@not-real.bogus> writes:
> I'm trying to learn X11 programming. I wrote a simple "hello world"
> program.
>
> For some reason, the background of the window I create is
> transparent (as opposed to black or white, as I specify in my
> graphics context).
It's not transparent, you're just not drawing anything to it. The
graphics context is only used by the functions that take one as an
argument. To set a background color for the window, try
XSetWindowBackground.
--
Måns Rullgård
mru@inprovide.com
| |
| Matt Garman 2005-09-15, 9:56 pm |
| On Thu, 15 Sep 2005 19:50:01 +0100, Måns Rullgård <mru@inprovide.com> wrote:
> It's not transparent, you're just not drawing anything to it. The
> graphics context is only used by the functions that take one as an
> argument. To set a background color for the window, try
> XSetWindowBackground.
Ahh, indeed. Actually, for this exercise, I just switched to
XCreateSimpleWindow(), and used BlackPixel and WhitePixel for my
foreground and background colors.
Now I have a new question... whenever I create a window, the window
manager overwrites the top portion of my window with the titlebar.
I guess I assumed that the window manager would "grow" its titlebar
upward from the top of my window.
How can I possibly know what the window manager's titlebar height
is? To even provide such a function seems out of scope for X. Am I
supposed to set some kind of hint to the window manager?
Thanks again,
Matt
--
Matt Garman
email at: http://raw-sewage.net/index.php?file=email
| |
| Russell Shaw 2005-09-16, 3:57 am |
| Matt Garman wrote:
> On Thu, 15 Sep 2005 19:50:01 +0100, Måns Rullgård <mru@inprovide.com> wrote:
>
>
> Ahh, indeed. Actually, for this exercise, I just switched to
> XCreateSimpleWindow(), and used BlackPixel and WhitePixel for my
> foreground and background colors.
>
> Now I have a new question... whenever I create a window, the window
> manager overwrites the top portion of my window with the titlebar.
> I guess I assumed that the window manager would "grow" its titlebar
> upward from the top of my window.
>
> How can I possibly know what the window manager's titlebar height
> is? To even provide such a function seems out of scope for X. Am I
> supposed to set some kind of hint to the window manager?
>
> Thanks again,
> Matt
The client is meant to know about the window manager border.
All this is explained in the ICCCM.
http://www.google.com.au/search?hl=...le+Search&meta=
| |
| Måns Rullgård 2005-09-16, 3:57 am |
| Matt Garman <fake@not-real.bogus> writes:
> Now I have a new question... whenever I create a window, the window
> manager overwrites the top portion of my window with the titlebar.
> I guess I assumed that the window manager would "grow" its titlebar
> upward from the top of my window.
Are you sure about this? Which window manager are you using? The
ones I've used (including twm, mwm, olvwm, fvwm, sawfish, metacity,
kwin, enlightenment, blackbox) have never done anything like this.
--
Måns Rullgård
mru@inprovide.com
| |
| Matt Garman 2005-09-16, 6:59 pm |
| On Fri, 16 Sep 2005 08:20:39 +0100, Måns Rullgård <mru@inprovide.com> wrote:
> Are you sure about this? Which window manager are you using? The
> ones I've used (including twm, mwm, olvwm, fvwm, sawfish,
> metacity, kwin, enlightenment, blackbox) have never done anything
> like this.
Yup, quite sure---it's actually part of the reason I was intially
unable to see what was being drawing to my window. I can take some
screenshots later, if you're interested.
The WM I'm using is enlightenment 0.16.7.2. This is on gentoo Linux
on i386.
I haven't yet tried other window managers---I'll try that also
(much later today).
Thanks again!
Matt
--
Matt Garman
email at: http://raw-sewage.net/index.php?file=email
| |
| Måns Rullgård 2005-09-16, 6:59 pm |
| Matt Garman <fake@not-real.bogus> writes:
> On Fri, 16 Sep 2005 08:20:39 +0100, Måns Rullgård <mru@inprovide.com> wrote:
>
> Yup, quite sure---it's actually part of the reason I was intially
> unable to see what was being drawing to my window. I can take some
> screenshots later, if you're interested.
I'd rather see some code that creates a window with that behavior.
--
Måns Rullgård
mru@inprovide.com
| |
| Matt Garman 2005-09-16, 6:59 pm |
| On Fri, 16 Sep 2005 18:41:02 +0100, Måns Rullgård <mru@inprovide.com> wrote:
>
> I'd rather see some code that creates a window with that behavior.
This code exhibits said behavior (window manager title bar
overwriting top portion of window).
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
Display *dpy = NULL;
Window window;
char* display_name = NULL;
XFontStruct* font_info;
/* picking a larger font, as my default "fixed" font is so small that it
* will be completely overwritten by the titlebar */
char* font_name = "10x20";
GC gc;
XGCValues values;
unsigned long valuemask = 0;
int screen_num = 0;
/* create display */
display_name = getenv("DISPLAY");
dpy = XOpenDisplay(display_name);
if (!dpy) {
fprintf(stderr, "Can't open display '%s'!\n",
display_name);
}
screen_num = DefaultScreen(dpy);
/* create window */
window = XCreateWindow( dpy, DefaultRootWindow(dpy), 0, 0, 400, 400, 0,
CopyFromParent, CopyFromParent, CopyFromParent, 0, 0);
XMapWindow(dpy, window);
XFlush(dpy);
/* create graphics context (gc) */
gc = XCreateGC(dpy, window, valuemask, &values);
if (gc < 0) {
fprintf(stderr, "XCreateGC() failure!\n");
}
XSetForeground(dpy, gc, WhitePixel(dpy, screen_num));
XSetBackground(dpy, gc, BlackPixel(dpy, screen_num));
XSetLineAttributes(dpy, gc, 10, LineSolid, CapButt, JoinBevel);
XSetFillStyle(dpy, gc, FillSolid);
/* set font */
font_info = XLoadQueryFont(dpy, font_name);
if (!font_info) {
fprintf(stderr, "XLoadQueryFont() failed for '%s'\n", font_name);
}
XSetFont(dpy, gc, font_info->fid);
XSync(dpy, False);
/* draw! draw! draw! */
XDrawString(dpy, window, gc, 40, 40, "Hello World", strlen("Hello World"));
XFillRectangle(dpy, window, gc, 60, 150, 50, 60);
XFlush(dpy);
sleep(10);
XCloseDisplay(dpy);
return 0;
}
--
Matt Garman
email at: http://raw-sewage.net/index.php?file=email
| |
| Måns Rullgård 2005-09-16, 9:56 pm |
| Matt Garman <fake@not-real.bogus> writes:
> On Fri, 16 Sep 2005 18:41:02 +0100, Måns Rullgård <mru@inprovide.com> wrote:
>
> This code exhibits said behavior (window manager title bar
> overwriting top portion of window).
Works just fine here. Your window manager is broken.
--
Måns Rullgård
mru@inprovide.com
| |
| Matt Garman 2005-09-20, 7:02 pm |
| On Sat, 17 Sep 2005 02:48:38 +0100, Måns Rullgård <mru@inprovide.com> wrote:
> Matt Garman <fake@not-real.bogus> writes:
>
> Works just fine here. Your window manager is broken.
What window manager are you using?
FWIW, I got the same behavior under enlightenment 0.16.7.2 and
fluxbox 0.9.14.
When I tried it under FVWM 2.5.12, I have the same problem I
originally posted about (the background is "transparent" and no
drawn features show up in the window).
Matt
--
Matt Garman
email at: http://raw-sewage.net/index.php?file=email
| |
| Måns Rullgård 2005-09-20, 7:02 pm |
| Matt Garman <fake@not-real.bogus> writes:
> On Sat, 17 Sep 2005 02:48:38 +0100, Måns Rullgård <mru@inprovide.com> wrote:
>
> What window manager are you using?
Sawfish at the moment. I have used many different window managers,
and I have never seen the problem of the title bar overlapping the
window.
> FWIW, I got the same behavior under enlightenment 0.16.7.2 and
> fluxbox 0.9.14.
>
> When I tried it under FVWM 2.5.12, I have the same problem I
> originally posted about (the background is "transparent" and no
> drawn features show up in the window).
The transparent background is not transparent. You just haven't drawn
anything there, so whatever was on the screen where your window got
mapped is still shown.
--
Måns Rullgård
mru@inprovide.com
| |
| Ulrich Hobelmann 2005-09-20, 7:02 pm |
| Måns Rullgård wrote:
>
> Sawfish at the moment. I have used many different window managers,
> and I have never seen the problem of the title bar overlapping the
> window.
AFAIK about all window managers *add* their decoration around the X
window, so it should never really cover any of the window (except for
some very weird enlightenment themes maybe).
--
My mouth says the words, my brain is thinking monstertrucks.
Joey (Friends)
| |
| Måns Rullgård 2005-09-20, 7:02 pm |
| Ulrich Hobelmann <u.hobelmann@web.de> writes:
> Måns Rullgård wrote:
>
> AFAIK about all window managers *add* their decoration around the X
> window, so it should never really cover any of the window (except for
> some very weird enlightenment themes maybe).
That how it's supposed to be done, and that's what the dozen or so
window managers I've ever used did. Every one of them.
--
Måns Rullgård
mru@inprovide.com
| |
| Matt Garman 2005-09-20, 10:02 pm |
| On Tue, 20 Sep 2005 19:10:51 +0100, Måns Rullgård <mru@inprovide.com> wrote:
> Sawfish at the moment. I have used many different window
> managers, and I have never seen the problem of the title bar
> overlapping the window.
I believe I figured out what my problem was.
The sample program you posted over in the other NG worked just fine.
So I went about adding a call to XDrawString(). Guess what? I
couldn't see the string!
But since your program worked as advertised, I realized that the
window manager is *not* overwriting part of my window.
XDrawString() just wasn't drawing the string where I expected it.
The fourth and fifth params to XDrawString() are the starting x and
y coordinates of the rendered screen within your window.
Originally, I had been using position (0, 0) as the starting
location of my string. So I arbitrarily added 20 to the y-position.
And the string appeared!
So then I made it somewhat smarter: I used the "ascent" member of my
XFontStruct as the y-position argument to XDrawString(). Now my
string starts exactly at the top of the window, as I originally
expected. I tried it with a few different fonts, and I'm convinced
that this was my problem.
If you're interested, I posted your program, slightly modified,
below. On my system, the "fixed" font has an ascent of 11 and a
decent of 2.
> The transparent background is not transparent. You just haven't drawn
> anything there, so whatever was on the screen where your window got
> mapped is still shown.
Does this mean you always have to call XSetWindowBackground() on any
window upon which you wish to draw? Once again, while I was hacking
on your program, I removed the call to XSetWindowBackground(), and
nothing showed up in the window. I even tried setting
XSetBackground() (to set the background color for the graphics
context), and still got nothing.
So, is XSetWindowBackground() basically a required call?
Thanks a million, you've been extremely helpful!
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <unistd.h>
#define FONT_NAME "fixed"
//#define FONT_NAME "-b&h-lucidabright-*-r-*-*-34-*-*-*-*-*-*-*"
//#define FONT_NAME "10x20"
int main(int argc, char **argv)
{
Display *dpy;
Window w;
GC gc;
XGCValues gcv;
XFontStruct* font_info;
int run = 1;
if(!(dpy = XOpenDisplay(NULL)))
return 1;
if (!(font_info = XLoadQueryFont(dpy, FONT_NAME))) {
fprintf(stderr, "ERROR: XLoadQueryFont() '%s'\n", FONT_NAME);
return 1;
}
printf("font_info->ascent = %i\n", font_info->ascent);
printf("font_info->descent = %i\n", font_info->descent);
w = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, 200, 100, 0,
CopyFromParent, InputOutput, CopyFromParent, 0, NULL);
gcv.foreground = BlackPixel(dpy, DefaultScreen(dpy));
gcv.line_width = 1;
gcv.line_style = LineSolid;
gc = XCreateGC(dpy, w,
GCForeground | GCLineWidth | GCLineStyle, &gcv);
XSetFont(dpy, gc, font_info->fid);
XSetWindowBackground(dpy, w, WhitePixel(dpy, DefaultScreen(dpy)));
XSelectInput(dpy, w, ExposureMask | KeyPressMask);
XMapWindow(dpy, w);
XSync(dpy, False);
while(run){
XEvent xe;
XNextEvent(dpy, &xe);
switch(xe.type){
case Expose:
XDrawString(dpy, w, gc, 0, font_info->ascent, "Hello World",
strlen("Hello World"));
break;
case KeyPress:
run = 0;
break;
}
}
XDestroyWindow(dpy, w);
XCloseDisplay(dpy);
return 0;
}
--
Matt Garman
email at: http://raw-sewage.net/index.php?file=email
| |
| Måns Rullgård 2005-09-21, 3:56 am |
| Matt Garman <fake@not-real.bogus> writes:
> On Tue, 20 Sep 2005 19:10:51 +0100, Måns Rullgård <mru@inprovide.com> wrote:
>
> I believe I figured out what my problem was.
>
> The sample program you posted over in the other NG worked just fine.
> So I went about adding a call to XDrawString(). Guess what? I
> couldn't see the string!
>
> But since your program worked as advertised, I realized that the
> window manager is *not* overwriting part of my window.
> XDrawString() just wasn't drawing the string where I expected it.
> The fourth and fifth params to XDrawString() are the starting x and
> y coordinates of the rendered screen within your window.
>
> Originally, I had been using position (0, 0) as the starting
> location of my string. So I arbitrarily added 20 to the y-position.
> And the string appeared!
Yes, the coordinates are for the baseline of the text, not the top
left corner.
> So then I made it somewhat smarter: I used the "ascent" member of my
> XFontStruct as the y-position argument to XDrawString(). Now my
> string starts exactly at the top of the window, as I originally
> expected. I tried it with a few different fonts, and I'm convinced
> that this was my problem.
>
> If you're interested, I posted your program, slightly modified,
> below. On my system, the "fixed" font has an ascent of 11 and a
> decent of 2.
>
>
> Does this mean you always have to call XSetWindowBackground() on any
> window upon which you wish to draw? Once again, while I was hacking
> on your program, I removed the call to XSetWindowBackground(), and
> nothing showed up in the window. I even tried setting
> XSetBackground() (to set the background color for the graphics
> context), and still got nothing.
>
> So, is XSetWindowBackground() basically a required call?
It's never required, but useful if you want a solid background color.
The alternative is to explicitly draw the background, for instance
using XFillRectangle. Letting the X server do this for you is
obviously faster.
--
Måns Rullgård
mru@inprovide.com
|
|
|
|
|