Tante cose
parent
296985d382
commit
454f84c5ae
|
|
@ -96,6 +96,25 @@ dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dbus"
|
||||||
|
version = "0.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acd824d45fad5ff0e178fcb3c040f13780e73f63a0a6d5cde59e7894f251ab0e"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"libdbus-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dbus-macros"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "efc7077f517382c729c845ea59d2e36a9946f5e0dd837e589a287d87535a4730"
|
||||||
|
dependencies = [
|
||||||
|
"dbus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.4"
|
version = "0.3.4"
|
||||||
|
|
@ -352,6 +371,15 @@ version = "0.2.67"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
|
checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libdbus-sys"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8720f9274907052cb50313f91201597868da9d625f8dd125f2aca5bddb7e83a1"
|
||||||
|
dependencies = [
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "maybe-uninit"
|
name = "maybe-uninit"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
|
|
@ -499,10 +527,14 @@ name = "waydrop"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
|
"dbus",
|
||||||
|
"dbus-macros",
|
||||||
"gdk",
|
"gdk",
|
||||||
"gdk-sys",
|
"gdk-sys",
|
||||||
"gio",
|
"gio",
|
||||||
|
"gio-sys",
|
||||||
"glib",
|
"glib",
|
||||||
|
"glib-sys",
|
||||||
"gtk",
|
"gtk",
|
||||||
"pango",
|
"pango",
|
||||||
"vte-rs",
|
"vte-rs",
|
||||||
|
|
|
||||||
16
Cargo.toml
16
Cargo.toml
|
|
@ -7,20 +7,28 @@ edition = "2018"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
vte-rs = "*"
|
vte-rs = "^0.3"
|
||||||
vte-sys = "*"
|
vte-sys = "*"
|
||||||
gio = "*"
|
gio = "*"
|
||||||
gtk = "*"
|
gio-sys = "*"
|
||||||
|
gtk = {version = "*", features = ["v3_22"]}
|
||||||
gdk-sys="*"
|
gdk-sys="*"
|
||||||
gdk = "*"
|
gdk = "*"
|
||||||
pango = "*"
|
pango = "*"
|
||||||
crossbeam-channel="*"
|
crossbeam-channel="*"
|
||||||
glib = "*"
|
glib = "*"
|
||||||
|
glib-sys = "*"
|
||||||
|
# jsonrpc-ipc-server = "^14.0"
|
||||||
|
# jsonrpc-derive = "*"
|
||||||
|
# jsonrpc-core = "*"
|
||||||
|
# jsonrpc-core-client = "*"
|
||||||
|
dbus = "*"
|
||||||
|
dbus-macros = "*"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "waydrop"
|
name = "waydrop"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "wake"
|
name = "waydrop-toggle"
|
||||||
path = "src/wake.rs"
|
path = "src/toggle.rs"
|
||||||
143
src/main.rs
143
src/main.rs
|
|
@ -6,7 +6,6 @@ use gio::prelude::*;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
||||||
use glib::clone;
|
use glib::clone;
|
||||||
use glib::translate::{ToGlib, ToGlibPtr};
|
|
||||||
use gtk::SettingsExt;
|
use gtk::SettingsExt;
|
||||||
use std::env::args;
|
use std::env::args;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
@ -26,6 +25,10 @@ fn build_ui(application: >k::Application) {
|
||||||
window.set_title("First GTK+ Program");
|
window.set_title("First GTK+ Program");
|
||||||
window.set_border_width(0);
|
window.set_border_width(0);
|
||||||
window.move_(0, 0);
|
window.move_(0, 0);
|
||||||
|
//window.maximize();
|
||||||
|
window.set_position(gtk::WindowPosition::None);
|
||||||
|
window.set_type_hint(gdk::WindowTypeHint::Dock);
|
||||||
|
window.set_gravity(gdk::Gravity::NorthWest);
|
||||||
window.set_default_size(1920, 500);
|
window.set_default_size(1920, 500);
|
||||||
window.set_decorated(false);
|
window.set_decorated(false);
|
||||||
|
|
||||||
|
|
@ -41,19 +44,71 @@ fn build_ui(application: >k::Application) {
|
||||||
modifier,
|
modifier,
|
||||||
gtk::AccelFlags::VISIBLE,
|
gtk::AccelFlags::VISIBLE,
|
||||||
clone!(@weak window, @weak nb => @default-return true, move |accel_g, _window, _key, _modif| {
|
clone!(@weak window, @weak nb => @default-return true, move |accel_g, _window, _key, _modif| {
|
||||||
tabs::apri_tab(&window, &nb, &accel_g, true);
|
tabs::apri_tab(&window, &nb, true, None, None, None);
|
||||||
true
|
true
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
let (key, modifier) = gtk::accelerator_parse("<Control>Page_Down");
|
||||||
|
accel_group.connect_accel_group(
|
||||||
|
key,
|
||||||
|
modifier,
|
||||||
|
gtk::AccelFlags::VISIBLE,
|
||||||
|
clone!(@weak nb => @default-return true, move |_accel_g, _window, _key, _modif| {
|
||||||
|
nb.next_page();
|
||||||
|
true
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
let (key, modifier) = gtk::accelerator_parse("<Control>Page_Up");
|
||||||
|
accel_group.connect_accel_group(
|
||||||
|
key,
|
||||||
|
modifier,
|
||||||
|
gtk::AccelFlags::VISIBLE,
|
||||||
|
clone!(@weak nb => @default-return true, move |_accel_g, _window, _key, _modif| {
|
||||||
|
nb.prev_page();
|
||||||
|
true
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
let (key, modifier) = gtk::accelerator_parse("F11");
|
||||||
|
let full_screen = Arc::new(RwLock::new(false));
|
||||||
|
accel_group.connect_accel_group(
|
||||||
|
key,
|
||||||
|
modifier,
|
||||||
|
gtk::AccelFlags::VISIBLE,
|
||||||
|
clone!(@weak window => @default-return true, move |_accel_g, _win, _key, _modif| {
|
||||||
|
if let Ok(mut lock) = full_screen.write(){
|
||||||
|
if *lock {
|
||||||
|
window.unfullscreen();
|
||||||
|
} else {
|
||||||
|
window.fullscreen();
|
||||||
|
}
|
||||||
|
*lock = !*lock;
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
for i in 1..9 {
|
||||||
|
let (key, modifier) = gtk::accelerator_parse(&format!("<Alt>{}", i));
|
||||||
|
accel_group.connect_accel_group(
|
||||||
|
key,
|
||||||
|
modifier,
|
||||||
|
gtk::AccelFlags::VISIBLE,
|
||||||
|
clone!(@weak nb => @default-return true, move |_accel_g, _win, _key, _modif| {
|
||||||
|
nb.set_current_page(Some(i-1));
|
||||||
|
true
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
window.add_accel_group(&accel_group);
|
window.add_accel_group(&accel_group);
|
||||||
|
|
||||||
window.add(&nb);
|
window.add(&nb);
|
||||||
let first_tab = tabs::build_tab(&nb, &accel_group);
|
if let Ok(first_tab) = tabs::build_tab(&window, &nb, None, None) {
|
||||||
|
tabs::passa_a_tab(&window, &nb, &first_tab);
|
||||||
|
}
|
||||||
window.set_skip_taskbar_hint(true);
|
window.set_skip_taskbar_hint(true);
|
||||||
window.set_skip_pager_hint(true);
|
window.set_skip_pager_hint(true);
|
||||||
window.show_all();
|
window.show_all();
|
||||||
tabs::passa_a_tab(&window, &nb, &first_tab);
|
/*unsafe {
|
||||||
unsafe {
|
|
||||||
gdk_sys::gdk_window_set_skip_pager_hint(
|
gdk_sys::gdk_window_set_skip_pager_hint(
|
||||||
window.get_window().unwrap().to_glib_none().0,
|
window.get_window().unwrap().to_glib_none().0,
|
||||||
true.to_glib(),
|
true.to_glib(),
|
||||||
|
|
@ -62,43 +117,93 @@ fn build_ui(application: >k::Application) {
|
||||||
window.get_window().unwrap().to_glib_none().0,
|
window.get_window().unwrap().to_glib_none().0,
|
||||||
true.to_glib(),
|
true.to_glib(),
|
||||||
);
|
);
|
||||||
}
|
}*/
|
||||||
let stato = Arc::new(RwLock::new(stato_finestra::StatoFinestra::Su));
|
let stato = Arc::new(RwLock::new(stato_finestra::StatoFinestra::Su));
|
||||||
|
let stato0 = stato.clone();
|
||||||
let stato1 = stato.clone();
|
let stato1 = stato.clone();
|
||||||
let stato2 = stato.clone();
|
let stato2 = stato.clone();
|
||||||
let stato3 = stato.clone();
|
let stato3 = stato.clone();
|
||||||
let stato4 = stato.clone();
|
let stato4 = stato.clone();
|
||||||
|
|
||||||
//let cloned_app = application.clone();
|
|
||||||
|
|
||||||
window.connect_focus_out_event(move |_widget, _b| stato_finestra::focus_out(&stato1));
|
window.connect_focus_out_event(move |_widget, _b| stato_finestra::focus_out(&stato1));
|
||||||
window.connect_focus_in_event(move |_widget, _b| stato_finestra::focus_in(&stato2));
|
window.connect_focus_in_event(clone!(@weak window => @default-return gtk::Inhibit(false),
|
||||||
nb.connect_page_removed(clone!(@weak window, @weak accel_group => move |notebook, _vte, _index| {
|
move |_widget, _b| stato_finestra::focus_in(&window, &stato2)));
|
||||||
if notebook.get_n_pages() == 0 {
|
nb.connect_destroy(move |_nb| {
|
||||||
if let Ok(ref mut lock_stato) = stato.write() {
|
if let Ok(mut lock_stato) = stato.write() {
|
||||||
tabs::apri_tab(&window, ¬ebook, &accel_group, false);
|
*lock_stato = stato_finestra::StatoFinestra::Chiudendo;
|
||||||
stato_finestra::butta_giu(&window, lock_stato);
|
|
||||||
}
|
}
|
||||||
} else if notebook.get_n_pages() == 1 {
|
});
|
||||||
|
nb.connect_page_removed(
|
||||||
|
clone!(@weak window => move |notebook, _vte, _index| {
|
||||||
|
if notebook.get_n_pages() == 0 {
|
||||||
|
if let Ok(mut lock_stato) = stato0.write() {
|
||||||
|
if *lock_stato != stato_finestra::StatoFinestra::Chiudendo {
|
||||||
|
crate::tabs::apri_tab(&window, ¬ebook, false,None, None, None);
|
||||||
|
stato_finestra::butta_giu(&window, &mut lock_stato);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tabs::set_titles(¬ebook);
|
||||||
|
if notebook.get_n_pages() == 1 {
|
||||||
notebook.set_show_tabs(false);
|
notebook.set_show_tabs(false);
|
||||||
}
|
}
|
||||||
}));
|
}
|
||||||
|
dbg!();
|
||||||
|
}),
|
||||||
|
);
|
||||||
nb.connect_page_added(move |notebook, _vte, _index| {
|
nb.connect_page_added(move |notebook, _vte, _index| {
|
||||||
if notebook.get_n_pages() > 1 {
|
if notebook.get_n_pages() > 1 {
|
||||||
notebook.set_show_tabs(true);
|
notebook.set_show_tabs(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
nb.connect_page_reordered(move |notebook, _vte, _index| {
|
||||||
|
tabs::set_titles(¬ebook);
|
||||||
|
});
|
||||||
|
|
||||||
let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
||||||
if let Ok(ref mut lock_stato) = stato4.write() {
|
if let Ok(ref mut lock_stato) = stato4.write() {
|
||||||
stato_finestra::tira_su(&window, lock_stato, gtk::get_current_event_time());
|
stato_finestra::tira_su(&window, lock_stato, gtk::get_current_event_time());
|
||||||
}
|
}
|
||||||
//tabs::focus_tab_corrente(&nb);
|
//tabs::focus_tab_corrente(&nb);
|
||||||
rx.attach(None, move |_cmd| {
|
rx.attach(None, move |cmd| {
|
||||||
stato_finestra::esegui_toggle(&window, &nb, &stato3)
|
let tira_su = || {
|
||||||
|
if let Ok(ref mut lock_stato) = stato3.write() {
|
||||||
|
stato_finestra::tira_su(&window, lock_stato, gtk::get_current_event_time());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
use wake_listener::RpcCommand::*;
|
||||||
|
match cmd {
|
||||||
|
Toggle => {
|
||||||
|
stato_finestra::esegui_toggle(&window, &nb, &stato3);
|
||||||
|
}
|
||||||
|
RunShell { cwd, shell } => {
|
||||||
|
tira_su();
|
||||||
|
tabs::apri_tab(&window, &nb, true, cwd, Some(shell), None);
|
||||||
|
}
|
||||||
|
RunInDefaultShell { cwd, command } => {
|
||||||
|
tira_su();
|
||||||
|
tabs::apri_tab(&window, &nb, true, cwd, None, Some(command));
|
||||||
|
}
|
||||||
|
RunInCustomShell {
|
||||||
|
cwd,
|
||||||
|
shell,
|
||||||
|
command,
|
||||||
|
} => {
|
||||||
|
tira_su();
|
||||||
|
tabs::apri_tab(
|
||||||
|
&window,
|
||||||
|
&nb,
|
||||||
|
true,
|
||||||
|
cwd,
|
||||||
|
Some(shell),
|
||||||
|
Some(command),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glib::Continue(true)
|
||||||
});
|
});
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
wake_listener::listener(&tx);
|
wake_listener::listener(tx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,22 +5,45 @@ pub enum StatoFinestra {
|
||||||
Nascondendo,
|
Nascondendo,
|
||||||
Nascosta,
|
Nascosta,
|
||||||
SuNonFocusata,
|
SuNonFocusata,
|
||||||
|
Chiudendo,
|
||||||
}
|
}
|
||||||
use gdk::WindowExt;
|
use gdk::WindowExt;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
pub fn tira_su(window: >k::ApplicationWindow, stato: &mut StatoFinestra, ts: u32) {
|
pub fn tira_su(window: >k::ApplicationWindow, stato: &mut StatoFinestra, ts: u32) {
|
||||||
|
match *stato {
|
||||||
|
StatoFinestra::Nascosta | StatoFinestra::Nascondendo => {
|
||||||
// Shameless copy from guake
|
// Shameless copy from guake
|
||||||
|
/*window.hide();
|
||||||
window.present();
|
window.present();
|
||||||
window.deiconify();
|
window.deiconify();*/
|
||||||
window.show();
|
window.show();
|
||||||
window.get_window().unwrap().focus(ts);
|
let gdk_window = window.get_window();
|
||||||
|
if let Some(ref gdk_window) = gdk_window {
|
||||||
|
gdk_window.focus(ts);
|
||||||
|
}
|
||||||
window.set_type_hint(gdk::WindowTypeHint::Dock);
|
window.set_type_hint(gdk::WindowTypeHint::Dock);
|
||||||
window.set_type_hint(gdk::WindowTypeHint::Normal);
|
/*if let Some(ref gdk_window) = gdk_window {
|
||||||
window.get_window().unwrap().focus(0);
|
gdk_window.focus(0);
|
||||||
|
}*/
|
||||||
*stato = StatoFinestra::TirandoSu;
|
*stato = StatoFinestra::TirandoSu;
|
||||||
}
|
}
|
||||||
|
StatoFinestra::SuNonFocusata => {
|
||||||
|
window.hide();
|
||||||
|
window.show();
|
||||||
|
let gdk_window = window.get_window();
|
||||||
|
if let Some(ref gdk_window) = gdk_window {
|
||||||
|
gdk_window.focus(ts);
|
||||||
|
gdk_window.focus(0);
|
||||||
|
}
|
||||||
|
let s = calc_w_h(window);
|
||||||
|
window.get_window().map(|w| w.resize(s.0, s.1));
|
||||||
|
*stato = StatoFinestra::Su;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn butta_giu(window: >k::ApplicationWindow, stato: &mut StatoFinestra) {
|
pub fn butta_giu(window: >k::ApplicationWindow, stato: &mut StatoFinestra) {
|
||||||
*stato = StatoFinestra::Nascondendo;
|
*stato = StatoFinestra::Nascondendo;
|
||||||
|
|
@ -31,32 +54,20 @@ pub fn esegui_toggle(
|
||||||
window: >k::ApplicationWindow,
|
window: >k::ApplicationWindow,
|
||||||
nb: >k::Notebook,
|
nb: >k::Notebook,
|
||||||
stato: &Arc<RwLock<StatoFinestra>>,
|
stato: &Arc<RwLock<StatoFinestra>>,
|
||||||
) -> glib::source::Continue {
|
) {
|
||||||
let ts = gtk::get_current_event_time();
|
let ts = gtk::get_current_event_time();
|
||||||
if let Ok(mut inner) = stato.write() {
|
if let Ok(mut inner) = stato.write() {
|
||||||
match *inner {
|
match *inner {
|
||||||
StatoFinestra::Nascosta | StatoFinestra::Nascondendo => {
|
StatoFinestra::Nascosta | StatoFinestra::Nascondendo | StatoFinestra::SuNonFocusata => {
|
||||||
tira_su(window, &mut inner, ts);
|
tira_su(window, &mut inner, ts);
|
||||||
crate::tabs::focus_tab_corrente(&nb);
|
crate::tabs::focus_tab_corrente(&nb);
|
||||||
}
|
}
|
||||||
StatoFinestra::SuNonFocusata => {
|
StatoFinestra::Su => butta_giu(window, &mut inner),
|
||||||
window.hide();
|
|
||||||
window.show();
|
|
||||||
window.get_window().unwrap().focus(ts);
|
|
||||||
window.get_window().unwrap().focus(0);
|
|
||||||
crate::tabs::focus_tab_corrente(&nb);
|
|
||||||
*inner = StatoFinestra::Su;
|
|
||||||
}
|
|
||||||
StatoFinestra::Su => {
|
|
||||||
butta_giu(window, &mut inner)
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Can't acquire lock!");
|
eprintln!("Can't acquire lock!");
|
||||||
}
|
}
|
||||||
println!("Stato: {:?}", stato);
|
|
||||||
glib::Continue(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn focus_out(stato: &Arc<RwLock<StatoFinestra>>) -> gtk::Inhibit {
|
pub fn focus_out(stato: &Arc<RwLock<StatoFinestra>>) -> gtk::Inhibit {
|
||||||
|
|
@ -68,14 +79,35 @@ pub fn focus_out(stato: &Arc<RwLock<StatoFinestra>>) -> gtk::Inhibit {
|
||||||
//widget.unstick();
|
//widget.unstick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("Stato: {:?}", stato);
|
|
||||||
gtk::Inhibit(false)
|
gtk::Inhibit(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn focus_in(stato: &Arc<RwLock<StatoFinestra>>) -> gtk::Inhibit {
|
pub fn focus_in(
|
||||||
|
window: >k::ApplicationWindow,
|
||||||
|
stato: &Arc<RwLock<StatoFinestra>>,
|
||||||
|
) -> gtk::Inhibit {
|
||||||
if let Ok(mut inner) = stato.write() {
|
if let Ok(mut inner) = stato.write() {
|
||||||
*inner = StatoFinestra::Su;
|
*inner = StatoFinestra::Su;
|
||||||
}
|
}
|
||||||
println!("Stato: {:?}", stato);
|
let s = calc_w_h(window);
|
||||||
|
window.set_type_hint(gdk::WindowTypeHint::Dock);
|
||||||
|
if let Some((_x, _y, width, height)) = window.get_window().and_then(|x| Some(x.get_geometry()))
|
||||||
|
{
|
||||||
|
if height != s.1 || width != s.0 {
|
||||||
|
window.hide();
|
||||||
|
window.resize( s.0, s.1);
|
||||||
|
window.show();
|
||||||
|
window.move_(0,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
gtk::Inhibit(false)
|
gtk::Inhibit(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn calc_w_h(window: >k::ApplicationWindow) -> (i32, i32) {
|
||||||
|
window
|
||||||
|
.get_window()
|
||||||
|
.and_then(|gdk_win| gdk_win.get_display().get_monitor_at_window(&gdk_win))
|
||||||
|
.map(|mon| mon.get_geometry())
|
||||||
|
.and_then(|gdk::Rectangle { width, height, .. }| Some((width, height / 2)))
|
||||||
|
.unwrap_or((1920, 540))
|
||||||
|
}
|
||||||
|
|
|
||||||
91
src/tabs.rs
91
src/tabs.rs
|
|
@ -1,17 +1,24 @@
|
||||||
use glib::clone;
|
use glib::clone;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
use std::{env::var, path::Path};
|
||||||
use vte::TerminalExt;
|
use vte::TerminalExt;
|
||||||
|
|
||||||
pub fn build_tab(nb: >k::Notebook, w_accel_group: >k::AccelGroup) -> vte::Terminal {
|
pub fn build_tab(
|
||||||
|
window: >k::ApplicationWindow,
|
||||||
|
nb: >k::Notebook,
|
||||||
|
cwd: Option<String>,
|
||||||
|
shell: Option<Vec<String>>,
|
||||||
|
) -> Result<vte::Terminal, glib::Error> {
|
||||||
|
let new_accel_g = gtk::AccelGroup::new();
|
||||||
let l = gtk::Label::new(Some("~"));
|
let l = gtk::Label::new(Some("~"));
|
||||||
l.set_width_chars(10);
|
l.set_width_chars(14);
|
||||||
l.set_ellipsize(pango::EllipsizeMode::Start);
|
l.set_ellipsize(pango::EllipsizeMode::Middle);
|
||||||
//gtk::Window::set_interactive_debugging(true);
|
//gtk::Window::set_interactive_debugging(true);
|
||||||
let vte = vte::Terminal::new();
|
let vte = vte::Terminal::new();
|
||||||
let (key, modifier) = gtk::accelerator_parse("<Control><Shift>c");
|
let (key, modifier) = gtk::accelerator_parse("<Control><Shift>c");
|
||||||
vte.add_accelerator(
|
vte.add_accelerator(
|
||||||
"copy-clipboard",
|
"copy-clipboard",
|
||||||
w_accel_group,
|
&new_accel_g,
|
||||||
key,
|
key,
|
||||||
modifier,
|
modifier,
|
||||||
gtk::AccelFlags::VISIBLE,
|
gtk::AccelFlags::VISIBLE,
|
||||||
|
|
@ -20,22 +27,28 @@ pub fn build_tab(nb: >k::Notebook, w_accel_group: >k::AccelGroup) -> vte::Te
|
||||||
let font = pango::FontDescription::from_string("Iosevka Regular 13");
|
let font = pango::FontDescription::from_string("Iosevka Regular 13");
|
||||||
vte.set_font(Some(&font));
|
vte.set_font(Some(&font));
|
||||||
let c = gio::Cancellable::get_current();
|
let c = gio::Cancellable::get_current();
|
||||||
let pid = vte
|
let shell = shell.unwrap_or(vec![var("SHELL").unwrap_or("/bin/sh".to_string())]);
|
||||||
.spawn_sync(
|
let shell: Vec<_> = shell.iter().map(Path::new).collect();
|
||||||
|
let stringa: String;
|
||||||
|
let cwd = if cwd.is_some() {
|
||||||
|
stringa = cwd.unwrap();
|
||||||
|
Some(stringa.as_str())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let _pid = vte.spawn_sync(
|
||||||
vte::PtyFlags::DEFAULT,
|
vte::PtyFlags::DEFAULT,
|
||||||
None,
|
cwd,
|
||||||
&[&std::path::PathBuf::from("/usr/bin/fish")],
|
&shell,
|
||||||
&[],
|
&[],
|
||||||
glib::SpawnFlags::DEFAULT,
|
glib::SpawnFlags::DEFAULT,
|
||||||
Some(&mut || {}),
|
Some(&mut || {}),
|
||||||
c.as_ref(),
|
c.as_ref(),
|
||||||
)
|
)?;
|
||||||
.unwrap();
|
|
||||||
vte.watch_child(pid);
|
|
||||||
nb.append_page(&vte, Some(&l));
|
nb.append_page(&vte, Some(&l));
|
||||||
nb.set_tab_reorderable(&vte, true);
|
nb.set_tab_reorderable(&vte, true);
|
||||||
vte.connect_child_exited(clone!(@weak nb, @weak vte => move |_a, status| {
|
vte.connect_child_exited(clone!(@weak nb, @weak vte => move |a, status| {
|
||||||
println!("Child exited with status {}", status);
|
println!("Child exited with status {:?} {}", a, status);
|
||||||
let p_num = nb.page_num(&vte);
|
let p_num = nb.page_num(&vte);
|
||||||
nb.remove_page(p_num);
|
nb.remove_page(p_num);
|
||||||
}));
|
}));
|
||||||
|
|
@ -49,13 +62,10 @@ pub fn build_tab(nb: >k::Notebook, w_accel_group: >k::AccelGroup) -> vte::Te
|
||||||
gtk::Inhibit(false)
|
gtk::Inhibit(false)
|
||||||
});
|
});
|
||||||
|
|
||||||
vte.connect_window_title_changed(move |term| {
|
vte.connect_window_title_changed(clone!(@weak nb => move |term| {
|
||||||
if let Some(title) = term.get_window_title() {
|
set_title(term, &nb);
|
||||||
l.set_label(&title);
|
}));
|
||||||
} else {
|
window.add_accel_group(&new_accel_g);
|
||||||
l.set_label("");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Setto colori terminale
|
// Setto colori terminale
|
||||||
use glib::translate::ToGlibPtr;
|
use glib::translate::ToGlibPtr;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
@ -91,7 +101,32 @@ pub fn build_tab(nb: >k::Notebook, w_accel_group: >k::AccelGroup) -> vte::Te
|
||||||
unsafe_palette.len(),
|
unsafe_palette.len(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
vte
|
Ok(vte)
|
||||||
|
}
|
||||||
|
fn set_title(term: &vte::Terminal, nb: >k::Notebook) {
|
||||||
|
let tab_n = if let Some(num) = nb.page_num(term) {
|
||||||
|
format!("{}. ", num + 1)
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
};
|
||||||
|
if let Some(l) = nb.get_tab_label(term) {
|
||||||
|
if let Ok(l) = l.downcast::<gtk::Label>() {
|
||||||
|
if let Some(title) = term.get_window_title() {
|
||||||
|
l.set_label(&format!("{}{}", tab_n, title));
|
||||||
|
} else {
|
||||||
|
l.set_label(&tab_n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn set_titles(nb: >k::Notebook) {
|
||||||
|
for page_n in 0..nb.get_n_pages() {
|
||||||
|
if let Some(widget) = nb.get_nth_page(Some(page_n)) {
|
||||||
|
if let Ok(vte) = widget.downcast::<vte::Terminal>() {
|
||||||
|
set_title(&vte, nb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn passa_a_tab(win: >k::ApplicationWindow, nb: >k::Notebook, vte: &vte::Terminal) {
|
pub fn passa_a_tab(win: >k::ApplicationWindow, nb: >k::Notebook, vte: &vte::Terminal) {
|
||||||
|
|
@ -110,15 +145,25 @@ pub fn focus_tab_corrente(nb: >k::Notebook) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn inject(term: &vte::Terminal, command: String) {
|
||||||
|
term.feed_child_binary(format!("{}\n", command.trim()).as_bytes());
|
||||||
|
}
|
||||||
pub fn apri_tab(
|
pub fn apri_tab(
|
||||||
window: >k::ApplicationWindow,
|
window: >k::ApplicationWindow,
|
||||||
nb: >k::Notebook,
|
nb: >k::Notebook,
|
||||||
accel_g: >k::AccelGroup,
|
|
||||||
focus: bool,
|
focus: bool,
|
||||||
|
cwd: Option<String>,
|
||||||
|
shell: Option<Vec<String>>,
|
||||||
|
inject_command: Option<String>,
|
||||||
) {
|
) {
|
||||||
let new_tab = build_tab(&nb, accel_g);
|
let new_tab = build_tab(window, nb, cwd, shell);
|
||||||
|
if let Ok(new_tab) = new_tab {
|
||||||
window.show_all();
|
window.show_all();
|
||||||
if focus {
|
if focus {
|
||||||
crate::tabs::passa_a_tab(&window, &nb, &new_tab);
|
crate::tabs::passa_a_tab(&window, &nb, &new_tab);
|
||||||
}
|
}
|
||||||
|
if let Some(command) = inject_command {
|
||||||
|
inject(&new_tab, command);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
#![allow(deprecated)]
|
||||||
|
|
||||||
|
extern crate dbus;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate dbus_macros;
|
||||||
|
|
||||||
|
use dbus::{BusType, Connection};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
dbus_interface!("net.ddns.chiocciolo.waydrop.term", interface Term {
|
||||||
|
fn toggle() -> bool;
|
||||||
|
fn run_shell(cwd: String, shell: Vec<String>) -> bool;
|
||||||
|
fn run_in_default_shell(cwd: String, command: String) -> bool;
|
||||||
|
fn run_in_custom_shell(cwd: String , shell: Vec<String>, command: String) -> bool;
|
||||||
|
});
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let session_connection = std::rc::Rc::new(Connection::get_private(BusType::Session).unwrap());
|
||||||
|
let term = Term::new(
|
||||||
|
"net.ddns.chiocciolo.waydrop.term",
|
||||||
|
"/Term",
|
||||||
|
session_connection,
|
||||||
|
);
|
||||||
|
// let res = term.run_in_custom_shell(
|
||||||
|
// vec!["/bin/bash".to_string()],
|
||||||
|
// "/usr/bin/htop".to_string(),
|
||||||
|
// );
|
||||||
|
//let res = term.run_in_default_shell("/".to_string(), "ls".to_string());
|
||||||
|
let _ = term.toggle();
|
||||||
|
}
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
use std::os::unix::net::UnixStream;
|
|
||||||
use std::io::prelude::*;
|
|
||||||
fn main() -> std::io::Result<()>{
|
|
||||||
let mut s = UnixStream::connect("/tmp/waydrop.sock")?;
|
|
||||||
s.write_all(b"t")?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +1,49 @@
|
||||||
|
use dbus_macros::*;
|
||||||
use glib::Sender;
|
use glib::Sender;
|
||||||
|
|
||||||
pub fn listener(tx: &Sender<u32>) {
|
pub enum RpcCommand {
|
||||||
use std::io::Read;
|
Toggle,
|
||||||
use std::os::unix::net::UnixListener;
|
RunShell {
|
||||||
let _a = std::fs::remove_file("/tmp/waydrop.sock");
|
cwd: Option<String>,
|
||||||
let sock = UnixListener::bind("/tmp/waydrop.sock").unwrap();
|
shell: Vec<String>,
|
||||||
for stream in sock.incoming() {
|
},
|
||||||
match stream {
|
RunInDefaultShell {
|
||||||
Ok(mut stream) => {
|
cwd: Option<String>,
|
||||||
let mut buf = [0u8];
|
command: String,
|
||||||
if let Ok(_n) = stream.read_exact(&mut buf) {
|
},
|
||||||
let _s = String::from_utf8_lossy(&buf).into_owned();
|
RunInCustomShell {
|
||||||
tx.send(0).expect("can't send");
|
cwd: Option<String>,
|
||||||
}
|
shell: Vec<String>,
|
||||||
}
|
command: String,
|
||||||
Err(err) => {
|
},
|
||||||
eprintln!("{:?}", err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
dbus_class!("net.ddns.chiocciolo.waydrop.term", class Term (tx: Sender<RpcCommand>) {
|
||||||
|
fn toggle(&this) -> bool{
|
||||||
|
this.tx.send(RpcCommand::Toggle).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run_shell(&this, cwd: String, shell: Vec<String>) -> bool {
|
||||||
|
let cwd = if cwd != "" {Some(cwd)} else {None };
|
||||||
|
this.tx.send(RpcCommand::RunShell{cwd, shell}).is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_in_default_shell(&this, cwd: String, command: String) -> bool {
|
||||||
|
let cwd = if cwd != "" {Some(cwd)} else {None };
|
||||||
|
this.tx.send(RpcCommand::RunInDefaultShell{cwd, command}).is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_in_custom_shell(&this, cwd: String, shell: Vec<String>, command: String) -> bool {
|
||||||
|
let cwd = if cwd != "" {Some(cwd)} else {None };
|
||||||
|
this.tx.send(RpcCommand::RunInCustomShell{cwd, shell, command}).is_ok()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pub fn listener(tx: Sender<RpcCommand>) {
|
||||||
|
use dbus::{BusType, Connection};
|
||||||
|
let session_connection = Connection::get_private(BusType::Session).unwrap();
|
||||||
|
let hello = Term::new(tx);
|
||||||
|
hello.run(
|
||||||
|
"net.ddns.chiocciolo.waydrop.term",
|
||||||
|
&session_connection,
|
||||||
|
"/Term",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Waydrop
|
||||||
|
Exec=/home/pietro/Schifezze/cacca/target/release/waydrop
|
||||||
|
Icon=
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Categories=GNOME;GTK;System;Utility;TerminalEmulator;
|
||||||
|
|
||||||
Loading…
Reference in New Issue