Compare commits

...

26 Commits

Author SHA1 Message Date
Mihai Fufezan
927e1b5a8f flake.lock: update 2025-02-23 14:19:45 +02:00
Vaxry
882f7ad7d2 version: bump to 0.47.2 2025-02-02 00:47:17 +00:00
Vaxry
3822673c05 desktop: move popups to UPs and fix missing subsurface resource
fixes #9283
2025-02-02 00:47:17 +00:00
Vaxry
bdbfa93371 popup: take xdg geometry into account in input calcs
fixes #9023
2025-02-02 00:47:17 +00:00
Vaxry
f827690983 desktop: move popup and subsurface ctors to factories
makes sure m_pSelf is set before we do anything like possibly adding children

fixes #9275

supersedes #9276
2025-02-02 00:47:17 +00:00
Maximilian Seidler
ff8b5b70fa animation: don't immediately disconnect active vars during tick (#9272) 2025-02-02 00:47:17 +00:00
nyx
3236566939 xwayland: correct pointer coordinate mismatch in X11 windows (#9259)
refactor(xwayland): add back comments
2025-02-02 00:47:17 +00:00
Mihai Fufezan
dd64757602 configWatcher: watch both symlinks and canonical paths (#9219) 2025-02-02 00:47:16 +00:00
Brayden Zee
047ea02820 desktop: fix segfault when destroying a partially create layer surface (#9247) 2025-02-02 00:45:37 +00:00
nyx
c8eec1916d xwayland: prevent invalid window configurations for X11 apps (#9253)
* fix(xwayland): prevent invalid window configurations for X11 apps

* refact(xwayland): remove unneeded line
2025-02-02 00:45:37 +00:00
Ikalco
c062fd2985 monitor: preferred mode now tries first 3 modes if preferred fails before erroring (#9246) 2025-02-02 00:45:37 +00:00
nyx
f04d94aa13 xwayland: handle window coords correctly (#9238) 2025-02-02 00:45:37 +00:00
Vaxry
75dff7205f version: bump to 0.47.1 2025-01-29 23:19:39 +00:00
Vaxry
48817b97f5 subsurface: fix invalid parent typo
fixes #9224
2025-01-29 23:19:20 +00:00
Vaxry
664da71d10 popup: stop refocusing at unmap
fixes #9018
2025-01-29 23:19:20 +00:00
Vaxry
a285722bc8 monitor: round refresh rates in sorting modes
fixes #9209
2025-01-29 23:19:20 +00:00
vaxerski
bdee557d15 config/hyprctl: fix keyword not updating autoreload
ref #9139
2025-01-29 23:19:20 +00:00
vaxerski
901271fa8b pass/rect: fix bounding / opaque regions
fixes #9212
2025-01-29 23:19:20 +00:00
nyx
fa61042288 renderer: calculate UV using both pixel and monitor dimensions (#9210) 2025-01-29 23:19:20 +00:00
Vaxry
778508e39e presentation: log a fixme when there is a feedback leak
ref #8087
2025-01-29 23:19:20 +00:00
Tom Englund
762bbf5857 configmgr: properly free glob memory
globfree is only freeing internally allocated resources, so also call
free the on glob_t memory we allocated.
2025-01-29 23:19:20 +00:00
Tom Englund
c68653d7c4 ikeyboard: free xkbSymState in clearManuallyAllocd
asan reported a leak on xkbSymState on destruction, because it wasnt
beeing unrefed, was only being unrefed on calls to updateXKBTranslationState.
2025-01-29 23:19:20 +00:00
DDoSolitary
56540f5bd8 xwayland: respect window size set by configure requests (#9190) 2025-01-29 23:19:20 +00:00
Jan Beich
017f322532 deps: add libinotify-kqueue on BSDs after 8dd2cd41fb (#9197)
src/config/ConfigWatcher.cpp:2:10: fatal error: 'sys/inotify.h' file not found
    2 | #include <sys/inotify.h>
      |          ^~~~~~~~~~~~~~~
2025-01-29 23:19:20 +00:00
DDoSolitary
a7d7df5c4b xwayland: send synthetic configure events (#9193) 2025-01-29 23:19:20 +00:00
Vaxry
0d06f287d0 core: fix clang-format 2025-01-29 23:19:20 +00:00
28 changed files with 217 additions and 127 deletions

View File

@@ -104,7 +104,7 @@ find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION})
pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.4.5) pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.4.5)
pkg_check_modules(hyprlang_dep REQUIRED IMPORTED_TARGET hyprlang>=0.3.2) pkg_check_modules(hyprlang_dep REQUIRED IMPORTED_TARGET hyprlang>=0.3.2)
pkg_check_modules(hyprcursor_dep REQUIRED IMPORTED_TARGET hyprcursor>=0.1.7) pkg_check_modules(hyprcursor_dep REQUIRED IMPORTED_TARGET hyprcursor>=0.1.7)
pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.4.0) pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.5.0)
pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1) pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1)
add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}") add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}")
@@ -197,6 +197,12 @@ if(NOT HAS_TIMERFD AND epoll_FOUND)
target_link_libraries(Hyprland PkgConfig::epoll) target_link_libraries(Hyprland PkgConfig::epoll)
endif() endif()
check_include_file("sys/inotify.h" HAS_INOTIFY)
pkg_check_modules(inotify IMPORTED_TARGET libinotify)
if(NOT HAS_INOTIFY AND inotify_FOUND)
target_link_libraries(Hyprland PkgConfig::inotify)
endif()
if(LEGACY_RENDERER) if(LEGACY_RENDERER)
message(STATUS "Using the legacy GLES2 renderer!") message(STATUS "Using the legacy GLES2 renderer!")
add_compile_definitions(LEGACY_RENDERER) add_compile_definitions(LEGACY_RENDERER)

View File

@@ -1 +1 @@
0.47.0 0.47.2

6
flake.lock generated
View File

