Skip to content

Commit

Permalink
Merge pull request #132 from mahkoh/jorth/move-workspace
Browse files Browse the repository at this point in the history
tree: fix restoration of workspaces to their desired outputs
  • Loading branch information
mahkoh authored Mar 17, 2024
2 parents a4559f5 + fecfd24 commit 1401697
Show file tree
Hide file tree
Showing 18 changed files with 451 additions and 142 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/toml-spec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ env:
CARGO_TERM_COLOR: always

jobs:
rustfmt:
toml-spec:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
Expand Down
9 changes: 8 additions & 1 deletion jay-config/src/_private/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use {
crate::{
_private::{
bincode_ops,
ipc::{ClientMessage, InitMessage, Response, ServerMessage},
ipc::{ClientMessage, InitMessage, Response, ServerMessage, WorkspaceSource},
logging, Config, ConfigEntry, ConfigEntryGen, PollableId, WireMode, VERSION,
},
exec::Command,
Expand Down Expand Up @@ -421,6 +421,13 @@ impl Client {
self.send(&ClientMessage::DisablePointerConstraint { seat });
}

pub fn move_to_output(&self, workspace: WorkspaceSource, connector: Connector) {
self.send(&ClientMessage::MoveToOutput {
workspace,
connector,
});
}

pub fn set_fullscreen(&self, seat: Seat, fullscreen: bool) {
self.send(&ClientMessage::SetFullscreen { seat, fullscreen });
}
Expand Down
10 changes: 10 additions & 0 deletions jay-config/src/_private/ipc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,16 @@ pub enum ClientMessage<'a> {
SetIdle {
timeout: Duration,
},
MoveToOutput {
workspace: WorkspaceSource,
connector: Connector,
},
}

#[derive(Serialize, Deserialize, Debug)]
pub enum WorkspaceSource {
Seat(Seat),
Explicit(Workspace),
}

#[derive(Serialize, Deserialize, Debug)]
Expand Down
8 changes: 7 additions & 1 deletion jay-config/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use {
input::{acceleration::AccelProfile, capability::Capability},
keyboard::Keymap,
Axis, Direction, ModifiedKeySym, Workspace,
_private::DEFAULT_SEAT_NAME,
_private::{ipc::WorkspaceSource, DEFAULT_SEAT_NAME},
video::Connector,
},
serde::{Deserialize, Serialize},
std::time::Duration,
Expand Down Expand Up @@ -319,6 +320,11 @@ impl Seat {
pub fn disable_pointer_constraint(self) {
get!().disable_pointer_constraint(self)
}

/// Moves the currently focused workspace to another output.
pub fn move_to_output(self, connector: Connector) {
get!().move_to_output(WorkspaceSource::Seat(self), connector);
}
}

/// Returns all seats.
Expand Down
9 changes: 8 additions & 1 deletion jay-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
)]

