【问题标题】:How to set an opaque background for window with depth=32如何为深度= 32的窗口设置不透明背景
【发布时间】:2021-10-09 20:53:28
【问题描述】:

在我的 reparenting 窗口管理器中,我有一些代码来创建框架窗口:

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 以便透明度起作用,请参阅Opacity in a reparenting WM),框架窗口最终也是透明的。那不是我想要的。 (当然,只有在合成器运行时)

如果 background_pixel 是纯色,为什么窗口背景是透明的,我该如何解决这个问题?

【问题讨论】:

    标签: x11 xlib xcb


    【解决方案1】:

    我不再那么肯定我的第一个答案,但我会再试一次。

    你写:

    如果 background_pixel 是纯色,为什么窗口背景是透明的,我该如何解决这个问题?

    “是纯色”究竟是什么意思?这种纯色从何而来?尝试使用 0xffffffff 作为这个值,看看这是否能正常工作。这在任何正常的 X11 服务器上都应该是“完全不透明的白色”。

    既然您正在查看 Awesome 的源代码,请查看它的 color.c。一个 alpha 组件被固定在 X11 的设计上。因此,“所有 X11”假装不存在透明度。 color.c 中有一条评论是关于它如何猜测 alpha 组件的放置位置。

    我希望大多数 X11 服务器使用像 0xAARRGGBB 这样的像素值,例如0x80ff0000 将是半透明的红色。但这比color.c 所做的更糟糕。

    【讨论】:

    • 完美,看起来我只是忘记了颜色中的 alpha。
    • 我剩下的唯一问题是在 depth=32 的窗口上没有渲染阴影,嗯。
    • 我不想混淆问题,所以我创建了另一个(感谢您的帮助!)stackoverflow.com/questions/69517233/…
    【解决方案2】:

    尝试删除这段代码:

            self.conn
                .change_property32(
                    xproto::PropMode::REPLACE,
                    ev.window,
                    self.net_atoms[ewmh::Net::WMWindowOpacity as usize],
                    xproto::AtomEnum::CARDINAL,
                    &[1],
                )?
                .check()?;
    

    由于您已经在查看 AwesomeWM 代码(您在另一个答案中这么说),这里是它的一段代码(对此答案略微简化;我只删除了一些 ifs):

    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 不透明百分比的百分比值。对我来说听起来“几乎完全透明”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-23
      • 1970-01-01
      • 2013-04-21
      • 2014-05-29
      • 2013-11-08
      • 2011-04-23
      • 1970-01-01
      相关资源
      最近更新 更多