Skip to content
Draft
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
15 changes: 11 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ license = "GPL-3.0"
readme = "README.md"

[features]
default = ["hack"]
default = []
"hack" = []

[dependencies]
log = "0.4.20"
pretty_env_logger = "0.5.0"
eyre = "0.6"
thiserror = "1.0"

Expand All @@ -23,7 +25,7 @@ dirs = "5.0.1"
clap = { version = "4.4.6", features = ["derive"] }

gtk = "0.18"
gdk = "0.18"
gdk = { version = "0.18" , features = ["v3_24"]}
glib = "0.18"
pango = { version = "0.18", features = ["v1_50"] }

Expand All @@ -32,8 +34,13 @@ pango = { version = "0.18", features = ["v1_50"] }
zoha-vte = { version = "0.5.0", features = ["v0_50"] }
zoha-vte-sys = { version = "0.5.0", features = ["v0_50"] }
x11rb = "0.12.0"

[target.'cfg(target_os = "macos")'.dependencies]
libc = "0.2"
cacao = "0.3.2"

[target.'cfg(target_os = "linux")'.dependencies]
device_query = "1.1.3"
dbus = "0.9.7"
dbus-crossroads = "0.5.2"
log = "0.4.20"
pretty_env_logger = "0.5.0"

6 changes: 2 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
.DEFAULT_GOAL = r

# RUST_FLAGS := 'RUSTFLAGS=-Awarnings'
RUST_FLAGS := ''

export
# RUSTFLAGS := -Awarnings
# export

