mirror of
https://github.com/moons-14/dotfiles.git
synced 2026-10-06 04:08:12 +09:00
feat
This commit is contained in:
@@ -125,7 +125,7 @@ in
|
|||||||
(execute "W-l" "loginctl lock-session")
|
(execute "W-l" "loginctl lock-session")
|
||||||
(execute "W-v" "vicinae vicinae://launch/clipboard/history?toggle=true")
|
(execute "W-v" "vicinae vicinae://launch/clipboard/history?toggle=true")
|
||||||
(execute "W-j" "nani-translate-primary")
|
(execute "W-j" "nani-translate-primary")
|
||||||
(execute "W-S-j" "normcap-translate")
|
(execute "W-S-j" "nani-translate-ocr")
|
||||||
(execute "W-C-j" "${lib.getExe' pkgs.xdg-utils "xdg-open"} naniapp://translate")
|
(execute "W-C-j" "${lib.getExe' pkgs.xdg-utils "xdg-open"} naniapp://translate")
|
||||||
(execute "W-space" "ghostty +toggle-quick-terminal")
|
(execute "W-space" "ghostty +toggle-quick-terminal")
|
||||||
(execute "W-p" "wdisplays")
|
(execute "W-p" "wdisplays")
|
||||||
|
|||||||
@@ -1,5 +1,78 @@
|
|||||||
_: {
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
tessdataBest = pkgs.runCommand "tessdata-best-jpn-eng-chi-sim" { } ''
|
||||||
|
mkdir -p "$out"
|
||||||
|
ln -s ${
|
||||||
|
pkgs.fetchurl {
|
||||||
|
url = "https://github.com/tesseract-ocr/tessdata_best/raw/main/jpn.traineddata";
|
||||||
|
hash = "sha256-Nr35rII/WRHmJMMNBVPokLirx8MaZbPvFNqUNljEC3k=";
|
||||||
|
}
|
||||||
|
} "$out/jpn.traineddata"
|
||||||
|
ln -s ${
|
||||||
|
pkgs.fetchurl {
|
||||||
|
url = "https://github.com/tesseract-ocr/tessdata_best/raw/main/eng.traineddata";
|
||||||
|
hash = "sha256-goCu0Hgv4nJXpo6hD+fvMkyg+Nhb0v0UXRwrVgvLZro=";
|
||||||
|
}
|
||||||
|
} "$out/eng.traineddata"
|
||||||
|
ln -s ${
|
||||||
|
pkgs.fetchurl {
|
||||||
|
url = "https://github.com/tesseract-ocr/tessdata_best/raw/main/chi_sim.traineddata";
|
||||||
|
hash = "sha256-T+8tEwbI6HYW1NPkxsZ/r11EvjNCKQz48vD246p+c1s=";
|
||||||
|
}
|
||||||
|
} "$out/chi_sim.traineddata"
|
||||||
|
'';
|
||||||
|
|
||||||
|
tesseract = pkgs.tesseract5.override {
|
||||||
|
tessdata = tessdataBest;
|
||||||
|
};
|
||||||
|
|
||||||
|
naniTranslatePrimary = pkgs.writeShellApplication {
|
||||||
|
name = "nani-translate-primary";
|
||||||
|
|
||||||
|
runtimeInputs = with pkgs; [
|
||||||
|
jq
|
||||||
|
wl-clipboard
|
||||||
|
xdg-utils
|
||||||
|
];
|
||||||
|
|
||||||
|
text = ''
|
||||||
|
selected_text="$(wl-paste --primary --no-newline)" || exit 0
|
||||||
|
[ -n "$selected_text" ] || exit 0
|
||||||
|
encoded_text="$(printf '%s' "$selected_text" | jq -sRr @uri)"
|
||||||
|
exec xdg-open "naniapp://translate?source=$encoded_text"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
naniTranslateOcr = pkgs.writeShellApplication {
|
||||||
|
name = "nani-translate-ocr";
|
||||||
|
|
||||||
|
runtimeInputs = with pkgs; [
|
||||||
|
grim
|
||||||
|
jq
|
||||||
|
slurp
|
||||||
|
tesseract
|
||||||
|
xdg-utils
|
||||||
|
];
|
||||||
|
|
||||||
|
text = ''
|
||||||
|
geometry="$(slurp)" || exit 0
|
||||||
|
captured_text="$(
|
||||||
|
grim -g "$geometry" - \
|
||||||
|
| tesseract stdin stdout -l jpn+eng+chi_sim --oem 1 --psm 6
|
||||||
|
)"
|
||||||
|
[ -n "$captured_text" ] || exit 0
|
||||||
|
encoded_text="$(printf '%s' "$captured_text" | jq -sRr @uri)"
|
||||||
|
exec xdg-open "naniapp://translate?source=$encoded_text"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
programs.naniTranslateLinux.enable = true;
|
programs.naniTranslateLinux.enable = true;
|
||||||
|
|
||||||
xdg.mimeApps.defaultApplications."x-scheme-handler/naniapp" = "nani.desktop";
|
xdg.mimeApps.defaultApplications."x-scheme-handler/naniapp" = "nani.desktop";
|
||||||
|
|
||||||
|
home.packages = [
|
||||||
|
naniTranslatePrimary
|
||||||
|
naniTranslateOcr
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,8 @@
|
|||||||
{ lib, pkgs, ... }:
|
{ lib, pkgs, ... }:
|
||||||
let
|
let
|
||||||
keybindings = import ./keybindings.nix;
|
keybindings = import ./keybindings.nix;
|
||||||
naniTranslatePrimary = pkgs.writeShellApplication {
|
|
||||||
name = "nani-translate-primary";
|
|
||||||
runtimeInputs = with pkgs; [
|
|
||||||
jq
|
|
||||||
wl-clipboard
|
|
||||||
xdg-utils
|
|
||||||
];
|
|
||||||
text = ''
|
|
||||||
selected_text="$(wl-paste --primary --no-newline)" || exit 0
|
|
||||||
[ -n "$selected_text" ] || exit 0
|
|
||||||
encoded_text="$(printf '%s' "$selected_text" | jq -sRr @uri)"
|
|
||||||
exec xdg-open "naniapp://translate?source=$encoded_text"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
home.packages = [ naniTranslatePrimary ];
|
|
||||||
|
|
||||||
programs.niri.settings = {
|
programs.niri.settings = {
|
||||||
|
|
||||||
binds = keybindings // {
|
binds = keybindings // {
|
||||||
@@ -119,7 +103,7 @@ in
|
|||||||
};
|
};
|
||||||
"Mod+Shift+J" = {
|
"Mod+Shift+J" = {
|
||||||
repeat = false;
|
repeat = false;
|
||||||
action.spawn = [ "normcap-translate" ];
|
action.spawn = [ "nani-translate-ocr" ];
|
||||||
hotkey-overlay.title = "OCR and Translate with Nani";
|
hotkey-overlay.title = "OCR and Translate with Nani";
|
||||||
};
|
};
|
||||||
"Mod+Ctrl+J" = {
|
"Mod+Ctrl+J" = {
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
diff --git a/src/shell/bar/widgets/taskbar_widget.cpp b/src/shell/bar/widgets/taskbar_widget.cpp
|
||||||
|
--- a/src/shell/bar/widgets/taskbar_widget.cpp
|
||||||
|
+++ b/src/shell/bar/widgets/taskbar_widget.cpp
|
||||||
|
@@ -5,6 +5,7 @@
|
||||||
|
#include "compositors/workspace_backend.h"
|
||||||
|
#include "config/config_service.h"
|
||||||
|
#include "core/deferred_call.h"
|
||||||
|
+#include "core/process/process.h"
|
||||||
|
#include "i18n/i18n.h"
|
||||||
|
#include "render/core/color.h"
|
||||||
|
#include "render/core/renderer.h"
|
||||||
|
@@ -36,6 +37,18 @@
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
+ [[nodiscard]] bool launchTaskbarOverview(const std::string& appId) {
|
||||||
|
+ constexpr const char* command = "noctalia-taskbar-overview";
|
||||||
|
+ if (appId.empty() || !process::commandExists(command)) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ return process::runAsync({
|
||||||
|
+ command,
|
||||||
|
+ "--app-id",
|
||||||
|
+ appId.c_str(),
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// Integer centering; optional odd spare pixel on the end side (right/bottom).
|
||||||
|
[[nodiscard]] float centeredOffset(float extent, float content, float inset = 0.0F, bool oddSpareOnEnd = true) {
|
||||||
|
const float inner = std::max(0.0F, extent - inset * 2.0F);
|
||||||
|
@@ -373,6 +386,12 @@ void TaskbarWidget::activateOrLaunchPinned(const TaskModel& task) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ const std::string overviewAppId =
|
||||||
|
+ !task.appId.empty() ? task.appId : (!task.desktopEntryId.empty() ? task.desktopEntryId : task.idLower);
|
||||||
|
+ if (launchTaskbarOverview(overviewAppId)) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
const std::string cycleKey = !task.desktopEntryId.empty() ? task.desktopEntryId : task.idLower;
|
||||||
|
std::size_t& cursor = m_groupedAppCycleCursor[cycleKey];
|
||||||
|
if (cursor >= windows.size()) {
|
||||||
@@ -24,56 +24,3 @@ diff --git a/src/shell/switcher/window_switcher.cpp b/src/shell/switcher/window_
|
|||||||
if (key.empty()) {
|
if (key.empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
diff --git a/src/shell/bar/widgets/taskbar_widget.cpp b/src/shell/bar/widgets/taskbar_widget.cpp
|
|
||||||
--- a/src/shell/bar/widgets/taskbar_widget.cpp
|
|
||||||
+++ b/src/shell/bar/widgets/taskbar_widget.cpp
|
|
||||||
@@ -5,6 +5,7 @@
|
|
||||||
#include "compositors/workspace_backend.h"
|
|
||||||
#include "config/config_service.h"
|
|
||||||
#include "core/deferred_call.h"
|
|
||||||
+#include "core/process/process.h"
|
|
||||||
#include "i18n/i18n.h"
|
|
||||||
#include "render/core/color.h"
|
|
||||||
#include "render/core/renderer.h"
|
|
||||||
@@ -36,6 +37,18 @@
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
+ [[nodiscard]] bool launchTaskbarOverview(const std::string& appId) {
|
|
||||||
+ constexpr const char* command = "noctalia-taskbar-overview";
|
|
||||||
+ if (appId.empty() || !process::commandExists(command)) {
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+ return process::runAsync({
|
|
||||||
+ command,
|
|
||||||
+ "--app-id",
|
|
||||||
+ appId.c_str(),
|
|
||||||
+ });
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
// Integer centering; optional odd spare pixel on the end side (right/bottom).
|
|
||||||
[[nodiscard]] float centeredOffset(float extent, float content, float inset = 0.0F, bool oddSpareOnEnd = true) {
|
|
||||||
const float inner = std::max(0.0F, extent - inset * 2.0F);
|
|
||||||
@@ -373,6 +386,12 @@ void TaskbarWidget::activateOrLaunchPinned(const TaskModel& task) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ const std::string overviewAppId =
|
|
||||||
+ !task.appId.empty() ? task.appId : (!task.desktopEntryId.empty() ? task.desktopEntryId : task.idLower);
|
|
||||||
+ if (launchTaskbarOverview(overviewAppId)) {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
const std::string cycleKey = !task.desktopEntryId.empty() ? task.desktopEntryId : task.idLower;
|
|
||||||
std::size_t& cursor = m_groupedAppCycleCursor[cycleKey];
|
|
||||||
if (cursor >= windows.size()) {
|
|
||||||
@@ -792,6 +811,9 @@ void TaskbarWidget::create() {
|
|
||||||
}
|
|
||||||
if (data.button == BTN_LEFT) {
|
|
||||||
if (!cycleCandidates.empty()) {
|
|
||||||
+ if (cycleCandidates.size() > 1 && launchTaskbarOverview(current->appId)) {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
std::size_t& cursor = m_groupedAppCycleCursor[cycleKey];
|
|
||||||
if (cursor >= cycleCandidates.size()) {
|
|
||||||
cursor = 0;
|
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
let
|
|
||||||
normcap = pkgs.normcap.override {
|
|
||||||
tesseract4 = pkgs.tesseract4.override {
|
|
||||||
enableLanguages = [
|
|
||||||
"chi_sim"
|
|
||||||
"jpn"
|
|
||||||
"eng"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
normcapTranslate = pkgs.writeShellApplication {
|
|
||||||
name = "normcap-translate";
|
|
||||||
|
|
||||||
runtimeInputs = [
|
|
||||||
normcap
|
|
||||||
pkgs.jq
|
|
||||||
pkgs.xdg-utils
|
|
||||||
];
|
|
||||||
|
|
||||||
text = ''
|
|
||||||
captured_text="$(
|
|
||||||
normcap \
|
|
||||||
--cli-mode \
|
|
||||||
--screenshot-handler grim \
|
|
||||||
--show-introduction False \
|
|
||||||
--update False \
|
|
||||||
--detect-codes False \
|
|
||||||
--notification False \
|
|
||||||
-l jpn eng chi_sim
|
|
||||||
)" || exit 0
|
|
||||||
[ -n "$captured_text" ] || exit 0
|
|
||||||
encoded_text="$(printf '%s' "$captured_text" | jq -sRr @uri)"
|
|
||||||
exec xdg-open "naniapp://translate?source=$encoded_text"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
home.packages = [
|
|
||||||
normcap
|
|
||||||
normcapTranslate
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
description = "NormCap OCR screen capture";
|
|
||||||
|
|
||||||
includes = [
|
|
||||||
"applications.nani"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
"applications.loupe"
|
"applications.loupe"
|
||||||
"applications.linux-wallpaperengine"
|
"applications.linux-wallpaperengine"
|
||||||
"applications.nautilus"
|
"applications.nautilus"
|
||||||
"applications.normcap"
|
"applications.nani"
|
||||||
"applications.papers"
|
"applications.papers"
|
||||||
"applications.qalculate-gtk"
|
"applications.qalculate-gtk"
|
||||||
"applications.resources"
|
"applications.resources"
|
||||||
|
|||||||
Reference in New Issue
Block a user