Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
lars-berger authored Nov 7, 2024
2 parents e2d367d + 04e6c2f commit aaa1473
Show file tree
Hide file tree
Showing 41 changed files with 384 additions and 194 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ GlazeWM lets you easily organize windows and adjust their layout on the fly by u

[Installation](#installation)
[Default keybindings](#default-keybindings)
[Config documentation](#config-docs)
[Config documentation](#config-documentation)
[FAQ](#faq)
[Contributing ↗](https://github.com/glzr-io/glazewm/blob/main/CONTRIBUTING.md)

Expand Down
8 changes: 4 additions & 4 deletions packages/watcher/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ async fn main() -> anyhow::Result<()> {

let managed_windows = managed_handles
.into_iter()
.map(|handle| NativeWindow::new(handle))
.map(NativeWindow::new)
.collect::<Vec<_>>();

run_cleanup(managed_windows);
Expand All @@ -56,7 +56,7 @@ async fn query_initial_windows(
.context("Failed to send window query command.")?;

client
.client_response(&query_message)
.client_response(query_message)
.await
.and_then(|response| match response.data {
Some(ClientResponseData::Windows(data)) => Some(data),
Expand All @@ -83,12 +83,12 @@ async fn watch_managed_handles(
"sub -e window_managed window_unmanaged application_exiting";

client
.send(&subscription_message)
.send(subscription_message)
.await
.context("Failed to send subscribe command to IPC server.")?;

let subscription_id = client
.client_response(&subscription_message)
.client_response(subscription_message)
.await
.and_then(|response| match response.data {
Some(ClientResponseData::EventSubscribe(data)) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/wm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ edition = "2021"
default-run = "glazewm"

[lib]
path = "src\\lib.rs"
path = "src/lib.rs"

[[bin]]
name = "glazewm"
path = "src\\main.rs"
path = "src/main.rs"

[features]
no_console = []
Expand Down
90 changes: 78 additions & 12 deletions packages/wm/src/app_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ use crate::{
windows::{
commands::{
ignore_window, move_window_in_direction, move_window_to_workspace,
resize_window, set_window_size, update_window_state,
resize_window, set_window_position, set_window_position_to_center,
set_window_size, update_window_state,
},
traits::WindowGetters,
WindowState,
Expand All @@ -38,7 +39,7 @@ use crate::{
},
};

const VERSION: &'static str = env!("VERSION_NUMBER");
const VERSION: &str = env!("VERSION_NUMBER");

#[derive(Clone, Debug, Parser)]
#[clap(author, version = VERSION, about, long_about = None)]
Expand Down Expand Up @@ -188,13 +189,26 @@ pub enum InvokeCommand {
#[clap(long)]
direction: Direction,
},
Position(InvokePositionCommand),
Resize(InvokeResizeCommand),
SetFloating {
#[clap(long, default_missing_value = "true", require_equals = true, num_args = 0..=1)]
shown_on_top: Option<bool>,

#[clap(long, default_missing_value = "true", require_equals = true, num_args = 0..=1)]
centered: Option<bool>,

#[clap(long, allow_hyphen_values = true)]
x_pos: Option<i32>,

#[clap(long, allow_hyphen_values = true)]
y_pos: Option<i32>,

#[clap(long, allow_hyphen_values = true)]
width: Option<LengthValue>,

#[clap(long, allow_hyphen_values = true)]
height: Option<LengthValue>,
},
SetFullscreen {
#[clap(long, default_missing_value = "true", require_equals = true, num_args = 0..=1)]
Expand All @@ -210,6 +224,9 @@ pub enum InvokeCommand {
visibility: TitleBarVisibility,
},
ShellExec {
#[clap(long, action)]
hide_window: bool,

#[clap(required = true, trailing_var_arg = true)]
command: Vec<String>,
},
Expand Down Expand Up @@ -427,6 +444,20 @@ impl InvokeCommand {
config,
)
}
InvokeCommand::Position(args) => {
match subject_container.as_window_container() {
Ok(window) => match args.centered {
true => set_window_position_to_center(window, state),
false => set_window_position(
window,
args.x_pos.clone(),
args.y_pos.clone(),
state,
),
},
_ => Ok(()),
}
}
InvokeCommand::Resize(args) => {
match subject_container.as_window_container() {
Ok(window) => resize_window(
Expand All @@ -441,22 +472,47 @@ impl InvokeCommand {
InvokeCommand::SetFloating {
centered,
shown_on_top,
x_pos,
y_pos,
width,
height,
} => match subject_container.as_window_container() {
Ok(window) => {
let floating_defaults =
&config.value.window_behavior.state_defaults.floating;
let is_centered = centered.unwrap_or(floating_defaults.centered);

update_window_state(
let window = update_window_state(
window.clone(),
WindowState::Floating(FloatingStateConfig {
centered: centered.unwrap_or(floating_defaults.centered),
centered: is_centered,
shown_on_top: shown_on_top
.unwrap_or(floating_defaults.shown_on_top),
}),
state,
config,
)?;

if width.is_some() || height.is_some() {
set_window_size(
window.clone(),
width.clone(),
height.clone(),
state,
)?;
}

if is_centered {
set_window_position_to_center(window, state)?;
} else if x_pos.is_some() || y_pos.is_some() {
set_window_position(
window.clone(),
x_pos.clone(),
y_pos.clone(),
state,
)?;
}

Ok(())
}
_ => Ok(()),
Expand Down Expand Up @@ -519,20 +575,17 @@ impl InvokeCommand {
match subject_container.as_window_container() {
Ok(window) => {
_ = window.native().set_title_bar_visibility(
if *visibility == TitleBarVisibility::Shown {
true
} else {
false
},
*visibility == TitleBarVisibility::Shown,
);
Ok(())
}
_ => Ok(()),
}
}
InvokeCommand::ShellExec { command } => {
shell_exec(&command.join(" "))
}
InvokeCommand::ShellExec {
hide_window,
command,
} => shell_exec(&command.join(" "), *hide_window),
InvokeCommand::Size(args) => {
match subject_container.as_window_container() {
Ok(window) => set_window_size(
Expand Down Expand Up @@ -801,3 +854,16 @@ pub struct InvokeResizeCommand {
#[clap(long, allow_hyphen_values = true)]
height: Option<LengthValue>,
}

#[derive(Args, Clone, Debug, PartialEq, Serialize)]
#[group(required = true, multiple = true)]
pub struct InvokePositionCommand {
#[clap(long, action)]
centered: bool,

#[clap(long, allow_hyphen_values = true)]
x_pos: Option<i32>,

#[clap(long, allow_hyphen_values = true)]
y_pos: Option<i32>,
}
14 changes: 8 additions & 6 deletions packages/wm/src/common/commands/cycle_focus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ pub fn cycle_focus(
let window_of_type = workspace
.descendant_focus_order()
.filter_map(|descendant| descendant.as_window_container().ok())
.find(|descendant| match (descendant.state(), &next) {
(WindowState::Floating(_), WindowState::Floating(_)) => true,
(WindowState::Fullscreen(_), WindowState::Fullscreen(_)) => true,
(WindowState::Minimized, WindowState::Minimized) => true,
(WindowState::Tiling, WindowState::Tiling) => true,
_ => false,
.find(|descendant| {
matches!(
(descendant.state(), &next),
(WindowState::Floating(_), WindowState::Floating(_))
| (WindowState::Fullscreen(_), WindowState::Fullscreen(_))
| (WindowState::Minimized, WindowState::Minimized)
| (WindowState::Tiling, WindowState::Tiling)
)
});

if let Some(window) = window_of_type {
Expand Down
10 changes: 5 additions & 5 deletions packages/wm/src/common/commands/platform_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub fn platform_sync(
state: &mut WmState,
config: &UserConfig,
) -> anyhow::Result<()> {
if state.pending_sync.containers_to_redraw.len() > 0 {
if !state.pending_sync.containers_to_redraw.is_empty() {
redraw_containers(state, config)?;
state.pending_sync.containers_to_redraw.clear();
}
Expand Down Expand Up @@ -132,10 +132,10 @@ fn redraw_containers(
.to_rect()?
.apply_delta(&window.total_border_delta()?, None);

let is_visible = match window.display_state() {
DisplayState::Showing | DisplayState::Shown => true,
_ => false,
};
let is_visible = matches!(
window.display_state(),
DisplayState::Showing | DisplayState::Shown
);

if let Err(err) = window.native().set_position(
&window.state(),
Expand Down
1 change: 0 additions & 1 deletion packages/wm/src/common/commands/reload_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ fn update_container_gaps(state: &mut WmState, config: &UserConfig) {
let tiling_containers = state
.root_container
.self_and_descendants()
.into_iter()
.filter_map(|container| container.as_tiling_container().ok());

for container in tiling_containers {
Expand Down
4 changes: 2 additions & 2 deletions packages/wm/src/common/commands/shell_exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use tracing::{error, info};

use crate::common::platform::Platform;

pub fn shell_exec(command: &str) -> anyhow::Result<()> {
pub fn shell_exec(command: &str, hide_window: bool) -> anyhow::Result<()> {
let res =
Platform::parse_command(command).and_then(|(program, args)| {
info!("Parsed command program: '{}', args: '{}'.", program, args);

Platform::run_command(&program, &args)
Platform::run_command(&program, &args, hide_window)
});

match res {
Expand Down
9 changes: 7 additions & 2 deletions packages/wm/src/common/direction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ impl Direction {
///
/// Example:
/// ```
/// Direction::Left.inverse() // Direction::Right
/// # use wm::common::Direction;
/// let dir = Direction::Left.inverse();
/// assert_eq!(dir, Direction::Right);
/// ```
pub fn inverse(&self) -> Direction {
match self {
Expand All @@ -36,7 +38,10 @@ impl FromStr for Direction {
///
/// Example:
/// ```
/// Direction::from_str("left") // Direction::Left
/// # use wm::common::Direction;
/// # use std::str::FromStr;
/// let dir = Direction::from_str("left");
/// assert_eq!(dir.unwrap(), Direction::Left);
/// ```
fn from_str(unparsed: &str) -> anyhow::Result<Self> {
match unparsed {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ pub fn handle_display_settings_changed(
}

for native_monitor in new_native_monitors {
match pending_monitors.get(0) {
match pending_monitors.first() {
Some(_) => {
let monitor = pending_monitors.remove(0);
update_monitor(monitor, native_monitor, state)
Expand Down
17 changes: 15 additions & 2 deletions packages/wm/src/common/events/handle_window_destroyed.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use anyhow::Context;
use tracing::info;

use crate::{
common::platform::NativeWindow, windows::commands::unmanage_window,
wm_state::WmState,
common::platform::NativeWindow, containers::traits::CommonGetters,
windows::commands::unmanage_window, wm_state::WmState,
workspaces::commands::deactivate_workspace,
};

pub fn handle_window_destroyed(
Expand All @@ -14,8 +16,19 @@ pub fn handle_window_destroyed(
// Unmanage the window if it's currently managed.
if let Some(window) = found_window {
// TODO: Log window details.
let workspace = window.workspace().context("No workspace.")?;

info!("Window closed");
unmanage_window(window, state)?;

// Destroy parent workspace if window was killed while its workspace
// was not displayed (e.g. via task manager).
if !workspace.config().keep_alive
&& !workspace.has_children()
&& !workspace.is_displayed()
{
deactivate_workspace(workspace, state)?;
}
}

Ok(())
Expand Down
7 changes: 1 addition & 6 deletions packages/wm/src/common/events/handle_window_focused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ use anyhow::Context;
use tracing::info;

use crate::{
common::{
platform::{NativeWindow, Platform},
DisplayState,
},
common::{platform::NativeWindow, DisplayState},
containers::{commands::set_focused_descendant, traits::CommonGetters},
user_config::{UserConfig, WindowRuleEvent},
windows::{commands::run_window_rules, traits::WindowGetters},
Expand All @@ -24,10 +21,8 @@ pub fn handle_window_focused(
// Ignore the focus event if:
// 1. Window is being hidden by the WM.
// 2. Focus is already set to the WM's focused container.
// 3. Window is not actually the foreground window.
if window.display_state() == DisplayState::Hiding
|| state.focused_container() == Some(window.clone().into())
|| Platform::foreground_window() != native_window
{
return Ok(());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub fn handle_window_location_changed(
// A fullscreen window that gets minimized can hit this arm, so
// ignore such events and let it be handled by the handler for
// `PlatformEvent::WindowMinimized` instead.
if !(is_fullscreen || is_maximized) && !is_minimized {
if !(is_fullscreen || is_maximized || !is_minimized) {
info!("Window restored");

let target_state = window
Expand Down
Loading

0 comments on commit aaa1473

Please sign in to comment.