diff options
author | Yuqian Yang <crupest@crupest.life> | 2025-09-11 22:19:32 +0800 |
---|---|---|
committer | Yuqian Yang <crupest@crupest.life> | 2025-09-11 22:19:32 +0800 |
commit | 4122cffc95a05ecc2a136ce30bf64f3492812443 (patch) | |
tree | 4f26067f8b7303447dcc1506c45fdc99f8489d72 /src/platform | |
parent | fe6e1686ce484cb0dd9a69f130e82f647c30016f (diff) | |
download | cru-4122cffc95a05ecc2a136ce30bf64f3492812443.tar.gz cru-4122cffc95a05ecc2a136ce30bf64f3492812443.tar.bz2 cru-4122cffc95a05ecc2a136ce30bf64f3492812443.zip |
xcb window style flag.
Diffstat (limited to 'src/platform')
-rw-r--r-- | src/platform/gui/xcb/UiApplication.cpp | 26 | ||||
-rw-r--r-- | src/platform/gui/xcb/Window.cpp | 45 |
2 files changed, 64 insertions, 7 deletions
diff --git a/src/platform/gui/xcb/UiApplication.cpp b/src/platform/gui/xcb/UiApplication.cpp index 462e2fde..2fceac30 100644 --- a/src/platform/gui/xcb/UiApplication.cpp +++ b/src/platform/gui/xcb/UiApplication.cpp @@ -49,6 +49,32 @@ xcb_connection_t *XcbUiApplication::GetXcbConnection() { xcb_screen_t *XcbUiApplication::GetFirstXcbScreen() { return screen_; } +xcb_atom_t XcbUiApplication::GetOrCreateXcbAtom(std::string name) { + auto iter = xcb_atom_.find(name); + if (iter != xcb_atom_.cend()) { + return iter->second; + } + + auto cookie = + xcb_intern_atom(xcb_connection_, false, name.size(), name.data()); + auto reply = xcb_intern_atom_reply(xcb_connection_, cookie, nullptr); + auto atom = reply->atom; + xcb_atom_.emplace(std::move(name), atom); + return atom; +} + +xcb_atom_t XcbUiApplication::GetXcbAtom_NET_WM_WINDOW_TYPE() { + return GetOrCreateXcbAtom("_NET_WM_WINDOW_TYPE"); +} + +xcb_atom_t XcbUiApplication::GetXcbAtom_NET_WM_WINDOW_TYPE_NORMAL() { + return GetOrCreateXcbAtom("_NET_WM_WINDOW_TYPE_NORMAL"); +} + +xcb_atom_t XcbUiApplication::GetXcbAtom_NET_WM_WINDOW_TYPE_UTILITY() { + return GetOrCreateXcbAtom("_NET_WM_WINDOW_TYPE_UTILITY"); +} + int XcbUiApplication::Run() { auto exit_code = event_loop_.Run(); diff --git a/src/platform/gui/xcb/Window.cpp b/src/platform/gui/xcb/Window.cpp index 9dd510e9..9b72789b 100644 --- a/src/platform/gui/xcb/Window.cpp +++ b/src/platform/gui/xcb/Window.cpp @@ -76,13 +76,16 @@ INativeWindow *XcbWindow::GetParent() { return parent_; } void XcbWindow::SetParent(INativeWindow *parent) { parent_ = CheckPlatform<XcbWindow>(parent, GetPlatformIdUtf8()); if (xcb_window_) { - auto real_parent = application_->GetFirstXcbScreen()->root; - if (parent_ && parent_->xcb_window_) { - real_parent = *parent_->xcb_window_; - } - xcb_reparent_window(application_->GetXcbConnection(), *xcb_window_, - real_parent, 0, 0); - // TODO: Maybe restore position? + DoSetParent(*xcb_window_); + } +} + +WindowStyleFlag XcbWindow::GetStyleFlag() { return style_; } + +void XcbWindow::SetStyleFlag(WindowStyleFlag flag) { + style_ = flag; + if (xcb_window_) { + DoSetStyleFlags(*xcb_window_); } } @@ -160,6 +163,9 @@ xcb_window_t XcbWindow::DoCreateWindow() { screen->root_visual, mask, values); current_size_ = Size(width, height); + DoSetStyleFlags(window); + DoSetParent(window); + xcb_visualtype_t *visual_type; for (xcb_depth_iterator_t depth_iter = @@ -361,4 +367,29 @@ std::optional<xcb_window_t> XcbWindow::GetEventWindow( return std::nullopt; } } + +void XcbWindow::DoSetParent(xcb_window_t window) { + auto real_parent = + application_->GetFirstXcbScreen()->root; // init to desktop + if (parent_ && parent_->xcb_window_) { + real_parent = *parent_->xcb_window_; + } + xcb_reparent_window(application_->GetXcbConnection(), window, real_parent, 0, + 0); + // TODO: Maybe restore position? +} + +void XcbWindow::DoSetStyleFlags(xcb_window_t window) { + std::vector<xcb_atom_t> atoms; + if (style_.Has(WindowStyleFlags::NoCaptionAndBorder)) { + atoms = {application_->GetXcbAtom_NET_WM_WINDOW_TYPE_UTILITY()}; + } else { + atoms = {application_->GetXcbAtom_NET_WM_WINDOW_TYPE_NORMAL()}; + } + + xcb_change_property(application_->GetXcbConnection(), XCB_PROP_MODE_REPLACE, + window, application_->GetXcbAtom_NET_WM_WINDOW_TYPE(), + XCB_ATOM_ATOM, 32, atoms.size(), atoms.data()); +} + } // namespace cru::platform::gui::xcb |