Skip to content

Commit

Permalink
focused window handling
Browse files Browse the repository at this point in the history
  • Loading branch information
laudominik committed Sep 8, 2024
1 parent 1472302 commit 5279676
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 48 deletions.
7 changes: 5 additions & 2 deletions script/test
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#!/bin/sh
export TESTAPP=snes9x-gtk
export TESTAPP0=alacritty
export TESTAPP1=snes9x-gtk
export DISPLAY=":1"

$TESTAPP
$TESTAPP0 &
$TESTAPP0 &
$TESTAPP1
12 changes: 6 additions & 6 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ use std::thread;
pub static STYLE: Style = Style {
colors: ColorSchemes {
normal: ColorScheme {
fg: "#222",
bg: "#222",
border: "#ff0000"
fg: "#024442",
bg: "#ffffff",
border: "#8b9458"
},
selected: ColorScheme {
fg: "#222",
bg: "#222",
border: "#222"
fg: "#ffff00",
bg: "#ffffff",
border: "#ffff00"
}
},
border_thickness: 3,
Expand Down
5 changes: 3 additions & 2 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::mem;

use x11::xlib::{self, CWBorderWidth, False, Window, XConfigureWindow, XDisplayHeight, XDisplayWidth, XFlush, XGetWindowAttributes, XMapRequestEvent, XMapWindow, XMoveResizeWindow, XSetWindowBorder, XSync, XWindowAttributes, XWindowChanges};

use crate::{state::State, config::STYLE, wm::_Tile};
use crate::{active_workspace_wins, config::STYLE, state::State, wm::_Tile};


macro_rules! callback {
Expand All @@ -25,7 +25,8 @@ fn map_request(state: &mut State, ev: xlib::XMapRequestEvent){
let mut wa : XWindowAttributes = unsafe { mem::zeroed() };
if( unsafe { XGetWindowAttributes(state.dpy, ev.window, &mut wa) } == 0) { return };

state.workspaces[state.active_workspace].windows.push(ev.window);
state.focus(ev.window);
active_workspace_wins!(state).push(ev.window);
state.retile();
unsafe {XSync(state.dpy, False)};
}
31 changes: 6 additions & 25 deletions src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::mem;
use crate::config::STYLE;
use crate::wm;
use crate::style::{self};
use crate::state::{Cursor, NetAtoms, WmAtoms};
use crate::state::{Active, Cursor, NetAtoms, WmAtoms};

use super::error;
use super::state;
Expand All @@ -25,13 +25,6 @@ pub fn check_other_wms(dpy: &mut xlib::Display){
}
}

macro_rules! init_atom {
($dpy:expr, $name:expr) => {{
let c_name = CString::new($name).unwrap();
unsafe {xlib::XInternAtom($dpy, c_name.as_ptr(), xlib::False)}
}};
}

macro_rules! init_cursor {
($dpy:expr, $ty:expr) => {{
unsafe {xlib::XCreateFontCursor($dpy, $ty)}
Expand All @@ -47,31 +40,19 @@ pub fn setup(dpy: &mut xlib::Display) -> state::State {
state = state::State {
screen: screen,
root: root,
wmatom: WmAtoms {
protocols: init_atom!(dpy, "WM_PROTOCOLS"),
delete: init_atom!(dpy, "WM_DELETE_WINDOW"),
state: init_atom!(dpy, "WM_STATE"),
take_focus: init_atom!(dpy, "WM_TAKE_FOCUS")
},
netatom: NetAtoms {
active_window: init_atom!(dpy, "ACTIVE_WINDOW"),
supported: init_atom!(dpy, "_NET_SUPPORTED"),
state: init_atom!(dpy, "_NET_WM_STATE"),
check: init_atom!(dpy, "_NET_SUPPORTING_WM_CHECK"),
fullscreen: init_atom!(dpy, "FULLSCREEN"),
wtype: init_atom!(dpy, "_NET_WINDOW_TYPE")
},

cursor: Cursor {
normal: init_cursor!(dpy, 68 /* XC left ptr */),
resize: init_cursor!(dpy, 120 /* XC sizing */),
mov: init_cursor!(dpy, 52 /* XC fleur */)
},
dpy: dpy,
workspaces: Vec::new(),
active_workspace: 0,
colors: unsafe { mem::zeroed() },
keybindings: Vec::new()
keybindings: Vec::new(),
active: Active {
workspace: 0,
window: root
}
};
}

Expand Down
13 changes: 8 additions & 5 deletions src/state.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use x11::xlib;
use x11::xlib::{self, Window};

use crate::{style::{ColorSchemesXft}, wm};

Expand Down Expand Up @@ -31,14 +31,17 @@ pub struct Cursor_<T> {
pub struct State<'a> {
pub screen: i32,
pub root: xlib::Window,
pub wmatom: WmAtoms,
pub netatom: NetAtoms,
pub cursor: Cursor,
pub dpy: &'a mut xlib::Display,
pub workspaces: Vec<wm::Space<'a>>,
pub active_workspace: usize,
pub colors : ColorSchemesXft,
pub keybindings: Vec<Keybinding>
pub keybindings: Vec<Keybinding>,
pub active: Active
}

pub struct Active {
pub workspace: usize,
pub window: Window
}

pub struct Keybinding {}
30 changes: 22 additions & 8 deletions src/wm.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use x11::xlib::{CWBorderWidth, False, Window, XConfigureWindow, XDisplayHeight, XDisplayWidth, XMapWindow, XMoveResizeWindow, XSetWindowBorder, XSync, XWindowChanges};
use x11::xlib::{CWBorderWidth, CurrentTime, False, RevertToNone, RevertToPointerRoot, Window, XConfigureWindow, XDisplayHeight, XDisplayWidth, XMapWindow, XMoveResizeWindow, XSetInputFocus, XSetWindowBorder, XSync, XWindowChanges};
use std::{mem, process::exit};

use crate::{config::STYLE, state};
Expand All @@ -13,18 +13,30 @@ pub struct _Tile {
pub size: (u32, u32)
}

#[macro_export]
macro_rules! active_workspace_wins {
($state: expr) => {
$state.workspaces[$state.active.workspace].windows
};
}

impl state::State<'_> {

pub fn focus(&mut self, window: Window){
self.active.window = window;
}

pub fn cascade_autotiling(&mut self){
let useless_gap: u32 = STYLE.useless_gap;
let border = STYLE.border_thickness;
let screen_width = unsafe{XDisplayWidth(self.dpy, self.screen) as u32};
let screen_height = unsafe{XDisplayHeight(self.dpy, self.screen) as u32};

let maybe_latest_window: Option<&u64> = self.workspaces[self.active_workspace].windows.last();
let maybe_latest_window: Option<&u64> = active_workspace_wins!(self).last();
if(maybe_latest_window.is_none()) { return };

let latest_window = maybe_latest_window.unwrap();
if self.workspaces[self.active_workspace].windows.len() == 1 {
if self.workspaces[self.active.workspace].windows.len() == 1 {
latest_window.do_map(self, (
useless_gap as i32, useless_gap as i32,
screen_width - useless_gap * 2 - border * 2, screen_height - useless_gap * 2 - border * 2
Expand All @@ -37,38 +49,40 @@ impl state::State<'_> {
screen_width / 2 - useless_gap * 2 - border * 2, screen_height - useless_gap * 2 - border * 2
));

let len_rest = self.workspaces[self.active_workspace].windows.len() - 1;
let len_rest = active_workspace_wins!(self).len() - 1;
let increment = screen_height / len_rest as u32;

for i in 0..len_rest {
let start_y = increment * i as u32 + useless_gap;

self.workspaces[self.active_workspace].windows[i].do_map(self, (
active_workspace_wins!(self)[i].do_map(self, (
(useless_gap / 2 + screen_width / 2) as i32, start_y as i32,
screen_width / 2 - useless_gap * 2 - border * 2, increment - useless_gap * 2 - border * 2
));
}
}
}



trait WindowExt {
fn do_map(self, state: &mut state::State, rect: (i32, i32, u32, u32));
}

impl WindowExt for Window {
fn do_map(self, state: &mut state::State, rect: (i32, i32, u32, u32)){
let mut wc: XWindowChanges = unsafe { mem::zeroed() };
let mut border_col = state.colors.normal.border.pixel;
wc.border_width = STYLE.border_thickness as i32;

if self == state.active.window { border_col = state.colors.selected.border.pixel; }

unsafe {
XConfigureWindow(state.dpy, self, CWBorderWidth.into(), &mut wc as *mut XWindowChanges);
XSetWindowBorder(state.dpy, self, state.colors.normal.border.pixel);
XSetWindowBorder(state.dpy, self, border_col);
XMoveResizeWindow(state.dpy, self,
rect.0, rect.1,
rect.2, rect.3);
XMapWindow(state.dpy, self);
if self == state.active.window { XSetInputFocus(state.dpy, self, RevertToNone, CurrentTime); }
}
}
}
Expand Down

0 comments on commit 5279676

Please sign in to comment.