hide dock when mouse not hovered on transparent dock window

This commit is contained in:
Ashley Wulber 2021-12-14 16:36:28 -05:00 committed by Jeremy Soller
parent 40b89dffca
commit 5927e29fc6
5 changed files with 85 additions and 16 deletions

View file

@ -6,6 +6,7 @@ use gio::DesktopAppInfo;
use gtk::Application; use gtk::Application;
use gtk4 as gtk; use gtk4 as gtk;
use gtk4::CssProvider; use gtk4::CssProvider;
use gtk4::Revealer;
use gtk4::StyleContext; use gtk4::StyleContext;
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
@ -98,14 +99,12 @@ fn main() {
std::process::exit(1); std::process::exit(1);
}; };
let (conn, screen_num) = x11rb::connect(None).expect("Failed to connect to X"); let (conn, _screen_num) = x11rb::connect(None).expect("Failed to connect to X");
if X11_CONN.set(conn).is_err() { if X11_CONN.set(conn).is_err() {
println!("failed to set X11_CONN. Exiting"); println!("failed to set X11_CONN. Exiting");
std::process::exit(1); std::process::exit(1);
}; };
let window = Window::new(app); let window = Window::new(app);
let wclone = window.clone();
window.show(); window.show();
glib::MainContext::default().spawn_local(async move { glib::MainContext::default().spawn_local(async move {
@ -138,7 +137,7 @@ fn main() {
DesktopAppInfo::new(&path.file_name().expect("desktop entry path needs to be a valid filename").to_string_lossy()) DesktopAppInfo::new(&path.file_name().expect("desktop entry path needs to be a valid filename").to_string_lossy())
.expect("failed to create a Desktop App info for launching the application."); .expect("failed to create a Desktop App info for launching the application.");
app_info app_info
.launch(&[], Some(&wclone.display().app_launch_context().clone())).expect("failed to launch the application."); .launch(&[], Some(&window.display().app_launch_context())).expect("failed to launch the application.");
} }
} }
} }

View file

@ -9,6 +9,5 @@ listview {
background: #333333; background: #333333;
} }
window { window {
background: #333333; background: rgba(50,50,50,0.0);
border-radius: 15px;
} }

View file

