Merge branch 'master' into laptop

This commit is contained in:
Thomas Avé 2023-12-02 17:49:01 +01:00
commit c270650fdd
26 changed files with 2091 additions and 82 deletions

View File

@ -166,7 +166,7 @@ keys.globalkeys = gears.table.join(
function() function()
local c = client.focus local c = client.focus
if c and c.class == "Alacritty" then if c and c.class == "Alacritty" then
awful.spawn(string.format(os.getenv("XDG_CONFIG_HOME") .. "/awesome/scripts/launch_alacritty.sh %d", c.pid)) awful.spawn(string.format(os.getenv("XDG_CONFIG_HOME") .. "/scripts/launch_alacritty.sh %d", c.pid))
else else
awful.spawn('bash -c "WINIT_X11_SCALE_FACTOR=1 alacritty"') awful.spawn('bash -c "WINIT_X11_SCALE_FACTOR=1 alacritty"')
end end
@ -211,14 +211,14 @@ keys.globalkeys = gears.table.join(
-- launch rofi -- launch rofi
awful.key({modkey}, "XF86Launch5", awful.key({modkey}, "XF86Launch5",
function() function()
awful.spawn(os.getenv("XDG_CONFIG_HOME") .. "/awesome/scripts/toggle_rofi.sh") awful.spawn(os.getenv("XDG_CONFIG_HOME") .. "/scripts/toggle_rofi.sh")
end, end,
{description = "application launcher", group = "launcher"} {description = "application launcher", group = "launcher"}
), ),
-- launch rofi -- launch rofi
awful.key({modkey}, "d", awful.key({modkey}, "d",
function() function()
awful.spawn(os.getenv("XDG_CONFIG_HOME") .. "/awesome/scripts/toggle_rofi.sh") awful.spawn(os.getenv("XDG_CONFIG_HOME") .. "/scripts/toggle_rofi.sh")
end, end,
{description = "application launcher", group = "launcher"} {description = "application launcher", group = "launcher"}
), ),
@ -335,7 +335,7 @@ keys.globalkeys = gears.table.join(
awful.key({modkey}, "Escape", awful.key({modkey}, "Escape",
function() function()
-- emit signal to show the exit screen -- emit signal to show the exit screen
awful.spawn("rofi -show power-menu -modi power-menu:" .. os.getenv("XDG_CONFIG_HOME") .. "/awesome/scripts/rofi-power-menu") awful.spawn("rofi -show power-menu -modi power-menu:" .. os.getenv("XDG_CONFIG_HOME") .. "/scripts/rofi-power-menu")
end, end,
{description = "toggle exit screen", group = "hotkeys"} {description = "toggle exit screen", group = "hotkeys"}
), ),
@ -343,7 +343,7 @@ keys.globalkeys = gears.table.join(
awful.key({}, "XF86PowerOff", awful.key({}, "XF86PowerOff",
function() function()
-- emit signal to show the exit screen -- emit signal to show the exit screen
awful.spawn("rofi -show power-menu -modi power-menu:~/.config/awesome/scripts/rofi-power-menu") awful.spawn("rofi -show power-menu -modi power-menu:~/.config/scripts/rofi-power-menu")
end, end,
{description = "toggle exit screen", group = "hotkeys"} {description = "toggle exit screen", group = "hotkeys"}
), ),

View File

@ -5,10 +5,45 @@ exec-once=waybar
exec-once=sudo wg-quick up wg0 exec-once=sudo wg-quick up wg0
exec-once=sleep 0.7 && swaylock exec-once=sleep 0.7 && swaylock
workspace=eDP-1,1
workspace=HDMI-A-1,11
workspace=11,monitor:HDMI-A-1, default:true
workspace=12,monitor:HDMI-A-1
workspace=13,monitor:HDMI-A-1
workspace=14,monitor:HDMI-A-1
workspace=15,monitor:HDMI-A-1
workspace=16,monitor:HDMI-A-1
workspace=17,monitor:HDMI-A-1
workspace=18,monitor:HDMI-A-1
workspace=19,monitor:HDMI-A-1
workspace=1,monitor:eDP-1, default:true
workspace=2,monitor:eDP-1
workspace=3,monitor:eDP-1
workspace=4,monitor:eDP-1
workspace=5,monitor:eDP-1
workspace=6,monitor:eDP-1
workspace=7,monitor:eDP-1
workspace=8,monitor:eDP-1
workspace=9,monitor:eDP-1
windowrule = float,title:^(rofi)(.*)$
windowrule = center,title:^(rofi)(.*)$
windowrule = noborder,title:^(rofi)(.*)$
windowrule = noanim,waybar
exec-once=waybar
binds {
scroll_event_delay=1
}
input { input {
kb_layout = us kb_layout = us
follow_mouse = 1 follow_mouse = 1
kb_options = compose:rctrl kb_options = compose:rctrl
numlock_by_default = true
} }
general { general {
@ -53,7 +88,7 @@ animations {
dwindle { dwindle {
preserve_split = yes preserve_split = yes
no_gaps_when_only = 1 # no_gaps_when_only = 1
force_split = 2 force_split = 2
} }
@ -66,8 +101,8 @@ gestures {
$mainMod = SUPER $mainMod = SUPER
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more # Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
bindr = $mainMod, SUPER_L, exec, /home/user/.config/awesome/scripts/toggle_rofi.sh bindr = $mainMod, SUPER_L, exec, /home/user/.config/scripts/toggle_rofi.sh
bind = $mainMod, return, exec, /home/user/.config/awesome/scripts/launch_alacritty.sh $(hyprctl activewindow -j | jq .pid) bind = $mainMod, return, exec, /home/user/.config/scripts/launch_alacritty.sh $(hyprctl activewindow -j | jq .pid)
bind = $mainMod SHIFT, return, exec, alacritty bind = $mainMod SHIFT, return, exec, alacritty
bind = $mainMod, Q, killactive, bind = $mainMod, Q, killactive,
bind = $mainMod, A, exec, nautilus bind = $mainMod, A, exec, nautilus
@ -79,14 +114,15 @@ bind = $mainMod, SPACE, togglesplit, # dwindle
bind = CONTROL_L ALT_L, L, exec, swaylock bind = CONTROL_L ALT_L, L, exec, swaylock
bind = $mainMod, C, exec, CM_LAUNCHER=rofi-script rofi -modi "clipmenu:/usr/bin/clipmenu" -show clipmenu bind = $mainMod, C, exec, CM_LAUNCHER=rofi-script rofi -modi "clipmenu:/usr/bin/clipmenu" -show clipmenu
bind = $mainMod, Y, exec, /home/user/.config/rofi/rofi-ykman.sh bind = $mainMod, Y, exec, /home/user/.config/rofi/rofi-ykman.sh
bind = Control Mod2 Mod4, Q, exec, systemctl suspend bind = Super_L Control_L, Q, exec, systemctl suspend
bind = $mainMod, Escape, exec, rofi -show power-menu -modi power-menu:/home/user/.config/awesome/scripts/rofi-power-menu bind = $mainMod, Escape, exec, rofi -show power-menu -modi power-menu:/home/user/.config/scripts/rofi-power-menu
bind = ,XF86PowerOff, exec, rofi -show power-menu -modi power-menu:/home/user/.config/scripts/rofi-power-menu
bind = ,XF86PowerOff, exec, rofi -show power-menu -modi power-menu:/home/user/.config/awesome/scripts/rofi-power-menu
bind = ,XF86MonBrightnessUp, exec, xbacklight -inc 10 bind = ,XF86MonBrightnessUp, exec, xbacklight -inc 10
bind = ,XF86MonBrightnessDown, exec, xbacklight -dec 10 bind = ,XF86MonBrightnessDown, exec, xbacklight -dec 10
bind = ,XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 10%+ --limit 1.0 bind = ,XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 10%+ --limit 1.0
bind = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 10%- bind = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 10%-
bind = ,mouse_right, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 1%+ --limit 1.0
bind = ,mouse_left, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 1%-
bind = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle bind = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
bind = ,XF86AudioNext, exec, playerctl next bind = ,XF86AudioNext, exec, playerctl next
bind = ,XF86AudioPrev, exec, playerctl previous bind = ,XF86AudioPrev, exec, playerctl previous
@ -99,45 +135,46 @@ bind = $mainMod, H, movefocus, l
bind = $mainMod, L, movefocus, r bind = $mainMod, L, movefocus, r
bind = $mainMod, K, movefocus, u bind = $mainMod, K, movefocus, u
bind = $mainMod, J, movefocus, d bind = $mainMod, J, movefocus, d
bind = $mainMod CONTROL_L, H, swapwindow, l
bind = $mainMod CONTROL_L, L, swapwindow, r
bind = $mainMod CONTROL_L, K, swapwindow, u
bind = $mainMod CONTROL_L, J, swapwindow, d
bind = $mainMod SHIFT, H, movewindow, l bind = $mainMod SHIFT, H, movewindow, l
bind = $mainMod SHIFT, L, movewindow, r bind = $mainMod SHIFT, L, movewindow, r
bind = $mainMod SHIFT, K, movewindow, u bind = $mainMod SHIFT, K, movewindow, u
bind = $mainMod SHIFT, J, movewindow, d bind = $mainMod SHIFT, J, movewindow, d
bind = $mainMod CONTROL_L, L, resizeactive, 20 0 bind = $mainMod ALT, L, resizeactive, 20 0
bind = $mainMod CONTROL_L, H, resizeactive, -20 0 bind = $mainMod ALT, H, resizeactive, -20 0
bind = $mainMod CONTROL_L, K, resizeactive, 0 -20 bind = $mainMod ALT, K, resizeactive, 0 -20
bind = $mainMod CONTROL_L, J, resizeactive, 0 20 bind = $mainMod ALT, J, resizeactive, 0 20
# Switch workspaces with mainMod + [0-9] bind = $mainMod, 1, exec, hyprsome workspace 1
bind = $mainMod, 1, workspace, 1 bind = $mainMod, 2, exec, hyprsome workspace 2
bind = $mainMod, 2, workspace, 2 bind = $mainMod, 3, exec, hyprsome workspace 3
bind = $mainMod, 3, workspace, 3 bind = $mainMod, 4, exec, hyprsome workspace 4
bind = $mainMod, 4, workspace, 4 bind = $mainMod, 5, exec, hyprsome workspace 5
bind = $mainMod, 5, workspace, 5 bind = $mainMod, 6, exec, hyprsome workspace 6
bind = $mainMod, 6, workspace, 6 bind = $mainMod, 7, exec, hyprsome workspace 7
bind = $mainMod, 7, workspace, 7 bind = $mainMod, 8, exec, hyprsome workspace 8
bind = $mainMod, 8, workspace, 8 bind = $mainMod, 9, exec, hyprsome workspace 9
bind = $mainMod, 9, workspace, 9
bind = $mainMod, 0, workspace, 10
# Move active window to a workspace with mainMod + SHIFT + [0-9] bind = $mainMod SHIFT, 1, exec, hyprsome movefocus 1
bind = $mainMod SHIFT, 1, movetoworkspace, 1 bind = $mainMod SHIFT, 2, exec, hyprsome movefocus 2
bind = $mainMod SHIFT, 2, movetoworkspace, 2 bind = $mainMod SHIFT, 3, exec, hyprsome movefocus 3
bind = $mainMod SHIFT, 3, movetoworkspace, 3 bind = $mainMod SHIFT, 4, exec, hyprsome movefocus 4
bind = $mainMod SHIFT, 4, movetoworkspace, 4 bind = $mainMod SHIFT, 5, exec, hyprsome movefocus 5
bind = $mainMod SHIFT, 5, movetoworkspace, 5 bind = $mainMod SHIFT, 6, exec, hyprsome movefocus 6
bind = $mainMod SHIFT, 6, movetoworkspace, 6 bind = $mainMod SHIFT, 7, exec, hyprsome movefocus 7
bind = $mainMod SHIFT, 7, movetoworkspace, 7 bind = $mainMod SHIFT, 8, exec, hyprsome movefocus 8
bind = $mainMod SHIFT, 8, movetoworkspace, 8 bind = $mainMod SHIFT, 9, exec, hyprsome movefocus 9
bind = $mainMod SHIFT, 9, movetoworkspace, 9
bind = $mainMod SHIFT, 0, movetoworkspace, 10 bind = $mainMod SHIFT, T, exec, hyprsome move-empty
bind = $mainMod SHIFT, T, movetoworkspace, empty bind = $mainMod, T, exec, hyprsome focus-empty
# Scroll through existing workspaces with mainMod + scroll # Scroll through existing workspaces with mainMod + scroll
bind = $mainMod, TAB, workspace, e+1 bind = $mainMod, TAB, workspace, m+1
bind = $mainMod SHIFT, TAB, workspace, e-1 bind = $mainMod SHIFT, TAB, workspace, m-1
bind = $mainMod, T, workspace, empty
# Move/resize windows with mainMod + LMB/RMB and dragging # Move/resize windows with mainMod + LMB/RMB and dragging
bindm = $mainMod, mouse:272, movewindow bindm = $mainMod, mouse:272, movewindow

2
hypr/hyprsome/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
/result

1207
hypr/hyprsome/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

17
hypr/hyprsome/Cargo.toml Normal file
View File

@ -0,0 +1,17 @@
[package]
name = "hyprsome"
description = "A small CLI apps that allows to make Hyprland's workspaces work like Awesome in multi-monitor setup"
license = "GPL-3.0"
version = "0.1.11"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "4.0.15", features = ["derive"] }
ipc-rpc = "1.2.2"
schemars = "0.8.11"
serde = "1.0.145"
serde_json = "1.0.86"
tokio = "1.21.2"
hyprland = "0.3.1"

16
hypr/hyprsome/LICENSE.txt Normal file
View File

@ -0,0 +1,16 @@
The GPLv3 License (GPLv3)
Copyright (c) 2022 Author
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

76
hypr/hyprsome/README.md Normal file
View File

@ -0,0 +1,76 @@
# Hyprsome
Hyprsome is a binary that interacts with Hyprland's Unix socket to make workspaces behave similarly to AwesomeWM in a multi-monitor setup.
If you're focused on a monitor and press SUPER+[1-9], you'll only switch to the workspaces that are bound to that monitor.
It is inspired by Swaysome, which does a similar thing for Sway.
# Installation
`
cargo install hyprsome
`
# Usage
Once the binary is installed, you can modify your ~/.config/hypr/hyprland.conf to accomodate it.
Here is an example of a dual monitor setup:
```
monitor=DP-1,1920x1080@60,0x0,1.33
monitor=DP-1,transform,1
workspace=DP-1,1
monitor=HDMI-A-1,3440x1440@100,813x0,1
workspace=HDMI-A-1,11
```
Most noteworthy thing here is the 'workspace' keyword that I use to bind a default workspace for each monitor.
Then you can bind workspaces to your different monitors.
It is very important that you bind your workspaces in order.
Check the results of `hyprctl monitors`. Bind workspaces from 1 to 9 on your monitor that has 0 as an id.
Then just bind workspaces by prefixing numbers by the id of the monitor they're bound to.
Here, HDMI-A-1's id is 1, so I bind workspaces from 11 to 19 to it.
```
workspace=1,monitor:DP-1
workspace=2,monitor:DP-1
workspace=3,monitor:DP-1
workspace=4,monitor:DP-1
workspace=5,monitor:DP-1
workspace=11,monitor:HDMI-A-1
workspace=12,monitor:HDMI-A-1
workspace=13,monitor:HDMI-A-1
workspace=14,monitor:HDMI-A-1
workspace=15,monitor:HDMI-A-1
```
Then it's just a matter of making sure your regular workspace keybinds call hyprsome.
```
bind=SUPER,1,exec,hyprsome workspace 1
bind=SUPER,2,exec,hyprsome workspace 2
bind=SUPER,3,exec,hyprsome workspace 3
bind=SUPER,4,exec,hyprsome workspace 4
bind=SUPER,5,exec,hyprsome workspace 5
bind=SUPERSHIFT,1,exec,hyprsome move 1
bind=SUPERSHIFT,2,exec,hyprsome move 2
bind=SUPERSHIFT,3,exec,hyprsome move 3
bind=SUPERSHIFT,4,exec,hyprsome move 4
bind=SUPERSHIFT,5,exec,hyprsome move 5
```
# Limitations
This is alpha software and my first program in Rust, bugs are bound to happen but nothing that will break your system.
Some features are most likely missing.
You can only have 9 workspaces per monitor as of now.
I haven't worked on supporting monitor hot-plug at all. It may work but it's unlikely.

159
hypr/hyprsome/flake.lock Normal file
View File

@ -0,0 +1,159 @@
{
"nodes": {
"crane": {
"inputs": {
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
],
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1684981077,
"narHash": "sha256-68X9cFm0RTZm8u0rXPbeBzOVUH5OoUGAfeHHVoxGd9o=",
"owner": "ipetkov",
"repo": "crane",
"rev": "35110cccf28823320f4fd697fcafcb5038683982",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1681202837,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1685518550,
"narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1685498995,
"narHash": "sha256-rdyjnkq87tJp+T2Bm1OD/9NXKSsh/vLlPeqCc/mm7qs=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9cfaa8a1a00830d17487cb60a19bb86f96f09b27",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"crane": "crane",
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs"
}
},
"rust-overlay": {
"inputs": {
"flake-utils": [
"crane",
"flake-utils"
],
"nixpkgs": [
"crane",
"nixpkgs"
]
},
"locked": {
"lastModified": 1683080331,
"narHash": "sha256-nGDvJ1DAxZIwdn6ww8IFwzoHb2rqBP4wv/65Wt5vflk=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "d59c3fa0cba8336e115b376c2d9e91053aa59e56",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

23
hypr/hyprsome/flake.nix Normal file
View File

@ -0,0 +1,23 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
crane.url = "github:ipetkov/crane";
crane.inputs.nixpkgs.follows = "nixpkgs";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, crane, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
craneLib = crane.lib.${system};
in
{
packages.default = craneLib.buildPackage {
src = craneLib.cleanCargoSource (craneLib.path ./.);
# Add extra inputs here or any other derivation settings
# doCheck = true;
# buildInputs = [];
# nativeBuildInputs = [];
};
});
}

View File

@ -0,0 +1,17 @@
use hyprland::{
data::{Client, Clients},
dispatch::{Direction, Dispatch, DispatchType},
shared::{HyprData, HyprDataActiveOptional},
};
pub fn get_active() -> Option<Client> {
Client::get_active().unwrap()
}
pub fn get() -> Clients {
Clients::get().unwrap()
}
pub fn focus_by_direction(direction: Direction) {
let _ = Dispatch::call(DispatchType::MoveFocus(direction));
}

View File

@ -0,0 +1,37 @@
pub mod client;
pub mod monitor;
pub mod option;
pub mod workspace;
use std::env;
use std::io::prelude::*;
use std::os::unix::net::UnixStream;
extern crate serde_json;
fn send_message(action: &str, args: Vec<&str>) -> String {
let env_var_name = "HYPRLAND_INSTANCE_SIGNATURE";
let hyprland_instance_sig = match env::var(env_var_name) {
Ok(v) => v,
Err(e) => panic!("${} is not set ({})", env_var_name, e),
};
let socket_path = format!("/tmp/hypr/{}/.socket.sock", hyprland_instance_sig);
let mut stream = match UnixStream::connect(socket_path) {
Err(_) => panic!("server is not running"),
Ok(stream) => stream,
};
let mut message = format!("j/{}", action);
args.into_iter()
.for_each(|a| message.push_str(&format!(" {}", a)));
// TODO: stop being stinky and manage errors
let _ = stream.write_all(message.as_bytes());
let mut response = String::new();
// TODO: stop being stinky and manage errors
let _ = stream.read_to_string(&mut response);
response
}

View File

@ -0,0 +1,43 @@
use hyprland::data::{Monitor, Monitors};
use hyprland::dispatch::*;
use hyprland::shared::HyprData;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
pub struct ActiveWorkspace {
pub id: u64,
pub name: String,
}
pub fn get_by_id(id: i16) -> Monitor {
let mut monitors = get();
monitors.find(|m| m.id == id).unwrap()
}
pub fn get() -> Monitors {
Monitors::get().unwrap()
}
pub fn focus_left() {
let _ = Dispatch::call(DispatchType::FocusMonitor(MonitorIdentifier::Direction(
Direction::Left,
)));
}
pub fn focus_right() {
let _ = Dispatch::call(DispatchType::FocusMonitor(MonitorIdentifier::Direction(
Direction::Right,
)));
}
pub fn focus_up() {
let _ = Dispatch::call(DispatchType::FocusMonitor(MonitorIdentifier::Direction(
Direction::Up,
)));
}
pub fn focus_down() {
let _ = Dispatch::call(DispatchType::FocusMonitor(MonitorIdentifier::Direction(
Direction::Down,
)));
}

View File

@ -0,0 +1,19 @@
use serde::{Deserialize, Serialize};
const GETOPTIONS: &str = "getoptions";
const GENERAL_GAPS_OUT: &str = "general:gaps_out";
#[derive(Serialize, Deserialize, Debug)]
pub struct HyprlandOption {
pub option: String,
pub int: i32,
pub float: f64,
pub str: String,
}
pub fn get_gaps() -> i16 {
let response = super::send_message(GETOPTIONS, vec![GENERAL_GAPS_OUT]);
let gap_option: HyprlandOption = serde_json::from_str(&response).unwrap();
gap_option.int as i16
}

View File

@ -0,0 +1,23 @@
// TODO: change this file to hyprland-rs
const WORKSPACE: &str = "workspace";
const DISPATCH: &str = "dispatch";
const MOVETOWORKSPACESILENT: &str = "movetoworkspacesilent";
const MOVETOWORKSPACE: &str = "movetoworkspace";
pub fn focus(workspace_number: &u64) {
let _ = super::send_message(DISPATCH, vec![WORKSPACE, &workspace_number.to_string()]);
}
pub fn move_to(workspace_number: &u64) {
super::send_message(
DISPATCH,
vec![MOVETOWORKSPACESILENT, &workspace_number.to_string()],
);
}
pub fn move_focus(workspace_number: &u64) {
super::send_message(
DISPATCH,
vec![MOVETOWORKSPACE, &workspace_number.to_string()],
);
}

350
hypr/hyprsome/src/main.rs Normal file
View File

@ -0,0 +1,350 @@
use clap::{Parser, Subcommand, ValueEnum};
mod hyprland_ipc;
use hyprland::{
data::{Client, Monitor, Transforms, Workspaces},
dispatch::Direction, shared::HyprData,
};
use hyprland_ipc::{client, monitor, option, workspace};
#[derive(Parser)]
#[command(name = "hyprsome")]
#[command(author = "sopa0")]
#[command(version = "0.1.11")]
#[command(about = "Makes hyprland workspaces behave like awesome", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Focus { direction: Directions },
Workspace { workspace_number: u64 },
Move { workspace_number: u64 },
Movefocus { workspace_number: u64 },
MoveEmpty,
FocusEmpty,
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug)]
enum Directions {
L,
R,
U,
D,
}
pub trait MonitorDimensions {
fn real_width(&self) -> f32;
fn real_height(&self) -> f32;
}
impl MonitorDimensions for Monitor {
fn real_width(&self) -> f32 {
match self.transform {
Transforms::Normal
| Transforms::Normal180
| Transforms::Flipped
| Transforms::Flipped180 => self.width as f32 / self.scale,
Transforms::Normal90 | Transforms::Normal270 | Transforms::Flipped90 => {
self.height as f32 / self.scale
}
_ => self.width as f32,
}
}
fn real_height(&self) -> f32 {
match self.transform {
Transforms::Normal
| Transforms::Flipped
| Transforms::Normal180
| Transforms::Flipped180 => self.height as f32 / self.scale,
Transforms::Normal90 | Transforms::Normal270 | Transforms::Flipped90 => {
self.width as f32 / self.scale
}
_ => self.height as f32,
}
}
}
pub fn get_current_monitor() -> Monitor {
monitor::get().find(|m| m.focused).unwrap()
}
//TODO: refactor this nonsense
pub fn select_workspace(workspace_number: &u64) {
let mon = get_current_monitor();
match mon.id {
0 => workspace::focus(workspace_number),
_ => {
workspace::focus(
&format!("{}{}", mon.id, workspace_number)
.parse::<u64>()
.unwrap(),
);
}
}
}
pub fn get_empty_workspace() -> u64 {
let mon = get_current_monitor();
let mut found = Vec::new();
for workspaces in Workspaces::get().iter() {
for workspace in workspaces.iter() {
if workspace.monitor == mon.name {
let mut id = workspace.name.clone();
if id.len() > 1 {
id = id.chars().nth(1).unwrap().to_string();
}
found.push(id);
}
}
}
for i in 1..9 {
if !found.contains(&i.to_string()) {
return i;
}
}
return 1; // Send to the first workspace if no others are available
}
//TODO: refactor this nonsense
pub fn send_to_workspace(workspace_number: &u64) {
let mon = get_current_monitor();
match mon.id {
0 => workspace::move_to(workspace_number),
_ => {
workspace::move_to(
&format!("{}{}", mon.id, workspace_number)
.parse::<u64>()
.unwrap(),
);
}
}
}
//TODO: refactor this nonsense
pub fn movefocus(workspace_number: &u64) {
let mon = get_current_monitor();
match mon.id {
0 => workspace::move_focus(workspace_number),
_ => {
workspace::move_focus(
&format!("{}{}", mon.id, workspace_number)
.parse::<u64>()
.unwrap(),
);
}
}
}
pub fn get_leftmost_client_for_monitor(mon_id: i16) -> Client {
let clients = client::get();
clients
.into_iter()
.filter(|c| c.monitor == mon_id)
.min_by_key(|c| c.at.0)
.unwrap()
}
pub fn focus_left(aw: Client) {
let mon = monitor::get_by_id(aw.monitor);
let is_leftmost_client = is_leftmost_client(&aw, &mon);
if is_leftmost_monitor(&mon) && is_leftmost_client {
return;
}
if is_leftmost_client {
monitor::focus_left();
return;
}
client::focus_by_direction(Direction::Left);
}
pub fn focus_right(aw: Client) {
let mon = monitor::get_by_id(aw.monitor);
if is_rightmost_monitor(&mon) && is_rightmost_client(&aw, &mon) {
return;
}
if is_rightmost_client(&aw, &mon) {
monitor::focus_right();
return;
}
client::focus_by_direction(Direction::Right);
}
pub fn focus_up(aw: Client) {
let mon = monitor::get_by_id(aw.monitor);
let is_top_client = is_top_client(&aw, &mon);
if is_top_monitor(&mon) && is_top_client {
return;
}
if is_top_client {
monitor::focus_up();
return;
}
client::focus_by_direction(Direction::Up);
}
pub fn focus_down(aw: Client) {
let mon = monitor::get_by_id(aw.monitor);
let is_bottom_client = is_bottom_client(&aw, &mon);
if is_bottom_monitor(&mon) && is_bottom_client {
return;
}
if is_bottom_client {
monitor::focus_down();
return;
}
client::focus_by_direction(Direction::Down);
}
pub fn is_leftmost_client(aw: &Client, mon: &Monitor) -> bool {
let gaps = option::get_gaps();
if (aw.at.0 - gaps) as i32 == mon.x {
return true;
}
false
}
pub fn is_rightmost_client(aw: &Client, mon: &Monitor) -> bool {
let gaps = option::get_gaps();
if mon.real_width() + mon.x as f32 - gaps as f32 == aw.size.0 as f32 + aw.at.0 as f32 {
return true;
}
false
}
pub fn is_top_client(aw: &Client, mon: &Monitor) -> bool {
let gaps = option::get_gaps();
if mon.y + (gaps as i32) + (mon.reserved.1 as i32) == (aw.at.1 as i32) {
return true;
}
false
}
pub fn is_bottom_client(aw: &Client, mon: &Monitor) -> bool {
let gaps = option::get_gaps();
if mon.real_height() + mon.y as f32 - gaps as f32 - mon.reserved.1 as f32
== aw.size.1 as f32 + gaps as f32
{
return true;
}
false
}
pub fn is_rightmost_monitor(mon: &Monitor) -> bool {
let monitors = monitor::get();
let max = monitors.into_iter().max_by_key(|m| m.x).unwrap();
if max.x == mon.x {
return true;
}
false
}
pub fn is_leftmost_monitor(mon: &Monitor) -> bool {
let monitors = monitor::get();
let min = monitors.into_iter().min_by_key(|m| m.x).unwrap();
if min.x == mon.x {
return true;
}
false
}
pub fn is_top_monitor(mon: &Monitor) -> bool {
let monitors = monitor::get();
let min = monitors.into_iter().min_by_key(|m| m.y).unwrap();
if min.y == mon.y {
return true;
}
false
}
pub fn is_bottom_monitor(mon: &Monitor) -> bool {
let monitors = monitor::get();
let max = monitors.into_iter().max_by_key(|m| m.y).unwrap();
if max.y == mon.y {
return true;
}
false
}
fn main() {
let cli = Cli::parse();
match &cli.command {
Commands::Focus { direction } => match direction {
Directions::L => {
let aw = client::get_active();
match aw {
Some(aw) => focus_left(aw),
None => monitor::focus_left(),
};
}
Directions::R => {
let aw = client::get_active();
match aw {
Some(aw) => focus_right(aw),
None => monitor::focus_right(),
};
}
Directions::U => {
let aw = client::get_active();
match aw {
Some(aw) => focus_up(aw),
None => monitor::focus_up(),
};
}
Directions::D => {
let aw = client::get_active();
match aw {
Some(aw) => focus_down(aw),
None => monitor::focus_down(),
};
}
},
Commands::Workspace { workspace_number } => {
select_workspace(workspace_number);
}
Commands::Move { workspace_number } => {
send_to_workspace(workspace_number);
}
Commands::Movefocus { workspace_number } => {
movefocus(workspace_number);
}
Commands::MoveEmpty => {
movefocus(&get_empty_workspace());
},
Commands::FocusEmpty => {
select_workspace(&get_empty_workspace());
},
}
}

View File

@ -1,8 +1,8 @@
set $mod Mod4 set $mod Mod4
font pango:monospace 0 font pango:monospace 0
exec --no-startup-id "/home/user/.config/awesome/scripts/setup_display.sh" exec --no-startup-id "/home/user/.config/scripts/setup_display.sh"
exec_always --no-startup-id "feh --no-fehbg --bg-fill /home/user/.config/awesome/wallpaper/wallpaper.png" exec_always --no-startup-id "feh --no-fehbg --bg-fill /home/user/.config/wallpaper/wallpaper.png"
exec --no-startup-id "picom -b" exec --no-startup-id "picom -b"
exec_always --no-startup-id "killall polybar; polybar -r &" exec_always --no-startup-id "killall polybar; polybar -r &"
exec --no-startup-id "nm-applet &" exec --no-startup-id "nm-applet &"
@ -36,21 +36,21 @@ floating_modifier $mod
tiling_drag modifier titlebar tiling_drag modifier titlebar
# start a terminal # start a terminal
bindsym $mod+Return exec /home/user/.config/awesome/scripts/launch_alacritty.sh $(xprop -id $(xdotool getwindowfocus) | ag ^_NET_WM_PID | cut -d '=' -f 2) bindsym $mod+Return exec /home/user/.config/scripts/launch_alacritty.sh $(xprop -id $(xdotool getwindowfocus) | ag ^_NET_WM_PID | cut -d '=' -f 2)
bindsym $mod+minus split v; exec /home/user/.config/awesome/scripts/launch_alacritty.sh $(xprop -id $(xdotool getwindowfocus) | ag ^_NET_WM_PID | cut -d '=' -f 2) bindsym $mod+minus split v; exec /home/user/.config/scripts/launch_alacritty.sh $(xprop -id $(xdotool getwindowfocus) | ag ^_NET_WM_PID | cut -d '=' -f 2)
bindsym $mod+bar split h; exec /home/user/.config/awesome/scripts/launch_alacritty.sh $(xprop -id $(xdotool getwindowfocus) | ag ^_NET_WM_PID | cut -d '=' -f 2) bindsym $mod+bar split h; exec /home/user/.config/scripts/launch_alacritty.sh $(xprop -id $(xdotool getwindowfocus) | ag ^_NET_WM_PID | cut -d '=' -f 2)
# kill focused window # kill focused window
bindsym $mod+q kill bindsym $mod+q kill
# start dmenu (a program launcher) # start dmenu (a program launcher)
bindsym $mod+d exec "~/.config/awesome/scripts/toggle_rofi.sh" bindsym $mod+d exec "~/.config/scripts/toggle_rofi.sh"
bindsym $mod+XF86Launch5 exec "~/.config/awesome/scripts/toggle_rofi.sh" bindsym $mod+XF86Launch5 exec "~/.config/scripts/toggle_rofi.sh"
bindsym $mod+Escape exec "rofi -show power-menu -modi power-menu:~/.config/awesome/scripts/rofi-power-menu" bindsym $mod+Escape exec "rofi -show power-menu -modi power-menu:~/.config/scripts/rofi-power-menu"
bindsym XF86PowerOff exec "rofi -show power-menu -modi power-menu:~/.config/awesome/scripts/rofi-power-menu" bindsym XF86PowerOff exec "rofi -show power-menu -modi power-menu:~/.config/scripts/rofi-power-menu"
bindsym $mod+c exec CM_LAUNCHER=rofi-script rofi -modi "clipmenu:/usr/bin/clipmenu" -show clipmenu bindsym $mod+c exec CM_LAUNCHER=rofi-script rofi -modi "clipmenu:/usr/bin/clipmenu" -show clipmenu
bindsym $mod+b exec firefox bindsym $mod+b exec firefox
bindsym $mod+a exec nautilus bindsym $mod+a exec nautilus

View File

@ -153,7 +153,7 @@ format-foreground = ${colors.white}
format-warn-background = ${self.background} format-warn-background = ${self.background}
exec = cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor exec = cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
format = " <label> " format = " <label> "
click-left = /home/user/.config/awesome/scripts/toggle_performance.sh click-left = /home/user/.config/scripts/toggle_performance.sh
[module/xwindow] [module/xwindow]
; Other settings ; Other settings

View File

@ -16,4 +16,4 @@ export WINEPREFIX="$XDG_DATA_HOME"/wine
export ZDOTDIR="$XDG_CONFIG_HOME"/zsh export ZDOTDIR="$XDG_CONFIG_HOME"/zsh
export XDG_CURRENT_DESKTOP=GNOME export XDG_CURRENT_DESKTOP=GNOME
export OPENCV_LOG_LEVEL=ERROR export OPENCV_LOG_LEVEL=ERROR
export PATH="$HOME/.local/bin:$PATH"

View File

@ -1,6 +1,6 @@
if ps -C rofi > /dev/null if ps -C rofi > /dev/null
then then
echo "Already running" killall rofi
else else
export TERMINAL=alacritty export TERMINAL=alacritty
rofi -show combi -combi-modi drun,calc:~/.config/rofi/show-calculator.sh -sort -levenshtein-sort rofi -show combi -combi-modi drun,calc:~/.config/rofi/show-calculator.sh -sort -levenshtein-sort

View File

@ -2,20 +2,21 @@
"layer": "top", // Waybar at top layer "layer": "top", // Waybar at top layer
"height": 28, // Waybar height (to be removed for auto height) "height": 28, // Waybar height (to be removed for auto height)
"spacing": 4, // Gaps between modules (4px) "spacing": 4, // Gaps between modules (4px)
"output": "eDP-1",
"modules-left": ["hyprland/window"], "modules-left": ["hyprland/window"],
"modules-center": ["hyprland/workspaces"], "modules-center": ["hyprland/workspaces"],
"modules-right": ["tray", "wireplumber", "cpu", "memory", "custom/updates", "temperature", "battery", "clock"], "modules-right": ["tray", "wireplumber", "cpu#cpu2", "cpu", "memory", "custom/updates", "temperature", "battery", "clock"],
"wireplumber": { "wireplumber": {
"format": "{icon} {volume}%", "format": "{icon} {volume}%",
"on-click": "helvum",
"format-muted": "", "format-muted": "",
"on-click": "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle", "on-click": "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle",
"format-icons": ["", "", ""] "format-icons": ["", "", ""]
}, },
"hyprland/workspaces": { "hyprland/workspaces": {
"disable-scroll": true, "disable-scroll": true,
"all-outputs": false, "all-outputs": true,
"warp-on-scroll": false "warp-on-scroll": false,
"format": "{name}"
}, },
"hyprland/window": { "hyprland/window": {
"max-length": 50, "max-length": 50,
@ -36,6 +37,11 @@
"tooltip": false, "tooltip": false,
"interval": 5 "interval": 5
}, },
"cpu#cpu2": {
"format": "CPU {usage}%",
"tooltip": false,
"interval": 5
},
"custom/updates": { "custom/updates": {
"exec": "bash -c \"checkupdates | wc -l\"", "exec": "bash -c \"checkupdates | wc -l\"",
"on-click": "alacritty -e bash -c \"yay ; echo '\nDone, press any key to exit...' ; read\"", "on-click": "alacritty -e bash -c \"yay ; echo '\nDone, press any key to exit...' ; read\"",
@ -49,6 +55,7 @@
"temperature": { "temperature": {
"thermal-zone": 6, "thermal-zone": 6,
// "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input", // "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
"interval": 5,
"critical-threshold": 80, "critical-threshold": 80,
// "format-critical": "{temperatureC}°C {icon}", // "format-critical": "{temperatureC}°C {icon}",
"format": "{temperatureC}°C", "format": "{temperatureC}°C",
@ -67,28 +74,4 @@
// "format-full": "", // "format-full": "",
"format-icons": [" ", " ", " ", " ", " "] "format-icons": [" ", " ", " ", " ", " "]
}, },
"battery#bat2": {
"bat": "BAT2"
},
"network": {
// "interface": "wlp2*", // (Optional) To force the use of this interface
"format-wifi": "{essid} ({signalStrength}%) ",
"format-ethernet": "{ipaddr}/{cidr} ",
"tooltip-format": "{ifname} via {gwaddr} ",
"format-linked": "{ifname} (No IP) ",
"format-disconnected": "Disconnected ⚠",
"format-alt": "{ifname}: {ipaddr}/{cidr}"
},
"custom/media": {
"format": "{icon} {}",
"return-type": "json",
"max-length": 40,
"format-icons": {
"spotify": "",
"default": "🎜"
},
"escape": true,
"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null" // Script in resources folder
// "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name
}
} }