refresh dock model on dnd

This commit is contained in:
Ashley Wulber 2021-12-27 20:19:59 -05:00
parent be9ee81967
commit 39fe8bbafe
3 changed files with 90 additions and 34 deletions

View file

@ -136,7 +136,7 @@ fn main() {
.expect("Failed to focus selected window"); .expect("Failed to focus selected window");
} }
Event::RefreshFromCache => { Event::RefreshFromCache => {
println!("refreshing model from cache"); // println!("refreshing model from cache");
let cached_results = cached_results.as_ref(); let cached_results = cached_results.as_ref();
let stack_active = cached_results.iter().fold( let stack_active = cached_results.iter().fold(
BTreeMap::new(), BTreeMap::new(),
@ -172,10 +172,10 @@ fn main() {
.enumerate() .enumerate()
.find(|(_i, s)| s.0[0].description == cur_app_info.name()) .find(|(_i, s)| s.0[0].description == cur_app_info.name())
{ {
println!( // println!(
"found active saved app {} at {}", // "found active saved app {} at {}",
_s.0[0].name, i // _s.0[0].name, i
); // );
let active = stack_active.remove(i); let active = stack_active.remove(i);
dock_obj dock_obj
.set_property("active", active.to_value()) .set_property("active", active.to_value())

View file

@ -33,8 +33,10 @@ pub struct Window {
pub drop_controller: OnceCell<DropTarget>, pub drop_controller: OnceCell<DropTarget>,
pub saved_drag_source: Rc<OnceCell<DragSource>>, pub saved_drag_source: Rc<OnceCell<DragSource>>,
pub active_drag_source: OnceCell<DragSource>, pub active_drag_source: OnceCell<DragSource>,
pub drag_end_signal: Rc<RefCell<Option<SignalHandlerId>>>, pub saved_drag_end_signal: Rc<RefCell<Option<SignalHandlerId>>>,
pub drag_cancel_signal: Rc<RefCell<Option<SignalHandlerId>>>, pub active_drag_end_signal: Rc<RefCell<Option<SignalHandlerId>>>,
pub saved_drag_cancel_signal: Rc<RefCell<Option<SignalHandlerId>>>,
pub active_drag_cancel_signal: Rc<RefCell<Option<SignalHandlerId>>>,
pub window_drop_controller: OnceCell<DropTarget>, pub window_drop_controller: OnceCell<DropTarget>,
} }

View file

@ -286,10 +286,27 @@ impl Window {
// drag end handler // drag end handler
// must be modified in case of reorder... // must be modified in case of reorder...
let drag_end = &imp.drag_end_signal; let drag_end = &imp.saved_drag_end_signal;
let saved_drag_source = &imp.saved_drag_source; let saved_drag_source = &imp.saved_drag_source;
drop_controller.connect_drop( drop_controller.connect_drop(
glib::clone!(@weak saved_app_model, @weak saved_app_list_view, @weak drag_end, @weak saved_drag_source => @default-return true, move |_self, drop_value, x, _y| { glib::clone!(@weak saved_app_model, @weak saved_app_list_view, @weak drag_end, @weak saved_drag_source => @default-return true, move |_self, drop_value, x, _y| {
//calculate insertion location
// dbg!(x);
// dbg!(y);
let max_x = saved_app_list_view.allocated_width();
// dbg!(max_x);
// dbg!(max_y);
let n_buckets = saved_app_model.n_items() * 2;
let drop_bucket = (x * n_buckets as f64 / (max_x as f64 + 0.1)) as u32;
let index = if drop_bucket == 0 {
0
} else if drop_bucket == n_buckets - 1 {
saved_app_model.n_items()
} else {
(drop_bucket + 1) / 2
};
if let Ok(Some(path_str)) = drop_value.get::<Option<String>>() { if let Ok(Some(path_str)) = drop_value.get::<Option<String>>() {
let desktop_path = &Path::new(&path_str); let desktop_path = &Path::new(&path_str);
if let Some(pathbase) = desktop_path.file_name() { if let Some(pathbase) = desktop_path.file_name() {
@ -318,22 +335,6 @@ impl Window {
} }
} }
//calculate insertion location
// dbg!(x);
// dbg!(y);
let max_x = saved_app_list_view.allocated_width();
// dbg!(max_x);
// dbg!(max_y);
let n_buckets = saved_app_model.n_items() * 2;
let drop_bucket = (x * n_buckets as f64 / (max_x as f64 + 0.1)) as u32;
let index = if drop_bucket == 0 {
0
} else if drop_bucket == n_buckets - 1 {
saved_app_model.n_items()
} else {
(drop_bucket + 1) / 2
};
// dbg!(index); // dbg!(index);
// dbg!("dropped it!"); // dbg!("dropped it!");
// dbg!(drop_value.type_()); // dbg!(drop_value.type_());
@ -341,10 +342,27 @@ impl Window {
} }
} }
} }
else if let Ok(old_index) = drop_value.get::<u32>() {
if let Some(item) = saved_app_model.item(old_index) {
if let Ok(dock_object) = item.downcast::<DockObject>() {
saved_app_model.remove(old_index);
saved_app_model.insert(index, &dock_object);
if let Some(old_handle) = drag_end.replace(None) {
glib::signal_handler_disconnect(saved_drag_source.get().expect("Failed to get drag handler"), old_handle);
}
}
}
}
else { else {
// dbg!("rejecting drop"); // dbg!("rejecting drop");
_self.reject(); _self.reject();
} }
glib::MainContext::default().spawn_local(async move {
if let Some(tx) = TX.get() {
let mut tx = tx.clone();
let _ = tx.send(Event::RefreshFromCache).await;
}
});
true true
}), }),
); );
@ -374,8 +392,9 @@ impl Window {
let mut drop_actions = gdk4::DragAction::COPY; let mut drop_actions = gdk4::DragAction::COPY;
drop_actions.insert(gdk4::DragAction::MOVE); drop_actions.insert(gdk4::DragAction::MOVE);
let drop_format = gdk4::ContentFormats::for_type(Type::STRING); let drop_format = gdk4::ContentFormats::for_type(Type::STRING);
// causes error for some reason... let drop_format = drop_format
drop_format.union(&gdk4::ContentFormats::for_type(DockObject::static_type())); .union(&gdk4::ContentFormats::for_type(Type::U32))
.expect("couldn't make union");
let drop_target_controller = DropTarget::builder() let drop_target_controller = DropTarget::builder()
.preload(true) .preload(true)
.actions(drop_actions) .actions(drop_actions)
@ -389,7 +408,7 @@ impl Window {
// hack for revealing hidden dock when drag enters dock window // hack for revealing hidden dock when drag enters dock window
let window_drop_target_controller = DropTarget::builder() let window_drop_target_controller = DropTarget::builder()
.actions(drop_actions) .actions(drop_actions)
.formats(&gdk4::ContentFormats::for_type(Type::STRING)) .formats(&drop_format)
.build(); .build();
let enter_handle = &imp.cursor_handle.get(); let enter_handle = &imp.cursor_handle.get();
@ -413,8 +432,8 @@ impl Window {
.actions(actions) .actions(actions)
.build(); .build();
let drag_end = &imp.drag_end_signal; let drag_end = &imp.saved_drag_end_signal;
let drag_cancel = &imp.drag_end_signal; let drag_cancel = &imp.saved_drag_cancel_signal;
saved_app_list_view.add_controller(&saved_drag_source); saved_app_list_view.add_controller(&saved_drag_source);
saved_drag_source.connect_prepare(glib::clone!(@weak saved_app_model, @weak saved_app_list_view, @weak drag_end, @weak drag_cancel => @default-return None, move |self_, x, _y| { saved_drag_source.connect_prepare(glib::clone!(@weak saved_app_model, @weak saved_app_list_view, @weak drag_end, @weak drag_cancel => @default-return None, move |self_, x, _y| {
// set drag source icon if possible... // set drag source icon if possible...
@ -429,7 +448,15 @@ impl Window {
if let Some(old_handle) = drag_end.replace(Some(self_.connect_drag_end( if let Some(old_handle) = drag_end.replace(Some(self_.connect_drag_end(
glib::clone!(@weak saved_app_model => move |_self, _drag, _delete_data| { glib::clone!(@weak saved_app_model => move |_self, _drag, _delete_data| {
dbg!(_delete_data); dbg!(_delete_data);
if _delete_data {saved_app_model.remove(index)}; if _delete_data {
saved_app_model.remove(index);
glib::MainContext::default().spawn_local(async move {
if let Some(tx) = TX.get() {
let mut tx = tx.clone();
let _ = tx.send(Event::RefreshFromCache).await;
}
});
};
}), }),
))) { ))) {
glib::signal_handler_disconnect(self_, old_handle); glib::signal_handler_disconnect(self_, old_handle);
@ -438,6 +465,12 @@ impl Window {
glib::clone!(@weak saved_app_model => @default-return false, move |_self, _drag, cancel_reason| { glib::clone!(@weak saved_app_model => @default-return false, move |_self, _drag, cancel_reason| {
if cancel_reason != gdk4::DragCancelReason::UserCancelled { if cancel_reason != gdk4::DragCancelReason::UserCancelled {
saved_app_model.remove(index); saved_app_model.remove(index);
glib::MainContext::default().spawn_local(async move {
if let Some(tx) = TX.get() {
let mut tx = tx.clone();
let _ = tx.send(Event::RefreshFromCache).await;
}
});
true true
} else { } else {
false false
@ -465,9 +498,14 @@ impl Window {
} }
} }
} }
if let Some(file) = app_info.filename() {
return Some(ContentProvider::for_value(&file.to_string_lossy().to_value())); // saved app list provides index
} let p = ContentProvider::for_value(&index.to_value());
dbg!(p.formats().types());
return Some(p);
// if let Some(file) = app_info.filename() {
// return Some(ContentProvider::for_value(&file.to_string_lossy().to_value()));
// }
} }
} }
} }
@ -488,6 +526,8 @@ impl Window {
.name("dock drag source") .name("dock drag source")
.actions(actions) .actions(actions)
.build(); .build();
let drag_end = &imp.active_drag_end_signal;
let drag_cancel = &imp.active_drag_cancel_signal;
active_drag_source.connect_drag_begin(|_self, drag| { active_drag_source.connect_drag_begin(|_self, drag| {
drag.set_selected_action(gdk4::DragAction::MOVE); drag.set_selected_action(gdk4::DragAction::MOVE);
@ -504,7 +544,15 @@ impl Window {
if let Some(old_handle) = drag_end.replace(Some(self_.connect_drag_end( if let Some(old_handle) = drag_end.replace(Some(self_.connect_drag_end(
glib::clone!(@weak active_app_model => move |_self, _drag, _delete_data| { glib::clone!(@weak active_app_model => move |_self, _drag, _delete_data| {
dbg!(_delete_data); dbg!(_delete_data);
if _delete_data {active_app_model.remove(index)}; if _delete_data {
active_app_model.remove(index);
glib::MainContext::default().spawn_local(async move {
if let Some(tx) = TX.get() {
let mut tx = tx.clone();
let _ = tx.send(Event::RefreshFromCache).await;
}
});
};
}), }),
))) { ))) {
glib::signal_handler_disconnect(self_, old_handle); glib::signal_handler_disconnect(self_, old_handle);
@ -513,6 +561,12 @@ impl Window {
glib::clone!(@weak active_app_model => @default-return false, move |_self, _drag, cancel_reason| { glib::clone!(@weak active_app_model => @default-return false, move |_self, _drag, cancel_reason| {
if cancel_reason != gdk4::DragCancelReason::UserCancelled { if cancel_reason != gdk4::DragCancelReason::UserCancelled {
active_app_model.remove(index); active_app_model.remove(index);
glib::MainContext::default().spawn_local(async move {
if let Some(tx) = TX.get() {
let mut tx = tx.clone();
let _ = tx.send(Event::RefreshFromCache).await;
}
});
true true
} else { } else {
false false