mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-30 20:34:49 +01:00
Remove old layout system completely
This commit is contained in:
parent
a98777c11e
commit
75852551e2
8 changed files with 3 additions and 408 deletions
|
@ -24,7 +24,6 @@ build = {
|
|||
["pinnacle.output"] = "pinnacle/output.lua",
|
||||
["pinnacle.process"] = "pinnacle/process.lua",
|
||||
["pinnacle.tag"] = "pinnacle/tag.lua",
|
||||
["pinnacle.tag.layout"] = "pinnacle/tag/layout.lua",
|
||||
["pinnacle.window"] = "pinnacle/window.lua",
|
||||
["pinnacle.util"] = "pinnacle/util.lua",
|
||||
["pinnacle.signal"] = "pinnacle/signal.lua",
|
||||
|
|
|
@ -14,9 +14,6 @@ local rpc_types = {
|
|||
OutputConnect = {
|
||||
response_type = "OutputConnectResponse",
|
||||
},
|
||||
Layout = {
|
||||
response_type = "LayoutResponse",
|
||||
},
|
||||
WindowPointerEnter = {
|
||||
response_type = "WindowPointerEnterResponse",
|
||||
},
|
||||
|
@ -65,17 +62,6 @@ local signals = {
|
|||
---@type fun(response: table)
|
||||
on_response = nil,
|
||||
},
|
||||
Layout = {
|
||||
---@nodoc
|
||||
---@type H2Stream?
|
||||
sender = nil,
|
||||
---@nodoc
|
||||
---@type (fun(tag: TagHandle, windows: WindowHandle[]))[]
|
||||
callbacks = {},
|
||||
---@nodoc
|
||||
---@type fun(response: table)
|
||||
on_response = nil,
|
||||
},
|
||||
WindowPointerEnter = {
|
||||
---@nodoc
|
||||
---@type H2Stream?
|
||||
|
@ -108,17 +94,6 @@ signals.OutputConnect.on_response = function(response)
|
|||
end
|
||||
end
|
||||
|
||||
signals.Layout.on_response = function(response)
|
||||
---@diagnostic disable-next-line: invisible
|
||||
local window_handles = require("pinnacle.window").handle.new_from_table(response.window_ids or {})
|
||||
---@diagnostic disable-next-line: invisible
|
||||
local tag_handle = require("pinnacle.tag").handle.new(response.tag_id)
|
||||
|
||||
for _, callback in ipairs(signals.Layout.callbacks) do
|
||||
callback(tag_handle, window_handles)
|
||||
end
|
||||
end
|
||||
|
||||
signals.WindowPointerEnter.on_response = function(response)
|
||||
---@diagnostic disable-next-line: invisible
|
||||
local window_handle = require("pinnacle.window").handle.new(response.window_id)
|
||||
|
|
|
@ -17,7 +17,6 @@ local rpc_types = {
|
|||
response_type = "AddResponse",
|
||||
},
|
||||
Remove = {},
|
||||
SetLayout = {},
|
||||
Get = {
|
||||
response_type = "GetResponse",
|
||||
},
|
||||
|
@ -211,165 +210,6 @@ function tag.remove(tags)
|
|||
client.unary_request(build_grpc_request_params("Remove", { tag_ids = ids }))
|
||||
end
|
||||
|
||||
---@class LayoutCycler
|
||||
---@field next fun(output: OutputHandle?)
|
||||
---@field prev fun(output: OutputHandle?)
|
||||
|
||||
---Create a layout cycler that will cycle layouts on the given output.
|
||||
---
|
||||
---This returns a `LayoutCycler` table with two fields, both functions that take in an optional `OutputHandle`:
|
||||
--- - `next`: Cycle to the next layout on the given output
|
||||
--- - `prev`: Cycle to the previous layout on the given output
|
||||
---
|
||||
---If the output isn't specified then the focused one will be used.
|
||||
---
|
||||
---Internally, this will only change the layout of the first active tag on the output
|
||||
---because that is the one that determines the layout.
|
||||
---
|
||||
---### Example
|
||||
---```lua
|
||||
--- ---@type LayoutCycler[]
|
||||
---local layouts = {
|
||||
--- "master_stack",
|
||||
--- "dwindle",
|
||||
--- "corner_top_left",
|
||||
--- "corner_top_right".
|
||||
---} -- Only cycle between these four layouts
|
||||
---
|
||||
---local layout_cycler = Tag.new_layout_cycler()
|
||||
---
|
||||
--- -- Assume the focused output starts with the "master_stack" layout
|
||||
---layout_cycler.next() -- Layout is now "dwindle"
|
||||
---layout_cycler.next() -- Layout is now "corner_top_left"
|
||||
---layout_cycler.next() -- Layout is now "corner_top_right"
|
||||
---layout_cycler.next() -- Layout is now "master_stack"
|
||||
---layout_cycler.next() -- Layout is now "dwindle"
|
||||
---
|
||||
--- -- Cycling on another output
|
||||
---layout_cycler.next(Output.get_by_name("eDP-1"))
|
||||
---layout_cycler.prev(Output.get_by_name("HDMI-1"))
|
||||
---```
|
||||
---
|
||||
---@param layouts LayoutOld[]
|
||||
---
|
||||
---@return LayoutCycler
|
||||
function tag.new_layout_cycler(layouts)
|
||||
local indices = {}
|
||||
|
||||
if #layouts == 0 then
|
||||
return {
|
||||
next = function(_) end,
|
||||
prev = function(_) end,
|
||||
}
|
||||
end
|
||||
|
||||
---@type LayoutCycler
|
||||
return {
|
||||
next = function(output)
|
||||
---@diagnostic disable-next-line: redefined-local
|
||||
local output = output or require("pinnacle.output").get_focused()
|
||||
if not output then
|
||||
return
|
||||
end
|
||||
|
||||
local tags = output:props().tags or {}
|
||||
|
||||
for _, tg in ipairs(tags) do
|
||||
if tg:props().active then
|
||||
local id = tg.id
|
||||
if #layouts == 1 then
|
||||
indices[id] = 1
|
||||
elseif indices[id] == nil then
|
||||
indices[id] = 2
|
||||
else
|
||||
if indices[id] + 1 > #layouts then
|
||||
indices[id] = 1
|
||||
else
|
||||
indices[id] = indices[id] + 1
|
||||
end
|
||||
end
|
||||
|
||||
tg:set_layout(layouts[indices[id]])
|
||||
break
|
||||
end
|
||||
end
|
||||
end,
|
||||
prev = function(output)
|
||||
---@diagnostic disable-next-line: redefined-local
|
||||
local output = output or require("pinnacle.output").get_focused()
|
||||
if not output then
|
||||
return
|
||||
end
|
||||
|
||||
local tags = output:props().tags or {}
|
||||
|
||||
for _, tg in ipairs(tags) do
|
||||
if tg:props().active then
|
||||
local id = tg.id
|
||||
|
||||
if #layouts == 1 then
|
||||
indices[id] = 1
|
||||
elseif indices[id] == nil then
|
||||
indices[id] = #layouts - 1
|
||||
else
|
||||
if indices[id] - 1 < 1 then
|
||||
indices[id] = #layouts
|
||||
else
|
||||
indices[id] = indices[id] - 1
|
||||
end
|
||||
end
|
||||
|
||||
tg:set_layout(layouts[indices[id]])
|
||||
break
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
local signal_name_to_SignalName = {
|
||||
layout = "Layout",
|
||||
}
|
||||
|
||||
---@class TagSignal Signals related to tag events.
|
||||
---@field layout fun(tag: TagHandle, windows: WindowHandle[])? The compositor requested a layout of the given tiled windows. You'll also receive the first active tag.
|
||||
|
||||
---Connect to a tag signal.
|
||||
---
|
||||
---The compositor sends signals about various events. Use this function to run a callback when
|
||||
---some tag signal occurs.
|
||||
---
|
||||
---This function returns a table of signal handles with each handle stored at the same key used
|
||||
---to connect to the signal. See `SignalHandles` for more information.
|
||||
---
|
||||
---# Example
|
||||
---```lua
|
||||
---Tag.connect_signal({
|
||||
--- layout = function(tag, windows)
|
||||
--- print("Compositor requested a layout")
|
||||
--- end
|
||||
---})
|
||||
---```
|
||||
---
|
||||
---@param signals TagSignal The signal you want to connect to
|
||||
---
|
||||
---@return SignalHandles signal_handles Handles to every signal you connected to wrapped in a table, with keys being the same as the connected signal.
|
||||
---
|
||||
---@see SignalHandles.disconnect_all - To disconnect from these signals
|
||||
function tag.connect_signal(signals)
|
||||
---@diagnostic disable-next-line: invisible
|
||||
local handles = require("pinnacle.signal").handles.new({})
|
||||
|
||||
for signal, callback in pairs(signals) do
|
||||
require("pinnacle.signal").add_callback(signal_name_to_SignalName[signal], callback)
|
||||
---@diagnostic disable-next-line: invisible
|
||||
local handle = require("pinnacle.signal").handle.new(signal_name_to_SignalName[signal], callback)
|
||||
handles[signal] = handle
|
||||
end
|
||||
|
||||
return handles
|
||||
end
|
||||
|
||||
---Remove this tag.
|
||||
---
|
||||
---### Example
|
||||
|
@ -384,45 +224,6 @@ function TagHandle:remove()
|
|||
client.unary_request(build_grpc_request_params("Remove", { tag_ids = { self.id } }))
|
||||
end
|
||||
|
||||
local layout_name_to_code = {
|
||||
master_stack = 1,
|
||||
dwindle = 2,
|
||||
spiral = 3,
|
||||
corner_top_left = 4,
|
||||
corner_top_right = 5,
|
||||
corner_bottom_left = 6,
|
||||
corner_bottom_right = 7,
|
||||
}
|
||||
---@alias LayoutOld
|
||||
---| "master_stack" # One master window on the left with all other windows stacked to the right.
|
||||
---| "dwindle" # Windows split in half towards the bottom right corner.
|
||||
---| "spiral" # Windows split in half in a spiral.
|
||||
---| "corner_top_left" # One main corner window in the top left with a column of windows on the right and a row on the bottom.
|
||||
---| "corner_top_right" # One main corner window in the top right with a column of windows on the left and a row on the bottom.
|
||||
---| "corner_bottom_left" # One main corner window in the bottom left with a column of windows on the right and a row on the top.
|
||||
---| "corner_bottom_right" # One main corner window in the bottom right with a column of windows on the left and a row on the top.
|
||||
|
||||
---Set this tag's layout.
|
||||
---
|
||||
---If this is the first active tag on its output, its layout will be used to tile windows.
|
||||
---
|
||||
---### Example
|
||||
---```lua
|
||||
--- -- Assume the focused output has tag "Tag"
|
||||
---Tag.get("Tag"):set_layout("dwindle")
|
||||
---```
|
||||
---
|
||||
---@param layout LayoutOld
|
||||
function TagHandle:set_layout(layout)
|
||||
---@diagnostic disable-next-line: redefined-local
|
||||
local layout = layout_name_to_code[layout]
|
||||
|
||||
client.unary_request(build_grpc_request_params("SetLayout", {
|
||||
tag_id = self.id,
|
||||
layout = layout,
|
||||
}))
|
||||
end
|
||||
|
||||
---Activate this tag and deactivate all other ones on the same output.
|
||||
---
|
||||
---### Example
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
---@class LayoutModule
|
||||
local layout = {}
|
||||
|
||||
return layout
|
|
@ -26,21 +26,6 @@ message RemoveRequest {
|
|||
repeated uint32 tag_ids = 1;
|
||||
}
|
||||
|
||||
message SetLayoutRequest {
|
||||
optional uint32 tag_id = 1;
|
||||
enum Layout {
|
||||
LAYOUT_UNSPECIFIED = 0;
|
||||
LAYOUT_MASTER_STACK = 1;
|
||||
LAYOUT_DWINDLE = 2;
|
||||
LAYOUT_SPIRAL = 3;
|
||||
LAYOUT_CORNER_TOP_LEFT = 4;
|
||||
LAYOUT_CORNER_TOP_RIGHT = 5;
|
||||
LAYOUT_CORNER_BOTTOM_LEFT = 6;
|
||||
LAYOUT_CORNER_BOTTOM_RIGHT = 7;
|
||||
}
|
||||
optional Layout layout = 2;
|
||||
}
|
||||
|
||||
message GetRequest {}
|
||||
message GetResponse {
|
||||
repeated uint32 tag_ids = 1;
|
||||
|
@ -60,7 +45,6 @@ service TagService {
|
|||
rpc SwitchTo(SwitchToRequest) returns (google.protobuf.Empty);
|
||||
rpc Add(AddRequest) returns (AddResponse);
|
||||
rpc Remove(RemoveRequest) returns (google.protobuf.Empty);
|
||||
rpc SetLayout(SetLayoutRequest) returns (google.protobuf.Empty);
|
||||
rpc Get(GetRequest) returns (GetResponse);
|
||||
rpc GetProperties(GetPropertiesRequest) returns (GetPropertiesResponse);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
use pinnacle_api::layout::{
|
||||
CornerLayout, DwindleLayout, FairLayout, LayoutManager, MasterStackLayout, SpiralLayout,
|
||||
CornerLayout, DwindleLayout, FairLayout, MasterStackLayout, SpiralLayout,
|
||||
};
|
||||
use pinnacle_api::signal::WindowSignal;
|
||||
use pinnacle_api::xkbcommon::xkb::Keysym;
|
||||
use pinnacle_api::{
|
||||
input::{Mod, MouseButton, MouseEdge},
|
||||
tag::{Layout, LayoutCycler},
|
||||
ApiModules,
|
||||
};
|
||||
|
||||
|
|
|
@ -29,11 +29,6 @@
|
|||
//!
|
||||
//! These [`TagHandle`]s allow you to manipulate individual tags and get their properties.
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use futures::FutureExt;
|
||||
use num_enum::TryFromPrimitive;
|
||||
use pinnacle_api_defs::pinnacle::{
|
||||
|
@ -41,7 +36,7 @@ use pinnacle_api_defs::pinnacle::{
|
|||
self,
|
||||
v0alpha1::{
|
||||
tag_service_client::TagServiceClient, AddRequest, RemoveRequest, SetActiveRequest,
|
||||
SetLayoutRequest, SwitchToRequest,
|
||||
SwitchToRequest,
|
||||
},
|
||||
},
|
||||
v0alpha1::SetOrToggle,
|
||||
|
@ -225,126 +220,6 @@ impl Tag {
|
|||
|
||||
block_on_tokio(client.remove(RemoveRequest { tag_ids })).unwrap();
|
||||
}
|
||||
|
||||
/// Create a [`LayoutCycler`] to cycle layouts on outputs.
|
||||
///
|
||||
/// This will create a `LayoutCycler` with two functions: one to cycle forward the layout for
|
||||
/// the first active tag on the specified output, and one to cycle backward.
|
||||
///
|
||||
/// If you do not specify an output for `LayoutCycler` functions, it will default to the
|
||||
/// focused output.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use pinnacle_api::tag::{Layout, LayoutCycler};
|
||||
/// use pinnacle_api::xkbcommon::xkb::Keysym;
|
||||
/// use pinnacle_api::input::Mod;
|
||||
///
|
||||
/// // Create a layout cycler that cycles through the listed layouts
|
||||
/// let LayoutCycler {
|
||||
/// prev: layout_prev,
|
||||
/// next: layout_next,
|
||||
/// } = tag.new_layout_cycler([
|
||||
/// Layout::MasterStack,
|
||||
/// Layout::Dwindle,
|
||||
/// Layout::Spiral,
|
||||
/// Layout::CornerTopLeft,
|
||||
/// Layout::CornerTopRight,
|
||||
/// Layout::CornerBottomLeft,
|
||||
/// Layout::CornerBottomRight,
|
||||
/// ]);
|
||||
///
|
||||
/// // Cycle layouts forward on the focused output
|
||||
/// layout_next(None);
|
||||
///
|
||||
/// // Cycle layouts backward on the focused output
|
||||
/// layout_prev(None);
|
||||
///
|
||||
/// // Cycle layouts forward on "eDP-1"
|
||||
/// layout_next(output.get_by_name("eDP-1")?);
|
||||
/// ```
|
||||
pub fn new_layout_cycler(&self, layouts: impl IntoIterator<Item = Layout>) -> LayoutCycler {
|
||||
let indices = Arc::new(Mutex::new(HashMap::<u32, usize>::new()));
|
||||
let indices_clone = indices.clone();
|
||||
|
||||
let layouts = layouts.into_iter().collect::<Vec<_>>();
|
||||
let layouts_clone = layouts.clone();
|
||||
let len = layouts.len();
|
||||
|
||||
let output_module = OUTPUT.get().expect("OUTPUT doesn't exist");
|
||||
let output_module_clone = output_module.clone();
|
||||
|
||||
let next = move |output: Option<&OutputHandle>| {
|
||||
let Some(output) = output.cloned().or_else(|| output_module.get_focused()) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(first_tag) = output
|
||||
.props()
|
||||
.tags
|
||||
.into_iter()
|
||||
.find(|tag| tag.active() == Some(true))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut indices = indices.lock().expect("layout next mutex lock failed");
|
||||
let index = indices.entry(first_tag.id).or_insert(0);
|
||||
|
||||
if *index + 1 >= len {
|
||||
*index = 0;
|
||||
} else {
|
||||
*index += 1;
|
||||
}
|
||||
|
||||
first_tag.set_layout(layouts[*index]);
|
||||
};
|
||||
|
||||
let prev = move |output: Option<&OutputHandle>| {
|
||||
let Some(output) = output
|
||||
.cloned()
|
||||
.or_else(|| output_module_clone.get_focused())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(first_tag) = output
|
||||
.props()
|
||||
.tags
|
||||
.into_iter()
|
||||
.find(|tag| tag.active() == Some(true))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut indices = indices_clone.lock().expect("layout next mutex lock failed");
|
||||
let index = indices.entry(first_tag.id).or_insert(0);
|
||||
|
||||
if index.checked_sub(1).is_none() {
|
||||
*index = len - 1;
|
||||
} else {
|
||||
*index -= 1;
|
||||
}
|
||||
|
||||
first_tag.set_layout(layouts_clone[*index]);
|
||||
};
|
||||
|
||||
LayoutCycler {
|
||||
prev: Box::new(prev),
|
||||
next: Box::new(next),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A layout cycler that keeps track of tags and their layouts and provides functions to cycle
|
||||
/// layouts on them.
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub struct LayoutCycler {
|
||||
/// Cycle to the next layout on the given output, or the focused output if `None`.
|
||||
pub prev: Box<dyn Fn(Option<&OutputHandle>) + Send + Sync + 'static>,
|
||||
/// Cycle to the previous layout on the given output, or the focused output if `None`.
|
||||
pub next: Box<dyn Fn(Option<&OutputHandle>) + Send + Sync + 'static>,
|
||||
}
|
||||
|
||||
/// A handle to a tag.
|
||||
|
@ -492,31 +367,6 @@ impl TagHandle {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
/// Set this tag's layout.
|
||||
///
|
||||
/// Layouting only applies to tiled windows (windows that are not floating, maximized, or
|
||||
/// fullscreen). If multiple tags are active on an output, the first active tag's layout will
|
||||
/// determine the layout strategy.
|
||||
///
|
||||
/// See [`Layout`] for the different static layouts Pinnacle currently has to offer.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use pinnacle_api::tag::Layout;
|
||||
///
|
||||
/// // Set the layout of tag "1" on the focused output to "corner top left".
|
||||
/// tag.get("1", None)?.set_layout(Layout::CornerTopLeft);
|
||||
/// ```
|
||||
pub fn set_layout(&self, layout: Layout) {
|
||||
let mut client = self.tag_client.clone();
|
||||
block_on_tokio(client.set_layout(SetLayoutRequest {
|
||||
tag_id: Some(self.id),
|
||||
layout: Some(layout as i32),
|
||||
}))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// Get all properties of this tag.
|
||||
///
|
||||
/// # Examples
|
||||
|
|
11
src/api.rs
11
src/api.rs
|
@ -21,7 +21,7 @@ use pinnacle_api_defs::pinnacle::{
|
|||
self,
|
||||
v0alpha1::{
|
||||
tag_service_server, AddRequest, AddResponse, RemoveRequest, SetActiveRequest,
|
||||
SetLayoutRequest, SwitchToRequest,
|
||||
SwitchToRequest,
|
||||
},
|
||||
},
|
||||
v0alpha1::{pinnacle_service_server, QuitRequest, SetOrToggle},
|
||||
|
@ -831,15 +831,6 @@ impl tag_service_server::TagService for TagService {
|
|||
.await
|
||||
}
|
||||
|
||||
async fn set_layout(
|
||||
&self,
|
||||
_request: Request<SetLayoutRequest>,
|
||||
) -> Result<Response<()>, Status> {
|
||||
warn!("Tag.set_layout has been deprecated");
|
||||
|
||||
run_unary_no_response(&self.sender, move |_state| {}).await
|
||||
}
|
||||
|
||||
async fn get(
|
||||
&self,
|
||||
_request: Request<tag::v0alpha1::GetRequest>,
|
||||
|
|
Loading…
Add table
Reference in a new issue