Commit iniziale, funzionano delle cose

This commit is contained in:
2020-03-13 13:08:30 +01:00
commit 90fecb55c2
8 changed files with 778 additions and 0 deletions
+106
View File
@@ -0,0 +1,106 @@
extern crate gio;
extern crate gtk;
extern crate vte;
use gio::prelude::*;
use gtk::prelude::*;
use vte::TerminalExt;
use gtk::SettingsExt;
use std::env::args;
use std::sync::{Arc, RwLock};
use std::thread;
use glib::translate::{ToGlibPtr, ToGlib};
mod menu;
mod stato_finestra;
mod wake_listener;
fn build_ui(application: &gtk::Application) {
let window = gtk::ApplicationWindow::new(application);
if let Some(settings) = window.get_settings() {
settings.set_property_gtk_enable_animations(false);
}
window.set_title("First GTK+ Program");
window.set_border_width(0);
window.move_(0, 0);
window.set_default_size(1920, 500);
window.set_decorated(false);
window.set_can_focus(true);
window.set_keep_above(true);
//gtk::Window::set_interactive_debugging(true);
let vte = vte::Terminal::new();
let accel_group = gtk::AccelGroup::new();
let (key,modifier) = gtk::accelerator_parse("<Control><Shift>c");
vte.add_accelerator("copy-clipboard", &accel_group, key, modifier, gtk::AccelFlags::VISIBLE);
window.add_accel_group(&accel_group);
let font = pango::FontDescription::from_string("Iosevka Regular 13");
vte.set_font(Some(&font));
let c = gio::Cancellable::get_current();
let pid = vte
.spawn_sync(
vte::PtyFlags::DEFAULT,
None,
&[&std::path::PathBuf::from("/usr/bin/fish")],
&[],
glib::SpawnFlags::DEFAULT,
Some(&mut || {}),
c.as_ref(),
)
.unwrap();
vte.watch_child(pid);
let button = gtk::Button::new_with_label("Click me!");
button.connect_clicked(|_asd| {
println!("ciao");
});
window.add(&vte);
window.set_skip_taskbar_hint(true);
window.set_skip_pager_hint(true);
window.show_all();
unsafe {
gdk_sys::gdk_window_set_skip_pager_hint(window.get_window().unwrap().to_glib_none().0, true.to_glib());
gdk_sys::gdk_window_set_skip_taskbar_hint(window.get_window().unwrap().to_glib_none().0, true.to_glib());
}
let stato = Arc::new(RwLock::new(stato_finestra::StatoFinestra::Su));
let stato1 = stato.clone();
let stato2 = stato.clone();
let cloned_app = application.clone();
vte.connect_child_exited(move |_a, status| {
println!("Child exited with status {}", status);
cloned_app.quit();
});
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));
vte.connect_popup_menu(move |ref vte| menu::menu(vte, None));
vte.connect_button_press_event(move |ref vte, ev| {
if ev.get_event_type() == gdk::EventType::ButtonPress &&
ev.get_button() == gdk_sys::GDK_BUTTON_SECONDARY as u32 {
menu::menu(vte, Some(ev.get_button()));
}
gtk::Inhibit(false)
});
let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
rx.attach(None, move |_cmd| {
stato_finestra::esegui_toggle(&window, &vte, &stato)
});
thread::spawn(move || {
wake_listener::listener(&tx);
});
}
fn main() {
let application =
gtk::Application::new(Some("net.ddns.chiocciolo.waydrop"), Default::default())
.expect("Initialization failed...");
application.connect_activate(|app| {
build_ui(app);
});
application.run(&args().collect::<Vec<_>>());
}
+33
View File
@@ -0,0 +1,33 @@
use gdk::Atom;
use gtk::prelude::*;
use gtk::{Menu, MenuItemBuilder};
use vte::TerminalExt;
pub fn menu(widget: &vte::Terminal, btn: Option<u32>) -> bool {
let clipboard = widget.get_clipboard(&Atom::intern("CLIPBOARD"));
let w1 = widget.clone();
let w2 = widget.clone();
let w3 = widget.clone();
clipboard.request_text(move |_clipboard, maybe_str| {
let ctx_menu = Menu::new();
let cpy = MenuItemBuilder::new()
.label("Copy")
.sensitive(w3.get_has_selection())
.parent(&ctx_menu)
.build();
let paste = MenuItemBuilder::new()
.label("Paste")
.sensitive(maybe_str.is_some() && maybe_str != Some(""))
.parent(&ctx_menu)
.build();
cpy.connect_activate(move |_m| {
w1.copy_clipboard();
});
paste.connect_activate(move |_m| {
w2.paste_clipboard();
});
ctx_menu.show_all();
ctx_menu.set_property_attach_widget(Some(&w3));
ctx_menu.popup_easy(btn.unwrap_or(1), gtk::get_current_event_time());
});
true
}
+73
View File
@@ -0,0 +1,73 @@
#[derive(Eq, PartialEq, Debug)]
pub enum StatoFinestra {
Su,
TirandoSu,
Nascondendo,
Nascosta,
SuNonFocusata,
}
use gdk::WindowExt;
use gtk::prelude::*;
use std::sync::{Arc, RwLock};
pub fn esegui_toggle(
window: &gtk::ApplicationWindow,
vte: &impl glib::IsA<gtk::Widget>,
stato: &Arc<RwLock<StatoFinestra>>,
) -> glib::source::Continue {
let ts = gtk::get_current_event_time();
if let Ok(mut inner) = stato.write() {
match *inner {
StatoFinestra::Nascosta | StatoFinestra::Nascondendo => {
// Shameless copy from guake
*inner = StatoFinestra::TirandoSu;
window.present();
window.deiconify();
window.show();
window.get_window().unwrap().focus(ts);
window.set_type_hint(gdk::WindowTypeHint::Dock);
window.set_type_hint(gdk::WindowTypeHint::Normal);
window.get_window().unwrap().focus(0);
window.set_focus(Some(vte));
}
StatoFinestra::SuNonFocusata => {
window.hide();
window.show();
window.get_window().unwrap().focus(ts);
window.get_window().unwrap().focus(0);
window.set_focus(Some(vte));
*inner = StatoFinestra::Su;
}
StatoFinestra::Su => {
*inner = StatoFinestra::Nascondendo;
window.hide();
}
_ => {}
}
} else {
eprintln!("Can't acquire lock!");
}
println!("Stato: {:?}", stato);
glib::Continue(true)
}
pub fn focus_out(stato: &Arc<RwLock<StatoFinestra>>) -> gtk::Inhibit {
if let Ok(mut inner) = stato.write() {
if *inner == StatoFinestra::Nascondendo {
*inner = StatoFinestra::Nascosta;
} else {
*inner = StatoFinestra::SuNonFocusata;
//widget.unstick();
}
}
println!("Stato: {:?}", stato);
gtk::Inhibit(false)
}
pub fn focus_in(stato: &Arc<RwLock<StatoFinestra>>) -> gtk::Inhibit {
if let Ok(mut inner) = stato.write() {
*inner = StatoFinestra::Su;
}
println!("Stato: {:?}", stato);
gtk::Inhibit(false)
}
+7
View File
@@ -0,0 +1,7 @@
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(())
}
+24
View File
@@ -0,0 +1,24 @@
use glib::Sender;
use gtk::get_current_event_time;
pub fn listener(tx: &Sender<u32>) {
use std::io::Read;
use std::os::unix::net::UnixListener;
let _a = std::fs::remove_file("/tmp/waydrop.sock");
let sock = UnixListener::bind("/tmp/waydrop.sock").unwrap();
for stream in sock.incoming() {
match stream {
Ok(mut stream) => {
let mut buf = [0u8];
if let Ok(_n) = stream.read_exact(&mut buf) {
let _s = String::from_utf8_lossy(&buf).into_owned();
tx.send(get_current_event_time()).expect("can't send");
}
}
Err(err) => {
eprintln!("{:?}", err);
}
}
}
}