feat(wm): impl drag to move in append mode

This commit ensures that when a window is dragged over another window container while
WindowContainerBehaviour::Append is set, the window will be removed from its current
container and appended to the target container instead of swapping the positions of the two
containers, as would be the case for WindowContainerBehaviour::Create.

re #72
This commit is contained in:
LGUG2Z
2021-11-15 12:38:08 -08:00
parent 676b643faf
commit 4a19edaab2
6 changed files with 55 additions and 33 deletions

View File

@@ -51,7 +51,7 @@ pub enum SocketMessage {
ToggleFloat,
ToggleMonocle,
ToggleMaximize,
ToggleNewWindowBehaviour,
ToggleWindowContainerBehaviour,
// Current Workspace Commands
ManageFocusedWindow,
UnmanageFocusedWindow,
@@ -142,9 +142,9 @@ pub enum FocusFollowsMouseImplementation {
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]
#[strum(serialize_all = "snake_case")]
pub enum NewWindowBehaviour {
CreateNewContainer,
AppendToFocusedContainer,
pub enum WindowContainerBehaviour {
Create,
Append,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]

View File

@@ -18,12 +18,12 @@ use uds_windows::UnixStream;
use komorebi_core::Axis;
use komorebi_core::FocusFollowsMouseImplementation;
use komorebi_core::Layout;
use komorebi_core::NewWindowBehaviour;
use komorebi_core::OperationDirection;
use komorebi_core::Rect;
use komorebi_core::Sizing;
use komorebi_core::SocketMessage;
use komorebi_core::StateQuery;
use komorebi_core::WindowContainerBehaviour;
use crate::notify_subscribers;
use crate::window_manager;
@@ -548,14 +548,16 @@ impl WindowManager {
SocketMessage::ResizeDelta(delta) => {
self.resize_delta = delta;
}
SocketMessage::ToggleNewWindowBehaviour => match self.new_window_behaviour {
NewWindowBehaviour::CreateNewContainer => {
self.new_window_behaviour = NewWindowBehaviour::AppendToFocusedContainer;
SocketMessage::ToggleWindowContainerBehaviour => {
match self.window_container_behaviour {
WindowContainerBehaviour::Create => {
self.window_container_behaviour = WindowContainerBehaviour::Append;
}
WindowContainerBehaviour::Append => {
self.window_container_behaviour = WindowContainerBehaviour::Create;
}
}
NewWindowBehaviour::AppendToFocusedContainer => {
self.new_window_behaviour = NewWindowBehaviour::CreateNewContainer;
}
},
}
};
tracing::info!("processed");

View File

@@ -7,10 +7,10 @@ use color_eyre::Result;
use crossbeam_channel::select;
use parking_lot::Mutex;
use komorebi_core::NewWindowBehaviour;
use komorebi_core::OperationDirection;
use komorebi_core::Rect;
use komorebi_core::Sizing;
use komorebi_core::WindowContainerBehaviour;
use crate::notify_subscribers;
use crate::window_manager::WindowManager;
@@ -202,16 +202,16 @@ impl WindowManager {
}
}
let behaviour = self.new_window_behaviour;
let behaviour = self.window_container_behaviour;
let workspace = self.focused_workspace_mut()?;
if !workspace.contains_window(window.hwnd) {
match behaviour {
NewWindowBehaviour::CreateNewContainer => {
WindowContainerBehaviour::Create => {
workspace.new_container_for_window(*window);
self.update_focused_workspace(false)?;
}
NewWindowBehaviour::AppendToFocusedContainer => {
WindowContainerBehaviour::Append => {
workspace
.focused_container_mut()
.ok_or_else(|| anyhow!("there is no focused container"))?
@@ -247,6 +247,8 @@ impl WindowManager {
.monitor_idx_from_current_pos()
.ok_or_else(|| anyhow!("cannot get monitor idx from current position"))?;
let new_window_behaviour = self.window_container_behaviour;
let workspace = self.focused_workspace_mut()?;
if workspace
.floating_windows()
@@ -352,15 +354,33 @@ impl WindowManager {
self.focus_workspace(target_workspace_idx)?;
self.update_focused_workspace(false)?;
}
// Here we handle a simple move on the same monitor which is treated as
// a container swap
} else {
// Here we handle a simple move on the same monitor which is treated as
// a container swap
match workspace.container_idx_from_current_point() {
Some(target_idx) => {
workspace.swap_containers(focused_container_idx, target_idx);
self.update_focused_workspace(false)?;
match new_window_behaviour {
WindowContainerBehaviour::Create => {
match workspace.container_idx_from_current_point() {
Some(target_idx) => {
workspace
.swap_containers(focused_container_idx, target_idx);
self.update_focused_workspace(false)?;
}
None => {
self.update_focused_workspace(self.mouse_follows_focus)?;
}
}
}
WindowContainerBehaviour::Append => {
match workspace.container_idx_from_current_point() {
Some(target_idx) => {
workspace.move_window_to_container(target_idx)?;
self.update_focused_workspace(false)?;
}
None => {
self.update_focused_workspace(self.mouse_follows_focus)?;
}
}
}
None => self.update_focused_workspace(self.mouse_follows_focus)?,
}
}
} else {

View File

@@ -21,10 +21,10 @@ use komorebi_core::CycleDirection;
use komorebi_core::DefaultLayout;
use komorebi_core::FocusFollowsMouseImplementation;
use komorebi_core::Layout;
use komorebi_core::NewWindowBehaviour;
use komorebi_core::OperationDirection;
use komorebi_core::Rect;
use komorebi_core::Sizing;
use komorebi_core::WindowContainerBehaviour;
use crate::container::Container;
use crate::load_configuration;
@@ -51,7 +51,7 @@ pub struct WindowManager {
pub invisible_borders: Rect,
pub work_area_offset: Option<Rect>,
pub resize_delta: i32,
pub new_window_behaviour: NewWindowBehaviour,
pub window_container_behaviour: WindowContainerBehaviour,
pub focus_follows_mouse: Option<FocusFollowsMouseImplementation>,
pub mouse_follows_focus: bool,
pub hotwatch: Hotwatch,
@@ -66,7 +66,7 @@ pub struct State {
pub is_paused: bool,
pub invisible_borders: Rect,
pub resize_delta: i32,
pub new_window_behaviour: NewWindowBehaviour,
pub new_window_behaviour: WindowContainerBehaviour,
pub work_area_offset: Option<Rect>,
pub focus_follows_mouse: Option<FocusFollowsMouseImplementation>,
pub mouse_follows_focus: bool,
@@ -86,7 +86,7 @@ impl From<&WindowManager> for State {
invisible_borders: wm.invisible_borders,
work_area_offset: wm.work_area_offset,
resize_delta: wm.resize_delta,
new_window_behaviour: wm.new_window_behaviour,
new_window_behaviour: wm.window_container_behaviour,
focus_follows_mouse: wm.focus_follows_mouse.clone(),
mouse_follows_focus: wm.mouse_follows_focus,
has_pending_raise_op: wm.has_pending_raise_op,
@@ -160,7 +160,7 @@ impl WindowManager {
bottom: 7,
},
work_area_offset: None,
new_window_behaviour: NewWindowBehaviour::CreateNewContainer,
window_container_behaviour: WindowContainerBehaviour::Create,
resize_delta: 50,
focus_follows_mouse: None,
mouse_follows_focus: true,

View File

@@ -184,8 +184,8 @@ WorkspaceName(monitor, workspace, value) {
Run, komorebic.exe workspace-name %monitor% %workspace% %value%, , Hide
}
ToggleNewWindowBehaviour() {
Run, komorebic.exe toggle-new-window-behaviour, , Hide
ToggleWindowContainerBehaviour() {
Run, komorebic.exe toggle-window-container-behaviour, , Hide
}
TogglePause() {

View File

@@ -484,7 +484,7 @@ enum SubCommand {
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
WorkspaceName(WorkspaceName),
/// Toggle the behaviour for new windows (stacking or dynamic tiling)
ToggleNewWindowBehaviour,
ToggleWindowContainerBehaviour,
/// Toggle window tiling on the focused workspace
TogglePause,
/// Toggle window tiling on the focused workspace
@@ -960,8 +960,8 @@ fn main() -> Result<()> {
SubCommand::ResizeDelta(arg) => {
send_message(&*SocketMessage::ResizeDelta(arg.pixels).as_bytes()?)?;
}
SubCommand::ToggleNewWindowBehaviour => {
send_message(&*SocketMessage::ToggleNewWindowBehaviour.as_bytes()?)?;
SubCommand::ToggleWindowContainerBehaviour => {
send_message(&*SocketMessage::ToggleWindowContainerBehaviour.as_bytes()?)?;
}
}