Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make hyprctl setcursor better (support XCursor themes, also give fail message) #6097

Merged
merged 3 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/debug/HyprCtl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,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 @@ -266,9 +266,6 @@ void CCursorManager::updateTheme() {
highestScale = m->scale;
}

if (std::round(highestScale * m_iSize) == m_sCurrentStyleInfo.size)
vaxerski marked this conversation as resolved.
Show resolved Hide resolved
return;

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

Expand All @@ -286,13 +283,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 @@ -22,7 +22,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(wlr_xwayland* xwayland);
Expand Down
Loading