Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update appwindow #49

Merged
merged 4 commits into from
Jul 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ log = "0.4.19"
serde = { version = "1.0.164", features = ["derive"] }
serde_yaml = "0.9.22"
simple-logging = "2.0.2"
windows = { version = "0.48.0", features = ["Win32_Foundation", "Win32_Graphics_Dwm", "Win32_Graphics_Gdi", "Win32_Globalization", "Win32_Security", "Win32_System_Com", "Win32_System_LibraryLoader", "Win32_System_ProcessStatus", "Win32_System_Threading", "Win32_UI_Accessibility", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging" ] }
windows = { version = "0.48.0", features = ["Win32_Foundation", "Win32_Graphics_Dwm", "Win32_Graphics_Gdi", "Win32_Globalization", "Win32_Security", "Win32_System_Com", "Win32_System_LibraryLoader", "Win32_System_ProcessStatus", "Win32_System_Threading", "Win32_UI_Accessibility", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging", "Win32_UI_Controls", "Win32_System_Registry"] }

[build-dependencies]
copy_to_output = "2.1.0"
Expand Down
Binary file added resources/columns-blk.ico
Binary file not shown.
Binary file added resources/columns-wht.ico
Binary file not shown.
Binary file added resources/dwindle-blk.ico
Binary file not shown.
Binary file added resources/dwindle-wht.ico
Binary file not shown.
Binary file added resources/focus-blk.ico
Binary file not shown.
Binary file added resources/focus-wht.ico
Binary file not shown.
Binary file added resources/monocle-blk.ico
Binary file not shown.
Binary file added resources/monocle-wht.ico
Binary file not shown.
10 changes: 10 additions & 0 deletions resources/res.rc
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
appicon ICON "app.ico"

dwindle-blk ICON "dwindle-blk.ico"
monocle-blk ICON "monocle-blk.ico"
columns-blk ICON "columns-blk.ico"
focus-blk ICON "focus-blk.ico"

dwindle-wht ICON "dwindle-wht.ico"
monocle-wht ICON "monocle-wht.ico"
columns-wht ICON "columns-wht.ico"
focus-wht ICON "focus-wht.ico"
85 changes: 72 additions & 13 deletions src/appwindow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use windows::{
},
};

use grout_wm::Result;
use grout_wm::{to_wide_arr, Result, HIWORD, LOWORD};

use crate::{
win32::{
Expand All @@ -40,18 +40,6 @@ use crate::{
},
};

macro_rules! LOWORD {
($w:expr) => {
$w & 0xFFFF
};
}

macro_rules! HIWORD {
($w:expr) => {
($w >> 16) & 0xFFFF
};
}

static MY_HWND: OnceLock<HWND> = OnceLock::new();

pub struct AppWindow {
Expand Down Expand Up @@ -98,6 +86,7 @@ impl AppWindow {
return Err("Could not create window".into());
}
let _ = MY_HWND.set(hwnd);
wm.set_hwnd(hwnd);
Ok(Self {
hwnd,
cloaked_event_hook: Default::default(),
Expand Down Expand Up @@ -147,6 +136,76 @@ impl AppWindow {
})
}

pub fn set_thumb_buttons(self) -> Result<Self> {
let is_light_theme = win32::theme::is_light_theme();
let instance = get_module_handle()?;
let dw_mask = windows::Win32::UI::Shell::THB_ICON
| windows::Win32::UI::Shell::THB_TOOLTIP
| windows::Win32::UI::Shell::THB_FLAGS;
let dwindle_icon = if is_light_theme {
w!("dwindle-blk")
} else {
w!("dwindle-wht")
};
let monocle_icon = if is_light_theme {
w!("monocle-blk")
} else {
w!("monocle-wht")
};
let columns_icon = if is_light_theme {
w!("columns-blk")
} else {
w!("columns-wht")
};
let focus_icon = if is_light_theme {
w!("focus-blk")
} else {
w!("focus-wht")
};
let buttons: Vec<windows::Win32::UI::Shell::THUMBBUTTON> = vec![
windows::Win32::UI::Shell::THUMBBUTTON {
dwMask: dw_mask,
iId: 0,
hIcon: load_icon(instance, dwindle_icon).unwrap(),
dwFlags: windows::Win32::UI::Shell::THBF_DISMISSONCLICK,
szTip: to_wide_arr!("Dwindle layout"),
..Default::default()
},
windows::Win32::UI::Shell::THUMBBUTTON {
dwMask: dw_mask,
iId: 1,
hIcon: load_icon(instance, monocle_icon).unwrap(),
dwFlags: windows::Win32::UI::Shell::THBF_DISMISSONCLICK,
szTip: to_wide_arr!("Monocle layout"),
..Default::default()
},
windows::Win32::UI::Shell::THUMBBUTTON {
dwMask: dw_mask,
iId: 2,
hIcon: load_icon(instance, columns_icon).unwrap(),
dwFlags: windows::Win32::UI::Shell::THBF_DISMISSONCLICK,
szTip: to_wide_arr!("Columns layout"),
..Default::default()
},
windows::Win32::UI::Shell::THUMBBUTTON {
dwMask: dw_mask,
iId: 3,
hIcon: load_icon(instance, focus_icon).unwrap(),
dwFlags: windows::Win32::UI::Shell::THBF_DISMISSONCLICK,
szTip: to_wide_arr!("Focus layout"),
..Default::default()
},
];
let taskbarlist = win32::taskbar::TaskbarList::new()?;
taskbarlist.thumb_bar_add_buttons(self.hwnd, &buttons)?;
Ok(Self {
hwnd: self.hwnd,
cloaked_event_hook: self.cloaked_event_hook,
minimized_event_hook: self.minimized_event_hook,
movesize_event_hook: self.movesize_event_hook,
})
}

pub fn cleanup(&self) -> Self {
info!("Cleaning up handles");
unsafe {
Expand Down
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{
path::Path,
};

#[derive(Deserialize, Serialize)]
#[derive(Clone, Deserialize, Serialize)]
pub struct Config {
#[serde(rename = "Windows.UI.Core.CoreWindow")]
pub windows_ui_core_corewindow: Option<Vec<String>>,
Expand Down
12 changes: 6 additions & 6 deletions src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,20 +120,20 @@ fn focus(bounds: RECT, n: usize) -> Vec<RECT> {
.collect()
}

pub enum Layouts {
pub enum Layout {
Dwindle,
Monocle,
Columns,
Focus,
}

impl Layouts {
impl Layout {
pub fn arrange(&self, bounds: RECT, n: usize) -> Vec<RECT> {
match self {
Layouts::Dwindle => dwindle(bounds, n),
Layouts::Monocle => monocle(bounds, n),
Layouts::Columns => columns(bounds, n),
Layouts::Focus => focus(bounds, n),
Layout::Dwindle => dwindle(bounds, n),
Layout::Monocle => monocle(bounds, n),
Layout::Columns => columns(bounds, n),
Layout::Focus => focus(bounds, n),
}
}
}
26 changes: 26 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,32 @@ macro_rules! has_flag {
};
}

#[macro_export]
macro_rules! LOWORD {
($w:expr) => {
$w & 0xFFFF
};
}

#[macro_export]
macro_rules! HIWORD {
($w:expr) => {
($w >> 16) & 0xFFFF
};
}

#[macro_export]
macro_rules! to_wide_arr {
($input:expr) => {{
let mut result: [u16; 260] = [0; 260];
let chars = $input.chars().take(260);
for (i, ch) in chars.enumerate() {
result[i] = ch as u16;
}
result
}};
}

pub struct Error {
pub(crate) message: String,
}
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ fn main() -> Result<()> {
let _appwindow = AppWindow::new_window(wm)?
.show_window()?
.register_hooks()?
.set_thumb_buttons()?
.handle_messages()?
.cleanup();
info!("quitting");
Expand Down
2 changes: 2 additions & 0 deletions src/win32/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ use grout_wm::Result;

pub(crate) mod com;
pub(crate) mod dwm;
pub(crate) mod taskbar;
pub(crate) mod theme;
pub(crate) mod virtualdesktop;

pub fn is_iconic(hwnd: HWND) -> bool {
Expand Down
26 changes: 26 additions & 0 deletions src/win32/taskbar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use log::info;
use windows::Win32::{
Foundation::HWND,
UI::Shell::{ITaskbarList3, TaskbarList as TaskbarList_ID, THUMBBUTTON},
};

use grout_wm::Result;

pub struct TaskbarList(ITaskbarList3);

impl TaskbarList {
pub fn new() -> Result<Self> {
use windows::Win32::System::Com::{CoCreateInstance, CLSCTX_ALL};
info!("Instantiate TaskbarList");
let taskbarlist = unsafe { CoCreateInstance(&TaskbarList_ID, None, CLSCTX_ALL)? };
Ok(Self(taskbarlist))
}

pub fn thumb_bar_add_buttons(
&self,
hwnd: HWND,
pbutton: &[THUMBBUTTON],
) -> windows::core::Result<()> {
unsafe { self.0.ThumbBarAddButtons(hwnd, pbutton) }
}
}
28 changes: 28 additions & 0 deletions src/win32/theme.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use windows::{
w,
Win32::{
Foundation::{ERROR_FILE_NOT_FOUND, ERROR_SUCCESS},
System::Registry::{RegGetValueW, HKEY_CURRENT_USER, REG_VALUE_TYPE, RRF_RT_REG_DWORD},
},
};

pub fn is_light_theme() -> bool {
let mut buffer: [u8; 4] = [0; 4];
let mut size: u32 = (buffer.len()).try_into().unwrap();
let mut kind: REG_VALUE_TYPE = Default::default();
let res = unsafe {
RegGetValueW(
HKEY_CURRENT_USER,
w!("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"),
w!("AppsUseLightTheme"),
RRF_RT_REG_DWORD,
Some(&mut kind),
Some(buffer.as_mut_ptr() as *mut _),
Some(&mut size),
)
};
if res != ERROR_SUCCESS && res == ERROR_FILE_NOT_FOUND {
return true;
}
i32::from_le_bytes(buffer) == 1
}
Loading