feat: app list is working fairly well again
This commit is contained in:
parent
2a8497fb2a
commit
ab851fceef
13 changed files with 80 additions and 66 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
|
@ -299,7 +299,6 @@ dependencies = [
|
||||||
"rust-embed",
|
"rust-embed",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
"wayland-client 0.30.0-beta.8",
|
"wayland-client 0.30.0-beta.8",
|
||||||
"xdg",
|
"xdg",
|
||||||
|
|
@ -443,7 +442,7 @@ dependencies = [
|
||||||
"i18n-embed",
|
"i18n-embed",
|
||||||
"i18n-embed-fl",
|
"i18n-embed-fl",
|
||||||
"log",
|
"log",
|
||||||
"nix 0.22.3",
|
"nix 0.24.1",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
"rust-embed",
|
"rust-embed",
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ gio = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||||
libcosmic = { git = "https://github.com/pop-os/libcosmic", branch = "relm4-next" }
|
libcosmic = { git = "https://github.com/pop-os/libcosmic", branch = "relm4-next" }
|
||||||
relm4-macros = { git = "https://github.com/Relm4/Relm4.git", branch = "next" }
|
relm4-macros = { git = "https://github.com/Relm4/Relm4.git", branch = "next" }
|
||||||
serde_json = "1.0.78"
|
serde_json = "1.0.78"
|
||||||
tokio = { version = "1.16.1", features = ["sync"] }
|
|
||||||
futures = "0.3.19"
|
futures = "0.3.19"
|
||||||
futures-util = "0.3.19"
|
futures-util = "0.3.19"
|
||||||
once_cell = "1.9.0"
|
once_cell = "1.9.0"
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
use std::env;
|
|
||||||
|
|
||||||
use crate::TX;
|
|
||||||
// SPDX-License-Identifier: MPL-2.0-only
|
// SPDX-License-Identifier: MPL-2.0-only
|
||||||
use crate::dock_list::DockList;
|
use crate::dock_list::DockList;
|
||||||
use crate::dock_list::DockListType;
|
use crate::dock_list::DockListType;
|
||||||
use crate::utils::AppListEvent;
|
|
||||||
use cascade::cascade;
|
use cascade::cascade;
|
||||||
use cosmic_panel_config::{CosmicPanelConfig, PanelAnchor};
|
use cosmic_panel_config::{CosmicPanelConfig, PanelAnchor};
|
||||||
use gtk4::prelude::*;
|
use gtk4::prelude::*;
|
||||||
|
|
@ -12,7 +8,6 @@ use gtk4::subclass::prelude::*;
|
||||||
use gtk4::Orientation;
|
use gtk4::Orientation;
|
||||||
use gtk4::Separator;
|
use gtk4::Separator;
|
||||||
use gtk4::{gio, glib};
|
use gtk4::{gio, glib};
|
||||||
use tokio::sync::mpsc::Sender;
|
|
||||||
|
|
||||||
mod imp;
|
mod imp;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,10 @@ impl CosmicAppListWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apps_container(&self) -> &AppsContainer {
|
pub fn apps_container(&self) -> &AppsContainer {
|
||||||
imp::CosmicAppListWindow::from_instance(&self).inner.get().unwrap()
|
imp::CosmicAppListWindow::from_instance(&self)
|
||||||
|
.inner
|
||||||
|
.get()
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_shortcuts(&self) {
|
fn setup_shortcuts(&self) {
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,15 @@
|
||||||
// SPDX-License-Identifier: MPL-2.0-only
|
// SPDX-License-Identifier: MPL-2.0-only
|
||||||
|
|
||||||
use glib::subclass::Signal;
|
use gtk4::{
|
||||||
use gtk4::glib;
|
glib::{self, subclass::Signal},
|
||||||
use gtk4::prelude::*;
|
prelude::*,
|
||||||
use gtk4::subclass::prelude::*;
|
subclass::prelude::*,
|
||||||
|
};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use once_cell::sync::OnceCell;
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use tokio::sync::mpsc::Sender;
|
|
||||||
|
|
||||||
use crate::dock_popover::DockPopover;
|
use crate::dock_popover::DockPopover;
|
||||||
use crate::utils::AppListEvent;
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct DockItem {
|
pub struct DockItem {
|
||||||
|
|
@ -20,7 +18,6 @@ pub struct DockItem {
|
||||||
pub item_box: Rc<RefCell<gtk4::Box>>,
|
pub item_box: Rc<RefCell<gtk4::Box>>,
|
||||||
pub popover: Rc<RefCell<gtk4::Popover>>,
|
pub popover: Rc<RefCell<gtk4::Popover>>,
|
||||||
pub popover_menu: Rc<RefCell<Option<DockPopover>>>,
|
pub popover_menu: Rc<RefCell<Option<DockPopover>>>,
|
||||||
pub tx: OnceCell<Sender<AppListEvent>>,
|
|
||||||
pub icon_size: Rc<Cell<u32>>,
|
pub icon_size: Rc<Cell<u32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ use gtk4::Image;
|
||||||
use gtk4::Orientation;
|
use gtk4::Orientation;
|
||||||
use gtk4::Popover;
|
use gtk4::Popover;
|
||||||
use gtk4::{Align, PositionType};
|
use gtk4::{Align, PositionType};
|
||||||
use tokio::sync::mpsc::Sender;
|
|
||||||
|
|
||||||
mod imp;
|
mod imp;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ use gtk4::{Box, DragSource, DropTarget, GestureClick, ListView};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use tokio::sync::mpsc;
|
|
||||||
|
|
||||||
use crate::utils::AppListEvent;
|
use crate::utils::AppListEvent;
|
||||||
|
|
||||||
|
|
@ -24,7 +23,6 @@ pub struct DockList {
|
||||||
pub drag_cancel_signal: Rc<RefCell<Option<SignalHandlerId>>>,
|
pub drag_cancel_signal: Rc<RefCell<Option<SignalHandlerId>>>,
|
||||||
pub popover_menu_index: Rc<Cell<Option<u32>>>,
|
pub popover_menu_index: Rc<Cell<Option<u32>>>,
|
||||||
pub position: Rc<Cell<PanelAnchor>>,
|
pub position: Rc<Cell<PanelAnchor>>,
|
||||||
pub tx: OnceCell<mpsc::Sender<AppListEvent>>,
|
|
||||||
pub config: OnceCell<CosmicPanelConfig>,
|
pub config: OnceCell<CosmicPanelConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,26 @@
|
||||||
// SPDX-License-Identifier: MPL-2.0-only
|
// SPDX-License-Identifier: MPL-2.0-only
|
||||||
|
|
||||||
use crate::dock_item::DockItem;
|
use crate::{
|
||||||
use crate::dock_object::DockObject;
|
dock_item::DockItem,
|
||||||
use crate::utils::data_path;
|
utils::{AppListEvent, BoxedWindowList, data_path},
|
||||||
use crate::utils::{AppListEvent, BoxedWindowList};
|
wayland::{Toplevel, ToplevelEvent},
|
||||||
use crate::wayland::{Toplevel, ToplevelEvent};
|
{TX, WAYLAND_TX}, dock_object::DockObject,
|
||||||
use crate::{TX, WAYLAND_TX};
|
};
|
||||||
use cascade::cascade;
|
use cascade::cascade;
|
||||||
use cosmic_panel_config::{CosmicPanelConfig, PanelAnchor};
|
use cosmic_panel_config::{CosmicPanelConfig, PanelAnchor};
|
||||||
use gio::DesktopAppInfo;
|
|
||||||
use gio::Icon;
|
use gio::traits::AppLaunchContextExt;
|
||||||
use glib::Object;
|
use gtk4::{
|
||||||
use glib::Type;
|
gdk::{self, ContentProvider, Display, ModifierType},
|
||||||
use gtk4::gdk;
|
gio::{self, DesktopAppInfo, Icon},
|
||||||
use gtk4::gdk::ContentProvider;
|
glib::{self, Object, Type},
|
||||||
use gtk4::gdk::Display;
|
prelude::ListModelExt,
|
||||||
use gtk4::gdk::ModifierType;
|
prelude::*,
|
||||||
use gtk4::glib;
|
subclass::prelude::*,
|
||||||
use gtk4::prelude::ListModelExt;
|
DropTarget, IconTheme, ListView, Orientation, SignalListItemFactory,
|
||||||
use gtk4::prelude::*;
|
{DragSource, GestureClick},
|
||||||
use gtk4::subclass::prelude::*;
|
};
|
||||||
use gtk4::DropTarget;
|
use std::{fs::File, path::Path};
|
||||||
use gtk4::IconTheme;
|
|
||||||
use gtk4::ListView;
|
|
||||||
use gtk4::Orientation;
|
|
||||||
use gtk4::SignalListItemFactory;
|
|
||||||
use gtk4::{DragSource, GestureClick};
|
|
||||||
use std::fs::File;
|
|
||||||
use std::path::Path;
|
|
||||||
use tokio::sync::mpsc::Sender;
|
|
||||||
|
|
||||||
mod imp;
|
mod imp;
|
||||||
|
|
||||||
|
|
@ -239,11 +231,14 @@ impl DockList {
|
||||||
// dbg!(click_modifier);
|
// dbg!(click_modifier);
|
||||||
// Launch the application when an item of the list is activated
|
// Launch the application when an item of the list is activated
|
||||||
|
|
||||||
|
// TODO use seat eventually
|
||||||
|
// let wl_seat = self_.device().map(|d| d.seat().downcast::<WaylandSeat>().unwrap().wl_seat()).unwrap();
|
||||||
let focus_window = move |first_focused_item: &Toplevel| {
|
let focus_window = move |first_focused_item: &Toplevel| {
|
||||||
let toplevel_handle = first_focused_item.toplevel_handle.clone();
|
let toplevel_handle = first_focused_item.toplevel_handle.clone();
|
||||||
let tx = WAYLAND_TX.get().unwrap().clone();
|
let tx = WAYLAND_TX.get().unwrap().clone();
|
||||||
let _ = tx.clone().send(ToplevelEvent::Activate(toplevel_handle));
|
let _ = tx.clone().send(ToplevelEvent::Activate(toplevel_handle));
|
||||||
};
|
};
|
||||||
|
|
||||||
let old_index = popover_menu_index.get();
|
let old_index = popover_menu_index.get();
|
||||||
if let Some(old_index) = old_index {
|
if let Some(old_index) = old_index {
|
||||||
if let Some(old_item) = model.item(old_index) {
|
if let Some(old_item) = model.item(old_index) {
|
||||||
|
|
|
||||||
|
|
@ -96,12 +96,22 @@ impl DockObject {
|
||||||
if let Some(app_info) = gio::DesktopAppInfo::new(path) {
|
if let Some(app_info) = gio::DesktopAppInfo::new(path) {
|
||||||
if app_info.should_show()
|
if app_info.should_show()
|
||||||
&& Some(&first.app_id)
|
&& Some(&first.app_id)
|
||||||
== app_info.filename().and_then(|p| p
|
== app_info
|
||||||
.file_stem()
|
.filename()
|
||||||
.and_then(|s| s.to_str().map(|s| s.to_string()))).as_ref()
|
.and_then(|p| {
|
||||||
|
p.file_stem().and_then(|s| {
|
||||||
|
s.to_str().map(|s| s.to_string())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.as_ref()
|
||||||
{
|
{
|
||||||
return Some(Object::new(&[("appinfo", &app_info), ("active", &results)])
|
return Some(
|
||||||
.expect("Failed to create `DockObject`."));
|
Object::new(&[
|
||||||
|
("appinfo", &app_info),
|
||||||
|
("active", &results),
|
||||||
|
])
|
||||||
|
.expect("Failed to create `DockObject`."),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,8 @@ use gtk4::prelude::*;
|
||||||
use gtk4::subclass::prelude::*;
|
use gtk4::subclass::prelude::*;
|
||||||
use gtk4::{Box, Button, ListBox, Revealer};
|
use gtk4::{Box, Button, ListBox, Revealer};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use once_cell::sync::OnceCell;
|
|
||||||
use tokio::sync::mpsc::Sender;
|
|
||||||
|
|
||||||
use crate::dock_object::DockObject;
|
use crate::dock_object::DockObject;
|
||||||
use crate::utils::AppListEvent;
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct DockPopover {
|
pub struct DockPopover {
|
||||||
|
|
@ -26,7 +23,6 @@ pub struct DockPopover {
|
||||||
pub quit_all_item: Rc<RefCell<Button>>,
|
pub quit_all_item: Rc<RefCell<Button>>,
|
||||||
//TODO figure out how to use lifetimes with glib::wrapper! macro
|
//TODO figure out how to use lifetimes with glib::wrapper! macro
|
||||||
pub dock_object: Rc<RefCell<Option<DockObject>>>,
|
pub dock_object: Rc<RefCell<Option<DockObject>>>,
|
||||||
pub tx: OnceCell<Sender<AppListEvent>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ use gtk4::subclass::prelude::*;
|
||||||
use gtk4::{gdk, gio, glib};
|
use gtk4::{gdk, gio, glib};
|
||||||
use gtk4::{prelude::*, Label};
|
use gtk4::{prelude::*, Label};
|
||||||
use gtk4::{Box, Button, Image, ListBox, Orientation};
|
use gtk4::{Box, Button, Image, ListBox, Orientation};
|
||||||
use tokio::sync::mpsc::Sender;
|
|
||||||
|
|
||||||
use crate::dock_object::DockObject;
|
use crate::dock_object::DockObject;
|
||||||
use crate::utils::AppListEvent;
|
use crate::utils::AppListEvent;
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,6 @@ use gtk4::gdk::Display;
|
||||||
use gtk4::{glib, prelude::*, CssProvider, StyleContext};
|
use gtk4::{glib, prelude::*, CssProvider, StyleContext};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
use std::time::Duration;
|
|
||||||
use tokio::sync::mpsc;
|
|
||||||
use utils::{block_on, AppListEvent, BoxedWindowList, DEST, PATH};
|
use utils::{block_on, AppListEvent, BoxedWindowList, DEST, PATH};
|
||||||
use wayland::{Toplevel, ToplevelEvent};
|
use wayland::{Toplevel, ToplevelEvent};
|
||||||
|
|
||||||
|
|
@ -87,7 +84,7 @@ fn main() {
|
||||||
let mut index: Option<u32> = None;
|
let mut index: Option<u32> = None;
|
||||||
while let Some(item) = active_app_model.item(cur) {
|
while let Some(item) = active_app_model.item(cur) {
|
||||||
if let Ok(cur_dock_object) = item.downcast::<DockObject>() {
|
if let Ok(cur_dock_object) = item.downcast::<DockObject>() {
|
||||||
if cur_dock_object.get_path() == Some(name.clone()) {
|
if cur_dock_object.get_name() == Some(name.clone()) {
|
||||||
cur_dock_object.set_saved(true);
|
cur_dock_object.set_saved(true);
|
||||||
index = Some(cur);
|
index = Some(cur);
|
||||||
}
|
}
|
||||||
|
|
@ -104,7 +101,7 @@ fn main() {
|
||||||
let mut index: Option<u32> = None;
|
let mut index: Option<u32> = None;
|
||||||
while let Some(item) = saved_app_model.item(cur) {
|
while let Some(item) = saved_app_model.item(cur) {
|
||||||
if let Ok(cur_dock_object) = item.downcast::<DockObject>() {
|
if let Ok(cur_dock_object) = item.downcast::<DockObject>() {
|
||||||
if cur_dock_object.get_path() == Some(name.clone()) {
|
if cur_dock_object.get_name() == Some(name.clone()) {
|
||||||
cur_dock_object.set_saved(false);
|
cur_dock_object.set_saved(false);
|
||||||
index = Some(cur);
|
index = Some(cur);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ use cosmic_protocols::{
|
||||||
zcosmic_workspace_manager_v1::{self, ZcosmicWorkspaceManagerV1},
|
zcosmic_workspace_manager_v1::{self, ZcosmicWorkspaceManagerV1},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use wayland_client::protocol::wl_seat::{WlSeat, self};
|
||||||
use std::{env, os::unix::net::UnixStream, path::PathBuf, time::Duration};
|
use std::{env, os::unix::net::UnixStream, path::PathBuf, time::Duration};
|
||||||
use wayland_client::{
|
use wayland_client::{
|
||||||
event_created_child,
|
event_created_child,
|
||||||
|
|
@ -80,15 +81,21 @@ pub fn spawn_toplevels() -> SyncSender<ToplevelEvent> {
|
||||||
expected_output: None,
|
expected_output: None,
|
||||||
running: true,
|
running: true,
|
||||||
toplevels: vec![],
|
toplevels: vec![],
|
||||||
|
seats: vec![],
|
||||||
};
|
};
|
||||||
let loop_handle = event_loop.handle();
|
let loop_handle = event_loop.handle();
|
||||||
loop_handle
|
loop_handle
|
||||||
.insert_source(workspaces_rx, |e, _, state| match e {
|
.insert_source(workspaces_rx, |e, _, state| match e {
|
||||||
Event::Msg(ToplevelEvent::Activate(_t)) => {
|
Event::Msg(ToplevelEvent::Activate(toplevel)) => {
|
||||||
todo!()
|
if let Some(manager) = &state.toplevel_manager {
|
||||||
|
for seat in &state.seats {
|
||||||
|
manager.activate(&toplevel,seat)
|
||||||
|
} }
|
||||||
}
|
}
|
||||||
Event::Msg(ToplevelEvent::Close(_t)) => {
|
Event::Msg(ToplevelEvent::Close(t)) => {
|
||||||
todo!()
|
if let Some(manager) = &state.toplevel_manager {
|
||||||
|
manager.close(&t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Event::Closed => {
|
Event::Closed => {
|
||||||
if let Some(workspace_manager) = &mut state.workspace_manager {
|
if let Some(workspace_manager) = &mut state.workspace_manager {
|
||||||
|
|
@ -134,6 +141,7 @@ pub struct State {
|
||||||
toplevel_info: Option<ZcosmicToplevelInfoV1>,
|
toplevel_info: Option<ZcosmicToplevelInfoV1>,
|
||||||
toplevel_manager: Option<ZcosmicToplevelManagerV1>,
|
toplevel_manager: Option<ZcosmicToplevelManagerV1>,
|
||||||
toplevels: Vec<Toplevel>,
|
toplevels: Vec<Toplevel>,
|
||||||
|
seats: Vec<WlSeat>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
|
|
@ -220,6 +228,9 @@ impl Dispatch<wl_registry::WlRegistry, ()> for State {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
state.workspace_manager = Some(workspace_manager);
|
state.workspace_manager = Some(workspace_manager);
|
||||||
}
|
}
|
||||||
|
"wl_seat" => {
|
||||||
|
registry.bind::<WlSeat, _, _>(name, 1, qh, ()).unwrap();
|
||||||
|
}
|
||||||
"wl_output" => {
|
"wl_output" => {
|
||||||
registry.bind::<WlOutput, _, _>(name, 1, qh, ()).unwrap();
|
registry.bind::<WlOutput, _, _>(name, 1, qh, ()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
@ -570,3 +581,19 @@ impl Dispatch<WlOutput, ()> for State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Dispatch<WlSeat, ()> for State {
|
||||||
|
fn event(
|
||||||
|
state: &mut Self,
|
||||||
|
seat: &WlSeat,
|
||||||
|
_: wl_seat::Event,
|
||||||
|
_: &(),
|
||||||
|
_: &Connection,
|
||||||
|
_: &QueueHandle<Self>,
|
||||||
|
) {
|
||||||
|
if state.seats.iter().find(|s| s == &seat).is_none() {
|
||||||
|
state.seats.push(seat.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue