Skip to content

Commit

Permalink
hyprctl: Make setcursor better (support XCursor themes, give fail mes…
Browse files Browse the repository at this point in the history
…sage) (hyprwm#6097)

* add support for changing to X cursor themes

* use new hyprcursor abi for options

* remove unneeded struct
  • Loading branch information
ikalco authored and cdubthecoolcat committed May 29, 2024
1 parent 17d83bc commit e243274
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
3 changes: 2 additions & 1 deletion src/debug/HyprCtl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,8 @@ std::string dispatchSetCursor(eHyprCtlOutputFormat format, std::string request)
if (size <= 0)
return "size not positive";

g_pCursorManager->changeTheme(theme, size);
if (!g_pCursorManager->changeTheme(theme, size))
return "failed to set cursor";

return "ok";
}
Expand Down
54 changes: 45 additions & 9 deletions src/managers/CursorManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,6 @@ void CCursorManager::updateTheme() {
highestScale = m->scale;
}

if (std::round(highestScale * m_iSize) == m_sCurrentStyleInfo.size)
return;

if (m_sCurrentStyleInfo.size && m_pHyprcursor->valid())
m_pHyprcursor->cursorSurfaceStyleDone(m_sCurrentStyleInfo);

Expand All @@ -287,13 +284,52 @@ void CCursorManager::updateTheme() {
}
}

void CCursorManager::changeTheme(const std::string& name, const int size) {
m_pHyprcursor = std::make_unique<Hyprcursor::CHyprcursorManager>(name.empty() ? "" : name.c_str(), hcLogger);
m_szTheme = name;
m_iSize = size;
bool CCursorManager::changeTheme(const std::string& name, const int size) {
auto options = Hyprcursor::SManagerOptions();
options.logFn = hcLogger;
options.allowDefaultFallback = false;

m_pHyprcursor = std::make_unique<Hyprcursor::CHyprcursorManager>(name.empty() ? "" : name.c_str(), options);
if (m_pHyprcursor->valid()) {
m_szTheme = name;
m_iSize = size;
updateTheme();
return true;
}

if (!m_pHyprcursor->valid())
Debug::log(ERR, "Hyprcursor failed loading theme \"{}\", falling back to X.", m_szTheme);
Debug::log(ERR, "Hyprcursor failed loading theme \"{}\", falling back to X.", name);

if (m_pWLRXCursorMgr)
wlr_xcursor_manager_destroy(m_pWLRXCursorMgr);

m_pWLRXCursorMgr = wlr_xcursor_manager_create(name.empty() ? "" : name.c_str(), size);
bool xSuccess = wlr_xcursor_manager_load(m_pWLRXCursorMgr, 1.0) == 1;

// this basically checks if xcursor changed used theme to default but better
bool diffTheme = false;
wlr_xcursor_manager_theme* theme;
wl_list_for_each(theme, &m_pWLRXCursorMgr->scaled_themes, link) {
if (std::string{theme->theme->name} != name) {
diffTheme = true;
break;
}
}

if (xSuccess && !diffTheme) {
m_szTheme = name;
m_iSize = size;
updateTheme();
return true;
}

Debug::log(ERR, "X also failed loading theme \"{}\", falling back to previous theme.", name);

m_pHyprcursor = std::make_unique<Hyprcursor::CHyprcursorManager>(m_szTheme.c_str(), hcLogger);

wlr_xcursor_manager_destroy(m_pWLRXCursorMgr);
m_pWLRXCursorMgr = wlr_xcursor_manager_create(m_szTheme.c_str(), m_iSize);
wlr_xcursor_manager_load(m_pWLRXCursorMgr, 1.0);

updateTheme();
return false;
}
2 changes: 1 addition & 1 deletion src/managers/CursorManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class CCursorManager {
void setCursorSurface(CWLSurface* surf, const Vector2D& hotspot);
void setXCursor(const std::string& name);

void changeTheme(const std::string& name, const int size);
bool changeTheme(const std::string& name, const int size);
void updateTheme();
SCursorImageData dataFor(const std::string& name); // for xwayland
void setXWaylandCursor();
Expand Down

0 comments on commit e243274

Please sign in to comment.