12
12
13
13
namespace waybar ::modules::hyprland {
14
14
15
+ constexpr int INVALID_WORKSPACE_ID = -100 ;
16
+
15
17
Workspaces::Workspaces (const std::string &id, const Bar &bar, const Json::Value &config)
16
18
: AModule(config, " workspaces" , id, false , false ),
17
19
m_bar (bar),
@@ -39,13 +41,7 @@ Workspaces::~Workspaces() {
39
41
}
40
42
41
43
void Workspaces::init () {
42
- <<<<<<< HEAD
43
- m_activeWorkspaceName = (m_ipc.getSocket1JsonReply (" activeworkspace" ))[" name" ].asString ();
44
- ||||||| parent of 24d391b9 (feat (hyprland): support workspacev2)
45
- m_activeWorkspaceName = (gIPC ->getSocket1JsonReply (" activeworkspace" ))[" name" ].asString ();
46
- =======
47
44
m_activeWorkspaceId = (gIPC ->getSocket1JsonReply (" activeworkspace" ))[" id" ].asInt ();
48
- >>>>>>> 24d391b9 (feat (hyprland): support workspacev2)
49
45
50
46
initializeWorkspaces ();
51
47
dp.emit ();
@@ -55,13 +51,12 @@ Json::Value Workspaces::createMonitorWorkspaceData(std::string const &name,
55
51
std::string const &monitor) {
56
52
spdlog::trace (" Creating persistent workspace: {} on monitor {}" , name, monitor);
57
53
Json::Value workspaceData;
58
- try {
59
- // numbered persistent workspaces get the name as ID
60
- workspaceData[" id" ] = name == " special" ? -99 : std::stoi (name);
61
- } catch (const std::exception &e) {
62
- // named persistent workspaces start with ID=0
63
- workspaceData[" id" ] = 0 ;
54
+
55
+ auto workspaceId = getWorkspaceId (name);
56
+ if (workspaceId == INVALID_WORKSPACE_ID) {
57
+ workspaceId = 0
64
58
}
59
+ workspaceData[" id" ] = workspaceId
65
60
workspaceData[" name" ] = name;
66
61
workspaceData[" monitor" ] = monitor;
67
62
workspaceData[" windows" ] = 0 ;
@@ -72,6 +67,7 @@ void Workspaces::createWorkspace(Json::Value const &workspace_data,
72
67
Json::Value const &clients_data) {
73
68
auto workspaceName = workspace_data[" name" ].asString ();
74
69
spdlog::debug (" Creating workspace {}" , workspaceName);
70
+
75
71
76
72
// avoid recreating existing workspaces
77
73
auto workspace = std::find_if (
@@ -331,21 +327,21 @@ void Workspaces::onEvent(const std::string &ev) {
331
327
onWorkspaceDestroyed (payload);
332
328
} else if (eventName == " createworkspacev2" ) {
333
329
onWorkspaceCreated (payload);
334
- } else if (eventName == " focusedmon " ) {
330
+ } else if (eventName == " focusedmonv2 " ) {
335
331
onMonitorFocused (payload);
336
- } else if (eventName == " moveworkspace " ) {
332
+ } else if (eventName == " moveworkspacev2 " ) {
337
333
onWorkspaceMoved (payload);
338
334
} else if (eventName == " openwindow" ) {
339
335
onWindowOpened (payload);
340
336
} else if (eventName == " closewindow" ) {
341
337
onWindowClosed (payload);
342
- } else if (eventName == " movewindow " ) {
338
+ } else if (eventName == " movewindowv2 " ) {
343
339
onWindowMoved (payload);
344
340
} else if (eventName == " urgent" ) {
345
341
setUrgentWorkspace (payload);
346
342
} else if (eventName == " renameworkspace" ) {
347
343
onWorkspaceRenamed (payload);
348
- } else if (eventName == " windowtitle " ) {
344
+ } else if (eventName == " windowtitlev2 " ) {
349
345
onWindowTitleEvent (payload);
350
346
} else if (eventName == " configreloaded" ) {
351
347
onConfigReloaded ();
@@ -355,8 +351,11 @@ void Workspaces::onEvent(const std::string &ev) {
355
351
}
356
352
357
353
void Workspaces::onWorkspaceActivated (std::string const &payload) {
358
- std::string workspaceIdStr = payload.substr (0 , payload.find (' ,' ));
359
- m_activeWorkspaceId = std::stoi (workspaceIdStr);
354
+ auto [workspaceIdStr, _] = splitDoublePayload (payload);
355
+ auto workspaceId = getWorkspaceId (workspaceIdStr);
356
+ if (workspaceId != INVALID_WORKSPACE_ID) {
357
+ m_activeWorkspaceId = workspaceId;
358
+ }
360
359
}
361
360
362
361
void Workspaces::onSpecialWorkspaceActivated (std::string const &payload) {
@@ -365,18 +364,22 @@ void Workspaces::onSpecialWorkspaceActivated(std::string const &payload) {
365
364
}
366
365
367
366
void Workspaces::onWorkspaceDestroyed (std::string const &payload) {
368
- std::string workspaceIdStr = payload.substr (0 , payload.find (' ,' ));
369
- std::string workspaceName = payload.substr (workspaceIdStr.size () + 1 );
367
+ auto [workspaceId, workspaceName] = splitDoublePayload (payload);
370
368
if (!isDoubleSpecial (workspaceName)) {
371
- m_workspacesToRemove.push_back (workspaceIdStr );
369
+ m_workspacesToRemove.push_back (workspaceId );
372
370
}
373
371
}
374
372
375
373
void Workspaces::onWorkspaceCreated (std::string const &payload,
376
374
Json::Value const &clientsData) {
377
375
spdlog::debug (" Workspace created: {}" , payload);
378
- std::string workspaceIdStr = payload.substr (0 , payload.find (' ,' ));
379
- int workspaceId = std::stoi (workspaceIdStr);
376
+
377
+ auto [workspaceIdStr, _] = splitDoublePayload (payload);
378
+
379
+ auto workspaceId = getWorkspaceId (workspaceIdStr);
380
+ if (workspaceId == INVALID_WORKSPACE_ID) {
381
+ return ;
382
+ }
380
383
381
384
auto const workspaceRules = gIPC ->getSocket1JsonReply (" workspacerules" );
382
385
auto const workspacesJson = gIPC ->getSocket1JsonReply (" workspaces" );
@@ -417,33 +420,30 @@ void Workspaces::onWorkspaceMoved(std::string const &payload) {
417
420
spdlog::debug (" Workspace moved: {}" , payload);
418
421
419
422
// Update active workspace
420
- <<<<<<< HEAD
421
- m_activeWorkspaceName = (m_ipc.getSocket1JsonReply (" activeworkspace" ))[" name" ].asString ();
422
- ||||||| parent of 24d391b9 (feat (hyprland): support workspacev2)
423
- m_activeWorkspaceName = (gIPC ->getSocket1JsonReply (" activeworkspace" ))[" name" ].asString ();
424
- =======
425
- m_activeWorkspaceId = (gIPC ->getSocket1JsonReply (" activeworkspace" ))[" id" ].asInt ();
426
- >>>>>>> 24d391b9 (feat (hyprland): support workspacev2)
423
+ m_activeWorkspaceId = (m_ipc.getSocket1JsonReply (" activeworkspace" ))[" id" ].asString ();
427
424
428
425
if (allOutputs ()) return ;
429
426
430
- std::string workspaceName = payload.substr (0 , payload.find (' ,' ));
431
- std::string monitorName = payload.substr (payload.find (' ,' ) + 1 );
427
+ auto [workspaceIdStr, workspaceName, monitorName] = splitTriplePayload (payload);
428
+
429
+ auto subPayload = joinDoublePayload (workspaceIdStr, workspaceName);
432
430
433
431
if (m_bar.output ->name == monitorName) {
434
432
Json::Value clientsData = m_ipc.getSocket1JsonReply (" clients" );
435
- onWorkspaceCreated (workspaceName , clientsData);
433
+ onWorkspaceCreated (subPayload , clientsData);
436
434
} else {
437
- spdlog::debug (" Removing workspace because it was moved to another monitor: {}" );
438
- onWorkspaceDestroyed (workspaceName );
435
+ spdlog::debug (" Removing workspace because it was moved to another monitor: {}" , subPayload );
436
+ onWorkspaceDestroyed (subPayload );
439
437
}
440
438
}
441
439
442
440
void Workspaces::onWorkspaceRenamed (std::string const &payload) {
443
441
spdlog::debug (" Workspace renamed: {}" , payload);
444
- std::string workspaceIdStr = payload.substr (0 , payload.find (' ,' ));
445
- int workspaceId = workspaceIdStr == " special" ? -99 : std::stoi (workspaceIdStr);
446
- std::string newName = payload.substr (payload.find (' ,' ) + 1 );
442
+ auto [workspaceIdStr, newName] = splitDoublePayload (payload);
443
+
444
+ auto workspaceId = getWorkspaceId (workspaceIdStr);
445
+ if (workspaceId == INVALID_WORKSPACE_ID) return ;
446
+
447
447
for (auto &workspace : m_workspaces) {
448
448
if (workspace->id () == workspaceId) {
449
449
workspace->setName (newName);
@@ -456,18 +456,15 @@ void Workspaces::onWorkspaceRenamed(std::string const &payload) {
456
456
void Workspaces::onMonitorFocused (std::string const &payload) {
457
457
spdlog::trace (" Monitor focused: {}" , payload);
458
458
459
- std::string workspaceName = payload. substr (payload. find ( ' , ' ) + 1 );
459
+ auto [monitorName, workspaceIdStr] = splitDoublePayload (payload);
460
460
461
- // TODO this will be in the payload when we upgrade to focusedmonv2
462
- for (auto &workspace : m_workspaces) {
463
- if (workspace->name () == workspaceName) {
464
- m_activeWorkspaceId = workspace->id ();
465
- break ;
466
- }
467
- }
461
+ auto workspaceId = getWorkspaceId (workspaceIdStr);
462
+ if (workspaceId == INVALID_WORKSPACE_ID) return ;
463
+
464
+ m_activeWorkspaceId = workspaceId;
468
465
469
466
for (Json::Value &monitor : m_ipc.getSocket1JsonReply (" monitors" )) {
470
- if (monitor[" name" ].asString () == payload. substr ( 0 , payload. find ( ' , ' )) ) {
467
+ if (monitor[" name" ].asString () == monitorName ) {
471
468
auto name = monitor[" specialWorkspace" ][" name" ].asString ();
472
469
m_activeSpecialWorkspaceName = !name.starts_with (" special:" ) ? name : name.substr (8 );
473
470
}
@@ -507,13 +504,7 @@ void Workspaces::onWindowClosed(std::string const &addr) {
507
504
void Workspaces::onWindowMoved (std::string const &payload) {
508
505
spdlog::trace (" Window moved: {}" , payload);
509
506
updateWindowCount ();
510
- size_t lastCommaIdx = 0 ;
511
- size_t nextCommaIdx = payload.find (' ,' );
512
- std::string windowAddress = payload.substr (lastCommaIdx, nextCommaIdx - lastCommaIdx);
513
-
514
- std::string workspaceName = payload.substr (nextCommaIdx + 1 , payload.length () - nextCommaIdx);
515
-
516
- std::string windowRepr;
507
+ auto [windowAddress, _, workspaceName] = splitTriplePayload (payload);
517
508
518
509
// If the window was still queued to be created, just change its destination
519
510
// and exit
@@ -547,13 +538,15 @@ void Workspaces::onWindowTitleEvent(std::string const &payload) {
547
538
spdlog::trace (" Window title changed: {}" , payload);
548
539
std::optional<std::function<void (WindowCreationPayload)>> inserter;
549
540
541
+ auto [windowAddress, _] = splitDoublePayload (payload);
542
+
550
543
// If the window was an orphan, rename it at the orphan's vector
551
- if (m_orphanWindowMap.contains (payload )) {
544
+ if (m_orphanWindowMap.contains (windowAddress )) {
552
545
inserter = [this ](WindowCreationPayload wcp) { this ->registerOrphanWindow (std::move (wcp)); };
553
546
} else {
554
547
auto windowWorkspace =
555
548
std::find_if (m_workspaces.begin (), m_workspaces.end (),
556
- [payload ](auto &workspace) { return workspace->containsWindow (payload ); });
549
+ [windowAddress ](auto &workspace) { return workspace->containsWindow (windowAddress ); });
557
550
558
551
// If the window exists on a workspace, rename it at the workspace's window
559
552
// map
@@ -692,52 +685,24 @@ void Workspaces::registerOrphanWindow(WindowCreationPayload create_window_payloa
692
685
}
693
686
694
687
auto Workspaces::registerIpc () -> void {
695
- <<<<<<< HEAD
696
688
m_ipc.registerForIPC (" workspace" , this );
697
689
m_ipc.registerForIPC (" activespecial" , this );
698
- m_ipc.registerForIPC (" createworkspace " , this );
699
- m_ipc.registerForIPC (" destroyworkspace " , this );
700
- m_ipc.registerForIPC (" focusedmon " , this );
701
- m_ipc.registerForIPC (" moveworkspace " , this );
690
+ m_ipc.registerForIPC (" createworkspacev2 " , this );
691
+ m_ipc.registerForIPC (" destroyworkspacev2 " , this );
692
+ m_ipc.registerForIPC (" focusedmonv2 " , this );
693
+ m_ipc.registerForIPC (" moveworkspacev2 " , this );
702
694
m_ipc.registerForIPC (" renameworkspace" , this );
703
695
m_ipc.registerForIPC (" openwindow" , this );
704
696
m_ipc.registerForIPC (" closewindow" , this );
705
- m_ipc.registerForIPC (" movewindow " , this );
697
+ m_ipc.registerForIPC (" movewindowv2 " , this );
706
698
m_ipc.registerForIPC (" urgent" , this );
707
699
m_ipc.registerForIPC (" configreloaded" , this );
708
- ||||||| parent of 24d391b9 (feat (hyprland): support workspacev2)
709
- gIPC ->registerForIPC (" workspace" , this );
710
- gIPC ->registerForIPC (" activespecial" , this );
711
- gIPC ->registerForIPC (" createworkspacev2" , this );
712
- gIPC ->registerForIPC (" destroyworkspacev2" , this );
713
- gIPC ->registerForIPC (" focusedmon" , this );
714
- gIPC ->registerForIPC (" moveworkspace" , this );
715
- gIPC ->registerForIPC (" renameworkspace" , this );
716
- gIPC ->registerForIPC (" openwindow" , this );
717
- gIPC ->registerForIPC (" closewindow" , this );
718
- gIPC ->registerForIPC (" movewindow" , this );
719
- gIPC ->registerForIPC (" urgent" , this );
720
- gIPC ->registerForIPC (" configreloaded" , this );
721
- =======
722
- gIPC ->registerForIPC (" workspacev2" , this );
723
- gIPC ->registerForIPC (" activespecial" , this );
724
- gIPC ->registerForIPC (" createworkspacev2" , this );
725
- gIPC ->registerForIPC (" destroyworkspacev2" , this );
726
- gIPC ->registerForIPC (" focusedmon" , this );
727
- gIPC ->registerForIPC (" moveworkspace" , this );
728
- gIPC ->registerForIPC (" renameworkspace" , this );
729
- gIPC ->registerForIPC (" openwindow" , this );
730
- gIPC ->registerForIPC (" closewindow" , this );
731
- gIPC ->registerForIPC (" movewindow" , this );
732
- gIPC ->registerForIPC (" urgent" , this );
733
- gIPC ->registerForIPC (" configreloaded" , this );
734
- >>>>>>> 24d391b9 (feat (hyprland): support workspacev2)
735
700
736
701
if (windowRewriteConfigUsesTitle ()) {
737
702
spdlog::info (
738
- " Registering for Hyprland's 'windowtitle ' events because a user-defined window "
703
+ " Registering for Hyprland's 'windowtitlev2 ' events because a user-defined window "
739
704
" rewrite rule uses the 'title' field." );
740
- m_ipc.registerForIPC (" windowtitle " , this );
705
+ m_ipc.registerForIPC (" windowtitlev2 " , this );
741
706
}
742
707
}
743
708
@@ -751,31 +716,29 @@ void Workspaces::removeWorkspacesToRemove() {
751
716
void Workspaces::removeWorkspace (std::string const &workspaceString) {
752
717
spdlog::debug (" Removing workspace {}" , workspaceString);
753
718
754
- int id;
755
- std::string name;
756
719
757
- try {
758
- // If this succeeds, we have a workspace ID.
759
- id = std::stoi (workspaceString) ;
760
- } catch ( const std:: exception &e) {
761
- // TODO: At some point we want to support all workspace selectors
762
- // This is just a subset.
763
- // https://wiki.hyprland.org/Configuring/Workspace-Rules/#workspace-selectors
764
- if (workspaceString. starts_with ( " special: " )) {
765
- name = workspaceString.substr ( 8 );
766
- } else if ( workspaceString.starts_with ( " name: " )) {
767
- name = workspaceString.substr ( 5 );
768
- } else {
769
- name = workspaceString;
770
- }
720
+ // If this succeeds, we have a workspace ID.
721
+ int id = getWorkspaceId (workspaceString);
722
+ auto matchByName = id == INVALID_WORKSPACE_ID ;
723
+
724
+ std::string name;
725
+ // TODO: At some point we want to support all workspace selectors
726
+ // This is just a subset.
727
+ // https://wiki.hyprland.org/Configuring/Workspace-Rules/#workspace-selectors
728
+ if ( workspaceString.starts_with ( " special: " )) {
729
+ name = workspaceString.substr ( 8 );
730
+ } else if ( workspaceString.starts_with ( " name: " )) {
731
+ name = workspaceString. substr ( 5 );
732
+ } else {
733
+ name = workspaceString;
771
734
}
772
735
773
736
auto workspace =
774
737
std::find_if (m_workspaces.begin (), m_workspaces.end (), [&](std::unique_ptr<Workspace> &x) {
775
- if (name. empty () ) {
776
- return id == x->id ();
738
+ if (matchByName ) {
739
+ return name == x->name ();
777
740
}
778
- return name == x->name ();
741
+ return id == x->id ();
779
742
});
780
743
781
744
if (workspace == m_workspaces.end ()) {
@@ -946,13 +909,7 @@ void Workspaces::updateWorkspaceStates() {
946
909
for (auto &workspace : m_workspaces) {
947
910
workspace->setActive (workspace->id () == m_activeWorkspaceId ||
948
911
workspace->name () == m_activeSpecialWorkspaceName);
949
- <<<<<<< HEAD
950
912
if (workspace->isActive () && workspace->isUrgent ()) {
951
- ||||||| parent of 24d391b9 (feat (hyprland): support workspacev2)
952
- if (workspace->name () == m_activeWorkspaceName && workspace->isUrgent ()) {
953
- =======
954
- if (workspace->id () == m_activeWorkspaceId && workspace->isUrgent ()) {
955
- >>>>>>> 24d391b9 (feat (hyprland): support workspacev2)
956
913
workspace->setUrgent (false );
957
914
}
958
915
workspace->setVisible (std::find (visibleWorkspaces.begin (), visibleWorkspaces.end (),
@@ -994,4 +951,34 @@ int Workspaces::windowRewritePriorityFunction(std::string const &window_rule) {
994
951
return 0 ;
995
952
}
996
953
954
+ std::string Workspaces::joinDoublePayload (std::string const &part1, std::string const &part2) {
955
+ return part1 + " ," + part2;
956
+ }
957
+
958
+ std::pair<std::string, std::string> Workspaces::splitDoublePayload (std::string const &payload) {
959
+ std::string part1 = payload.substr (0 , payload.find (' ,' ));
960
+ std::string part2 = payload.substr (part1.size () + 1 );
961
+ return {part1, part2};
962
+ }
963
+
964
+ std::tuple<std::string, std::string, std::string> Workspaces::splitTriplePayload (std::string const &payload) {
965
+ size_t firstComma = payload.find (' ,' );
966
+ size_t secondComma = payload.find (' ,' , firstComma + 1 );
967
+
968
+ std::string part1 = payload.substr (0 , firstComma);
969
+ std::string part2 = payload.substr (firstComma + 1 , secondComma - (firstComma + 1 ));
970
+ std::string part3 = payload.substr (secondComma + 1 );
971
+
972
+ return {part1, part2, part3};
973
+ }
974
+
975
+ std::int Workspaces::getWorkspaceId (std::string const &workspaceIdStr) {
976
+ try {
977
+ return workspaceIdStr == " special" ? -99 : std::stoi (workspaceIdStr);
978
+ } catch (std::exception const &e) {
979
+ spdlog::error (" Failed to parse workspace ID: {}" , e.what ());
980
+ return INVALID_WORKSPACE_ID;
981
+ }
982
+ }
983
+
997
984
} // namespace waybar::modules::hyprland
0 commit comments