use {
crate::keyboard::ModifiedKeySym,
crate::{_private::ipc::WorkspaceSource, keyboard::ModifiedKeySym, video::Connector},
serde::{Deserialize, Serialize},
std::{
fmt::{Debug, Display, Formatter},
Expand Down Expand Up @@ -159,6 +159,13 @@ impl Workspace {
let get = get!();
get.set_workspace_capture(self, !get.get_workspace_capture(self));
}

/// Moves this workspace to another output.
///
/// This has no effect if the workspace is not currently being shown.
pub fn move_to_output(self, output: Connector) {
get!().move_to_output(WorkspaceSource::Explicit(self), output);
}
}

/// Returns the workspace with the given name.
Expand Down
5 changes: 2 additions & 3 deletions src/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,9 +440,8 @@ fn create_dummy_output(state: &Rc<State>) {
title_texture: Cell::new(None),
attention_requests: Default::default(),
});
dummy_workspace.output_link.set(Some(
dummy_output.workspaces.add_last(dummy_workspace.clone()),
));
*dummy_workspace.output_link.borrow_mut() =
Some(dummy_output.workspaces.add_last(dummy_workspace.clone()));
dummy_output.show_workspace(&dummy_workspace);
state.dummy_output.set(Some(dummy_output));
}
Expand Down
52 changes: 50 additions & 2 deletions src/config/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ use {
scale::Scale,
state::{ConnectorData, DeviceHandlerData, DrmDevData, OutputData, State},
theme::{Color, ThemeSized, DEFAULT_FONT},
tree::{ContainerNode, ContainerSplit, FloatNode, Node, NodeVisitorBase, OutputNode},
tree::{
move_ws_to_output, ContainerNode, ContainerSplit, FloatNode, Node, NodeVisitorBase,
OutputNode, WsMoveConfig,
},
utils::{
asyncevent::AsyncEvent,
copyhashmap::CopyHashMap,
Expand All @@ -29,7 +32,7 @@ use {
jay_config::{
_private::{
bincode_ops,
ipc::{ClientMessage, Response, ServerMessage},
ipc::{ClientMessage, Response, ServerMessage, WorkspaceSource},
PollableId, WireMode,
},
input::{
Expand Down Expand Up @@ -753,6 +756,45 @@ impl ConfigProxyHandler {
Ok(())
}

fn handle_move_to_output(
&self,
workspace: WorkspaceSource,
connector: Connector,
) -> Result<(), CphError> {
let output = self.get_output(connector)?;
let ws = match workspace {
WorkspaceSource::Explicit(ws) => {
let name = self.get_workspace(ws)?;
match self.state.workspaces.get(name.as_str()) {
Some(ws) => ws,
_ => return Ok(()),
}
}
WorkspaceSource::Seat(s) => match self.get_seat(s)?.get_output().workspace.get() {
Some(ws) => ws,
_ => return Ok(()),
},
};
if ws.is_dummy || output.node.is_dummy {
return Ok(());
}
if ws.output.get().id == output.node.id {
return Ok(());
}
let link = match &*ws.output_link.borrow() {
None => return Ok(()),
Some(l) => l.to_ref(),
};
let config = WsMoveConfig {
make_visible_if_empty: true,
source_is_destroyed: false,
};
move_ws_to_output(&link, &output.node, config);
self.state.tree_changed();
self.state.damage();
Ok(())
}

fn handle_set_idle(&self, timeout: Duration) {
self.state.idle.set_timeout(timeout);
}
Expand Down Expand Up @@ -1676,6 +1718,12 @@ impl ConfigProxyHandler {
.handle_get_input_device_devnode(device)
.wrn("get_input_device_devnode")?,
ClientMessage::SetIdle { timeout } => self.handle_set_idle(timeout),
ClientMessage::MoveToOutput {
workspace,
connector,
} => self
.handle_move_to_output(workspace, connector)
.wrn("move_to_output")?,
}
Ok(())
}
Expand Down
3 changes: 3 additions & 0 deletions src/ifs/wl_surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,9 @@ impl WlSurface {
}
self.send_seat_release_events();
self.seat_state.destroy_node(self);
if self.visible.get() {
self.client.state.damage();
}
}

pub fn set_content_type(&self, content_type: Option<ContentType>) {
Expand Down
1 change: 1 addition & 0 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,7 @@ impl State {
ws.flush_jay_workspaces();
output.schedule_update_render_data();
self.tree_changed();
self.damage();
// let seats = self.globals.seats.lock();
// for seat in seats.values() {
// seat.workspace_changed(&output);
Expand Down
109 changes: 44 additions & 65 deletions src/tasks/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ use {
backend::{Connector, ConnectorEvent, ConnectorId, MonitorInfo},
ifs::wl_output::{OutputId, PersistentOutputState, WlOutputGlobal},
state::{ConnectorData, OutputData, State},
tree::{OutputNode, OutputRenderData},
tree::{move_ws_to_output, OutputNode, OutputRenderData, WsMoveConfig},
utils::{asyncevent::AsyncEvent, clonecell::CloneCell},
},
std::{
cell::{Cell, RefCell},
collections::VecDeque,
rc::Rc,
},
};
Expand Down Expand Up @@ -156,6 +157,8 @@ impl ConnectorHandler {
node: on.clone(),
});
self.state.outputs.set(self.id, output_data);
global.node.set(Some(on.clone()));
let mut ws_to_move = VecDeque::new();
if self.state.outputs.len() == 1 {
let seats = self.state.globals.seats.lock();
let pos = global.pos.get();
Expand All @@ -164,59 +167,45 @@ impl ConnectorHandler {
for seat in seats.values() {
seat.set_position(x, y);
}
}
global.node.set(Some(on.clone()));
if let Some(config) = self.state.config.get() {
config.connector_connected(self.id);
}
{
for source in self.state.outputs.lock().values() {
if source.node.id == on.id {
let dummy = self.state.dummy_output.get().unwrap();
for ws in dummy.workspaces.iter() {
if ws.is_dummy {
continue;
}
let mut ws_to_move = vec![];
for ws in source.node.workspaces.iter() {
if ws.is_dummy {
continue;
}
if ws.desired_output.get() == global.output_id {
ws_to_move.push(ws.clone());
}
}
for ws in ws_to_move {
ws.set_output(&on);
on.workspaces.add_last_existing(&ws);
if ws.visible_on_desired_output.get() && on.workspace.is_none() {
on.show_workspace(&ws);
} else {
ws.set_visible(false);
}
ws.flush_jay_workspaces();
if let Some(visible) = source.node.workspace.get() {
if visible.id == ws.id {
source.node.workspace.take();
}
}
}
if source.node.workspace.is_none() {
if let Some(ws) = source.node.workspaces.first() {
source.node.show_workspace(&ws);
ws.flush_jay_workspaces();
}
}
source.node.schedule_update_render_data();
ws_to_move.push_back(ws);
}
}
for source in self.state.outputs.lock().values() {
if source.node.id == on.id {
continue;
}
if on.workspace.is_none() {
if let Some(ws) = on.workspaces.first() {
on.show_workspace(&ws);
ws.flush_jay_workspaces();
for ws in source.node.workspaces.iter() {
if ws.is_dummy {
continue;
}
if ws.desired_output.get() == global.output_id {
ws_to_move.push_back(ws.clone());
}
}
}
on.schedule_update_render_data();
while let Some(ws) = ws_to_move.pop_front() {
let make_visible = (ws.visible_on_desired_output.get()
&& ws.desired_output.get() == output_id)
|| ws_to_move.is_empty();
let config = WsMoveConfig {
make_visible_if_empty: make_visible,
source_is_destroyed: false,
};
move_ws_to_output(&ws, &on, config);
}
if let Some(config) = self.state.config.get() {
config.connector_connected(self.id);
}
self.state.root.outputs.set(self.id, on.clone());
self.state.root.update_extents();
self.state.add_global(&global);
self.state.tree_changed();
self.state.damage();
'outer: loop {
while let Some(event) = self.data.connector.event() {
match event {
Expand Down Expand Up @@ -261,31 +250,19 @@ impl ConnectorHandler {
surface.send_closed();
}
}
let mut target_is_dummy = false;
let target = match self.state.outputs.lock().values().next() {
Some(o) => o.node.clone(),
_ => {
target_is_dummy = true;
self.state.dummy_output.get().unwrap()
}
_ => self.state.dummy_output.get().unwrap(),
};
if !on.workspaces.is_empty() {
for ws in on.workspaces.iter() {
let is_visible =
!target_is_dummy && target.workspaces.is_empty() && ws.visible.get();
for ws in on.workspaces.iter() {
if ws.desired_output.get() == output_id {
ws.visible_on_desired_output.set(ws.visible.get());
ws.set_output(&target);
target.workspaces.add_last_existing(&ws);
if is_visible {
target.show_workspace(&ws);
} else if ws.visible.get() {
ws.set_visible(false);
}
ws.flush_jay_workspaces();
}
target.schedule_update_render_data();
self.state.tree_changed();
self.state.damage();
let config = WsMoveConfig {
make_visible_if_empty: ws.visible.get(),
source_is_destroyed: true,
};
move_ws_to_output(&ws, &target, config);
}
let seats = self.state.globals.seats.lock();
for seat in seats.values() {
Expand All @@ -300,5 +277,7 @@ impl ConnectorHandler {
self.state
.remove_output_scale(on.global.persistent.scale.get());
let _ = self.state.remove_global(&*global);
self.state.tree_changed();
self.state.damage();
}
}
5 changes: 2 additions & 3 deletions src/tree/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ impl OutputNode {
stacked: Default::default(),
seat_state: Default::default(),
name: name.to_string(),
output_link: Cell::new(None),
output_link: Default::default(),
visible: Cell::new(false),
fullscreen: Default::default(),
visible_on_desired_output: Cell::new(false),
Expand All @@ -347,8 +347,7 @@ impl OutputNode {
title_texture: Default::default(),
attention_requests: Default::default(),
});
ws.output_link
.set(Some(self.workspaces.add_last(ws.clone())));
*ws.output_link.borrow_mut() = Some(self.workspaces.add_last(ws.clone()));
self.state.workspaces.set(name.to_string(), ws.clone());
if self.workspace.is_none() {
self.show_workspace(&ws);
Expand Down
Loading

0 comments on commit 1401697

Please sign in to comment.