summaryrefslogtreecommitdiffstats
path: root/zellij-server
diff options
context:
space:
mode:
Diffstat (limited to 'zellij-server')
-rw-r--r--zellij-server/src/panes/floating_panes/mod.rs3
-rw-r--r--zellij-server/src/panes/tiled_panes/mod.rs6
-rw-r--r--zellij-server/src/plugins/mod.rs4
-rw-r--r--zellij-server/src/plugins/unit/plugin_tests.rs93
-rw-r--r--zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__load_new_plugin_with_plugin_alias.snap12
-rw-r--r--zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__start_or_reload_plugin.snap22
-rw-r--r--zellij-server/src/screen.rs11
-rw-r--r--zellij-server/src/tab/layout_applier.rs2
-rw-r--r--zellij-server/src/unit/screen_tests.rs177
9 files changed, 308 insertions, 22 deletions
diff --git a/zellij-server/src/panes/floating_panes/mod.rs b/zellij-server/src/panes/floating_panes/mod.rs
index c8c8b42b6..572a75629 100644
--- a/zellij-server/src/panes/floating_panes/mod.rs
+++ b/zellij-server/src/panes/floating_panes/mod.rs
@@ -887,7 +887,8 @@ impl FloatingPanes {
.find(|(_id, s_p)| {
match s_p.invoked_with() {
// Some(Run::Plugin(RunPluginOrAlias::Alias(pane_alias))) => pane_alias.name == plugin_alias.name,
- Some(Run::Plugin(RunPluginOrAlias::Alias(pane_alias))) => pane_alias.name == plugin_alias.name && pane_alias.configuration == plugin_alias.configuration,
+ Some(Run::Plugin(RunPluginOrAlias::Alias(pane_alias))) => pane_alias.name == plugin_alias.name &&
+ pane_alias.configuration.as_ref().and_then(|c| if c.inner().is_empty() { None } else { Some(c)} ) == plugin_alias.configuration.as_ref().and_then(|c| if c.inner().is_empty() { None } else { Some(c) }),
_ => false
}
})
diff --git a/zellij-server/src/panes/tiled_panes/mod.rs b/zellij-server/src/panes/tiled_panes/mod.rs
index 57444c4e9..be973444a 100644
--- a/zellij-server/src/panes/tiled_panes/mod.rs
+++ b/zellij-server/src/panes/tiled_panes/mod.rs
@@ -1754,11 +1754,15 @@ impl TiledPanes {
.map(|(id, _)| *id)
}
RunPluginOrAlias::Alias(plugin_alias) => {
+ eprintln!("plugin_alias: {:?}", plugin_alias);
self.panes
.iter()
.find(|(_id, s_p)| {
+ eprintln!("comparing with: {:?}", s_p.invoked_with());
match s_p.invoked_with() {
- Some(Run::Plugin(RunPluginOrAlias::Alias(pane_alias))) => pane_alias.name == plugin_alias.name && pane_alias.configuration == plugin_alias.configuration,
+ Some(Run::Plugin(RunPluginOrAlias::Alias(pane_alias))) => pane_alias.name == plugin_alias.name &&
+ pane_alias.configuration.as_ref().and_then(|c| if c.inner().is_empty() { None } else { Some(c)} ) == plugin_alias.configuration.as_ref().and_then(|c| if c.inner().is_empty() { None } else { Some(c) }),
+ // Some(Run::Plugin(RunPluginOrAlias::Alias(pane_alias))) => pane_alias.name == plugin_alias.name && pane_alias.configuration == plugin_alias.configuration,
_ => false
}
})
diff --git a/zellij-server/src/plugins/mod.rs b/zellij-server/src/plugins/mod.rs
index e816d1578..5c5903bc2 100644
--- a/zellij-server/src/plugins/mod.rs
+++ b/zellij-server/src/plugins/mod.rs
@@ -190,12 +190,16 @@ pub(crate) fn plugin_thread_main(
let mut plugin_aliases = HashMap::new();
let mut filter_configuration = BTreeMap::new();
filter_configuration.insert("key_from_dict".to_owned(), "value_from_dict".to_owned());
+
+ // TODO: from config
plugin_aliases.insert("session-manager-alias", RunPlugin::from_url("zellij:session-manager").unwrap());
plugin_aliases.insert("filepicker", RunPlugin::from_url("zellij:strider").unwrap());
+ plugin_aliases.insert("fixture_plugin_for_tests", RunPlugin::from_url(&format!("file:{}/../target/e2e-data/plugins/fixture-plugin-for-tests.wasm", std::env::var_os("CARGO_MANIFEST_DIR").unwrap().to_string_lossy())).unwrap());
plugin_aliases.insert(
"filter",
RunPlugin::from_url("file:/home/aram/code/rust-plugin-example/target/wasm32-wasi/debug/rust-plugin-example.wasm").unwrap().with_configuration(filter_configuration)
);
+
layout.populate_plugin_aliases_in_layout(&plugin_aliases);
let store = Arc::new(Mutex::new(store));
diff --git a/zellij-server/src/plugins/unit/plugin_tests.rs b/zellij-server/src/plugins/unit/plugin_tests.rs
index ebec7bec5..5b2c71feb 100644
--- a/zellij-server/src/plugins/unit/plugin_tests.rs
+++ b/zellij-server/src/plugins/unit/plugin_tests.rs
@@ -8,7 +8,7 @@ use tempfile::tempdir;
use wasmer::Store;
use zellij_utils::data::{Event, Key, PermissionStatus, PermissionType, PluginCapabilities};
use zellij_utils::errors::ErrorContext;
-use zellij_utils::input::layout::{Layout, PluginUserConfiguration, RunPlugin, RunPluginOrAlias, RunPluginLocation};
+use zellij_utils::input::layout::{Layout, PluginUserConfiguration, RunPlugin, RunPluginOrAlias, RunPluginLocation, PluginAlias};
use zellij_utils::input::permission::PermissionCache;
use zellij_utils::input::plugins::PluginsConfig;
use zellij_utils::ipc::ClientAttributes;
@@ -621,6 +621,93 @@ pub fn load_new_plugin_from_hd() {
#[test]
#[ignore]
+pub fn load_new_plugin_with_plugin_alias() {
+ // here we load our fixture plugin into the plugin thread, and then send it an update message
+ // expecting tha thte plugin will log the received event and render it later after the update
+ // message (this is what the fixture plugin does)
+ // we then listen on our mock screen receiver to make sure we got a PluginBytes instruction
+ // that contains said render, and assert against it
+ let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its
+ let plugin_host_folder = PathBuf::from(temp_folder.path());
+ let cache_path = plugin_host_folder.join("permissions_test.kdl");
+ let (plugin_thread_sender, screen_receiver, teardown) = create_plugin_thread(None);
+ let plugin_should_float = Some(false);
+ let plugin_title = Some("test_plugin".to_owned());
+ // TODO: CONTINUE HERE (16/2)
+ // - add an alias version of this test - DONE
+ // - then make a version of the layout_with_plugin_panes test that also includes aliases (or
+ // add it to that test?) - N/A
+ // - then look through this file to see what other tests we can add, then look at more tests
+ // in these files:
+ // - plugin_tests
+ // - screen_tests
+ let run_plugin = RunPluginOrAlias::Alias(PluginAlias {
+ name: "fixture_plugin_for_tests".to_owned(),
+ configuration: Default::default(),
+ run_plugin: None,
+ });
+ let tab_index = 1;
+ let client_id = 1;
+ let size = Size {
+ cols: 121,
+ rows: 20,
+ };
+ let received_screen_instructions = Arc::new(Mutex::new(vec![]));
+ let screen_thread = grant_permissions_and_log_actions_in_thread!(
+ received_screen_instructions,
+ ScreenInstruction::PluginBytes,
+ screen_receiver,
+ 1,
+ &PermissionType::ChangeApplicationState,
+ cache_path,
+ plugin_thread_sender,
+ client_id
+ );
+
+ let _ = plugin_thread_sender.send(PluginInstruction::AddClient(client_id));
+ let _ = plugin_thread_sender.send(PluginInstruction::Load(
+ plugin_should_float,
+ false,
+ plugin_title,
+ run_plugin,
+ tab_index,
+ None,
+ client_id,
+ size,
+ None,
+ false,
+ ));
+ std::thread::sleep(std::time::Duration::from_millis(500));
+ let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
+ None,
+ Some(client_id),
+ Event::InputReceived,
+ )])); // will be cached and sent to the plugin once it's loaded
+ screen_thread.join().unwrap(); // this might take a while if the cache is cold
+ teardown();
+ let plugin_bytes_event = received_screen_instructions
+ .lock()
+ .unwrap()
+ .iter()
+ .find_map(|i| {
+ if let ScreenInstruction::PluginBytes(plugin_render_assets) = i {
+ for plugin_render_asset in plugin_render_assets {
+ let plugin_id = plugin_render_asset.plugin_id;
+ let client_id = plugin_render_asset.client_id;
+ let plugin_bytes = plugin_render_asset.bytes.clone();
+ let plugin_bytes = String::from_utf8_lossy(plugin_bytes.as_slice()).to_string();
+ if plugin_bytes.contains("InputReceived") {
+ return Some((plugin_id, client_id, plugin_bytes));
+ }
+ }
+ }
+ None
+ });
+ assert_snapshot!(format!("{:#?}", plugin_bytes_event));
+}
+
+#[test]
+#[ignore]
pub fn plugin_workers() {
let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its
// destructor removes the directory
@@ -5324,7 +5411,7 @@ pub fn granted_permission_request_result() {
let permission_cache = PermissionCache::from_path_or_default(Some(cache_path));
let mut permissions = permission_cache
- .get_permissions(run_plugin.location_string())
+ .get_permissions(PathBuf::from(&*PLUGIN_FIXTURE).display().to_string())
.clone();
let permissions = permissions.as_mut().map(|p| {
let mut permissions = p.clone();
@@ -5413,7 +5500,7 @@ pub fn denied_permission_request_result() {
teardown();
let permission_cache = PermissionCache::from_path_or_default(Some(cache_path));
- let permissions = permission_cache.get_permissions(run_plugin.location_string());
+ let permissions = permission_cache.get_permissions(PathBuf::from(&*PLUGIN_FIXTURE).display().to_string());
assert_snapshot!(format!("{:#?}", permissions));
}
diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__load_new_plugin_with_plugin_alias.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__load_new_plugin_with_plugin_alias.snap
new file mode 100644
index 000000000..b5b7ef4a3
--- /dev/null
+++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__load_new_plugin_with_plugin_alias.snap
@@ -0,0 +1,12 @@
+---
+source: zellij-server/src/plugins/./unit/plugin_tests.rs
+assertion_line: 706
+expression: "format!(\"{:#?}\", plugin_bytes_event)"
+---
+Some(
+ (
+ 0,
+ 1,
+ "Rows: 20, Cols: 121, Received events: [InputReceived]\n\r",
+ ),
+)
diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__start_or_reload_plugin.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__start_or_reload_plugin.snap
index 05002124a..a55b17ecf 100644
--- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__start_or_reload_plugin.snap
+++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__start_or_reload_plugin.snap
@@ -1,19 +1,21 @@
---
source: zellij-server/src/plugins/./unit/plugin_tests.rs
-assertion_line: 2931
+assertion_line: 3700
expression: "format!(\"{:#?}\", new_tab_event)"
---
Some(
StartOrReloadPluginPane(
- RunPlugin {
- _allow_exec_host_cmd: false,
- location: File(
- "/path/to/my/plugin.wasm",
- ),
- configuration: PluginUserConfiguration(
- {},
- ),
- },
+ RunPlugin(
+ RunPlugin {
+ _allow_exec_host_cmd: false,
+ location: File(
+ "/path/to/my/plugin.wasm",
+ ),
+ configuration: PluginUserConfiguration(
+ {},
+ ),
+ },
+ ),
None,
),
)
diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs
index 03b768586..d0789e9ce 100644
--- a/zellij-server/src/screen.rs
+++ b/zellij-server/src/screen.rs
@@ -1747,13 +1747,16 @@ impl Screen {
client_id: ClientId,
) -> Result<bool> {
// true => found and focused, false => not
+ log::info!("focus_plugin_pane");
let err_context = || format!("failed to focus_plugin_pane");
let mut tab_index_and_plugin_pane_id = None;
let mut plugin_pane_to_move_to_active_tab = None;
let focused_tab_index = *self.active_tab_indices.get(&client_id).unwrap_or(&0);
let all_tabs = self.get_tabs_mut();
for (tab_index, tab) in all_tabs.iter_mut() {
+ log::info!("finding plugin...");
if let Some(plugin_pane_id) = tab.find_plugin(&run_plugin) {
+ log::info!("found it!");
tab_index_and_plugin_pane_id = Some((*tab_index, plugin_pane_id));
if move_to_focused_tab && focused_tab_index != *tab_index {
plugin_pane_to_move_to_active_tab =
@@ -3474,7 +3477,7 @@ pub(crate) fn screen_thread_main(
skip_cache,
client_id,
) => match pane_id_to_replace {
- Some(pane_id_to_replace) => match screen.active_tab_indices.values().next() {
+ Some(pane_id_to_replace) if should_open_in_place => match screen.active_tab_indices.values().next() {
Some(tab_index) => {
let size = Size::default();
screen
@@ -3500,8 +3503,7 @@ pub(crate) fn screen_thread_main(
);
},
},
- None => {
- log::info!("run_plugin: {:?}", run_plugin);
+ _ => {
let client_id = if screen.active_tab_indices.contains_key(&client_id) {
Some(client_id)
} else {
@@ -3515,15 +3517,18 @@ pub(crate) fn screen_thread_main(
});
match client_id_and_focused_tab {
Some((tab_index, client_id)) => {
+ eprintln!("focus plugin pane??: {:?}", run_plugin);
if screen.focus_plugin_pane(
&run_plugin,
should_float,
move_to_focused_tab,
client_id,
)? {
+ eprintln!("can has focus plugin pane");
screen.render(None)?;
screen.log_and_report_session_state()?;
} else {
+ eprintln!("no!!");
screen
.bus
.senders
diff --git a/zellij-server/src/tab/layout_applier.rs b/zellij-server/src/tab/layout_applier.rs
index 34a71b22e..4f5246d33 100644
--- a/zellij-server/src/tab/layout_applier.rs
+++ b/zellij-server/src/tab/layout_applier.rs
@@ -269,11 +269,13 @@ impl<'a> LayoutApplier<'a> {
// if let Some(run_plugin) = layout.run.as_ref().and_then(|r| r.get_run_plugin()) {
if let Some(Run::Plugin(run)) = layout.run.clone() {
let pane_title = run.location_string();
+ eprintln!("new_plugin_ids: {:#?}, \nrun: {:#?}", new_plugin_ids, run);
let pid = new_plugin_ids
// .get_mut(&(run_plugin.location, run_plugin.configuration))
.get_mut(&run)
.and_then(|ids| ids.pop())
.with_context(err_context)?;
+ eprintln!("not here!");
let mut new_plugin = PluginPane::new(
pid,
*position_and_size,
diff --git a/zellij-server/src/unit/screen_tests.rs b/zellij-server/src/unit/screen_tests.rs
index 78846947b..52486e31d 100644
--- a/zellij-server/src/unit/screen_tests.rs
+++ b/zellij-server/src/unit/screen_tests.rs
@@ -16,7 +16,7 @@ use zellij_utils::input::actions::Action;
use zellij_utils::input::command::{RunCommand, TerminalAction};
use zellij_utils::input::layout::{
FloatingPaneLayout, Layout, Run, RunPlugin, RunPluginOrAlias, RunPluginLocation, SplitDirection, SplitSize,
- TiledPaneLayout,
+ TiledPaneLayout, PluginAlias, PluginUserConfiguration,
};
use zellij_utils::input::options::Options;
use zellij_utils::ipc::IpcReceiverWithContext;
@@ -374,6 +374,93 @@ impl MockScreen {
self.last_opened_tab_index = Some(tab_index);
screen_thread
}
+ // same as the above function, but starts a plugin with a plugin alias
+ pub fn run_with_alias(
+ &mut self,
+ initial_layout: Option<TiledPaneLayout>,
+ initial_floating_panes_layout: Vec<FloatingPaneLayout>,
+ ) -> std::thread::JoinHandle<()> {
+ let config_options = self.config_options.clone();
+ let client_attributes = self.client_attributes.clone();
+ let screen_bus = Bus::new(
+ vec![self.screen_receiver.take().unwrap()],
+ None,
+ Some(&self.to_pty.clone()),
+ Some(&self.to_plugin.clone()),
+ Some(&self.to_server.clone()),
+ Some(&self.to_pty_writer.clone()),
+ Some(&self.to_background_jobs.clone()),
+ Some(Box::new(self.os_input.clone())),
+ )
+ .should_silently_fail();
+ let debug = false;
+ let screen_thread = std::thread::Builder::new()
+ .name("screen_thread".to_string())
+ .spawn(move || {
+ set_var("ZELLIJ_SESSION_NAME", "zellij-test");
+ screen_thread_main(
+ screen_bus,
+ None,
+ client_attributes,
+ Box::new(config_options),
+ debug,
+ Box::new(Layout::default()),
+ )
+ .expect("TEST")
+ })
+ .unwrap();
+ let pane_layout = initial_layout.unwrap_or_default();
+ let pane_count = pane_layout.extract_run_instructions().len();
+ let floating_pane_count = initial_floating_panes_layout.len();
+ let mut pane_ids = vec![];
+ let mut floating_pane_ids = vec![];
+ let mut plugin_ids = HashMap::new();
+ plugin_ids.insert(
+ RunPluginOrAlias::Alias(PluginAlias {
+ name: "fixture_plugin_for_tests".to_owned(),
+ configuration: Some(Default::default()),
+ run_plugin: Some(RunPlugin {
+ location: RunPluginLocation::parse("file:/path/to/fake/plugin", None).unwrap(),
+ configuration: PluginUserConfiguration::default(),
+ ..Default::default()
+ }),
+ ..Default::default()
+ }),
+ vec![1],
+ );
+ for i in 0..pane_count {
+ pane_ids.push((i as u32, None));
+ }
+ for i in 0..floating_pane_count {
+ floating_pane_ids.push((i as u32, None));
+ }
+ let default_shell = None;
+ let tab_name = None;
+ let tab_index = self.last_opened_tab_index.map(|l| l + 1).unwrap_or(0);
+ let _ = self.to_screen.send(ScreenInstruction::NewTab(
+ None,
+ default_shell,
+ Some(pane_layout.clone()),
+ initial_floating_panes_layout.clone(),
+ // vec![], // floating_panes_layout
+ tab_name,
+ (vec![], vec![]), // swap layouts
+ self.main_client_id,
+ ));
+ let _ = self.to_screen.send(ScreenInstruction::ApplyLayout(
+ pane_layout,
+ initial_floating_panes_layout,
+ // vec![], // floating panes layout
+ pane_ids,
+ floating_pane_ids,
+ // vec![], // floating pane ids
+ plugin_ids,
+ tab_index,
+ self.main_client_id,
+ ));
+ self.last_opened_tab_index = Some(tab_index);
+ screen_thread
+ }
pub fn new_tab(&mut self, tab_layout: TiledPaneLayout) {
let pane_count = tab_layout.extract_run_instructions().len();
let mut pane_ids = vec![];
@@ -2737,7 +2824,7 @@ pub fn send_cli_launch_or_focus_plugin_action() {
floating: true,
in_place: false,
move_to_focused_tab: true,
- url: url::Url::parse("file:/path/to/fake/plugin").unwrap(),
+ url: "file:/path/to/fake/plugin".to_owned(),
configuration: Default::default(),
skip_plugin_cache: false,
};
@@ -2797,7 +2884,90 @@ pub fn send_cli_launch_or_focus_plugin_action_when_plugin_is_already_loaded() {
floating: true,
in_place: false,
move_to_focused_tab: true,
- url: url::Url::parse("file:/path/to/fake/plugin").unwrap(),
+ url: "file:/path/to/fake/plugin".to_owned(),
+ configuration: Default::default(),
+ skip_plugin_cache: false,
+ };
+ send_cli_action_to_server(&session_metadata, cli_action, client_id);
+ std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
+ mock_screen.teardown(vec![plugin_thread, server_thread, screen_thread]);
+
+ let plugin_load_instruction_sent = received_plugin_instructions
+ .lock()
+ .unwrap()
+ .iter()
+ .find(|instruction| match instruction {
+ PluginInstruction::Load(..) => true,
+ _ => false,
+ })
+ .is_some();
+ assert!(
+ !plugin_load_instruction_sent,
+ "Plugin Load instruction should not be sent for an already loaded plugin"
+ );
+ let snapshots = take_snapshots_and_cursor_coordinates_from_render_events(
+ received_server_instructions.lock().unwrap().iter(),
+ size,
+ );
+ let snapshot_count = snapshots.len();
+ assert_eq!(
+ snapshot_count, 2,
+ "Another render was sent for focusing the already loaded plugin"
+ );
+ for (cursor_coordinates, _snapshot) in snapshots.iter().skip(1) {
+ assert!(
+ cursor_coordinates.is_none(),
+ "Cursor moved to existing plugin in final snapshot indicating focus changed"
+ );
+ }
+}
+
+#[test]
+pub fn send_cli_launch_or_focus_plugin_action_when_plugin_is_already_loaded_for_plugin_alias() {
+ let size = Size {
+ cols: 121,
+ rows: 20,
+ };
+ let client_id = 10; // fake client id should not appear in the screen's state
+ let mut mock_screen = MockScreen::new(size);
+ let plugin_receiver = mock_screen.plugin_receiver.take().unwrap();
+ let session_metadata = mock_screen.clone_session_metadata();
+ let mut initial_layout = TiledPaneLayout::default();
+ let existing_plugin_pane = TiledPaneLayout {
+ run: Some(Run::Plugin(RunPluginOrAlias::Alias(PluginAlias {
+ name: "fixture_plugin_for_tests".to_owned(),
+ configuration: Some(Default::default()),
+ run_plugin: Some(RunPlugin {
+ _allow_exec_host_cmd: false,
+ location: RunPluginLocation::File(PathBuf::from("/path/to/fake/plugin")),
+ configuration: Default::default(),
+ }),
+ ..Default::default()
+ }))),
+ ..Default::default()
+ };
+ initial_layout.children_split_direction = SplitDirection::Vertical;
+ initial_layout.children = vec![TiledPaneLayout::default(), existing_plugin_pane];
+ let screen_thread = mock_screen.run_with_alias(Some(initial_layout), vec![]);
+ let received_plugin_instructions = Arc::new(Mutex::new(vec![]));
+ let plugin_thread = log_actions_in_thread!(
+ received_plugin_instructions,
+ PluginInstruction::Exit,
+ plugin_receiver
+ );
+ let received_server_instructions = Arc::new(Mutex::new(vec![]));
+ let server_receiver = mock_screen.server_receiver.take().unwrap();
+ let server_thread = log_actions_in_thread!(
+ received_server_instructions,
+ ServerInstruction::KillSession,
+ server_receiver
+ );
+ let cli_action = CliAction::LaunchOrFocusPlugin {
+ floating: true,
+ in_place: false,
+ move_to_focused_tab: true,
+ url: "fixture_plugin_for_tests".to_owned(),
+ // url: url::Url::parse("file:/path/to/fake/plugin").unwrap(),
configuration: Default::default(),
skip_plugin_cache: false,
};
@@ -3135,7 +3305,6 @@ pub fn screen_can_break_floating_plugin_pane_to_a_new_tab() {
// through the plugin and pty threads (to open extra stuff we need in the layout, eg. the
// default plugins)
floating_panes_layout.get_mut(0).unwrap().already_running = true;
- eprintln!("floating_panes_layout: {:#?}", floating_panes_layout);
let _ = mock_screen.to_screen.send(ScreenInstruction::ApplyLayout(
TiledPaneLayout::default(),
floating_panes_layout,