@ -1,4 +1,7 @@
use gtk4 as gtk; use gtk4 as gtk;
use gtk4::EventController;
use gtk4::EventControllerMotion;
use gtk4::Revealer;
use glib::subclass::InitializingObject; use glib::subclass::InitializingObject;
use gtk::prelude::*; use gtk::prelude::*;
@ -11,9 +14,12 @@ use once_cell::sync::OnceCell;
#[derive(CompositeTemplate, Default)] #[derive(CompositeTemplate, Default)]
#[template(file = "window.ui")] #[template(file = "window.ui")]
pub struct Window { pub struct Window {
// #[template_child]
// pub list_view: TemplateChild<ListView>,
#[template_child] #[template_child]
pub list_view: TemplateChild<ListView>, pub revealer: TemplateChild<Revealer>,
pub model: OnceCell<gio::ListStore>, pub model: OnceCell<gio::ListStore>,
pub event_controller: OnceCell<EventControllerMotion>,
} }
// The central trait for subclassing a GObject // The central trait for subclassing a GObject
@ -39,6 +45,7 @@ impl ObjectImpl for Window {
self.parent_constructed(obj); self.parent_constructed(obj);
// Setup // Setup
obj.setup_event_controller();
obj.setup_model(); obj.setup_model();
obj.setup_callbacks(); obj.setup_callbacks();
obj.setup_factory(); obj.setup_factory();

View file

@ -7,6 +7,7 @@ use gdk4::Surface;
use gdk4_x11::X11Surface; use gdk4_x11::X11Surface;
use gtk4 as gtk; use gtk4 as gtk;
use gtk4::Allocation; use gtk4::Allocation;
use gtk4::EventControllerMotion;
use postage::prelude::Sink; use postage::prelude::Sink;
use x11rb::connection::Connection; use x11rb::connection::Connection;
use x11rb::protocol::xproto::ConnectionExt; use x11rb::protocol::xproto::ConnectionExt;
@ -62,8 +63,15 @@ impl Window {
// Get state // Get state
let imp = imp::Window::from_instance(self); let imp = imp::Window::from_instance(self);
let window = self.clone().upcast::<gtk::Window>(); let window = self.clone().upcast::<gtk::Window>();
let list_view = &imp.list_view; // let list_view = &imp.list_view;
let lv = list_view.get(); // let lv = list_view.get();
// let revealer = Revealer::builder()
// .child(&window)
// .reveal_child(false)
// .transition_duration(200)
// .transition_type(gtk4::RevealerTransitionType::SlideUp)
// .build();
// let app_selection_model = list_view // let app_selection_model = list_view
// .model() // .model()
@ -91,6 +99,16 @@ impl Window {
// } // }
// })); // }));
let event_controller = &imp.event_controller.get().unwrap();
let revealer = &imp.revealer.get();
window.connect_show(
glib::clone!(@weak revealer, @weak event_controller => move |_| {
dbg!(!event_controller.contains_pointer());
if !event_controller.contains_pointer() {
revealer.set_reveal_child(false);
}
}),
);
window.connect_realize(move |window| { window.connect_realize(move |window| {
if let Some((display, surface)) = x::get_window_x11(window) { if let Some((display, surface)) = x::get_window_x11(window) {
unsafe { unsafe {
@ -143,10 +161,34 @@ impl Window {
s.connect_height_notify(surface_resize_handler.clone()); s.connect_height_notify(surface_resize_handler.clone());
s.connect_width_notify(surface_resize_handler.clone()); s.connect_width_notify(surface_resize_handler.clone());
s.connect_scale_factor_notify(surface_resize_handler); s.connect_scale_factor_notify(surface_resize_handler);
// s.connect_enter_monitor(glib::clone!(@weak rv => move |s, monitor| {
// monitor.connect_connector_notify
// }));
} else { } else {
println!("failed to get X11 window"); println!("failed to get X11 window");
} }
}); });
event_controller.connect_enter(glib::clone!(@weak revealer => move |_evc, _x, _y| {
dbg!("hello, mouse entered me :)");
revealer.set_reveal_child(true);
}));
event_controller.connect_leave(glib::clone!(@weak revealer => move |_evc| {
dbg!("hello, mouse left me :)");
revealer.set_reveal_child(false);
}));
}
fn setup_event_controller(&self) {
let imp = imp::Window::from_instance(self);
let window = &imp.revealer.get();
let ev = EventControllerMotion::builder()
.propagation_limit(gtk4::PropagationLimit::None)
.propagation_phase(gtk4::PropagationPhase::Capture)
.build();
window.add_controller(&ev);
imp.event_controller
.set(ev)
.expect("Could not set event controller");
} }
fn setup_factory(&self) { fn setup_factory(&self) {
@ -174,6 +216,6 @@ impl Window {
// }); // });
// Set the factory of the list view // Set the factory of the list view
let imp = imp::Window::from_instance(self); let imp = imp::Window::from_instance(self);
imp.list_view.set_factory(Some(&factory)); // imp.list_view.set_factory(Some(&factory));
} }
} }

View file

@ -7,12 +7,34 @@
<property name="decorated">false</property> <property name="decorated">false</property>
<property name="resizable">false</property> <property name="resizable">false</property>
<child> <child>
<object class="GtkListView" id="list_view"> <object class="GtkRevealer" id="revealer">
<property name="orientation">horizontal</property> <property name="hexpand">true</property>
<property name="margin-top">4</property> <property name="vexpand">true</property>
<property name="margin-bottom">4</property> <property name="reveal-child">true</property>
<property name="margin-start">4</property> <property name="transition-duration">200</property>
<property name="margin-end">4</property> <property name="transition-type">swing-up</property>
<!--
<child>
<object class="GtkListView" id="list_view">
<property name="orientation">horizontal</property>
<property name="hexpand">true</property>
<property name="margin-top">4</property>
<property name="margin-bottom">4</property>
<property name="margin-start">4</property>
<property name="margin-end">4</property>
</object>
</child>
-->
<child>
<object class="GtkLabel">
<property name="width-request">256</property>
<property name="height-request">64</property>
<property name="label">hello world</property>
<property name="hexpand">true</property>
<property name="margin-start">4</property>
<property name="margin-end">4</property>
</object>
</child>
</object> </object>
</child> </child>
</template> </template>