如何为深度为 32 的 window 设置不透明背景
How to set an opaque background for window with depth=32
在我的重新设置 window 管理器中,我有一些代码可以创建框架 window:
let screen = &self.conn.setup().roots[self.scrno];
let geom = self.conn.get_geometry(ev.window)?.reply()?;
let attr = self.conn.get_window_attributes(ev.window)?.reply()?;
let frame_win = self.conn.generate_id()?;
let frame_cmap = self.conn.generate_id()?;
self.conn.create_colormap(
xproto::ColormapAlloc::NONE,
frame_cmap,
ev.window,
attr.visual,
)?;
self.conn
.change_property32(
xproto::PropMode::REPLACE,
ev.window,
self.net_atoms[ewmh::Net::WMWindowOpacity as usize],
xproto::AtomEnum::CARDINAL,
&[1],
)?
.check()?;
let win_aux = xproto::CreateWindowAux::new()
.event_mask(
xproto::EventMask::EXPOSURE
| xproto::EventMask::SUBSTRUCTURE_REDIRECT
| xproto::EventMask::SUBSTRUCTURE_NOTIFY
| xproto::EventMask::BUTTON_PRESS
| xproto::EventMask::BUTTON_RELEASE
| xproto::EventMask::POINTER_MOTION
| xproto::EventMask::ENTER_WINDOW
| xproto::EventMask::PROPERTY_CHANGE,
)
.background_pixel(self.config.background_pixel)
.border_pixel(self.config.border_pixel)
.colormap(frame_cmap);
self.conn.create_window(
geom.depth,
frame_win,
screen.root,
geom.x,
geom.y,
geom.width,
geom.height + self.config.title_height as u16,
self.config.border_width as u16,
xproto::WindowClass::INPUT_OUTPUT,
attr.visual,
&win_aux,
)?;
我 运行 遇到的问题是当 attr.depth 是 32 时(我尊重它而不是 COPY_FROM_PARENT 以便透明度起作用,参见 ),框架window 也最终变得透明。那不是我想要的。 (当然,只有当合成器是运行ning时)
如果 background_pixel 是纯色,为什么 window 背景是透明的,我该如何解决这个问题?
尝试删除这段代码:
self.conn
.change_property32(
xproto::PropMode::REPLACE,
ev.window,
self.net_atoms[ewmh::Net::WMWindowOpacity as usize],
xproto::AtomEnum::CARDINAL,
&[1],
)?
.check()?;
由于您已经在查看 AwesomeWM 代码(您在另一个答案中这么说),这里是它的一段代码(针对这个答案稍微简化了;我只删除了一些 if
s):
void
xwindow_set_opacity(xcb_window_t win, double opacity)
{
uint32_t real_opacity = opacity * 0xffffffff;
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, win,
_NET_WM_WINDOW_OPACITY, XCB_ATOM_CARDINAL, 32, 1L, &real_opacity);
}
您可能会从此代码中猜到,“完全透明”的值为零,“完全不透明”的值为 0xffffffff
。您将此 属性 设置为值 1,对应于约 .000000023
百分比不透明的百分比值。对我来说听起来“几乎完全透明”。
我不再那么确定我的第一个答案,但我会再试一次。
你写:
Why is the window background transparent if background_pixel is a solid color, and how do I remedy the issue?
“是纯色”到底是什么意思,这种纯色从何而来?尝试使用 0xffffffff
作为该值,看看是否可以正常工作。在任何正常的 X11 服务器上,这应该是“完全不透明的白色”。
既然你在看 Awesome 的源代码,那就看看它的 color.c
。一个 alpha 组件被固定在 X11 的设计上。因此,“所有 X11”假装透明度不存在。 color.c
中有一条关于它如何猜测放置 alpha 组件的位置的评论。
我希望大多数 X11 服务器使用像 0xAARRGGBB
这样的像素值,例如0x80ff0000
将是半透明的红色。但这是一个比 color.c
更糟糕的猜测。
在我的重新设置 window 管理器中,我有一些代码可以创建框架 window:
let screen = &self.conn.setup().roots[self.scrno];
let geom = self.conn.get_geometry(ev.window)?.reply()?;
let attr = self.conn.get_window_attributes(ev.window)?.reply()?;
let frame_win = self.conn.generate_id()?;
let frame_cmap = self.conn.generate_id()?;
self.conn.create_colormap(
xproto::ColormapAlloc::NONE,
frame_cmap,
ev.window,
attr.visual,
)?;
self.conn
.change_property32(
xproto::PropMode::REPLACE,
ev.window,
self.net_atoms[ewmh::Net::WMWindowOpacity as usize],
xproto::AtomEnum::CARDINAL,
&[1],
)?
.check()?;
let win_aux = xproto::CreateWindowAux::new()
.event_mask(
xproto::EventMask::EXPOSURE
| xproto::EventMask::SUBSTRUCTURE_REDIRECT
| xproto::EventMask::SUBSTRUCTURE_NOTIFY
| xproto::EventMask::BUTTON_PRESS
| xproto::EventMask::BUTTON_RELEASE
| xproto::EventMask::POINTER_MOTION
| xproto::EventMask::ENTER_WINDOW
| xproto::EventMask::PROPERTY_CHANGE,
)
.background_pixel(self.config.background_pixel)
.border_pixel(self.config.border_pixel)
.colormap(frame_cmap);
self.conn.create_window(
geom.depth,
frame_win,
screen.root,
geom.x,
geom.y,
geom.width,
geom.height + self.config.title_height as u16,
self.config.border_width as u16,
xproto::WindowClass::INPUT_OUTPUT,
attr.visual,
&win_aux,
)?;
我 运行 遇到的问题是当 attr.depth 是 32 时(我尊重它而不是 COPY_FROM_PARENT 以便透明度起作用,参见
如果 background_pixel 是纯色,为什么 window 背景是透明的,我该如何解决这个问题?
尝试删除这段代码:
self.conn
.change_property32(
xproto::PropMode::REPLACE,
ev.window,
self.net_atoms[ewmh::Net::WMWindowOpacity as usize],
xproto::AtomEnum::CARDINAL,
&[1],
)?
.check()?;
由于您已经在查看 AwesomeWM 代码(您在另一个答案中这么说),这里是它的一段代码(针对这个答案稍微简化了;我只删除了一些 if
s):
void
xwindow_set_opacity(xcb_window_t win, double opacity)
{
uint32_t real_opacity = opacity * 0xffffffff;
xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, win,
_NET_WM_WINDOW_OPACITY, XCB_ATOM_CARDINAL, 32, 1L, &real_opacity);
}
您可能会从此代码中猜到,“完全透明”的值为零,“完全不透明”的值为 0xffffffff
。您将此 属性 设置为值 1,对应于约 .000000023
百分比不透明的百分比值。对我来说听起来“几乎完全透明”。
我不再那么确定我的第一个答案,但我会再试一次。
你写:
Why is the window background transparent if background_pixel is a solid color, and how do I remedy the issue?
“是纯色”到底是什么意思,这种纯色从何而来?尝试使用 0xffffffff
作为该值,看看是否可以正常工作。在任何正常的 X11 服务器上,这应该是“完全不透明的白色”。
既然你在看 Awesome 的源代码,那就看看它的 color.c
。一个 alpha 组件被固定在 X11 的设计上。因此,“所有 X11”假装透明度不存在。 color.c
中有一条关于它如何猜测放置 alpha 组件的位置的评论。
我希望大多数 X11 服务器使用像 0xAARRGGBB
这样的像素值,例如0x80ff0000
将是半透明的红色。但这是一个比 color.c
更糟糕的猜测。