mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-13 08:01:05 +01:00
Make window API functions non-nil
This does not apply to functions that return an array; you'll have to do a for loop or check for nil on index in that case.
This commit is contained in:
parent
ed5447d5b6
commit
17ca00f6be
6 changed files with 98 additions and 140 deletions
|
@ -61,14 +61,14 @@
|
|||
---@field Spawn { stdout: string?, stderr: string?, exit_code: integer?, exit_msg: string? }?
|
||||
---@field ConnectForAllOutputs { output_name: string }?
|
||||
|
||||
---@alias WindowId integer
|
||||
---@alias WindowId integer | "None"
|
||||
---@alias TagId integer
|
||||
---@alias RequestId integer
|
||||
---@alias OutputName string
|
||||
|
||||
---@class RequestResponse
|
||||
--Windows
|
||||
---@field Window { window_id: WindowId|nil }?
|
||||
---@field Window { window_id: WindowId }?
|
||||
---@field Windows { window_ids: WindowId[] }?
|
||||
---@field WindowProps { size: integer[]?, loc: integer[]?, class: string?, title: string?, focused: boolean?, floating: boolean?, fullscreen_or_maximized: FullscreenOrMaximized? }?
|
||||
--Outputs
|
||||
|
|
|
@ -18,8 +18,9 @@ require("pinnacle").setup(function(pinnacle)
|
|||
local output = pinnacle.output -- Output management
|
||||
|
||||
-- Every key supported by xkbcommon.
|
||||
-- Support for just putting in a string of a key is intended.
|
||||
local keys = input.keys
|
||||
-- Mouse buttons
|
||||
local buttons = input.buttons
|
||||
|
||||
---@type Modifier
|
||||
local mod_key = "Ctrl" -- This is set to `Ctrl` instead of `Super` to not conflict with your WM/DE keybinds
|
||||
|
@ -27,17 +28,37 @@ require("pinnacle").setup(function(pinnacle)
|
|||
|
||||
local terminal = "alacritty"
|
||||
|
||||
process.set_env("MOZ_ENABLE_WAYLAND", "1")
|
||||
|
||||
-- Outputs -----------------------------------------------------------------------
|
||||
|
||||
-- You can set your own monitor layout as I have done below for my monitors.
|
||||
|
||||
--
|
||||
-- local lg = output.get_by_name("DP-2") --[[@as Output]]
|
||||
-- local dell = output.get_by_name("DP-3") --[[@as Output]]
|
||||
--
|
||||
-- dell:set_loc_left_of(lg, "bottom")
|
||||
|
||||
-- Libinput settings -------------------------------------------------------------
|
||||
-- If you want to change settings like pointer acceleration,
|
||||
-- you can do them in `input.libinput`.
|
||||
--
|
||||
-- input.libinput.set_accel_profile("Flat")
|
||||
|
||||
-- Mousebinds --------------------------------------------------------------------
|
||||
|
||||
input.mousebind({ "Ctrl" }, buttons.left, "Press", function()
|
||||
window.begin_move(buttons.left)
|
||||
end)
|
||||
input.mousebind({ "Ctrl" }, buttons.right, "Press", function()
|
||||
window.begin_resize(buttons.right)
|
||||
end)
|
||||
|
||||
-- Keybinds ----------------------------------------------------------------------
|
||||
|
||||
input.keybind({ mod_key }, keys.t, function()
|
||||
window.get_focused():set_size({ w = 500, h = 500 })
|
||||
end)
|
||||
|
||||
-- mod_key + Alt + q quits the compositor
|
||||
input.keybind({ mod_key, "Alt" }, keys.q, pinnacle.quit)
|
||||
|
||||
|
@ -85,16 +106,40 @@ require("pinnacle").setup(function(pinnacle)
|
|||
|
||||
-- Tags ---------------------------------------------------------------------------
|
||||
|
||||
local tags = { "1", "2", "3", "4", "5" }
|
||||
|
||||
output.connect_for_all(function(op)
|
||||
-- Add tags 1, 2, 3, 4 and 5 on all monitors, and toggle tag 1 active by default
|
||||
|
||||
op:add_tags("1", "2", "3", "4", "5")
|
||||
op:add_tags(tags)
|
||||
-- Same as tag.add(op, "1", "2", "3", "4", "5")
|
||||
tag.toggle({ "1", op })
|
||||
tag.toggle({ name = "1", output = op })
|
||||
|
||||
-- Window rules
|
||||
-- Add your own window rules here. Below is an example.
|
||||
--
|
||||
-- These currently need to be added inside of `connect_for_all` because
|
||||
-- it only runs after the whole config is parsed, so any specified tags won't be available outside
|
||||
-- of this function. This means that if you have multiple monitors,
|
||||
-- these rules will be duplicated unless you write in some logic to prevent that.
|
||||
--
|
||||
-- window.rules.add({
|
||||
-- cond = { class = "kitty" },
|
||||
-- rule = { size = { 300, 300 }, location = { 50, 50 } },
|
||||
-- }, {
|
||||
-- cond = {
|
||||
-- class = "XTerm",
|
||||
-- tag = "4",
|
||||
-- },
|
||||
-- rule = { size = { 500, 800 }, floating_or_tiled = "Floating" },
|
||||
-- })
|
||||
end)
|
||||
|
||||
---@type Layout[]
|
||||
local layouts = {
|
||||
-- Layout cycling
|
||||
|
||||
-- Create a layout cycler to cycle your tag layouts. This will store which layout each tag has
|
||||
-- and change to the next or previous one in the array when the respective function is called.
|
||||
local layout_cycler = tag.layout_cycler({
|
||||
"MasterStack",
|
||||
"Dwindle",
|
||||
"Spiral",
|
||||
|
@ -102,124 +147,29 @@ require("pinnacle").setup(function(pinnacle)
|
|||
"CornerTopRight",
|
||||
"CornerBottomLeft",
|
||||
"CornerBottomRight",
|
||||
}
|
||||
local indices = {}
|
||||
|
||||
-- Window rules
|
||||
window.rules.add({
|
||||
cond = { class = "kitty" },
|
||||
rule = { floating_or_tiled = "Floating" },
|
||||
})
|
||||
|
||||
-- Layout cycling
|
||||
-- Yes, this is overly complicated and yes, I'll cook up a way to make it less so.
|
||||
input.keybind({ mod_key }, keys.space, function()
|
||||
local tags = output.get_focused():tags()
|
||||
for _, tg in pairs(tags) do
|
||||
if tg:active() then
|
||||
local name = tg:name()
|
||||
if name == nil then
|
||||
return
|
||||
end
|
||||
tg:set_layout(layouts[indices[name] or 1])
|
||||
if indices[name] == nil then
|
||||
indices[name] = 2
|
||||
else
|
||||
if indices[name] + 1 > #layouts then
|
||||
indices[name] = 1
|
||||
else
|
||||
indices[name] = indices[name] + 1
|
||||
end
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end)
|
||||
input.keybind({ mod_key, "Shift" }, keys.space, function()
|
||||
local tags = output.get_focused():tags()
|
||||
for _, tg in pairs(tags) do
|
||||
if tg:active() then
|
||||
local name = tg:name()
|
||||
if name == nil then
|
||||
return
|
||||
end
|
||||
tg:set_layout(layouts[indices[name] or #layouts])
|
||||
if indices[name] == nil then
|
||||
indices[name] = #layouts - 1
|
||||
else
|
||||
if indices[name] - 1 < 1 then
|
||||
indices[name] = #layouts
|
||||
else
|
||||
indices[name] = indices[name] - 1
|
||||
end
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end)
|
||||
input.keybind({ mod_key }, keys.space, layout_cycler.next)
|
||||
input.keybind({ mod_key, "Shift" }, keys.space, layout_cycler.prev)
|
||||
|
||||
input.keybind({ mod_key }, keys.KEY_1, function()
|
||||
tag.switch_to("1")
|
||||
end)
|
||||
input.keybind({ mod_key }, keys.KEY_2, function()
|
||||
tag.switch_to("2")
|
||||
end)
|
||||
input.keybind({ mod_key }, keys.KEY_3, function()
|
||||
tag.switch_to("3")
|
||||
end)
|
||||
input.keybind({ mod_key }, keys.KEY_4, function()
|
||||
tag.switch_to("4")
|
||||
end)
|
||||
input.keybind({ mod_key }, keys.KEY_5, function()
|
||||
tag.switch_to("5")
|
||||
end)
|
||||
-- Tag manipulation
|
||||
|
||||
input.keybind({ mod_key, "Shift" }, keys.KEY_1, function()
|
||||
tag.toggle("1")
|
||||
end)
|
||||
input.keybind({ mod_key, "Shift" }, keys.KEY_2, function()
|
||||
tag.toggle("2")
|
||||
end)
|
||||
input.keybind({ mod_key, "Shift" }, keys.KEY_3, function()
|
||||
tag.toggle("3")
|
||||
end)
|
||||
input.keybind({ mod_key, "Shift" }, keys.KEY_4, function()
|
||||
tag.toggle("4")
|
||||
end)
|
||||
input.keybind({ mod_key, "Shift" }, keys.KEY_5, function()
|
||||
tag.toggle("5")
|
||||
end)
|
||||
|
||||
-- I check for nil this way because I don't want stylua to take up like 80 lines on `if win ~= nil`
|
||||
input.keybind({ mod_key, "Alt" }, keys.KEY_1, function()
|
||||
local _ = window.get_focused() and window:get_focused():move_to_tag("1")
|
||||
end)
|
||||
input.keybind({ mod_key, "Alt" }, keys.KEY_2, function()
|
||||
local _ = window.get_focused() and window:get_focused():move_to_tag("2")
|
||||
end)
|
||||
input.keybind({ mod_key, "Alt" }, keys.KEY_3, function()
|
||||
local _ = window.get_focused() and window:get_focused():move_to_tag("3")
|
||||
end)
|
||||
input.keybind({ mod_key, "Alt" }, keys.KEY_4, function()
|
||||
local _ = window.get_focused() and window:get_focused():move_to_tag("4")
|
||||
end)
|
||||
input.keybind({ mod_key, "Alt" }, keys.KEY_5, function()
|
||||
local _ = window.get_focused() and window:get_focused():move_to_tag("5")
|
||||
end)
|
||||
|
||||
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_1, function()
|
||||
local _ = window.get_focused() and window.get_focused():toggle_tag("1")
|
||||
end)
|
||||
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_2, function()
|
||||
local _ = window.get_focused() and window.get_focused():toggle_tag("2")
|
||||
end)
|
||||
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_3, function()
|
||||
local _ = window.get_focused() and window.get_focused():toggle_tag("3")
|
||||
end)
|
||||
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_4, function()
|
||||
local _ = window.get_focused() and window.get_focused():toggle_tag("4")
|
||||
end)
|
||||
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_5, function()
|
||||
local _ = window.get_focused() and window.get_focused():toggle_tag("5")
|
||||
end)
|
||||
for _, tag_name in pairs(tags) do
|
||||
-- mod_key + 1-5 switches tags
|
||||
input.keybind({ mod_key }, tag_name, function()
|
||||
tag.switch_to(tag_name)
|
||||
end)
|
||||
-- mod_key + Shift + 1-5 toggles tags
|
||||
input.keybind({ mod_key, "Shift" }, tag_name, function()
|
||||
tag.toggle(tag_name)
|
||||
end)
|
||||
-- mod_key + Alt + 1-5 moves windows to tags
|
||||
input.keybind({ mod_key, "Alt" }, tag_name, function()
|
||||
local _ = window.get_focused() and window:get_focused():move_to_tag(tag_name)
|
||||
end)
|
||||
-- mod_key + Shift + Alt + 1-5 toggles tags on windows
|
||||
input.keybind({ mod_key, "Shift", "Alt" }, tag_name, function()
|
||||
local _ = window.get_focused() and window.get_focused():toggle_tag(tag_name)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
|
|
@ -20,7 +20,7 @@ local window = {
|
|||
---You can retrieve window handles through the various `get` functions in the `Window` module.
|
||||
---@classmod
|
||||
---@class WindowHandle
|
||||
---@field private _id integer The internal id of this window
|
||||
---@field private _id WindowId The internal id of this window
|
||||
local window_handle = {}
|
||||
|
||||
---@param window_id WindowId
|
||||
|
@ -225,7 +225,7 @@ function window.get_by_title(title)
|
|||
end
|
||||
|
||||
---Get the currently focused window.
|
||||
---@return WindowHandle|nil
|
||||
---@return WindowHandle
|
||||
function window.get_focused()
|
||||
-- TODO: get focused on output
|
||||
local windows = window.get_all()
|
||||
|
@ -236,7 +236,7 @@ function window.get_focused()
|
|||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
return create_window("None")
|
||||
end
|
||||
|
||||
---Get all windows.
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::{
|
||||
backend::Backend,
|
||||
config::api::msg::{CallbackId, Modifier, ModifierMask, MouseEdge, OutgoingMsg},
|
||||
focus::FocusTarget,
|
||||
state::WithState,
|
||||
|
@ -16,7 +15,6 @@ use smithay::{
|
|||
KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionEvent,
|
||||
},
|
||||
libinput::LibinputInputBackend,
|
||||
session::Session,
|
||||
},
|
||||
desktop::{layer_map_for_output, space::SpaceElement},
|
||||
input::{
|
||||
|
|
|
@ -110,7 +110,16 @@ impl State {
|
|||
if let Some(height) = height {
|
||||
window_size.h = height;
|
||||
}
|
||||
window.change_geometry(Rectangle::from_loc_and_size(window_loc, window_size));
|
||||
use crate::window::window_state::FloatingOrTiled;
|
||||
|
||||
let rect = Rectangle::from_loc_and_size(window_loc, window_size);
|
||||
window.change_geometry(rect);
|
||||
window.with_state(|state| {
|
||||
state.floating_or_tiled = match state.floating_or_tiled {
|
||||
FloatingOrTiled::Floating(_) => FloatingOrTiled::Floating(rect),
|
||||
FloatingOrTiled::Tiled(_) => FloatingOrTiled::Tiled(Some(rect)),
|
||||
}
|
||||
});
|
||||
if let Some(output) = window.output(self) {
|
||||
self.update_windows(&output);
|
||||
self.schedule_render(&output);
|
||||
|
|
|
@ -18,14 +18,22 @@ use crate::{
|
|||
|
||||
use super::WindowElement;
|
||||
|
||||
/// A unique identifier for each window.
|
||||
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct WindowId(u32);
|
||||
pub enum WindowId {
|
||||
/// A config API returned an invalid window. It should be using this variant.
|
||||
None,
|
||||
/// A valid window id.
|
||||
#[serde(untagged)]
|
||||
Some(u32),
|
||||
}
|
||||
|
||||
static WINDOW_ID_COUNTER: AtomicU32 = AtomicU32::new(0);
|
||||
|
||||
impl WindowId {
|
||||
/// Get the next available window id. This always starts at 0.
|
||||
pub fn next() -> Self {
|
||||
Self(WINDOW_ID_COUNTER.fetch_add(1, Ordering::Relaxed))
|
||||
Self::Some(WINDOW_ID_COUNTER.fetch_add(1, Ordering::Relaxed))
|
||||
}
|
||||
|
||||
/// Get the window that has this WindowId.
|
||||
|
@ -317,13 +325,6 @@ impl FullscreenOrMaximized {
|
|||
}
|
||||
}
|
||||
|
||||
impl WindowElementState {
|
||||
#[allow(dead_code)]
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for WindowElementState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
|
Loading…
Reference in a new issue