👷 add new page
This commit is contained in:
parent
c1799211c5
commit
e328e3af7a
|
@ -12,10 +12,39 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.57"
|
||||
name = "alpm"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
|
||||
checksum = "bedac9e074b9368777268cff76c02d8b26d3e567642a52379aadd5c5e204e120"
|
||||
dependencies = [
|
||||
"alpm-sys",
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alpm-sys"
|
||||
version = "2.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fee1afe3484685ecedf03aefd7904428befed7815687e48aa4b21b3417eeecf0"
|
||||
dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alpm-utils"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09329cd59e48e140faceb66ec714d8b5fe28a414327b381ae9a8af47ab29a700"
|
||||
dependencies = [
|
||||
"alpm",
|
||||
"pacmanconf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704"
|
||||
|
||||
[[package]]
|
||||
name = "atk"
|
||||
|
@ -61,8 +90,10 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
|||
|
||||
[[package]]
|
||||
name = "cachyos-hello"
|
||||
version = "0.7.0"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"alpm",
|
||||
"alpm-utils",
|
||||
"gdk",
|
||||
"gdk-pixbuf",
|
||||
"gettext-rs",
|
||||
|
@ -70,6 +101,7 @@ dependencies = [
|
|||
"glib",
|
||||
"gtk",
|
||||
"once_cell",
|
||||
"pacmanconf",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"subprocess",
|
||||
|
@ -77,9 +109,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cairo-rs"
|
||||
version = "0.15.11"
|
||||
version = "0.15.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62be3562254e90c1c6050a72aa638f6315593e98c5cdaba9017cedbabf0a5dee"
|
||||
checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cairo-sys-rs",
|
||||
|
@ -114,6 +146,12 @@ dependencies = [
|
|||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cini"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "895f4cd6403d7bd85e13ff3ec635d58183e5e708e7bd70430a91d661b04548e2"
|
||||
|
||||
[[package]]
|
||||
name = "field-offset"
|
||||
version = "0.3.4"
|
||||
|
@ -491,6 +529,15 @@ version = "1.12.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
|
||||
|
||||
[[package]]
|
||||
name = "pacmanconf"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "faba895e4237d5dfd3459a4c0ef807b3510e088d28e7f5fd71a72962af84fef4"
|
||||
dependencies = [
|
||||
"cini",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pango"
|
||||
version = "0.15.10"
|
||||
|
@ -579,18 +626,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.39"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
|
||||
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.18"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
|
||||
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
@ -647,18 +694,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.137"
|
||||
version = "1.0.138"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
|
||||
checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.137"
|
||||
version = "1.0.138"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
|
||||
checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -667,9 +714,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.81"
|
||||
version = "1.0.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
|
||||
checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -684,9 +731,9 @@ checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
|
|||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.8.0"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
||||
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
|
||||
|
||||
[[package]]
|
||||
name = "subprocess"
|
||||
|
@ -700,9 +747,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.95"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
|
||||
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -765,9 +812,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
|
||||
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
[package]
|
||||
name = "cachyos-hello"
|
||||
version = "0.7.0"
|
||||
version = "0.8.0"
|
||||
authors = ["Vladislav Nepogodin <nepogodin.vlad@gmail.com>"]
|
||||
license = "GPLv3"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
alpm = "2.2.1"
|
||||
alpm-utils = "1.1.2"
|
||||
pacmanconf = "1.0.0"
|
||||
|
||||
subprocess = "0.2.9"
|
||||
once_cell = "1.12.0"
|
||||
gettext-rs = { version = "0.7", features = ["gettext-system"] }
|
||||
|
|
|
@ -0,0 +1,702 @@
|
|||
[
|
||||
{
|
||||
"name": "Browsers",
|
||||
"icon": "browser",
|
||||
"description": "Web browsing and communication",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Chromium",
|
||||
"icon": "chromium",
|
||||
"description": "Open Sourced Chrome Browser",
|
||||
"pkg": "chromium",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Epiphany",
|
||||
"icon": "epiphany",
|
||||
"description": "Open source Web Browser",
|
||||
"pkg": "epiphany",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Falkon",
|
||||
"icon": "falkon",
|
||||
"description": "Qt based Web Browser",
|
||||
"pkg": "falkon",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Firefox",
|
||||
"icon": "mozilla-firefox",
|
||||
"description": "Mozilla Web Browser",
|
||||
"pkg": "firefox",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Konqueror",
|
||||
"icon": "konqueror",
|
||||
"description": "Konqueror Web Browser",
|
||||
"pkg": "konqueror",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Midori",
|
||||
"icon": "midori",
|
||||
"description": "Lightweight Webbrowser",
|
||||
"pkg": "midori",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Netsurf",
|
||||
"icon": "netsurf",
|
||||
"description": "Light and Fast Web Browser",
|
||||
"pkg": "netsurf",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Opera",
|
||||
"icon": "opera",
|
||||
"description": "Fast and secure webbrowser",
|
||||
"pkg": "opera",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "E-mail",
|
||||
"icon": "mail-client",
|
||||
"description": "E-mail, Calendar, Tasks",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Claws Mail",
|
||||
"icon": "claws-mail",
|
||||
"description": "Lightweight and fast GTK+ based Mail Client",
|
||||
"pkg": "claws-mail",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Evolution",
|
||||
"icon": "evolution",
|
||||
"description": "Manage your email, contacts and schedule",
|
||||
"pkg": "evolution",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Geary",
|
||||
"icon": "geary",
|
||||
"description": "Send and receive mail",
|
||||
"pkg": "geary",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "KMail",
|
||||
"icon": "kmail",
|
||||
"description": "KDE E-mail client",
|
||||
"pkg": "kmail",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Sylpheed",
|
||||
"icon": "sylpheed",
|
||||
"description": "E-mail client",
|
||||
"pkg": "sylpheed",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Thunderbird",
|
||||
"icon": "thunderbird",
|
||||
"description": "Send and receive mail, contacts and schedule",
|
||||
"pkg": "thunderbird",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Office Suites",
|
||||
"icon": "applications-office",
|
||||
"description": "Office suites like MS Office",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Calligra Office",
|
||||
"icon": "calligrawords",
|
||||
"description": "Qt Based Office Suite",
|
||||
"pkg": "calligra",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Free Office",
|
||||
"icon": "freeoffice-planmaker",
|
||||
"description": "Free Office suite compatible with Microsoft Office",
|
||||
"pkg": "freeoffice",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Libre Office (Fresh)",
|
||||
"icon": "libreoffice-main",
|
||||
"description": "Open Source Office Application (Lastest)",
|
||||
"pkg": "libreoffice-fresh",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Libre Office (Still)",
|
||||
"icon": "libreoffice-main",
|
||||
"description": "Open Source Office Application (Stable)",
|
||||
"pkg": "libreoffice-still",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "MS Office Online",
|
||||
"icon": "ms-word",
|
||||
"description": "Microsoft Office Online",
|
||||
"pkg": "microsoft-office-web-jak",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Office Apps",
|
||||
"icon": "gnumeric",
|
||||
"description": "Stand alone applications",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Abiword",
|
||||
"icon": "abiword",
|
||||
"description": "Compose, Edit and view documents",
|
||||
"pkg": "abiword",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Gnumeric",
|
||||
"icon": "gnumeric",
|
||||
"description": "A High Precision Spreadsheet Program",
|
||||
"pkg": "gnumeric",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Printing",
|
||||
"icon": "printer",
|
||||
"description": "Support for printing CUPS, HPLIP",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Manjaro Printing",
|
||||
"icon": "printer",
|
||||
"description": "Printing Meta Package",
|
||||
"pkg": "manjaro-printer",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PDF",
|
||||
"icon": "pdfeditor",
|
||||
"description": "PDF applications applications",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Epdfview",
|
||||
"icon": "qpdfview",
|
||||
"description": "Lightweight PDF document viewer",
|
||||
"pkg": "epdfview",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Evince",
|
||||
"icon": "evince",
|
||||
"description": "View multi page documents",
|
||||
"pkg": "evince",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Okular",
|
||||
"icon": "okular",
|
||||
"description": "Document Viewer",
|
||||
"pkg": "Okular",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "PDFMod",
|
||||
"icon": "pdfmod",
|
||||
"description": "Remove, extract and rotate pages in PDF Documents",
|
||||
"pkg": "pdfmod",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Qpdfview",
|
||||
"icon": "qpdfview",
|
||||
"description": "Tabbed document viewer",
|
||||
"pkg": "qpdfview",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "E-Book",
|
||||
"icon": "calibre",
|
||||
"description": "E-book library apps",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Calibre",
|
||||
"icon": "calibre-viewer",
|
||||
"description": "The one stop solution to your e-book needs",
|
||||
"pkg": "calibre",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "FBReader",
|
||||
"icon": "fbreader",
|
||||
"description": "FBReader E-Book Reader",
|
||||
"pkg": "fbreader",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Backup",
|
||||
"icon": "deja-dup",
|
||||
"description": "Backup utilites",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Deja Dup",
|
||||
"icon": "deja-dup",
|
||||
"description": "Keep your important documents safe from disater",
|
||||
"pkg": "deja-dup",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Grsync",
|
||||
"icon": "grsync",
|
||||
"description": "Synchronize files and folders",
|
||||
"pkg": "grsync",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Timeshift",
|
||||
"icon": "timeshift",
|
||||
"description": "A system restore utility for Linux",
|
||||
"pkg": "timeshift",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Text Editors",
|
||||
"icon": "text-editor",
|
||||
"description": "Various editors for text or code",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Atom",
|
||||
"icon": "atom",
|
||||
"description": "A hackable text editor for the 21st Century",
|
||||
"pkg": "atom",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Geany",
|
||||
"icon": "geany",
|
||||
"description": "A fast and lightweight IDE using GTK+",
|
||||
"pkg": "geany",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Mousepad",
|
||||
"icon": "mousepad",
|
||||
"description": "Simple Text Editor",
|
||||
"pkg": "mousepad",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Visual Studio Code OSS",
|
||||
"icon": "visual-studio-code",
|
||||
"description": "Microsoft Code Editor",
|
||||
"pkg": "code",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Xed",
|
||||
"icon": "xed",
|
||||
"description": "A small and lightweight text editor. X Apps Project",
|
||||
"pkg": "xed",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "System Tools",
|
||||
"icon": "disk-utility",
|
||||
"description": "System utilities",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Etcher",
|
||||
"icon": "etcher-electron",
|
||||
"description": "Graphical tool to write ISO to USB",
|
||||
"pkg": "etcher",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Gnome Disks",
|
||||
"icon": "gnome-disks",
|
||||
"description": "Disk management system for Gnome",
|
||||
"pkg": "gnome-disk-utility",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Gparted",
|
||||
"icon": "gparted",
|
||||
"description": "Create, reorganize, and delete partitions",
|
||||
"pkg": "gparted",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "IsoUSB",
|
||||
"icon": "usb-creator",
|
||||
"description": "A graphical tool to copy a hybrid ISO onto a USB key.",
|
||||
"pkg": "isousb",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Mintstick",
|
||||
"icon": "mintstick",
|
||||
"description": "Format or wirte imges to usb sticks (Linux Mint tool).",
|
||||
"pkg": "mintstick",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Pamac",
|
||||
"icon": "pamac-updater",
|
||||
"description": "Update your System, Add/Remove Software from repo and AUR",
|
||||
"pkg": "pamac",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Yay",
|
||||
"icon": "terminal",
|
||||
"description": "CLI AUR helper",
|
||||
"pkg": "yay",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Security",
|
||||
"icon": "security-high",
|
||||
"description": "Security oriented utilities",
|
||||
"apps": [
|
||||
{
|
||||
"name": "KeePassX",
|
||||
"icon": "keepassx",
|
||||
"description": "Cross Platform Password Manager",
|
||||
"pkg": "keepassx",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "SeaHorse",
|
||||
"icon": "seahorse",
|
||||
"description": "Manage your passwords and encryption keys",
|
||||
"pkg": "seahorse",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "VeraCrypt",
|
||||
"icon": "veracrypt",
|
||||
"description": "Disk encryption with strong security based on TrueCrypt",
|
||||
"pkg": "veracrypt",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Virtual Computing",
|
||||
"icon": "virt-manager",
|
||||
"description": "Virtual Machine applications",
|
||||
"apps": [
|
||||
{
|
||||
"name": "VirtualBox",
|
||||
"icon": "virtualbox",
|
||||
"description": "Run several virtual systems on a single host computer",
|
||||
"pkg": "calibre",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Gnome Boxes",
|
||||
"icon": "gnome-boxes",
|
||||
"description": "Simple remote and virtual machines",
|
||||
"pkg": "gnome-boxes",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Chat",
|
||||
"icon": "internet-chat",
|
||||
"description": "Online messaging and chat",
|
||||
"apps": [
|
||||
{
|
||||
"name": "HexChat",
|
||||
"icon": "hexchat",
|
||||
"description": "Graphic IRC Client",
|
||||
"pkg": "hexchat",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Pidgin Messenger",
|
||||
"icon": "pidgin",
|
||||
"description": "Instant messaging Client",
|
||||
"pkg": "pidgin",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "File Sharing",
|
||||
"icon": "transmission",
|
||||
"description": "FTP and Torrent apps",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Filezilla",
|
||||
"icon": "filezilla",
|
||||
"description": "Graphical FTP/FTPS/SFTP browser",
|
||||
"pkg": "filezilla",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "qBittorrent",
|
||||
"icon": "qbittorrent",
|
||||
"description": "A Qt based Bittorrent Client",
|
||||
"pkg": "qbittorrent",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Transmission GTK",
|
||||
"icon": "transmission",
|
||||
"description": "GTK based Bittorrent Client",
|
||||
"pkg": "transmission-gtk",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "QTransmission",
|
||||
"icon": "transmission",
|
||||
"description": "QT based Bittorrent Client",
|
||||
"pkg": "transmission-qt",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Graphics Creating",
|
||||
"icon": "applications-accessories",
|
||||
"description": "Creating and editing graphics",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Blender",
|
||||
"icon": "blender",
|
||||
"description": "3D modeling and animation",
|
||||
"pkg": "blender",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "GIMP",
|
||||
"icon": "gimp",
|
||||
"description": "Create images and edit photographs",
|
||||
"pkg": "gimp",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Inkscape",
|
||||
"icon": "inkscape",
|
||||
"description": "Vector Graphics Editor",
|
||||
"pkg": "inkscape",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Krita",
|
||||
"icon": "krita",
|
||||
"description": "Digital Painting Creative Freedom",
|
||||
"pkg": "krita",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Pinta",
|
||||
"icon": "pinta",
|
||||
"description": "Easy create and edit images",
|
||||
"pkg": "pinta",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Tux Paint",
|
||||
"icon": "tuxpaint",
|
||||
"description": "Drawing program for children",
|
||||
"pkg": "tuxpaint",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Graphics Organizing",
|
||||
"icon": "applications-graphics",
|
||||
"description": "Viewers and organizers",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Gpicview",
|
||||
"icon": "gpicview",
|
||||
"description": "Lightweight Image Viewer",
|
||||
"pkg": "gpicview",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "gThumb",
|
||||
"icon": "gthumb",
|
||||
"description": "View and organize your images",
|
||||
"pkg": "gthumb",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Gwenview",
|
||||
"icon": "gwenview",
|
||||
"description": "Image Viewer",
|
||||
"pkg": "gwenview",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Ristretto",
|
||||
"icon": "ristretto",
|
||||
"description": "Free and lightweight image viewer",
|
||||
"pkg": "ristretto",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Shotwell",
|
||||
"icon": "shotwell",
|
||||
"description": "Popular Photo Manager",
|
||||
"pkg": "shotwell",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Viewnior",
|
||||
"icon": "viewnior",
|
||||
"description": "GTK based Elegant Image Viewer",
|
||||
"pkg": "viewnior",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Video/Movie",
|
||||
"icon": "video-player",
|
||||
"description": "Organize and play videos and movies",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Kodi",
|
||||
"icon": "kodi",
|
||||
"description": "Manage and view your media",
|
||||
"pkg": "kodi",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Parole",
|
||||
"icon": "parole",
|
||||
"description": "Modern and simple media player",
|
||||
"pkg": "parole",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "SM Player",
|
||||
"icon": "smplayer",
|
||||
"description": "A great MPlayer front end",
|
||||
"pkg": "smplayer",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Totem",
|
||||
"icon": "totem",
|
||||
"description": "Play movies",
|
||||
"pkg": "totem",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "VLC",
|
||||
"icon": "vlc",
|
||||
"description": "VLC media player, the openxource multimedia player",
|
||||
"pkg": "vlc",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Audio",
|
||||
"icon": "musicbrainz",
|
||||
"description": "Audio players",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Audacious",
|
||||
"icon": "audacious",
|
||||
"description": "Listen to music",
|
||||
"pkg": "audacious",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Clementine",
|
||||
"icon": "clementine",
|
||||
"description": "Play music files and internet radio",
|
||||
"pkg": "clementine",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "DeadBeeF",
|
||||
"icon": "deadbeef",
|
||||
"description": "Listen to music",
|
||||
"pkg": "deadbeef",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Lollypop",
|
||||
"icon": "lollypop",
|
||||
"description": "Play and organize your music collection",
|
||||
"pkg": "deadbeef",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Rhythmbox",
|
||||
"icon": "rhythmbox",
|
||||
"description": "Gnome music playing application",
|
||||
"pkg": "rhythmbox",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Media recording/editing",
|
||||
"icon": "kdenlive",
|
||||
"description": "Audio and Video editing",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Audacity",
|
||||
"icon": "audacity",
|
||||
"description": "Record and Edit Audio files",
|
||||
"pkg": "audacity",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Kdenlive",
|
||||
"icon": "kdenlive",
|
||||
"description": "Video Editor",
|
||||
"pkg": "kdenlive",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "OBS Studio",
|
||||
"icon": "obs",
|
||||
"description": "Open Source Streaming/Recording Application",
|
||||
"pkg": "obs-studio",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Simple Screen Recorder",
|
||||
"icon": "simple-ccsm",
|
||||
"description": "Screen Capturing Application",
|
||||
"pkg": "simplescreenrecorder",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,874 @@
|
|||
[
|
||||
{
|
||||
"name": "Browsers",
|
||||
"icon": "browser",
|
||||
"description": "Web browsing and communication",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Vivaldi",
|
||||
"icon": "vivaldi",
|
||||
"description": "Configurable browser for power users",
|
||||
"pkg": "vivaldi",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Chromium",
|
||||
"icon": "chromium",
|
||||
"description": "Fast and popular open source browser",
|
||||
"pkg": "chromium",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Epiphany",
|
||||
"icon": "epiphany",
|
||||
"description": "Gnome Web Browser",
|
||||
"pkg": "epiphany",
|
||||
"filter": [
|
||||
"advanced"
|
||||
],
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Firefox",
|
||||
"icon": "mozilla-firefox",
|
||||
"description": "Privacy oriented Web Browser",
|
||||
"pkg": "firefox",
|
||||
"extra": ["firefox-gnome-theme-maia"]
|
||||
},
|
||||
{
|
||||
"name": "Midori",
|
||||
"icon": "midori",
|
||||
"description": "Lightweight Web browser",
|
||||
"pkg": "midori",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Falkon",
|
||||
"icon": "falkon",
|
||||
"description": "KDE Web Browser",
|
||||
"pkg": "falkon",
|
||||
"filter": [
|
||||
"advanced"
|
||||
],
|
||||
"desktop": [
|
||||
"!gnome"
|
||||
],
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Konqueror",
|
||||
"icon": "konqueror",
|
||||
"description": "Konqueror Web Browser",
|
||||
"pkg": "konqueror",
|
||||
"filter": [
|
||||
"advanced"
|
||||
],
|
||||
"desktop": [
|
||||
"!gnome"
|
||||
],
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Opera",
|
||||
"icon": "opera",
|
||||
"description": "Fast and secure webbrowser",
|
||||
"pkg": "opera",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "E-mail",
|
||||
"icon": "mail-client",
|
||||
"description": "E-mail, Calendar, Tasks",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Claws Mail",
|
||||
"icon": "claws-mail",
|
||||
"description": "Lightweight and fast GTK+ based Mail Client",
|
||||
"pkg": "claws-mail",
|
||||
"filter": [
|
||||
"advanced"
|
||||
],
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Evolution",
|
||||
"icon": "evolution",
|
||||
"description": "Manage your email, contacts and schedule",
|
||||
"pkg": "evolution",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Geary",
|
||||
"icon": "geary",
|
||||
"description": "Send and receive mail",
|
||||
"pkg": "geary",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "KMail",
|
||||
"icon": "kmail",
|
||||
"description": "KDE E-mail client",
|
||||
"pkg": "kmail",
|
||||
"desktop": [
|
||||
"!gnome"
|
||||
],
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Sylpheed",
|
||||
"icon": "sylpheed",
|
||||
"description": "E-mail client",
|
||||
"pkg": "sylpheed",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Thunderbird",
|
||||
"icon": "thunderbird",
|
||||
"description": "Send and receive mail, contacts and schedule",
|
||||
"pkg": "thunderbird",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Office Suites",
|
||||
"icon": "applications-office",
|
||||
"description": "Office suites like MS Office",
|
||||
"apps": [
|
||||
{
|
||||
"name": "FreeOffice",
|
||||
"icon": "ms-word",
|
||||
"description": "Microsoft Office compatible suite",
|
||||
"pkg": "freeoffice",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Libre Office (Fresh)",
|
||||
"icon": "libreoffice-main",
|
||||
"description": "Open Source Office Application (Latest)",
|
||||
"pkg": "libreoffice-fresh",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Libre Office (Still)",
|
||||
"icon": "libreoffice-main",
|
||||
"description": "Open Source Office Application (Stable)",
|
||||
"pkg": "libreoffice-still",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "MS Office Online",
|
||||
"icon": "ms-word",
|
||||
"description": "Microsoft Office Online",
|
||||
"pkg": "microsoft-office-web-jak",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "OnlyOffice Desktop Editors",
|
||||
"icon": "ms-word",
|
||||
"description": "Light and free MS Office clone.",
|
||||
"pkg": "onlyoffice-desktopeditors",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Extended language support",
|
||||
"icon": "gnumeric",
|
||||
"description": "Manjaro extended language support",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Manjaro Asian Input Support Fcitx",
|
||||
"icon": "gnumeric",
|
||||
"description": "Manjaro extended language support with fcitx support",
|
||||
"pkg": "manjaro-asian-input-support-fcitx",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Manjaro Asian Input Support Ibus",
|
||||
"icon": "gnumeric",
|
||||
"description": "Manjaro extended language support with ibus support",
|
||||
"pkg": "manjaro-asian-input-support-ibus",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "E-Book",
|
||||
"icon": "calibre",
|
||||
"description": "E-book library apps",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Calibre",
|
||||
"icon": "calibre-viewer",
|
||||
"description": "The one stop solution to your e-book needs",
|
||||
"pkg": "calibre",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "FBReader",
|
||||
"icon": "fbreader",
|
||||
"description": "FBReader E-Book Reader",
|
||||
"pkg": "fbreader",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Text Editors",
|
||||
"icon": "text-editor",
|
||||
"description": "Various editors for text or code",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Atom",
|
||||
"icon": "atom",
|
||||
"description": "A hackable text editor for the 21st Century",
|
||||
"pkg": "atom",
|
||||
"filter": [
|
||||
"advanced"
|
||||
],
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Gedit",
|
||||
"icon": "gedit",
|
||||
"description": "Gnome text editor.",
|
||||
"pkg": "gedit",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Micro",
|
||||
"icon": "micro",
|
||||
"description": "Inituitive Text Editor for terminal",
|
||||
"pkg": "micro-manjaro",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Vim",
|
||||
"icon": "gvim",
|
||||
"description": "Keyboard controlled text-editor",
|
||||
"pkg": "gvim",
|
||||
"filter": [
|
||||
"advanced"
|
||||
],
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Visual Studio Code OSS",
|
||||
"icon": "visual-studio-code",
|
||||
"description": "Microsoft Code Editor",
|
||||
"pkg": "code",
|
||||
"filter": [
|
||||
"advanced"
|
||||
],
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Gnome builder",
|
||||
"icon": "gedit",
|
||||
"description": "An IDE for writing GNOME-based software",
|
||||
"pkg": "gnome-builder",
|
||||
"filter": [
|
||||
"advanced"
|
||||
],
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Xed",
|
||||
"icon": "xed",
|
||||
"description": "A small and lightweight text editor. X Apps Project",
|
||||
"pkg": "xed",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Printing",
|
||||
"icon": "printer",
|
||||
"description": "Support for printing CUPS, HPLIP",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Manjaro Printing",
|
||||
"icon": "printer",
|
||||
"description": "Printing Meta Package",
|
||||
"pkg": "manjaro-printer",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PDF",
|
||||
"icon": "pdfeditor",
|
||||
"description": "PDF applications applications",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Evince",
|
||||
"icon": "evince",
|
||||
"description": "View multi page documents",
|
||||
"pkg": "evince",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Okular",
|
||||
"icon": "okular",
|
||||
"description": "Document Viewer",
|
||||
"pkg": "okular",
|
||||
"desktop": [
|
||||
"!gnome"
|
||||
],
|
||||
"extra": []
|
||||
},
|
||||
|
||||
{
|
||||
"name": "PDFMod",
|
||||
"icon": "pdfmod",
|
||||
"description": "Remove, extract and rotate pages in PDF Documents",
|
||||
"pkg": "pdfmod",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Xournalpp",
|
||||
"icon": "xournalpp",
|
||||
"description": "Easy pdf editing tool",
|
||||
"pkg": "xournalpp",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Xreader",
|
||||
"icon": "xreader",
|
||||
"description": "Xreader is based on Atril and acts as document and PDF reader",
|
||||
"pkg": "xreader",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Paperwork",
|
||||
"icon": "paperwork",
|
||||
"description": "Document manager for GNOME to manage scanned documents and PDFs",
|
||||
"pkg": "paperwork",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Graphics Creating",
|
||||
"icon": "applications-accessories",
|
||||
"description": "Creating and editing graphics",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Blender",
|
||||
"icon": "blender",
|
||||
"description": "3D modeling and animation",
|
||||
"pkg": "blender",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "GIMP",
|
||||
"icon": "gimp",
|
||||
"description": "Create images and edit photographs",
|
||||
"pkg": "gimp",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Inkscape",
|
||||
"icon": "inkscape",
|
||||
"description": "Vector Graphics Editor",
|
||||
"pkg": "inkscape",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Krita",
|
||||
"icon": "krita",
|
||||
"description": "Digital Painting Creative Freedom",
|
||||
"pkg": "krita",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Pinta",
|
||||
"icon": "pinta",
|
||||
"description": "Easy create and edit images",
|
||||
"pkg": "pinta",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Tux Paint",
|
||||
"icon": "tuxpaint",
|
||||
"description": "Drawing program for children",
|
||||
"pkg": "tuxpaint",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Photos",
|
||||
"icon": "applications-graphics",
|
||||
"description": "Viewers and organizers",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Gpicview",
|
||||
"icon": "gpicview",
|
||||
"description": "Lightweight Image Viewer",
|
||||
"pkg": "gpicview",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "gThumb",
|
||||
"icon": "gthumb",
|
||||
"description": "View and organize your images",
|
||||
"pkg": "gthumb",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Gnome-photos",
|
||||
"icon": "gthumb",
|
||||
"description": "Access, organize, and share your photos on GNOME",
|
||||
"pkg": "gnome-photos",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Ristretto",
|
||||
"icon": "ristretto",
|
||||
"description": "Free and lightweight image viewer",
|
||||
"pkg": "ristretto",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Shotwell",
|
||||
"icon": "shotwell",
|
||||
"description": "Popular Photo Manager",
|
||||
"pkg": "shotwell",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Viewnior",
|
||||
"icon": "viewnior",
|
||||
"description": "GTK based Elegant Image Viewer",
|
||||
"pkg": "viewnior",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Eye of Gnome",
|
||||
"icon": "eog",
|
||||
"description": "An image viewing and cataloging program",
|
||||
"pkg": "eog",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Video/Movie",
|
||||
"icon": "video-player",
|
||||
"description": "Organize and play videos and movies",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Kodi",
|
||||
"icon": "kodi",
|
||||
"description": "Manage and view your media",
|
||||
"pkg": "kodi",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Parole",
|
||||
"icon": "parole",
|
||||
"description": "Modern and simple media player",
|
||||
"pkg": "parole",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "SM Player",
|
||||
"icon": "smplayer",
|
||||
"description": "A great MPlayer front end",
|
||||
"pkg": "smplayer",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Totem",
|
||||
"icon": "totem",
|
||||
"description": "Play movies",
|
||||
"pkg": "totem",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "VLC",
|
||||
"icon": "vlc",
|
||||
"description": "VLC media player, the openxource multimedia player",
|
||||
"pkg": "vlc",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Xplayer",
|
||||
"icon": "xplayer",
|
||||
"description": "Xplayer is based on Totem and plays both music an video",
|
||||
"pkg": "xplayer",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Audio",
|
||||
"icon": "musicbrainz",
|
||||
"description": "Audio players",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Audacious",
|
||||
"icon": "audacious",
|
||||
"description": "Listen to music",
|
||||
"pkg": "audacious",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Clementine",
|
||||
"icon": "clementine",
|
||||
"description": "Play music files and internet radio",
|
||||
"pkg": "clementine",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "DeadBeeF",
|
||||
"icon": "deadbeef",
|
||||
"description": "Listen to music",
|
||||
"pkg": "deadbeef",
|
||||
"extra": ["ffmpeg", "libmad", "mpg123"]
|
||||
},
|
||||
{
|
||||
"name": "Lollypop",
|
||||
"icon": "lollypop",
|
||||
"description": "Play and organize your music collection",
|
||||
"pkg": "lollypop",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Rhythmbox",
|
||||
"icon": "rhythmbox",
|
||||
"description": "Gnome music playing application",
|
||||
"pkg": "rhythmbox",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Media recording/editing",
|
||||
"icon": "kdenlive",
|
||||
"description": "Audio and Video editing",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Audacity",
|
||||
"icon": "audacity",
|
||||
"description": "Record and Edit Audio files",
|
||||
"pkg": "audacity",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Kdenlive",
|
||||
"icon": "kdenlive",
|
||||
"description": "Video Editor",
|
||||
"pkg": "kdenlive",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "OBS Studio",
|
||||
"icon": "obs",
|
||||
"description": "Open Source Streaming/Recording Application",
|
||||
"pkg": "obs-studio",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Shotcut",
|
||||
"icon": "shotcut",
|
||||
"description": "Cross-platform Qt based Video Editor",
|
||||
"pkg": "shotcut",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Openshot",
|
||||
"icon": "openshot",
|
||||
"description": "Award-winning free and open-source video editor",
|
||||
"pkg": "obs-studio",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Pitivi",
|
||||
"icon": "pitivi",
|
||||
"description": "Editor for audio/video projects",
|
||||
"pkg": "pitivi",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Simple Screen Recorder",
|
||||
"icon": "simple-ccsm",
|
||||
"description": "Screen Capturing Application",
|
||||
"pkg": "simplescreenrecorder",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Flowblade",
|
||||
"icon": "flowblade",
|
||||
"description": "Multitrack non-linear video editor",
|
||||
"pkg": "flowblade",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Chat",
|
||||
"icon": "internet-chat",
|
||||
"description": "Online messaging and chat",
|
||||
"apps": [
|
||||
{
|
||||
"name": "HexChat",
|
||||
"icon": "hexchat",
|
||||
"description": "Graphic IRC Client",
|
||||
"pkg": "hexchat",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Telegram",
|
||||
"icon": "telegram-desktop",
|
||||
"description": "Official Telegram Desktop client",
|
||||
"pkg": "telegram-desktop",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Whatsapp web",
|
||||
"icon": "whatsapp-web-jak",
|
||||
"description": "Wrapper for whatsapp online",
|
||||
"pkg": "whatsapp-web-jak",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Slack web",
|
||||
"icon": "slack-web-jak",
|
||||
"description": "Wrapper for slack online",
|
||||
"pkg": "slack-web-jak",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Pidgin Messenger",
|
||||
"icon": "pidgin",
|
||||
"description": "Instant messaging Client",
|
||||
"pkg": "pidgin",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "File Sharing",
|
||||
"icon": "transmission",
|
||||
"description": "FTP and Torrent apps",
|
||||
"filter": [
|
||||
"advanced"
|
||||
],
|
||||
"apps": [
|
||||
{
|
||||
"name": "Deluge",
|
||||
"icon": "deluge",
|
||||
"description": "Python based Bittorrent Client",
|
||||
"pkg": "deluge",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Filezilla",
|
||||
"icon": "filezilla",
|
||||
"description": "Graphical FTP/FTPS/SFTP browser",
|
||||
"pkg": "filezilla",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Transmission GTK",
|
||||
"icon": "transmission",
|
||||
"description": "GTK based Bittorrent Client",
|
||||
"pkg": "transmission-gtk",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "QTransmission",
|
||||
"icon": "transmission",
|
||||
"description": "QT based Bittorrent Client",
|
||||
"pkg": "transmission-qt",
|
||||
"desktop": [
|
||||
"!gnome"
|
||||
],
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Syncthing",
|
||||
"icon": "syncthing-gtk",
|
||||
"description": "Cross Platform file synchronization tool",
|
||||
"pkg": "syncthing-gtk",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Backup",
|
||||
"icon": "deja-dup",
|
||||
"description": "Backup utilites",
|
||||
"apps": [
|
||||
{
|
||||
"name": "Deja Dup",
|
||||
"icon": "deja-dup",
|
||||
"description": "Keep your important documents safe from disater",
|
||||
"pkg": "deja-dup",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Grsync",
|
||||
"icon": "grsync",
|
||||
"description": "Synchronize files and folders",
|
||||
"pkg": "grsync",
|
||||
"filter": [
|
||||
"advanced"
|
||||
],
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Timeshift",
|
||||
"icon": "timeshift",
|
||||
"description": "A system restore utility for Linux",
|
||||
"pkg": "timeshift",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Backintime",
|
||||
"icon": "deja-dup",
|
||||
"description": "Simple backup system",
|
||||
"pkg": "backintime",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Borg",
|
||||
"icon": "deja-dup",
|
||||
"description": "Deduplicating backup program with compression and authenticated encryption",
|
||||
"pkg": "borg",
|
||||
"filter": [
|
||||
"advanced"
|
||||
],
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Password Manager",
|
||||
"icon": "security-high",
|
||||
"description": "Password Managers",
|
||||
"apps": [
|
||||
{
|
||||
"name": "KeePassXC",
|
||||
"icon": "keepassxc",
|
||||
"description": "Cross Platform Password Manager",
|
||||
"pkg": "keepassxc",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Bitwarden",
|
||||
"icon": "bitwarden",
|
||||
"description": "Secure and free cloud based password manager.",
|
||||
"pkg": "bitwarden",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Enpass",
|
||||
"icon": "enpass",
|
||||
"description": "Premium Cross-platform Password Manager",
|
||||
"pkg": "enpass",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "System Tools",
|
||||
"icon": "disk-utility",
|
||||
"description": "System utilities",
|
||||
"filter": [
|
||||
"advanced"
|
||||
],
|
||||
"apps": [
|
||||
{
|
||||
"name": "Popsicle",
|
||||
"icon": "mintstick",
|
||||
"description": "Graphical tool to write ISO to USB",
|
||||
"pkg": "popsicle",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Gnome Disks",
|
||||
"icon": "gnome-disks",
|
||||
"description": "Disk management system for Gnome",
|
||||
"pkg": "gnome-disk-utility",
|
||||
"desktop": [
|
||||
"!kde"
|
||||
],
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Gparted",
|
||||
"icon": "gparted",
|
||||
"description": "Create, reorganize, and delete partitions",
|
||||
"pkg": "gparted",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "IsoUSB",
|
||||
"icon": "mintstick",
|
||||
"description": "A graphical tool to copy a hybrid ISO onto a USB key.",
|
||||
"pkg": "isousb",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Mintstick",
|
||||
"icon": "mintstick",
|
||||
"description": "Format or write imges to usb sticks (Linux Mint tool).",
|
||||
"pkg": "mintstick",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Ventoy",
|
||||
"icon": "mintstick",
|
||||
"description": "Tool for creating multiboot isos",
|
||||
"pkg": "ventoy",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Alma",
|
||||
"icon": "mintstick",
|
||||
"description": "Tool for creating persistent live isos",
|
||||
"pkg": "alma-git",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Virtual Computing",
|
||||
"icon": "virt-manager",
|
||||
"description": "Virtual Machine applications",
|
||||
"filter": [
|
||||
"advanced"
|
||||
],
|
||||
"apps": [
|
||||
{
|
||||
"name": "VirtualBox",
|
||||
"icon": "virtualbox",
|
||||
"description": "Run several virtual systems on a single host computer",
|
||||
"pkg": "virtualbox",
|
||||
"extra": [
|
||||
"virtualbox-guest-iso"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Gnome Boxes",
|
||||
"icon": "gnome-boxes",
|
||||
"description": "Simple remote and virtual machines",
|
||||
"pkg": "gnome-boxes",
|
||||
"extra": []
|
||||
},
|
||||
{
|
||||
"name": "Virt-manager",
|
||||
"icon": "virt-manager",
|
||||
"description": "Desktop user interface for managing virtual machines",
|
||||
"pkg": "virt-manager",
|
||||
"extra": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,5 +1,5 @@
|
|||
project('cachyos-hello', 'rust',
|
||||
version: '0.7.0',
|
||||
version: '0.8.0',
|
||||
license: 'GPLv3',
|
||||
meson_version: '>=0.56.0',
|
||||
default_options: ['buildtype=debugoptimized',
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
#[derive(Clone, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct AlpmHelper {
|
||||
pub pkg_list_install: Vec<String>,
|
||||
pub pkg_list_removal: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum AlpmHelperResult {
|
||||
NOTHING,
|
||||
REMOVE,
|
||||
ADD,
|
||||
BOTH,
|
||||
}
|
||||
|
||||
impl AlpmHelper {
|
||||
pub fn new() -> Self {
|
||||
Self { pkg_list_install: Vec::new(), pkg_list_removal: Vec::new() }
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.pkg_list_install.clear();
|
||||
self.pkg_list_removal.clear();
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.pkg_list_install.is_empty() && self.pkg_list_removal.is_empty()
|
||||
}
|
||||
|
||||
pub fn do_update(&self) -> AlpmHelperResult {
|
||||
let mut result = AlpmHelperResult::NOTHING;
|
||||
if self.pkg_list_install.is_empty() && self.pkg_list_removal.is_empty() {
|
||||
return result;
|
||||
}
|
||||
|
||||
if !self.pkg_list_removal.is_empty() {
|
||||
if self.install_apps(&self.pkg_list_removal, false) {
|
||||
result = AlpmHelperResult::REMOVE;
|
||||
}
|
||||
}
|
||||
if !self.pkg_list_install.is_empty() {
|
||||
if self.install_apps(&self.pkg_list_install, true) {
|
||||
if result == AlpmHelperResult::NOTHING {
|
||||
result = AlpmHelperResult::ADD;
|
||||
} else {
|
||||
result = AlpmHelperResult::BOTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub fn set_package(&mut self, pkg_name: &String, install: bool, installed: bool) {
|
||||
if self.to_remove(&pkg_name) {
|
||||
let index = self.pkg_list_removal.iter().position(|x| *x == *pkg_name).unwrap();
|
||||
self.pkg_list_removal.remove(index);
|
||||
} else if !install && installed {
|
||||
self.pkg_list_removal.push(String::from(pkg_name));
|
||||
}
|
||||
|
||||
if self.to_install(&pkg_name) {
|
||||
let index = self.pkg_list_install.iter().position(|x| *x == *pkg_name).unwrap();
|
||||
self.pkg_list_install.remove(index);
|
||||
} else if install && !installed {
|
||||
self.pkg_list_install.push(String::from(pkg_name));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_install(&self, pkg_name: &String) -> bool {
|
||||
self.pkg_list_install.contains(&pkg_name)
|
||||
}
|
||||
|
||||
pub fn to_remove(&self, pkg_name: &String) -> bool {
|
||||
self.pkg_list_removal.contains(&pkg_name)
|
||||
}
|
||||
|
||||
fn install_apps(&self, pkg_list: &Vec<String>, install: bool) -> bool {
|
||||
let mut install_arg: &str = "";
|
||||
if pkg_list.is_empty() {
|
||||
return false;
|
||||
} else if !install {
|
||||
install_arg = "-R";
|
||||
}
|
||||
|
||||
println!("pacman {} {:?}", install_arg, pkg_list);
|
||||
|
||||
match install {
|
||||
true => !self.app_installed(&pkg_list[0]),
|
||||
false => self.app_installed(&pkg_list[0]),
|
||||
}
|
||||
}
|
||||
|
||||
fn app_installed(&self, pkg_name: &str) -> bool {
|
||||
let pacman =
|
||||
pacmanconf::Config::with_opts(None, Some("/etc/pacman.conf"), Some("/")).unwrap();
|
||||
let alpm = alpm_utils::alpm_with_conf(&pacman).unwrap();
|
||||
match alpm.localdb().pkg(pkg_name) {
|
||||
Ok(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,426 @@
|
|||
use crate::alpm_helper::*;
|
||||
use crate::config::PKGDATADIR;
|
||||
use crate::utils;
|
||||
|
||||
use gio::prelude::*;
|
||||
use gtk::prelude::{
|
||||
BoxExt, ButtonExt, CellRendererExt, CellRendererToggleExt, ComboBoxExt, ContainerExt, GridExt,
|
||||
GtkListStoreExt, GtkListStoreExtManual, ScrolledWindowExt, ToggleButtonExt, TreeModelExt,
|
||||
TreeStoreExt, TreeStoreExtManual, TreeViewColumnExt, TreeViewExt, WidgetExt,
|
||||
};
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use serde_json;
|
||||
use std::fs;
|
||||
use std::sync::Mutex;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ApplicationBrowser {
|
||||
pub alpm_handle: alpm::Alpm,
|
||||
pub alpm_helper: AlpmHelper,
|
||||
pub filter: bool,
|
||||
pub app_store: gtk::TreeStore,
|
||||
pub group_store: gtk::ListStore,
|
||||
pub group_tofilter: String,
|
||||
pub groups: serde_json::Value,
|
||||
pub tree_view: gtk::TreeView,
|
||||
pub app_browser_box: gtk::Box,
|
||||
pub button_box: gtk::Box,
|
||||
pub update_system_btn: gtk::Button,
|
||||
}
|
||||
|
||||
fn new_alpm() -> alpm::Result<alpm::Alpm> {
|
||||
let pacman = pacmanconf::Config::with_opts(None, Some("/etc/pacman.conf"), Some("/")).unwrap();
|
||||
let alpm = alpm_utils::alpm_with_conf(&pacman)?;
|
||||
|
||||
Ok(alpm)
|
||||
}
|
||||
|
||||
const GROUP: u32 = 0;
|
||||
const ICON: u32 = 1;
|
||||
const APPLICATION: u32 = 2;
|
||||
const DESCRIPTION: u32 = 3;
|
||||
const ACTIVE: u32 = 4;
|
||||
const PACKAGE: u32 = 5;
|
||||
const INSTALLED: u32 = 6;
|
||||
|
||||
// static mut G_APP_BROWSER: Rc<Mutex<ApplicationBrowser>> =
|
||||
// Rc::new(Mutex::new(ApplicationBrowser::new()));
|
||||
static mut G_APP_BROWSER: Lazy<Mutex<ApplicationBrowser>> = Lazy::new(|| {
|
||||
let mut app_browser = ApplicationBrowser::new();
|
||||
app_browser.create_page();
|
||||
Mutex::new(app_browser)
|
||||
});
|
||||
|
||||
impl ApplicationBrowser {
|
||||
pub fn new() -> Self {
|
||||
let app_browser_box = gtk::Box::new(gtk::Orientation::Vertical, 0);
|
||||
app_browser_box.set_expand(true);
|
||||
|
||||
let button_box = gtk::Box::new(gtk::Orientation::Horizontal, 10);
|
||||
let advanced_button = gtk::ToggleButton::with_label("advanced");
|
||||
advanced_button.set_tooltip_text(Some("Toggle an extended selection of packages"));
|
||||
advanced_button.connect_clicked(on_advanced_clicked);
|
||||
// let download_button = gtk::Button::with_label("download");
|
||||
// download_button.set_tooltip_text(Some("Download the most recent selection of packages"));
|
||||
// download_button.connect_clicked(on_download_clicked);
|
||||
let reset_button = gtk::Button::with_label("reset");
|
||||
reset_button.set_tooltip_text(Some("Reset your current selections..."));
|
||||
reset_button.connect_clicked(on_reload_clicked);
|
||||
let update_system_btn = gtk::Button::with_label("UPDATE SYSTEM");
|
||||
update_system_btn.set_tooltip_text(Some("Apply your current selections to the system"));
|
||||
update_system_btn.connect_clicked(on_update_system_clicked);
|
||||
update_system_btn.set_sensitive(false);
|
||||
|
||||
// Group filter
|
||||
let data =
|
||||
fs::read_to_string(format!("{}/data/application_utility/default.json", PKGDATADIR))
|
||||
.expect("Unable to read file");
|
||||
let groups: serde_json::Value = serde_json::from_str(&data).expect("Unable to parse");
|
||||
let group_store = load_groups_data(&groups);
|
||||
let group_combo = utils::create_combo_with_model(&group_store);
|
||||
group_combo.connect_changed(on_group_filter_changed);
|
||||
|
||||
// Packing button box
|
||||
button_box.pack_start(&advanced_button, false, false, 10);
|
||||
button_box.pack_start(&group_combo, false, false, 10);
|
||||
button_box.pack_end(&update_system_btn, false, false, 10);
|
||||
|
||||
button_box.pack_end(&reset_button, false, false, 10);
|
||||
// button_box.pack_end(&download_button, false, false, 10);
|
||||
app_browser_box.pack_start(&button_box, false, false, 10);
|
||||
|
||||
let col_types: [glib::Type; 7] = [
|
||||
String::static_type(),
|
||||
String::static_type(),
|
||||
String::static_type(),
|
||||
String::static_type(),
|
||||
bool::static_type(),
|
||||
String::static_type(),
|
||||
bool::static_type(),
|
||||
];
|
||||
|
||||
Self {
|
||||
alpm_handle: new_alpm().unwrap(),
|
||||
alpm_helper: AlpmHelper::new(),
|
||||
filter: false,
|
||||
app_store: gtk::TreeStore::new(&col_types),
|
||||
group_store,
|
||||
groups,
|
||||
group_tofilter: String::from("*"),
|
||||
tree_view: gtk::TreeView::new(),
|
||||
app_browser_box,
|
||||
button_box,
|
||||
update_system_btn,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_impl() -> &'static Mutex<Self> {
|
||||
unsafe { &G_APP_BROWSER }
|
||||
}
|
||||
|
||||
fn load_app_data(&mut self) -> usize {
|
||||
// not use data set for the moment
|
||||
let mut store_size: usize = 0;
|
||||
|
||||
let localdb = self.alpm_handle.localdb();
|
||||
|
||||
for group in self.groups.as_array().unwrap() {
|
||||
if let Some(apps_map) = group.get("apps") {
|
||||
let g_name = String::from(group["name"].as_str().unwrap());
|
||||
let g_icon = String::from(group["icon"].as_str().unwrap());
|
||||
let mut g_desc = String::from(group["description"].as_str().unwrap());
|
||||
if g_desc.len() < 72 {
|
||||
g_desc += " ";
|
||||
}
|
||||
|
||||
if self.group_tofilter != "*" && self.group_tofilter != g_name {
|
||||
continue;
|
||||
}
|
||||
if group["filter"].as_array() != None && !self.filter {
|
||||
continue;
|
||||
}
|
||||
|
||||
let index = self.app_store.insert_with_values(None, None, &[
|
||||
(GROUP, &None::<String>),
|
||||
(ICON, &g_icon),
|
||||
(APPLICATION, &g_name),
|
||||
(DESCRIPTION, &g_desc),
|
||||
(ACTIVE, &false),
|
||||
(PACKAGE, &None::<String>),
|
||||
(INSTALLED, &false),
|
||||
]);
|
||||
store_size += 1;
|
||||
|
||||
for app in apps_map.as_array().unwrap() {
|
||||
let app_name = String::from(app["pkg"].as_str().unwrap());
|
||||
let mut status = localdb.pkg(app_name).is_ok();
|
||||
|
||||
if app["filter"].as_array() != None && !self.filter {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Restore user checks
|
||||
if !status
|
||||
&& self.alpm_helper.to_install(&String::from(app["pkg"].as_str().unwrap()))
|
||||
{
|
||||
status = true;
|
||||
}
|
||||
if status
|
||||
&& self.alpm_helper.to_remove(&String::from(app["pkg"].as_str().unwrap()))
|
||||
{
|
||||
status = false;
|
||||
}
|
||||
|
||||
self.app_store.insert_with_values(Some(&index), None, &[
|
||||
(GROUP, &None::<String>),
|
||||
(ICON, &String::from(app["icon"].as_str().unwrap())),
|
||||
(APPLICATION, &String::from(app["name"].as_str().unwrap())),
|
||||
(DESCRIPTION, &String::from(app["description"].as_str().unwrap())),
|
||||
(ACTIVE, &status),
|
||||
(PACKAGE, &String::from(app["pkg"].as_str().unwrap())),
|
||||
(INSTALLED, &status),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
store_size
|
||||
}
|
||||
|
||||
pub fn reload_app_data(&mut self, refresh: bool) {
|
||||
self.alpm_helper.clear();
|
||||
self.app_store.clear();
|
||||
|
||||
if refresh {
|
||||
self.group_store = load_groups_data(&self.groups);
|
||||
}
|
||||
self.load_app_data();
|
||||
self.tree_view.set_model(Some(&self.app_store));
|
||||
self.update_system_btn.set_sensitive(!self.alpm_helper.is_empty());
|
||||
}
|
||||
|
||||
fn create_view_tree(&mut self) -> usize {
|
||||
// setup list store model
|
||||
let app_store_size = self.load_app_data();
|
||||
|
||||
// create a tree view with the model store
|
||||
self.tree_view = gtk::TreeView::with_model(&self.app_store);
|
||||
self.tree_view.set_activate_on_single_click(true);
|
||||
self.tree_view.set_has_tooltip(true);
|
||||
self.tree_view.connect_query_tooltip(on_query_tooltip_tree_view);
|
||||
|
||||
// column model: icon
|
||||
let icon = gtk::CellRendererPixbuf::new();
|
||||
let icon_column = create_column("", &icon, "icon_name", ICON);
|
||||
self.tree_view.append_column(&icon_column);
|
||||
|
||||
// column model: group name column
|
||||
// let group_cell_renderer = gtk::CellRendererText::new();
|
||||
// let group_column = create_column("Group", &group_cell_renderer, "text", APPLICATION);
|
||||
// tree_view.append_column(&group_column);
|
||||
// group_column
|
||||
// .set_cell_data_func(&group_cell_renderer,
|
||||
// Some(Box::new(treeview_cell_app_data_function)));
|
||||
|
||||
// column model: app name column
|
||||
let app_cell_renderer = gtk::CellRendererText::new();
|
||||
let app_column = create_column("Application", &app_cell_renderer, "text", APPLICATION);
|
||||
// app_column.set_resizable(false);
|
||||
app_column.set_cell_data_func(
|
||||
&app_cell_renderer,
|
||||
Some(Box::new(treeview_cell_app_data_function)),
|
||||
);
|
||||
self.tree_view.append_column(&app_column);
|
||||
|
||||
// column model: description column
|
||||
let desc_renderer = gtk::CellRendererText::new();
|
||||
let desc_column = create_column("Description", &desc_renderer, "text", DESCRIPTION);
|
||||
desc_column.set_resizable(true);
|
||||
self.tree_view.append_column(&desc_column);
|
||||
|
||||
// column model: install column
|
||||
let install_renderer = gtk::CellRendererToggle::new();
|
||||
install_renderer.connect_toggled(on_app_toggle);
|
||||
let install_column = create_column("Install/Remove", &install_renderer, "active", ACTIVE);
|
||||
install_column.set_cell_data_func(
|
||||
&install_renderer,
|
||||
Some(Box::new(treeview_cell_check_data_function)),
|
||||
);
|
||||
|
||||
install_column.set_resizable(false);
|
||||
install_column.set_max_width(40);
|
||||
install_column.set_fixed_width(40);
|
||||
self.tree_view.append_column(&install_column);
|
||||
|
||||
app_store_size
|
||||
}
|
||||
|
||||
pub fn get_page(&self) -> >k::Box {
|
||||
&self.app_browser_box
|
||||
}
|
||||
|
||||
fn create_page(&mut self) {
|
||||
// create view and app store
|
||||
let app_store_size = self.create_view_tree();
|
||||
// create a scrollable window
|
||||
let app_window = gtk::ScrolledWindow::new(gtk::Adjustment::NONE, gtk::Adjustment::NONE);
|
||||
app_window.set_vexpand(true);
|
||||
app_window.set_policy(gtk::PolicyType::Never, gtk::PolicyType::Automatic);
|
||||
// add window to tree view
|
||||
app_window.add(&self.tree_view);
|
||||
|
||||
// setup grid
|
||||
let grid_inter = gtk::Grid::new();
|
||||
grid_inter.set_column_homogeneous(true);
|
||||
grid_inter.set_row_homogeneous(true);
|
||||
// add grid to app browser
|
||||
self.app_browser_box.add(&grid_inter);
|
||||
grid_inter.attach(&app_window, 0, 0, 5, app_store_size as i32);
|
||||
}
|
||||
|
||||
pub fn get_alpm_handle(&self) -> &alpm::Alpm {
|
||||
&self.alpm_handle
|
||||
}
|
||||
}
|
||||
|
||||
fn treeview_cell_app_data_function(
|
||||
_column: >k::TreeViewColumn,
|
||||
renderer_cell: >k::CellRenderer,
|
||||
model: >k::TreeModel,
|
||||
iter_a: >k::TreeIter,
|
||||
) {
|
||||
let value_gobj = model.value(iter_a, INSTALLED as i32);
|
||||
let value = value_gobj.get::<bool>().unwrap();
|
||||
if value {
|
||||
renderer_cell.set_width(600);
|
||||
} else {
|
||||
renderer_cell.set_width(400);
|
||||
}
|
||||
}
|
||||
|
||||
fn treeview_cell_check_data_function(
|
||||
_column: >k::TreeViewColumn,
|
||||
renderer_cell: >k::CellRenderer,
|
||||
model: >k::TreeModel,
|
||||
iter_a: >k::TreeIter,
|
||||
) {
|
||||
let value_gobj = model.value(iter_a, GROUP as i32);
|
||||
let value = value_gobj.get::<&str>().is_ok();
|
||||
renderer_cell.set_visible(!value);
|
||||
}
|
||||
|
||||
fn on_reload_clicked(_button: >k::Button) {
|
||||
let app_browser = unsafe { &mut G_APP_BROWSER.lock().unwrap() };
|
||||
app_browser.reload_app_data(false);
|
||||
}
|
||||
|
||||
fn on_group_filter_changed(combo: >k::ComboBox) {
|
||||
let app_browser = unsafe { &mut G_APP_BROWSER.lock().unwrap() };
|
||||
if let Some(tree_iter) = combo.active_iter() {
|
||||
let model = combo.model().unwrap();
|
||||
let group_gobj = model.value(&tree_iter, 0);
|
||||
let group = group_gobj.get::<&str>().unwrap();
|
||||
app_browser.group_tofilter = String::from(group);
|
||||
app_browser.app_store.clear();
|
||||
app_browser.load_app_data();
|
||||
app_browser.tree_view.set_model(Some(&app_browser.app_store));
|
||||
if group != "*" {
|
||||
app_browser.tree_view.expand_all();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_advanced_clicked(button: >k::ToggleButton) {
|
||||
let app_browser = unsafe { &mut G_APP_BROWSER.lock().unwrap() };
|
||||
let is_active = button.is_active();
|
||||
app_browser.filter = is_active;
|
||||
app_browser.reload_app_data(false);
|
||||
}
|
||||
|
||||
fn on_query_tooltip_tree_view(
|
||||
treeview: >k::TreeView,
|
||||
x_f: i32,
|
||||
y_f: i32,
|
||||
keyboard_tip: bool,
|
||||
tooltip: >k::Tooltip,
|
||||
) -> bool {
|
||||
let mut x = x_f;
|
||||
let mut y = y_f;
|
||||
let tooltip_context = treeview.tooltip_context(&mut x, &mut y, keyboard_tip);
|
||||
if let Some((model_tmp, path, iter_a)) = tooltip_context {
|
||||
let model = model_tmp.unwrap();
|
||||
let value_gobj = model.value(&iter_a, INSTALLED as i32);
|
||||
let value = value_gobj.get::<bool>();
|
||||
if value.is_ok() && value.unwrap() {
|
||||
let mut msg = String::from("Installed");
|
||||
let active_gobj = model.value(&iter_a, ACTIVE as i32);
|
||||
let active = active_gobj.get::<bool>();
|
||||
if active.is_ok() && !active.unwrap() {
|
||||
msg.push_str(" , to remove");
|
||||
}
|
||||
tooltip.set_markup(Some(msg.as_str()));
|
||||
treeview.set_tooltip_row(tooltip, &path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn on_app_toggle(_cell: >k::CellRendererToggle, path: gtk::TreePath) {
|
||||
let app_browser = unsafe { &mut G_APP_BROWSER.lock().unwrap() };
|
||||
let app_store = app_browser.app_store.clone();
|
||||
let iter_a = app_store.iter(&path).unwrap();
|
||||
let value_gobj = app_store.value(&iter_a, PACKAGE as i32);
|
||||
|
||||
// a group has no package attached and we don't install groups
|
||||
if value_gobj.get::<&str>().is_ok() {
|
||||
let toggle_a = app_store.value(&iter_a, ACTIVE as i32).get::<bool>().unwrap();
|
||||
app_store.set(&iter_a, &[(ACTIVE, &!toggle_a)]);
|
||||
|
||||
let alpm_handle = app_browser.get_alpm_handle();
|
||||
let update_system_button = app_browser.update_system_btn.clone();
|
||||
let localdb = alpm_handle.localdb();
|
||||
let pkg = app_store.value(&iter_a, PACKAGE as i32).get::<String>().unwrap();
|
||||
|
||||
let installed = localdb.pkg(pkg.clone()).is_ok();
|
||||
// update lists
|
||||
app_browser.alpm_helper.set_package(&pkg, !toggle_a, installed);
|
||||
update_system_button.set_sensitive(!app_browser.alpm_helper.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
fn on_update_system_clicked(_: >k::Button) {
|
||||
let app_browser = unsafe { &mut G_APP_BROWSER.lock().unwrap() };
|
||||
if app_browser.alpm_helper.do_update() != AlpmHelperResult::NOTHING {
|
||||
// reload json for view new apps installed
|
||||
app_browser.reload_app_data(true);
|
||||
}
|
||||
}
|
||||
|
||||
fn load_groups_data(groups: &serde_json::Value) -> gtk::ListStore {
|
||||
// not use data set for the moment
|
||||
let store = gtk::ListStore::new(&[String::static_type()]);
|
||||
store.set(&store.append(), &[(0, &String::from("*"))]);
|
||||
|
||||
for group in groups.as_array().unwrap() {
|
||||
let g_name = String::from(group["name"].as_str().unwrap());
|
||||
store.set(&store.append(), &[(0, &String::from(g_name))]);
|
||||
}
|
||||
|
||||
store
|
||||
}
|
||||
|
||||
fn create_column(
|
||||
title: &str,
|
||||
cell: &impl IsA<gtk::CellRenderer>,
|
||||
attr: &str,
|
||||
val: u32,
|
||||
) -> gtk::TreeViewColumn {
|
||||
let column = gtk::TreeViewColumn::new();
|
||||
column.set_title(title);
|
||||
column.pack_start(cell, true);
|
||||
column.add_attribute(cell, attr, val as i32);
|
||||
|
||||
column
|
||||
}
|
281
src/main.rs
281
src/main.rs
|
@ -2,8 +2,11 @@
|
|||
#![feature(const_str_from_utf8)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
mod alpm_helper;
|
||||
mod application_browser;
|
||||
mod config;
|
||||
mod data_types;
|
||||
mod pages;
|
||||
mod utils;
|
||||
|
||||
use config::{APP_ID, GETTEXT_PACKAGE, LOCALEDIR, PKGDATADIR, PROFILE, VERSION};
|
||||
|
@ -12,9 +15,8 @@ use gettextrs::LocaleCategory;
|
|||
use gtk::{gio, glib, Builder, HeaderBar, Window};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Write as _;
|
||||
use std::path::Path;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use utils::*;
|
||||
|
||||
use gio::prelude::*;
|
||||
|
@ -23,14 +25,10 @@ use gtk::prelude::*;
|
|||
use gdk_pixbuf::Pixbuf;
|
||||
|
||||
use serde_json::json;
|
||||
use std::sync::Arc;
|
||||
use std::{fs, str};
|
||||
use subprocess::{Exec, Redirection};
|
||||
use subprocess::Exec;
|
||||
|
||||
static mut g_save_json: Lazy<Mutex<serde_json::Value>> = Lazy::new(|| Mutex::new(json!(null)));
|
||||
static mut g_local_units: Lazy<Mutex<SystemdUnits>> = Lazy::new(|| Mutex::new(SystemdUnits::new()));
|
||||
static mut g_global_units: Lazy<Mutex<SystemdUnits>> =
|
||||
Lazy::new(|| Mutex::new(SystemdUnits::new()));
|
||||
|
||||
static mut g_hello_window: Option<Arc<HelloWindow>> = None;
|
||||
|
||||
|
@ -71,84 +69,6 @@ fn quick_message(message: &str) {
|
|||
}
|
||||
}
|
||||
|
||||
fn create_options_section() -> gtk::Box {
|
||||
let topbox = gtk::Box::new(gtk::Orientation::Vertical, 2);
|
||||
let box_collection = gtk::Box::new(gtk::Orientation::Horizontal, 10);
|
||||
let label = gtk::Label::new(None);
|
||||
label.set_line_wrap(true);
|
||||
label.set_justify(gtk::Justification::Center);
|
||||
label.set_text("Tweaks");
|
||||
|
||||
let psd_btn = gtk::CheckButton::with_label("Profile-sync-daemon enable");
|
||||
let systemd_oomd_btn = gtk::CheckButton::with_label("Systemd-oomd enabled");
|
||||
let apparmor_btn = gtk::CheckButton::with_label("Apparmor enabled");
|
||||
let ananicy_cpp_btn = gtk::CheckButton::with_label("Ananicy Cpp enabled");
|
||||
|
||||
unsafe {
|
||||
psd_btn.set_data("actionData", "psd.service");
|
||||
psd_btn.set_data("actionType", "user_service");
|
||||
systemd_oomd_btn.set_data("actionData", "systemd-oomd.service");
|
||||
systemd_oomd_btn.set_data("actionType", "service");
|
||||
apparmor_btn.set_data("actionData", "apparmor.service");
|
||||
apparmor_btn.set_data("actionType", "service");
|
||||
ananicy_cpp_btn.set_data("actionData", "ananicy-cpp.service");
|
||||
ananicy_cpp_btn.set_data("actionType", "service");
|
||||
}
|
||||
|
||||
for btn in &[&psd_btn, &systemd_oomd_btn, &apparmor_btn, &ananicy_cpp_btn] {
|
||||
unsafe {
|
||||
let data: &str = *btn.data("actionData").unwrap().as_ptr();
|
||||
if g_local_units.lock().unwrap().enabled_units.contains(&String::from(data))
|
||||
|| g_global_units.lock().unwrap().enabled_units.contains(&String::from(data))
|
||||
{
|
||||
btn.set_active(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
psd_btn.connect_clicked(on_servbtn_clicked);
|
||||
systemd_oomd_btn.connect_clicked(on_servbtn_clicked);
|
||||
apparmor_btn.connect_clicked(on_servbtn_clicked);
|
||||
ananicy_cpp_btn.connect_clicked(on_servbtn_clicked);
|
||||
|
||||
topbox.pack_start(&label, true, false, 1);
|
||||
box_collection.pack_start(&psd_btn, true, false, 2);
|
||||
box_collection.pack_start(&systemd_oomd_btn, true, false, 2);
|
||||
box_collection.pack_start(&apparmor_btn, true, false, 2);
|
||||
box_collection.pack_start(&ananicy_cpp_btn, true, false, 2);
|
||||
box_collection.set_halign(gtk::Align::Fill);
|
||||
topbox.pack_start(&box_collection, true, false, 1);
|
||||
|
||||
topbox.set_hexpand(true);
|
||||
topbox
|
||||
}
|
||||
|
||||
fn create_apps_section() -> gtk::Box {
|
||||
let topbox = gtk::Box::new(gtk::Orientation::Vertical, 2);
|
||||
let box_collection = gtk::Box::new(gtk::Orientation::Horizontal, 10);
|
||||
let label = gtk::Label::new(None);
|
||||
label.set_line_wrap(true);
|
||||
label.set_justify(gtk::Justification::Center);
|
||||
label.set_text("Applications");
|
||||
|
||||
let cachyos_pi = gtk::Button::with_label("CachyOS PackageInstaller");
|
||||
let cachyos_km = gtk::Button::with_label("CachyOS Kernel Manager");
|
||||
|
||||
cachyos_pi.connect_clicked(on_appbtn_clicked);
|
||||
cachyos_km.connect_clicked(on_appbtn_clicked);
|
||||
|
||||
box_collection.pack_start(&cachyos_pi, true, true, 2);
|
||||
box_collection.pack_start(&cachyos_km, true, true, 2);
|
||||
|
||||
topbox.pack_start(&label, true, true, 2);
|
||||
|
||||
box_collection.set_halign(gtk::Align::Fill);
|
||||
topbox.pack_start(&box_collection, true, true, 0);
|
||||
|
||||
topbox.set_hexpand(true);
|
||||
topbox
|
||||
}
|
||||
|
||||
fn show_about_dialog() {
|
||||
let main_window: Window;
|
||||
unsafe {
|
||||
|
@ -364,50 +284,8 @@ fn build_ui(application: >k::Application) {
|
|||
let install: gtk::Button = builder.object("install").unwrap();
|
||||
install.set_visible(false);
|
||||
}
|
||||
let install: gtk::Button = builder.object("appBrowser").unwrap();
|
||||
install.set_visible(true);
|
||||
|
||||
load_enabled_units();
|
||||
load_global_enabled_units();
|
||||
|
||||
let viewport = gtk::Viewport::new(gtk::Adjustment::NONE, gtk::Adjustment::NONE);
|
||||
// let label = gtk::Label::new(None);
|
||||
// label.set_line_wrap(true);
|
||||
let image = gtk::Image::from_icon_name(Some("go-previous"), gtk::IconSize::Button);
|
||||
let back_btn = gtk::Button::new();
|
||||
back_btn.set_image(Some(&image));
|
||||
back_btn.set_widget_name("home");
|
||||
|
||||
back_btn.connect_clicked(glib::clone!(@weak builder => move |button| {
|
||||
let name = button.widget_name();
|
||||
let stack: gtk::Stack = builder.object("stack").unwrap();
|
||||
stack.set_visible_child_name(&format!("{}page", name));
|
||||
}));
|
||||
|
||||
let options_section_box = create_options_section();
|
||||
let apps_section_box = create_apps_section();
|
||||
|
||||
let grid = gtk::Grid::new();
|
||||
grid.set_hexpand(true);
|
||||
grid.set_margin_start(10);
|
||||
grid.set_margin_end(10);
|
||||
grid.set_margin_top(5);
|
||||
grid.set_margin_bottom(5);
|
||||
grid.attach(&back_btn, 0, 1, 1, 1);
|
||||
let box_collection = gtk::Box::new(gtk::Orientation::Vertical, 5);
|
||||
|
||||
box_collection.pack_start(&options_section_box, true, true, 5);
|
||||
box_collection.pack_start(&apps_section_box, true, true, 5);
|
||||
|
||||
box_collection.set_valign(gtk::Align::Center);
|
||||
box_collection.set_halign(gtk::Align::Center);
|
||||
grid.attach(&box_collection, 1, 2, 5, 1);
|
||||
viewport.add(&grid);
|
||||
viewport.show_all();
|
||||
|
||||
let stack: gtk::Stack = builder.object("stack").unwrap();
|
||||
let child_name = "appBrowserpage";
|
||||
stack.add_named(&viewport, child_name);
|
||||
pages::create_appbrowser_page(&builder);
|
||||
pages::create_tweaks_page(&builder);
|
||||
|
||||
// Show the UI
|
||||
main_window.show();
|
||||
|
@ -575,54 +453,6 @@ fn get_page(name: &str, preferences: &serde_json::Value, save: &serde_json::Valu
|
|||
fs::read_to_string(filename).unwrap()
|
||||
}
|
||||
|
||||
fn load_enabled_units() {
|
||||
unsafe {
|
||||
g_local_units.lock().unwrap().loaded_units.clear();
|
||||
g_local_units.lock().unwrap().enabled_units.clear();
|
||||
|
||||
let mut exec_out = Exec::shell("systemctl list-unit-files -q --no-pager | tr -s \" \"")
|
||||
.stdout(Redirection::Pipe)
|
||||
.capture()
|
||||
.unwrap()
|
||||
.stdout_str();
|
||||
exec_out.pop();
|
||||
|
||||
let service_list = exec_out.split('\n');
|
||||
|
||||
for service in service_list {
|
||||
let out: Vec<&str> = service.split(' ').collect();
|
||||
g_local_units.lock().unwrap().loaded_units.push(out[0].to_string());
|
||||
if out[1] == "enabled" {
|
||||
g_local_units.lock().unwrap().enabled_units.push(out[0].to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_global_enabled_units() {
|
||||
unsafe {
|
||||
g_global_units.lock().unwrap().loaded_units.clear();
|
||||
g_global_units.lock().unwrap().enabled_units.clear();
|
||||
|
||||
let mut exec_out =
|
||||
Exec::shell("systemctl --global list-unit-files -q --no-pager | tr -s \" \"")
|
||||
.stdout(Redirection::Pipe)
|
||||
.capture()
|
||||
.unwrap()
|
||||
.stdout_str();
|
||||
exec_out.pop();
|
||||
|
||||
let service_list = exec_out.split('\n');
|
||||
for service in service_list {
|
||||
let out: Vec<&str> = service.split(' ').collect();
|
||||
g_global_units.lock().unwrap().loaded_units.push(out[0].to_string());
|
||||
if out[1] == "enabled" {
|
||||
g_global_units.lock().unwrap().enabled_units.push(out[0].to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handlers
|
||||
fn on_languages_changed(param: &[glib::Value]) -> Option<glib::Value> {
|
||||
let widget = param[0].get::<gtk::ComboBox>().unwrap();
|
||||
|
@ -652,103 +482,6 @@ fn on_action_clicked(param: &[glib::Value]) -> Option<glib::Value> {
|
|||
};
|
||||
}
|
||||
|
||||
fn on_servbtn_clicked(button: >k::CheckButton) {
|
||||
// Get action data/type.
|
||||
let action_type: &str;
|
||||
let action_data: &str;
|
||||
unsafe {
|
||||
action_type = *button.data("actionType").unwrap().as_ptr();
|
||||
action_data = *button.data("actionData").unwrap().as_ptr();
|
||||
}
|
||||
|
||||
let (user_only, pkexec_only) =
|
||||
if action_type == "user_service" { ("--user", "--user $(logname)") } else { ("", "") };
|
||||
|
||||
let cmd: String;
|
||||
unsafe {
|
||||
let local_units = &g_local_units.lock().unwrap().enabled_units;
|
||||
cmd = if !local_units.contains(&String::from(action_data)) {
|
||||
format!(
|
||||
"/sbin/pkexec {} bash -c \"systemctl {} enable --now --force {}\"",
|
||||
pkexec_only, user_only, action_data
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"/sbin/pkexec {} bash -c \"systemctl {} disable --now {}\"",
|
||||
pkexec_only, user_only, action_data
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
// Spawn child process in separate thread.
|
||||
std::thread::spawn(move || {
|
||||
Exec::shell(cmd).join().unwrap();
|
||||
|
||||
if action_type == "user_service" {
|
||||
load_global_enabled_units();
|
||||
} else {
|
||||
load_enabled_units();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn on_appbtn_clicked(button: >k::Button) {
|
||||
// Get button label.
|
||||
let name = button.label().unwrap();
|
||||
let (binname, is_sudo) = if name == "CachyOS PackageInstaller" {
|
||||
("cachyos-pi-bin", true)
|
||||
} else if name == "CachyOS Kernel Manager" {
|
||||
("cachyos-kernel-manager", false)
|
||||
} else {
|
||||
("", false)
|
||||
};
|
||||
|
||||
// Check if executable exists.
|
||||
let exit_status = Exec::cmd("which").arg(binname).join().unwrap();
|
||||
if !exit_status.success() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut envs = String::new();
|
||||
for env in glib::listenv() {
|
||||
if env == "PATH" {
|
||||
envs += "PATH=/sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin ";
|
||||
continue;
|
||||
}
|
||||
let _ = write!(
|
||||
envs,
|
||||
"{}=\"{}\" ",
|
||||
env.to_str().unwrap(),
|
||||
glib::getenv(&env).unwrap().to_str().unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
// Get executable path.
|
||||
let mut exe_path =
|
||||
Exec::cmd("which").arg(binname).stdout(Redirection::Pipe).capture().unwrap().stdout_str();
|
||||
exe_path.pop();
|
||||
let bash_cmd = format!("{} {}", &envs, &exe_path);
|
||||
|
||||
// Create context channel.
|
||||
let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
||||
|
||||
// Spawn child process in separate thread.
|
||||
std::thread::spawn(move || {
|
||||
let exit_status = if is_sudo {
|
||||
Exec::cmd("/sbin/pkexec").arg("bash").arg("-c").arg(bash_cmd).join().unwrap()
|
||||
} else {
|
||||
Exec::shell(bash_cmd).join().unwrap()
|
||||
};
|
||||
tx.send(format!("Exit status successfully? = {:?}", exit_status.success()))
|
||||
.expect("Couldn't send data to channel");
|
||||
});
|
||||
|
||||
rx.attach(None, move |text| {
|
||||
println!("{}", text);
|
||||
glib::Continue(true)
|
||||
});
|
||||
}
|
||||
|
||||
fn on_btn_clicked(param: &[glib::Value]) -> Option<glib::Value> {
|
||||
let widget = param[0].get::<gtk::Button>().unwrap();
|
||||
let name = widget.widget_name();
|
||||
|
|
|
@ -0,0 +1,388 @@
|
|||
// extern crate gtk;
|
||||
|
||||
use crate::application_browser::ApplicationBrowser;
|
||||
use crate::data_types::*;
|
||||
use gtk::{glib, Builder};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::fmt::Write as _;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use gtk::prelude::*;
|
||||
|
||||
use std::str;
|
||||
use subprocess::{Exec, Redirection};
|
||||
// static mut g_app_browser: Lazy<Mutex<ApplicationBrowser>> =
|
||||
// Lazy::new(|| Mutex::new(ApplicationBrowser::new()));
|
||||
|
||||
// pub fn create_appbrowser_page() -> gtk::Box {
|
||||
// NOTE: we might not even need that here
|
||||
// let app_browser_box = ApplicationBrowser::default_impl().create_page();
|
||||
// let app_browser_box = ApplicationBrowser::default_impl().lock().expect("Initialization
|
||||
// failed!").create_page();
|
||||
|
||||
// let app_browser_box = gtk::Box::new(gtk::Orientation::Vertical, 10);
|
||||
// app_browser_box.set_expand(true);
|
||||
|
||||
// let button_box = gtk::Box::new(gtk::Orientation::Horizontal, 10);
|
||||
// let advanced_button = gtk::Button::with_label("advanced");
|
||||
// advanced_button.set_tooltip_text(Some("Toggle an extended selection of packages"));
|
||||
// advanced_button.connect_clicked(on_advanced_clicked);
|
||||
// let download_button = gtk::Button::with_label("download");
|
||||
// download_button.set_tooltip_text(Some("Download the most recent selection of packages"));
|
||||
// download_button.connect_clicked(on_download_clicked);
|
||||
// let reset_button = gtk::Button::with_label("reset");
|
||||
// reset_button.set_tooltip_text(Some("Reset your current selections..."));
|
||||
// reset_button.connect_clicked(on_reload_clicked);
|
||||
// let update_system_button = unsafe { g_app_browser.lock().unwrap().update_system_btn };
|
||||
|
||||
// Group filter
|
||||
// let data = fs::read_to_string(format!("{}/data/application_utility/default.json",
|
||||
// PKGDATADIR)) .expect("Unable to read file");
|
||||
// let groups: serde_json::Value = serde_json::from_str(&data).expect("Unable to parse");
|
||||
// let group_store = load_groups_data(&groups);
|
||||
// let group_combo = utils::create_combo_with_model(&group_store);
|
||||
|
||||
// Packing button box
|
||||
// button_box.pack_start(&advanced_button, false, false, 10);
|
||||
// button_box.pack_start(&group_combo, false, false, 10);
|
||||
// button_box.pack_end(&update_system_button, false, false, 10);
|
||||
|
||||
// button_box.pack_end(&reset_button, false, false, 10);
|
||||
// button_box.pack_end(&download_button, false, false, 10);
|
||||
// app_browser_box.pack_start(&button_box, false, false, 10);
|
||||
|
||||
// create view and app store
|
||||
// let (tree_view, app_store_size) = create_view_tree(&groups);
|
||||
|
||||
// create a scrollable window
|
||||
// let app_window = gtk::ScrolledWindow::new(gtk::Adjustment::NONE, gtk::Adjustment::NONE);
|
||||
// app_window.set_vexpand(true);
|
||||
// app_window.set_policy(gtk::PolicyType::Never, gtk::PolicyType::Automatic);
|
||||
// add window to tree view
|
||||
// app_window.add(&tree_view);
|
||||
|
||||
// // setup grid
|
||||
// let grid_inter = gtk::Grid::new();
|
||||
// grid_inter.set_column_homogeneous(true);
|
||||
// grid_inter.set_row_homogeneous(true);
|
||||
// // add grid to app browser
|
||||
// app_browser_box.add(&grid_inter);
|
||||
// grid_inter.attach(&app_window, 0, 0, 5, app_store_size as i32);
|
||||
//
|
||||
// app_browser_box
|
||||
// gtk::Box::new(gtk::Orientation::Vertical, 10)
|
||||
//}
|
||||
|
||||
static mut g_local_units: Lazy<Mutex<SystemdUnits>> = Lazy::new(|| Mutex::new(SystemdUnits::new()));
|
||||
static mut g_global_units: Lazy<Mutex<SystemdUnits>> =
|
||||
Lazy::new(|| Mutex::new(SystemdUnits::new()));
|
||||
|
||||
fn create_options_section() -> gtk::Box {
|
||||
let topbox = gtk::Box::new(gtk::Orientation::Vertical, 2);
|
||||
let box_collection = gtk::Box::new(gtk::Orientation::Horizontal, 10);
|
||||
let label = gtk::Label::new(None);
|
||||
label.set_line_wrap(true);
|
||||
label.set_justify(gtk::Justification::Center);
|
||||
label.set_text("Tweaks");
|
||||
|
||||
let psd_btn = gtk::CheckButton::with_label("Profile-sync-daemon enable");
|
||||
let systemd_oomd_btn = gtk::CheckButton::with_label("Systemd-oomd enabled");
|
||||
let apparmor_btn = gtk::CheckButton::with_label("Apparmor enabled");
|
||||
let ananicy_cpp_btn = gtk::CheckButton::with_label("Ananicy Cpp enabled");
|
||||
|
||||
unsafe {
|
||||
psd_btn.set_data("actionData", "psd.service");
|
||||
psd_btn.set_data("actionType", "user_service");
|
||||
systemd_oomd_btn.set_data("actionData", "systemd-oomd.service");
|
||||
systemd_oomd_btn.set_data("actionType", "service");
|
||||
apparmor_btn.set_data("actionData", "apparmor.service");
|
||||
apparmor_btn.set_data("actionType", "service");
|
||||
ananicy_cpp_btn.set_data("actionData", "ananicy-cpp.service");
|
||||
ananicy_cpp_btn.set_data("actionType", "service");
|
||||
}
|
||||
|
||||
for btn in &[&psd_btn, &systemd_oomd_btn, &apparmor_btn, &ananicy_cpp_btn] {
|
||||
unsafe {
|
||||
let data: &str = *btn.data("actionData").unwrap().as_ptr();
|
||||
if g_local_units.lock().unwrap().enabled_units.contains(&String::from(data))
|
||||
|| g_global_units.lock().unwrap().enabled_units.contains(&String::from(data))
|
||||
{
|
||||
btn.set_active(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
psd_btn.connect_clicked(on_servbtn_clicked);
|
||||
systemd_oomd_btn.connect_clicked(on_servbtn_clicked);
|
||||
apparmor_btn.connect_clicked(on_servbtn_clicked);
|
||||
ananicy_cpp_btn.connect_clicked(on_servbtn_clicked);
|
||||
|
||||
topbox.pack_start(&label, true, false, 1);
|
||||
box_collection.pack_start(&psd_btn, true, false, 2);
|
||||
box_collection.pack_start(&systemd_oomd_btn, true, false, 2);
|
||||
box_collection.pack_start(&apparmor_btn, true, false, 2);
|
||||
box_collection.pack_start(&ananicy_cpp_btn, true, false, 2);
|
||||
box_collection.set_halign(gtk::Align::Fill);
|
||||
topbox.pack_start(&box_collection, true, false, 1);
|
||||
|
||||
topbox.set_hexpand(true);
|
||||
topbox
|
||||
}
|
||||
|
||||
fn create_apps_section() -> gtk::Box {
|
||||
let topbox = gtk::Box::new(gtk::Orientation::Vertical, 2);
|
||||
let box_collection = gtk::Box::new(gtk::Orientation::Horizontal, 10);
|
||||
let label = gtk::Label::new(None);
|
||||
label.set_line_wrap(true);
|
||||
label.set_justify(gtk::Justification::Center);
|
||||
label.set_text("Applications");
|
||||
|
||||
let cachyos_pi = gtk::Button::with_label("CachyOS PackageInstaller");
|
||||
let cachyos_km = gtk::Button::with_label("CachyOS Kernel Manager");
|
||||
|
||||
cachyos_pi.connect_clicked(on_appbtn_clicked);
|
||||
cachyos_km.connect_clicked(on_appbtn_clicked);
|
||||
|
||||
box_collection.pack_start(&cachyos_pi, true, true, 2);
|
||||
box_collection.pack_start(&cachyos_km, true, true, 2);
|
||||
|
||||
topbox.pack_start(&label, true, true, 2);
|
||||
|
||||
box_collection.set_halign(gtk::Align::Fill);
|
||||
topbox.pack_start(&box_collection, true, true, 0);
|
||||
|
||||
topbox.set_hexpand(true);
|
||||
topbox
|
||||
}
|
||||
|
||||
fn load_enabled_units() {
|
||||
unsafe {
|
||||
g_local_units.lock().unwrap().loaded_units.clear();
|
||||
g_local_units.lock().unwrap().enabled_units.clear();
|
||||
|
||||
let mut exec_out = Exec::shell("systemctl list-unit-files -q --no-pager | tr -s \" \"")
|
||||
.stdout(Redirection::Pipe)
|
||||
.capture()
|
||||
.unwrap()
|
||||
.stdout_str();
|
||||
exec_out.pop();
|
||||
|
||||
let service_list = exec_out.split('\n');
|
||||
|
||||
for service in service_list {
|
||||
let out: Vec<&str> = service.split(' ').collect();
|
||||
g_local_units.lock().unwrap().loaded_units.push(out[0].to_string());
|
||||
if out[1] == "enabled" {
|
||||
g_local_units.lock().unwrap().enabled_units.push(out[0].to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_global_enabled_units() {
|
||||
unsafe {
|
||||
g_global_units.lock().unwrap().loaded_units.clear();
|
||||
g_global_units.lock().unwrap().enabled_units.clear();
|
||||
|
||||
let mut exec_out =
|
||||
Exec::shell("systemctl --global list-unit-files -q --no-pager | tr -s \" \"")
|
||||
.stdout(Redirection::Pipe)
|
||||
.capture()
|
||||
.unwrap()
|
||||
.stdout_str();
|
||||
exec_out.pop();
|
||||
|
||||
let service_list = exec_out.split('\n');
|
||||
for service in service_list {
|
||||
let out: Vec<&str> = service.split(' ').collect();
|
||||
g_global_units.lock().unwrap().loaded_units.push(out[0].to_string());
|
||||
if out[1] == "enabled" {
|
||||
g_global_units.lock().unwrap().enabled_units.push(out[0].to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_tweaks_page(builder: &Builder) {
|
||||
let install: gtk::Button = builder.object("tweaksBrowser").unwrap();
|
||||
install.set_visible(true);
|
||||
|
||||
load_enabled_units();
|
||||
load_global_enabled_units();
|
||||
|
||||
let viewport = gtk::Viewport::new(gtk::Adjustment::NONE, gtk::Adjustment::NONE);
|
||||
// let label = gtk::Label::new(None);
|
||||
// label.set_line_wrap(true);
|
||||
let image = gtk::Image::from_icon_name(Some("go-previous"), gtk::IconSize::Button);
|
||||
let back_btn = gtk::Button::new();
|
||||
back_btn.set_image(Some(&image));
|
||||
back_btn.set_widget_name("home");
|
||||
|
||||
back_btn.connect_clicked(glib::clone!(@weak builder => move |button| {
|
||||
let name = button.widget_name();
|
||||
let stack: gtk::Stack = builder.object("stack").unwrap();
|
||||
stack.set_visible_child_name(&format!("{}page", name));
|
||||
}));
|
||||
|
||||
let options_section_box = create_options_section();
|
||||
let apps_section_box = create_apps_section();
|
||||
|
||||
let grid = gtk::Grid::new();
|
||||
grid.set_hexpand(true);
|
||||
grid.set_margin_start(10);
|
||||
grid.set_margin_end(10);
|
||||
grid.set_margin_top(5);
|
||||
grid.set_margin_bottom(5);
|
||||
grid.attach(&back_btn, 0, 1, 1, 1);
|
||||
let box_collection = gtk::Box::new(gtk::Orientation::Vertical, 5);
|
||||
|
||||
box_collection.pack_start(&options_section_box, true, true, 5);
|
||||
box_collection.pack_start(&apps_section_box, true, true, 5);
|
||||
|
||||
box_collection.set_valign(gtk::Align::Center);
|
||||
box_collection.set_halign(gtk::Align::Center);
|
||||
grid.attach(&box_collection, 1, 2, 5, 1);
|
||||
viewport.add(&grid);
|
||||
viewport.show_all();
|
||||
|
||||
let stack: gtk::Stack = builder.object("stack").unwrap();
|
||||
let child_name = "tweaksBrowserpage";
|
||||
stack.add_named(&viewport, child_name);
|
||||
}
|
||||
|
||||
pub fn create_appbrowser_page(builder: &Builder) {
|
||||
let install: gtk::Button = builder.object("appBrowser").unwrap();
|
||||
install.set_visible(true);
|
||||
|
||||
let viewport = gtk::Viewport::new(gtk::Adjustment::NONE, gtk::Adjustment::NONE);
|
||||
// let label = gtk::Label::new(None);
|
||||
// label.set_line_wrap(true);
|
||||
let image = gtk::Image::from_icon_name(Some("go-previous"), gtk::IconSize::Button);
|
||||
let back_btn = gtk::Button::new();
|
||||
back_btn.set_image(Some(&image));
|
||||
back_btn.set_widget_name("home");
|
||||
|
||||
back_btn.connect_clicked(glib::clone!(@weak builder => move |button| {
|
||||
let name = button.widget_name();
|
||||
let stack: gtk::Stack = builder.object("stack").unwrap();
|
||||
stack.set_visible_child_name(&format!("{}page", name));
|
||||
}));
|
||||
|
||||
let grid = gtk::Grid::new();
|
||||
grid.set_hexpand(true);
|
||||
grid.set_margin_start(10);
|
||||
grid.set_margin_end(10);
|
||||
grid.set_margin_top(5);
|
||||
grid.set_margin_bottom(5);
|
||||
grid.attach(&back_btn, 0, 1, 1, 1);
|
||||
|
||||
let app_browser_ref = ApplicationBrowser::default_impl().lock().unwrap();
|
||||
let app_browser_box = app_browser_ref.get_page();
|
||||
grid.attach(app_browser_box, 0, 2, 1, 1);
|
||||
|
||||
// Add grid to the viewport
|
||||
// NOTE: we might eliminate that?
|
||||
viewport.add(&grid);
|
||||
viewport.show_all();
|
||||
|
||||
let stack: gtk::Stack = builder.object("stack").unwrap();
|
||||
let child_name = "appBrowserpage";
|
||||
stack.add_named(&viewport, child_name);
|
||||
}
|
||||
|
||||
fn on_servbtn_clicked(button: >k::CheckButton) {
|
||||
// Get action data/type.
|
||||
let action_type: &str;
|
||||
let action_data: &str;
|
||||
unsafe {
|
||||
action_type = *button.data("actionType").unwrap().as_ptr();
|
||||
action_data = *button.data("actionData").unwrap().as_ptr();
|
||||
}
|
||||
|
||||
let (user_only, pkexec_only) =
|
||||
if action_type == "user_service" { ("--user", "--user $(logname)") } else { ("", "") };
|
||||
|
||||
let cmd: String;
|
||||
unsafe {
|
||||
let local_units = &g_local_units.lock().unwrap().enabled_units;
|
||||
cmd = if !local_units.contains(&String::from(action_data)) {
|
||||
format!(
|
||||
"/sbin/pkexec {} bash -c \"systemctl {} enable --now --force {}\"",
|
||||
pkexec_only, user_only, action_data
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"/sbin/pkexec {} bash -c \"systemctl {} disable --now {}\"",
|
||||
pkexec_only, user_only, action_data
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
// Spawn child process in separate thread.
|
||||
std::thread::spawn(move || {
|
||||
Exec::shell(cmd).join().unwrap();
|
||||
|
||||
if action_type == "user_service" {
|
||||
load_global_enabled_units();
|
||||
} else {
|
||||
load_enabled_units();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn on_appbtn_clicked(button: >k::Button) {
|
||||
// Get button label.
|
||||
let name = button.label().unwrap();
|
||||
let (binname, is_sudo) = if name == "CachyOS PackageInstaller" {
|
||||
("cachyos-pi-bin", true)
|
||||
} else if name == "CachyOS Kernel Manager" {
|
||||
("cachyos-kernel-manager", false)
|
||||
} else {
|
||||
("", false)
|
||||
};
|
||||
|
||||
// Check if executable exists.
|
||||
let exit_status = Exec::cmd("which").arg(binname).join().unwrap();
|
||||
if !exit_status.success() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut envs = String::new();
|
||||
for env in glib::listenv() {
|
||||
if env == "PATH" {
|
||||
envs += "PATH=/sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin ";
|
||||
continue;
|
||||
}
|
||||
let _ = write!(
|
||||
envs,
|
||||
"{}=\"{}\" ",
|
||||
env.to_str().unwrap(),
|
||||
glib::getenv(&env).unwrap().to_str().unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
// Get executable path.
|
||||
let mut exe_path =
|
||||
Exec::cmd("which").arg(binname).stdout(Redirection::Pipe).capture().unwrap().stdout_str();
|
||||
exe_path.pop();
|
||||
let bash_cmd = format!("{} {}", &envs, &exe_path);
|
||||
|
||||
// Create context channel.
|
||||
let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
||||
|
||||
// Spawn child process in separate thread.
|
||||
std::thread::spawn(move || {
|
||||
let exit_status = if is_sudo {
|
||||
Exec::cmd("/sbin/pkexec").arg("bash").arg("-c").arg(bash_cmd).join().unwrap()
|
||||
} else {
|
||||
Exec::shell(bash_cmd).join().unwrap()
|
||||
};
|
||||
tx.send(format!("Exit status successfully? = {:?}", exit_status.success()))
|
||||
.expect("Couldn't send data to channel");
|
||||
});
|
||||
|
||||
rx.attach(None, move |text| {
|
||||
println!("{}", text);
|
||||
glib::Continue(true)
|
||||
});
|
||||
}
|
11
src/utils.rs
11
src/utils.rs
|
@ -1,3 +1,4 @@
|
|||
use gtk::prelude::*;
|
||||
use std::fs::File;
|
||||
use std::{fs, slice, str};
|
||||
|
||||
|
@ -54,6 +55,16 @@ pub fn check_regular_file(path: &str) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn create_combo_with_model(group_store: >k::ListStore) -> gtk::ComboBox {
|
||||
let group_combo = gtk::ComboBox::with_model(group_store);
|
||||
let combo_renderer = gtk::CellRendererText::new();
|
||||
group_combo.pack_start(&combo_renderer, true);
|
||||
group_combo.add_attribute(&combo_renderer, "text", 0);
|
||||
group_combo.set_active(Some(0));
|
||||
|
||||
group_combo
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
|
|
@ -425,10 +425,27 @@ We, the CachyOS Developers, hope that you will enjoy using CachyOS as much as we
|
|||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="appBrowser">
|
||||
<property name="label" translatable="yes">Apps/Tweaks</property>
|
||||
<property name="label" translatable="yes">Install Apps</property>
|
||||
<property name="name">appBrowser</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="tooltip-text" translatable="yes">Install Apps</property>
|
||||
<property name="margin-left">15</property>
|
||||
<property name="margin-right">15</property>
|
||||
<signal name="clicked" handler="on_btn_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="tweaksBrowser">
|
||||
<property name="label" translatable="yes">Apps/Tweaks</property>
|
||||
<property name="name">tweaksBrowser</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="tooltip-text" translatable="yes">Apps/Tweaks</property>
|
||||
<property name="margin-left">15</property>
|
||||
<property name="margin-right">15</property>
|
||||
|
|
Loading…
Reference in New Issue