.PHONY: c
c:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,4 @@ zoha --dry-run
# OR
zoha --dry-run -k
```
atk pango gtk+3 vte3
6 changes: 6 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() {
if cfg!(target_os = "macos") {
println!("cargo:rustc-link-lib=framework=Carbon");
println!("cargo:rustc-link-lib=framework=AppKit");
}
}
12 changes: 9 additions & 3 deletions src/config/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@ pub struct ZohaArgs {

/// Disable listening on dbus for keypress.
#[arg(short, long, default_value_t = false)]
#[cfg(feature = "hack")]
#[cfg(all(feature = "hack"))]
pub keypress_grabber: bool,

/// List keys accepted by keypress grabber.
#[arg(long, default_value_t = false)]
#[cfg(feature = "hack")]
#[cfg(all(feature = "hack"))]
pub list_key_grabber_keys: bool,

/// Enable native key listener.
#[arg(short, long, default_value_t = true)]
#[cfg(all(target_os = "macos"))]
pub listener: bool,

/// Signal Zoha to toggle visibility and exit.
#[arg(short, long, default_value_t = false)]
pub signal: bool,
Expand All @@ -40,4 +45,5 @@ pub struct ZohaArgs {
/// Print color pallets
#[arg(long, default_value_t = false)]
pub print_pallets: bool,
}
}

2 changes: 2 additions & 0 deletions src/config/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,7 @@ mod defaults {
pub(super) const TAB_NUM_CHARS: i8 = 25;
// pub(super) const PROMPT_ON_EXIT: bool = false;

#[cfg(feature = "hack")]
pub(super) const TOGGLE_KEYCODE: &str = "F1";

pub(super) const ACTION_TAB_ADD: &str = "<Ctrl><Shift>t";
Expand All @@ -737,6 +738,7 @@ mod defaults {
pub(super) const ACTION_FONT_SIZE_DEC: &str = "<Ctrl><Alt>minus";
pub(super) const ACTION_FONT_SIZE_RESET: &str = "<Ctrl><Alt>0";

#[cfg(feature = "hack")]
pub(super) fn default_key_codes() -> Vec<String> {
return TOGGLE_KEYCODE.split('+').map(|it| it.to_string()).collect();
}
Expand Down
76 changes: 58 additions & 18 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,40 @@
#![allow(clippy::needless_return)]
#[cfg(all(feature = "hack", not(target_os = "linux")))]
compile_error!("feature 'hack' can oly be enabled on linux");

use std::cell::RefCell;
use std::collections::HashMap;
use std::fmt::Debug;
use std::fmt::Formatter;
use std::rc::Rc;
use std::sync::Arc;
use cacao::foundation::id;
use cacao::objc::{class, msg_send, sel, sel_impl};

use dbus::blocking::Connection;
use dbus::channel::Sender;
use dbus::Message;
use eyre::ContextCompat;
use eyre::eyre;
use gdk::Display;
use gdk::prelude::MonitorExt;
use gtk::AccelGroup;
use gtk::Application;
use gtk::ApplicationWindow;
#[cfg(target_os = "linux")]
use gtk::gio::DBusSignalFlags;
use gtk::Notebook;
#[cfg(target_os = "linux")]
use gtk::prelude::ApplicationExt;
use gtk::prelude::ContainerExt;
use gtk::prelude::GtkWindowExt;
use gtk::prelude::NotebookExt;
use gtk::prelude::WidgetExt;
use log::{debug, trace};

#[cfg(target_os = "linux")]
use dbus::blocking::Connection;
#[cfg(target_os = "linux")]
use dbus::channel::Sender;
#[cfg(target_os = "linux")]
use dbus::Message;

use crate::config::cfg::ZohaCfg;
use crate::config::color::Pallet;
use crate::ui::actions::set_app_actions;
Expand All @@ -42,21 +52,24 @@ pub mod ui;
pub mod hack;


#[cfg(target_os = "linux")]
pub const DBUS_INTERFACE: &str = "io.koosha.zoha";
#[cfg(target_os = "linux")]
pub const DBUS_MEMBER: &str = "zoha";
#[cfg(target_os = "linux")]
pub const DBUS_PATH: &str = "/io/koosha/zoha";

struct TabCounter(usize);

pub struct ZohaCtx {
pub cfg: Rc<ZohaCfg>,
pub cfg: Arc<ZohaCfg>,
pub font_scale: f64,
pub fullscreen: bool,
pub accel_group: AccelGroup,
pub showing: bool,
pub terminals: Rc<RefCell<HashMap<u32, ZohaTerminal>>>,
pub terminals: Arc<RefCell<HashMap<u32, ZohaTerminal>>>,
pub transparency_enabled: bool,
tab_counter: Rc<RefCell<TabCounter>>,
tab_counter: Arc<RefCell<TabCounter>>,
window: Option<ApplicationWindow>,
notebook: Option<Notebook>,
}
Expand All @@ -79,19 +92,19 @@ impl Debug for ZohaCtx {
}

impl ZohaCtx {
pub fn new(cfg: Rc<ZohaCfg>) -> Self {
pub fn new(cfg: Arc<ZohaCfg>) -> Self {
let fullscreen = cfg.display.fullscreen;
return Self {
cfg,
font_scale: 1.0,
fullscreen,
accel_group: AccelGroup::new(),
showing: true,
terminals: Rc::new(RefCell::new(HashMap::new())),
terminals: Arc::new(RefCell::new(HashMap::new())),
transparency_enabled: true,
window: None,
notebook: None,
tab_counter: Rc::new(RefCell::new(TabCounter(1))),
tab_counter: Arc::new(RefCell::new(TabCounter(1))),
};
}

Expand Down Expand Up @@ -155,11 +168,11 @@ impl ZohaCtx {
}


pub fn on_app_activate(ctx: &Rc<RefCell<ZohaCtx>>,
pub fn on_app_activate(ctx: &Arc<RefCell<ZohaCtx>>,
app: &Application) -> eyre::Result<()> {
let window: ApplicationWindow = create_window(&ctx.borrow().cfg, app).build();

// let ctx_on_focus = Rc::clone(ctx);
// let ctx_on_focus = Arc::clone(ctx);
// window.connect_activate_focus(move |_| {
// match ctx_on_focus.borrow().get_notebook() {
// None => eprintln!("missing notebook on window activate"),
Expand Down Expand Up @@ -194,7 +207,7 @@ pub fn on_app_activate(ctx: &Rc<RefCell<ZohaCtx>>,

add_tab(ctx, !ctx.borrow().cfg.display.start_hidden);

let reorder_ctx = Rc::clone(ctx);
let reorder_ctx = Arc::clone(ctx);
ctx.borrow().get_notebook().unwrap().connect_page_reordered(move |_, child, index| {
on_page_reorder(&reorder_ctx, child, index);
});
Expand All @@ -211,10 +224,11 @@ pub fn on_app_activate(ctx: &Rc<RefCell<ZohaCtx>>,
return Ok(());
}

pub fn connect_gdk_dbus(ctx: &Rc<RefCell<ZohaCtx>>,
#[cfg(target_os = "linux")]
pub fn connect_gdk_dbus(ctx: &Arc<RefCell<ZohaCtx>>,
app: &Application) {
let app: Application = app.clone();
let ctx = Rc::clone(ctx);
let ctx = Arc::clone(ctx);
app.dbus_connection()
.expect("could not get a dbus connection")
.signal_subscribe(
Expand All @@ -230,7 +244,7 @@ pub fn connect_gdk_dbus(ctx: &Rc<RefCell<ZohaCtx>>,
);
}

pub fn toggle(ctx: &Rc<RefCell<ZohaCtx>>) {
pub fn toggle(ctx: &Arc<RefCell<ZohaCtx>>) {
let mut ctx = ctx.borrow_mut();

let window: &ApplicationWindow = ctx
Expand All @@ -244,9 +258,11 @@ pub fn toggle(ctx: &Rc<RefCell<ZohaCtx>>) {
window.show_all();
window.present();
ctx.showing = true;
unsafe { macos_screens(); }
}
}

#[cfg(target_os = "linux")]
pub fn send_toggle_signal_through_dbus() -> eyre::Result<()> {
debug!("sending dbus signal");
let conn: Connection = Connection::new_session()?;
Expand All @@ -257,8 +273,10 @@ pub fn send_toggle_signal_through_dbus() -> eyre::Result<()> {
}
Err(_) => Err(eyre!("failed to send dbus signal")),
};
return Ok(());
}

#[cfg(target_os = "linux")]
pub(crate) fn new_signal() -> Message {
let signal = Message::new_signal(
DBUS_PATH,
Expand Down Expand Up @@ -287,7 +305,7 @@ pub fn list_monitors() -> eyre::Result<Vec<String>> {
return Ok(monitors);
}

#[cfg(feature = "hack")]
#[cfg(all(feature = "hack"))]
pub fn list_keycodes() -> Vec<&'static str> {
return vec![
"Key0",
Expand Down Expand Up @@ -588,4 +606,26 @@ pub fn print_pallets() {
println!("[13] = {}", pallet.colors()[13]);
println!("[14] = {}", pallet.colors()[14]);
}
}
}

pub unsafe fn macos_screens() {
// NSWindowCollectionBehaviorCanJoinAllSpaces and friends
let mask = 1 | (1 << 6) | (1 << 8);

let shared: id = msg_send![class!(NSApplication), sharedApplication];
println!("shared {:?}", shared);

let windows: id = msg_send![shared, windows];
println!("windows {:?}", windows);

let window: id = msg_send![windows, firstObject];
println!("first {:?}", window);

if !window.is_null() {
let _: () = msg_send![window, setCollectionBehavior:mask];
}
else {
eprintln!("no window")
}
}

Loading