Closed rogarb closed 2 years ago
When I test your code, it stays in wait_for_event
. Expose or key event are never reached.
Does it draw on your system?
As far as I remember, the example was working when I made the PR, but it was not working anymore tonight. It seems that defining a x::Function value in the graphical context was preventing the drawing of the rectangle on the root window. While there I removed the key press events which are not relevant for the root window, AFAIK. I just tested it now and it worked.
On my side still nothing visible (expose is not received). In order to see the rectangle, I have to add SubwindowMode and force drawing without waiting for event. I guess it depends on the compositing manager or desktop and how it redraws the screen.
conn.send_request(&x::CreateGc {
cid: gc,
drawable: x::Drawable::Window(window),
value_list: &[
x::Gc::Foreground(screen.black_pixel()),
x::Gc::LineWidth(1),
x::Gc::LineStyle(x::LineStyle::OnOffDash),
x::Gc::SubwindowMode(x::SubwindowMode::IncludeInferiors),
],
});
loop {
/* Draw a rectangle on screen using the graphical context */
conn.send_request(&x::PolyRectangle {
drawable: x::Drawable::Window(window),
gc,
rectangles,
});
/* We flush the request */
conn.flush()?;
}
My code is of course bad because of 100% CPU load. I don't know how to properly wait for expose event on the root window. I don't want to take too much of your time digging for this. Can you please only uncomment the relevant example section in Cargo.toml and I'll be OK to merge.
On my computer (I am running i3 wm), the rectangle appears with a graphical context as minimal as:
conn.send_request(&x::CreateGc {
cid: gc,
drawable: x::Drawable::Window(window),
value_list: &[
x::Gc::Foreground(screen.black_pixel()),
x::Gc::LineWidth(1),
x::Gc::LineStyle(x::LineStyle::OnOffDash),
],
});
Could it be related to your wm using a virtual root window? After digging a bit, I found this in the Xlib documentation:
The default GC values are:
Component | Default function | GXcopy plane_mask | All ones foreground | 0 background | 1 line_width | 0 line_style | LineSolid cap_style | CapButt join_style | JoinMiter fill_style | FillSolid fill_rule | EvenOddRule arc_mode | ArcPieSlice tile | Pixmap of unspecified size filled with foreground pixel (that is, client specified pixel if any, else 0) (subsequent changes to foreground do not affect this pixmap) stipple | Pixmap of unspecified size filled with ones ts_x_origin | 0 ts_y_origin | 0 font | \<implementation dependent> subwindow_mode | ClipByChildren graphics_exposures | True clip_x_origin | 0 clip_y_origin | 0 clip_mask | None dash_offset | 0 dashes | 4 (that is, the list [4, 4])
If setting the value x::Gc::SubwindowMode(x::SubwindowMode::IncludeInferiors)
helps, I will add it to the PR, since it doesn't seem to hurt.
Regarding the Expose event, it should be activated by this request:
conn.send_request(&x::ChangeWindowAttributes {
window,
value_list: &[
x::Cw::BackPixel(screen.white_pixel()),
// events that will be waited for
x::Cw::EventMask(x::EventMask::EXPOSURE),
],
});
Does mapping the root window before the event loop (maybe even before the creation of the gc) help?
conn.send_request(&x::MapWindow { window });
I'm using Gnome. I guess this example can't work on such DE.
After messing around, I managed to make the draw_root_window.rs example work with the current API, so I am contributing it back.