@@ -3,7 +3,10 @@ use anyhow::Context;
3
3
use super :: sort_workspaces;
4
4
use crate :: {
5
5
common:: TilingDirection ,
6
- containers:: { commands:: attach_container, traits:: PositionGetters } ,
6
+ containers:: {
7
+ commands:: attach_container,
8
+ traits:: { CommonGetters , PositionGetters } ,
9
+ } ,
7
10
monitors:: Monitor ,
8
11
user_config:: { UserConfig , WorkspaceConfig } ,
9
12
wm_event:: WmEvent ,
@@ -15,14 +18,39 @@ use crate::{
15
18
///
16
19
/// If no workspace name is provided, the first suitable workspace defined
17
20
/// in the user's config will be used.
21
+ ///
22
+ /// If no target monitor is provided, the workspace is activated on
23
+ /// whichever monitor it is bound to, or the currently focused monitor.
18
24
pub fn activate_workspace (
19
25
workspace_name : Option < & str > ,
20
- target_monitor : & Monitor ,
26
+ target_monitor : Option < Monitor > ,
21
27
state : & mut WmState ,
22
28
config : & UserConfig ,
23
29
) -> anyhow:: Result < ( ) > {
24
- let workspace_config =
25
- workspace_config ( workspace_name, target_monitor, state, config) ?;
30
+ let workspace_config = workspace_config (
31
+ workspace_name,
32
+ target_monitor. clone ( ) ,
33
+ state,
34
+ config,
35
+ ) ?;
36
+
37
+ let target_monitor = target_monitor
38
+ . or_else ( || {
39
+ workspace_config
40
+ . bind_to_monitor
41
+ . and_then ( |index| {
42
+ state
43
+ . monitors ( )
44
+ . into_iter ( )
45
+ . find ( |monitor| monitor. index ( ) == index as usize )
46
+ } )
47
+ . or_else ( || {
48
+ state
49
+ . focused_container ( )
50
+ . and_then ( |focused| focused. monitor ( ) )
51
+ } )
52
+ } )
53
+ . context ( "Failed to get a target monitor for the workspace." ) ?;
26
54
27
55
let monitor_rect = target_monitor. to_rect ( ) ?;
28
56
let tiling_direction = match monitor_rect. height ( ) > monitor_rect. width ( )
@@ -56,28 +84,33 @@ pub fn activate_workspace(
56
84
/// Gets config for the workspace to activate.
57
85
fn workspace_config (
58
86
workspace_name : Option < & str > ,
59
- target_monitor : & Monitor ,
87
+ target_monitor : Option < Monitor > ,
60
88
state : & mut WmState ,
61
89
config : & UserConfig ,
62
90
) -> anyhow:: Result < WorkspaceConfig > {
63
- match workspace_name {
64
- Some ( workspace_name) => {
65
- let found_config = config
66
- . inactive_workspace_configs ( & state. workspaces ( ) )
67
- . into_iter ( )
68
- . find ( |config| config. name == workspace_name)
69
- . with_context ( || {
70
- format ! ( "Workspace with name {} doesn't exist." , workspace_name)
71
- } ) ?;
72
-
73
- Ok ( found_config. clone ( ) )
74
- }
75
- None => {
76
- let inactive_config = config
77
- . workspace_config_for_monitor ( & target_monitor, & state. workspaces ( ) )
78
- . context ( "No workspace config found for monitor." ) ?;
91
+ let found_config = match workspace_name {
92
+ Some ( workspace_name) => config
93
+ . inactive_workspace_configs ( & state. workspaces ( ) )
94
+ . into_iter ( )
95
+ . find ( |config| config. name == workspace_name)
96
+ . with_context ( || {
97
+ format ! (
98
+ "Workspace with name '{}' doesn't exist or is already active." ,
99
+ workspace_name
100
+ )
101
+ } ) ,
102
+ None => target_monitor
103
+ . and_then ( |target_monitor| {
104
+ config. workspace_config_for_monitor (
105
+ & target_monitor,
106
+ & state. workspaces ( ) ,
107
+ )
108
+ } )
109
+ . or_else ( || {
110
+ config. next_inactive_workspace_config ( & state. workspaces ( ) )
111
+ } )
112
+ . context ( "No workspace config available to activate workspace." ) ,
113
+ } ;
79
114
80
- Ok ( inactive_config. clone ( ) )
81
- }
82
- }
115
+ found_config. cloned ( )
83
116
}
0 commit comments