diff --git a/examples/app_library/window/.#mod.rs b/examples/app_library/window/.#mod.rs new file mode 120000 index 00000000..46713fb8 --- /dev/null +++ b/examples/app_library/window/.#mod.rs @@ -0,0 +1 @@ +ashleywulber@pop-os.146928:1639590163 \ No newline at end of file diff --git a/examples/dock/.main.rs.swp b/examples/dock/.main.rs.swp new file mode 100644 index 00000000..74647281 Binary files /dev/null and b/examples/dock/.main.rs.swp differ diff --git a/examples/dock/dock_item/mod.rs b/examples/dock/dock_item/mod.rs index 21a347a7..35451dba 100644 --- a/examples/dock/dock_item/mod.rs +++ b/examples/dock/dock_item/mod.rs @@ -1,12 +1,10 @@ use gdk4::ContentProvider; use gdk4::Display; -use gio::File; use gio::Icon; use gio::ListStore; use gtk4 as gtk; use gtk4::DragSource; use gtk4::IconTheme; -use gtk4::TreeIter; mod imp; use gtk::glib; @@ -89,9 +87,7 @@ impl DockItem { let icon = app_info .icon() .unwrap_or(Icon::for_string("image-missing").expect("Failed to set default icon")); - drag_controller.connect_drag_begin(glib::clone!(@weak icon, => move |_self, drag| { - // drag.set_selected_action(gdk4::DragAction::MOVE); - // override formats + drag_controller.connect_drag_begin(glib::clone!(@weak icon, => move |_self, _drag| { // set drag source icon if possible... // gio Icon is not easily converted to a Paintable, but this seems to be the correct method if let Some(default_display) = &Display::default() { diff --git a/examples/dock/ipc.rs b/examples/dock/ipc.rs deleted file mode 100644 index c1ce7576..00000000 --- a/examples/dock/ipc.rs +++ /dev/null @@ -1,76 +0,0 @@ -use pop_launcher::{Request, Response}; -use std::process; -use std::io::{self, BufRead, Write}; - -pub struct LauncherIpc { - child: process::Child, - stdin: process::ChildStdin, - stdout: io::BufReader, - exited: bool, -} - -impl LauncherIpc { - pub fn new() -> io::Result { - let mut child = process::Command::new("pop-launcher") - .stdin(process::Stdio::piped()) - .stdout(process::Stdio::piped()) - .spawn()?; - - let stdin = child.stdin.take().ok_or( - io::Error::new(io::ErrorKind::Other, "failed to find child stdin") - )?; - - let stdout = io::BufReader::new(child.stdout.take().ok_or( - io::Error::new(io::ErrorKind::Other, "failed to find child stdout") - )?); - - Ok(Self { - child, - stdin, - stdout, - exited: false, - }) - } - - fn send_request(&mut self, request: Request) -> io::Result<()> { - let mut request_json = serde_json::to_string(&request).map_err(|err| { - io::Error::new(io::ErrorKind::InvalidInput, err) - })?; - request_json.push('\n'); - self.stdin.write_all(request_json.as_bytes()) - } - - fn recv_response(&mut self) -> io::Result { - let mut response_json = String::new(); - self.stdout.read_line(&mut response_json)?; - serde_json::from_str(&response_json).map_err(|err| { - io::Error::new(io::ErrorKind::InvalidData, err) - }) - } - - pub fn request(&mut self, request: Request) -> io::Result { - self.send_request(request)?; - self.recv_response() - } - - //TODO: better exit implementation - pub fn exit(&mut self) -> io::Result> { - if ! self.exited { - self.send_request(Request::Exit)?; - let status = self.child.wait()?; - self.exited = true; - Ok(Some(status)) - } else { - Ok(None) - } - } -} - -impl Drop for LauncherIpc { - fn drop(&mut self) { - match self.exit() { - Ok(_) => (), - Err(err) => eprintln!("LauncherIpc::drop failed: {}", err), - } - } -} diff --git a/examples/dock/main.rs b/examples/dock/main.rs index 08124acc..46f6b18a 100644 --- a/examples/dock/main.rs +++ b/examples/dock/main.rs @@ -8,7 +8,6 @@ use gio::DesktopAppInfo; use gtk::Application; use gtk4 as gtk; use gtk4::CssProvider; -use gtk4::Revealer; use gtk4::StyleContext; use once_cell::sync::OnceCell; @@ -27,20 +26,6 @@ const NUM_LAUNCHER_ITEMS: u8 = 10; static TX: OnceCell> = OnceCell::new(); static X11_CONN: OnceCell = OnceCell::new(); -fn icon_source(icon: >k::Image, source: &Option) { - match source { - Some(pop_launcher::IconSource::Name(name)) => { - icon.set_from_icon_name(Some(name)); - } - Some(pop_launcher::IconSource::Mime(content_type)) => { - icon.set_from_gicon(&gio::content_type_get_icon(content_type)); - } - _ => { - icon.set_from_icon_name(None); - } - } -} - pub enum Event { Response(pop_launcher::Response), Search(String), diff --git a/examples/dock/utils.rs b/examples/dock/utils.rs index 3f03b5b5..8b137891 100644 --- a/examples/dock/utils.rs +++ b/examples/dock/utils.rs @@ -1,42 +1 @@ -use gdk4::ContentProvider; -use gdk4::Display; -use gio::File; -use gio::Icon; -use gtk4 as gtk; -use gtk4::DragSource; -use gtk4::IconTheme; -use gtk::glib; -use gtk::prelude::*; - -pub fn init_drag_controller(drag_controller: &DragSource, app_info: &gio::DesktopAppInfo) { - if let Some(file) = app_info.filename() { - let file = File::for_path(file); - let provider = ContentProvider::for_value(&file.to_value()); - drag_controller.set_content(Some(&provider)); - } - drag_controller.connect_drag_end(move |_self, _drag, delete_data| { - dbg!("removing", delete_data); - }); - let icon = app_info - .icon() - .unwrap_or(Icon::for_string("image-missing").expect("Failed to set default icon")); - drag_controller.connect_drag_begin(glib::clone!(@weak icon, => move |_self, drag| { - drag.set_selected_action(gdk4::DragAction::MOVE); - // set drag source icon if possible... - // gio Icon is not easily converted to a Paintable, but this seems to be the correct method - if let Some(default_display) = &Display::default() { - if let Some(icon_theme) = IconTheme::for_display(default_display) { - if let Some(paintable_icon) = icon_theme.lookup_by_gicon( - &icon, - 64, - 1, - gtk4::TextDirection::None, - gtk4::IconLookupFlags::empty(), - ) { - _self.set_icon(Some(&paintable_icon), 32, 32); - } - } - } - })); -} diff --git a/examples/dock/window/imp.rs b/examples/dock/window/imp.rs index 74b30c07..5b49e2fc 100644 --- a/examples/dock/window/imp.rs +++ b/examples/dock/window/imp.rs @@ -30,6 +30,7 @@ pub struct Window { pub enter_event_controller: OnceCell, pub leave_event_controller: OnceCell, pub drop_controller: OnceCell, + pub window_drop_controller: OnceCell, } // The central trait for subclassing a GObject diff --git a/examples/dock/window/mod.rs b/examples/dock/window/mod.rs index 2ea05858..b91c9a40 100644 --- a/examples/dock/window/mod.rs +++ b/examples/dock/window/mod.rs @@ -2,20 +2,15 @@ mod imp; // use crate::ApplicationObject; use crate::dock_item::DockItem; use crate::X11_CONN; -use gdk4::ContentProvider; use gdk4::Rectangle; use gdk4::Surface; use gdk4_x11::X11Surface; -use gio::Cancellable; use gio::DesktopAppInfo; use glib::Type; use gtk4 as gtk; use gtk4::prelude::ListModelExt; use gtk4::DropTarget; -use gtk4::DropTargetAsync; use gtk4::EventControllerMotion; -use gtk4::ListStore; -use gtk4::TreeIter; use std::path::Path; use x11rb::connection::Connection; use x11rb::protocol::xproto::ConnectionExt; @@ -142,13 +137,13 @@ impl Window { let enter_event_controller = &imp.enter_event_controller.get().unwrap(); let leave_event_controller = &imp.leave_event_controller.get().unwrap(); let drop_controller = &imp.drop_controller.get().unwrap(); + let window_drop_controller = &imp.window_drop_controller.get().unwrap(); let revealer = &imp.revealer.get(); window.connect_show( glib::clone!(@weak revealer, @weak leave_event_controller => move |_| { dbg!(!leave_event_controller.contains_pointer()); if !leave_event_controller.contains_pointer() { - // TODO uncomment - // revealer.set_reveal_child(false); + revealer.set_reveal_child(false); } }), ); @@ -212,21 +207,25 @@ impl Window { dbg!("hello, mouse entered me :)"); revealer.set_reveal_child(true); })); - // TODO uncomment.. - // Temporarily disable hiding for dnd testing while the other options are being figured out.. - leave_event_controller.connect_leave(glib::clone!(@weak revealer => move |_evc| { - dbg!("hello, mouse left me :)"); - // revealer.set_reveal_child(false); - })); + leave_event_controller.connect_leave( + glib::clone!(@weak revealer, @weak drop_controller => move |_evc| { + // only hide if DnD is not happening + if drop_controller.current_drop().is_none() { + dbg!("hello, mouse left me :)"); + revealer.set_reveal_child(false); + } + }), + ); - // drop_controller.connect_enter(move |_self, drag, x, y| { - // dbg!(x); - // dbg!(y); - // match drag.drag() { - // Some(d) => d.selected_action(), - // None => drag.actions(), - // } - // }); + drop_controller.connect_enter(glib::clone!(@weak revealer => @default-return gdk4::DragAction::COPY, move |_self, _x, _y| { + revealer.set_reveal_child(true); + gdk4::DragAction::COPY + })); + // hack for showing hidden dock when drag enters window + window_drop_controller.connect_enter(glib::clone!(@weak revealer => @default-return gdk4::DragAction::COPY, move |_self, _x, _y| { + revealer.set_reveal_child(true); + gdk4::DragAction::empty() + })); let saved_app_list_view = saved_app_list_view.get(); @@ -317,12 +316,8 @@ impl Window { let drop_actions = gdk4::DragAction::COPY; // drop_actions.toggle(gdk4::DragAction::MOVE); let drop_format = gdk4::ContentFormats::for_type(Type::STRING); - let provider = - ContentProvider::for_value(&DesktopAppInfo::new("firefox.desktop").to_value()); - let desktop_type = provider.formats().types()[0]; // causes error for some reason... // let desktop_type = Type::from_name("GDesktopAppInfo").expect("Invalid GType"); - drop_format.union(&gdk4::ContentFormats::for_type(desktop_type)); let drop_target_controller = DropTarget::builder() .preload(true) .actions(drop_actions) @@ -332,6 +327,18 @@ impl Window { imp.drop_controller .set(drop_target_controller) .expect("Could not set dock dnd drop controller"); + + // hack for revealing hidden dock when drag enters dock window + let window_drop_target_controller = DropTarget::builder() + .actions(gdk4::DragAction::COPY) + .formats(&gdk4::ContentFormats::for_type(Type::STRING)) + .build(); + + let window = self.clone().upcast::(); + window.add_controller(&window_drop_target_controller); + imp.window_drop_controller + .set(window_drop_target_controller) + .expect("Could not set dock dnd drop controller"); } fn setup_factory(&self) { diff --git a/examples/dock/window/window.ui b/examples/dock/window/window.ui index 09df77dd..44e2b80b 100644 --- a/examples/dock/window/window.ui +++ b/examples/dock/window/window.ui @@ -18,8 +18,8 @@ true - 200 - swing-up + 300 + slide-up horizontal diff --git a/examples/launcher/ipc.rs b/examples/launcher/ipc.rs deleted file mode 100644 index c1ce7576..00000000 --- a/examples/launcher/ipc.rs +++ /dev/null @@ -1,76 +0,0 @@ -use pop_launcher::{Request, Response}; -use std::process; -use std::io::{self, BufRead, Write}; - -pub struct LauncherIpc { - child: process::Child, - stdin: process::ChildStdin, - stdout: io::BufReader, - exited: bool, -} - -impl LauncherIpc { - pub fn new() -> io::Result { - let mut child = process::Command::new("pop-launcher") - .stdin(process::Stdio::piped()) - .stdout(process::Stdio::piped()) - .spawn()?; - - let stdin = child.stdin.take().ok_or( - io::Error::new(io::ErrorKind::Other, "failed to find child stdin") - )?; - - let stdout = io::BufReader::new(child.stdout.take().ok_or( - io::Error::new(io::ErrorKind::Other, "failed to find child stdout") - )?); - - Ok(Self { - child, - stdin, - stdout, - exited: false, - }) - } - - fn send_request(&mut self, request: Request) -> io::Result<()> { - let mut request_json = serde_json::to_string(&request).map_err(|err| { - io::Error::new(io::ErrorKind::InvalidInput, err) - })?; - request_json.push('\n'); - self.stdin.write_all(request_json.as_bytes()) - } - - fn recv_response(&mut self) -> io::Result { - let mut response_json = String::new(); - self.stdout.read_line(&mut response_json)?; - serde_json::from_str(&response_json).map_err(|err| { - io::Error::new(io::ErrorKind::InvalidData, err) - }) - } - - pub fn request(&mut self, request: Request) -> io::Result { - self.send_request(request)?; - self.recv_response() - } - - //TODO: better exit implementation - pub fn exit(&mut self) -> io::Result> { - if ! self.exited { - self.send_request(Request::Exit)?; - let status = self.child.wait()?; - self.exited = true; - Ok(Some(status)) - } else { - Ok(None) - } - } -} - -impl Drop for LauncherIpc { - fn drop(&mut self) { - match self.exit() { - Ok(_) => (), - Err(err) => eprintln!("LauncherIpc::drop failed: {}", err), - } - } -}