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

fix: Hyprland clash when unplug monitor #69

Closed
Closed
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ compile_flags.txt
compile_commands.json
.cache
result/
.idea
.idea
build
28 changes: 28 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.10)
project(virtual-desktops)

find_package(PkgConfig REQUIRED)
pkg_check_modules(PIXMAN REQUIRED pixman-1)
pkg_check_modules(DRM REQUIRED libdrm)

file(GLOB_RECURSE SOURCE_FILES src/*.cpp)
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
target_include_directories(${PROJECT_NAME} PRIVATE
./include
${PIXMAN_INCLUDE_DIRS}
${DRM_INCLUDE_DIRS}
)
target_link_libraries(${PROJECT_NAME} PRIVATE
${PIXMAN_LIBRARIES}
${DRM_LIBRARIES}
)

set_target_properties(${PROJECT_NAME} PROPERTIES
POSITION_INDEPENDENT_CODE ON # -fPIC
COMPILE_FLAGS "--no-gnu-unique -std=c++23 -Wall"
)

target_compile_definitions(${PROJECT_NAME} PRIVATE
WLR_USE_UNSTABLE
)

25 changes: 8 additions & 17 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ using namespace Hyprutils::Memory;
static CSharedPointer<HOOK_CALLBACK_FN> onWorkspaceChangeHook = nullptr;
static CSharedPointer<HOOK_CALLBACK_FN> onWindowOpenHook = nullptr;
static CSharedPointer<HOOK_CALLBACK_FN> onConfigReloadedHook = nullptr;
static CSharedPointer<HOOK_CALLBACK_FN> onMonitorAddedHook = nullptr;
static CSharedPointer<HOOK_CALLBACK_FN> onPreMonitorRemovedHook = nullptr;

inline CFunctionHook* g_pMonitorConnectHook = nullptr;
inline CFunctionHook* g_pMonitorDisconnectHook = nullptr;
typedef void (*origMonitorConnect)(void*, bool);
typedef void (*origMonitorDisconnect)(void*, bool);

Expand Down Expand Up @@ -294,12 +294,11 @@ void onWindowOpen(void*, SCallbackInfo&, std::any val) {
manager->changeActiveDesk(vdesk, true);
}

void hookMonitorDisconnect(void* thisptr, bool destroy) {
void onPreMonitorRemoved(void*, SCallbackInfo&, std::any val) {
auto monitor = std::any_cast<PHLMONITOR>(val);
monitorLayoutChanging = true;
(*(origMonitorDisconnect)g_pMonitorDisconnectHook->m_pOriginal)(thisptr, destroy);
monitorLayoutChanging = false;

CSharedPointer<CMonitor> monitor = CSharedPointer(static_cast<CMonitor*>(thisptr));
if (isVerbose())
printLog("Monitor disconnect called with disabled monitor " + monitor->szName);
if (!currentlyEnabledMonitors(monitor).empty()) {
Expand All @@ -310,12 +309,11 @@ void hookMonitorDisconnect(void* thisptr, bool destroy) {
}
}

void hookMonitorConnect(void* thisptr, bool noRule) {
void onMonitorAdded(void*, SCallbackInfo&, std::any val) {
auto monitor = std::any_cast<PHLMONITOR>(val);
monitorLayoutChanging = true;
(*(origMonitorConnect)g_pMonitorConnectHook->m_pOriginal)(thisptr, noRule);
monitorLayoutChanging = false;

CSharedPointer<CMonitor> monitor = CSharedPointer(static_cast<CMonitor*>(thisptr));
if (monitor->szName == std::string("HEADLESS-1")) {
return;
}
Expand Down Expand Up @@ -405,15 +403,8 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
onWorkspaceChangeHook = HyprlandAPI::registerCallbackDynamic(PHANDLE, "workspace", onWorkspaceChange);
onWindowOpenHook = HyprlandAPI::registerCallbackDynamic(PHANDLE, "openWindow", onWindowOpen);
onConfigReloadedHook = HyprlandAPI::registerCallbackDynamic(PHANDLE, "configReloaded", onConfigReloaded);

// Function hooks
static const auto METHODS_CONNECT = HyprlandAPI::findFunctionsByName(PHANDLE, "onConnect");
g_pMonitorConnectHook = HyprlandAPI::createFunctionHook(handle, METHODS_CONNECT[0].address, (void*)&hookMonitorConnect);
g_pMonitorConnectHook->hook();

static const auto METHODS_DISCONNECT = HyprlandAPI::findFunctionsByName(PHANDLE, "onDisconnect");
g_pMonitorDisconnectHook = HyprlandAPI::createFunctionHook(handle, METHODS_DISCONNECT[0].address, (void*)&hookMonitorDisconnect);
g_pMonitorDisconnectHook->hook();
onMonitorAddedHook = HyprlandAPI::registerCallbackDynamic(PHANDLE, "monitorAdded", onMonitorAdded);
onPreMonitorRemovedHook = HyprlandAPI::registerCallbackDynamic(PHANDLE, "preMonitorRemoved", onPreMonitorRemoved);

registerHyprctlCommands();

Expand Down
Loading