@@ -287,11 +287,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1737725508, "lastModified": 1739891528,
"narHash": "sha256-jGmcPc6y/prg/4A8KGYqJ27nSPaProCMiFadaxNAKvA=", "narHash": "sha256-h8HOCZ/rw2Buzku+GKF77VXxrGjCSOQkLhptiEKMYg0=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprutils", "repo": "hyprutils",
"rev": "fb0c2d1de3d1ef7396d19c18ac09e12bd956929e", "rev": "61a5382f4b1ab578064d470b1b3d3f0df396b8ba",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -58,6 +58,7 @@ endif
backtrace_dep = cpp_compiler.find_library('execinfo', required: false) backtrace_dep = cpp_compiler.find_library('execinfo', required: false)
epoll_dep = dependency('epoll-shim', required: false) # timerfd on BSDs epoll_dep = dependency('epoll-shim', required: false) # timerfd on BSDs
inotify_dep = dependency('libinotify', required: false) # inotify on BSDs
re2 = dependency('re2', required: true) re2 = dependency('re2', required: true)

View File

@@ -912,12 +912,16 @@ std::optional<std::string> CConfigManager::resetHLConfig() {
return RET; return RET;
} }
void CConfigManager::updateWatcher() {
static const auto PDISABLEAUTORELOAD = CConfigValue<Hyprlang::INT>("misc:disable_autoreload");
g_pConfigWatcher->setWatchList(*PDISABLEAUTORELOAD ? std::vector<std::string>{} : m_configPaths);
}
void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) { void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
static const auto PENABLEEXPLICIT = CConfigValue<Hyprlang::INT>("render:explicit_sync"); static const auto PENABLEEXPLICIT = CConfigValue<Hyprlang::INT>("render:explicit_sync");
static const auto PDISABLEAUTORELOAD = CConfigValue<Hyprlang::INT>("misc:disable_autoreload");
static int prevEnabledExplicit = *PENABLEEXPLICIT; static int prevEnabledExplicit = *PENABLEEXPLICIT;
g_pConfigWatcher->setWatchList(*PDISABLEAUTORELOAD ? std::vector<std::string>{} : m_configPaths); updateWatcher();
for (auto const& w : g_pCompositor->m_vWindows) { for (auto const& w : g_pCompositor->m_vWindows) {
w->uncacheWindowDecos(); w->uncacheWindowDecos();
@@ -2690,8 +2694,14 @@ std::optional<std::string> CConfigManager::handleSource(const std::string& comma
Debug::log(ERR, "source= path garbage"); Debug::log(ERR, "source= path garbage");
return "source= path " + rawpath + " bogus!"; return "source= path " + rawpath + " bogus!";
} }
std::unique_ptr<glob_t, void (*)(glob_t*)> glob_buf{new glob_t, [](glob_t* g) { globfree(g); }};
memset(glob_buf.get(), 0, sizeof(glob_t)); std::unique_ptr<glob_t, void (*)(glob_t*)> glob_buf{static_cast<glob_t*>(calloc(1, sizeof(glob_t))), // allocate and zero-initialize
[](glob_t* g) {
if (g) {
globfree(g); // free internal resources allocated by glob()
free(g); // free the memory for the glob_t structure
}
}};
if (auto r = glob(absolutePath(rawpath, configCurrentPath).c_str(), GLOB_TILDE, nullptr, glob_buf.get()); r != 0) { if (auto r = glob(absolutePath(rawpath, configCurrentPath).c_str(), GLOB_TILDE, nullptr, glob_buf.get()); r != 0) {
std::string err = std::format("source= globbing error: {}", r == GLOB_NOMATCH ? "found no match" : GLOB_ABORTED ? "read error" : "out of memory"); std::string err = std::format("source= globbing error: {}", r == GLOB_NOMATCH ? "found no match" : GLOB_ABORTED ? "read error" : "out of memory");

View File

@@ -190,6 +190,7 @@ class CConfigManager {
void ensureVRR(PHLMONITOR pMonitor = nullptr); void ensureVRR(PHLMONITOR pMonitor = nullptr);
bool shouldUseSoftwareCursors(); bool shouldUseSoftwareCursors();
void updateWatcher();
std::string parseKeyword(const std::string&, const std::string&); std::string parseKeyword(const std::string&, const std::string&);

View File

@@ -4,6 +4,7 @@
#include <ranges> #include <ranges>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <filesystem>
CConfigWatcher::CConfigWatcher() : m_inotifyFd(inotify_init()) { CConfigWatcher::CConfigWatcher() : m_inotifyFd(inotify_init()) {
if (m_inotifyFd < 0) { if (m_inotifyFd < 0) {
@@ -46,9 +47,19 @@ void CConfigWatcher::setWatchList(const std::vector<std::string>& paths) {
// add new paths // add new paths
for (const auto& path : paths) { for (const auto& path : paths) {
m_watches.emplace_back(SInotifyWatch{ m_watches.emplace_back(SInotifyWatch{
.wd = inotify_add_watch(m_inotifyFd, path.c_str(), IN_MODIFY), .wd = inotify_add_watch(m_inotifyFd, path.c_str(), IN_MODIFY | IN_DONT_FOLLOW),
.file = path, .file = path,
}); });
std::error_code ec, ec2;
const auto CANONICAL = std::filesystem::canonical(path, ec);
const auto IS_SYMLINK = std::filesystem::is_symlink(path, ec2);
if (!ec && !ec2 && IS_SYMLINK) {
m_watches.emplace_back(SInotifyWatch{
.wd = inotify_add_watch(m_inotifyFd, CANONICAL.c_str(), IN_MODIFY),
.file = path,
});
}
} }
} }

View File

@@ -1100,6 +1100,9 @@ static std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in)
} }
} }
if (COMMAND.contains("misc:disable_autoreload"))
g_pConfigManager->updateWatcher();
// decorations will probably need a repaint // decorations will probably need a repaint
if (COMMAND.contains("decoration:") || COMMAND.contains("border") || COMMAND == "workspace" || COMMAND.contains("zoom_factor") || COMMAND == "source" || if (COMMAND.contains("decoration:") || COMMAND.contains("border") || COMMAND == "workspace" || COMMAND.contains("zoom_factor") || COMMAND == "source" ||
COMMAND.starts_with("windowrule")) { COMMAND.starts_with("windowrule")) {

View File

@@ -31,10 +31,9 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
pLS->szNamespace = resource->layerNamespace; pLS->szNamespace = resource->layerNamespace;
pLS->layer = resource->current.layer; pLS->layer = resource->current.layer;
pLS->popupHead = makeUnique<CPopup>(pLS); pLS->popupHead = CPopup::create(pLS);
pLS->popupHead->m_pSelf = pLS->popupHead; pLS->monitor = pMonitor;
pLS->monitor = pMonitor;
pMonitor->m_aLayerSurfaceLayers[resource->current.layer].emplace_back(pLS); pMonitor->m_aLayerSurfaceLayers[resource->current.layer].emplace_back(pLS);
pLS->forceBlur = g_pConfigManager->shouldBlurLS(pLS->szNamespace); pLS->forceBlur = g_pConfigManager->shouldBlurLS(pLS->szNamespace);
@@ -98,7 +97,8 @@ void CLayerSurface::onDestroy() {
onUnmap(); onUnmap();
} else { } else {
Debug::log(LOG, "Removing LayerSurface that wasn't mapped."); Debug::log(LOG, "Removing LayerSurface that wasn't mapped.");
alpha->setValueAndWarp(0.f); if (alpha)
alpha->setValueAndWarp(0.f);
fadingOut = true; fadingOut = true;
g_pCompositor->addToFadingOutSafe(self.lock()); g_pCompositor->addToFadingOutSafe(self.lock());
} }

View File

@@ -12,23 +12,37 @@
#include "../render/OpenGL.hpp" #include "../render/OpenGL.hpp"
#include <ranges> #include <ranges>
CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) { UP<CPopup> CPopup::create(PHLWINDOW pOwner) {
initAllSignals(); auto popup = UP<CPopup>(new CPopup());
popup->m_pWindowOwner = pOwner;
popup->m_pSelf = popup;
popup->initAllSignals();
return popup;
} }
CPopup::CPopup(PHLLS pOwner) : m_pLayerOwner(pOwner) { UP<CPopup> CPopup::create(PHLLS pOwner) {
initAllSignals(); auto popup = UP<CPopup>(new CPopup());
popup->m_pLayerOwner = pOwner;
popup->m_pSelf = popup;
popup->initAllSignals();
return popup;
} }
CPopup::CPopup(SP<CXDGPopupResource> popup, WP<CPopup> pOwner) : UP<CPopup> CPopup::create(SP<CXDGPopupResource> resource, WP<CPopup> pOwner) {
m_pWindowOwner(pOwner->m_pWindowOwner), m_pLayerOwner(pOwner->m_pLayerOwner), m_pParent(pOwner), m_pResource(popup) { auto popup = UP<CPopup>(new CPopup());
m_pWLSurface = CWLSurface::create(); popup->m_pResource = resource;
m_pWLSurface->assign(popup->surface->surface.lock(), this); popup->m_pWindowOwner = pOwner->m_pWindowOwner;
popup->m_pLayerOwner = pOwner->m_pLayerOwner;
popup->m_pParent = pOwner;
popup->m_pSelf = popup;
popup->m_pWLSurface = CWLSurface::create();
popup->m_pWLSurface->assign(resource->surface->surface.lock(), popup.get());
m_vLastSize = popup->surface->current.geometry.size(); popup->m_vLastSize = resource->surface->current.geometry.size();
reposition(); popup->reposition();
initAllSignals(); popup->initAllSignals();
return popup;
} }
CPopup::~CPopup() { CPopup::~CPopup() {
@@ -59,7 +73,7 @@ void CPopup::initAllSignals() {
} }
void CPopup::onNewPopup(SP<CXDGPopupResource> popup) { void CPopup::onNewPopup(SP<CXDGPopupResource> popup) {
const auto& POPUP = m_vChildren.emplace_back(makeShared<CPopup>(popup, m_pSelf)); const auto& POPUP = m_vChildren.emplace_back(CPopup::create(popup, m_pSelf));
POPUP->m_pSelf = POPUP; POPUP->m_pSelf = POPUP;
Debug::log(LOG, "New popup at {:x}", (uintptr_t)POPUP); Debug::log(LOG, "New popup at {:x}", (uintptr_t)POPUP);
} }
@@ -91,8 +105,7 @@ void CPopup::onMap() {
g_pInputManager->simulateMouseMovement(); g_pInputManager->simulateMouseMovement();
m_pSubsurfaceHead = makeUnique<CSubsurface>(m_pSelf); m_pSubsurfaceHead = CSubsurface::create(m_pSelf);
m_pSubsurfaceHead->m_pSelf = m_pSubsurfaceHead;
//unconstrain(); //unconstrain();
sendScale(); sendScale();
@@ -138,10 +151,11 @@ void CPopup::onUnmap() {
}, },
nullptr); nullptr);
const bool WASLASTFOCUS = g_pSeatManager->state.keyboardFocus == m_pWLSurface->resource() || g_pSeatManager->state.pointerFocus == m_pWLSurface->resource(); // TODO: probably refocus, but without a motion event?
// const bool WASLASTFOCUS = g_pSeatManager->state.keyboardFocus == m_pWLSurface->resource() || g_pSeatManager->state.pointerFocus == m_pWLSurface->resource();
if (WASLASTFOCUS) // if (WASLASTFOCUS)
g_pInputManager->simulateMouseMovement(); // g_pInputManager->simulateMouseMovement();
} }
void CPopup::onCommit(bool ignoreSiblings) { void CPopup::onCommit(bool ignoreSiblings) {
@@ -268,7 +282,8 @@ void CPopup::recheckTree() {
} }
void CPopup::recheckChildrenRecursive() { void CPopup::recheckChildrenRecursive() {
auto cpy = m_vChildren; std::vector<WP<CPopup>> cpy;
std::ranges::for_each(m_vChildren, [&cpy](const auto& el) { cpy.emplace_back(el); });
for (auto const& c : cpy) { for (auto const& c : cpy) {
c->onCommit(true); c->onCommit(true);
c->recheckChildrenRecursive(); c->recheckChildrenRecursive();
@@ -325,22 +340,24 @@ void CPopup::breadthfirst(std::function<void(WP<CPopup>, void*)> fn, void* data)
WP<CPopup> CPopup::at(const Vector2D& globalCoords, bool allowsInput) { WP<CPopup> CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
std::vector<WP<CPopup>> popups; std::vector<WP<CPopup>> popups;
breadthfirst([](WP<CPopup> popup, void* data) { ((std::vector<WP<CPopup>>*)data)->push_back(popup); }, &popups); breadthfirst([&popups](WP<CPopup> popup, void* data) { popups.push_back(popup); }, &popups);
for (auto const& p : popups | std::views::reverse) { for (auto const& p : popups | std::views::reverse) {
if (!p->m_pResource || !p->m_bMapped) if (!p->m_pResource || !p->m_bMapped)
continue; continue;
if (!allowsInput) { if (!allowsInput) {
const Vector2D offset = p->m_pResource ? (p->size() - p->m_pResource->geometry.size()) / 2.F : Vector2D{}; const Vector2D offset =
const Vector2D size = p->m_pResource ? p->m_pResource->geometry.size() : p->size(); p->m_pResource && p->m_pResource->surface ? (p->size() - p->m_pResource->geometry.size()) / 2.F - p->m_pResource->surface->current.geometry.pos() : Vector2D{};
const Vector2D size = p->m_pResource ? p->m_pResource->geometry.size() : p->size();
const auto BOX = CBox{p->coordsGlobal() + offset, size}; const auto BOX = CBox{p->coordsGlobal() + offset, size};
if (BOX.containsPoint(globalCoords)) if (BOX.containsPoint(globalCoords))
return p; return p;
} else { } else {
const Vector2D offset = p->m_pResource ? (p->size() - p->m_pResource->geometry.size()) / 2.F : Vector2D{}; const Vector2D offset =
const auto REGION = p->m_pResource && p->m_pResource->surface ? (p->size() - p->m_pResource->geometry.size()) / 2.F - p->m_pResource->surface->current.geometry.pos() : Vector2D{};
const auto REGION =
CRegion{p->m_pWLSurface->resource()->current.input}.intersect(CBox{{}, p->m_pWLSurface->resource()->current.size}).translate(p->coordsGlobal() + offset); CRegion{p->m_pWLSurface->resource()->current.input}.intersect(CBox{{}, p->m_pWLSurface->resource()->current.size}).translate(p->coordsGlobal() + offset);
if (REGION.containsPoint(globalCoords)) if (REGION.containsPoint(globalCoords))
return p; return p;

View File

@@ -10,11 +10,11 @@ class CXDGPopupResource;
class CPopup { class CPopup {
public: public:
// dummy head nodes // dummy head nodes
CPopup(PHLWINDOW pOwner); static UP<CPopup> create(PHLWINDOW pOwner);
CPopup(PHLLS pOwner); static UP<CPopup> create(PHLLS pOwner);
// real nodes // real nodes
CPopup(SP<CXDGPopupResource> popup, WP<CPopup> pOwner); static UP<CPopup> create(SP<CXDGPopupResource> popup, WP<CPopup> pOwner);
~CPopup(); ~CPopup();
@@ -45,6 +45,8 @@ class CPopup {
bool m_bMapped = false; bool m_bMapped = false;
private: private:
CPopup() = default;
// T1 owners, each popup has to have one of these // T1 owners, each popup has to have one of these
PHLWINDOWREF m_pWindowOwner; PHLWINDOWREF m_pWindowOwner;
PHLLSREF m_pLayerOwner; PHLLSREF m_pLayerOwner;
@@ -62,7 +64,7 @@ class CPopup {
bool m_bInert = false; bool m_bInert = false;
// //
std::vector<SP<CPopup>> m_vChildren; std::vector<UP<CPopup>> m_vChildren;
UP<CSubsurface> m_pSubsurfaceHead; UP<CSubsurface> m_pSubsurfaceHead;
struct { struct {

View File

@@ -7,28 +7,47 @@
#include "../render/Renderer.hpp" #include "../render/Renderer.hpp"
#include "../managers/input/InputManager.hpp" #include "../managers/input/InputManager.hpp"
CSubsurface::CSubsurface(PHLWINDOW pOwner) : m_pWindowParent(pOwner) { UP<CSubsurface> CSubsurface::create(PHLWINDOW pOwner) {
initSignals(); auto subsurface = UP<CSubsurface>(new CSubsurface());
initExistingSubsurfaces(pOwner->m_pWLSurface->resource()); subsurface->m_pWindowParent = pOwner;
subsurface->m_pSelf = subsurface;
subsurface->initSignals();
subsurface->initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
return subsurface;
} }
CSubsurface::CSubsurface(WP<CPopup> pOwner) : m_pPopupParent(pOwner) { UP<CSubsurface> CSubsurface::create(WP<CPopup> pOwner) {
initSignals(); auto subsurface = UP<CSubsurface>(new CSubsurface());
initExistingSubsurfaces(pOwner->m_pWLSurface->resource()); subsurface->m_pPopupParent = pOwner;
subsurface->m_pSelf = subsurface;
subsurface->initSignals();
subsurface->initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
return subsurface;
} }
CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) { UP<CSubsurface> CSubsurface::create(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner) {
m_pWLSurface = CWLSurface::create(); auto subsurface = UP<CSubsurface>(new CSubsurface());
m_pWLSurface->assign(pSubsurface->surface.lock(), this); subsurface->m_pWindowParent = pOwner;
initSignals(); subsurface->m_pSubsurface = pSubsurface;
initExistingSubsurfaces(pSubsurface->surface.lock()); subsurface->m_pSelf = subsurface;
subsurface->m_pWLSurface = CWLSurface::create();
subsurface->m_pWLSurface->assign(pSubsurface->surface.lock(), subsurface.get());
subsurface->initSignals();
subsurface->initExistingSubsurfaces(pSubsurface->surface.lock());
return subsurface;
} }
CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, WP<CPopup> pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) { UP<CSubsurface> CSubsurface::create(SP<CWLSubsurfaceResource> pSubsurface, WP<CPopup> pOwner) {
m_pWLSurface = CWLSurface::create(); auto subsurface = UP<CSubsurface>(new CSubsurface());
m_pWLSurface->assign(pSubsurface->surface.lock(), this); subsurface->m_pPopupParent = pOwner;
initSignals(); subsurface->m_pSubsurface = pSubsurface;
initExistingSubsurfaces(pSubsurface->surface.lock()); subsurface->m_pSelf = subsurface;
subsurface->m_pWLSurface = CWLSurface::create();
subsurface->m_pWLSurface->assign(pSubsurface->surface.lock(), subsurface.get());
subsurface->initSignals();
subsurface->initExistingSubsurfaces(pSubsurface->surface.lock());
return subsurface;
} }
CSubsurface::~CSubsurface() { CSubsurface::~CSubsurface() {
@@ -135,15 +154,15 @@ void CSubsurface::onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface) {
WP<CSubsurface> PSUBSURFACE; WP<CSubsurface> PSUBSURFACE;
if (!m_pWindowParent.expired()) if (!m_pWindowParent.expired())
PSUBSURFACE = m_vChildren.emplace_back(makeUnique<CSubsurface>(pSubsurface, m_pWindowParent.lock())); PSUBSURFACE = m_vChildren.emplace_back(CSubsurface::create(pSubsurface, m_pWindowParent.lock()));
else if (m_pPopupParent) else if (m_pPopupParent)
PSUBSURFACE = m_vChildren.emplace_back(makeUnique<CSubsurface>(pSubsurface, m_pPopupParent)); PSUBSURFACE = m_vChildren.emplace_back(CSubsurface::create(pSubsurface, m_pPopupParent));
PSUBSURFACE->m_pSelf = PSUBSURFACE; PSUBSURFACE->m_pSelf = PSUBSURFACE;
ASSERT(PSUBSURFACE); ASSERT(PSUBSURFACE);
PSUBSURFACE->m_pParent = PSUBSURFACE; PSUBSURFACE->m_pParent = m_pSelf;
} }
void CSubsurface::onMap() { void CSubsurface::onMap() {

View File

@@ -10,12 +10,12 @@ class CWLSubsurfaceResource;
class CSubsurface { class CSubsurface {
public: public:
// root dummy nodes // root dummy nodes
CSubsurface(PHLWINDOW pOwner); static UP<CSubsurface> create(PHLWINDOW pOwner);
CSubsurface(WP<CPopup> pOwner); static UP<CSubsurface> create(WP<CPopup> pOwner);
// real nodes // real nodes
CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner); static UP<CSubsurface> create(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner);
CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, WP<CPopup> pOwner); static UP<CSubsurface> create(SP<CWLSubsurfaceResource> pSubsurface, WP<CPopup> pOwner);
~CSubsurface(); ~CSubsurface();
@@ -37,6 +37,8 @@ class CSubsurface {
WP<CSubsurface> m_pSelf; WP<CSubsurface> m_pSelf;
private: private:
CSubsurface() = default;
struct { struct {
CHyprSignalListener destroySubsurface; CHyprSignalListener destroySubsurface;
CHyprSignalListener commitSubsurface; CHyprSignalListener commitSubsurface;

View File

@@ -571,10 +571,8 @@ void CWindow::onMap() {
if (m_bIsX11) if (m_bIsX11)
return; return;
m_pSubsurfaceHead = makeUnique<CSubsurface>(m_pSelf.lock()); m_pSubsurfaceHead = CSubsurface::create(m_pSelf.lock());
m_pSubsurfaceHead->m_pSelf = m_pSubsurfaceHead; m_pPopupHead = CPopup::create(m_pSelf.lock());
m_pPopupHead = makeUnique<CPopup>(m_pSelf.lock());
m_pPopupHead->m_pSelf = m_pPopupHead;
} }
void CWindow::onBorderAngleAnimEnd(WP<CBaseAnimatedVariable> pav) { void CWindow::onBorderAngleAnimEnd(WP<CBaseAnimatedVariable> pav) {
@@ -1697,18 +1695,18 @@ Vector2D CWindow::requestedMaxSize() {
void CWindow::sendWindowSize(Vector2D size, bool force, std::optional<Vector2D> overridePos) { void CWindow::sendWindowSize(Vector2D size, bool force, std::optional<Vector2D> overridePos) {
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling"); static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
const auto PMONITOR = m_pMonitor.lock();
const auto PMONITOR = m_pMonitor.lock(); size = size.clamp(Vector2D{1, 1}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
size = size.clamp(Vector2D{0, 0}, Vector2D{std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity()});
// calculate pos // calculate pos
// TODO: this should be decoupled from setWindowSize IMO // TODO: this should be decoupled from setWindowSize IMO
Vector2D windowPos = overridePos.value_or(m_vRealPosition->goal()); Vector2D windowPos = overridePos.value_or(m_vRealPosition->goal());
if (m_bIsX11) { if (m_bIsX11 && PMONITOR) {
if (const auto XWAYLANDPOS = g_pXWaylandManager->waylandToXWaylandCoords(windowPos); XWAYLANDPOS != Vector2D{}) windowPos = g_pXWaylandManager->waylandToXWaylandCoords(windowPos);
windowPos = XWAYLANDPOS; if (*PXWLFORCESCALEZERO)
size *= PMONITOR->scale;
} }
if (!force && m_vPendingReportedSize == size && (windowPos == m_vReportedPosition || !m_bIsX11)) if (!force && m_vPendingReportedSize == size && (windowPos == m_vReportedPosition || !m_bIsX11))
@@ -1716,13 +1714,10 @@ void CWindow::sendWindowSize(Vector2D size, bool force, std::optional<Vector2D>
m_vReportedPosition = windowPos; m_vReportedPosition = windowPos;
m_vPendingReportedSize = size; m_vPendingReportedSize = size;
m_fX11SurfaceScaledBy = 1.0f;
m_fX11SurfaceScaledBy = 1.0f; if (*PXWLFORCESCALEZERO && m_bIsX11 && PMONITOR)
if (*PXWLFORCESCALEZERO && m_bIsX11 && PMONITOR) {
size *= PMONITOR->scale;
m_fX11SurfaceScaledBy = PMONITOR->scale; m_fX11SurfaceScaledBy = PMONITOR->scale;
}
if (m_bIsX11 && m_pXWaylandSurface) if (m_bIsX11 && m_pXWaylandSurface)
m_pXWaylandSurface->configure({windowPos, size}); m_pXWaylandSurface->configure({windowPos, size});

View File

@@ -44,6 +44,10 @@ void IKeyboard::clearManuallyAllocd() {
if (xkbKeymapFD >= 0) if (xkbKeymapFD >= 0)
close(xkbKeymapFD); close(xkbKeymapFD);
if (xkbSymState)
xkb_state_unref(xkbSymState);
xkbSymState = nullptr;
xkbKeymap = nullptr; xkbKeymap = nullptr;
xkbState = nullptr; xkbState = nullptr;
xkbStaticState = nullptr; xkbStaticState = nullptr;

View File

@@ -434,7 +434,7 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
// accumulate requested modes in reverse order (cause inesrting at front is inefficient) // accumulate requested modes in reverse order (cause inesrting at front is inefficient)
std::vector<SP<Aquamarine::SOutputMode>> requestedModes; std::vector<SP<Aquamarine::SOutputMode>> requestedModes;
std::string requestedStr = "preferred"; std::string requestedStr = "unknown";
// use sortFunc, add best 3 to requestedModes in reverse, since we test in reverse // use sortFunc, add best 3 to requestedModes in reverse, since we test in reverse
auto addBest3Modes = [&](auto const& sortFunc) { auto addBest3Modes = [&](auto const& sortFunc) {
@@ -445,20 +445,31 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
requestedModes.insert(requestedModes.end(), sortedModes.rbegin(), sortedModes.rend()); requestedModes.insert(requestedModes.end(), sortedModes.rbegin(), sortedModes.rend());
}; };
// last fallback is preferred mode, btw this covers resolution == Vector2D() // last fallback is always preferred mode
if (!output->preferredMode()) if (!output->preferredMode())
Debug::log(ERR, "Monitor {} has NO PREFERRED MODE", output->name); Debug::log(ERR, "Monitor {} has NO PREFERRED MODE", output->name);
else else
requestedModes.push_back(output->preferredMode()); requestedModes.push_back(output->preferredMode());
if (RULE->resolution == Vector2D(-1, -1)) { if (RULE->resolution == Vector2D()) {
requestedStr = "preferred";
// fallback to first 3 modes if preferred fails/doesn't exist
requestedModes = output->modes;
if (requestedModes.size() > 3)
requestedModes.erase(requestedModes.begin() + 3, requestedModes.end());
std::ranges::reverse(requestedModes.begin(), requestedModes.end());
if (output->preferredMode())
requestedModes.push_back(output->preferredMode());
} else if (RULE->resolution == Vector2D(-1, -1)) {
requestedStr = "highrr"; requestedStr = "highrr";
// sort prioritizing refresh rate 1st and resolution 2nd, then add best 3 // sort prioritizing refresh rate 1st and resolution 2nd, then add best 3
addBest3Modes([](auto const& a, auto const& b) { addBest3Modes([](auto const& a, auto const& b) {
if (a->refreshRate > b->refreshRate) if (std::round(a->refreshRate) > std::round(b->refreshRate))
return true; return true;
else if (DELTALESSTHAN((float)a->refreshRate, (float)b->refreshRate, 1000) && a->pixelSize.x > b->pixelSize.x && a->pixelSize.y > b->pixelSize.y) else if (DELTALESSTHAN((float)a->refreshRate, (float)b->refreshRate, 1.F) && a->pixelSize.x > b->pixelSize.x && a->pixelSize.y > b->pixelSize.y)
return true; return true;
return false; return false;
}); });
@@ -469,7 +480,8 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
addBest3Modes([](auto const& a, auto const& b) { addBest3Modes([](auto const& a, auto const& b) {
if (a->pixelSize.x > b->pixelSize.x && a->pixelSize.y > b->pixelSize.y) if (a->pixelSize.x > b->pixelSize.x && a->pixelSize.y > b->pixelSize.y)
return true; return true;
else if (DELTALESSTHAN(a->pixelSize.x, b->pixelSize.x, 1) && DELTALESSTHAN(a->pixelSize.y, b->pixelSize.y, 1) && a->refreshRate > b->refreshRate) else if (DELTALESSTHAN(a->pixelSize.x, b->pixelSize.x, 1) && DELTALESSTHAN(a->pixelSize.y, b->pixelSize.y, 1) &&
std::round(a->refreshRate) > std::round(b->refreshRate))
return true; return true;
return false; return false;
}); });

View File

@@ -33,7 +33,7 @@ struct SMonitorRule {
Vector2D resolution = Vector2D(1280, 720); Vector2D resolution = Vector2D(1280, 720);
Vector2D offset = Vector2D(0, 0); Vector2D offset = Vector2D(0, 0);
float scale = 1; float scale = 1;
float refreshRate = 60; float refreshRate = 60; // Hz
bool disabled = false; bool disabled = false;
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL; wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
std::string mirrorOf = ""; std::string mirrorOf = "";
@@ -92,7 +92,7 @@ class CMonitor {
CDamageRing damage; CDamageRing damage;
SP<Aquamarine::IOutput> output; SP<Aquamarine::IOutput> output;
float refreshRate = 60; float refreshRate = 60; // Hz
int forceFullFrames = 0; int forceFullFrames = 0;
bool scheduledRecalc = false; bool scheduledRecalc = false;
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL; wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;

View File

@@ -43,7 +43,7 @@ CHyprAnimationManager::CHyprAnimationManager() {
template <Animable VarType> template <Animable VarType>
static void updateVariable(CAnimatedVariable<VarType>& av, const float POINTY, bool warp = false) { static void updateVariable(CAnimatedVariable<VarType>& av, const float POINTY, bool warp = false) {
if (warp || av.value() == av.goal()) { if (warp || av.value() == av.goal()) {
av.warp(); av.warp(true, false);
return; return;
} }
@@ -53,7 +53,7 @@ static void updateVariable(CAnimatedVariable<VarType>& av, const float POINTY, b
static void updateColorVariable(CAnimatedVariable<CHyprColor>& av, const float POINTY, bool warp) { static void updateColorVariable(CAnimatedVariable<CHyprColor>& av, const float POINTY, bool warp) {
if (warp || av.value() == av.goal()) { if (warp || av.value() == av.goal()) {
av.warp(); av.warp(true, false);
return; return;
} }

View File

@@ -82,29 +82,9 @@ CBox CHyprXWaylandManager::getGeometryForWindow(PHLWINDOW pWindow) {
CBox box; CBox box;
if (pWindow->m_bIsX11) { if (pWindow->m_bIsX11)
const auto SIZEHINTS = pWindow->m_pXWaylandSurface->sizeHints.get(); box = pWindow->m_pXWaylandSurface->geometry;
else if (pWindow->m_pXDGSurface)
if (SIZEHINTS && !pWindow->isX11OverrideRedirect()) {
// WM_SIZE_HINTS' x,y,w,h is deprecated it seems.
// Source: https://x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html#wm_normal_hints_property
box.x = pWindow->m_pXWaylandSurface->geometry.x;
box.y = pWindow->m_pXWaylandSurface->geometry.y;
constexpr int ICCCM_USSize = 0x2;
constexpr int ICCCM_PSize = 0x8;
if ((SIZEHINTS->flags & ICCCM_USSize) || (SIZEHINTS->flags & ICCCM_PSize)) {
box.w = SIZEHINTS->base_width;
box.h = SIZEHINTS->base_height;
} else {
box.w = pWindow->m_pXWaylandSurface->geometry.w;
box.h = pWindow->m_pXWaylandSurface->geometry.h;
}
} else
box = pWindow->m_pXWaylandSurface->geometry;
} else if (pWindow->m_pXDGSurface)
box = pWindow->m_pXDGSurface->current.geometry; box = pWindow->m_pXDGSurface->current.geometry;
return box; return box;

View File

@@ -32,6 +32,7 @@ executable(
xcb_xfixes_dep, xcb_xfixes_dep,
backtrace_dep, backtrace_dep,
epoll_dep, epoll_dep,
inotify_dep,
gio_dep, gio_dep,
tracy, tracy,

View File

@@ -130,6 +130,11 @@ void CPresentationProtocol::onPresented(PHLMONITOR pMonitor, timespec* when, uin
} }
} }
if (m_vFeedbacks.size() > 10000 /* arbitrary number I chose as fitting */) {
LOGM(ERR, "FIXME: presentation has a feedback leak, and has grown to {} pending entries!!! Dropping!!!!!", m_vFeedbacks.size());
m_vFeedbacks = {m_vFeedbacks.begin() + 9000, m_vFeedbacks.end()};
}
std::erase_if(m_vFeedbacks, [](const auto& other) { return !other->surface || other->done; }); std::erase_if(m_vFeedbacks, [](const auto& other) { return !other->surface || other->done; });
std::erase_if(m_vQueue, [pMonitor](const auto& other) { return !other->surface || other->pMonitor == pMonitor || !other->pMonitor || other->done; }); std::erase_if(m_vQueue, [pMonitor](const auto& other) { return !other->surface || other->pMonitor == pMonitor || !other->pMonitor || other->done; });
} }

View File

@@ -308,9 +308,7 @@ void CWLSurfaceResource::breadthfirst(std::function<void(SP<CWLSurfaceResource>,
std::pair<SP<CWLSurfaceResource>, Vector2D> CWLSurfaceResource::at(const Vector2D& localCoords, bool allowsInput) { std::pair<SP<CWLSurfaceResource>, Vector2D> CWLSurfaceResource::at(const Vector2D& localCoords, bool allowsInput) {
std::vector<std::pair<SP<CWLSurfaceResource>, Vector2D>> surfs; std::vector<std::pair<SP<CWLSurfaceResource>, Vector2D>> surfs;
breadthfirst([](SP<CWLSurfaceResource> surf, const Vector2D& offset, breadthfirst([&surfs](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) { surfs.emplace_back(std::make_pair<>(surf, offset)); }, &surfs);
void* data) { ((std::vector<std::pair<SP<CWLSurfaceResource>, Vector2D>>*)data)->emplace_back(std::make_pair<>(surf, offset)); },
&surfs);
for (auto const& [surf, pos] : surfs | std::views::reverse) { for (auto const& [surf, pos] : surfs | std::views::reverse) {
if (!allowsInput) { if (!allowsInput) {

View File

@@ -2147,14 +2147,20 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP<CTexture> tex, const CBox& box, f
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
// stencil done. Render everything. // stencil done. Render everything.
CBox MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
// render our great blurred FB
// calculate the uv for it
const auto LASTTL = m_RenderData.primarySurfaceUVTopLeft; const auto LASTTL = m_RenderData.primarySurfaceUVTopLeft;
const auto LASTBR = m_RenderData.primarySurfaceUVBottomRight; const auto LASTBR = m_RenderData.primarySurfaceUVBottomRight;
m_RenderData.primarySurfaceUVTopLeft = box.pos() / MONITORBOX.size(); CBox transformedBox = box;
m_RenderData.primarySurfaceUVBottomRight = (box.pos() + box.size()) / MONITORBOX.size(); transformedBox.transform(wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x,
m_RenderData.pMonitor->vecTransformedSize.y);
CBox monitorSpaceBox = {transformedBox.pos().x / m_RenderData.pMonitor->vecPixelSize.x * m_RenderData.pMonitor->vecTransformedSize.x,
transformedBox.pos().y / m_RenderData.pMonitor->vecPixelSize.y * m_RenderData.pMonitor->vecTransformedSize.y,
transformedBox.width / m_RenderData.pMonitor->vecPixelSize.x * m_RenderData.pMonitor->vecTransformedSize.x,
transformedBox.height / m_RenderData.pMonitor->vecPixelSize.y * m_RenderData.pMonitor->vecTransformedSize.y};
m_RenderData.primarySurfaceUVTopLeft = monitorSpaceBox.pos() / m_RenderData.pMonitor->vecTransformedSize;
m_RenderData.primarySurfaceUVBottomRight = (monitorSpaceBox.pos() + monitorSpaceBox.size()) / m_RenderData.pMonitor->vecTransformedSize;
static auto PBLURIGNOREOPACITY = CConfigValue<Hyprlang::INT>("decoration:blur:ignore_opacity"); static auto PBLURIGNOREOPACITY = CConfigValue<Hyprlang::INT>("decoration:blur:ignore_opacity");
setMonitorTransformEnabled(true); setMonitorTransformEnabled(true);

View File

@@ -337,7 +337,8 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(PHLMONITOR pMonitor, PHLWOR
// then render windows over fullscreen. // then render windows over fullscreen.
for (auto const& w : g_pCompositor->m_vWindows) { for (auto const& w : g_pCompositor->m_vWindows) {
if (w->m_pWorkspace != pWorkspaceWindow->m_pWorkspace || !w->m_bIsFloating || (!w->m_bCreatedOverFullscreen && !w->m_bPinned) || (!w->m_bIsMapped && !w->m_bFadingOut) || w->isFullscreen()) if (w->m_pWorkspace != pWorkspaceWindow->m_pWorkspace || !w->m_bIsFloating || (!w->m_bCreatedOverFullscreen && !w->m_bPinned) || (!w->m_bIsMapped && !w->m_bFadingOut) ||
w->isFullscreen())
continue; continue;
if (w->m_pMonitor == pWorkspace->m_pMonitor && pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace()) if (w->m_pMonitor == pWorkspace->m_pMonitor && pWorkspace->m_bIsSpecialWorkspace != w->onSpecialWorkspace())

View File

@@ -13,7 +13,7 @@ class IPassElement {
virtual const char* passName() = 0; virtual const char* passName() = 0;
virtual void discard(); virtual void discard();
virtual bool undiscardable(); virtual bool undiscardable();
virtual std::optional<CBox> boundingBox(); virtual std::optional<CBox> boundingBox(); // in monitor-local logical coordinates
virtual CRegion opaqueRegion(); virtual CRegion opaqueRegion(); // in monitor-local logical coordinates
virtual bool disableSimplification(); virtual bool disableSimplification();
}; };

View File

@@ -24,7 +24,7 @@ bool CRectPassElement::needsPrecomputeBlur() {
} }
std::optional<CBox> CRectPassElement::boundingBox() { std::optional<CBox> CRectPassElement::boundingBox() {
return data.box; return data.box.copy().scale(1.F / g_pHyprOpenGL->m_RenderData.pMonitor->scale).round();
} }
CRegion CRectPassElement::opaqueRegion() { CRegion CRectPassElement::opaqueRegion() {

View File

@@ -169,6 +169,22 @@ void CXWaylandSurface::configure(const CBox& box) {
uint32_t values[] = {box.x, box.y, box.width, box.height, 0}; uint32_t values[] = {box.x, box.y, box.width, box.height, 0};
xcb_configure_window(g_pXWayland->pWM->connection, xID, mask, values); xcb_configure_window(g_pXWayland->pWM->connection, xID, mask, values);
if (geometry.width == box.width && geometry.height == box.height) {
// ICCCM requires a synthetic event when window size is not changed
xcb_configure_notify_event_t e;
e.response_type = XCB_CONFIGURE_NOTIFY;
e.event = xID;
e.window = xID;
e.x = box.x;
e.y = box.y;
e.width = box.width;
e.height = box.height;
e.border_width = 0;
e.above_sibling = XCB_NONE;
e.override_redirect = overrideRedirect;
xcb_send_event(g_pXWayland->pWM->connection, false, xID, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char*)&e);
}
g_pXWayland->pWM->updateClientList(); g_pXWayland->pWM->updateClientList();
xcb_flush(g_pXWayland->pWM->connection); xcb_flush(g_pXWayland->pWM->connection);

View File

@@ -102,8 +102,8 @@ void CXWM::handleMapRequest(xcb_map_request_event_t* e) {
const bool HAS_HINTS = XSURF->sizeHints && Vector2D{XSURF->sizeHints->base_width, XSURF->sizeHints->base_height} > Vector2D{5, 5}; const bool HAS_HINTS = XSURF->sizeHints && Vector2D{XSURF->sizeHints->base_width, XSURF->sizeHints->base_height} > Vector2D{5, 5};
const auto DESIREDSIZE = HAS_HINTS ? Vector2D{XSURF->sizeHints->base_width, XSURF->sizeHints->base_height} : Vector2D{800, 800}; const auto DESIREDSIZE = HAS_HINTS ? Vector2D{XSURF->sizeHints->base_width, XSURF->sizeHints->base_height} : Vector2D{800, 800};
// if it's too small, or its base size is set, configure it. // if it's too small, configure it.
if ((SMALL || HAS_HINTS) && !XSURF->overrideRedirect) // default to 800 x 800 if (SMALL && !XSURF->overrideRedirect) // default to 800 x 800
XSURF->configure({XSURF->geometry.pos(), DESIREDSIZE}); XSURF->configure({XSURF->geometry.pos(), DESIREDSIZE});
Debug::log(LOG, "[xwm] Mapping window {} in X (geometry {}x{} at {}x{}))", e->window, XSURF->geometry.width, XSURF->geometry.height, XSURF->geometry.x, XSURF->geometry.y); Debug::log(LOG, "[xwm] Mapping window {} in X (geometry {}x{} at {}x{}))", e->window, XSURF->geometry.width, XSURF->geometry.height, XSURF->geometry.x, XSURF->geometry.y);