Showing preview only (1,351K chars total). Download the full file or copy to clipboard to get everything.
Repository: H3rmt/hyprswitch
Branch: hyprshell-release
Commit: 30ce7a9e2579
Files: 331
Total size: 1.2 MB
Directory structure:
gitextract_elrb4jir/
├── .githooks/
│ └── pre-commit
├── .github/
│ └── workflows/
│ ├── publish.yml
│ ├── release-please.yml
│ ├── test.yml
│ └── update.yml
├── .gitignore
├── .idea/
│ ├── .gitignore
│ ├── copilot.data.migration.agent.xml
│ ├── copilot.data.migration.ask.xml
│ ├── copilot.data.migration.ask2agent.xml
│ ├── copilot.data.migration.edit.xml
│ ├── file.template.settings.xml
│ ├── hyprshell.iml
│ ├── inspectionProfiles/
│ │ └── Project_Default.xml
│ ├── modules.xml
│ ├── rust.xml
│ └── vcs.xml
├── .release-please-manifest.json
├── CHANGELOG.md
├── Cargo.toml
├── DEVELOPMENT.md
├── LICENSE
├── README.md
├── crates/
│ ├── clipboard-lib/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── config/
│ │ │ └── mod.rs
│ │ ├── lib.rs
│ │ ├── store/
│ │ │ ├── listen.rs
│ │ │ ├── mime.rs
│ │ │ ├── mod.rs
│ │ │ ├── save_image.rs
│ │ │ ├── save_map.rs
│ │ │ ├── save_text.rs
│ │ │ ├── util.rs
│ │ │ └── write.rs
│ │ └── util/
│ │ ├── brotli_compressor.rs
│ │ ├── crypt.rs
│ │ ├── lz4_compressor.rs
│ │ ├── mod.rs
│ │ ├── secret_service.rs
│ │ └── zstd_compressor.rs
│ ├── config-edit-lib/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── components/
│ │ │ ├── changes.rs
│ │ │ ├── footer.rs
│ │ │ ├── generate/
│ │ │ │ ├── main.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── step0.rs
│ │ │ │ ├── step1.rs
│ │ │ │ ├── step2.rs
│ │ │ │ ├── step3.rs
│ │ │ │ └── step4.rs
│ │ │ ├── launcher.rs
│ │ │ ├── launcher_plugins/
│ │ │ │ ├── actions.rs
│ │ │ │ ├── applications.rs
│ │ │ │ ├── main.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── simple.rs
│ │ │ │ └── websearch.rs
│ │ │ ├── mod.rs
│ │ │ ├── nix_preview.rs
│ │ │ ├── root.rs
│ │ │ ├── shortcut_dialog.rs
│ │ │ ├── switch.rs
│ │ │ ├── theme.rs
│ │ │ ├── windows.rs
│ │ │ └── windows_overview.rs
│ │ ├── lib.rs
│ │ ├── start.rs
│ │ ├── structs.rs
│ │ ├── styles.css
│ │ └── util.rs
│ ├── config-lib/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── actions.rs
│ │ ├── check.rs
│ │ ├── explain.rs
│ │ ├── lib.rs
│ │ ├── load.rs
│ │ ├── migrate/
│ │ │ ├── check.rs
│ │ │ ├── m1t2/
│ │ │ │ ├── convert.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── old_structs.rs
│ │ │ ├── m2t3/
│ │ │ │ ├── convert.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── old_structs.rs
│ │ │ ├── migrate_config.rs
│ │ │ └── mod.rs
│ │ ├── modifier.rs
│ │ ├── save.rs
│ │ ├── structs.rs
│ │ └── style/
│ │ ├── load.rs
│ │ ├── mod.rs
│ │ └── structs.rs
│ ├── core-lib/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── binds/
│ │ │ ├── mod.rs
│ │ │ ├── structs.rs
│ │ │ └── transfer.rs
│ │ ├── const.rs
│ │ ├── data.rs
│ │ ├── default/
│ │ │ └── mod.rs
│ │ ├── ini.rs
│ │ ├── ini_owned.rs
│ │ ├── lib.rs
│ │ ├── listener.rs
│ │ ├── notify.rs
│ │ ├── path.rs
│ │ ├── transfer/
│ │ │ ├── mod.rs
│ │ │ ├── receive.rs
│ │ │ ├── send.rs
│ │ │ └── structs.rs
│ │ └── util/
│ │ ├── boot.rs
│ │ ├── exec.rs
│ │ ├── exists.rs
│ │ ├── helpers.rs
│ │ ├── mod.rs
│ │ └── path.rs
│ ├── exec-lib/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── binds.rs
│ │ ├── collect.rs
│ │ ├── lib.rs
│ │ ├── listener.rs
│ │ ├── plugin.rs
│ │ ├── run.rs
│ │ ├── switch.rs
│ │ └── util.rs
│ ├── hyprland-plugin/
│ │ ├── Cargo.toml
│ │ ├── build.rs
│ │ ├── plugin/
│ │ │ ├── .gitignore
│ │ │ ├── .idea/
│ │ │ │ ├── copilot.data.migration.agent.xml
│ │ │ │ ├── copilot.data.migration.ask2agent.xml
│ │ │ │ ├── copilot.data.migration.edit.xml
│ │ │ │ ├── dictionaries/
│ │ │ │ │ └── project.xml
│ │ │ │ ├── editor.xml
│ │ │ │ ├── misc.xml
│ │ │ │ ├── vcs.xml
│ │ │ │ └── workspace.xml
│ │ │ ├── Makefile
│ │ │ ├── README.md
│ │ │ ├── src-52/
│ │ │ │ ├── defs-test.h
│ │ │ │ ├── defs.h
│ │ │ │ ├── exit.cpp
│ │ │ │ ├── globals.h
│ │ │ │ ├── handlers.h
│ │ │ │ ├── init.cpp
│ │ │ │ ├── key-press.cpp
│ │ │ │ ├── keyboard-focus.cpp
│ │ │ │ ├── layer-change.cpp
│ │ │ │ ├── main.cpp
│ │ │ │ ├── mouse-button.cpp
│ │ │ │ ├── send.cpp
│ │ │ │ └── send.h
│ │ │ ├── src-54/
│ │ │ │ ├── defs-test.h
│ │ │ │ ├── defs.h
│ │ │ │ ├── exit.cpp
│ │ │ │ ├── globals.h
│ │ │ │ ├── handlers.h
│ │ │ │ ├── init.cpp
│ │ │ │ ├── key-press.cpp
│ │ │ │ ├── keyboard-focus.cpp
│ │ │ │ ├── layer-change.cpp
│ │ │ │ ├── main.cpp
│ │ │ │ ├── mouse-button.cpp
│ │ │ │ ├── send.cpp
│ │ │ │ └── send.h
│ │ │ └── test-hyprland.conf
│ │ └── src/
│ │ ├── build.rs
│ │ ├── configure.rs
│ │ ├── extract.rs
│ │ ├── lib.rs
│ │ └── test.rs
│ ├── launcher-lib/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── close.rs
│ │ ├── create.rs
│ │ ├── css.rs
│ │ ├── debug.rs
│ │ ├── global.rs
│ │ ├── lib.rs
│ │ ├── open.rs
│ │ ├── plugins/
│ │ │ ├── actions.rs
│ │ │ ├── applications/
│ │ │ │ ├── data.rs
│ │ │ │ ├── map.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── plugin.rs
│ │ │ ├── calc.rs
│ │ │ ├── mod.rs
│ │ │ ├── path.rs
│ │ │ ├── search.rs
│ │ │ ├── shell.rs
│ │ │ └── terminal.rs
│ │ ├── stop.rs
│ │ ├── styles.css
│ │ └── update.rs
│ └── windows-lib/
│ ├── Cargo.toml
│ └── src/
│ ├── css.rs
│ ├── data.rs
│ ├── desktop_map.rs
│ ├── global.rs
│ ├── icon.rs
│ ├── keybinds.rs
│ ├── lib.rs
│ ├── next.rs
│ ├── overview/
│ │ ├── close.rs
│ │ ├── create.rs
│ │ ├── mod.rs
│ │ ├── open.rs
│ │ ├── stop.rs
│ │ └── update.rs
│ ├── sort.rs
│ ├── styles.css
│ └── switch/
│ ├── close.rs
│ ├── create.rs
│ ├── mod.rs
│ ├── open.rs
│ ├── stop.rs
│ └── update.rs
├── dep-crates/
│ ├── hyprland-rs/
│ │ ├── Cargo.toml
│ │ ├── LICENSE
│ │ ├── MIGRATION.md
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── bind.rs
│ │ │ ├── bind_async.rs
│ │ │ ├── data.rs
│ │ │ ├── data_async.rs
│ │ │ ├── dispatch.rs
│ │ │ ├── dispatch_async.rs
│ │ │ ├── events.rs
│ │ │ ├── events_async.rs
│ │ │ ├── keyword.rs
│ │ │ └── keyword_async.rs
│ │ ├── flake.nix
│ │ ├── hyprland-macros/
│ │ │ ├── Cargo.toml
│ │ │ ├── README.md
│ │ │ └── src/
│ │ │ └── lib.rs
│ │ ├── src/
│ │ │ ├── config.rs
│ │ │ ├── ctl.rs
│ │ │ ├── data/
│ │ │ │ ├── helpers.rs
│ │ │ │ ├── macros.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── regular.rs
│ │ │ ├── dispatch.rs
│ │ │ ├── error.rs
│ │ │ ├── event_listener/
│ │ │ │ ├── async_im.rs
│ │ │ │ ├── immutable.rs
│ │ │ │ ├── macros.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── shared.rs
│ │ │ │ └── stream.rs
│ │ │ ├── hyprpaper/
│ │ │ │ ├── error.rs
│ │ │ │ ├── keyword.rs
│ │ │ │ ├── monitor.rs
│ │ │ │ ├── preload.rs
│ │ │ │ ├── reload.rs
│ │ │ │ ├── unload.rs
│ │ │ │ ├── wallpaper.rs
│ │ │ │ ├── wallpaper_listing.rs
│ │ │ │ └── wallpaper_mode.rs
│ │ │ ├── hyprpaper.rs
│ │ │ ├── instance.rs
│ │ │ ├── keyword.rs
│ │ │ ├── lib.rs
│ │ │ ├── shared.rs
│ │ │ └── unsafe_impl.rs
│ │ ├── test.sh
│ │ └── treefmt.toml
│ └── wl-clipboard-rs/
│ ├── .github/
│ │ ├── dependabot.yml
│ │ └── workflows/
│ │ └── ci.yml
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── Cargo.toml
│ ├── LICENSE-APACHE
│ ├── LICENSE-MIT
│ ├── README.md
│ ├── README.tpl
│ ├── doc/
│ │ └── index.html
│ ├── rustfmt.toml
│ └── src/
│ ├── common.rs
│ ├── copy.rs
│ ├── data_control.rs
│ ├── lib.rs
│ ├── paste.rs
│ ├── seat_data.rs
│ ├── tests/
│ │ ├── copy.rs
│ │ ├── mod.rs
│ │ ├── paste.rs
│ │ ├── state.rs
│ │ └── utils.rs
│ └── utils.rs
├── docs/
│ ├── CONFIGURE.md
│ ├── DEBUG.md
│ ├── NIX.md
│ └── css-examples/
│ ├── default.css
│ ├── dracula.css
│ ├── gruvbox_dark.css
│ ├── liquid-glass.css
│ ├── modern.css
│ ├── solarized_dark.css
│ ├── test.css
│ └── tokyo_night_storm.css
├── flake.nix
├── justfile
├── nix/
│ ├── build.nix
│ ├── checks.nix
│ ├── meta.nix
│ ├── module.nix
│ └── util.nix
├── packaging/
│ ├── hyprshell-settings.desktop
│ ├── hyprshell.service
│ └── pkgbuild/
│ ├── PKGBUILD
│ ├── PKGBUILD-bin
│ └── PKGBUILD-slim
├── pkgbuild/
│ ├── PKGBUILD
│ ├── PKGBUILD-bin
│ └── PKGBUILD-slim
├── release-please-config.json
├── renovate.json
├── scripts/
│ ├── check-all-feature-combinations.sh
│ └── ci/
│ ├── build-aarch64.sh
│ ├── build-x86.sh
│ ├── install-gtk4-layer-shell-aarch64.sh
│ └── install-gtk4-layer-shell.sh
└── src/
├── cli.rs
├── completions.rs
├── data.rs
├── debug.rs
├── default_apps.rs
├── default_styles.css
├── explain.rs
├── keybinds.rs
├── main.rs
├── receive_handle.rs
├── socket.rs
├── start.rs
└── util.rs
================================================
FILE CONTENTS
================================================
================================================
FILE: .githooks/pre-commit
================================================
just check
================================================
FILE: .github/workflows/publish.yml
================================================
name: publish
on:
push:
tags:
- 'v*'
jobs:
check:
runs-on: ubuntu-latest
outputs:
should_publish: ${{ steps.check_commit.outputs.should_publish }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Check commit message
id: check_commit
run: |
commit_msg=$(git log -1 --pretty=%B)
if [[ $commit_msg =~ ^chore\(hyprshell.*\):\ release ]]; then
echo "should_publish=true" >> $GITHUB_OUTPUT
else
echo "Error: Commit message must start with 'chore(hyprshell): release'"
echo "should_publish=false" >> $GITHUB_OUTPUT
fi
publish:
needs: check
runs-on: ubuntu-latest
container:
image: ghcr.io/h3rmt/actions-image:latest
options: --privileged
if: needs.check.outputs.should_publish == 'true'
steps:
- run: rustup default stable
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
ssh-key: ${{ secrets.SSH_KEY }}
- name: Install gtk4-layer-shell
run: ./scripts/ci/install-gtk4-layer-shell.sh
- name: Install cargo-workspaces
run: |
mkdir -p $HOME/.cargo/bin
cargo install cargo-workspaces
cargo ws --version
- name: Publish to crates.io
run: |
set -euxo pipefail
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git fetch --tags origin hyprshell-release
git checkout ${{ github.ref }} -b hyprshell-release
git log -1 --pretty=%B
git push origin HEAD:hyprshell-release --force
git switch hyprshell-release
current_sha=$(git rev-parse HEAD)
jq --arg sha "$current_sha" '.["last-release-sha"]=$sha' release-please-config.json > tmp.json
mv tmp.json release-please-config.json
git add release-please-config.json
git commit -m "chore(release): update last-release-sha"
git push origin hyprshell-release
git tag --delete ${{ github.ref_name }}
git push --delete origin ${{ github.ref_name }}
version=$(echo ${{ github.ref_name }} | sed 's/v//')
cargo ws publish custom $version -m "chore(release): bump versions to $version" --no-individual-tags --allow-branch hyprshell-release --exact --yes --force "hyprshell*" --token ${{ secrets.CRATES_TOKEN }}
# push current branch to hyprshell branch (for development)
git push origin HEAD:hyprshell-release
gh release edit ${{ github.ref_name }} --latest --draft=false --title "hyprshell ${{ github.ref_name }}"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish AUR package
uses: KSXGitHub/github-actions-deploy-aur@2ac5a4c1d7035885d46b10e3193393be8460b6f1 # v4.1.1
with:
pkgname: hyprshell
pkgbuild: ./packaging/pkgbuild/PKGBUILD
commit_username: ${{ secrets.AUR_USERNAME }}
commit_email: ${{ secrets.AUR_EMAIL }}
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
commit_message: Update hyprshell AUR package
updpkgsums: true
ssh_keyscan_types: rsa,ecdsa,ed25519
- name: Publish AUR slim package
uses: KSXGitHub/github-actions-deploy-aur@2ac5a4c1d7035885d46b10e3193393be8460b6f1 # v4.1.1
with:
pkgname: hyprshell-slim
pkgbuild: ./packaging/pkgbuild/PKGBUILD-slim
commit_username: ${{ secrets.AUR_USERNAME }}
commit_email: ${{ secrets.AUR_EMAIL }}
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
commit_message: Update hyprshell-slim AUR package
updpkgsums: true
ssh_keyscan_types: rsa,ecdsa,ed25519
- name: Build binary for x86_64-unknown-linux-gnu
run: |
version=$(echo ${{ github.ref_name }} | sed 's/v//')
./scripts/ci/build-x86.sh
mv "/tmp/hyprshell-x86_64.tar.zst" "/tmp/hyprshell-$version-x86_64.tar.zst"
gh release upload ${{ github.ref_name }} "/tmp/hyprshell-$version-x86_64.tar.zst"
mv "/tmp/hyprshell-slim-x86_64.tar.zst" "/tmp/hyprshell-slim-$version-x86_64.tar.zst"
gh release upload ${{ github.ref_name }} "/tmp/hyprshell-slim-$version-x86_64.tar.zst"
cargo clean
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build binary for aarch64-unknown-linux-gnu
run: |
version=$(echo ${{ github.ref_name }} | sed 's/v//')
./scripts/ci/install-gtk4-layer-shell-aarch64.sh
./scripts/ci/build-aarch64.sh
mv "/tmp/hyprshell-aarch64.tar.zst" "/tmp/hyprshell-$version-aarch64.tar.zst"
gh release upload ${{ github.ref_name }} "/tmp/hyprshell-$version-aarch64.tar.zst"
mv "/tmp/hyprshell-slim-aarch64.tar.zst" "/tmp/hyprshell-slim-$version-aarch64.tar.zst"
gh release upload ${{ github.ref_name }} "/tmp/hyprshell-slim-$version-aarch64.tar.zst"
cargo clean
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish AUR bin package
uses: KSXGitHub/github-actions-deploy-aur@2ac5a4c1d7035885d46b10e3193393be8460b6f1 # v4.1.1
with:
pkgname: hyprshell-bin
pkgbuild: ./packaging/pkgbuild/PKGBUILD-bin
commit_username: ${{ secrets.AUR_USERNAME }}
commit_email: ${{ secrets.AUR_EMAIL }}
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
commit_message: Update hyprshell-bin AUR package
updpkgsums: true
ssh_keyscan_types: rsa,ecdsa,ed25519
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
with:
name: hyprshell
extraPullNames: hyprshell-dev, hyprland
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
- name: Run Nix Flake Build
run: nix build '.#packages.x86_64-linux.hyprshell' -L
================================================
FILE: .github/workflows/release-please.yml
================================================
name: release-please
on:
push:
branches:
- 'hyprshell'
- 'hyprshell-patch-**'
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38 # v4.4.0
with:
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
target-branch: ${{ github.ref_name }}
================================================
FILE: .github/workflows/test.yml
================================================
name: test
on:
push:
branches-ignore:
- 'release-please-**'
- 'hyprshell-release'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
check-nix:
name: Run Nix Flake Check
runs-on: "ubuntu-latest"
container:
image: ghcr.io/h3rmt/actions-image:latest
options: --privileged
steps:
- run: rustup default stable
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
with:
name: hyprshell-dev
extraPullNames: hyprland
pushFilter: "hyprshell-(nextest|clippy|fmt|check-all-feature-combinations|check-nix-configs).*"
authToken: ${{ secrets.CACHIX_AUTH_TOKEN_DEV }}
- name: Run Nix Flake Build deps
run: nix build '.#checks.x86_64-linux.hyprshell-build-deps' -L
- name: Run Nix Flake Check build
run: nix build '.#checks.x86_64-linux.hyprshell-config-check' -L
- name: Run Nix Flake Check clippy
run: nix build '.#checks.x86_64-linux.hyprshell-clippy' -L
- name: Run Nix Flake Check fmt
run: nix build '.#checks.x86_64-linux.hyprshell-fmt' -L
- name: Run Nix Flake Check test
run: nix build '.#checks.x86_64-linux.hyprshell-test' -L
- name: Run Nix Flake Check check-nix-configs
run: nix build '.#checks.x86_64-linux.hyprshell-check-nix-configs' -L
- name: Run Nix Flake Check check-all-feature-combinations
run: nix build '.#checks.x86_64-linux.hyprshell-check-all-feature-combinations' -L
check:
name: Run build tests
runs-on: "ubuntu-latest"
container:
image: ghcr.io/h3rmt/actions-image:latest
options: --privileged
if: github.ref == 'refs/heads/hyprshell'
steps:
- run: rustup default stable
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # v2.8.1
with:
prefix-key: hyprshell
cache-on-failure: true
- name: Build binary for x86_64-unknown-linux-gnu
run: |
./scripts/ci/install-gtk4-layer-shell.sh
./scripts/ci/build-x86.sh
- name: Build binary for aarch64-unknown-linux-gnu
run: |
./scripts/ci/install-gtk4-layer-shell-aarch64.sh
./scripts/ci/build-aarch64.sh
================================================
FILE: .github/workflows/update.yml
================================================
name: update flake.lock
on:
workflow_dispatch: # allows manual triggering
schedule:
- cron: '30 2 1,15 * *' # At 02:30 on every 14th day-of-month.
jobs:
nix-flake-update:
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: cachix/install-nix-action@0b0e072294b088b73964f1d72dfdac0951439dbd # v31.8.4
with:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
- name: Update flake
run: |
git fetch
git switch hyprshell
nix flake update
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add flake.lock
git commit -m "fix(nix-flake): update flake.lock"
git push origin hyprshell
================================================
FILE: .gitignore
================================================
/target
/*/target
/result
/test-data
================================================
FILE: .idea/.gitignore
================================================
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
================================================
FILE: .idea/copilot.data.migration.agent.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AgentMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>
================================================
FILE: .idea/copilot.data.migration.ask.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AskMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>
================================================
FILE: .idea/copilot.data.migration.ask2agent.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Ask2AgentMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>
================================================
FILE: .idea/copilot.data.migration.edit.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EditMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>
================================================
FILE: .idea/file.template.settings.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExportableFileTemplateSettings">
<j2ee_templates>
<template name="qt.CMakeLists.txt" reformat="true" live-template-enabled="false" enabled="false" />
</j2ee_templates>
</component>
</project>
================================================
FILE: .idea/hyprshell.iml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/gui-lib/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test-global/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/config-lib/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/core-lib/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/exec-lib/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/hyprland-plugin/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/launcher-lib/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/windows-lib/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dep-crates/hyprland-rs/examples" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dep-crates/hyprland-rs/hyprland-macros/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dep-crates/hyprland-rs/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/clipboard-lib/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dep-crates/wl-clipboard-rs/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dep-crates/wl-clipboard-rs/wl-clipboard-rs-tools/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/config-edit-lib/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/config" />
<excludeFolder url="file://$MODULE_DIR$/gui-lib/target" />
<excludeFolder url="file://$MODULE_DIR$/target" />
<excludeFolder url="file://$MODULE_DIR$/data" />
<excludeFolder url="file://$MODULE_DIR$/test-global" />
<excludeFolder url="file://$MODULE_DIR$/result" />
<excludeFolder url="file://$MODULE_DIR$/crates/core-lib/target" />
<excludeFolder url="file://$MODULE_DIR$/crates/exec-lib/target" />
<excludeFolder url="file://$MODULE_DIR$/crates/hyprland-plugin/Hyprland" />
<excludeFolder url="file://$MODULE_DIR$/crates/launcher-lib/target" />
<excludeFolder url="file://$MODULE_DIR$/crates/windows-lib/target" />
<excludeFolder url="file://$MODULE_DIR$/dep-crates/hyprland-rs/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
================================================
FILE: .idea/inspectionProfiles/Project_Default.xml
================================================
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="DuplicatedCode" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="RsSortImplTraitMembers" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
</profile>
</component>
================================================
FILE: .idea/modules.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/hyprshell.iml" filepath="$PROJECT_DIR$/.idea/hyprshell.iml" />
</modules>
</component>
</project>
================================================
FILE: .idea/rust.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RsVcsConfiguration">
<option name="rustFmt" value="true" />
</component>
</project>
================================================
FILE: .idea/vcs.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
================================================
FILE: .release-please-manifest.json
================================================
{
".": "4.9.5"
}
================================================
FILE: CHANGELOG.md
================================================
# Changelog
## [4.9.5](https://github.com/H3rmt/hyprshell/compare/v4.9.4...v4.9.5) (2026-03-31)
### Bug Fixes
* use cpp26 for hyprland plugin ([6fcff3b](https://github.com/H3rmt/hyprshell/commit/6fcff3b3de906497f96648f53fe20522ea5db577))
## [4.9.4](https://github.com/H3rmt/hyprshell/compare/v4.9.3...v4.9.4) (2026-03-02)
### Bug Fixes
* bundle multiple plugin versions to support wider range of hyprland versions ([95908e0](https://github.com/H3rmt/hyprshell/commit/95908e067293fd4ad4381f6b11bf923a69f96637))
* fix use correct keyboard in plugin ([805bbb4](https://github.com/H3rmt/hyprshell/commit/805bbb44c9671b57fb633e90227bc69b318c685d))
* update plugin to new hyprland plugin api ([6bfc01d](https://github.com/H3rmt/hyprshell/commit/6bfc01de8e0461119d2e4b5b0bc4b2202c36b4c9))
## [4.9.3](https://github.com/H3rmt/hyprshell/compare/v4.9.2...v4.9.3) (2026-03-02)
### Bug Fixes
* bundle multiple plugin versions to support wider range of hyprland versions ([95908e0](https://github.com/H3rmt/hyprshell/commit/95908e067293fd4ad4381f6b11bf923a69f96637))
* update plugin to new hyprland plugin api ([6bfc01d](https://github.com/H3rmt/hyprshell/commit/6bfc01de8e0461119d2e4b5b0bc4b2202c36b4c9))
## [4.9.2](https://github.com/H3rmt/hyprshell/compare/v4.9.1...v4.9.2) (2026-01-06)
### Bug Fixes
* fix release ci workflow ([eada938](https://github.com/H3rmt/hyprshell/commit/eada9385f52846c6468891cb061c5a879fd16098))
## [4.9.1](https://github.com/H3rmt/hyprshell/compare/v4.9.0...v4.9.1) (2026-01-06)
### Bug Fixes
* add websearch and actions configs ([923055e](https://github.com/H3rmt/hyprshell/commit/923055ea721fd01a3abce376564cb7b2f81449dd))
* reduce image size ([923055e](https://github.com/H3rmt/hyprshell/commit/923055ea721fd01a3abce376564cb7b2f81449dd))
## [4.9.0](https://github.com/H3rmt/hyprshell/compare/v4.8.3...v4.9.0) (2026-01-05)
### Features
* add generate page ([1f9cb52](https://github.com/H3rmt/hyprshell/commit/1f9cb52edf6f48c446b92ec3398e19fe3e5cb224))
* add terminal settings and overview keyboard shortcut chooser to generate setup ([f7ae9bf](https://github.com/H3rmt/hyprshell/commit/f7ae9bf3d2b5769627faa2735fb7c6058a6de998))
* added data file to themes ([9e13a4a](https://github.com/H3rmt/hyprshell/commit/9e13a4a3e2273cd9be56438f0b6515e3fa593c52))
* added debug info command ([efa1010](https://github.com/H3rmt/hyprshell/commit/efa10109c0af9ed04912f1e2066632650d460494))
* added theme chooser ([8deccc2](https://github.com/H3rmt/hyprshell/commit/8deccc2dba445411bca4f781b93d9ddab52ac942))
* added theme settings to config editor ([178f60b](https://github.com/H3rmt/hyprshell/commit/178f60b975a85ec54840801d627bdfd0a1bfd0b3))
* allow custom key for switch mode ([3d07d3c](https://github.com/H3rmt/hyprshell/commit/3d07d3ceac3f1233f58498e7725c34c867450016))
* generate config from gui ([c6237a2](https://github.com/H3rmt/hyprshell/commit/c6237a25ef6d0b676aedd48aa5260fd12e6b39f8))
* retry getting version for 40 times ([9207c2a](https://github.com/H3rmt/hyprshell/commit/9207c2a9485211b3ba8c86c5e15cac35ca5e7c1d))
### Bug Fixes
* **deps:** update rust crate ron to 0.12.0 ([1c6038a](https://github.com/H3rmt/hyprshell/commit/1c6038a3f546d56da6ce18a2cccdeaedc7fdd90b))
* fix bin package for aur ([4906ccb](https://github.com/H3rmt/hyprshell/commit/4906ccb8344d3022298d225841276e89b703702a))
* fix bin package for aur ([22a9b3b](https://github.com/H3rmt/hyprshell/commit/22a9b3b33e30ce810da9a806bbc61418f85537d9))
* fix systemd unit generation ([4318bf5](https://github.com/H3rmt/hyprshell/commit/4318bf5442ac08dfde638caa97417d5ad67bd5c9))
* **nix-flake:** update flake.lock ([54fb1d0](https://github.com/H3rmt/hyprshell/commit/54fb1d06a1e63a3abc3004caae96a306a0cdd98d))
* **nix-flake:** update flake.lock ([cfe263a](https://github.com/H3rmt/hyprshell/commit/cfe263a09189d92c218f2223d6b4552200777410))
* **nix-flake:** update flake.lock ([66e4a85](https://github.com/H3rmt/hyprshell/commit/66e4a85b98b06febd33036e8f14ed12bff923941))
* update hyprland plugin ([3d07d3c](https://github.com/H3rmt/hyprshell/commit/3d07d3ceac3f1233f58498e7725c34c867450016))
### Code Refactoring
* add remaining plugin options ([ad9359f](https://github.com/H3rmt/hyprshell/commit/ad9359f6fb99042dbc94d229a343a5dffb789186))
* fix clippy fixes ([219f14c](https://github.com/H3rmt/hyprshell/commit/219f14c2d857975cdd6f9f6149df6085956e39ef))
* use justfile ([c6237a2](https://github.com/H3rmt/hyprshell/commit/c6237a25ef6d0b676aedd48aa5260fd12e6b39f8))
* use relm4 as base for adw and gtk ([d95e69e](https://github.com/H3rmt/hyprshell/commit/d95e69e783de3333458eb2aa112ed9a22844355c))
* use relm4 as base for adw and gtk ([f2e158c](https://github.com/H3rmt/hyprshell/commit/f2e158c0611773cb96d288451b965421ee4d1b3c))
### Documentation
* add minimum gtk and adwaita versions to README.md ([c33f431](https://github.com/H3rmt/hyprshell/commit/c33f431c3ef32e8530ca56589c5e107693ef4a2c))
## [4.8.3](https://github.com/H3rmt/hyprshell/compare/v4.8.2...v4.8.3) (2025-12-27)
### Bug Fixes
* fix bin package for aur ([443febe](https://github.com/H3rmt/hyprshell/commit/443febe5d54f2b32b3eb3c5c3b8d6f0af3e7276b))
## [4.8.2](https://github.com/H3rmt/hyprshell/compare/v4.8.1...v4.8.2) (2025-12-25)
### Bug Fixes
* fix systemd unit generation ([f0fdc99](https://github.com/H3rmt/hyprshell/commit/f0fdc99832510eee5862df6b5826d07e8b16cb9e))
* **nix-flake:** update flake.lock ([01531df](https://github.com/H3rmt/hyprshell/commit/01531df3820ab6346814f83abd5852a88ccf2c69))
* **nix-flake:** update flake.lock ([b8827a3](https://github.com/H3rmt/hyprshell/commit/b8827a3b2e0528991b22eacf41ad9f07b4cbbc73))
## [4.8.1](https://github.com/H3rmt/hyprshell/compare/v4.8.0...v4.8.1) (2025-11-17)
### Bug Fixes
* crash when filtering windows or clients ([#379](https://github.com/H3rmt/hyprshell/issues/379)) ([13e0105](https://github.com/H3rmt/hyprshell/commit/13e010558b47e416322c8961e5dd1a3e75008503))
* dont check for a hyprland session on commands other than run ([c93b2dc](https://github.com/H3rmt/hyprshell/commit/c93b2dc95347f32904c45fe820fa5f9e596fcdc0))
* increase waiting time if no initial workspace is being found ([b6e2782](https://github.com/H3rmt/hyprshell/commit/b6e27827f89670c90b11401d8931beea74dcf57c))
* **nix-flake:** update flake.lock ([b166440](https://github.com/H3rmt/hyprshell/commit/b16644046b712881d8bafbdd99f8acda9f39b6d6))
* use xdg notifications instead of hyprland notifications ([0db43a7](https://github.com/H3rmt/hyprshell/commit/0db43a7b905529bf5447fd373a01c78fb804972b))
### Code Refactoring
* update dependencies ([a1c00c7](https://github.com/H3rmt/hyprshell/commit/a1c00c782ae3ffac8b4a9f7c1793c5e8daddd061))
### Documentation
* updated nix docs ([facdf5a](https://github.com/H3rmt/hyprshell/commit/facdf5a3b40544b49d26886edb65b3726129ac9c))
## [4.8.0](https://github.com/H3rmt/hyprshell/compare/v4.7.2...v4.8.0) (2025-11-09)
### Features
* add special workspace support ([0604d21](https://github.com/H3rmt/hyprshell/commit/0604d21371552666b8e62e29ef4a782948c864fc))
* Add vim navigation to the switcher ([#360](https://github.com/H3rmt/hyprshell/issues/360)) ([cc0797d](https://github.com/H3rmt/hyprshell/commit/cc0797d8f18a970170619ad3b8e17ca8646d8d93))
* added brotli compression to clipboard lib ([dd0fb3d](https://github.com/H3rmt/hyprshell/commit/dd0fb3d29939775807fa372e280b688c8001e0da))
* added gui config editor ([bb29010](https://github.com/H3rmt/hyprshell/commit/bb29010eb262dc22335e2c51d7bc5b78042e7553))
* added hyprshell-slim and hyprshell-bin aur packages ([bb29010](https://github.com/H3rmt/hyprshell/commit/bb29010eb262dc22335e2c51d7bc5b78042e7553))
* added libadwaita instead of gtk4, added more config options ([bb29010](https://github.com/H3rmt/hyprshell/commit/bb29010eb262dc22335e2c51d7bc5b78042e7553))
* remove nix wrapper fn and add hyprland input instead ([bb29010](https://github.com/H3rmt/hyprshell/commit/bb29010eb262dc22335e2c51d7bc5b78042e7553))
### Bug Fixes
* add `Edit via `hyprshell config edit`` to config file ([e9b9ca4](https://github.com/H3rmt/hyprshell/commit/e9b9ca40c705c050f91859ebe8984cf778494c7b))
* disable hyprland plugin after loading fails once ([96cb6e6](https://github.com/H3rmt/hyprshell/commit/96cb6e6f2ab97fe4fc0f2d0eb53a13104c8685cf))
* dont generate systemd file if config is generated in debug mode ([bb29010](https://github.com/H3rmt/hyprshell/commit/bb29010eb262dc22335e2c51d7bc5b78042e7553))
* downgrad gtk version ([914bc34](https://github.com/H3rmt/hyprshell/commit/914bc34ceba8add1aec1691ace18740ef629b3da))
* downgrad libadwaita version ([7b6cced](https://github.com/H3rmt/hyprshell/commit/7b6ccedb29db0af4af7ee4a96198ad41c6762ba6))
* fix selecting client in a special workspace ([97d707c](https://github.com/H3rmt/hyprshell/commit/97d707cca2affd27f9a9cbc356224e96ecd831d2))
* Fix version check for Hyprshell Plugin ([#373](https://github.com/H3rmt/hyprshell/issues/373)) ([da03596](https://github.com/H3rmt/hyprshell/commit/da035960aadb971c518e415ac273443eceaad19c))
* **nix-flake:** update flake.lock ([2d6e0ee](https://github.com/H3rmt/hyprshell/commit/2d6e0eee010f88f67d97624a44ebe00abc00bd30))
* **nix-flake:** update flake.lock ([67e720e](https://github.com/H3rmt/hyprshell/commit/67e720e953bfcd0e30fa53ba9abafbaf2dff8cd7))
### Code Refactoring
* use adw instead of gtk4 ([bb29010](https://github.com/H3rmt/hyprshell/commit/bb29010eb262dc22335e2c51d7bc5b78042e7553))
### Documentation
* add explanations to tooltips ([2d7009c](https://github.com/H3rmt/hyprshell/commit/2d7009c22efadcace58f099f7f86173ec1f8dbcb))
* update readme ([bb29010](https://github.com/H3rmt/hyprshell/commit/bb29010eb262dc22335e2c51d7bc5b78042e7553))
## [4.7.2](https://github.com/H3rmt/hyprshell/compare/v4.7.1...v4.7.2) (2025-10-14)
### Bug Fixes
* added more logging to creation of windows ([2c57b0f](https://github.com/H3rmt/hyprshell/commit/2c57b0ffb3213b164053090c7c6ef47e8ac0c0ed))
## [4.7.1](https://github.com/H3rmt/hyprshell/compare/v4.7.0...v4.7.1) (2025-10-03)
### Bug Fixes
* docs mentioned style.css instead of styles.css as the default location for the CSS file ([a32a317](https://github.com/H3rmt/hyprshell/commit/a32a3171442357ae886fd5a07367a692097dccaf))
* **nix-flake:** update flake.lock ([944c2b4](https://github.com/H3rmt/hyprshell/commit/944c2b4ad012d7ab963f20c73e6d310d94c1cb33))
## [4.7.0](https://github.com/H3rmt/hyprshell/compare/v4.6.4...v4.7.0) (2025-09-23)
### Features
* add actions plugin ([559cc8a](https://github.com/H3rmt/hyprshell/commit/559cc8a81e6a55a09c0f637b503e646e80fc2570))
* add vim keybinds (https://github.com/H3rmt/hyprshell/issues/185) ([dca2dcc](https://github.com/H3rmt/hyprshell/commit/dca2dccc4199c5823959edfef56115d7b010c177))
### Bug Fixes
* **nix-flake:** update flake.lock ([590315d](https://github.com/H3rmt/hyprshell/commit/590315d396ff3811f9115f47dd52c228bd23e5bc))
* remove and update options from homemanager module ([2ae00bf](https://github.com/H3rmt/hyprshell/commit/2ae00bf10c17ab64685fc7458b880b68b7eddf97))
## [4.6.4](https://github.com/H3rmt/hyprshell/compare/v4.6.3...v4.6.4) (2025-09-14)
### Bug Fixes
* allow multiple instances (use wayland socket as part of APPID for gtk) ([8b8bce8](https://github.com/H3rmt/hyprshell/commit/8b8bce807a8d0ad9491396532f2bbfcde037ad0b))
* allow setting custom hyprland package to fix nix plugin build ([28d0e67](https://github.com/H3rmt/hyprshell/commit/28d0e677eaa4f7032cdacee8fa9ff279188b797b))
* always apply layerrules ([fbc9cb8](https://github.com/H3rmt/hyprshell/commit/fbc9cb853b986d82b4aac5307b5cb9e8465dcaab))
* disable gestures disabling (changed in Hyprland 51) ([8b8bce8](https://github.com/H3rmt/hyprshell/commit/8b8bce807a8d0ad9491396532f2bbfcde037ad0b))
* fix https://github.com/H3rmt/hyprshell/issues/336 by converting open to switch ([5c55ba6](https://github.com/H3rmt/hyprshell/commit/5c55ba6abcd5adb28eb9d216d80e300d942a6997))
* fix meta for wrapped program ([eabdefb](https://github.com/H3rmt/hyprshell/commit/eabdefbe4ee1cd81c295e049bd3ab0473b5660d0))
* reload follow mouse prev value on config reload ([8a43141](https://github.com/H3rmt/hyprshell/commit/8a431419941aa6641fc2abaf5e73b576d6f2c40a))
### Code Refactoring
* move crates to crate folder ([68633c6](https://github.com/H3rmt/hyprshell/commit/68633c6d776383e2384af9faa7456f15f2fcda1d))
## [4.6.3](https://github.com/H3rmt/hyprshell/compare/v4.6.2...v4.6.3) (2025-09-11)
### Bug Fixes
* allow for removal of shell completions ([9699d32](https://github.com/H3rmt/hyprshell/commit/9699d32212ce1c58784d7c83f925ad043f359a4f))
* cancel key events when opening hyprshell overview and switch ([92e4ea7](https://github.com/H3rmt/hyprshell/commit/92e4ea7a7990719071eae626feeb3f43911a4def))
* check for nothing enabled in config ([66b6820](https://github.com/H3rmt/hyprshell/commit/66b682089fb94b426c3d8f7c615b097dfe9f40f4))
* **deps:** update rust crate regex to v1.11.2 ([272fd94](https://github.com/H3rmt/hyprshell/commit/272fd94aeb8ae47ae7f3523e47ecd162e869cf15))
* fix reload of hyprland if hyprland config was reloaded ([9c2dd76](https://github.com/H3rmt/hyprshell/commit/9c2dd76e4b0c2ee791f6b4fa80aeb6ea5ca017de))
* ignore virtual keyboard inputs ([9699d32](https://github.com/H3rmt/hyprshell/commit/9699d32212ce1c58784d7c83f925ad043f359a4f))
* include /usr/share/applications/mimeapps ([7022cb2](https://github.com/H3rmt/hyprshell/commit/7022cb2c4d5a436cd1ccd63b50b944265a40e9a3))
* override of desktop files (https://github.com/H3rmt/hyprshell/issues/334) ([18fe033](https://github.com/H3rmt/hyprshell/commit/18fe03365799ce372af832a61335a5cf6f8f029c))
* plugin now still works if overview or switch are disabled ([66b6820](https://github.com/H3rmt/hyprshell/commit/66b682089fb94b426c3d8f7c615b097dfe9f40f4))
* print `No runs` if hyprshell data launch-history doesnt find any runs ([c67ab1b](https://github.com/H3rmt/hyprshell/commit/c67ab1b62c23cbf4f5f047a284f62b61a144adfa))
* use Layer::Top for launcher (fix https://github.com/H3rmt/hyprshell/issues/327) ([8389d58](https://github.com/H3rmt/hyprshell/commit/8389d5871be307919dd0bb37cbc8bcf7f010b8aa))
## [4.6.2](https://github.com/H3rmt/hyprshell/compare/v4.6.1...v4.6.2) (2025-09-07)
### Bug Fixes
* fix nix packaging ([efe38a2](https://github.com/H3rmt/hyprshell/commit/efe38a2508c50fc6eb9aecb39f1f65fe7047a28c))
* remove zip dependencies ([efe38a2](https://github.com/H3rmt/hyprshell/commit/efe38a2508c50fc6eb9aecb39f1f65fe7047a28c))
* use monochrome if path in launcher is a valid path but doesn't exist ([0f59ca3](https://github.com/H3rmt/hyprshell/commit/0f59ca33d4946e1247c5ca937d7f399a03a00f44))
### Code Refactoring
* better nix caching ([0f59ca3](https://github.com/H3rmt/hyprshell/commit/0f59ca33d4946e1247c5ca937d7f399a03a00f44))
## [4.6.1](https://github.com/H3rmt/hyprshell/compare/v4.6.0...v4.6.1) (2025-09-04)
### Bug Fixes
* **deps:** update deps ([108057a](https://github.com/H3rmt/hyprshell/commit/108057aa10525cb710f7785bd7ed3221bbf7c0e8))
* hyprland plugin now build without make in OUT_DIR ([31bdfb1](https://github.com/H3rmt/hyprshell/commit/31bdfb1392c4086ee6de6805826666ece2a0c18f))
### Documentation
* update nix docs ([eac79f1](https://github.com/H3rmt/hyprshell/commit/eac79f1b2dd2f3d5cc634d2cbcecdca40d8cdd4c))
## [4.6.0](https://github.com/H3rmt/hyprshell/compare/v4.5.0...v4.6.0) (2025-09-04)
### Features
* added shell completions ([a74fa47](https://github.com/H3rmt/hyprshell/commit/a74fa4777a2f905b6a0f0269401c564e60068692))
* added toml to ron migration (toml dropped, as it can't store None values) ([9d1e370](https://github.com/H3rmt/hyprshell/commit/9d1e370b7c2223171a6fb92d0aba0f9cc2a9ca01))
* better config migrations (allow multi version migrations) ([299d388](https://github.com/H3rmt/hyprshell/commit/299d38816d02dadd97160e7a13088f6aaca2d4ea))
* enhance ini parsing and added new cli command to get, list and set default apps ([2036a3c](https://github.com/H3rmt/hyprshell/commit/2036a3cb1a3588b97eaea5967e8900cff73726c8))
* show info when new version detected ([e80fe65](https://github.com/H3rmt/hyprshell/commit/e80fe65a86da07448936babfd4a59ee33340217f))
### Bug Fixes
* apply user style with user priority ([b700ee0](https://github.com/H3rmt/hyprshell/commit/b700ee0e4954b9e463ba64263953dacfc36ad097))
* close overview with open key ([aa5be3f](https://github.com/H3rmt/hyprshell/commit/aa5be3f560bd1fd7bf0026d8c9e09b3f4b4d15b4))
* **deps:** update rust crate anyhow to v1.0.99 ([a7e96f3](https://github.com/H3rmt/hyprshell/commit/a7e96f388deb7c132bf5bd2f35e88be3f7d56d45))
* **deps:** update rust crate notify to v8.1.0 ([611cde3](https://github.com/H3rmt/hyprshell/commit/611cde3cb681f030a038439f321421d4e875222e))
* enable show_actions_submenu for nix users ([8c19498](https://github.com/H3rmt/hyprshell/commit/8c1949892c46da3ff24548ccd904741694339fb0))
* exclude empty workspaces in switch mode ([10786eb](https://github.com/H3rmt/hyprshell/commit/10786eb5001f1ed7abc3bb2483741b30e410152f))
* exit app when removing / adding monitors ([032a047](https://github.com/H3rmt/hyprshell/commit/032a047597cab6f2dbe0c6e4482c8d05eb7fbdca))
* fix cargo install cargo-workspaces ([e62a334](https://github.com/H3rmt/hyprshell/commit/e62a33465633ae87653fed679549b4cfc988f73b))
* fix cargo ws publish, allow buildscript to run make ([14b5b5a](https://github.com/H3rmt/hyprshell/commit/14b5b5a2ab9e6501c2c125203f44808a80314649))
* fix missing version in dependency of custom hyprland-rs ([94747cc](https://github.com/H3rmt/hyprshell/commit/94747cc81f554faf034bb5b7c5ec04dcbad03119))
* fix publish workflow check commit ([29e440f](https://github.com/H3rmt/hyprshell/commit/29e440f6f0685e93d24291196b16623d7721bcd6))
* fixed select window in overview ([71080a9](https://github.com/H3rmt/hyprshell/commit/71080a9211bd63de4aa0c1405810dfa1126c180c))
* **nix-flake:** update flake.lock ([918e40b](https://github.com/H3rmt/hyprshell/commit/918e40beb8e70649e52ffcf8dd21747bcdc3f27f))
* **nix-flake:** update flake.lock ([4eeaa57](https://github.com/H3rmt/hyprshell/commit/4eeaa5710aa7503b9a1307c8016879fd8df664ec))
* **plugin:** fix open overview after mouse button press ([bd03613](https://github.com/H3rmt/hyprshell/commit/bd0361332ca313d527daec85d7cfdc0d057a5fc1))
* reload desktop files, etc. after opening launcher ([a679985](https://github.com/H3rmt/hyprshell/commit/a67998550abd8069c47a6d2bd762b72208a70b2f))
* style changes, liquid gras css updated ([6871827](https://github.com/H3rmt/hyprshell/commit/687182774094aa572441ece0ad9b44c52612a196))
* typos in home manager configuration ([a9fc51e](https://github.com/H3rmt/hyprshell/commit/a9fc51e6e8d1e23302e17cc905f2f8285744c9fc))
* use bash to start apps ([c86dee1](https://github.com/H3rmt/hyprshell/commit/c86dee15733bc86f0ab81cceeb84bb1671876da3))
* use new hyprland-rs Instance ([c519605](https://github.com/H3rmt/hyprshell/commit/c51960581592469653380adfc03d3ea2f78e2e3a))
* use toml extension on lookup config file ([0ab9e9d](https://github.com/H3rmt/hyprshell/commit/0ab9e9dee21e70e80a815dbea7d833a32f5497cc))
### Code Refactoring
* add hyprland plugin ([1412e7a](https://github.com/H3rmt/hyprshell/commit/1412e7a46a3945d7a2f76dd1d1c5ac675160a17e))
* add hyprland plugin ([33ced1c](https://github.com/H3rmt/hyprshell/commit/33ced1cab64d2864de3f3b3d41f53484ec9adedb))
* better animations for launcher ([9c2a71c](https://github.com/H3rmt/hyprshell/commit/9c2a71cb275516adbd98ef084a9f5dcd564dedb2))
* build plugin at runtime ([400a93b](https://github.com/H3rmt/hyprshell/commit/400a93bbc340f933d473c393f4d71fcf2b5339ad))
* check if set desktop file is valid ([b7cfa98](https://github.com/H3rmt/hyprshell/commit/b7cfa982a371300bf523e12dbfd06f2734bc7ebd))
* fix nix wrap program ([5895432](https://github.com/H3rmt/hyprshell/commit/58954329f521daabaf67cb0c67a3f130ef9f26cc))
* implement plugin for switch mode ([9e1193e](https://github.com/H3rmt/hyprshell/commit/9e1193e14b7335af4c017593b2bcafb0a1882f90))
* more strict clippy rules ([fea4993](https://github.com/H3rmt/hyprshell/commit/fea4993df001461e1e0cc7ba64ccedfda605bb3c))
* return Ok / Err from socket ([61e09b7](https://github.com/H3rmt/hyprshell/commit/61e09b799860451290d68f46a0b98dc279ae2962))
* separate config crate ([9d1e370](https://github.com/H3rmt/hyprshell/commit/9d1e370b7c2223171a6fb92d0aba0f9cc2a9ca01))
* split launcher plugin into 2 data ([c0ff0b7](https://github.com/H3rmt/hyprshell/commit/c0ff0b74cce58f0eec04f79754971863770ebac3))
* store clippy lints in cargo.toml ([4387f52](https://github.com/H3rmt/hyprshell/commit/4387f52881a05780efa34de0457271363400c121))
* use different dirs for debug mode ([045def3](https://github.com/H3rmt/hyprshell/commit/045def381c611950851d4819b973a791ea896a2c))
* use global desktopfile and mime cache ([ea64c40](https://github.com/H3rmt/hyprshell/commit/ea64c408bbb4ca1d84eabadab3d6a9db9632b1de))
* use keymaps in hyprland plugin ([e0cd4da](https://github.com/H3rmt/hyprshell/commit/e0cd4daae2ed88ab7129a1f2c4dffca98d78d371))
* use make to improve plugin build time ([df032f4](https://github.com/H3rmt/hyprshell/commit/df032f4a1559dd13e60131a731e4d6e8d449de98))
* using plugin for all keyboard interactions ([ae39988](https://github.com/H3rmt/hyprshell/commit/ae39988bc3206089fb1b729d98b1ead4df1f32b9))
* using plugin for all keyboard interactions ([9dfa549](https://github.com/H3rmt/hyprshell/commit/9dfa5494bfd526d3acace3730f0edd9f7fbbe1eb))
### Documentation
* update CONFIGURE.md ([#304](https://github.com/H3rmt/hyprshell/issues/304)) ([9e590a0](https://github.com/H3rmt/hyprshell/commit/9e590a0339b547dfceea07ee8165eda649b1c8ec))
* updated docs ([d713230](https://github.com/H3rmt/hyprshell/commit/d713230fe5435b1f75e78b53c8e749423283a8af))
## [4.5.0](https://github.com/H3rmt/hyprshell/compare/v4.4.3...v4.5.0) (2025-06-27)
### Features
* added path plugin ([910aa35](https://github.com/H3rmt/hyprshell/commit/910aa357abc27c4c6f801d19920feed4e05549f1))
### Documentation
* update screenshots ([e9b8c7c](https://github.com/H3rmt/hyprshell/commit/e9b8c7ce5b2915ec13adf2cbd8994a3eb669408f))
## [4.4.3](https://github.com/H3rmt/hyprshell/compare/v4.4.2...v4.4.3) (2025-06-26)
### Bug Fixes
* fix modifier keys to launch again... ([d31ee66](https://github.com/H3rmt/hyprshell/commit/d31ee669c8da6460b1b0821b9b66783fd10c4a0e))
* use correct keys for switch mode ([b1c3353](https://github.com/H3rmt/hyprshell/commit/b1c335325f68ca1c5810fac772072640d5db464f))
### Code Refactoring
* changed PKGBUILD ([b3f207d](https://github.com/H3rmt/hyprshell/commit/b3f207d7bc0c27892d30fa2420053f27b8e714e6))
## [4.4.2](https://github.com/H3rmt/hyprshell/compare/v4.4.1...v4.4.2) (2025-06-26)
### Bug Fixes
* fix launcher keybinds ([05b2867](https://github.com/H3rmt/hyprshell/commit/05b28670edef4ca23e47100785b90b57b8311c06))
* fix modifier keys to launch, added launch_modifier ([19ba571](https://github.com/H3rmt/hyprshell/commit/19ba57169ae4c77e1e5331c764828f7f67703b90))
* **nix-flake:** update flake.lock ([abeaea5](https://github.com/H3rmt/hyprshell/commit/abeaea56cb568cb8e30ab8289e194ce10c46ec26))
* run flake update ci on hyprshell branch ([b39d435](https://github.com/H3rmt/hyprshell/commit/b39d435af9ceb60b25667bf70965499828f1f719))
### Code Refactoring
* simplify flake ([431536c](https://github.com/H3rmt/hyprshell/commit/431536cddc88606ebe2246ddb755c10a2db51643))
### Documentation
* update nix docs ([d0f45f1](https://github.com/H3rmt/hyprshell/commit/d0f45f1fdaeac348e25d5c5f7c95f76cabefb3d0))
## [4.4.1](https://github.com/H3rmt/hyprshell/compare/v4.4.0...v4.4.1) (2025-06-24)
### Bug Fixes
* run flake update ci on hyprshell branch ([b39d435](https://github.com/H3rmt/hyprshell/commit/b39d435af9ceb60b25667bf70965499828f1f719))
### Code Refactoring
* simplify flake ([431536c](https://github.com/H3rmt/hyprshell/commit/431536cddc88606ebe2246ddb755c10a2db51643))
### Documentation
* update nix docs ([d0f45f1](https://github.com/H3rmt/hyprshell/commit/d0f45f1fdaeac348e25d5c5f7c95f76cabefb3d0))
## [4.4.0](https://github.com/H3rmt/hyprshell/compare/v4.3.1...v4.4.0) (2025-06-24)
### Features
* add tui question for switch>show_workspaces ([8e0d925](https://github.com/H3rmt/hyprshell/commit/8e0d9254ec9e0556a1f7b214acbb70a98710c1ca))
* added show_workspaces flag ([bbba547](https://github.com/H3rmt/hyprshell/commit/bbba5472ed493b4ce5f0b4efe47e98c303e734b6))
### Bug Fixes
* dont allow opening overview and switch at the same time. ([7b61fd5](https://github.com/H3rmt/hyprshell/commit/7b61fd58627a7fe5be85c4322fd506b57b8685f0))
* dont launch plugin entries when typing num instead of ctrl + num ([7b61fd5](https://github.com/H3rmt/hyprshell/commit/7b61fd58627a7fe5be85c4322fd506b57b8685f0))
* fix nix strip_html_from_workspace_title ([e3f02ea](https://github.com/H3rmt/hyprshell/commit/e3f02ea902fd84fe6201fe29bf221e9804100f57))
* fix nix version setting ([06fd3f7](https://github.com/H3rmt/hyprshell/commit/06fd3f7f0de5e3f8c7ae80eb99e98f953766c81e))
* generate correct keybinds for opening overview with super + <key>, fix [#254](https://github.com/H3rmt/hyprshell/issues/254) ([9d52a57](https://github.com/H3rmt/hyprshell/commit/9d52a57baa17a0b41897073b3602619bc04f53d4))
* mark the current workspace as active if the overview is opened without an active client ([f6eaa02](https://github.com/H3rmt/hyprshell/commit/f6eaa0212782e35d2d0d051f77da53b3efaeda7c))
* removed old nix navigate assertions ([8151fba](https://github.com/H3rmt/hyprshell/commit/8151fba64718e69e7ed3a9d46bccfd54a84329d6))
### Code Refactoring
* add better nix checks and switch to nix only for ci ([b5f8682](https://github.com/H3rmt/hyprshell/commit/b5f86823ed599f2f133b6cba8271248417fbe03f))
* added check-if-default command for ci ([db912d1](https://github.com/H3rmt/hyprshell/commit/db912d1f1b6919e71288b9cc75e703071bce559e))
* separate nix code utils ([a3b61e8](https://github.com/H3rmt/hyprshell/commit/a3b61e869c6ff60b4b755f4b2c977ffbc4d82d91))
### Documentation
* update CONFIGURE.md ([24b9799](https://github.com/H3rmt/hyprshell/commit/24b979918340dd76515686996cf836e61cd96694))
## [4.3.1](https://github.com/H3rmt/hyprshell/compare/v4.3.0...v4.3.1) (2025-06-21)
### Bug Fixes
* repair launcher control keys ([78147fa](https://github.com/H3rmt/hyprshell/commit/78147fa354e3b961b19ce8a9a147601434d71d06))
## [4.3.0](https://github.com/H3rmt/hyprshell/compare/v4.2.12...v4.3.0) (2025-06-21)
### Features
* switch to gtk key handling ([65a0ad5](https://github.com/H3rmt/hyprshell/commit/65a0ad5f482707cab8339c3c01195ff9b5557c1a))
### Bug Fixes
* **deps:** update rust crate libc to v0.2.174 ([b6d1089](https://github.com/H3rmt/hyprshell/commit/b6d10891ce2bc1f649a6af7d62f2f7f2fa09d74b))
* fix closing on mod keys other than open key ([d6aba16](https://github.com/H3rmt/hyprshell/commit/d6aba16a2eedfee40bd74feae95750d75c2edf85))
* fix colored output for explain command ([5cbf8ed](https://github.com/H3rmt/hyprshell/commit/5cbf8ede5d3323b6d7484ab1b638f26842165e83))
### Code Refactoring
* remove launcher dependency of overview/switch crate ([df40faa](https://github.com/H3rmt/hyprshell/commit/df40faaec4bf5e5466575d6189194b97e303ac78))
* remove submaps (10/10) ([c7551ea](https://github.com/H3rmt/hyprshell/commit/c7551ea526583841b5de1b8071ee22a6d5b158fd))
* remove submaps (3/?) ([9f0c09e](https://github.com/H3rmt/hyprshell/commit/9f0c09e32d8a2ead763f38810f06b71e7dfa93e9))
* remove submaps (4/?) ([765c88c](https://github.com/H3rmt/hyprshell/commit/765c88c331c3b0e7d834857ef8dc76f235a342ad))
* remove submaps (5/?) ([65b31cf](https://github.com/H3rmt/hyprshell/commit/65b31cf95ec0edb16357cd865f8d2fa6a22f4e6a))
* remove submaps (6/?) ([0bc4396](https://github.com/H3rmt/hyprshell/commit/0bc43963a7783a03fc0681f43549e2cd55a56bc7))
* remove submaps (7/?) ([fdc797d](https://github.com/H3rmt/hyprshell/commit/fdc797d52cba759167a93f88e03b66609ef54f78))
* remove submaps (8/?) ([9de4678](https://github.com/H3rmt/hyprshell/commit/9de46780f4b2cfeb0f5f4fe9e39c67aebc9e8730))
* remove submaps (9/?) ([b3f0209](https://github.com/H3rmt/hyprshell/commit/b3f02096c69aa90ca49eebd02b922fb8a127c1b2))
## [4.2.12](https://github.com/H3rmt/hyprshell/compare/v4.2.11...v4.2.12) (2025-06-20)
### Bug Fixes
* repair ci ([eaf5391](https://github.com/H3rmt/hyprshell/commit/eaf5391a28a9821caaec626baab2a78211ee7cdd))
* repair ci ([e0f8af6](https://github.com/H3rmt/hyprshell/commit/e0f8af675a8702fa50c062030b00c51d2f0d4c30))
* repair ci ([ca782ce](https://github.com/H3rmt/hyprshell/commit/ca782ce03493b3d01f1e30540b7869ff20b0ad1e))
* repair ci ([761bd1b](https://github.com/H3rmt/hyprshell/commit/761bd1b3444f35c32924efbdd1fc375452600096))
* repair ci ([0aadfcc](https://github.com/H3rmt/hyprshell/commit/0aadfcc95262f34f49fd535fc88a35f767997423))
* show toast when using switch mode ([a34a9bb](https://github.com/H3rmt/hyprshell/commit/a34a9bbe2460dd44213fc5c15d7c34a140b19315))
* use release branch in ci to create new commits ([d8a489e](https://github.com/H3rmt/hyprshell/commit/d8a489e80070f3a3c7d9d451a9f4b04f703fb2d9))
## [4.2.11](https://github.com/H3rmt/hyprshell/compare/v4.2.10...v4.2.11) (2025-06-20)
### Bug Fixes
* repair ci ([ca782ce](https://github.com/H3rmt/hyprshell/commit/ca782ce03493b3d01f1e30540b7869ff20b0ad1e))
## [4.2.10](https://github.com/H3rmt/hyprshell/compare/v4.2.9...v4.2.10) (2025-06-20)
### Bug Fixes
* repair ci ([761bd1b](https://github.com/H3rmt/hyprshell/commit/761bd1b3444f35c32924efbdd1fc375452600096))
* repair ci ([0aadfcc](https://github.com/H3rmt/hyprshell/commit/0aadfcc95262f34f49fd535fc88a35f767997423))
* show toast when using switch mode ([a34a9bb](https://github.com/H3rmt/hyprshell/commit/a34a9bbe2460dd44213fc5c15d7c34a140b19315))
* use release branch in ci to create new commits ([d8a489e](https://github.com/H3rmt/hyprshell/commit/d8a489e80070f3a3c7d9d451a9f4b04f703fb2d9))
## [4.2.9](https://github.com/H3rmt/hyprshell/compare/v4.2.8...v4.2.9) (2025-06-20)
### Bug Fixes
* repair ci ([0aadfcc](https://github.com/H3rmt/hyprshell/commit/0aadfcc95262f34f49fd535fc88a35f767997423))
## [4.2.8](https://github.com/H3rmt/hyprshell/compare/v4.2.7...v4.2.8) (2025-06-20)
### Bug Fixes
* use release branch in ci to create new commits ([d8a489e](https://github.com/H3rmt/hyprshell/commit/d8a489e80070f3a3c7d9d451a9f4b04f703fb2d9))
## [4.2.7](https://github.com/H3rmt/hyprshell/compare/v4.2.6...v4.2.7) (2025-06-20)
### Bug Fixes
* show toast when using switch mode ([a34a9bb](https://github.com/H3rmt/hyprshell/commit/a34a9bbe2460dd44213fc5c15d7c34a140b19315))
## [4.2.6](https://github.com/H3rmt/hyprshell/compare/v4.2.5...v4.2.6) (2025-06-20)
### Bug Fixes
* show toast when using switch mode ([a34a9bb](https://github.com/H3rmt/hyprshell/commit/a34a9bbe2460dd44213fc5c15d7c34a140b19315))
## [4.2.5](https://github.com/H3rmt/hyprshell/compare/v4.2.4...v4.2.5) (2025-06-11)
### Bug Fixes
* fix run programs ([3997d2a](https://github.com/H3rmt/hyprshell/commit/3997d2a85e77d2d0e3a6799b17518ad5886aca74))
## [4.2.4](https://github.com/H3rmt/hyprswitch/compare/v4.2.3...v4.2.4) (2025-06-11)
### Bug Fixes
* diable gestures and input:follow_mouse on start and reset after close ([6a516b2](https://github.com/H3rmt/hyprswitch/commit/6a516b23e9124f577e16d2475962f8e3347237ae))
## [4.2.3](https://github.com/H3rmt/hyprswitch/compare/v4.2.2...v4.2.3) (2025-06-11)
### Bug Fixes
* fix storage of input:follow_mouse setting ([62ab0f2](https://github.com/H3rmt/hyprswitch/commit/62ab0f2f90a7235e3e2d6a8aa9267ebff4c16348))
* fix systemd exit ([26ae103](https://github.com/H3rmt/hyprswitch/commit/26ae103729696a02069c873bad76c2edbe9dcdf6))
## [4.2.2](https://github.com/H3rmt/hyprswitch/compare/v4.2.1...v4.2.2) (2025-06-11)
### Bug Fixes
* add HYPRSHELL_RELOAD_TIMEOUT to change timeout ([764cbb2](https://github.com/H3rmt/hyprswitch/commit/764cbb211ee0a2a1382443b34e58e8a4a035fdb9))
## [4.2.1](https://github.com/H3rmt/hyprswitch/compare/v4.2.0...v4.2.1) (2025-06-11)
### Bug Fixes
* add show_actions_submenu with default false ([c0828d6](https://github.com/H3rmt/hyprswitch/commit/c0828d6706157728e4af7742a8e97f7190a8eec0))
* file watchers work again ([73c7ebf](https://github.com/H3rmt/hyprswitch/commit/73c7ebf0914442c85b8af49e920fdbdd87be10a9))
* use correct path to generate config ([112e7d2](https://github.com/H3rmt/hyprswitch/commit/112e7d26acde6dd98805b69b807b6a5004763a96))
## [4.2.0](https://github.com/H3rmt/hyprswitch/compare/v4.1.1...v4.2.0) (2025-06-11)
### Features
* better window selection on empty workspace ([24b36b3](https://github.com/H3rmt/hyprswitch/commit/24b36b38cc0b127fe2de2a59c223936ffc9c988e))
* **nix:** Add `show_when_empty` ([8ebb333](https://github.com/H3rmt/hyprswitch/commit/8ebb333cd0dad0ff919ea1790136c8e6120d4560))
### Bug Fixes
* close socket after restarting app ([b4a8f2e](https://github.com/H3rmt/hyprswitch/commit/b4a8f2e61d503fb6eee7850ce1ce6f33dfab72bf))
* debounce reload ([5858cfd](https://github.com/H3rmt/hyprswitch/commit/5858cfd475f1e3b604f6d035bdc5507977833af5))
* **deps:** update rust crate clap to v4.5.40 ([19272f4](https://github.com/H3rmt/hyprswitch/commit/19272f40aec98c2820919f4d5924533f12b15fc9))
* **deps:** update rust crate toml to v0.8.23 ([6268be8](https://github.com/H3rmt/hyprswitch/commit/6268be8a74f85eb90dc1d7d94a5057ce6534ce89))
* handle sigterm and reset submap ([1516024](https://github.com/H3rmt/hyprswitch/commit/1516024a04d46f4433f52984197bf6f39eeee6a6))
* improved file watcher, file descriptor limit was reached if reloaded too many times ([b4a8f2e](https://github.com/H3rmt/hyprswitch/commit/b4a8f2e61d503fb6eee7850ce1ce6f33dfab72bf))
* selecting a client with filtering form workspace without an enabled client now selects the first valid client depending on the direction instead of a first client in the workspace ([2a72d8b](https://github.com/H3rmt/hyprswitch/commit/2a72d8ba63ff7c20412d1a9a1dcd7da861c8204b))
* toml config plugins for launcher ([5858cfd](https://github.com/H3rmt/hyprswitch/commit/5858cfd475f1e3b604f6d035bdc5507977833af5))
## [4.1.1](https://github.com/H3rmt/hyprswitch/compare/v4.1.0...v4.1.1) (2025-06-02)
### Bug Fixes
* release workflow now uses deploy keys ([e2c9b89](https://github.com/H3rmt/hyprswitch/commit/e2c9b89f10505a6617f74b3e05c4129b162029ec))
## [4.1.0](https://github.com/H3rmt/hyprswitch/compare/v4.0.4...v4.1.0) (2025-06-02)
### Features
* added kill_bind if hyprshell crashes ([5e0b0fa](https://github.com/H3rmt/hyprswitch/commit/5e0b0fa2cf8b7c7d4902fafff0b0dc4b2d03a84a))
* better parsing of desktop files(ini) to add DesktopActions in launcher ([a304809](https://github.com/H3rmt/hyprswitch/commit/a3048098b1702277cf25e0454e0a7dd3d48c61ee))
* faster open speeds by applying submaps earlier ([a304809](https://github.com/H3rmt/hyprswitch/commit/a3048098b1702277cf25e0454e0a7dd3d48c61ee))
### Bug Fixes
* use new ini parser everywhere ([8db2643](https://github.com/H3rmt/hyprswitch/commit/8db2643a7c5e5b51a316d4654268c38bc2202be4))
## [4.0.4](https://github.com/H3rmt/hyprswitch/compare/v4.0.3...v4.0.4) (2025-06-01)
### Bug Fixes
* more debugging for default browser to fix [#188](https://github.com/H3rmt/hyprswitch/issues/188) ([551bfd0](https://github.com/H3rmt/hyprswitch/commit/551bfd0b58aedbccc93236595beab63dcf9195dc))
## [4.0.3](https://github.com/H3rmt/hyprswitch/compare/v4.0.2...v4.0.3) (2025-06-01)
### Bug Fixes
* fixed icon scaling ([5a0489a](https://github.com/H3rmt/hyprswitch/commit/5a0489a39742d89abed3760096c3dccee2fa5845))
* remove launch animation from plugins after close ([685b7bd](https://github.com/H3rmt/hyprswitch/commit/685b7bdf205cafc48e9a21aaccd9428e774905d9))
* use dbus to open if no browser was found ([c074a56](https://github.com/H3rmt/hyprswitch/commit/c074a56ac7603c14754a4b20a65eeb095e2a103d))
## [4.0.2](https://github.com/H3rmt/hyprswitch/compare/v4.0.1...v4.0.2) (2025-05-31)
### Bug Fixes
* fixed the PKGBUILD for arch ([89c06ba](https://github.com/H3rmt/hyprswitch/commit/89c06baa318157827e7042adeaa4ca274b251756))
## [4.0.1](https://github.com/H3rmt/hyprswitch/compare/v4.0.0...v4.0.1) (2025-05-31)
### Bug Fixes
* added the PKGBUILD for arch ([93ca69b](https://github.com/H3rmt/hyprswitch/commit/93ca69b15061f4ad8e4f1bcb674dba59c278571b))
## [4.0.0](https://github.com/H3rmt/hyprswitch/compare/v0.8.2...v4.0.0) (2025-05-31)
### Features
* add animation to plugin close launch ([b944274](https://github.com/H3rmt/hyprswitch/commit/b9442742b5a357966061c66e594b9104d158fe7b))
* add calc plugin ([06c8a41](https://github.com/H3rmt/hyprswitch/commit/06c8a41db42d482b777f158fcf9eb1b23708cc13))
* add debug command ([00afa1e](https://github.com/H3rmt/hyprswitch/commit/00afa1e34b9716a041d3bd33734700836075bd70))
* Add NixOS `home-manager` module ([cd20717](https://github.com/H3rmt/hyprswitch/commit/cd207178a0cfd44c7ad1069880ef35532f5547ae))
* add run shell commands from launcher ([879cbba](https://github.com/H3rmt/hyprswitch/commit/879cbba0597281c14b07dadfe03149b4323caf6f))
* add websearch plugin ([1a079d1](https://github.com/H3rmt/hyprswitch/commit/1a079d1552036f8713ba69f33271475ff4a41103))
* added `data` command to see LaunchHistory ([8e3de53](https://github.com/H3rmt/hyprswitch/commit/8e3de53b31834c8a034d28d26d72ebcbbd4d9815))
* added click on clients and workspaces in overview and switch ([328fc3b](https://github.com/H3rmt/hyprswitch/commit/328fc3b432b28ad1e390be10f945e1425708d430))
* added config file migrations ([db2f6cd](https://github.com/H3rmt/hyprswitch/commit/db2f6cd9fb3c08ab2f9858fb9c1dac61540353b5))
* added custom args for hyprshell systemd ([aa01139](https://github.com/H3rmt/hyprswitch/commit/aa01139aebfe2dcd717b670ac6ce557f93c2f1d0))
* added show_when_empty ([6f916d5](https://github.com/H3rmt/hyprswitch/commit/6f916d5b0355293eb0d4007b3c996deddb943c0d))
* added systemd generation (use --no-systemd to disable) ([97c2c7f](https://github.com/H3rmt/hyprswitch/commit/97c2c7f88c3ba221863a43b8adbfb50b444fa841))
* better debug commands ([b17a393](https://github.com/H3rmt/hyprswitch/commit/b17a393b04201beab8b582a340d1bb80bef5cda2))
* click on entry in launcher works ([87076ef](https://github.com/H3rmt/hyprswitch/commit/87076ef8c715fc0f7e29a7c2187aa59f17514df5))
* NixOS Support ([#171](https://github.com/H3rmt/hyprswitch/issues/171)) ([d42f12b](https://github.com/H3rmt/hyprswitch/commit/d42f12be62c08d3764bc91b034bc7aa05d531608))
* rewrite hyprswitch ([198cd0f](https://github.com/H3rmt/hyprswitch/commit/198cd0f5ae03210b46cfaba8dbf5f8d30fcc77a9))
* rewrite hyprswitch ([0d834ab](https://github.com/H3rmt/hyprswitch/commit/0d834ab64cb607d2bc10ca7b13d2642728592f50))
### Bug Fixes
* add aur publish ([fc4f9ab](https://github.com/H3rmt/hyprswitch/commit/fc4f9ab4f040646ff075930a86457bf7d4f3e77c))
* add nix back ([9efadcd](https://github.com/H3rmt/hyprswitch/commit/9efadcdc37ae0c639ab36a1880e3d48b1b6c51a2))
* allow hold of tab and arrow keys to switch ([e0aaa57](https://github.com/H3rmt/hyprswitch/commit/e0aaa570f54fce0155631c5720805886a0c275a1))
* arrow keys in the launcher ([179ca7b](https://github.com/H3rmt/hyprswitch/commit/179ca7b45e865875584a4c658a0455ea00af0bc6))
* background loading of icons ([f5c8ff0](https://github.com/H3rmt/hyprswitch/commit/f5c8ff0e29713432726bb841bafd8dd6729331fa))
* better icon detection ([453888e](https://github.com/H3rmt/hyprswitch/commit/453888e61551946cfa3dec92409df606f7aa04db))
* check for config file extensions at start ([7a41bb2](https://github.com/H3rmt/hyprswitch/commit/7a41bb2bf8abea7b2bc2efc2544deb26243faf7c))
* ci release ([4a0f45f](https://github.com/H3rmt/hyprswitch/commit/4a0f45f466d47a12e6cab70d2e71c835287287a0))
* close launcher on esc ([a003b82](https://github.com/H3rmt/hyprswitch/commit/a003b8227b709a7bb186e2b3703ec70f3f16dd7d))
* detect socat path at runtime ([312f667](https://github.com/H3rmt/hyprswitch/commit/312f6677165a023466a115d8a61f2927b31adc71))
* don't exit launcher when no items ([a4356b7](https://github.com/H3rmt/hyprswitch/commit/a4356b783c148f61736fcd9e4af23d63b1be7c85))
* don't unset all CSS styles at the start, only necessary ([b42d25c](https://github.com/H3rmt/hyprswitch/commit/b42d25c1d342d10a5af378e1ebcae167a83ca01f))
* filter apps in the launcher by name, exec and details ([ab0f23e](https://github.com/H3rmt/hyprswitch/commit/ab0f23e43c4ce540e14fe3f0ac515fa52ec56ab9))
* fix ci publish ([bb1e659](https://github.com/H3rmt/hyprswitch/commit/bb1e65987ac7c371b29cbf09000bb4f117f5b0e9))
* fix ci release ([e498ca1](https://github.com/H3rmt/hyprswitch/commit/e498ca19f86fcf2d4668fa7582f9320232fd194d))
* fix ci release ([6dc00c7](https://github.com/H3rmt/hyprswitch/commit/6dc00c719ef7beaea70c86f7851c6de8cdf9117e))
* fix focus window problem ([3c702a1](https://github.com/H3rmt/hyprswitch/commit/3c702a1da63d56168aa6e7ba2932842c55f97c8d))
* fix multiple run week caches not being added together ([c027209](https://github.com/H3rmt/hyprswitch/commit/c027209d6f01ec10210420182ea3283380f8e74f))
* Fix Nix Build ([02bd2c4](https://github.com/H3rmt/hyprswitch/commit/02bd2c400616cb96cd21ccc6b2f530143fcb511b))
* fix overflow for selecting workspaces ([9efadcd](https://github.com/H3rmt/hyprswitch/commit/9efadcdc37ae0c639ab36a1880e3d48b1b6c51a2))
* fix overview click on client or workspace ([71d445c](https://github.com/H3rmt/hyprswitch/commit/71d445c0f310f986b769eb420b55e21e9559d94d))
* fix panic when listening for changes on nonexisting file ([2e02509](https://github.com/H3rmt/hyprswitch/commit/2e025099b4b259844a6f5192a4e9db3db10a00ba))
* fix right alt bind ([4394240](https://github.com/H3rmt/hyprswitch/commit/43942408b0febe18026e278d2e4cffd7eece25db))
* fix slow start times ([0c4bb95](https://github.com/H3rmt/hyprswitch/commit/0c4bb9585806de61f73e885026083e49b2fe2048))
* fix switch mode monitor select ([b8c1d44](https://github.com/H3rmt/hyprswitch/commit/b8c1d440d47fe4a6ca2c1690e1b0be65b81de1df))
* fix versions ([899b2cc](https://github.com/H3rmt/hyprswitch/commit/899b2cc95018a342c2bf45d0fdf0ef971616be7b))
* fix versions ([e9565fd](https://github.com/H3rmt/hyprswitch/commit/e9565fd627c85ed4fa8fcf26cd35c06ceeaeb2b7))
* fix versions ([8d9a5ee](https://github.com/H3rmt/hyprswitch/commit/8d9a5eeeee5d74fef9501fec39c5d8692061ec97))
* fix versions ([05f3da6](https://github.com/H3rmt/hyprswitch/commit/05f3da60197e59d6a882fa0282127ae62091f879))
* fix versions ([b4e0380](https://github.com/H3rmt/hyprswitch/commit/b4e0380cced9b3ae35e3d8368fb336edc5530274))
* fix versions ([14e4a72](https://github.com/H3rmt/hyprswitch/commit/14e4a725dfe6b0d70c235db80069238338ec2890))
* fix versions ([89711a6](https://github.com/H3rmt/hyprswitch/commit/89711a628c45d6286742ac274ad4ec2fe487faed))
* fix wrong name in hm module ([99386d5](https://github.com/H3rmt/hyprswitch/commit/99386d56c0e40e65bc491e2b87cf28ef83305f6d))
* force command now accepts args ([7a41bb2](https://github.com/H3rmt/hyprswitch/commit/7a41bb2bf8abea7b2bc2efc2544deb26243faf7c))
* get socat path at buildtime ([a4356b7](https://github.com/H3rmt/hyprswitch/commit/a4356b783c148f61736fcd9e4af23d63b1be7c85))
* make css optional ([b0c36ee](https://github.com/H3rmt/hyprswitch/commit/b0c36eeb3f9dfbe9a85933505dc618cd0c231308))
* move scripts ([97329b7](https://github.com/H3rmt/hyprswitch/commit/97329b723d4c90e674fa74d65fb4397252266b85))
* moved size_factor to scale for a more sensible default and bounds check ([a85f3b8](https://github.com/H3rmt/hyprswitch/commit/a85f3b8948211711acf232b9834f4c9c2afadf61))
* nix allow source and text attributes ([dcd9e41](https://github.com/H3rmt/hyprswitch/commit/dcd9e417071e80cfd489eaefc8908a6b12a324eb))
* nix json config fixes ([ced4a45](https://github.com/H3rmt/hyprswitch/commit/ced4a45ef6b8361663b30062298f3084f2219a37))
* **nix:** Fix HM Module ([b8367b4](https://github.com/H3rmt/hyprswitch/commit/b8367b4de9dcd2a5b6e49a3e9322534657de4886))
* open windows earlier ([b42d25c](https://github.com/H3rmt/hyprswitch/commit/b42d25c1d342d10a5af378e1ebcae167a83ca01f))
* reload desktop maps on close ([204358d](https://github.com/H3rmt/hyprswitch/commit/204358dc20ad49ff44d79444f707d20a4535d0da))
* remove size_factor from config ([77b53bd](https://github.com/H3rmt/hyprswitch/commit/77b53bd205d32c0619d244a601cea8304f4a4b9c))
* remove socat dependency ([01758a6](https://github.com/H3rmt/hyprswitch/commit/01758a6d6384c5ad73a841c3f2e8b90ee9912393))
* search for installed terminals from PATH ([453888e](https://github.com/H3rmt/hyprswitch/commit/453888e61551946cfa3dec92409df606f7aa04db))
* show recent windows on one screen only ([f6a3016](https://github.com/H3rmt/hyprswitch/commit/f6a301689827ebb27afc10d445715c070a5762f1))
* some focus fixes ([9fa8009](https://github.com/H3rmt/hyprswitch/commit/9fa80093f943f6941aeaeb424a262cb3b4c40ec6))
* sort launcher applications by shorted exec instead of full (removed /bin/flatpak...) ([b17a393](https://github.com/H3rmt/hyprswitch/commit/b17a393b04201beab8b582a340d1bb80bef5cda2))
* speedup animation ([179ca7b](https://github.com/H3rmt/hyprswitch/commit/179ca7b45e865875584a4c658a0455ea00af0bc6))
* switch window if no results are present in launcher ([50a81a0](https://github.com/H3rmt/hyprswitch/commit/50a81a0503f8f259374fdafab73e383f930902fe))
* try all config extensions if file missing ([6cd4799](https://github.com/H3rmt/hyprswitch/commit/6cd4799198c7b170537135a611c8ed88b97aa62f))
* try to fix publication to creates.io ([c911a07](https://github.com/H3rmt/hyprswitch/commit/c911a078e40655fd869df317479a6a93cce508b2))
* update documentation ([229921d](https://github.com/H3rmt/hyprswitch/commit/229921d82167d59670cdeab488677b372ecafe73))
* Update Nix Package ([a147d38](https://github.com/H3rmt/hyprswitch/commit/a147d385ee5928e0616d232f741657069242272f))
* use char instead of String for key for websearch plugins ([eba4282](https://github.com/H3rmt/hyprswitch/commit/eba42823569cbf19dcb35cf37cc78db7bcdb0e3b))
### Documentation
* fix css explain images ([d86d566](https://github.com/H3rmt/hyprswitch/commit/d86d5667201031915100391c1eeb9571e763f370))
### Continuous Integration
* fix ci release ([a24657b](https://github.com/H3rmt/hyprswitch/commit/a24657bb9e237e69ff2f8687577114c25de921fe))
* fix ci release ([e02df4a](https://github.com/H3rmt/hyprswitch/commit/e02df4a193718664762ba8d7e22c63814f061de3))
* fix ci release ([d8d481d](https://github.com/H3rmt/hyprswitch/commit/d8d481d672809a4f8907a156eed1705caa27a9aa))
* fix release-please again ([824bf03](https://github.com/H3rmt/hyprswitch/commit/824bf032ab3b131121b16d9c16ce9f6a5215c580))
* fix release-please again ([bce2335](https://github.com/H3rmt/hyprswitch/commit/bce23355cd3f477e95179acadd5d1401544b1822))
* fix releases ([06ad9fc](https://github.com/H3rmt/hyprswitch/commit/06ad9fc8cc85a4a6fe3584510bce0efbd1aa1425))
* switch CI back to normal repo ([9aec89c](https://github.com/H3rmt/hyprswitch/commit/9aec89c4705d1c9683d30274aa442512e3665493))
================================================
FILE: Cargo.toml
================================================
[workspace]
members = ["crates/exec-lib", "crates/core-lib", "crates/windows-lib", "crates/launcher-lib", "crates/config-lib", "crates/hyprland-plugin", "crates/clipboard-lib", "dep-crates/hyprland-rs", "dep-crates/hyprland-rs/hyprland-macros", "dep-crates/wl-clipboard-rs", "crates/config-edit-lib"]
[workspace.package]
version = "4.9.5"
description = "A modern GTK4-based window switcher and application launcher for Hyprland"
license = "MIT"
authors = ["h3rmt"]
keywords = ["hyprland"]
repository = "https://github.com/h3rmt/hyprshell/"
# update when nixpkgs has a newer rustc
rust-version = "1.91.0"
edition = "2024"
[workspace.dependencies]
anyhow = { version = "1.0.100" }
tracing = { version = "0.1.44" }
serde_json = { version = "1.0.148" }
serde = { version = "1.0.228", features = ["derive"] }
async-channel = { version = "2.5.0", default-features = true }
semver = { version = "1.0.27" }
test-log = { version = "0.2.19", default-features = false, features = ["trace", "unstable"] }
relm4 = { version = "0.10.0", default-features = false, features = ["libadwaita", "macros", "gnome_48"] }
relm4-components = "0.10.0"
gtk4-layer-shell = { version = "0.7.1" }
config-lib = { path = "crates/config-lib", package = "hyprshell-config-lib", version = "=4.9.5" }
core-lib = { path = "crates/core-lib", package = "hyprshell-core-lib", version = "=4.9.5" }
exec-lib = { path = "crates/exec-lib", package = "hyprshell-exec-lib", version = "=4.9.5" }
hyprland-plugin = { path = "crates/hyprland-plugin", package = "hyprshell-hyprland-plugin", version = "=4.9.5" }
[package]
name = "hyprshell"
readme = "README.md"
categories = []
documentation = "https://docs.rs/hyprshell"
version = "4.9.5"
edition.workspace = true
description.workspace = true
license.workspace = true
authors.workspace = true
keywords.workspace = true
repository.workspace = true
rust-version.workspace = true
exclude = [".idea/*", ".github/*"]
[dependencies]
anyhow.workspace = true
tracing.workspace = true
relm4.workspace = true
async-channel.workspace = true
semver.workspace = true
clap = { version = "4.5.47", features = ["derive"] }
clap_complete = "4.5.57"
tracing-subscriber = { version = "0.3.20", features = ["fmt", "env-filter", "ansi"], default-features = false }
signal-hook = { version = "0.4.1" }
config-lib.workspace = true
core-lib.workspace = true
exec-lib.workspace = true
clipboard-lib = { path = "crates/clipboard-lib", package = "hyprshell-clipboard-lib", version = "=4.9.5" }
windows-lib = { path = "crates/windows-lib", package = "hyprshell-windows-lib", version = "=4.9.5" }
launcher-lib = { path = "crates/launcher-lib", package = "hyprshell-launcher-lib", version = "=4.9.5" }
config-edit-lib = { path = "crates/config-edit-lib", package = "hyprshell-config-edit-lib", version = "=4.9.5", optional = true }
[dev-dependencies]
test-log.workspace = true
[features]
default = ["json5_config", "gui_settings_editor", "launcher_calc", "debug_command", "clipboard_compress_lz4", "clipboard_compress_zstd", "clipboard_compress_brotli", "clipboard_encrypt_chacha20poly1305", "clipboard_encrypt_aes_gcm"]
slim = ["gui_settings_editor", "debug_command", "clipboard_compress_lz4"]
json5_config = ["config-lib/json5_config"]
gui_settings_editor = ["dep:config-edit-lib"]
launcher_calc = ["launcher-lib/calc", "config-lib/launcher_calc_plugin", "config-edit-lib?/launcher_calc_plugin"]
debug_command = []
ci_config_check = ["config-lib/ci_no_default_config_values"]
clipboard_compress_lz4 = ["clipboard-lib/compress_lz4"]
clipboard_compress_zstd = ["clipboard-lib/compress_zstd"]
clipboard_compress_brotli = ["clipboard-lib/compress_brotli"]
clipboard_encrypt_chacha20poly1305 = ["clipboard-lib/encrypt_chacha20poly1305"]
clipboard_encrypt_aes_gcm = ["clipboard-lib/encrypt_aes_gcm"]
[profile.release]
strip = "debuginfo"
lto = true
opt-level = 3
[lints]
workspace = true
[workspace.lints.clippy]
all = { level = "warn", priority = -1 }
pedantic = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }
unwrap_used = "deny"
single_match = "allow"
match_wildcard_for_single_variants = "allow"
struct_excessive_bools = "allow"
missing_errors_doc = "allow"
cast_possible_truncation = "allow"
# This is broken
uninlined_format_args = "warn"
unnecessary_debug_formatting = "warn"
unnecessary_wraps = "warn"
pathbuf_init_then_push = "warn"
print_stdout = "warn"
print_stderr = "warn"
================================================
FILE: DEVELOPMENT.md
================================================
# Development Guide
Welcome to the Hyprshell development guide. This document provides information on how to set up your environment, the project structure, and common development tasks.
## Prerequisites
To develop for Hyprshell, you need to have the following installed:
- **Rust**: Latest stable version (minimum `1.92.0`).
- **GTK4 & Libadwaita**: Development headers for GTK4 and Libadwaita.
- **GTK4 Layer Shell**: Development headers for [gtk4-layer-shell](https://github.com/wmww/gtk4-layer-shell).
- **Hyprland**: Minimum version `0.52.1`. Development headers (`hyprland-devel`) are needed for the plugin.
- **just**: A handy command runner used for various development tasks.
### Installing `just`
We use [just](https://github.com/casey/just) to automate common tasks. You can install it using your package manager:
- **Arch Linux**: `sudo pacman -S just`
- **Fedora**: `sudo dnf install just`
- **Nix**: `nix-shell -p just` or add it to your flake.
- **Cargo**: `cargo install just`
## Project Structure
Hyprshell is organized as a Rust workspace with multiple crates and some vendored dependencies.
### Directories
- `crates/`: Contains the internal libraries that make up Hyprshell.
- `core-lib`: Fundamental types and utilities.
- `config-lib`: Configuration loading, generation, and migration.
- `config-edit-lib`: The GUI settings editor.
- `exec-lib`: Hyprland specific logic and plugin management.
- `launcher-lib`: Logic for the application launcher.
- `windows-lib`: Logic for the window switcher.
- `clipboard-lib`: Clipboard management and history.
- `hyprland-plugin`: A C++ Hyprland plugin used to capture keyboard events.
- `dep-crates/`: Contains forks or local versions of external dependencies.
- `hyprland-rs`: A fork of the Hyprland IPC library.
- `wl-clipboard-rs`: A fork of the Wayland clipboard library.
- `src/`: Contains the main entry point for the `hyprshell` binary.
- `scripts/`: Various helper scripts for CI and development.
- `nix/`: Nix-related files for building and development shells.
- `docs/`: Documentation files.
- `packaging/`: Files for packaging Hyprshell.
## Common Tasks
We use `just` to run common development tasks. Run `just` without arguments to see a full list of available commands.
### Development
- `just run`: Run the application in debug mode (prints available commands).
- `just run release`: Run the application in release mode.
- `just run-run`: Run the application process in debug mode.
### Environment Variables
Useful environment variables for development:
- `HYPRSHELL_EXPERIMENTAL=1`: Enables experimental features.
- `HYPRSHELL_LOG_MODULE_PATH=1`: Adds module path to logs (use with `-vv`).
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2025 Enrico Stemmer
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Hyprshell
[](https://crates.io/crates/hyprshell) [](https://docs.rs/hyprshell)

## Overview
Hyprshell _(previously hyprswitch)_ is a Rust-based GUI designed to enhance window management in [Hyprland](https://github.com/hyprwm/Hyprland).
It provides a powerful and customizable interface for switching between windows using keyboard shortcuts and GUI.
The application also includes a launcher for running applications, doing calculations, etc.
## Features
- **Window Switching**: Switch between windows using keyboard shortcuts in a GUI.
- **Customizable Keybindings**: Define your own keybindings for window switching and GUI interactions.
- **Config**: Interactive [config file](docs/CONFIGURE.md) generation for easy setup.
- **Launcher Integration**: Launch applications directly from the GUI, sorted by usage frequency.
- **Launcher Plugins**: Different plugins like Web search, actions or calculations can be enabled.
- **Theming**: Customize the GUI appearance (gtk4) using [CSS](docs/CONFIGURE.md).
- **Settings App**: Customize the application using a settings app.
- **Dynamic Configuration**: Automatically reloads configuration/style changes without restarting the application.
- **Debug commands**: Many [Commands](docs/DEBUG.md) to debug desktop files, icons and default applications.
## Installation
**Minimum hyprland version: 0.52.1**
[](https://repology.org/project/hyprshell/versions)
### Arch Linux (AUR)
```bash
paru -S hyprshell
# or
yay -S hyprshell
```
Use `hyprshell-bin` for the pre-built binaries from GitHub releases.
Use `hyprshell-slim` for the [slim](#feature-flags) version (faster buildtime).
### Binary pre-built packages (only for x86_64 and aarch64)
Download and extract from the latest release on the [releases](https://github.com/h3rmt/hyprshell/releases) page.
### NixOS
This repository contains a `flake` and with a type-save `home-manager` module for configuration.
Hyprshell is also available in `nixpkgs` repository and can be configured using a generic `home-manager` module.
More information can be found in the [NixOS](docs/NIX.md) section.
### From Source
hyprland, gtk4[v4_18], libadwaita[v1_8] and [gtk4-layer-shell](https://github.com/wmww/gtk4-layer-shell)[1.1.1] must be installed
```bash
cargo install hyprshell
```
Build with less features in [slim](#feature-flags) mode
```bash
cargo install hyprshell --no-default-features --features "slim"
```
**hyprland-devel is needed for the hyprland headers (needed to build hyprland plugin)**
Fedora: `sudo dnf install gtk4-layer-shell-devel libadwaita-devel hyprland-devel`
Arch: `sudo pacman -Sy gtk4-layer-shell libadwaita hyprland`
Minimum required rustc version: `1.92.0`
## Usage
Run `hyprshell --help` to see available commands and options.
### Config
To generate a default configuration file, run:
```bash
hyprshell config generate
```
This launches an interactive prompt to set up your configuration.
The generated file will be located at `~/.config/hyprshell/config.ron`.
If you want to modify these settings, look at the [Documentation](docs/CONFIGURE.md) for the config file.
To validate your configuration file, run:
```bash
hyprshell config explain
```
This checks for any syntax errors or issues in your configuration file and shows a `explanation` of how to use hyprshell.
To edit the configuration file run `hyprshell config edit`. This launches the settings editor.
### Initialization
Enable the systemd service (generated with `hyprshell config generate`) [recommended]:
```bash
systemctl --user enable --now hyprshell.service
```
Or add the following to your Hyprland configuration (`~/.config/hypr/hyprland.conf`):
```ini
exec-once = hyprshell run &
```


### Debugging
Debug commands are provided to help troubleshoot desktop files, icons, default applications and launcher functionality, see [Debug.md](docs/DEBUG.md) for detailed information about available commands and their usage.
### Feature Flags
✅ = included in the default feature set.
✨ = included in the slim feature set. (build with ``--no-default-features --features "slim"``)
- `gui_settings_editor`✅✨: Adds the `hyprshell config edit` command to open the settings editor.
- `json5_config`✅: Adds support for a json5 config file.
- `launcher_calc`✅: Adds support for the calc plugin in the launcher.
- `debug_command`✅✨: Adds the `hyprshell debug` command to debug icons, desktop files, etc.
- `clipboard_compress_lz4`✅✨: Adds support for compressing clipboard content using lz4.
- `clipboard_compress_brotli`✅: Adds support for compressing clipboard content using brotli.
- `clipboard_compress_zstd`✅: Adds support for compressing clipboard content using zstd.
- `clipboard_encrypt_chacha20poly1305`✅: Adds support for encrypting clipboard content using chacha20poly1305.
- `clipboard_encrypt_aes_gcm`✅: Adds support for encrypting clipboard content using aes_256_gcm.
- `ci_config_check`: (!used for ci tests) Adds a command to check if the loaded config is equal to the default config or the full config. Also diables loading of configs without all values.
### Env Variables
- `HYPRSHELL_NO_LISTENERS`: Disable all config listeners (config file, css file, hyprland config, monitor count)
- `HYPRSHELL_NO_ALL_ICONS`: Don't check for all icons on fs and just use the ones provided by the `gtk4` icon theme.
- `HYPRSHELL_RELOAD_TIMEOUT`: Set the timeout for reloading the config file in milliseconds (default: `1500`).
- `HYPRSHELL_LOG_MODULE_PATH`: Add the module path to each log message. (use with -vv)
- `HYPRSHELL_NO_USE_PLUGIN`: Disable the use of the hyprland plugin to capture switch mode events.
- `HYPRSHELL_EXPERIMENTAL`: Enables experimental features (grep through the source code for `"HYPRSHELL_EXPERIMENTAL"` to see them)
- `HYPRSHELL_RUN_ACTIONS_IN_DEBUG`: Run actions from launcher plugin in debug mode
================================================
FILE: crates/clipboard-lib/Cargo.toml
================================================
[package]
name = "hyprshell-clipboard-lib"
documentation = "https://docs.rs/hyprshell-clipboard-lib"
version = "4.9.5"
description = "A library monitoring and storing clipboard contents"
edition.workspace = true
license.workspace = true
authors.workspace = true
keywords.workspace = true
repository.workspace = true
rust-version.workspace = true
[dependencies]
anyhow.workspace = true
tracing.workspace = true
core-lib.workspace = true
wl_clipboard = { package = "hyprshell-wl-clipboard-rs", path = "../../dep-crates/wl-clipboard-rs", version = "=4.9.5" }
fast_image_resize = { version = "5.3.0", features = ["image"] }
bitcode = { version = "0.6.9" }
image = { version = "0.25.8", features = ["png", "jpeg", "webp", "gif"], default-features = false }
lz4_flex = { version = "0.12.0", optional = true }
zstd = { version = "0.13.3", optional = true }
brotli = { version = "8.0.2", optional = true }
secret-service = { version = "5.0.0", features = ["rt-tokio-crypto-rust"], default-features = false, optional = true }
chacha20poly1305 = { version = "0.11.0-rc.2", optional = true }
aes-gcm = { version = "0.11.0-rc.2", optional = true }
crypto-common = { version = "0.2.0-rc.9", optional = true }
[features]
compress_lz4 = ["dep:lz4_flex"]
compress_zstd = ["dep:zstd"]
compress_brotli = ["dep:brotli"]
encrypt_chacha20poly1305 = ["dep:chacha20poly1305", "dep:secret-service", "dep:crypto-common"]
encrypt_aes_gcm = ["dep:aes-gcm", "dep:secret-service", "dep:crypto-common"]
[lints]
workspace = true
================================================
FILE: crates/clipboard-lib/src/config/mod.rs
================================================
#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct Config {
pub encryption: Encryption,
pub compression: Compression,
pub image_conv_filter: ConvolutionFilterType,
}
#[derive(Debug, Copy, Clone, Default)]
pub enum Encryption {
#[default]
None,
#[cfg(feature = "encrypt_chacha20poly1305")]
ChaCha20Poly1305,
#[cfg(feature = "encrypt_aes_gcm")]
AesGcm,
}
#[derive(Debug, Copy, Clone, Default)]
pub enum Compression {
#[default]
None,
#[cfg(feature = "compress_lz4")]
Lz4,
#[cfg(feature = "compress_zstd")]
Zstd(u8),
#[cfg(feature = "compress_brotli")]
Brotli(u8),
}
#[derive(Debug, Copy, Clone, Default)]
pub enum ConvolutionFilterType {
Box,
Bilinear,
Hamming,
CatmullRom,
Mitchell,
Gaussian,
#[default]
Lanczos3,
}
impl From<ConvolutionFilterType> for fast_image_resize::FilterType {
fn from(value: ConvolutionFilterType) -> Self {
match value {
ConvolutionFilterType::Box => Self::Box,
ConvolutionFilterType::Bilinear => Self::Bilinear,
ConvolutionFilterType::Hamming => Self::Hamming,
ConvolutionFilterType::CatmullRom => Self::CatmullRom,
ConvolutionFilterType::Mitchell => Self::Mitchell,
ConvolutionFilterType::Gaussian => Self::Gaussian,
ConvolutionFilterType::Lanczos3 => Self::Lanczos3,
}
}
}
================================================
FILE: crates/clipboard-lib/src/lib.rs
================================================
mod config;
pub mod store;
pub(crate) mod util;
================================================
FILE: crates/clipboard-lib/src/store/listen.rs
================================================
use crate::config::{Compression, Config, ConvolutionFilterType, Encryption};
use crate::store::mime::{filer_mimes, get_preferred_mime};
use crate::store::save_image::compress_and_store_image;
use crate::store::save_map::compress_and_store_map;
use crate::store::save_text::store_text;
use core_lib::WarnWithDetails;
use std::any::Any;
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::{Arc, RwLock};
use std::thread;
use tracing::{debug, warn};
use wl_clipboard::paste::{CallbackData, Seat, get_all_contents_callback};
/// # Panics
pub fn test_clipboard(_data_dir: PathBuf, cache_dir: PathBuf) {
debug!("Starting clipboard listener");
let cl_config = Arc::new(RwLock::new(conf()));
let config_clone = cl_config.clone();
let _ = cl_config.type_id();
let handle_values = move |val: CallbackData| -> bool {
let (mut mimes, load) = match val {
Ok(r) => r,
Err(err) => {
warn!("Failed to get clipboard contents: {err:?}");
return false;
}
};
let config = {
let Ok(config) = config_clone.read() else {
return true; // lock poisoned, aboard clipboard listener
};
config.clone()
};
filer_mimes(&mut mimes);
let Some(pref_mime) = get_preferred_mime(&mimes) else {
warn!("No preferred MIME type found, available: {mimes:?}");
return false;
};
// load data for all mime types
let mut data = HashMap::new();
for mime in &mimes {
data.insert(
mime.clone(),
load(mime.clone()).expect("mime type despawned while loading clipboard data"),
);
}
if pref_mime.starts_with("image/") {
let pref_data = data
.get(&pref_mime)
.expect("Preferred MIME type not found")
.clone();
let cache_dir_clone = cache_dir.clone();
let config_clone = config.clone();
thread::spawn(move || {
compress_and_store_image(pref_data, &config_clone, &cache_dir_clone)
.warn_details("Failed to store clipboard image")
});
} else {
let pref_data = data.get(&pref_mime).expect("Preferred MIME type not found");
let text = String::from_utf8_lossy(pref_data);
store_text(&text, &config, &cache_dir).warn_details("Failed to store clipboard text");
}
let cache_dir_clone = cache_dir.clone();
thread::spawn(move || compress_and_store_map(data, &config, &cache_dir_clone));
false
};
let _ = get_all_contents_callback(Seat::Unspecified, Box::new(handle_values))
.expect("Failed to start clipboard listener")
.join();
warn!("Clipboard listener stopped");
}
fn conf() -> Config {
let mut config = Config {
encryption: Encryption::default(),
compression: Compression::default(),
image_conv_filter: ConvolutionFilterType::Lanczos3,
};
config.encryption = Encryption::default();
config.compression = Compression::default();
#[cfg(feature = "compress_brotli")]
{
config.compression = Compression::Brotli(6);
}
#[cfg(feature = "compress_zstd")]
{
config.compression = Compression::Zstd(16);
}
#[cfg(feature = "encrypt_aes_gcm")]
{
config.encryption = Encryption::AesGcm;
}
#[cfg(feature = "compress_lz4")]
{
config.compression = Compression::Lz4;
}
#[cfg(feature = "encrypt_chacha20poly1305")]
{
config.encryption = Encryption::ChaCha20Poly1305;
}
config
}
================================================
FILE: crates/clipboard-lib/src/store/mime.rs
================================================
use std::collections::HashSet;
use tracing::trace;
static MIME_TYPES_PRIO: &[&str] = &[
"image/png",
"image/jpg",
"image/jpeg",
"image/webp",
"image/gif",
"text/plain;charset=utf-8",
"UTF8_STRING",
"STRING",
"TEXT",
"text/*",
];
static MIME_TYPES_IMAGES_PRIO: &[&str] = &[
"image/png",
"image/jpg",
"image/jpeg",
"image/webp",
"image/gif",
];
pub fn get_preferred_mime(mime_types: &HashSet<String>) -> Option<String> {
// Find by priority
for (index, mime) in MIME_TYPES_PRIO.iter().enumerate() {
if mime.ends_with("/*") {
let prefix = &mime[..mime.len() - 1];
if let Some(mt) = mime_types.iter().find(|x| x.starts_with(prefix)) {
trace!("Chosen MIME type: {mt:?} from prio({index}), by prefix {prefix}*");
return Some(mt.clone());
}
} else if let Some(mt) = mime_types.iter().find(|x| x == mime) {
trace!("Chosen MIME type: {mt:?} from prio({index}), by exact match {mime}");
return Some(mt.clone());
}
}
None
}
pub fn filer_mimes(mime_types: &mut HashSet<String>) {
let count = mime_types.len();
// remove audio
mime_types.retain(|mt| !mt.starts_with("audio/"));
// Retain only one image/ MIME type.
let image_mime = MIME_TYPES_IMAGES_PRIO
.iter()
.find(|preferred| mime_types.contains(&(**preferred).to_string()))
.map(|&preferred| preferred.to_string())
.or_else(|| {
mime_types
.iter()
.find(|mt| mt.starts_with("image/"))
.cloned()
});
mime_types.retain(|mt| {
if mt.starts_with("image/") {
image_mime.as_ref() == Some(mt)
} else {
true
}
});
trace!(
"Available MIME types: {:?}, removed {} elements",
mime_types,
count - mime_types.len()
);
}
================================================
FILE: crates/clipboard-lib/src/store/mod.rs
================================================
mod listen;
mod mime;
mod save_image;
mod save_map;
mod save_text;
pub(crate) mod util;
mod write;
pub use listen::test_clipboard;
================================================
FILE: crates/clipboard-lib/src/store/save_image.rs
================================================
use crate::store::util::create_storage_path;
use anyhow::Context;
use image::{ImageEncoder, ImageReader};
use std::fs::File;
use std::io::{Cursor, Write};
use std::path::Path;
use tracing::trace;
use crate::config::Config;
use crate::store::write::get_storage_writer;
use fast_image_resize::images::Image;
use fast_image_resize::{IntoImageView, ResizeAlg, ResizeOptions, Resizer};
use image::codecs::png::PngEncoder;
const IMAGE_HEIGHT: u32 = 150;
pub fn compress_and_store_image(
pref_data: Vec<u8>,
config: &Config,
cache_dir: &Path,
) -> anyhow::Result<()> {
let now = std::time::SystemTime::now();
let img2 = ImageReader::new(Cursor::new(pref_data))
.with_guessed_format()?
.decode()?;
trace!(
"Loaded image in {:?}, Image size: {}x{}",
now.elapsed()?,
img2.width(),
img2.height()
);
let now = std::time::SystemTime::now();
#[allow(clippy::cast_sign_loss, clippy::cast_precision_loss)]
let mut dst_image = Image::new(
(img2.width() as f32 * (IMAGE_HEIGHT as f32 / img2.height() as f32)) as u32,
IMAGE_HEIGHT,
img2.pixel_type()
.context("Failed to get pixel type for clipboard image")?,
);
let mut resizer = Resizer::new();
resizer.resize(
&img2,
&mut dst_image,
&ResizeOptions::new().resize_alg(ResizeAlg::Convolution(config.image_conv_filter.into())),
)?;
trace!(
"Resized image size: {}x{} in {:?}",
dst_image.width(),
dst_image.height(),
now.elapsed()?
);
let mut cursor = Cursor::new(Vec::new());
{
let (mut write, _ext) = get_storage_writer(&mut cursor, config, false);
PngEncoder::new(&mut write).write_image(
dst_image.buffer(),
dst_image.width(),
dst_image.height(),
img2.color().into(),
)?;
}
let storage_path = create_storage_path(cache_dir, "images", "png")
.context("Failed to get storage path for clipboard image")?;
let mut file = File::create(&storage_path).context("Failed to create clipboard image file")?;
file.write_all(&cursor.into_inner())
.context("Failed to write clipboard data")?;
trace!(
"Wrote image to {:?} ({} bytes)",
storage_path.display(),
file.metadata().map(|m| m.len()).unwrap_or(0)
);
Ok(())
}
================================================
FILE: crates/clipboard-lib/src/store/save_map.rs
================================================
use crate::config::Config;
use crate::store::util::create_storage_path;
use crate::store::write::get_storage_writer;
use anyhow::Context;
use std::collections::HashMap;
use std::fs::File;
use std::io::{Cursor, Write};
use std::path::Path;
use std::time::SystemTime;
use tracing::{trace, warn};
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
pub enum ClipboardDataType {
Alias(Box<str>),
Data(Vec<u8>),
}
pub fn compress_and_store_map(data: HashMap<String, Vec<u8>>, config: &Config, cache_dir: &Path) {
let combined_size = data.values().map(Vec::len).sum::<usize>();
let (data, contains_image) = deduplicate_clipboard_entries(data, true);
let compressed_combined_size = data
.values()
.filter_map(|dt| {
if let ClipboardDataType::Data(d) = dt {
Some(d.len())
} else {
None
}
})
.sum::<usize>();
trace!(
"Combined size: {} bytes, compressed size {} bytes, storing {} aliased and {} data entries",
combined_size,
compressed_combined_size,
data.values()
.filter(|dt| matches!(dt, ClipboardDataType::Alias(_)))
.count(),
data.values()
.filter(|dt| matches!(dt, ClipboardDataType::Data(_)))
.count()
);
// dont compress if contains image
if let Err(err) = store_map(&data, config, !contains_image, cache_dir) {
warn!("Failed to store clipboard data: {err}");
}
}
fn store_map(
data: &HashMap<Box<str>, ClipboardDataType>,
config: &Config,
compress: bool,
cache_dir: &Path,
) -> anyhow::Result<()> {
let now = SystemTime::now();
let mut cursor = Cursor::new(Vec::new());
let ext = {
let (mut writer, ext) = get_storage_writer(&mut cursor, config, compress);
let encoded = bitcode::encode(data);
writer
.write_all(&encoded)
.context("Failed to write encoded clipboard data")?;
ext
};
let storage_path = create_storage_path(cache_dir, "data", &format!("bin.{ext}"))
.context("Failed to get storage path for clipboard data")?;
let mut file = File::create(&storage_path).context("Failed to create clipboard data file")?;
file.write_all(&cursor.into_inner())
.context("Failed to write clipboard data")?;
trace!(
"Wrote clipboard data to {} ({} bytes) in {:?}",
storage_path.display(),
file.metadata().map(|m| m.len()).unwrap_or(0),
now.elapsed()?
);
Ok(())
}
pub fn deduplicate_clipboard_entries(
data: HashMap<String, Vec<u8>>,
dedup: bool,
) -> (HashMap<Box<str>, ClipboardDataType>, bool) {
let time = std::time::Instant::now();
let mut image_found = false;
let mut dedupted = 0u16;
let mut map: HashMap<Box<str>, ClipboardDataType> = HashMap::new();
'outer: for (mime, data) in data {
if mime.starts_with("image/") {
image_found = true;
}
if dedup {
for (f_mime, f_dt) in map.iter().filter(|(m, _)| !m.starts_with("image/")) {
if let ClipboardDataType::Data(check_data) = f_dt
&& data.eq(check_data)
{
trace!("Deduped MIME type {mime} to {f_mime}");
map.insert(
mime.into_boxed_str(),
ClipboardDataType::Alias(f_mime.clone()),
);
dedupted += 1;
continue 'outer;
}
}
}
map.insert(mime.into_boxed_str(), ClipboardDataType::Data(data));
}
trace!(
"Deduplication took {:?}, dedupted {dedupted} entries",
time.elapsed()
);
(map, image_found)
}
================================================
FILE: crates/clipboard-lib/src/store/save_text.rs
================================================
use crate::config::Config;
use crate::store::util::create_storage_path;
use crate::store::write::get_storage_writer;
use anyhow::Context;
use std::fs::File;
use std::io::{Cursor, Write};
use std::path::Path;
use tracing::trace;
pub fn store_text(text: &str, config: &Config, cache_dir: &Path) -> anyhow::Result<()> {
let compress = text.len() > 100;
let mut cursor = Cursor::new(Vec::new());
let ext = {
let (mut write, ext) = get_storage_writer(&mut cursor, config, compress);
write
.write_all(text.as_bytes())
.context("Failed to write text to clipboard")?;
ext
};
let storage_path = create_storage_path(cache_dir, "text", &format!("txt.{ext}"))
.context("Failed to get storage path for clipboard data")?;
let mut file = File::create(&storage_path).context("Failed to create clipboard data file")?;
file.write_all(&cursor.into_inner())
.context("Failed to write clipboard data")?;
trace!(
"Wrote text to {} ({} bytes)",
storage_path.display(),
file.metadata().map(|m| m.len()).unwrap_or(0)
);
Ok(())
}
================================================
FILE: crates/clipboard-lib/src/store/util.rs
================================================
use anyhow::Context;
use core_lib::util::get_boot_id;
use std::fs;
use std::path::{Path, PathBuf};
use std::time::{SystemTime, UNIX_EPOCH};
/// # Panics if time went backwards or no `boot_id` is available
pub fn create_storage_path(cache_dir: &Path, path: &str, ext: &str) -> anyhow::Result<PathBuf> {
let now_millis = SystemTime::now()
.duration_since(UNIX_EPOCH)
.context("Time went backwards?")?
.as_millis();
let get_boot_id = get_boot_id().clone().context("Failed to get boot_id")?;
let path = cache_dir
.to_path_buf()
.join("clipboard")
.join(path)
.join(get_boot_id);
fs::create_dir_all(&path).context("Failed to create storage directory")?;
Ok(path.join(format!("{now_millis}.{ext}")))
}
================================================
FILE: crates/clipboard-lib/src/store/write.rs
================================================
use crate::config::{Compression, Config, Encryption};
use std::io::Write;
pub fn get_storage_writer<'a, I: Write + 'a>(
writer: I,
config: &Config,
compress: bool,
) -> (Box<dyn Write + 'a>, &'static str) {
let base: Box<dyn Write> = match config.encryption {
Encryption::None => Box::new(writer),
#[cfg(any(feature = "encrypt_chacha20poly1305", feature = "encrypt_aes_gcm"))]
_ => {
let config_val = match config.encryption {
#[cfg(feature = "encrypt_chacha20poly1305")]
Encryption::ChaCha20Poly1305 => crate::util::crypt::Config::ChaCha20Poly1305,
#[cfg(feature = "encrypt_aes_gcm")]
Encryption::AesGcm => crate::util::crypt::Config::AesGcm,
_ => unreachable!(),
};
match crate::util::secret_service::get_hyprshell_key() {
Ok(key) => Box::new(crate::util::crypt::SecretEncryptWriter::new(
writer, key, config_val,
)),
Err(err) => {
tracing::warn!("Failed to load/generate new encryption key: {err:?}");
Box::new(writer)
}
}
}
};
match (compress, config.compression) {
(false, _) | (true, Compression::None) => (base, "raw"),
#[cfg(feature = "compress_lz4")]
(true, Compression::Lz4) => (
Box::new(crate::util::lz4_compressor::LZ4CompressWriter::new(base)),
"lz4",
),
#[cfg(feature = "compress_brotli")]
(true, Compression::Brotli(level)) => (
Box::new(crate::util::brotli_compressor::BrotliCompressWriter::new(
base, level,
)),
"br",
),
#[cfg(feature = "compress_zstd")]
(true, Compression::Zstd(level)) => (
Box::new(crate::util::zstd_compressor::ZstdCompressWriter::new(
base, level,
)),
"zstd",
),
}
}
================================================
FILE: crates/clipboard-lib/src/util/brotli_compressor.rs
================================================
use brotli::CompressorWriter;
use brotli::enc::BrotliEncoderParams;
use std::io::Write;
use tracing::warn;
pub struct BrotliCompressWriter<W: Write> {
encoder: CompressorWriter<W>,
}
impl<W: Write> BrotliCompressWriter<W> {
pub fn new(writer: W, mut level: u8) -> Self {
// use 6 as default compression level
if level > 11 {
warn!("Brotli compression level out of range, clamping to 11");
level = 11;
}
let params = BrotliEncoderParams::default();
Self {
#[allow(clippy::cast_sign_loss)]
encoder: CompressorWriter::new(writer, 4096, u32::from(level), params.lgwin as u32),
}
}
}
impl<W: Write> Write for BrotliCompressWriter<W> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.encoder.write(buf)
}
fn flush(&mut self) -> std::io::Result<()> {
self.encoder.flush()
}
}
================================================
FILE: crates/clipboard-lib/src/util/crypt.rs
================================================
use anyhow::Context;
use crypto_common::Generate;
use std::io::Write;
use tracing::trace;
#[cfg(feature = "encrypt_chacha20poly1305")]
type K = chacha20poly1305::Key;
#[cfg(all(not(feature = "encrypt_chacha20poly1305"), feature = "encrypt_aes_gcm"))]
type K = aes_gcm::Key<aes_gcm::Aes256Gcm>;
pub fn generate_new_key() -> anyhow::Result<Vec<u8>> {
K::try_generate()
.map_err(|_| anyhow::anyhow!("Failed to generate new encryption key"))
.map(|k| k.to_vec())
}
pub struct SecretEncryptWriter<W: Write> {
key: Vec<u8>,
buffer: Vec<u8>,
writer: W,
config: Config,
}
pub enum Config {
#[cfg(feature = "encrypt_chacha20poly1305")]
ChaCha20Poly1305,
#[cfg(feature = "encrypt_aes_gcm")]
AesGcm,
}
impl<W: Write> SecretEncryptWriter<W> {
pub const fn new(writer: W, key: Vec<u8>, config: Config) -> Self {
Self {
buffer: Vec::new(),
key,
writer,
config,
}
}
pub fn encrypt(&self, cleartext: &[u8]) -> anyhow::Result<Vec<u8>> {
trace!("length of cleartext: {}", cleartext.len());
match self.config {
#[cfg(feature = "encrypt_chacha20poly1305")]
Config::ChaCha20Poly1305 => {
use chacha20poly1305::{KeyInit, aead::Aead};
let nonce = chacha20poly1305::Nonce::try_generate()
.map_err(|_| anyhow::anyhow!("Failed to generate nonce"))?;
let cypher = chacha20poly1305::ChaCha20Poly1305::new_from_slice(&self.key)
.context("Failed to generate cypher with encryption key")?;
let obsf = cypher
.encrypt(&nonce, cleartext)
.context("Encryption failed")?;
let mut nonce = nonce.to_vec();
nonce.extend_from_slice(&obsf);
Ok(nonce)
}
#[cfg(feature = "encrypt_aes_gcm")]
Config::AesGcm => {
use aes_gcm::{KeyInit, aead::Aead};
let nonce = aes_gcm::Nonce::try_generate()
.map_err(|_| anyhow::anyhow!("Failed to generate nonce"))?;
let cypher = aes_gcm::Aes256Gcm::new_from_slice(&self.key)
.context("Failed to generate cypher with encryption key")?;
let obsf = cypher
.encrypt(&nonce, cleartext)
.context("Encryption failed")?;
let mut nonce = nonce.to_vec();
nonce.extend_from_slice(&obsf);
Ok(nonce)
}
}
}
}
impl<W: Write> Write for SecretEncryptWriter<W> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.buffer.extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
self.writer.flush()
}
}
impl<W: Write> Drop for SecretEncryptWriter<W> {
fn drop(&mut self) {
if !self.buffer.is_empty() {
if let Ok(encrypted) = self.encrypt(&self.buffer) {
trace!("Writing {} bytes encrypted data to writer", encrypted.len());
let _ = self.writer.write_all(&encrypted);
}
self.buffer.clear();
}
let _ = self.writer.flush();
}
}
// pub fn decrypt(&self, obsf: &[u8]) -> anyhow::Result<Vec<u8>> {
// type NonceSize = <ChaCha20Poly1305 as AeadCore>::NonceSize;
// let cipher = generate_cypher(&self.key).context("Failed to generate cipher")?;
// let (nonce_bytes, ciphertext) = obsf.split_at(NonceSize::to_usize());
// let nonce =
// Nonce::<ChaCha20Poly1305>::try_from(nonce_bytes).context("Failed to parse nonce")?;
// let out = cipher
// .decrypt(&nonce, ciphertext)
// .context("Decryption failed")?;
// Ok(out)
// }
================================================
FILE: crates/clipboard-lib/src/util/lz4_compressor.rs
================================================
use lz4_flex::frame::FrameEncoder;
use std::io::Write;
use tracing::warn;
pub struct LZ4CompressWriter<W: Write> {
encoder: FrameEncoder<W>,
}
impl<W: Write> LZ4CompressWriter<W> {
pub fn new(writer: W) -> Self {
Self {
encoder: FrameEncoder::new(writer),
}
}
}
impl<W: Write> Write for LZ4CompressWriter<W> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.encoder.write(buf)
}
fn flush(&mut self) -> std::io::Result<()> {
self.encoder.flush()
}
}
impl<W: Write> Drop for LZ4CompressWriter<W> {
fn drop(&mut self) {
if let Err(err) = self.encoder.try_finish() {
warn!("Failed to finish compressor: {err:?}");
}
}
}
================================================
FILE: crates/clipboard-lib/src/util/mod.rs
================================================
#[cfg(feature = "compress_brotli")]
pub mod brotli_compressor;
#[cfg(any(feature = "encrypt_chacha20poly1305", feature = "encrypt_aes_gcm"))]
pub mod crypt;
#[cfg(feature = "compress_lz4")]
pub mod lz4_compressor;
#[cfg(any(feature = "encrypt_chacha20poly1305", feature = "encrypt_aes_gcm"))]
pub mod secret_service;
#[cfg(feature = "compress_zstd")]
pub mod zstd_compressor;
================================================
FILE: crates/clipboard-lib/src/util/secret_service.rs
================================================
use crate::util::crypt::generate_new_key;
use anyhow::Context;
use secret_service::EncryptionType;
use secret_service::blocking::SecretService;
use std::collections::HashMap;
use std::sync::OnceLock;
use tracing::warn;
fn get_secret_service() -> Option<&'static SecretService<'static>> {
static SERVICE: OnceLock<Option<SecretService>> = OnceLock::new();
SERVICE
.get_or_init(|| {
SecretService::connect(EncryptionType::Dh).map_or_else(
|e| {
warn!("Failed to connect to Secret Service: {e}");
None
},
Some,
)
})
.as_ref()
}
pub fn get_hyprshell_key() -> anyhow::Result<Vec<u8>> {
let service =
get_secret_service().ok_or_else(|| anyhow::anyhow!("Secret Service not available"))?;
let collection = service
.get_default_collection()
.context("Failed to get default collection")?;
let items =
collection.search_items(HashMap::from([("application", "Hyprshell Clipboard Key")]))?;
let key = if items.is_empty() {
// instead generate a new key and insert it into the collection
let key = generate_new_key().context("Failed to generate new encryption key")?;
collection
.create_item(
"hyprshell",
HashMap::from([("application", "Hyprshell Clipboard Key")]),
&key,
true,
"application/octet-stream",
)
.context("Failed to create new secret service item for hyprshell key")?;
key
} else {
items[0]
.get_secret()
.context("Failed to get hyprshell key from secret service")?
};
Ok(key)
}
================================================
FILE: crates/clipboard-lib/src/util/zstd_compressor.rs
================================================
use std::io::Write;
use tracing::warn;
use zstd::Encoder;
pub struct ZstdCompressWriter<'a, W: Write> {
encoder: Encoder<'a, W>,
}
impl<W: Write> ZstdCompressWriter<'_, W> {
pub fn new(writer: W, mut level: u8) -> Self {
// use 16 as default compression level
if level > 22 {
warn!("Zstd compression level out of range, clamping to 22");
level = 22;
}
Self {
encoder: Encoder::new(writer, i32::from(level)).expect("Failed to create encoder"),
}
}
}
impl<W: Write> Write for ZstdCompressWriter<'_, W> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.encoder.write(buf)
}
fn flush(&mut self) -> std::io::Result<()> {
self.encoder.flush()
}
}
impl<W: Write> Drop for ZstdCompressWriter<'_, W> {
fn drop(&mut self) {
if let Err(err) = self.encoder.do_finish() {
warn!("Failed to finish compressor: {err:?}");
}
}
}
================================================
FILE: crates/config-edit-lib/Cargo.toml
================================================
[package]
name = "hyprshell-config-edit-lib"
documentation = "https://docs.rs/hyprshell-config-edit-lib"
version = "4.9.5"
description = "A library for editing the config file with a gui"
edition.workspace = true
license.workspace = true
authors.workspace = true
keywords.workspace = true
repository.workspace = true
rust-version.workspace = true
[dependencies]
tracing.workspace = true
config-lib.workspace = true
core-lib.workspace = true
relm4.workspace = true
relm4-components = "0.10.0"
# needed because relm4 version is too old for v1_8
_adw = { version = "0.8.1", package = "libadwaita", features = ["v1_8"] }
[features]
launcher_calc_plugin = []
[lints]
workspace = true
================================================
FILE: crates/config-edit-lib/src/components/changes.rs
================================================
use crate::flags_csv;
use crate::structs::{Config, Plugins};
use relm4::adw::ActionRow;
use relm4::adw::gtk::SelectionMode;
use relm4::adw::prelude::*;
use relm4::gtk;
use relm4::{ComponentParts, ComponentSender, RelmWidgetExt, SimpleComponent};
use std::collections::HashSet;
use tracing::trace;
#[derive(Debug)]
pub struct Changes {
config: Config,
prev_config: Config,
list: gtk::ListBox,
how_to_use: gtk::TextView,
}
#[derive(Debug)]
pub enum ChangesInput {
SetConfig(Config),
SetPrevConfig(Config),
}
#[derive(Debug)]
pub struct ChangesInit {
pub config: Config,
}
#[derive(Debug)]
pub enum ChangesOutput {
ChangesExist(bool),
}
#[allow(unused_assignments)]
#[relm4::component(pub)]
impl SimpleComponent for Changes {
type Init = ChangesInit;
type Input = ChangesInput;
type Output = ChangesOutput;
view! {
#[root]
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_margin_all: 10,
set_spacing: 15,
#[name="list"]
gtk::ListBox {
set_show_separators: false,
set_halign: gtk::Align::Center,
set_valign: gtk::Align::Start,
set_hexpand: true,
set_selection_mode: SelectionMode::None,
set_css_classes: &["items-list", "boxed-list"]
},
#[name="how_to_use"]
gtk::TextView {
set_editable: false,
set_sensitive: false,
set_align: gtk::Align::Fill,
set_hexpand: true,
set_vexpand: true,
set_css_classes: &["changes-text"]
}
}
}
fn init(
init: Self::Init,
root: Self::Root,
_sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
#[allow(unused_assignments)]
let widgets = view_output!();
let model = Self {
config: init.config.clone(),
prev_config: init.config,
list: widgets.list.clone(),
how_to_use: widgets.how_to_use.clone(),
};
ComponentParts { model, widgets }
}
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
trace!("changes::update: {message:?}");
match message {
ChangesInput::SetConfig(config) => {
self.config = config;
}
ChangesInput::SetPrevConfig(config) => {
self.prev_config = config;
}
}
let changes = generate_items(&self.list, &self.config, &self.prev_config);
let text = config_lib::explain(&(self.config.clone().into()), None, false);
self.how_to_use.buffer().set_text(&text);
sender
.output_sender()
.emit(ChangesOutput::ChangesExist(changes));
}
}
#[allow(clippy::too_many_lines)]
pub fn generate_items(changes: >k::ListBox, config: &Config, prev_config: &Config) -> bool {
while let Some(child) = changes.first_child() {
changes.remove(&child);
}
match (prev_config.windows.enabled, config.windows.enabled) {
(false, false) => {}
(true, false) => {
add_info(changes, "Disabled Windows");
}
(_, true) => {
if !prev_config.windows.enabled {
add_info(changes, "Enabled Windows");
}
#[allow(clippy::cast_sign_loss)]
if (prev_config.windows.scale - config.windows.scale).abs() > 0.001 {
add_info_subtitle(
changes,
"Changed windows scale",
format!("{} -> {}", prev_config.windows.scale, config.windows.scale),
);
}
if prev_config.windows.items_per_row != config.windows.items_per_row {
add_info_subtitle(
changes,
"Changed windows items per row",
format!(
"{} -> {}",
prev_config.windows.items_per_row, config.windows.items_per_row
),
);
}
match (
prev_config.windows.overview.enabled,
config.windows.overview.enabled,
) {
(false, false) => {}
(true, false) => {
add_info(changes, "Disabled Overview");
}
(_, true) => {
if !prev_config.windows.overview.enabled {
add_info(changes, "Enabled Overview");
}
if prev_config.windows.overview.modifier != config.windows.overview.modifier {
add_info_subtitle(
changes,
"Changed overview modifier",
format!(
"{} -> {}",
prev_config.windows.overview.modifier,
config.windows.overview.modifier
),
);
}
if prev_config.windows.overview.key != config.windows.overview.key {
add_info_subtitle(
changes,
"Changed overview key",
format!(
"{} -> {}",
prev_config.windows.overview.key, config.windows.overview.key,
),
);
}
if prev_config.windows.overview.same_class != config.windows.overview.same_class
|| prev_config.windows.overview.current_monitor
!= config.windows.overview.current_monitor
|| prev_config.windows.overview.current_workspace
!= config.windows.overview.current_workspace
{
add_info_subtitle(
changes,
"Changed overview filter by",
format!(
"{} -> {}",
flags_csv!(
prev_config.windows.overview,
same_class,
current_monitor,
current_workspace
),
flags_csv!(
config.windows.overview,
same_class,
current_monitor,
current_workspace
),
),
);
}
if prev_config.windows.overview.launcher.launch_modifier
!= config.windows.overview.launcher.launch_modifier
{
add_info_subtitle(
changes,
"Changed overview launcher launch modifier",
format!(
"{} -> {}",
prev_config.windows.overview.launcher.launch_modifier,
config.windows.overview.launcher.launch_modifier
),
);
}
if prev_config.windows.overview.launcher.max_items
!= config.windows.overview.launcher.max_items
{
add_info_subtitle(
changes,
"Changed overview launcher max items",
format!(
"{} -> {}",
prev_config.windows.overview.launcher.max_items,
config.windows.overview.launcher.max_items
),
);
}
if prev_config.windows.overview.launcher.show_when_empty
!= config.windows.overview.launcher.show_when_empty
{
add_info_subtitle(
changes,
"Changed overview launcher show when empty",
format!(
"{} -> {}",
prev_config.windows.overview.launcher.show_when_empty,
config.windows.overview.launcher.show_when_empty
),
);
}
if prev_config.windows.overview.launcher.width
!= config.windows.overview.launcher.width
{
add_info_subtitle(
changes,
"Changed overview launcher width",
format!(
"{} -> {}",
prev_config.windows.overview.launcher.width,
config.windows.overview.launcher.width
),
);
}
match (
&prev_config.windows.overview.launcher.default_terminal,
&config.windows.overview.launcher.default_terminal,
) {
(None, None) => {}
(Some(_), None) => {
add_info(changes, "Disabled overview launcher default terminal");
}
(None, Some(dt)) => {
add_info_subtitle(
changes,
"Enabled overview launcher default terminal",
format!("{dt:?}"),
);
}
(Some(pdt), Some(cdt)) => {
if pdt != cdt {
add_info_subtitle(
changes,
"Changed overview launcher default terminal",
format!("{pdt:?} -> {cdt:?}"),
);
}
}
}
add_plugin_changes(
changes,
&prev_config.windows.overview.launcher.plugins,
&config.windows.overview.launcher.plugins,
);
}
}
match (
&prev_config.windows.switch.enabled,
&config.windows.switch.enabled,
) {
(false, false) => {}
(true, false) => {
add_info(changes, "Disabled Switch view");
}
(_, true) => {
if !prev_config.windows.switch.enabled {
add_info(changes, "Enabled Switch view");
}
if prev_config.windows.switch.key != config.windows.switch.key {
add_info_subtitle(
changes,
"Changed switch key",
format!(
"{} -> {}",
prev_config.windows.switch.key, config.windows.switch.key
),
);
}
if prev_config.windows.switch.modifier != config.windows.switch.modifier {
add_info_subtitle(
changes,
"Changed switch modifier",
format!(
"{} -> {}",
prev_config.windows.switch.modifier, config.windows.switch.modifier
),
);
}
if prev_config.windows.switch.same_class != config.windows.switch.same_class
|| prev_config.windows.switch.current_monitor
!= config.windows.switch.current_monitor
|| prev_config.windows.switch.current_workspace
!= config.windows.switch.current_workspace
{
add_info_subtitle(
changes,
"Changed switch filter by",
format!(
"{} -> {}",
flags_csv!(
prev_config.windows.switch,
same_class,
current_monitor,
current_workspace
),
flags_csv!(
config.windows.switch,
same_class,
current_monitor,
current_workspace
),
),
);
}
if prev_config.windows.switch.switch_workspaces
!= config.windows.switch.switch_workspaces
{
add_info_subtitle(
changes,
"Changed switch switch workspaces",
format!(
"{} -> {}",
prev_config.windows.switch.switch_workspaces,
config.windows.switch.switch_workspaces
),
);
}
}
}
match (
&prev_config.windows.switch_2.enabled,
&config.windows.switch_2.enabled,
) {
(false, false) => {}
(true, false) => {
add_info(changes, "Disabled Switch 2 view");
}
(_, true) => {
if !prev_config.windows.switch_2.enabled {
add_info(changes, "Enabled Switch 2 view");
}
if prev_config.windows.switch_2.key != config.windows.switch_2.key {
add_info_subtitle(
changes,
"Changed switch 2 key",
format!(
"{} -> {}",
prev_config.windows.switch_2.key, config.windows.switch_2.key
),
);
}
if prev_config.windows.switch_2.modifier != config.windows.switch_2.modifier {
add_info_subtitle(
changes,
"Changed switch 2 modifier",
format!(
"{} -> {}",
prev_config.windows.switch_2.modifier,
config.windows.switch_2.modifier
),
);
}
if prev_config.windows.switch_2.same_class != config.windows.switch_2.same_class
|| prev_config.windows.switch_2.current_monitor
!= config.windows.switch_2.current_monitor
|| prev_config.windows.switch_2.current_workspace
!= config.windows.switch_2.current_workspace
{
add_info_subtitle(
changes,
"Changed switch 2 filter by",
format!(
"{} -> {}",
flags_csv!(
prev_config.windows.switch_2,
same_class,
current_monitor,
current_workspace
),
flags_csv!(
config.windows.switch_2,
same_class,
current_monitor,
current_workspace
),
),
);
}
if prev_config.windows.switch_2.switch_workspaces
!= config.windows.switch_2.switch_workspaces
{
add_info_subtitle(
changes,
"Changed switch 2 switch workspaces",
format!(
"{} -> {}",
prev_config.windows.switch_2.switch_workspaces,
config.windows.switch_2.switch_workspaces
),
);
}
}
}
}
}
if changes.first_child().is_none() {
add_info(changes, "No changes");
false
} else {
true
}
}
#[allow(clippy::too_many_lines)]
fn add_plugin_changes(changes: >k::ListBox, prev: &Plugins, current: &Plugins) {
match (&prev.applications.enabled, ¤t.applications.enabled) {
(false, false) => {}
(true, false) => {
add_info(changes, "Disabled Application Plugin");
}
(_, true) => {
if !prev.applications.enabled {
add_info(changes, "Enabled Application Plugin");
}
if prev.applications.show_execs != current.applications.show_execs {
add_info_subtitle(
changes,
"Changed application plugin show execs",
format!(
"{} -> {}",
prev.applications.show_execs, current.applications.show_execs
),
);
}
if prev.applications.show_actions_submenu != current.applications.show_actions_submenu {
add_info_subtitle(
changes,
"Changed application plugin show actions",
format!(
"{} -> {}",
prev.applications.show_actions_submenu,
current.applications.show_actions_submenu
),
);
}
if prev.applications.run_cache_weeks != current.applications.run_cache_weeks {
add_info_subtitle(
changes,
"Changed application plugin run cache weeks",
format!(
"{} -> {}",
prev.applications.run_cache_weeks, current.applications.run_cache_weeks
),
);
}
}
}
match (&prev.terminal.enabled, ¤t.terminal.enabled) {
(true, false) => {
add_info(changes, "Disabled Terminal Plugin");
}
(false, true) => {
add_info(changes, "Enabled Terminal Plugin");
}
_ => {}
}
match (&prev.shell.enabled, ¤t.shell.enabled) {
(true, false) => {
add_info(changes, "Disabled Shell Plugin");
}
(false, true) => {
add_info(changes, "Enabled Shell Plugin");
}
_ => {}
}
match (&prev.calc.enabled, ¤t.calc.enabled) {
(true, false) => {
add_info(changes, "Disabled Calculator Plugin");
}
(false, true) => {
add_info(changes, "Enabled Calculator Plugin");
}
_ => {}
}
match (&prev.path.enabled, ¤t.path.enabled) {
(true, false) => {
add_info(changes, "Disabled Path Plugin");
}
(false, true) => {
add_info(changes, "Enabled Path Plugin");
}
_ => {}
}
match (&prev.websearch.enabled, ¤t.websearch.enabled) {
(false, false) => {}
(true, false) => {
add_info(changes, "Disabled Websearch Plugin");
}
(_, true) => {
if !prev.websearch.enabled {
add_info(changes, "Enabled Websearch Plugin");
}
let prev_engines = &prev.websearch.engines;
let cur_engines = ¤t.websearch.engines;
let prev_keys: HashSet<_> = prev_engines.iter().map(|e| e.key).collect();
let cur_keys: HashSet<_> = cur_engines.iter().map(|e| e.key).collect();
for e in cur_engines.iter().filter(|e| !prev_keys.contains(&e.key)) {
add_info_subtitle(
changes,
"Added Websearch engine",
format!("{} ({})", e.name, e.key),
);
}
for e in prev_engines.iter().filter(|e| !cur_keys.contains(&e.key)) {
add_info_subtitle(
changes,
"Removed Websearch engine",
format!("{} ({})", e.name, e.key),
);
}
}
}
}
fn add_info(changes: >k::ListBox, text: &str) {
let label = ActionRow::builder().title(text).build();
changes.append(&label);
}
fn add_info_subtitle(changes: >k::ListBox, text: &str, subtitle: String) {
let label = ActionRow::builder().title(text).subtitle(subtitle).build();
changes.append(&label);
}
================================================
FILE: crates/config-edit-lib/src/components/footer.rs
================================================
use relm4::adw::prelude::*;
use relm4::gtk::Orientation;
use relm4::{ComponentParts, ComponentSender, SimpleComponent, gtk};
use std::path::Path;
use tracing::trace;
#[derive(Debug)]
pub struct Footer {
config_file: Box<Path>,
changes: bool,
generate: bool,
}
#[derive(Debug)]
pub enum FooterInput {
ChangesExist(bool),
GenerateMode(bool),
}
#[derive(Debug)]
pub struct FooterInit {
pub config_file: Box<Path>,
}
#[derive(Debug)]
pub enum FooterOutput {
Close,
Save,
Reset,
Reload,
Abort,
}
#[relm4::component(pub)]
impl SimpleComponent for Footer {
type Init = FooterInit;
type Input = FooterInput;
type Output = FooterOutput;
view! {
gtk::ActionBar {
#[wrap(Some)]
set_center_widget = >k::Box {
set_spacing: 20,
set_hexpand: true,
set_css_classes: &["footer"],
set_orientation: Orientation::Horizontal,
gtk::LinkButton {
set_label: &format!("Hyprshell v{}", env!("CARGO_PKG_VERSION")),
set_uri: &format!("https://github.com/H3rmt/hyprshell/tree/v{}", env!("CARGO_PKG_VERSION")),
},
gtk::Box {
set_spacing: 10,
set_hexpand: true,
set_halign: gtk::Align::End,
set_orientation: Orientation::Horizontal,
gtk::Button {
set_label: "Reload from Disk",
#[watch]
set_visible: !model.generate,
set_sensitive: true,
set_css_classes: &["destructive-action"],
connect_clicked[sender] => move |_| sender.output_sender().emit(FooterOutput::Reload),
},
gtk::Button {
set_label: "Reset",
#[watch]
set_visible: !model.generate,
#[watch]
set_sensitive: model.changes,
set_css_classes: &["destructive-action"],
connect_clicked[sender] => move |_| sender.output_sender().emit(FooterOutput::Reset),
},
gtk::Button {
set_label: "Save Changes",
#[watch]
set_visible: !model.generate,
#[watch]
set_sensitive: model.changes,
set_css_classes: &["suggested-action"],
set_tooltip_text: Some(&format!("Config file: {}", model.config_file.display())),
connect_clicked[sender] => move |_| sender.output_sender().emit(FooterOutput::Save),
},
gtk::Button {
set_label: "Abort Generate",
#[watch]
set_visible: model.generate,
set_css_classes: &["destructive-action"],
connect_clicked[sender] => move |_| sender.output_sender().emit(FooterOutput::Abort),
},
gtk::Button {
set_label: "Close",
set_css_classes: &["destructive-action"],
connect_clicked[sender] => move |_| sender.output_sender().emit(FooterOutput::Close),
}
}
}
}
}
fn init(
init: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let model = Self {
config_file: init.config_file,
changes: false,
generate: false,
};
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self>) {
trace!("footer::update: {message:?}");
match message {
FooterInput::ChangesExist(changes) => {
self.changes = changes;
}
FooterInput::GenerateMode(generate) => {
self.generate = generate;
}
}
}
}
================================================
FILE: crates/config-edit-lib/src/components/generate/main.rs
================================================
use crate::components::generate::step0::{Step0, Step0Init, Step0Input};
use crate::components::generate::step1::{LauncherPlugins, Step1, Step1Init, Step1Input};
use crate::components::generate::step2::{Step2, Step2Init, Step2Input};
use crate::components::generate::step3::{SearchEngines, Step3, Step3Init, Step3Input};
use crate::components::generate::step4::{Step4, Step4Init, Step4Input};
use crate::structs::ConfigModifier;
use crate::util::{ScrollToPosition, default_config};
use config_lib::SearchEngine;
use relm4::gtk::prelude::{BoxExt, ButtonExt, OrientableExt, WidgetExt};
use relm4::gtk::{Align, Justification};
use relm4::{
Component, ComponentController, ComponentParts, ComponentSender, Controller, RelmWidgetExt,
SimpleComponent,
};
use relm4::{adw, gtk};
use std::path::Path;
use tracing::trace;
#[derive(Debug)]
pub struct Generate {
themes_carousel: adw::Carousel,
step: usize,
step_boxes: Vec<gtk::Box>,
explain_label: gtk::Label,
step0: Controller<Step0>,
step0_data: Option<(ConfigModifier, String)>,
step1: Controller<Step1>,
step1_data: LauncherPlugins,
step2: Controller<Step2>,
step2_data: Option<String>,
step3: Controller<Step3>,
step3_data: SearchEngines,
step4: Controller<Step4>,
step4_data: Option<(ConfigModifier, String)>,
}
#[derive(Debug)]
pub enum GenerateInput {
Start,
Advance(usize),
Back(usize),
SetStep0(Option<(ConfigModifier, String)>),
SetStep1(LauncherPlugins),
SetStep2(Option<String>),
SetStep3(SearchEngines),
SetStep4(Option<(ConfigModifier, String)>),
}
#[derive(Debug)]
pub struct GenerateInit {
pub system_data_dir: Box<Path>,
}
#[derive(Debug)]
pub enum GenerateOutput {
Finish(crate::Config),
}
struct Out {
overview: Option<(ConfigModifier, String)>,
launcher: LauncherPlugins,
default_terminal: Option<String>,
launcher_websearch_plugin: SearchEngines,
switch: Option<(ConfigModifier, String)>,
}
const MAX_STEP: usize = 5;
#[allow(unused_assignments)]
#[relm4::component(pub)]
impl SimpleComponent for Generate {
type Init = GenerateInit;
type Input = GenerateInput;
type Output = GenerateOutput;
view! {
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_spacing: 10,
gtk::Box {
#[local_ref]
themes_carousel -> adw::Carousel {
set_visible: true,
#[local_ref]
step0 -> gtk::Box {},
#[local_ref]
step1 -> gtk::Box {},
#[local_ref]
step2 -> gtk::Box {},
#[local_ref]
step3 -> gtk::Box {},
#[local_ref]
step4 -> gtk::Box {},
#[local_ref]
step5 -> gtk::Box {},
},
set_expand: true,
set_spacing: 20,
set_margin_all: 20,
#[transition = "SlideUpDown"]
#[name="step0_stack"]
match model.step {
0 => *model.step0.widget(),
1 => *model.step1.widget(),
2 => *model.step2.widget(),
3 => *model.step3.widget(),
4 => *model.step4.widget(),
5 => {
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_hexpand: true,
set_spacing: 20,
#[local_ref]
explain_label -> gtk::Label {
set_css_classes: &[],
set_align: Align::Center,
set_justify: Justification::Left,
},
}
},
_ => gtk::Label::new(Some("INVALID GENERATE STEP")) {}
},
},
adw::CarouselIndicatorDots {
set_carousel: Some(themes_carousel),
},
gtk::Box {
set_spacing: 25,
set_halign: Align::Center,
gtk::Button {
set_label: "Back",
set_css_classes: &["suggested-action", "pill"],
connect_clicked[sender] => move |_| sender.input(GenerateInput::Back(1)),
},
gtk::Button {
#[watch]
set_label: if model.step == MAX_STEP { "Finish" } else { "Next" },
set_css_classes: &["suggested-action", "pill"],
connect_clicked[sender] => move |_| sender.input(GenerateInput::Advance(1)),
}
}
}
}
fn init(
init: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let path = init.system_data_dir.join("setup_preview");
let step0 = Step0::builder()
.launch(Step0Init {
system_data_dir: path.clone().into_boxed_path(),
})
.forward(sender.input_sender(), GenerateInput::SetStep0);
let step1 = Step1::builder()
.launch(Step1Init {})
.forward(sender.input_sender(), GenerateInput::SetStep1);
let step2 = Step2::builder()
.launch(Step2Init {})
.forward(sender.input_sender(), GenerateInput::SetStep2);
let step3 = Step3::builder()
.launch(Step3Init {})
.forward(sender.input_sender(), GenerateInput::SetStep3);
let step4 = Step4::builder()
.launch(Step4Init {
system_data_dir: path.into_boxed_path(),
})
.forward(sender.input_sender(), GenerateInput::SetStep4);
let themes_carousel = adw::Carousel::builder().build();
let mut step_boxes = vec![];
for _ in 0..=MAX_STEP {
step_boxes.push(gtk::Box::builder().build());
}
let explain_label = gtk::Label::default();
let model = Self {
step: 0,
step_boxes,
step0,
step0_data: None,
step1,
step1_data: LauncherPlugins::default(),
step2,
step2_data: None,
step3,
step3_data: SearchEngines::default(),
step4,
step4_data: None,
explain_label,
themes_carousel,
};
let themes_carousel = &model.themes_carousel;
let step0 = &model.step_boxes[0];
let step1 = &model.step_boxes[1];
let step2 = &model.step_boxes[2];
let step3 = &model.step_boxes[3];
let step4 = &model.step_boxes[4];
let step5 = &model.step_boxes[5];
let explain_label = &model.explain_label;
let widgets = view_output!();
widgets.step0_stack.set_transition_duration(500);
ComponentParts { model, widgets }
}
#[allow(clippy::too_many_lines)]
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
trace!("launcher::update: {message:?}");
match message {
GenerateInput::Advance(by) => {
if self.step + by <= MAX_STEP {
self.step += by;
self.themes_carousel.scroll_to_pos(self.step, false);
} else {
let conf = Out {
overview: self.step0_data.clone(),
launcher: self.step1_data,
default_terminal: self.step2_data.clone(),
launcher_websearch_plugin: self.step3_data,
switch: self.step4_data.clone(),
}
.into();
sender.output_sender().emit(GenerateOutput::Finish(conf));
}
match self.step {
// advanced to the launcher setup
1 => {
// skip launcher config if overview disabled
if self.step0_data.is_none() {
sender.input(GenerateInput::Advance(3));
}
}
// advanced to websearch plugin
3 => {
// skip websearch plugin config if websearch disabled
if !self.step1_data.search_the_web {
sender.input(GenerateInput::Advance(1));
}
}
5 => {
let conf: crate::Config = Out {
overview: self.step0_data.clone(),
launcher: self.step1_data,
default_terminal: self.step2_data.clone(),
launcher_websearch_plugin: self.step3_data,
switch: self.step4_data.clone(),
}
.into();
let conf: config_lib::Config = conf.into();
let explanation = config_lib::explain(&conf, None, false);
self.explain_label.set_label(&explanation);
}
_ => {}
}
}
GenerateInput::Back(by) => {
#[allow(clippy::cast_possible_wrap)]
if (self.step as i64) - (by as i64) >= 0 {
self.step -= by;
self.themes_carousel.scroll_to_pos(self.step, false);
}
match self.step {
// stepped back to launcher setup
3 => {
// skip launcher config if overview disabled
if self.step0_data.is_none() {
sender.input(GenerateInput::Back(3));
}
// skip websearch plugin config if websearch disabled
if !self.step1_data.search_the_web {
sender.input(GenerateInput::Back(1));
}
}
_ => {}
}
}
GenerateInput::Start => {
self.step = 0;
self.themes_carousel.scroll_to_pos(self.step, false);
let default = crate::Config::from(default_config());
self.step0_data = Some((
default.windows.overview.modifier,
default.windows.overview.key,
));
self.step1_data = LauncherPlugins::default();
self.step2_data = None;
self.step3_data = SearchEngines::default();
self.step4_data =
Some((default.windows.switch.modifier, default.windows.switch.key));
self.step0
.emit(Step0Input::SetData(self.step0_data.clone()));
self.step1.emit(Step1Input::SetData(self.step1_data));
self.step2
.emit(Step2Input::SetData(self.step2_data.clone()));
self.step3.emit(Step3Input::SetData(self.step3_data));
self.step4
.emit(Step4Input::SetData(self.step4_data.clone()));
}
GenerateInput::SetStep0(data) => {
self.step0_data = data;
}
GenerateInput::SetStep1(data) => {
self.step1_data = data;
}
GenerateInput::SetStep2(step) => {
self.step2_data = step;
}
GenerateInput::SetStep3(data) => {
self.step3_data = data;
}
GenerateInput::SetStep4(data) => {
self.step4_data = data;
}
}
}
}
impl From<Out> for crate::Config {
fn from(val: Out) -> Self {
let mut config = Self::from(default_config());
if let Some(overview) = &val.overview {
config.windows.overview.enabled = true;
config.windows.overview.modifier = overview.0;
config.windows.overview.key.clone_from(&overview.1);
config
.windows
.overview
.launcher
.plugins
.applications
.enabled = val.launcher.launch_applications;
config.windows.overview.launcher.plugins.terminal.enabled =
val.launcher.run_commands_in_terminal;
config.windows.overview.launcher.plugins.shell.enabled =
val.launcher.run_commands_in_background;
config.windows.overview.launcher.plugins.websearch.enabled =
val.launcher.search_the_web;
config.windows.overview.launcher.plugins.calc.enabled =
val.launcher.calculate_math_expressions;
config.windows.overview.launcher.plugins.actions.enabled = val.launcher.run_actions;
config.windows.overview.launcher.default_terminal = val.default_terminal;
let mut vec = vec![];
if val.launcher_websearch_plugin.google {
vec.push(WEB_SEARCH_ENGINES
.iter()
.find(|(n, _)| *n == "Google")
.expect("engine not found: Google")
.1());
}
if val.launcher_websearch_plugin.startpage {
vec.push(WEB_SEARCH_ENGINES
.iter()
.find(|(n, _)| *n == "Startpage")
.expect("engine not found: Startpage")
.1());
}
if val.launcher_websearch_plugin.duckduckgo {
vec.push(WEB_SEARCH_ENGINES
.iter()
.find(|(n, _)| *n == "DuckDuckGo")
.expect("engine not found: DuckDuckGo")
.1());
}
if val.launcher_websearch_plugin.bing {
vec.push(WEB_SEARCH_ENGINES
.iter()
.find(|(n, _)| *n == "Bing")
.expect("engine not found: Bing")
.1());
}
if val.launcher_websearch_plugin.wikipedia {
vec.push(WEB_SEARCH_ENGINES
.iter()
.find(|(n, _)| *n == "Wikipedia")
.expect("engine not found: Wikipedia")
.1());
}
if val.launcher_websearch_plugin.chatgpt {
vec.push(WEB_SEARCH_ENGINES
.iter()
.find(|(n, _)| *n == "ChatGpt")
.expect("engine not found: ChatGpt")
.1());
}
if val.launcher_websearch_plugin.youtube {
vec.push(WEB_SEARCH_ENGINES
.iter()
.find(|(n, _)| *n == "YouTube")
.expect("engine not found: YouTube")
.1());
}
if val.launcher_websearch_plugin.reddit {
vec.push(WEB_SEARCH_ENGINES
.iter()
.find(|(n, _)| *n == "Reddit")
.expect("engine not found: Reddit")
.1());
}
config.windows.overview.launcher.plugins.websearch.engines = vec;
} else {
config.windows.overview.enabled = false;
}
if let Some(switch) = &val.switch {
config.windows.switch.enabled = true;
config.windows.switch.modifier = switch.0;
config.windows.switch.key.clone_from(&switch.1);
} else {
config.windows.switch.enabled = false;
}
config
}
}
#[allow(clippy::type_complexity)]
pub const WEB_SEARCH_ENGINES: &[(&str, fn() -> SearchEngine)] = &[
("Google", || SearchEngine {
url: "https://www.google.com/search?q={}".into(),
name: "Google".into(),
key: 'g',
}),
("Startpage", || SearchEngine {
url: "https://www.startpage.com/sp/search?query={}".into(),
name: "Startpage".into(),
key: 's',
}),
("DuckDuckGo", || SearchEngine {
url: "https://duckduckgo.com/?q={}".into(),
name: "DuckDuckGo".into(),
key: 'd',
}),
("Bing", || SearchEngine {
url: "https://www.bing.com/search?q={}".into(),
name: "Bing".into(),
key: 'b',
}),
("Wikipedia", || SearchEngine {
url: "https://en.wikipedia.org/wiki/Special:Search?search={}".into(),
name: "Wikipedia".into(),
key: 'w',
}),
("ChatGpt", || SearchEngine {
url: "https://chatgpt.com/?q={}".into(),
name: "ChatGpt".into(),
key: 'c',
}),
("YouTube", || SearchEngine {
url: "https://www.youtube.com/results?search_query={}".into(),
name: "YouTube".into(),
key: 'y',
}),
("Reddit", || SearchEngine {
url: "https://www.reddit.com/search?q={}".into(),
name: "Reddit".into(),
key: 'r',
}),
];
================================================
FILE: crates/config-edit-lib/src/components/generate/mod.rs
================================================
mod main;
pub use main::*;
mod step0;
mod step1;
mod step2;
mod step3;
mod step4;
================================================
FILE: crates/config-edit-lib/src/components/generate/step0.rs
================================================
use crate::components::shortcut_dialog::{
KeyboardShortcut, KeyboardShortcutInit, KeyboardShortcutInput, KeyboardShortcutOutput,
};
use crate::structs::ConfigModifier;
use crate::util::{SelectRow, mod_key_to_string};
use relm4::adw::gtk::{Align, Justification};
use relm4::adw::prelude::*;
use relm4::gtk::{SelectionMode, gio};
use relm4::{
Component, ComponentController, ComponentParts, ComponentSender, Controller, RelmWidgetExt,
SimpleComponent, WidgetRef,
};
use relm4::{adw, gtk};
use std::path::Path;
use tracing::trace;
#[derive(Debug)]
pub struct Step0 {
keyboard_shortcut: Controller<KeyboardShortcut>,
list_box: gtk::ListBox,
button: adw::ButtonRow,
}
#[derive(Debug)]
pub enum Step0Input {
// external set method
SetData(Option<(ConfigModifier, String)>),
// internal set method
ISetData(Option<(ConfigModifier, String)>),
OpenKeyboardShortcut(gtk::Widget),
}
#[derive(Debug)]
pub struct Step0Init {
pub system_data_dir: Box<Path>,
}
#[allow(unused_assignments)]
#[relm4::component(pub)]
impl SimpleComponent for Step0 {
type Init = Step0Init;
type Input = Step0Input;
type Output = Option<(ConfigModifier, String)>;
view! {
#[root]
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_hexpand: true,
set_spacing: 20,
gtk::Label::new(Some("Key combination to open the overview and launcher")) {
set_css_classes: &["title-1"],
set_align: Align::Center,
set_justify: Justification::Center,
},
#[local_ref]
list_box -> gtk::ListBox {
set_halign: Align::Center,
set_valign: Align::Start,
set_hexpand: true,
set_selection_mode: SelectionMode::Single,
set_css_classes: &["boxed-list", "generate-min-width"],
connect_row_activated[sender] => move |_, row| {
if let Some(wdg) = row.downcast_ref::<adw::ActionRow>() {
let title = wdg.title().to_string();
trace!("press title: {title}");
match &*title {
"Disabled" => {
sender.input(Step0Input::ISetData(None));
}
"Super" => {
sender.input(Step0Input::ISetData(Some((ConfigModifier::Super, "Super_L".to_string()))));
}
"Super + Tab" => {
sender.input(Step0Input::ISetData(Some((ConfigModifier::Super, "Tab".to_string()))));
}
"Ctrl" => {
sender.input(Step0Input::ISetData(Some((ConfigModifier::Ctrl, "Ctrl_L".to_string()))));
}
"Ctrl + Tab" => {
sender.input(Step0Input::ISetData(Some((ConfigModifier::Ctrl, "Tab".to_string()))));
}
"Alt" => {
sender.input(Step0Input::ISetData(Some((ConfigModifier::Alt, "Alt_L".to_string()))));
}
"Alt + Tab" => {
sender.input(Step0Input::ISetData(Some((ConfigModifier::Alt, "Tab".to_string()))));
}
_ => {}
}
}
},
adw::ActionRow {
set_title: "Disabled",
set_activatable: true,
},
adw::ActionRow {
set_title: "Super",
set_activatable: true,
},
adw::ActionRow {
set_title: "Super + Tab",
set_activatable: true,
},
adw::ActionRow {
set_title: "Ctrl",
set_activatable: true,
},
adw::ActionRow {
set_title: "Ctrl + Tab",
set_activatable: true,
},
adw::ActionRow {
set_title: "Alt",
set_activatable: true,
},
adw::ActionRow {
set_title: "Alt + Tab",
set_activatable: true,
},
#[local_ref]
button -> adw::ButtonRow {
connect_activated[sender] => move |b| {
trace!("Generate: step0_keyboard_button toggled");
sender.input(Step0Input::OpenKeyboardShortcut(b.widget_ref().clone()));
}
},
},
gtk::Picture {
set_file: Some(&gio::File::for_path(init.system_data_dir.join("00_overview.png"))),
set_css_classes: &["theme-image"],
set_vexpand: true,
set_hexpand: false,
set_valign: Align::Fill,
set_halign: Align::Center,
},
gtk::Label::new(Some("similar to gnome's overview\nShows all apps in a miniature view, allows to switch using arrow keys or tab.")) {
set_css_classes: &["title-4"],
set_justify: Justification::Center,
set_vexpand: true,
set_valign: Align::End,
},
}
}
fn init(
init: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let ins = sender.input_sender().clone();
let keyboard_shortcut = KeyboardShortcut::builder()
.launch(KeyboardShortcutInit {
label: Some("Custom".to_string()),
icon: None,
init: None,
})
.connect_receiver(move |_send, out| match out {
KeyboardShortcutOutput::SetKey(r#mod, key) => {
// updates the label
ins.emit(Step0Input::ISetData(Some((r#mod, key))));
}
_ => {}
});
let list_box = gtk::ListBox::default();
let button = adw::ButtonRow::default();
let model = Self {
keyboard_shortcut,
button: button.clone(),
list_box: list_box.clone(),
};
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
trace!("launcher::step0:update: {message:?}");
match message {
Step0Input::ISetData(data) => {
sender.input(Step0Input::SetData(data.clone()));
sender.output_sender().emit(data);
}
Step0Input::SetData(data) => {
self.list_box
.select_row_index(match data.as_ref().map(|(a, b)| (a, b.as_str())) {
None => 0,
Some((ConfigModifier::Super, "Super_L")) => 1,
Some((ConfigModifier::Super, "Tab")) => 2,
Some((ConfigModifier::Ctrl, "Ctrl_L")) => 3,
Some((ConfigModifier::Ctrl, "Tab")) => 4,
Some((ConfigModifier::Alt, "Alt_L")) => 5,
Some((ConfigModifier::Alt, "Tab")) => 6,
_ => 7,
});
self.button.set_title(&format!(
"Custom: {}",
if data.is_some()
&& data != Some((ConfigModifier::Super, "Super_L".to_string()))
&& data != Some((ConfigModifier::Super, "Tab".to_string()))
&& data != Some((ConfigModifier::Ctrl, "Ctrl_L".to_string()))
&& data != Some((ConfigModifier::Ctrl, "Tab".to_string()))
&& data != Some((ConfigModifier::Alt, "Alt_L".to_string()))
&& data != Some((ConfigModifier::Alt, "Tab".to_string()))
{
data.as_ref()
.map(|(r#mod, key)| mod_key_to_string(*r#mod, key))
.unwrap_or_default()
} else {
String::new()
}
));
}
Step0Input::OpenKeyboardShortcut(widget) => {
self.keyboard_shortcut
.emit(KeyboardShortcutInput::ShowKeyboardShortcutDialog(
None,
Some(widget),
));
}
}
}
}
================================================
FILE: crates/config-edit-lib/src/components/generate/step1.rs
================================================
use relm4::adw::prelude::*;
use relm4::gtk::{Align, Justification, SelectionMode};
use relm4::{ComponentParts, ComponentSender, RelmWidgetExt, SimpleComponent};
use relm4::{adw, gtk};
use tracing::trace;
#[derive(Debug, Copy, Clone)]
pub struct LauncherPlugins {
pub launch_applications: bool,
pub run_commands_in_background: bool,
pub run_commands_in_terminal: bool,
pub search_the_web: bool,
pub calculate_math_expressions: bool,
pub run_actions: bool,
}
impl Default for LauncherPlugins {
fn default() -> Self {
Self {
launch_applications: true,
run_commands_in_background: false,
run_commands_in_terminal: true,
search_the_web: false,
calculate_math_expressions: true,
run_actions: true,
}
}
}
#[derive(Debug)]
pub struct Step1 {
launch_apps: adw::SwitchRow,
run_commands_in_background: adw::SwitchRow,
run_commands_in_terminal: adw::SwitchRow,
search_the_web: adw::SwitchRow,
calculate_math_expressions: adw::SwitchRow,
run_actions: adw::SwitchRow,
}
#[derive(Debug)]
pub enum Step1Input {
// external set method
SetData(LauncherPlugins),
// internal set method
_Update,
}
#[derive(Debug)]
pub struct Step1Init {}
#[allow(unused_assignments)]
#[relm4::component(pub)]
impl SimpleComponent for Step1 {
type Init = Step1Init;
type Input = Step1Input;
type Output = LauncherPlugins;
view! {
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_hexpand: true,
set_spacing: 40,
gtk::Label::new(Some("Launcher Plugins")) {
set_css_classes: &["title-1"],
set_align: Align::Center,
set_justify: Justification::Center,
},
gtk::ListBox {
set_halign: Align::Center,
set_valign: Align::Start,
set_hexpand: true,
set_selection_mode: SelectionMode::None,
set_css_classes: &["items-list", "boxed-list", "generate-min-width"],
#[local_ref]
launch_apps -> adw::SwitchRow {
set_title: "Launch Applications",
set_subtitle: "Launch .desktop files, sorted based on recent usage",
connect_active_notify => Step1Input::_Update,
},
#[local_ref]
run_commands_in_background -> adw::SwitchRow {
set_title: "Run Commands in Background",
set_subtitle: "Run shell commands without opening a terminal",
connect_active_notify => Step1Input::_Update,
},
#[local_ref]
run_commands_in_terminal -> adw::SwitchRow {
set_title: "Run Commands in Terminal",
set_subtitle: "Run command in a new terminal",
connect_active_notify => Step1Input::_Update,
},
#[local_ref]
search_the_web -> adw::SwitchRow {
set_title: "Search the Web",
set_subtitle: "Open browser searching for text with user defined search engine",
connect_active_notify => Step1Input::_Update,
},
#[local_ref]
calculate_math_expressions -> adw::SwitchRow {
set_title: "Calculate Math expressions",
set_subtitle: "Calculate valid Expressions using Rink",
connect_active_notify => Step1Input::_Update,
},
#[local_ref]
run_actions -> adw::SwitchRow {
set_title: "Run Actions (shutdown, sleep, custom, etc.)",
set_subtitle: "Run predefined / user defined actions",
connect_active_notify => Step1Input::_Update,
},
},
gtk::Label::new(Some("")) {
set_css_classes: &["title-4"],
set_justify: Justification::Center,
set_vexpand: true,
set_valign: Align::End,
},
}
}
fn init(
_init: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let launch_apps = adw::SwitchRow::default();
let run_commands_in_background = adw::SwitchRow::default();
let run_commands_in_terminal = adw::SwitchRow::default();
let search_the_web = adw::SwitchRow::default();
let calculate_math_expressions = adw::SwitchRow::default();
let run_actions = adw::SwitchRow::default();
let model = Self {
launch_apps: launch_apps.clone(),
run_commands_in_background: run_commands_in_background.clone(),
run_commands_in_terminal: run_commands_in_terminal.clone(),
search_the_web: search_the_web.clone(),
calculate_math_expressions: calculate_math_expressions.clone(),
run_actions: run_actions.clone(),
};
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
trace!("launcher::step1:update: {message:?}");
match message {
Step1Input::_Update => {
let data = self.get_data();
sender.output_sender().emit(data);
}
Step1Input::SetData(data) => {
self.launch_apps.set_active(data.launch_applications);
self.run_commands_in_background
.set_active(data.run_commands_in_background);
self.run_commands_in_terminal
.set_active(data.run_commands_in_terminal);
self.search_the_web.set_active(data.search_the_web);
self.calculate_math_expressions
.set_active(data.calculate_math_expressions);
self.run_actions.set_active(data.run_actions);
}
}
}
}
impl Step1 {
fn get_data(&self) -> LauncherPlugins {
LauncherPlugins {
launch_applications: self.launch_apps.is_active(),
run_commands_in_background: self.run_commands_in_background.is_active(),
run_commands_in_terminal: self.run_commands_in_terminal.is_active(),
search_the_web: self.search_the_web.is_active(),
calculate_math_expressions: self.calculate_math_expressions.is_active(),
run_actions: self.run_actions.is_active(),
}
}
}
================================================
FILE: crates/config-edit-lib/src/components/generate/step2.rs
================================================
use crate::util::{SelectRow, SetTextIfDifferent};
use core_lib::util::find_command;
use relm4::adw::prelude::*;
use relm4::gtk::{Align, Justification, SelectionMode};
use relm4::{ComponentParts, ComponentSender, RelmWidgetExt, SimpleComponent};
use relm4::{adw, gtk};
use std::path::PathBuf;
use std::sync::OnceLock;
use tracing::trace;
#[derive(Debug)]
pub struct Step2 {
list_box: gtk::ListBox,
entry: adw::EntryRow,
}
#[derive(Debug)]
pub enum Step2Input {
// external set method
SetData(Option<String>),
// internal set method
ISetData(Option<String>),
}
#[derive(Debug)]
pub struct Step2Init {}
#[allow(unused_assignments)]
#[relm4::component(pub)]
impl SimpleComponent for Step2 {
type Init = Step2Init;
type Input = Step2Input;
type Output = Option<String>;
view! {
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_hexpand: true,
set_spacing: 40,
gtk::Label::new(Some("Default Terminal")) {
set_css_classes: &["title-1"],
set_align: Align::Center,
set_justify: Justification::Center,
},
#[local_ref]
list_box -> gtk::ListBox {
set_halign: Align::Center,
set_valign: Align::Start,
set_hexpand: true,
set_selection_mode: SelectionMode::Single,
set_css_classes: &["boxed-list", "generate-min-width"],
connect_row_activated[sender] => move |_, row| {
if let Some(wdg) = row.downcast_ref::<adw::ActionRow>() {
let title = wdg.title().to_string();
trace!("press title: {title}");
match &*title {
"Autodetect" => {
sender.input(Step2Input::ISetData(None));
}
"Alacritty" => {
sender.input(Step2Input::ISetData(Some("alacritty".to_string())));
}
"Kitty" => {
sender.input(Step2Input::ISetData(Some("kitty".to_string())));
}
"Wezterm" => {
sender.input(Step2Input::ISetData(Some("wezterm".to_string())));
}
"Foot" => {
sender.input(Step2Input::ISetData(Some("foot".to_string())));
}
"QTerminal" => {
sender.input(Step2Input::ISetData(Some("qterminal".to_string())));
}
"Lilyterm" => {
sender.input(Step2Input::ISetData(Some("lilyterm".to_string())));
}
"Tilix" => {
sender.input(Step2Input::ISetData(Some("tilix".to_string())));
}
"Terminix" => {
sender.input(Step2Input::ISetData(Some("terminix".to_string())));
}
"Konsole" => {
sender.input(Step2Input::ISetData(Some("konsole".to_string())));
}
_ => {}
}
}
},
adw::ActionRow {
set_title: "Autodetect",
set_activatable: true,
set_subtitle: "autodetect from list of known terminals"
},
adw::ActionRow {
set_title: "Alacritty",
set_activatable: true,
set_css_classes: if get_terminals().iter().any(|(name, _)| *name == "alacritty") {&[]} else {&["gray-label"]},
set_subtitle: &get_terminals().iter().find(|(name, _)| *name == "alacritty").map(|(_, path)| path.display().to_string()).unwrap_or_default()
},
adw::ActionRow {
set_title: "Kitty",
set_activatable: true,
set_css_classes: if get_terminals().iter().any(|(name, _)| *name == "kitty") {&[]} else {&["gray-label"]},
set_subtitle: &get_terminals().iter().find(|(name, _)| *name == "kitty").map(|(_, path)| path.display().to_string()).unwrap_or_default()
},
adw::ActionRow {
set_title: "Wezterm",
set_activatable: true,
set_css_classes: if get_terminals().iter().any(|(name, _)| *name == "wezterm") {&[]} else {&["gray-label"]},
set_subtitle: &get_terminals().iter().find(|(name, _)| *name == "wezterm").map(|(_, path)| path.display().to_string()).unwrap_or_default()
},
adw::ActionRow {
set_title: "Foot",
set_activatable: true,
set_css_classes: if get_terminals().iter().any(|(name, _)| *name == "foot") {&[]} else {&["gray-label"]},
set_subtitle: &get_terminals().iter().find(|(name, _)| *name == "foot").map(|(_, path)| path.display().to_string()).unwrap_or_default()
},
adw::ActionRow {
set_title: "QTerminal",
set_activatable: true,
set_css_classes: if get_terminals().iter().any(|(name, _)| *name == "qterminal") {&[]} else {&["gray-label"]},
set_subtitle: &get_terminals().iter().find(|(name, _)| *name == "qterminal").map(|(_, path)| path.display().to_string()).unwrap_or_default()
},
adw::ActionRow {
set_title: "Lilyterm",
set_activatable: true,
set_css_classes: if get_terminals().iter().any(|(name, _)| *name == "lilyterm") {&[]} else {&["gray-label"]},
set_subtitle: &get_terminals().iter().find(|(name, _)| *name == "lilyterm").map(|(_, path)| path.display().to_string()).unwrap_or_default()
},
adw::ActionRow {
set_title: "Tilix",
set_activatable: true,
set_css_classes: if get_terminals().iter().any(|(name, _)| *name == "tilix") {&[]} else {&["gray-label"]},
set_subtitle: &get_terminals().iter().find(|(name, _)| *name == "tilix").map(|(_, path)| path.display().to_string()).unwrap_or_default()
},
adw::ActionRow {
set_title: "Terminix",
set_activatable: true,
set_css_classes: if get_terminals().iter().any(|(name, _)| *name == "terminix") {&[]} else {&["gray-label"]},
set_subtitle: &get_terminals().iter().find(|(name, _)| *name == "terminix").map(|(_, path)| path.display().to_string()).unwrap_or_default()
},
adw::ActionRow {
set_title: "Konsole",
set_activatable: true,
set_css_classes: if get_terminals().iter().any(|(name, _)| *name == "konsole") {&[]} else {&["gray-label"]},
set_subtitle: &get_terminals().iter().find(|(name, _)| *name == "konsole").map(|(_, path)| path.display().to_string()).unwrap_or_default()
},
#[local_ref]
entry -> adw::EntryRow {
set_title: "Custom",
connect_changed[sender] => move |e| { sender.input(Step2Input::ISetData(Some(e.text().into())))} @h_20,
set_input_purpose: gtk::InputPurpose::FreeForm,
},
},
gtk::Label::new(Some("used to open terminal applications like htop")) {
set_css_classes: &["title-4"],
set_justify: Justification::Center,
set_vexpand: true,
set_valign: Align::End,
},
}
}
fn init(
_init: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let list_box = gtk::ListBox::default();
let entry = adw::EntryRow::default();
let model = Self {
list_box: list_box.clone(),
entry: entry.clone(),
};
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
trace!("launcher::step2:update: {message:?}");
match message {
Step2Input::ISetData(data) => {
sender.input(Step2Input::SetData(data.clone()));
sender.output_sender().emit(data);
}
Step2Input::SetData(data) => {
self.list_box.select_row_index(match data.as_deref() {
None => 0,
Some("alacritty") => 1,
Some("kitty") => 2,
Some("wezterm") => 3,
Some("foot") => 4,
Some("qterminal") => 5,
Some("lilyterm") => 6,
Some("tilix") => 7,
Some("terminix") => 8,
Some("konsole") => 9,
_ => 10,
});
self.entry.set_text_if_different(
if data.is_some()
&& data != Some("alacritty".to_string())
&& data != Some("kitty".to_string())
&& data != Some("wezterm".to_string())
&& data != Some("foot".to_string())
&& data != Some("qterminal".to_string())
&& data != Some("lilyterm".to_string())
&& data != Some("tilix".to_string())
&& data != Some("terminix".to_string())
&& data != Some("konsole".to_string())
{
data.as_ref().map_or("", |v| v)
} else {
""
},
);
}
}
}
}
const TERMINALS: &[&str] = &[
"alacritty",
"kitty",
"wezterm",
"foot",
"qterminal",
"lilyterm",
"tilix",
"terminix",
"konsole",
];
fn get_terminals() -> &'static Vec<(&'static str, PathBuf)> {
static TERMS: OnceLock<Vec<(&'static str, PathBuf)>> = OnceLock::new();
TERMS.get_or_init(|| {
let mut out = vec![];
for terminal in TERMINALS {
trace!("terminal: {terminal}");
if let Some(path) = find_command(terminal) {
out.push((*terminal, path));
}
}
out
})
}
================================================
FILE: crates/config-edit-lib/src/components/generate/step3.rs
================================================
use relm4::adw::prelude::*;
use relm4::gtk::{Align, Justification, SelectionMode};
use relm4::{ComponentParts, ComponentSender, RelmWidgetExt, SimpleComponent};
use relm4::{adw, gtk};
use tracing::trace;
#[derive(Debug, Copy, Clone)]
pub struct SearchEngines {
pub google: bool,
pub startpage: bool,
pub duckduckgo: bool,
pub bing: bool,
pub wikipedia: bool,
pub chatgpt: bool,
pub youtube: bool,
pub reddit: bool,
}
impl Default for SearchEngines {
fn default() -> Self {
Self {
google: false,
startpage: true,
duckduckgo: false,
bing: false,
wikipedia: true,
chatgpt: false,
youtube: false,
reddit: false,
}
}
}
#[derive(Debug)]
pub struct Step3 {
pub google: adw::SwitchRow,
pub startpage: adw::SwitchRow,
pub duckduckgo: adw::SwitchRow,
pub bing: adw::SwitchRow,
pub wikipedia: adw::SwitchRow,
pub chatgpt: adw::SwitchRow,
pub youtube: adw::SwitchRow,
pub reddit: adw::SwitchRow,
}
#[derive(Debug)]
pub enum Step3Input {
// external set method
SetData(SearchEngines),
// internal set method
_Update,
}
#[derive(Debug)]
pub struct Step3Init {}
#[allow(unused_assignments)]
#[relm4::component(pub)]
impl SimpleComponent for Step3 {
type Init = Step3Init;
type Input = Step3Input;
type Output = SearchEngines;
view! {
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_hexpand: true,
set_spacing: 40,
gtk::Label::new(Some("Launcher Websearch Plugin")) {
set_css_classes: &["title-1"],
set_align: Align::Center,
set_justify: Justification::Center,
},
gtk::ListBox {
set_halign: Align::Center,
set_valign: Align::Start,
set_hexpand: true,
set_selection_mode: SelectionMode::None,
set_css_classes: &["items-list", "boxed-list", "generate-min-width"],
#[local_ref]
google -> adw::SwitchRow {
set_title: "Google",
set_subtitle: "https://www.google.com/search?q={}",
connect_active_notify => Step3Input::_Update,
},
#[local_ref]
startpage -> adw::SwitchRow {
set_title: "Startpage",
set_subtitle: "https://www.startpage.com/sp/search?query={}",
connect_active_notify => Step3Input::_Update,
},
#[local_ref]
duckduckgo -> adw::SwitchRow {
set_title: "DuckDuckGo",
set_subtitle: "https://duckduckgo.com/?q={}",
connect_active_notify => Step3Input::_Update,
},
#[local_ref]
bing -> adw::SwitchRow {
set_title: "Bing",
set_subtitle: "https://www.bing.com/search?q={}",
connect_active_notify => Step3Input::_Update,
},
#[local_ref]
wikipedia -> adw::SwitchRow {
set_title: "Wikipedia",
set_subtitle: "https://en.wikipedia.org/wiki/Special:Search?search={}",
connect_active_notify => Step3Input::_Update,
},
#[local_ref]
chatgpt -> adw::SwitchRow {
set_title: "ChatGpt",
set_subtitle: "https://chatgpt.com/?q={}",
connect_active_notify => Step3Input::_Update,
},
#[local_ref]
youtube -> adw::SwitchRow {
set_title: "YouTube",
set_subtitle: "https://www.youtube.com/results?search_query={}",
connect_active_notify => Step3Input::_Update,
},
#[local_ref]
reddit -> adw::SwitchRow {
set_title: "Reddit",
set_subtitle: "https://www.reddit.com/search?q={}",
connect_active_notify => Step3Input::_Update,
},
},
gtk::Label::new(Some("Search engines used for the websearch plugin in the launcher\n{} are replaced with the search string")) {
set_css_classes: &["title-4"],
set_justify: Justification::Center,
set_vexpand: true,
set_valign: Align::End,
},
}
}
fn init(
_init: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let google = adw::SwitchRow::default();
let startpage = adw::SwitchRow::default();
let duckduckgo = adw::SwitchRow::default();
let bing = adw::SwitchRow::default();
let wikipedia = adw::SwitchRow::default();
let chatgpt = adw::SwitchRow::default();
let youtube = adw::SwitchRow::default();
let reddit = adw::SwitchRow::default();
let model = Self {
google: google.clone(),
startpage: startpage.clone(),
duckduckgo: duckduckgo.clone(),
bing: bing.clone(),
wikipedia: wikipedia.clone(),
chatgpt: chatgpt.clone(),
youtube: youtube.clone(),
reddit: reddit.clone(),
};
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
trace!("launcher::step3:update: {message:?}");
match message {
Step3Input::_Update => {
let data = self.get_data();
sender.output_sender().emit(data);
}
Step3Input::SetData(data) => {
self.google.set_active(data.google);
self.startpage.set_active(data.startpage);
self.duckduckgo.set_active(data.duckduckgo);
self.bing.set_active(data.bing);
self.wikipedia.set_active(data.wikipedia);
self.chatgpt.set_active(data.chatgpt);
self.youtube.set_active(data.youtube);
self.reddit.set_active(data.reddit);
}
}
}
}
impl Step3 {
fn get_data(&self) -> SearchEngines {
SearchEngines {
google: self.google.is_active(),
startpage: self.startpage.is_active(),
duckduckgo: self.duckduckgo.is_active(),
bing: self.bing.is_active(),
wikipedia: self.wikipedia.is_active(),
chatgpt: self.chatgpt.is_active(),
youtube: self.youtube.is_active(),
reddit: self.reddit.is_active(),
}
}
}
================================================
FILE: crates/config-edit-lib/src/components/generate/step4.rs
================================================
use crate::components::shortcut_dialog::{
KeyboardShortcut, KeyboardShortcutInit, KeyboardShortcutInput, KeyboardShortcutOutput,
};
use crate::structs::ConfigModifier;
use crate::util::{SelectRow, mod_key_to_string};
use relm4::adw::prelude::*;
use relm4::gtk::{Align, Justification, SelectionMode, gio};
use relm4::{
Component, ComponentController, ComponentParts, ComponentSender, Controller, RelmWidgetExt,
SimpleComponent, WidgetRef,
};
use relm4::{adw, gtk};
use std::path::Path;
use tracing::trace;
#[derive(Debug)]
pub struct Step4 {
keyboard_shortcut: Controller<KeyboardShortcut>,
list_box: gtk::ListBox,
button: adw::ButtonRow,
}
#[derive(Debug)]
pub enum Step4Input {
// external set method
SetData(Option<(ConfigModifier, String)>),
// internal set method
ISetData(Option<(ConfigModifier, String)>),
OpenKeyboardShortcut(gtk::Widget),
}
#[derive(Debug)]
pub struct Step4Init {
pub system_data_dir: Box<Path>,
}
#[allow(unused_assignments)]
#[relm4::component(pub)]
impl SimpleComponent for Step4 {
type Init = Step4Init;
type Input = Step4Input;
type Output = Option<(ConfigModifier, String)>;
view! {
#[root]
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_hexpand: true,
set_spacing: 20,
gtk::Label::new(Some("Key combination to open the overview and launcher")) {
set_css_classes: &["title-1"],
set_align: Align::Center,
set_justify: Justification::Center,
},
#[local_ref]
list_box -> gtk::ListBox {
set_halign: Align::Center,
set_valign: Align::Start,
set_hexpand: true,
set_selection_mode: SelectionMode::Single,
set_css_classes: &["boxed-list", "generate-min-width"],
connect_row_activated[sender] => move |_, row| {
if let Some(wdg) = row.downcast_ref::<adw::ActionRow>() {
let title = wdg.title().to_string();
trace!("press title: {title}");
match &*title {
"Disabled" => {
sender.input(Step4Input::ISetData(None));
}
"Super" => {
sender.input(Step4Input::ISetData(Some((ConfigModifier::Super, "Super_L".to_string()))));
}
"Super + Tab" => {
sender.input(Step4Input::ISetData(Some((ConfigModifier::Super, "Tab".to_string()))));
}
"Ctrl" => {
sender.input(Step4Input::ISetData(Some((ConfigModifier::Ctrl, "Ctrl_L".to_string()))));
}
"Ctrl + Tab" => {
sender.input(Step4Input::ISetData(Some((ConfigModifier::Ctrl, "Tab".to_string()))));
}
"Alt" => {
sender.input(Step4Input::ISetData(Some((ConfigModifier::Alt, "Alt_L".to_string()))));
}
"Alt + Tab" => {
sender.input(Step4Input::ISetData(Some((ConfigModifier::Alt, "Tab".to_string()))));
}
_ => {}
}
}
},
adw::ActionRow {
set_title: "Disabled",
set_activatable: true,
},
adw::ActionRow {
set_title: "Super",
set_activatable: true,
},
adw::ActionRow {
set_title: "Super + Tab",
set_activatable: true,
},
adw::ActionRow {
set_title: "Ctrl",
set_activatable: true,
},
adw::ActionRow {
set_title: "Ctrl + Tab",
set_activatable: true,
},
adw::ActionRow {
set_title: "Alt",
set_activatable: true,
},
adw::ActionRow {
set_title: "Alt + Tab",
set_activatable: true,
},
#[local_ref]
button -> adw::ButtonRow {
connect_activated[sender] => move |b| {
trace!("Generate: step0_keyboard_button toggled");
sender.input(Step4Input::OpenKeyboardShortcut(b.widget_ref().clone()));
}
},
},
gtk::Picture {
set_file: Some(&gio::File::for_path(init.system_data_dir.join("04_switch.png"))),
set_css_classes: &["theme-image"],
set_vexpand: true,
set_hexpand: false,
set_valign: Align::Fill,
set_halign: Align::Center,
},
gtk::Label::new(Some("Shows windows in a list sorted by recently accessed. Navigate using tab.\nPlease use a different keyboard Shortcut than the Overview modifier")) {
set_css_classes: &["title-4"],
set_justify: Justification::Center,
set_vexpand: true,
set_valign: Align::End,
},
}
}
fn init(
init: Self::Init,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let ins = sender.input_sender().clone();
let keyboard_shortcut = KeyboardShortcut::builder()
.launch(KeyboardShortcutInit {
label: Some("Custom".to_string()),
icon: None,
init: None,
})
.connect_receiver(move |_send, out| match out {
KeyboardShortcutOutput::SetKey(r#mod, key) => {
// updates the label
ins.emit(Step4Input::ISetData(Some((r#mod, key))));
}
_ => {}
});
let list_box = gtk::ListBox::default();
let button = adw::ButtonRow::default();
let model = Self {
keyboard_shortcut,
button: button.clone(),
list_box: list_box.clone(),
};
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
trace!("launcher::step4:update: {message:?}");
match message {
Step4Input::ISetData(data) => {
sender.input(Step4Input::SetData(data.clone()));
sender.output_sender().emit(data);
}
Step4Input::SetData(data) => {
self.list_box
.select_row_index(match data.as_ref().map(|(a, b)| (a, b.as_str())) {
None => 0,
Some((ConfigModifier::Super, "Super_L")) => 1,
Some((ConfigModifier::Super, "Tab")) => 2,
Some((ConfigModifier::Ctrl, "Ctrl_L")) => 3,
Some((ConfigModifier::Ctrl, "Tab")) => 4,
Some((ConfigModifier::Alt, "Alt_L")) => 5,
Some((ConfigModifier::Alt, "Tab")) => 6,
_ => 7,
});
self.button.set_title(&format!(
"Custom: {}",
if data.is_some()
&& data != Some((ConfigModifier::Super, "Super_L".to_string()))
&& data != Some((ConfigModifier::Super, "Tab".to_string()))
&& data != Some((ConfigModifier::Ctrl, "Ctrl_L".to_string()))
&& data != Some((ConfigModifier::Ctrl, "Tab".to_string()))
&& data != Some((ConfigModifier::Alt, "Alt_L".to_string()))
&& data != Some((ConfigModifier::Alt, "Tab".to_string()))
{
data.as_ref()
.map(|(r#mod, key)| mod_key_to_string(*r#mod, key))
.unwrap_or_default()
} else {
String::new()
}
));
}
Step4Input::OpenKeyboardShortcut(widget) => {
self.keyboard_shortcut
.emit(KeyboardShortcutInput::ShowKeyboardShortcutDialog(
None,
Some(widget),
));
}
}
}
}
================================================
FILE: crates/config-edit-lib/src/components/launcher.rs
================================================
use crate::components::launcher_plugins::{
LauncherPlugins, LauncherPluginsInit, LauncherPluginsInput, LauncherPluginsOutput,
};
use crate::structs::ConfigModifier;
use crate::util::{SetCursor, SetTextIfDifferent};
use relm4::ComponentController;
use relm4::adw::prelude::*;
use relm4::{
Component, ComponentParts, ComponentSender, Controller, RelmWidgetExt, SimpleComponent,
};
use relm4::{adw, gtk};
use tracing::trace;
#[derive(Debug)]
pub struct Launcher {
config: crate::Launcher,
prev_config: crate::Launcher,
plugins: Controller<LauncherPlugins>,
}
#[derive(Debug)]
pub enum LauncherInput {
Set(crate::Launcher),
SetPrev(crate::Launcher),
Reset,
}
#[derive(Debug)]
pub struct LauncherInit {
pub config: crate::Launcher,
}
#[derive(Debug)]
pub enum LauncherOutput {
Modifier(ConfigModifier),
Width(u32),
MaxItems(u8),
DefaultTerminal(Option<String>),
LauncherPlugins(LauncherPluginsOutput),
}
#[relm4::component(pub)]
impl SimpleComponent for Launcher {
type Init = LauncherInit;
type Input = LauncherInput;
type Output = LauncherOutput;
view! {
#[root]
gtk::Box {
set_orientation: gtk::Orientation::Horizontal,
set_margin_all: 10,
adw::ExpanderRow {
set_title_selectable: true,
set_show_enable_switch: false,
set_hexpand: true,
set_css_classes: &["enable-frame"],
set_title: "Launcher",
set_expanded: true,
add_row = >k::Box {
set_orientation: gtk::Orientation::Horizontal,
set_css_classes: &["frame-row"],
set_spacing: 30,
gtk::Box {
set_orientation: gtk::Orientation::Horizontal,
set_spacing: 10,
gtk::Label {
#[wa
gitextract_elrb4jir/
├── .githooks/
│ └── pre-commit
├── .github/
│ └── workflows/
│ ├── publish.yml
│ ├── release-please.yml
│ ├── test.yml
│ └── update.yml
├── .gitignore
├── .idea/
│ ├── .gitignore
│ ├── copilot.data.migration.agent.xml
│ ├── copilot.data.migration.ask.xml
│ ├── copilot.data.migration.ask2agent.xml
│ ├── copilot.data.migration.edit.xml
│ ├── file.template.settings.xml
│ ├── hyprshell.iml
│ ├── inspectionProfiles/
│ │ └── Project_Default.xml
│ ├── modules.xml
│ ├── rust.xml
│ └── vcs.xml
├── .release-please-manifest.json
├── CHANGELOG.md
├── Cargo.toml
├── DEVELOPMENT.md
├── LICENSE
├── README.md
├── crates/
│ ├── clipboard-lib/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── config/
│ │ │ └── mod.rs
│ │ ├── lib.rs
│ │ ├── store/
│ │ │ ├── listen.rs
│ │ │ ├── mime.rs
│ │ │ ├── mod.rs
│ │ │ ├── save_image.rs
│ │ │ ├── save_map.rs
│ │ │ ├── save_text.rs
│ │ │ ├── util.rs
│ │ │ └── write.rs
│ │ └── util/
│ │ ├── brotli_compressor.rs
│ │ ├── crypt.rs
│ │ ├── lz4_compressor.rs
│ │ ├── mod.rs
│ │ ├── secret_service.rs
│ │ └── zstd_compressor.rs
│ ├── config-edit-lib/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── components/
│ │ │ ├── changes.rs
│ │ │ ├── footer.rs
│ │ │ ├── generate/
│ │ │ │ ├── main.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── step0.rs
│ │ │ │ ├── step1.rs
│ │ │ │ ├── step2.rs
│ │ │ │ ├── step3.rs
│ │ │ │ └── step4.rs
│ │ │ ├── launcher.rs
│ │ │ ├── launcher_plugins/
│ │ │ │ ├── actions.rs
│ │ │ │ ├── applications.rs
│ │ │ │ ├── main.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── simple.rs
│ │ │ │ └── websearch.rs
│ │ │ ├── mod.rs
│ │ │ ├── nix_preview.rs
│ │ │ ├── root.rs
│ │ │ ├── shortcut_dialog.rs
│ │ │ ├── switch.rs
│ │ │ ├── theme.rs
│ │ │ ├── windows.rs
│ │ │ └── windows_overview.rs
│ │ ├── lib.rs
│ │ ├── start.rs
│ │ ├── structs.rs
│ │ ├── styles.css
│ │ └── util.rs
│ ├── config-lib/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── actions.rs
│ │ ├── check.rs
│ │ ├── explain.rs
│ │ ├── lib.rs
│ │ ├── load.rs
│ │ ├── migrate/
│ │ │ ├── check.rs
│ │ │ ├── m1t2/
│ │ │ │ ├── convert.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── old_structs.rs
│ │ │ ├── m2t3/
│ │ │ │ ├── convert.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── old_structs.rs
│ │ │ ├── migrate_config.rs
│ │ │ └── mod.rs
│ │ ├── modifier.rs
│ │ ├── save.rs
│ │ ├── structs.rs
│ │ └── style/
│ │ ├── load.rs
│ │ ├── mod.rs
│ │ └── structs.rs
│ ├── core-lib/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── binds/
│ │ │ ├── mod.rs
│ │ │ ├── structs.rs
│ │ │ └── transfer.rs
│ │ ├── const.rs
│ │ ├── data.rs
│ │ ├── default/
│ │ │ └── mod.rs
│ │ ├── ini.rs
│ │ ├── ini_owned.rs
│ │ ├── lib.rs
│ │ ├── listener.rs
│ │ ├── notify.rs
│ │ ├── path.rs
│ │ ├── transfer/
│ │ │ ├── mod.rs
│ │ │ ├── receive.rs
│ │ │ ├── send.rs
│ │ │ └── structs.rs
│ │ └── util/
│ │ ├── boot.rs
│ │ ├── exec.rs
│ │ ├── exists.rs
│ │ ├── helpers.rs
│ │ ├── mod.rs
│ │ └── path.rs
│ ├── exec-lib/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── binds.rs
│ │ ├── collect.rs
│ │ ├── lib.rs
│ │ ├── listener.rs
│ │ ├── plugin.rs
│ │ ├── run.rs
│ │ ├── switch.rs
│ │ └── util.rs
│ ├── hyprland-plugin/
│ │ ├── Cargo.toml
│ │ ├── build.rs
│ │ ├── plugin/
│ │ │ ├── .gitignore
│ │ │ ├── .idea/
│ │ │ │ ├── copilot.data.migration.agent.xml
│ │ │ │ ├── copilot.data.migration.ask2agent.xml
│ │ │ │ ├── copilot.data.migration.edit.xml
│ │ │ │ ├── dictionaries/
│ │ │ │ │ └── project.xml
│ │ │ │ ├── editor.xml
│ │ │ │ ├── misc.xml
│ │ │ │ ├── vcs.xml
│ │ │ │ └── workspace.xml
│ │ │ ├── Makefile
│ │ │ ├── README.md
│ │ │ ├── src-52/
│ │ │ │ ├── defs-test.h
│ │ │ │ ├── defs.h
│ │ │ │ ├── exit.cpp
│ │ │ │ ├── globals.h
│ │ │ │ ├── handlers.h
│ │ │ │ ├── init.cpp
│ │ │ │ ├── key-press.cpp
│ │ │ │ ├── keyboard-focus.cpp
│ │ │ │ ├── layer-change.cpp
│ │ │ │ ├── main.cpp
│ │ │ │ ├── mouse-button.cpp
│ │ │ │ ├── send.cpp
│ │ │ │ └── send.h
│ │ │ ├── src-54/
│ │ │ │ ├── defs-test.h
│ │ │ │ ├── defs.h
│ │ │ │ ├── exit.cpp
│ │ │ │ ├── globals.h
│ │ │ │ ├── handlers.h
│ │ │ │ ├── init.cpp
│ │ │ │ ├── key-press.cpp
│ │ │ │ ├── keyboard-focus.cpp
│ │ │ │ ├── layer-change.cpp
│ │ │ │ ├── main.cpp
│ │ │ │ ├── mouse-button.cpp
│ │ │ │ ├── send.cpp
│ │ │ │ └── send.h
│ │ │ └── test-hyprland.conf
│ │ └── src/
│ │ ├── build.rs
│ │ ├── configure.rs
│ │ ├── extract.rs
│ │ ├── lib.rs
│ │ └── test.rs
│ ├── launcher-lib/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── close.rs
│ │ ├── create.rs
│ │ ├── css.rs
│ │ ├── debug.rs
│ │ ├── global.rs
│ │ ├── lib.rs
│ │ ├── open.rs
│ │ ├── plugins/
│ │ │ ├── actions.rs
│ │ │ ├── applications/
│ │ │ │ ├── data.rs
│ │ │ │ ├── map.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── plugin.rs
│ │ │ ├── calc.rs
│ │ │ ├── mod.rs
│ │ │ ├── path.rs
│ │ │ ├── search.rs
│ │ │ ├── shell.rs
│ │ │ └── terminal.rs
│ │ ├── stop.rs
│ │ ├── styles.css
│ │ └── update.rs
│ └── windows-lib/
│ ├── Cargo.toml
│ └── src/
│ ├── css.rs
│ ├── data.rs
│ ├── desktop_map.rs
│ ├── global.rs
│ ├── icon.rs
│ ├── keybinds.rs
│ ├── lib.rs
│ ├── next.rs
│ ├── overview/
│ │ ├── close.rs
│ │ ├── create.rs
│ │ ├── mod.rs
│ │ ├── open.rs
│ │ ├── stop.rs
│ │ └── update.rs
│ ├── sort.rs
│ ├── styles.css
│ └── switch/
│ ├── close.rs
│ ├── create.rs
│ ├── mod.rs
│ ├── open.rs
│ ├── stop.rs
│ └── update.rs
├── dep-crates/
│ ├── hyprland-rs/
│ │ ├── Cargo.toml
│ │ ├── LICENSE
│ │ ├── MIGRATION.md
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── bind.rs
│ │ │ ├── bind_async.rs
│ │ │ ├── data.rs
│ │ │ ├── data_async.rs
│ │ │ ├── dispatch.rs
│ │ │ ├── dispatch_async.rs
│ │ │ ├── events.rs
│ │ │ ├── events_async.rs
│ │ │ ├── keyword.rs
│ │ │ └── keyword_async.rs
│ │ ├── flake.nix
│ │ ├── hyprland-macros/
│ │ │ ├── Cargo.toml
│ │ │ ├── README.md
│ │ │ └── src/
│ │ │ └── lib.rs
│ │ ├── src/
│ │ │ ├── config.rs
│ │ │ ├── ctl.rs
│ │ │ ├── data/
│ │ │ │ ├── helpers.rs
│ │ │ │ ├── macros.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── regular.rs
│ │ │ ├── dispatch.rs
│ │ │ ├── error.rs
│ │ │ ├── event_listener/
│ │ │ │ ├── async_im.rs
│ │ │ │ ├── immutable.rs
│ │ │ │ ├── macros.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── shared.rs
│ │ │ │ └── stream.rs
│ │ │ ├── hyprpaper/
│ │ │ │ ├── error.rs
│ │ │ │ ├── keyword.rs
│ │ │ │ ├── monitor.rs
│ │ │ │ ├── preload.rs
│ │ │ │ ├── reload.rs
│ │ │ │ ├── unload.rs
│ │ │ │ ├── wallpaper.rs
│ │ │ │ ├── wallpaper_listing.rs
│ │ │ │ └── wallpaper_mode.rs
│ │ │ ├── hyprpaper.rs
│ │ │ ├── instance.rs
│ │ │ ├── keyword.rs
│ │ │ ├── lib.rs
│ │ │ ├── shared.rs
│ │ │ └── unsafe_impl.rs
│ │ ├── test.sh
│ │ └── treefmt.toml
│ └── wl-clipboard-rs/
│ ├── .github/
│ │ ├── dependabot.yml
│ │ └── workflows/
│ │ └── ci.yml
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── Cargo.toml
│ ├── LICENSE-APACHE
│ ├── LICENSE-MIT
│ ├── README.md
│ ├── README.tpl
│ ├── doc/
│ │ └── index.html
│ ├── rustfmt.toml
│ └── src/
│ ├── common.rs
│ ├── copy.rs
│ ├── data_control.rs
│ ├── lib.rs
│ ├── paste.rs
│ ├── seat_data.rs
│ ├── tests/
│ │ ├── copy.rs
│ │ ├── mod.rs
│ │ ├── paste.rs
│ │ ├── state.rs
│ │ └── utils.rs
│ └── utils.rs
├── docs/
│ ├── CONFIGURE.md
│ ├── DEBUG.md
│ ├── NIX.md
│ └── css-examples/
│ ├── default.css
│ ├── dracula.css
│ ├── gruvbox_dark.css
│ ├── liquid-glass.css
│ ├── modern.css
│ ├── solarized_dark.css
│ ├── test.css
│ └── tokyo_night_storm.css
├── flake.nix
├── justfile
├── nix/
│ ├── build.nix
│ ├── checks.nix
│ ├── meta.nix
│ ├── module.nix
│ └── util.nix
├── packaging/
│ ├── hyprshell-settings.desktop
│ ├── hyprshell.service
│ └── pkgbuild/
│ ├── PKGBUILD
│ ├── PKGBUILD-bin
│ └── PKGBUILD-slim
├── pkgbuild/
│ ├── PKGBUILD
│ ├── PKGBUILD-bin
│ └── PKGBUILD-slim
├── release-please-config.json
├── renovate.json
├── scripts/
│ ├── check-all-feature-combinations.sh
│ └── ci/
│ ├── build-aarch64.sh
│ ├── build-x86.sh
│ ├── install-gtk4-layer-shell-aarch64.sh
│ └── install-gtk4-layer-shell.sh
└── src/
├── cli.rs
├── completions.rs
├── data.rs
├── debug.rs
├── default_apps.rs
├── default_styles.css
├── explain.rs
├── keybinds.rs
├── main.rs
├── receive_handle.rs
├── socket.rs
├── start.rs
└── util.rs
SYMBOL INDEX (1370 symbols across 200 files)
FILE: crates/clipboard-lib/src/config/mod.rs
type Config (line 4) | pub struct Config {
type Encryption (line 11) | pub enum Encryption {
type Compression (line 21) | pub enum Compression {
type ConvolutionFilterType (line 33) | pub enum ConvolutionFilterType {
function from (line 45) | fn from(value: ConvolutionFilterType) -> Self {
FILE: crates/clipboard-lib/src/store/listen.rs
function test_clipboard (line 16) | pub fn test_clipboard(_data_dir: PathBuf, cache_dir: PathBuf) {
function conf (line 81) | fn conf() -> Config {
FILE: crates/clipboard-lib/src/store/mime.rs
function get_preferred_mime (line 25) | pub fn get_preferred_mime(mime_types: &HashSet<String>) -> Option<String> {
function filer_mimes (line 42) | pub fn filer_mimes(mime_types: &mut HashSet<String>) {
FILE: crates/clipboard-lib/src/store/save_image.rs
constant IMAGE_HEIGHT (line 15) | const IMAGE_HEIGHT: u32 = 150;
function compress_and_store_image (line 17) | pub fn compress_and_store_image(
FILE: crates/clipboard-lib/src/store/save_map.rs
type ClipboardDataType (line 13) | pub enum ClipboardDataType {
function compress_and_store_map (line 18) | pub fn compress_and_store_map(data: HashMap<String, Vec<u8>>, config: &C...
function store_map (line 49) | fn store_map(
function deduplicate_clipboard_entries (line 80) | pub fn deduplicate_clipboard_entries(
FILE: crates/clipboard-lib/src/store/save_text.rs
function store_text (line 10) | pub fn store_text(text: &str, config: &Config, cache_dir: &Path) -> anyh...
FILE: crates/clipboard-lib/src/store/util.rs
function create_storage_path (line 8) | pub fn create_storage_path(cache_dir: &Path, path: &str, ext: &str) -> a...
FILE: crates/clipboard-lib/src/store/write.rs
function get_storage_writer (line 4) | pub fn get_storage_writer<'a, I: Write + 'a>(
FILE: crates/clipboard-lib/src/util/brotli_compressor.rs
type BrotliCompressWriter (line 7) | pub struct BrotliCompressWriter<W: Write> {
function new (line 12) | pub fn new(writer: W, mut level: u8) -> Self {
method write (line 27) | fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
method flush (line 31) | fn flush(&mut self) -> std::io::Result<()> {
FILE: crates/clipboard-lib/src/util/crypt.rs
type K (line 7) | type K = chacha20poly1305::Key;
type K (line 9) | type K = aes_gcm::Key<aes_gcm::Aes256Gcm>;
function generate_new_key (line 11) | pub fn generate_new_key() -> anyhow::Result<Vec<u8>> {
type SecretEncryptWriter (line 17) | pub struct SecretEncryptWriter<W: Write> {
type Config (line 24) | pub enum Config {
function new (line 32) | pub const fn new(writer: W, key: Vec<u8>, config: Config) -> Self {
function encrypt (line 41) | pub fn encrypt(&self, cleartext: &[u8]) -> anyhow::Result<Vec<u8>> {
method write (line 77) | fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
method flush (line 82) | fn flush(&mut self) -> std::io::Result<()> {
method drop (line 88) | fn drop(&mut self) {
FILE: crates/clipboard-lib/src/util/lz4_compressor.rs
type LZ4CompressWriter (line 5) | pub struct LZ4CompressWriter<W: Write> {
function new (line 10) | pub fn new(writer: W) -> Self {
method write (line 18) | fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
method flush (line 22) | fn flush(&mut self) -> std::io::Result<()> {
method drop (line 28) | fn drop(&mut self) {
FILE: crates/clipboard-lib/src/util/secret_service.rs
function get_secret_service (line 9) | fn get_secret_service() -> Option<&'static SecretService<'static>> {
function get_hyprshell_key (line 24) | pub fn get_hyprshell_key() -> anyhow::Result<Vec<u8>> {
FILE: crates/clipboard-lib/src/util/zstd_compressor.rs
type ZstdCompressWriter (line 5) | pub struct ZstdCompressWriter<'a, W: Write> {
function new (line 10) | pub fn new(writer: W, mut level: u8) -> Self {
method write (line 23) | fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
method flush (line 27) | fn flush(&mut self) -> std::io::Result<()> {
method drop (line 33) | fn drop(&mut self) {
FILE: crates/config-edit-lib/src/components/changes.rs
type Changes (line 12) | pub struct Changes {
type ChangesInput (line 20) | pub enum ChangesInput {
type ChangesInit (line 26) | pub struct ChangesInit {
type ChangesOutput (line 31) | pub enum ChangesOutput {
type Init (line 38) | type Init = ChangesInit;
type Input (line 39) | type Input = ChangesInput;
type Output (line 40) | type Output = ChangesOutput;
method init (line 69) | fn init(
method update (line 85) | fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
function generate_items (line 107) | pub fn generate_items(changes: >k::ListBox, config: &Config, prev_conf...
function add_plugin_changes (line 444) | fn add_plugin_changes(changes: >k::ListBox, prev: &Plugins, current: &...
function add_info (line 566) | fn add_info(changes: >k::ListBox, text: &str) {
function add_info_subtitle (line 571) | fn add_info_subtitle(changes: >k::ListBox, text: &str, subtitle: Strin...
FILE: crates/config-edit-lib/src/components/footer.rs
type Footer (line 8) | pub struct Footer {
type FooterInput (line 15) | pub enum FooterInput {
type FooterInit (line 21) | pub struct FooterInit {
type FooterOutput (line 26) | pub enum FooterOutput {
type Init (line 36) | type Init = FooterInit;
type Input (line 37) | type Input = FooterInput;
type Output (line 38) | type Output = FooterOutput;
method init (line 101) | fn init(
method update (line 115) | fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self...
FILE: crates/config-edit-lib/src/components/generate/main.rs
type Generate (line 20) | pub struct Generate {
type GenerateInput (line 40) | pub enum GenerateInput {
type GenerateInit (line 52) | pub struct GenerateInit {
type GenerateOutput (line 57) | pub enum GenerateOutput {
type Out (line 61) | struct Out {
constant MAX_STEP (line 69) | const MAX_STEP: usize = 5;
type Init (line 74) | type Init = GenerateInit;
type Input (line 75) | type Input = GenerateInput;
type Output (line 76) | type Output = GenerateOutput;
method init (line 147) | fn init(
method update (line 214) | fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
function from (line 327) | fn from(val: Out) -> Self {
constant WEB_SEARCH_ENGINES (line 427) | pub const WEB_SEARCH_ENGINES: &[(&str, fn() -> SearchEngine)] = &[
FILE: crates/config-edit-lib/src/components/generate/step0.rs
type Step0 (line 18) | pub struct Step0 {
type Step0Input (line 25) | pub enum Step0Input {
type Step0Init (line 34) | pub struct Step0Init {
type Init (line 41) | type Init = Step0Init;
type Input (line 42) | type Input = Step0Input;
type Output (line 43) | type Output = Option<(ConfigModifier, String)>;
method init (line 146) | fn init(
method update (line 178) | fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
FILE: crates/config-edit-lib/src/components/generate/step1.rs
type LauncherPlugins (line 8) | pub struct LauncherPlugins {
method default (line 18) | fn default() -> Self {
type Step1 (line 31) | pub struct Step1 {
method get_data (line 168) | fn get_data(&self) -> LauncherPlugins {
type Step1Input (line 41) | pub enum Step1Input {
type Step1Init (line 49) | pub struct Step1Init {}
type Init (line 54) | type Init = Step1Init;
type Input (line 55) | type Input = Step1Input;
type Output (line 56) | type Output = LauncherPlugins;
method init (line 120) | fn init(
method update (line 145) | fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
FILE: crates/config-edit-lib/src/components/generate/step2.rs
type Step2 (line 12) | pub struct Step2 {
type Step2Input (line 18) | pub enum Step2Input {
type Step2Init (line 26) | pub struct Step2Init {}
type Init (line 31) | type Init = Step2Init;
type Input (line 32) | type Input = Step2Input;
type Output (line 33) | type Output = Option<String>;
method init (line 166) | fn init(
method update (line 182) | fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
constant TERMINALS (line 225) | const TERMINALS: &[&str] = &[
function get_terminals (line 237) | fn get_terminals() -> &'static Vec<(&'static str, PathBuf)> {
FILE: crates/config-edit-lib/src/components/generate/step3.rs
type SearchEngines (line 8) | pub struct SearchEngines {
method default (line 20) | fn default() -> Self {
type Step3 (line 35) | pub struct Step3 {
method get_data (line 189) | fn get_data(&self) -> SearchEngines {
type Step3Input (line 47) | pub enum Step3Input {
type Step3Init (line 55) | pub struct Step3Init {}
type Init (line 60) | type Init = Step3Init;
type Input (line 61) | type Input = Step3Input;
type Output (line 62) | type Output = SearchEngines;
method init (line 138) | fn init(
method update (line 167) | fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
FILE: crates/config-edit-lib/src/components/generate/step4.rs
type Step4 (line 17) | pub struct Step4 {
type Step4Input (line 24) | pub enum Step4Input {
type Step4Init (line 33) | pub struct Step4Init {
type Init (line 40) | type Init = Step4Init;
type Input (line 41) | type Input = Step4Input;
type Output (line 43) | type Output = Option<(ConfigModifier, String)>;
method init (line 146) | fn init(
method update (line 178) | fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
FILE: crates/config-edit-lib/src/components/launcher.rs
type Launcher (line 15) | pub struct Launcher {
type LauncherInput (line 22) | pub enum LauncherInput {
type LauncherInit (line 29) | pub struct LauncherInit {
type LauncherOutput (line 34) | pub enum LauncherOutput {
type Init (line 44) | type Init = LauncherInit;
type Input (line 45) | type Input = LauncherInput;
type Output (line 46) | type Output = LauncherOutput;
method init (line 171) | fn init(
method update (line 191) | fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self...
FILE: crates/config-edit-lib/src/components/launcher_plugins/actions.rs
type Actions (line 13) | pub struct Actions {
type ActionsInput (line 27) | pub enum ActionsInput {
type ActionsInit (line 38) | pub struct ActionsInit {
type ActionsOutput (line 43) | pub enum ActionsOutput {
type Init (line 51) | type Init = ActionsInit;
type Input (line 52) | type Input = ActionsInput;
type Output (line 53) | type Output = ActionsOutput;
method init (line 102) | fn init(
method update (line 172) | fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
type Action (line 242) | struct Action {
type ActionInput (line 247) | enum ActionInput {
type ActionOutput (line 252) | pub enum ActionOutput {
type Init (line 259) | type Init = ActionsPluginAction;
type Input (line 260) | type Input = ActionInput;
type Output (line 261) | type Output = ActionOutput;
type CommandOutput (line 262) | type CommandOutput = ();
type ParentWidget (line 263) | type ParentWidget = gtk::ListBox;
method init_model (line 277) | fn init_model(init: Self::Init, _index: &DynamicIndex, sender: FactorySe...
method update_with_view (line 284) | fn update_with_view(
method update (line 300) | fn update(&mut self, msg: Self::Input, _sender: FactorySender<Self>) {
FILE: crates/config-edit-lib/src/components/launcher_plugins/applications.rs
type Applications (line 9) | pub struct Applications {
type ApplicationsInput (line 15) | pub enum ApplicationsInput {
type ApplicationsInit (line 22) | pub struct ApplicationsInit {
type ApplicationsOutput (line 27) | pub enum ApplicationsOutput {
type Init (line 36) | type Init = ApplicationsInit;
type Input (line 37) | type Input = ApplicationsInput;
type Output (line 38) | type Output = ApplicationsOutput;
method init (line 137) | fn init(
method update (line 151) | fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self...
FILE: crates/config-edit-lib/src/components/launcher_plugins/main.rs
type LauncherPlugins (line 22) | pub struct LauncherPlugins {
type LauncherPluginsInput (line 35) | pub enum LauncherPluginsInput {
type LauncherPluginsInit (line 42) | pub struct LauncherPluginsInit {
type LauncherPluginsOutput (line 47) | pub enum LauncherPluginsOutput {
type Init (line 59) | type Init = LauncherPluginsInit;
type Input (line 60) | type Input = LauncherPluginsInput;
type Output (line 61) | type Output = LauncherPluginsOutput;
method init (line 103) | fn init(
method update (line 168) | fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self...
FILE: crates/config-edit-lib/src/components/launcher_plugins/simple.rs
type SimplePlugin (line 9) | pub struct SimplePlugin {
type SimplePluginInput (line 15) | pub enum SimplePluginInput {
type SimplePluginInit (line 22) | pub struct SimplePluginInit {
type SimplePluginOutput (line 29) | pub enum SimplePluginOutput {
type Init (line 35) | type Init = SimplePluginInit;
type Input (line 36) | type Input = SimplePluginInput;
type Output (line 37) | type Output = SimplePluginOutput;
method init (line 68) | fn init(
method update (line 82) | fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self...
FILE: crates/config-edit-lib/src/components/launcher_plugins/websearch.rs
type WebSearch (line 12) | pub struct WebSearch {
type WebSearchInput (line 25) | pub enum WebSearchInput {
type WebSearchInit (line 36) | pub struct WebSearchInit {
type WebSearchOutput (line 41) | pub enum WebSearchOutput {
type Init (line 49) | type Init = WebSearchInit;
type Input (line 50) | type Input = WebSearchInput;
type Output (line 51) | type Output = WebSearchOutput;
method init (line 98) | fn init(
method update (line 165) | fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
type Search (line 227) | struct Search {
type SearchInput (line 232) | enum SearchInput {}
type SearchOutput (line 235) | pub enum SearchOutput {
type Init (line 241) | type Init = SearchEngine;
type Input (line 242) | type Input = SearchInput;
type Output (line 243) | type Output = SearchOutput;
type CommandOutput (line 244) | type CommandOutput = ();
type ParentWidget (line 245) | type ParentWidget = gtk::ListBox;
method init_model (line 257) | fn init_model(init: Self::Init, _index: &DynamicIndex, _sender: FactoryS...
method update (line 261) | fn update(&mut self, msg: Self::Input, _sender: FactorySender<Self>) {
FILE: crates/config-edit-lib/src/components/nix_preview.rs
type NixPreview (line 6) | pub struct NixPreview {}
type NixPreviewInput (line 9) | pub enum NixPreviewInput {}
type NixPreviewInit (line 12) | pub struct NixPreviewInit {}
type NixPreviewOutput (line 15) | pub enum NixPreviewOutput {}
type Init (line 19) | type Init = NixPreviewInit;
type Input (line 20) | type Input = NixPreviewInput;
type Output (line 21) | type Output = NixPreviewOutput;
method init (line 33) | fn init(
method update (line 44) | fn update(&mut self, _message: Self::Input, _sender: ComponentSender<Sel...
FILE: crates/config-edit-lib/src/components/root.rs
type Root (line 31) | pub struct Root {
type RootInput (line 55) | pub enum RootInput {
type RootInit (line 76) | pub struct RootInit {
type RootOutput (line 84) | pub enum RootOutput {}
type Init (line 89) | type Init = RootInit;
type Input (line 90) | type Input = RootInput;
type Output (line 91) | type Output = RootOutput;
method init (line 154) | fn init(
method update (line 294) | fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
FILE: crates/config-edit-lib/src/components/shortcut_dialog.rs
type KeyboardShortcut (line 14) | pub struct KeyboardShortcut {
type KeyboardShortcutInput (line 24) | pub enum KeyboardShortcutInput {
type KeyboardShortcutInit (line 34) | pub struct KeyboardShortcutInit {
type KeyboardShortcutOutput (line 41) | pub enum KeyboardShortcutOutput {
type Init (line 49) | type Init = KeyboardShortcutInit;
type Input (line 50) | type Input = KeyboardShortcutInput;
type Output (line 51) | type Output = KeyboardShortcutOutput;
method init (line 65) | fn init(
method update (line 125) | fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
FILE: crates/config-edit-lib/src/components/switch.rs
type Switch (line 15) | pub struct Switch {
type SwitchInput (line 23) | pub enum SwitchInput {
type SwitchInit (line 31) | pub struct SwitchInit {
type SwitchOutput (line 37) | pub enum SwitchOutput {
type Init (line 50) | type Init = SwitchInit;
type Input (line 51) | type Input = SwitchInput;
type Output (line 52) | type Output = SwitchOutput;
method init (line 187) | fn init(
method update (line 224) | fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self...
FILE: crates/config-edit-lib/src/components/theme.rs
type ThemeCarousel (line 15) | struct ThemeCarousel {
type ThemeCarouselInput (line 20) | enum ThemeCarouselInput {}
type ThemeCarouselOutput (line 23) | enum ThemeCarouselOutput {
type Init (line 29) | type Init = Theme;
type Input (line 30) | type Input = ThemeCarouselInput;
type Output (line 31) | type Output = ThemeCarouselOutput;
type CommandOutput (line 32) | type CommandOutput = ();
type ParentWidget (line 33) | type ParentWidget = adw::Carousel;
method init_model (line 101) | fn init_model(init: Self::Init, _index: &DynamicIndex, _sender: FactoryS...
method update (line 105) | fn update(&mut self, msg: Self::Input, _sender: FactorySender<Self>) {
type Style (line 111) | pub struct Style {
type StyleInput (line 121) | pub enum StyleInput {
type StyleInit (line 126) | pub struct StyleInit {
type StyleOutput (line 132) | pub enum StyleOutput {
type Init (line 139) | type Init = StyleInit;
type Input (line 140) | type Input = StyleInput;
type Output (line 141) | type Output = StyleOutput;
method init (line 185) | fn init(
method update (line 239) | fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self...
function load_themes (line 269) | fn load_themes(
FILE: crates/config-edit-lib/src/components/windows.rs
type Windows (line 15) | pub struct Windows {
type WindowsInput (line 24) | pub enum WindowsInput {
type WindowsOutput (line 31) | pub enum WindowsOutput {
type WindowsInit (line 41) | pub struct WindowsInit {
type Init (line 47) | type Init = WindowsInit;
type Input (line 48) | type Input = WindowsInput;
type Output (line 49) | type Output = WindowsOutput;
method init (line 125) | fn init(
method update (line 160) | fn update(&mut self, message: WindowsInput, _sender: ComponentSender<Sel...
FILE: crates/config-edit-lib/src/components/windows_overview.rs
type WindowsOverview (line 16) | pub struct WindowsOverview {
type WindowsOverviewInput (line 23) | pub enum WindowsOverviewInput {
type WindowsOverviewInit (line 31) | pub struct WindowsOverviewInit {
type WindowsOverviewOutput (line 36) | pub enum WindowsOverviewOutput {
type Init (line 48) | type Init = WindowsOverviewInit;
type Input (line 49) | type Input = WindowsOverviewInput;
type Output (line 50) | type Output = WindowsOverviewOutput;
method init (line 165) | fn init(
method update (line 198) | fn update(&mut self, message: WindowsOverviewInput, _sender: ComponentSe...
FILE: crates/config-edit-lib/src/lib.rs
constant APPLICATION_EDIT_ID (line 6) | pub const APPLICATION_EDIT_ID: &str = "com.github.h3rmt.hyprshell-edit";
FILE: crates/config-edit-lib/src/start.rs
function start (line 12) | pub fn start(config_file: PathBuf, css_file: PathBuf, system_data_dir: P...
FILE: crates/config-edit-lib/src/structs.rs
type Config (line 5) | pub struct Config {
method from (line 166) | fn from(value: config_lib::Config) -> Self {
type Windows (line 10) | pub struct Windows {
method from (line 183) | fn from(value: Option<config_lib::Windows>) -> Self {
type Overview (line 20) | pub struct Overview {
method from (line 259) | fn from(value: Option<config_lib::Overview>) -> Self {
type Launcher (line 32) | pub struct Launcher {
method from (line 305) | fn from(value: config_lib::Launcher) -> Self {
type Plugins (line 42) | pub struct Plugins {
method from (line 421) | fn from(value: config_lib::Plugins) -> Self {
type WebSearchConfig (line 53) | pub struct WebSearchConfig {
method from (line 398) | fn from(value: Option<config_lib::WebSearchConfig>) -> Self {
type EmptyConfig (line 59) | pub struct EmptyConfig {
method from (line 331) | fn from(value: Option<config_lib::EmptyConfig>) -> Self {
type ActionsPluginConfig (line 64) | pub struct ActionsPluginConfig {
method from (line 348) | fn from(value: Option<config_lib::ActionsPluginConfig>) -> Self {
type ApplicationsPluginConfig (line 70) | pub struct ApplicationsPluginConfig {
method from (line 371) | fn from(value: Option<config_lib::ApplicationsPluginConfig>) -> Self {
type Switch (line 79) | pub struct Switch {
method from (line 214) | fn from(value: Option<config_lib::Switch>) -> Self {
type ConfigModifier (line 91) | pub enum ConfigModifier {
method strings (line 100) | pub const fn strings() -> &'static [&'static str] {
method strings_with_none (line 103) | pub const fn strings_with_none() -> &'static [&'static str] {
method fmt (line 109) | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
type Error (line 120) | type Error = ();
method try_from (line 121) | fn try_from(value: u32) -> Result<Self, Self::Error> {
method from (line 144) | fn from(value: config_lib::Modifier) -> Self {
function from (line 133) | fn from(value: ConfigModifier) -> Self {
function from (line 155) | fn from(value: ConfigModifier) -> Self {
function from (line 174) | fn from(value: Config) -> Self {
function from (line 198) | fn from(value: Windows) -> Self {
function from (line 233) | fn from(value: Switch) -> Self {
function from (line 278) | fn from(value: Overview) -> Self {
function from (line 318) | fn from(value: Launcher) -> Self {
function from (line 338) | fn from(value: EmptyConfig) -> Self {
function from (line 359) | fn from(value: ActionsPluginConfig) -> Self {
function from (line 384) | fn from(value: ApplicationsPluginConfig) -> Self {
function from (line 409) | fn from(value: WebSearchConfig) -> Self {
function from (line 435) | fn from(value: Plugins) -> Self {
FILE: crates/config-edit-lib/src/util.rs
type SetTextIfDifferent (line 8) | pub trait SetTextIfDifferent {
method set_text_if_different (line 9) | fn set_text_if_different(&self, text: &str);
method set_text_if_different (line 13) | fn set_text_if_different(&self, text: &str) {
method set_text_if_different (line 22) | fn set_text_if_different(&self, text: &str) {
type SetCursor (line 29) | pub trait SetCursor {
method set_cursor_by_name (line 30) | fn set_cursor_by_name(&self, name: &str);
method set_cursor_by_name (line 34) | fn set_cursor_by_name(&self, name: &str) {
type ScrollToPosition (line 40) | pub trait ScrollToPosition {
method scroll_to_pos (line 41) | fn scroll_to_pos(&self, pos: usize, animate: bool);
method scroll_to_pos (line 45) | fn scroll_to_pos(&self, pos: usize, animate: bool) {
type SelectRow (line 65) | pub trait SelectRow {
method select_row_index_opt (line 66) | fn select_row_index_opt(&self, index: Option<i32>);
method select_row_index (line 67) | fn select_row_index(&self, index: i32);
method select_row_index_opt (line 71) | fn select_row_index_opt(&self, index: Option<i32>) {
method select_row_index (line 78) | fn select_row_index(&self, index: i32) {
function handle_key (line 90) | pub fn handle_key(val: Key, state: ModifierType) -> Option<(String, Conf...
function default_config (line 114) | pub fn default_config() -> config_lib::Config {
function mod_key_to_accelerator (line 122) | pub fn mod_key_to_accelerator(modifier: ConfigModifier, key: &str) -> St...
function mod_key_to_string (line 142) | pub fn mod_key_to_string(modifier: ConfigModifier, key: &str) -> String {
FILE: crates/config-lib/src/actions.rs
type ToAction (line 4) | pub trait ToAction {
method to_action (line 5) | fn to_action(self) -> ActionsPluginActionCustom;
method to_action (line 9) | fn to_action(self) -> ActionsPluginActionCustom {
FILE: crates/config-lib/src/check.rs
function check (line 4) | pub fn check(config: &Config) -> anyhow::Result<()> {
function full (line 69) | fn full() -> Config {
function test_valid_config (line 82) | fn test_valid_config() {
function test_invalid_scale (line 89) | fn test_invalid_scale() {
function test_invalid_key (line 107) | fn test_invalid_key() {
function test_duplicate_engine_key (line 122) | fn test_duplicate_engine_key() {
function test_empty_engine_url (line 144) | fn test_empty_engine_url() {
function test_empty_engine_name (line 162) | fn test_empty_engine_name() {
function test_empty_terminal (line 180) | fn test_empty_terminal() {
FILE: crates/config-lib/src/explain.rs
constant BOLD (line 5) | const BOLD: &str = "\x1b[1m";
constant ITALIC (line 6) | const ITALIC: &str = "\x1b[3m";
constant BLUE (line 7) | const BLUE: &str = "\x1b[34m";
constant GREEN (line 8) | const GREEN: &str = "\x1b[32m";
constant RESET (line 9) | const RESET: &str = "\x1b[0m";
function explain (line 12) | pub fn explain(config: &Config, config_file: Option<&Path>, enable_color...
function create_test_config (line 111) | fn create_test_config() -> Config {
function test_explain_with_overview (line 124) | fn test_explain_with_overview() {
function test_explain_without_overview (line 147) | fn test_explain_without_overview() {
function test_explain_without_switch (line 167) | fn test_explain_without_switch() {
function test_explain_without_plugins (line 195) | fn test_explain_without_plugins() {
FILE: crates/config-lib/src/lib.rs
constant CURRENT_CONFIG_VERSION (line 18) | pub const CURRENT_CONFIG_VERSION: u16 = 3;
FILE: crates/config-lib/src/load.rs
function load_and_migrate_config (line 11) | pub fn load_and_migrate_config(config_file: &Path, allow_migrate: bool) ...
function load_config_file (line 52) | pub fn load_config_file<T: DeserializeOwned>(config_file: &Path) -> anyh...
FILE: crates/config-lib/src/migrate/check.rs
type EmptyConfig (line 9) | pub(super) struct EmptyConfig {
function check_migration_needed (line 13) | pub fn check_migration_needed(config_file: &Path) -> anyhow::Result<bool> {
function get_config_version (line 19) | pub fn get_config_version(config_file: &Path) -> anyhow::Result<u16> {
FILE: crates/config-lib/src/migrate/m1t2/convert.rs
function from (line 5) | fn from(value: old_structs::Config) -> Self {
function from (line 16) | fn from(value: old_structs::Windows) -> Self {
function from (line 27) | fn from(value: old_structs::Overview) -> Self {
function from (line 39) | fn from(value: old_structs::Switch) -> Self {
function from (line 51) | fn from(value: old_structs::Launcher) -> Self {
function from (line 69) | fn from(value: old_structs::Modifier) -> Self {
FILE: crates/config-lib/src/migrate/m1t2/mod.rs
constant PREV_CONFIG_VERSION (line 1) | pub const PREV_CONFIG_VERSION: u16 = 1;
constant NEXT_CONFIG_VERSION (line 2) | pub const NEXT_CONFIG_VERSION: u16 = 2;
FILE: crates/config-lib/src/migrate/m1t2/old_structs.rs
type Config (line 8) | pub struct Config {
type Windows (line 21) | pub(super) struct Windows {
type Switch (line 34) | pub(super) struct Switch {
type Overview (line 45) | pub(super) struct Overview {
type Launcher (line 62) | pub(super) struct Launcher {
type Modifier (line 89) | pub(super) enum Modifier {
method fmt (line 97) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
FILE: crates/config-lib/src/migrate/m2t3/convert.rs
function from (line 4) | fn from(value: old_structs::Config) -> Self {
function from (line 13) | fn from(value: old_structs::Windows) -> Self {
function from (line 25) | fn from(value: old_structs::Overview) -> Self {
function from (line 38) | fn from(value: old_structs::Launcher) -> Self {
function from (line 51) | fn from(value: old_structs::Plugins) -> Self {
FILE: crates/config-lib/src/migrate/m2t3/mod.rs
constant PREV_CONFIG_VERSION (line 1) | pub const PREV_CONFIG_VERSION: u16 = 2;
constant NEXT_CONFIG_VERSION (line 2) | pub const NEXT_CONFIG_VERSION: u16 = 3;
FILE: crates/config-lib/src/migrate/m2t3/old_structs.rs
type Config (line 6) | pub struct Config {
type Windows (line 19) | pub struct Windows {
type Overview (line 32) | pub struct Overview {
type Launcher (line 46) | pub struct Launcher {
type Plugins (line 70) | pub struct Plugins {
FILE: crates/config-lib/src/migrate/migrate_config.rs
function migrate (line 8) | pub fn migrate(config_file: &Path) -> anyhow::Result<crate::Config> {
FILE: crates/config-lib/src/modifier.rs
type Modifier (line 7) | pub enum Modifier {
method to_l_key (line 16) | pub fn to_l_key(&self) -> String {
method to_str (line 24) | pub const fn to_str(&self) -> &'static str {
method deserialize (line 35) | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
type Error (line 69) | type Error = anyhow::Error;
method try_from (line 71) | fn try_from(value: &str) -> Result<Self, Self::Error> {
method fmt (line 83) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method serialize (line 59) | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
FILE: crates/config-lib/src/save.rs
constant CONFIG_EXPLANATION (line 12) | const CONFIG_EXPLANATION: &str = "Edit with `hyprshell config edit`";
function write_config (line 14) | pub fn write_config(
FILE: crates/config-lib/src/structs.rs
type Config (line 9) | pub struct Config {
type Windows (line 19) | pub struct Windows {
type Overview (line 35) | pub struct Overview {
type Launcher (line 52) | pub struct Launcher {
type Plugins (line 79) | pub struct Plugins {
type EmptyConfig (line 92) | pub struct EmptyConfig {}
type ActionsPluginConfig (line 97) | pub struct ActionsPluginConfig {
type ApplicationsPluginConfig (line 124) | pub struct ApplicationsPluginConfig {
type ActionsPluginAction (line 135) | pub enum ActionsPluginAction {
type ActionsPluginActionCustom (line 147) | pub struct ActionsPluginActionCustom {
type WebSearchConfig (line 157) | pub struct WebSearchConfig {
type SearchEngine (line 172) | pub struct SearchEngine {
type Switch (line 181) | pub struct Switch {
type FilterBy (line 196) | pub enum FilterBy {
FILE: crates/config-lib/src/style/load.rs
function load_themes (line 10) | pub fn load_themes(
function parse_data (line 105) | fn parse_data(data: &str, name: &str) -> ThemeData {
FILE: crates/config-lib/src/style/structs.rs
type Theme (line 4) | pub struct Theme {
type ThemeData (line 14) | pub struct ThemeData {
FILE: crates/core-lib/src/binds/structs.rs
type ExecBind (line 2) | pub struct ExecBind {
FILE: crates/core-lib/src/binds/transfer.rs
function get_hyprshell_path (line 7) | pub fn get_hyprshell_path() -> String {
function generate_transfer_socat (line 18) | pub fn generate_transfer_socat(transfer: &TransferType) -> String {
function generate_transfer (line 29) | pub fn generate_transfer(transfer: &TransferType) -> String {
FILE: crates/core-lib/src/const.rs
constant APPLICATION_ID (line 1) | pub const APPLICATION_ID: &str = "com.github.h3rmt.hyprshell";
constant OVERVIEW_NAMESPACE (line 2) | pub const OVERVIEW_NAMESPACE: &str = "hyprshell_overview";
constant SWITCH_NAMESPACE (line 3) | pub const SWITCH_NAMESPACE: &str = "hyprshell_switch";
constant LAUNCHER_NAMESPACE (line 4) | pub const LAUNCHER_NAMESPACE: &str = "hyprshell_launcher";
constant TERMINALS (line 8) | pub const TERMINALS: [&str; 9] = [
FILE: crates/core-lib/src/data.rs
type WorkspaceId (line 1) | pub type WorkspaceId = i32;
type MonitorId (line 2) | pub type MonitorId = i128;
type ClientId (line 3) | pub type ClientId = u64;
type Active (line 6) | pub struct Active {
type MonitorData (line 13) | pub struct MonitorData {
type WorkspaceData (line 22) | pub struct WorkspaceData {
type ClientData (line 31) | pub struct ClientData {
type HyprlandData (line 47) | pub struct HyprlandData {
type FindByFirst (line 53) | pub trait FindByFirst<ID, Data> {
method find_by_first (line 54) | fn find_by_first(&self, id: &ID) -> Option<&Data>;
function find_by_first (line 58) | fn find_by_first(&self, id: &ClientId) -> Option<&ClientData> {
function find_by_first (line 64) | fn find_by_first(&self, id: &WorkspaceId) -> Option<&WorkspaceData> {
function find_by_first (line 70) | fn find_by_first(&self, id: &MonitorId) -> Option<&MonitorData> {
FILE: crates/core-lib/src/default/mod.rs
function get_desktop_files_from_cache (line 11) | fn get_desktop_files_from_cache() -> &'static RwLock<Vec<(DirEntry, IniF...
function get_mime_files_from_cache (line 15) | fn get_mime_files_from_cache() -> &'static RwLock<Vec<(DirEntry, IniFile...
function get_icons_from_cache (line 19) | fn get_icons_from_cache() -> &'static RwLock<BTreeSet<Box<str>>> {
function get_all_desktop_files (line 24) | pub fn get_all_desktop_files<'a>()
function get_all_mime_files (line 31) | pub fn get_all_mime_files<'a>() -> anyhow::Result<RwLockReadGuard<'a, Ve...
function get_all_icons (line 38) | pub fn get_all_icons<'a>() -> anyhow::Result<RwLockReadGuard<'a, BTreeSe...
function theme_has_icon_name (line 45) | pub fn theme_has_icon_name(name: &str) -> bool {
function get_default_desktop_file (line 52) | pub fn get_default_desktop_file<F, R>(mime: &str, r#fn: F) -> Option<R>
function reload_default_files (line 83) | pub fn reload_default_files() -> anyhow::Result<()> {
function reload_available_icons (line 120) | pub fn reload_available_icons(
function collect_unique_filenames_recursive (line 176) | fn collect_unique_filenames_recursive(dir: &Path) -> BTreeSet<Box<str>> {
FILE: crates/core-lib/src/ini.rs
type Section (line 8) | pub struct Section<'a> {
function new (line 14) | pub fn new() -> Self {
function get_all (line 19) | pub fn get_all(&self, key: &str) -> Option<&Vec<&'a str>> {
function get_first (line 24) | pub fn get_first(&self, key: &str) -> Option<&'a str> {
function get_all_as_boxed (line 29) | pub fn get_all_as_boxed(&self, key: &str) -> Option<Vec<Box<str>>> {
function get_first_as_boxed (line 35) | pub fn get_first_as_boxed(&self, key: &str) -> Option<Box<str>> {
function get_first_as_path_boxed (line 39) | pub fn get_first_as_path_boxed(&self, key: &str) -> Option<Box<Path>> {
function get_first_as_boolean (line 44) | pub fn get_first_as_boolean(&self, key: &str) -> Option<bool> {
function insert_item (line 50) | pub fn insert_item(&mut self, key: &'a str, desktop_file: &'a str) {
function insert_item_at_front (line 53) | pub fn insert_item_at_front(&mut self, key: &'a str, desktop_file: &'a s...
function insert_items (line 56) | pub fn insert_items(&mut self, key: &'a str, mut desktop_files: Vec<&'a ...
function set_items (line 62) | pub fn set_items(&mut self, key: &'a str, mut desktop_files: Vec<&'a str...
type IniFile (line 74) | pub struct IniFile<'a> {
function from_str (line 80) | pub fn from_str(content: &str) -> IniFile<'_> {
function get_section (line 125) | pub fn get_section(&'a self, section_name: &str) -> Option<&'a Section<'...
function sections (line 130) | pub const fn sections(&self) -> &HashMap<&'a str, Section<'a>> {
function format (line 135) | pub fn format(&self) -> String {
function get_section_mut (line 158) | pub fn get_section_mut<'b>(&'b mut self, section_name: &str) -> Option<&...
function section_entry (line 165) | pub fn section_entry<'b>(&'b mut self, section_name: &'a str) -> Entry<'...
function insert_section (line 171) | pub fn insert_section(&mut self, name: &'a str, section: Section<'a>) {
function iter (line 178) | fn iter(&'a self) -> Box<dyn Iterator<Item = <&'a Self as IntoIterator>:...
type Item (line 184) | type Item = (&'a str, &'a str, &'a Vec<&'a str>);
type IntoIter (line 185) | type IntoIter = Box<dyn Iterator<Item = Self::Item> + 'a>;
method into_iter (line 187) | fn into_iter(self) -> Self::IntoIter {
function iter (line 199) | fn iter(&'a self) -> Box<dyn Iterator<Item = <&'a Self as IntoIterator>:...
type Item (line 205) | type Item = (&'a str, &'a Vec<&'a str>);
type IntoIter (line 206) | type IntoIter = Box<dyn Iterator<Item = Self::Item> + 'a>;
method into_iter (line 208) | fn into_iter(self) -> Self::IntoIter {
function test_parse_ini (line 220) | fn test_parse_ini() {
function test_empty_ini (line 283) | fn test_empty_ini() {
function test_no_sections (line 291) | fn test_no_sections() {
function test_values_iterator (line 304) | fn test_values_iterator() {
function test_values_iterator_2 (line 328) | fn test_values_iterator_2() {
function test_format_empty (line 350) | fn test_format_empty() {
function test_format_multiple_sections (line 358) | fn test_format_multiple_sections() {
FILE: crates/core-lib/src/ini_owned.rs
type OwnedSection (line 8) | pub struct OwnedSection {
method new (line 14) | pub fn new() -> Self {
method get_all (line 19) | pub fn get_all(&self, key: &str) -> Option<Vec<Box<str>>> {
method get_first (line 24) | pub fn get_first(&self, key: &str) -> Option<Box<str>> {
method get_first_as_path (line 29) | pub fn get_first_as_path(&self, key: &str) -> Option<Box<Path>> {
method get_first_as_boolean (line 34) | pub fn get_first_as_boolean(&self, key: &str) -> Option<bool> {
method insert_item (line 40) | pub fn insert_item(&mut self, mime: Box<str>, desktop_file: Box<str>) {
method insert_item_at_front (line 43) | pub fn insert_item_at_front(&mut self, mime: Box<str>, desktop_file: B...
method insert_items (line 49) | pub fn insert_items(&mut self, mime: Box<str>, mut desktop_files: Vec<...
method iter (line 179) | fn iter(&'a self) -> Box<dyn Iterator<Item = <&'a Self as IntoIterator...
type IniFileOwned (line 58) | pub struct IniFileOwned {
method from_str (line 64) | pub fn from_str(content: &str) -> Self {
method get_section (line 111) | pub fn get_section(&self, section_name: &str) -> Option<&OwnedSection> {
method sections (line 116) | pub const fn sections(&self) -> &HashMap<Box<str>, OwnedSection> {
method format (line 121) | pub fn format(&self) -> String {
method get_section_mut (line 144) | pub fn get_section_mut(&mut self, section_name: &str) -> Option<&mut O...
method section_entry (line 148) | pub fn section_entry(&mut self, section_name: Box<str>) -> Entry<'_, B...
method insert_section (line 151) | pub fn insert_section(&mut self, name: Box<str>, section: OwnedSection) {
method iter (line 158) | fn iter(&'a self) -> Box<dyn Iterator<Item = <&'a Self as IntoIterator...
type Item (line 164) | type Item = (&'a Box<str>, &'a Box<str>, &'a Vec<Box<str>>);
type IntoIter (line 165) | type IntoIter = Box<dyn Iterator<Item = Self::Item> + 'a>;
method into_iter (line 167) | fn into_iter(self) -> Self::IntoIter {
type Item (line 185) | type Item = (&'a Box<str>, &'a Vec<Box<str>>);
type IntoIter (line 186) | type IntoIter = Box<dyn Iterator<Item = Self::Item> + 'a>;
method into_iter (line 188) | fn into_iter(self) -> Self::IntoIter {
function test_parse_ini (line 200) | fn test_parse_ini() {
function test_empty_ini (line 263) | fn test_empty_ini() {
function test_no_sections (line 271) | fn test_no_sections() {
function test_values_iterator (line 284) | fn test_values_iterator() {
function test_values_iterator_2 (line 318) | fn test_values_iterator_2() {
function test_format_empty (line 340) | fn test_format_empty() {
function test_format_multiple_sections (line 348) | fn test_format_multiple_sections() {
FILE: crates/core-lib/src/listener.rs
function hyprshell_config_listener (line 8) | pub fn hyprshell_config_listener<F>(
function hyprshell_css_listener (line 42) | pub fn hyprshell_css_listener<F>(
function hyprshell_config_block (line 76) | pub fn hyprshell_config_block(file_path: &Path) -> anyhow::Result<()> {
FILE: crates/core-lib/src/notify.rs
function notify (line 5) | pub fn notify(body: &str, duration: Duration) {
function notify_resident (line 16) | pub fn notify_resident(body: &str, duration: Duration) {
function notify_warn (line 29) | pub fn notify_warn(body: &str) {
FILE: crates/core-lib/src/path.rs
function get_default_config_file (line 5) | pub fn get_default_config_file() -> PathBuf {
function get_default_css_file (line 43) | pub fn get_default_css_file() -> PathBuf {
function get_default_data_dir (line 54) | pub fn get_default_data_dir() -> PathBuf {
function get_default_cache_dir (line 65) | pub fn get_default_cache_dir() -> PathBuf {
function get_default_system_data_dir (line 76) | pub fn get_default_system_data_dir() -> PathBuf {
function get_data_home (line 91) | pub fn get_data_home() -> PathBuf {
function get_system_data_home (line 103) | pub fn get_system_data_home() -> PathBuf {
function get_cache_home (line 112) | pub fn get_cache_home() -> PathBuf {
function get_config_home (line 127) | pub fn get_config_home() -> PathBuf {
function get_config_dirs (line 139) | pub fn get_config_dirs() -> Vec<PathBuf> {
function get_data_dirs (line 148) | pub fn get_data_dirs() -> Vec<PathBuf> {
FILE: crates/core-lib/src/transfer/receive.rs
function receive_from_buffer (line 5) | pub fn receive_from_buffer(mut buffer: Vec<u8>) -> anyhow::Result<Transf...
FILE: crates/core-lib/src/transfer/send.rs
function send_raw_to_socket (line 7) | pub fn send_raw_to_socket(data: &str) -> anyhow::Result<()> {
FILE: crates/core-lib/src/transfer/structs.rs
type TransferType (line 5) | pub enum TransferType {
type OpenSwitch (line 24) | pub struct OpenSwitch {
type SwitchOverviewConfig (line 29) | pub struct SwitchOverviewConfig {
type SwitchSwitchConfig (line 35) | pub struct SwitchSwitchConfig {
type CloseOverviewConfig (line 40) | pub enum CloseOverviewConfig {
type PluginNames (line 48) | pub enum PluginNames {
type Identifier (line 59) | pub struct Identifier {
method plugin (line 69) | pub const fn plugin(plugin: PluginNames) -> Self {
method data (line 78) | pub const fn data(plugin: PluginNames, data: Box<str>) -> Self {
method data_additional (line 87) | pub const fn data_additional(
type WindowsOverride (line 101) | pub enum WindowsOverride {
type Direction (line 107) | pub enum Direction {
FILE: crates/core-lib/src/util/boot.rs
function get_boot_id (line 7) | pub fn get_boot_id() -> &'static Option<String> {
function load_boot_id (line 21) | fn load_boot_id() -> anyhow::Result<String> {
FILE: crates/core-lib/src/util/exec.rs
type ExecType (line 2) | pub enum ExecType {
constant UNKNOWN_EXEC (line 11) | const UNKNOWN_EXEC: &str = "unknown";
function analyse_exec (line 14) | pub fn analyse_exec(exec: &str) -> ExecType {
function test_relative_exec (line 92) | fn test_relative_exec() {
function test_flatpak_pwa_exec (line 101) | fn test_flatpak_pwa_exec() {
function test_appimage_exec (line 112) | fn test_appimage_exec() {
function test_absolute_pwa_exec (line 123) | fn test_absolute_pwa_exec() {
function test_flatpak_exec (line 134) | fn test_flatpak_exec() {
function test_absolute_exec (line 143) | fn test_absolute_exec() {
FILE: crates/core-lib/src/util/exists.rs
constant COMMON_DIRS (line 10) | const COMMON_DIRS: &[&str] = &[
constant NIX_DIRS (line 20) | const NIX_DIRS: &[&str] = &[
function find_command (line 35) | pub fn find_command(name: &str) -> Option<PathBuf> {
function command_exists (line 84) | pub fn command_exists(name: &str) -> bool {
function is_executable (line 88) | fn is_executable(path: &Path) -> bool {
function find_shell_exists (line 118) | fn find_shell_exists() {
function nonexistent_command_does_not_exist (line 126) | fn nonexistent_command_does_not_exist() {
FILE: crates/core-lib/src/util/helpers.rs
type GetFirstOrLast (line 4) | pub trait GetFirstOrLast: Iterator + Sized {
method get_first_or_last (line 5) | fn get_first_or_last(self, last: bool) -> Option<Self::Item>;
method get_first_or_last (line 8) | fn get_first_or_last(mut self, last: bool) -> Option<Self::Item> {
type GetNextOrPrev (line 13) | pub trait GetNextOrPrev: Iterator + Sized {
method get_next_or_prev (line 14) | fn get_next_or_prev(self, last: bool, len: usize) -> Option<Self::Item>;
method get_next_or_prev (line 17) | fn get_next_or_prev(mut self, last: bool, len: usize) -> Option<Self::...
type RevIf (line 31) | pub trait RevIf<'a>: Iterator + Sized + 'a {
method reverse_if (line 32) | fn reverse_if(self, cond: bool) -> Box<dyn Iterator<Item = Self::Item>...
method reverse_if (line 36) | fn reverse_if(self, cond: bool) -> Box<dyn Iterator<Item = Self::Item> +...
type WarnWithDetails (line 45) | pub trait WarnWithDetails<A> {
method warn_details (line 46) | fn warn_details(self, msg: &str) -> Option<A>;
type Warn (line 49) | pub trait Warn<A> {
method warn (line 50) | fn warn(self) -> Option<A>;
function warn_details (line 54) | fn warn_details(self, msg: &str) -> Self {
function warn_details (line 66) | fn warn_details(self, msg: &str) -> Option<A> {
function warn (line 79) | fn warn(self) -> Option<A> {
FILE: crates/core-lib/src/util/mod.rs
function get_daemon_socket_path_buff (line 18) | pub fn get_daemon_socket_path_buff() -> PathBuf {
function daemon_running (line 35) | pub fn daemon_running() -> bool {
FILE: crates/core-lib/src/util/path.rs
function collect_desktop_files (line 7) | pub fn collect_desktop_files() -> Vec<DirEntry> {
function collect_mime_files (line 48) | pub fn collect_mime_files() -> Vec<DirEntry> {
FILE: crates/exec-lib/src/binds.rs
function apply_layerrules (line 10) | pub fn apply_layerrules() -> anyhow::Result<()> {
function apply_exec_bind (line 28) | pub fn apply_exec_bind(bind: &ExecBind) -> anyhow::Result<()> {
FILE: crates/exec-lib/src/collect.rs
function get_hypr_data (line 10) | fn get_hypr_data() -> anyhow::Result<(Vec<Monitor>, Vec<Workspace>, Vec<...
function collect_hypr_data (line 34) | pub fn collect_hypr_data() -> anyhow::Result<(
FILE: crates/exec-lib/src/listener.rs
function monitor_listener (line 5) | pub async fn monitor_listener<F>(callback: F)
function hyprland_config_listener (line 25) | pub async fn hyprland_config_listener<F>(callback: F)
FILE: crates/exec-lib/src/plugin.rs
function load_plugin (line 15) | pub fn load_plugin(
function check_new_plugin_needed (line 58) | pub fn check_new_plugin_needed(config: &PluginConfig) -> bool {
function unload (line 75) | pub fn unload() -> anyhow::Result<()> {
function mod_to_xkb_key (line 93) | pub const fn mod_to_xkb_key(r#mod: Modifier) -> &'static str {
FILE: crates/exec-lib/src/run.rs
function run_program (line 10) | pub fn run_program(
function get_command (line 52) | fn get_command(command: &str) -> Command {
function run_command (line 78) | fn run_command(run: &str, path: Option<&Path>) -> anyhow::Result<()> {
FILE: crates/exec-lib/src/switch.rs
function switch_client (line 11) | pub fn switch_client(address: Address) -> anyhow::Result<()> {
function switch_client_by_initial_class (line 21) | pub fn switch_client_by_initial_class(class: &str) -> anyhow::Result<()> {
function switch_workspace (line 34) | pub fn switch_workspace(workspace_id: WorkspaceId) -> anyhow::Result<()> {
function switch_special_workspace (line 58) | fn switch_special_workspace(workspace_id: WorkspaceId) -> anyhow::Result...
function switch_normal_workspace (line 76) | fn switch_normal_workspace(workspace_id: WorkspaceId) -> anyhow::Result<...
function deactivate_special_workspace_if_needed (line 87) | fn deactivate_special_workspace_if_needed() -> anyhow::Result<()> {
FILE: crates/exec-lib/src/util.rs
function get_clients (line 13) | pub fn get_clients() -> Vec<Client> {
function get_monitors (line 17) | pub fn get_monitors() -> Vec<Monitor> {
function get_current_monitor (line 22) | pub fn get_current_monitor() -> Option<Monitor> {
function reload_hyprland_config (line 26) | pub fn reload_hyprland_config() -> anyhow::Result<()> {
function to_client_id (line 36) | pub fn to_client_id(id: &hyprland::shared::Address) -> ClientId {
function to_client_address (line 43) | pub fn to_client_address(id: ClientId) -> hyprland::shared::Address {
function get_prev_follow_mouse (line 47) | fn get_prev_follow_mouse() -> &'static Mutex<Option<String>> {
function set_no_follow_mouse (line 52) | pub fn set_no_follow_mouse() -> anyhow::Result<()> {
function reset_no_follow_mouse (line 58) | pub fn reset_no_follow_mouse() -> anyhow::Result<()> {
function set_follow_mouse_default (line 72) | pub fn set_follow_mouse_default() -> anyhow::Result<()> {
function get_initial_active (line 87) | pub fn get_initial_active() -> anyhow::Result<Active> {
function internal_get_initial_active (line 104) | fn internal_get_initial_active() -> anyhow::Result<Active> {
function check_version (line 123) | pub fn check_version() -> anyhow::Result<Version> {
function get_version (line 151) | fn get_version() -> anyhow::Result<hyprland::data::Version> {
FILE: crates/hyprland-plugin/build.rs
function include_plugin (line 8) | fn include_plugin(srcs_dir: &Path, out_dir: &Path) {
function combine (line 34) | fn combine(srcs_dir: &Path, out_dir: &Path) -> PathBuf {
function main (line 78) | fn main() {
FILE: crates/hyprland-plugin/plugin/src-52/defs.h
type PluginDescriptionInfo (line 8) | struct PluginDescriptionInfo {
FILE: crates/hyprland-plugin/plugin/src-52/exit.cpp
function exit (line 3) | void exit() {
FILE: crates/hyprland-plugin/plugin/src-52/init.cpp
function PluginDescriptionInfo (line 5) | PluginDescriptionInfo init(HANDLE handle) {
FILE: crates/hyprland-plugin/plugin/src-52/key-press.cpp
function onKeyPress (line 13) | void onKeyPress(const std::unordered_map<std::string, std::any> &data, S...
FILE: crates/hyprland-plugin/plugin/src-52/keyboard-focus.cpp
function onKeyboardFocus (line 4) | void onKeyboardFocus(const SP<CWLSurfaceResource> &surface) {
FILE: crates/hyprland-plugin/plugin/src-52/layer-change.cpp
function onOpenLayerChange (line 6) | void onOpenLayerChange(const PHLLS &window, const bool open) {
FILE: crates/hyprland-plugin/plugin/src-52/main.cpp
function APICALL (line 5) | APICALL EXPORT std::string PLUGIN_API_VERSION() {
function APICALL (line 9) | APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
function APICALL (line 14) | APICALL EXPORT void PLUGIN_EXIT() {
FILE: crates/hyprland-plugin/plugin/src-52/mouse-button.cpp
function onMouseButton (line 5) | void onMouseButton(const IPointer::SButtonEvent event) {
FILE: crates/hyprland-plugin/plugin/src-52/send.cpp
function sendStringToHyprshellSocket (line 9) | void sendStringToHyprshellSocket(const std::string &message) {
FILE: crates/hyprland-plugin/plugin/src-54/defs.h
type PluginDescriptionInfo (line 8) | struct PluginDescriptionInfo {
FILE: crates/hyprland-plugin/plugin/src-54/exit.cpp
function exit (line 3) | void exit() {
FILE: crates/hyprland-plugin/plugin/src-54/init.cpp
function PluginDescriptionInfo (line 8) | PluginDescriptionInfo init(HANDLE handle) {
FILE: crates/hyprland-plugin/plugin/src-54/key-press.cpp
function onKeyPress (line 17) | void onKeyPress(const IKeyboard::SKeyEvent &event, Event::SCallbackInfo ...
FILE: crates/hyprland-plugin/plugin/src-54/keyboard-focus.cpp
function onKeyboardFocus (line 4) | void onKeyboardFocus(const SP<CWLSurfaceResource> &surface) {
FILE: crates/hyprland-plugin/plugin/src-54/layer-change.cpp
function onOpenLayerChange (line 6) | void onOpenLayerChange(const PHLLS &window, const bool open) {
FILE: crates/hyprland-plugin/plugin/src-54/main.cpp
function APICALL (line 5) | APICALL EXPORT std::string PLUGIN_API_VERSION() {
function APICALL (line 9) | APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
function APICALL (line 14) | APICALL EXPORT void PLUGIN_EXIT() {
FILE: crates/hyprland-plugin/plugin/src-54/mouse-button.cpp
function onMouseButton (line 6) | void onMouseButton(IPointer::SButtonEvent event, Event::SCallbackInfo &i...
FILE: crates/hyprland-plugin/plugin/src-54/send.cpp
function sendStringToHyprshellSocket (line 9) | void sendStringToHyprshellSocket(const std::string &message) {
FILE: crates/hyprland-plugin/src/build.rs
function build (line 8) | pub fn build(dir: &TempDir) -> anyhow::Result<()> {
FILE: crates/hyprland-plugin/src/configure.rs
type PluginConfig (line 12) | pub struct PluginConfig {
method fmt (line 19) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function configure (line 31) | pub fn configure(
FILE: crates/hyprland-plugin/src/extract.rs
function extract_plugin (line 9) | pub fn extract_plugin(version: &semver::Version) -> anyhow::Result<TempD...
FILE: crates/hyprland-plugin/src/lib.rs
constant PLUGIN_NAME (line 9) | pub const PLUGIN_NAME: &str = env!("CARGO_PKG_NAME");
constant PLUGIN_AUTHOR (line 10) | pub const PLUGIN_AUTHOR: &str = env!("CARGO_PKG_AUTHORS");
constant PLUGIN_DESC (line 11) | pub const PLUGIN_DESC: &str = env!("CARGO_PKG_DESCRIPTION");
constant PLUGIN_VERSION (line 12) | pub const PLUGIN_VERSION: &str = env!("CARGO_PKG_VERSION");
constant PLUGIN_OUTPUT_PATH (line 13) | pub const PLUGIN_OUTPUT_PATH: &str = "/tmp/hyprshell.so";
function generate (line 20) | pub fn generate(config: &PluginConfig, version: &semver::Version) -> any...
FILE: crates/hyprland-plugin/src/test.rs
function build_plugin (line 8) | fn build_plugin() {
FILE: crates/launcher-lib/src/close.rs
constant ANIMATE_LAUNCH_MS (line 12) | const ANIMATE_LAUNCH_MS: u64 = 500;
function close_launcher_by_char (line 14) | pub fn close_launcher_by_char(data: &mut LauncherData, char: Option<char...
function close_launcher_by_iden (line 35) | pub fn close_launcher_by_iden(data: &mut LauncherData, iden: &Identifier) {
function close_launcher (line 43) | fn close_launcher(data: &LauncherData, iden: &Identifier) {
function close_window (line 74) | fn close_window(entry: &Entry, window: &ApplicationWindow) {
function show_launch (line 80) | fn show_launch(
FILE: crates/launcher-lib/src/create.rs
function create_windows_overview_launcher_window (line 22) | pub fn create_windows_overview_launcher_window(
function launcher_entry_text_change (line 127) | fn launcher_entry_text_change(text: String, event_sender: &Sender<Transf...
function handle_key (line 134) | fn handle_key(
FILE: crates/launcher-lib/src/css.rs
function get_css (line 7) | pub fn get_css() -> anyhow::Result<()> {
FILE: crates/launcher-lib/src/debug.rs
function get_matches (line 11) | pub fn get_matches(plugins: &Plugins, text: &str, all_items: bool, max_i...
FILE: crates/launcher-lib/src/global.rs
type LauncherData (line 8) | pub struct LauncherData {
type LauncherConfig (line 21) | pub struct LauncherConfig {
FILE: crates/launcher-lib/src/open.rs
function open_launcher (line 7) | pub fn open_launcher(data: &LauncherData) {
FILE: crates/launcher-lib/src/plugins/actions.rs
function get_actions_options (line 7) | pub fn get_actions_options(
function run_action (line 74) | pub fn run_action(data: Option<&str>) -> PluginReturn {
FILE: crates/launcher-lib/src/plugins/applications/data.rs
function save_run (line 9) | pub fn save_run(desktop_file: &Path, data_dir: &Path) -> anyhow::Result<...
function get_current_week (line 43) | fn get_current_week(data_dir: &Path) -> PathBuf {
function get_all_weeks (line 49) | fn get_all_weeks(run_cache_weeks: u8, data_dir: &Path) -> Vec<Box<Path>> {
function get_name_from_timestamp (line 60) | fn get_name_from_timestamp(week: u8) -> Box<Path> {
function get_stored_runs (line 70) | pub fn get_stored_runs(run_cache_weeks: u8, data_dir: &Path) -> HashMap<...
FILE: crates/launcher-lib/src/plugins/applications/map.rs
type DesktopEntry (line 9) | pub struct DesktopEntry {
type DesktopAction (line 24) | pub struct DesktopAction {
function get_desktop_file_map (line 30) | fn get_desktop_file_map() -> &'static RwLock<Vec<DesktopEntry>> {
function get_all_desktop_entries (line 35) | pub fn get_all_desktop_entries<'a>() -> RwLockReadGuard<'a, Vec<DesktopE...
function reload_desktop_entries_map (line 41) | pub fn reload_desktop_entries_map() -> anyhow::Result<()> {
FILE: crates/launcher-lib/src/plugins/applications/plugin.rs
type MatchType (line 14) | enum MatchType {
method from_desktop_entry (line 24) | fn from_desktop_entry(
function get_sortable_options (line 79) | pub fn get_sortable_options(
function launch_option (line 185) | pub fn launch_option(
FILE: crates/launcher-lib/src/plugins/calc.rs
function get_context (line 9) | fn get_context() -> Option<&'static RwLock<rink_core::Context>> {
function init_context (line 20) | pub fn init_context() {
function get_calc_options (line 24) | pub fn get_calc_options(matches: &mut Vec<SortableLaunchOption>, text: &...
function copy_result (line 58) | pub fn copy_result(data: Option<&str>) -> bool {
function parse_result (line 72) | fn parse_result(result: String) -> (Box<str>, Option<Box<str>>) {
function test_parse_result_approx_with_dimensions (line 107) | fn test_parse_result_approx_with_dimensions() {
function test_parse_result_approx_with_dimensions_and_fraction (line 115) | fn test_parse_result_approx_with_dimensions_and_fraction() {
function test_parse_result_approx (line 123) | fn test_parse_result_approx() {
function test_parse_result_fraction (line 131) | fn test_parse_result_fraction() {
function test_parse_result_with_parentheses (line 139) | fn test_parse_result_with_parentheses() {
function test_parse_result_simple (line 147) | fn test_parse_result_simple() {
FILE: crates/launcher-lib/src/plugins/mod.rs
function init_calc_context (line 22) | pub const fn init_calc_context() {}
type SortableLaunchOption (line 25) | pub struct SortableLaunchOption {
type DetailsMenuItem (line 38) | pub struct DetailsMenuItem {
type StaticLaunchOption (line 45) | pub struct StaticLaunchOption {
function get_sortable_launch_options (line 53) | pub fn get_sortable_launch_options(
function get_static_launch_options (line 94) | pub fn get_static_launch_options(
type PluginReturn (line 119) | pub struct PluginReturn {
function launch (line 123) | pub fn launch(
function get_static_options_chars (line 165) | pub fn get_static_options_chars(plugins: &Plugins) -> Vec<Key> {
FILE: crates/launcher-lib/src/plugins/path.rs
function get_path_options (line 9) | pub fn get_path_options(matches: &mut Vec<SortableLaunchOption>, text: &...
function launch_option (line 33) | pub fn launch_option(text: &str) -> PluginReturn {
type FilemanagerData (line 62) | pub struct FilemanagerData {
function get_file_manager_info (line 68) | pub(super) fn get_file_manager_info() -> FilemanagerData {
FILE: crates/launcher-lib/src/plugins/search.rs
function get_static_options (line 11) | pub fn get_static_options(matches: &mut Vec<StaticLaunchOption>, config:...
function launch_option (line 33) | pub fn launch_option(iden: Option<&str>, text: &str) -> PluginReturn {
function get_chars (line 72) | pub fn get_chars(config: &[SearchEngine]) -> Vec<Key> {
type BrowserData (line 79) | pub struct BrowserData {
function get_browser_info (line 85) | pub(super) fn get_browser_info() -> BrowserData {
function convert_to_key (line 117) | pub const fn convert_to_key(char: char) -> Option<Key> {
FILE: crates/launcher-lib/src/plugins/shell.rs
function get_static_options (line 8) | pub fn get_static_options(matches: &mut Vec<StaticLaunchOption>) {
function launch_option (line 19) | pub fn launch_option(text: &str, default_terminal: Option<&str>) -> Plug...
function get_chars (line 32) | pub fn get_chars() -> Vec<Key> {
FILE: crates/launcher-lib/src/plugins/terminal.rs
function get_static_options (line 8) | pub fn get_static_options(matches: &mut Vec<StaticLaunchOption>, default...
function launch_option (line 26) | pub fn launch_option(text: &str, default_terminal: Option<&str>) -> Plug...
function get_chars (line 47) | pub fn get_chars() -> Vec<Key> {
FILE: crates/launcher-lib/src/stop.rs
function stop_launcher (line 5) | pub fn stop_launcher(data: &LauncherData) {
FILE: crates/launcher-lib/src/update.rs
function update_launcher (line 22) | pub fn update_launcher(data: &mut LauncherData, text: &str, event_sender...
function create_static_plugin_box (line 76) | fn create_static_plugin_box(
function create_entry (line 136) | fn create_entry(
function click_plugin (line 260) | fn click_plugin(button: &Button, iden: Identifier, event_sender: Sender<...
function click_entry (line 271) | fn click_entry(button: >k::Box, iden: Identifier, event_sender: Sender...
function click_details_entry (line 284) | fn click_details_entry(button: &Button, iden: Identifier, event_sender: ...
FILE: crates/windows-lib/src/css.rs
function get_css (line 7) | pub fn get_css() -> anyhow::Result<()> {
FILE: crates/windows-lib/src/data.rs
type SortConfig (line 11) | pub struct SortConfig {
function collect_data (line 18) | pub fn collect_data(config: &SortConfig) -> anyhow::Result<(HyprlandData...
function update_client_position (line 78) | pub fn update_client_position(
FILE: crates/windows-lib/src/desktop_map.rs
type Source (line 9) | pub enum Source {
type IconPathMap (line 15) | type IconPathMap = HashMap<(Box<str>, Source), (Box<Path>, Box<Path>)>;
function get_icon_path_map (line 17) | fn get_icon_path_map() -> &'static RwLock<IconPathMap> {
function reload_class_to_icon_map (line 22) | pub fn reload_class_to_icon_map() -> anyhow::Result<()> {
function extract_exec_name (line 73) | fn extract_exec_name(line: Box<str>) -> Option<String> {
function add_path_for_icon_by_pid_exec (line 93) | pub fn add_path_for_icon_by_pid_exec(class: &str, path: Box<Path>) -> an...
function get_icon_name_by_name_from_desktop_files (line 106) | pub fn get_icon_name_by_name_from_desktop_files(
FILE: crates/windows-lib/src/global.rs
type WindowsOverviewData (line 7) | pub struct WindowsOverviewData {
type WindowsOverviewConfig (line 17) | pub struct WindowsOverviewConfig {
type WindowsSwitchData (line 26) | pub struct WindowsSwitchData {
type WindowsSwitchConfig (line 38) | pub struct WindowsSwitchConfig {
type WindowsOverviewMonitorData (line 48) | pub struct WindowsOverviewMonitorData {
method new (line 56) | pub fn new(id: MonitorId, workspaces_flow: FlowBox) -> Self {
FILE: crates/windows-lib/src/icon.rs
function set_icon (line 8) | pub fn set_icon(class: &str, pid: i32, image: &Image) {
function load_icon_from_cache (line 46) | fn load_icon_from_cache(name: &str, pic: &Image) -> Option<Box<Path>> {
FILE: crates/windows-lib/src/keybinds.rs
function generate_open_keybinds (line 6) | pub fn generate_open_keybinds(windows: &Windows) -> Vec<ExecBind> {
FILE: crates/windows-lib/src/next.rs
function find_next_workspace (line 8) | pub fn find_next_workspace(
function find_next_client (line 67) | pub fn find_next_client(
function find_next_grid (line 123) | fn find_next_grid(
function find_first_client (line 187) | fn find_first_client(
function create_test_data (line 236) | fn create_test_data(
function test_find_next_workspace_0 (line 291) | fn test_find_next_workspace_0() {
function test_find_next_workspace_1_filter (line 325) | fn test_find_next_workspace_1_filter() {
function test_find_next_workspace_1 (line 375) | fn test_find_next_workspace_1() {
function test_find_next_workspace_2 (line 424) | fn test_find_next_workspace_2() {
function test_find_next_workspace_2_filter (line 461) | fn test_find_next_workspace_2_filter() {
function test_find_next_client (line 498) | fn test_find_next_client() {
FILE: crates/windows-lib/src/overview/close.rs
function overview_already_hidden (line 11) | pub fn overview_already_hidden(data: &WindowsOverviewData) -> bool {
function close_overview (line 15) | pub fn close_overview(data: &mut WindowsOverviewData, ids: Option<Option...
FILE: crates/windows-lib/src/overview/create.rs
function create_windows_overview_window (line 15) | pub fn create_windows_overview_window(
FILE: crates/windows-lib/src/overview/open.rs
function scale (line 16) | fn scale<T: Into<f64>>(value: T, scale: f64) -> i32 {
function overview_already_open (line 21) | pub fn overview_already_open(data: &WindowsOverviewData) -> bool {
function open_overview (line 26) | pub fn open_overview(
function click_client (line 166) | fn click_client(button: &Button, client_id: ClientId, event_sender: Send...
FILE: crates/windows-lib/src/overview/stop.rs
function stop_overview (line 7) | pub fn stop_overview(data: &WindowsOverviewData) {
FILE: crates/windows-lib/src/overview/update.rs
function update_overview (line 7) | pub fn update_overview(data: &mut WindowsOverviewData, config: &SwitchOv...
FILE: crates/windows-lib/src/sort.rs
function sort_clients_by_position (line 6) | pub fn sort_clients_by_position(
function sort_clients_by_recent (line 107) | pub fn sort_clients_by_recent(clients: &mut [(ClientId, ClientData)]) {
function sort_workspaces_by_recent (line 122) | pub fn sort_workspaces_by_recent(
function sort_monitor_by_x (line 146) | pub fn sort_monitor_by_x(monitors: &mut [(MonitorId, MonitorData)]) {
function sort_workspaces_by_position (line 150) | pub fn sort_workspaces_by_position(
FILE: crates/windows-lib/src/switch/close.rs
function switch_already_hidden (line 10) | pub fn switch_already_hidden(data: &WindowsSwitchData) -> bool {
function close_switch (line 14) | pub fn close_switch(data: &mut WindowsSwitchData, switch: bool) {
FILE: crates/windows-lib/src/switch/create.rs
function create_windows_switch_window (line 19) | pub fn create_windows_switch_window(
function handle_release (line 85) | fn handle_release(key: Key, modifier: Modifier, event_sender: &Sender<Tr...
function handle_key (line 96) | fn handle_key(key: Key, s_key: Key, event_sender: &Sender<TransferType>)...
FILE: crates/windows-lib/src/switch/open.rs
function scale (line 15) | fn scale<T: Into<f64>>(value: T, scale: f64) -> i32 {
function switch_already_open (line 20) | pub fn switch_already_open(data: &WindowsSwitchData) -> bool {
function open_switch (line 25) | pub fn open_switch(data: &mut WindowsSwitchData, config: &OpenSwitch) ->...
FILE: crates/windows-lib/src/switch/stop.rs
function stop_switch (line 7) | pub fn stop_switch(data: &WindowsSwitchData) {
FILE: crates/windows-lib/src/switch/update.rs
function update_switch (line 7) | pub fn update_switch(data: &mut WindowsSwitchData, config: &SwitchSwitch...
FILE: dep-crates/hyprland-rs/examples/bind.rs
function main (line 13) | fn main() -> hyprland::Result<()> {
FILE: dep-crates/hyprland-rs/examples/bind_async.rs
function main (line 14) | async fn main() -> hyprland::Result<()> {
FILE: dep-crates/hyprland-rs/examples/data.rs
function main (line 13) | fn main() -> hyprland::Result<()> {
FILE: dep-crates/hyprland-rs/examples/data_async.rs
function main (line 14) | async fn main() -> hyprland::Result<()> {
FILE: dep-crates/hyprland-rs/examples/dispatch.rs
function describe (line 11) | fn describe(desc: &str) {
function main (line 16) | fn main() -> hyprland::Result<()> {
FILE: dep-crates/hyprland-rs/examples/dispatch_async.rs
function describe (line 10) | fn describe(desc: &str) {
function main (line 16) | async fn main() -> hyprland::Result<()> {
FILE: dep-crates/hyprland-rs/examples/events.rs
function main (line 7) | fn main() -> hyprland::Result<()> {
FILE: dep-crates/hyprland-rs/examples/events_async.rs
function main (line 10) | async fn main() -> hyprland::Result<()> {
FILE: dep-crates/hyprland-rs/examples/keyword.rs
function main (line 10) | fn main() -> hyprland::Result<()> {
FILE: dep-crates/hyprland-rs/examples/keyword_async.rs
function main (line 11) | async fn main() -> hyprland::Result<()> {
FILE: dep-crates/hyprland-rs/hyprland-macros/src/lib.rs
function async_closure (line 14) | pub fn async_closure(input: TokenStream) -> TokenStream {
type If (line 26) | struct If<T: Parse> {
method parse (line 34) | fn parse(input: ParseStream) -> Result<Self> {
function block_if (line 55) | pub fn block_if(input: TokenStream) -> TokenStream {
function type_if (line 81) | pub fn type_if(input: TokenStream) -> TokenStream {
function expr_if (line 102) | pub fn expr_if(input: TokenStream) -> TokenStream {
FILE: dep-crates/hyprland-rs/src/config.rs
type Join (line 13) | trait Join: IntoIterator {
method join (line 14) | fn join(&self) -> String;
method join (line 61) | fn join(&self) -> String {
method join (line 107) | fn join(&self) -> String {
type Key (line 19) | pub enum Key<'a> {
function fmt (line 32) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type Mod (line 47) | pub enum Mod {
type Flag (line 73) | pub enum Flag {
type Binding (line 118) | pub struct Binding<'a> {
type Binder (line 130) | pub struct Binder;
method gen_str (line 133) | pub(crate) fn gen_str(binding: Binding) -> crate::Result<String> {
method bind (line 143) | pub fn bind(binding: Binding) -> crate::Result<()> {
method instance_bind (line 148) | pub fn instance_bind(instance: &Instance, binding: Binding) -> crate::...
method bind_async (line 159) | pub async fn bind_async(binding: Binding<'_>) -> crate::Result<()> {
method instance_bind_async (line 165) | pub async fn instance_bind_async(
function test_binds (line 400) | fn test_binds() {
FILE: dep-crates/hyprland-rs/src/ctl.rs
function call (line 13) | pub fn call() -> crate::Result<()> {
function instance_call (line 18) | pub fn instance_call(instance: &Instance) -> crate::Result<()> {
function call_async (line 25) | pub async fn call_async() -> crate::Result<()> {
function instance_call_async (line 31) | pub async fn instance_call_async(instance: &Instance) -> crate::Result<(...
function call (line 43) | pub fn call() -> crate::Result<()> {
function instance_call (line 48) | pub fn instance_call(instance: &Instance) -> crate::Result<()> {
function call_async (line 55) | pub async fn call_async() -> crate::Result<()> {
function instance_call_async (line 61) | pub async fn instance_call_async(instance: &Instance) -> crate::Result<(...
function call (line 74) | pub fn call<Str: FDisplay>(theme: Str, size: u16) -> crate::Result<()> {
function instance_call (line 79) | pub fn instance_call<Str: FDisplay>(
function call_async (line 90) | pub async fn call_async<Str: FDisplay>(theme: Str, size: u16) -> crate::...
function instance_call_async (line 96) | pub async fn instance_call_async<Str: FDisplay>(
type OutputBackends (line 114) | pub enum OutputBackends {
function create (line 130) | pub fn create(backend: OutputBackends, name: Option<&str>) -> crate::Res...
function remove (line 135) | pub fn remove<Str: FDisplay>(name: Str) -> crate::Result<()> {
function instance_create (line 140) | pub fn instance_create(
function instance_remove (line 151) | pub fn instance_remove<Str: FDisplay>(instance: &Instance, name: Str) ->...
function create_async (line 158) | pub async fn create_async(backend: OutputBackends, name: Option<&str>) -...
function instance_create_async (line 164) | pub async fn instance_create_async(
function remove_async (line 178) | pub async fn remove_async<Str: FDisplay>(name: Str) -> crate::Result<()> {
function instance_remove_async (line 184) | pub async fn instance_remove_async<Str: FDisplay>(
type SwitchXKBLayoutCmdTypes (line 201) | pub enum SwitchXKBLayoutCmdTypes {
function call (line 214) | pub fn call<Str: FDisplay>(device: Str, cmd: SwitchXKBLayoutCmdTypes) ->...
function instance_call (line 219) | pub fn instance_call<Str: FDisplay>(
function call_async (line 230) | pub async fn call_async<Str: FDisplay>(
function instance_call_async (line 240) | pub async fn instance_call_async<Str: FDisplay>(
function call (line 257) | pub fn call(color: Color, msg: String) -> crate::Result<()> {
function instance_call (line 262) | pub fn instance_call(instance: &Instance, color: Color, msg: String) -> ...
function call_async (line 269) | pub async fn call_async(color: Color, msg: String) -> crate::Result<()> {
function instance_call_async (line 275) | pub async fn instance_call_async(
type Icon (line 294) | pub enum Icon {
function call (line 305) | pub fn call(
function instance_call (line 315) | pub fn instance_call(
function call_async (line 333) | pub async fn call_async(
function instance_call_async (line 344) | pub async fn instance_call_async(
function call (line 369) | pub fn call(amount: Option<std::num::NonZeroU8>) -> crate::Result<()> {
function instance_call (line 376) | pub fn instance_call(
function call_async (line 396) | pub async fn call_async(amount: Option<std::num::NonZeroU8>) -> crate::R...
function instance_call_async (line 404) | pub async fn instance_call_async(
type Color (line 426) | pub struct Color(u8, u8, u8, u8);
function l (line 432) | fn l(b: bool) -> &'static str {
type PropType (line 442) | pub enum PropType {
function call (line 568) | pub fn call(ident: String, prop: PropType, lock: bool) -> crate::Result<...
function instance_call (line 573) | pub fn instance_call(
function call_async (line 589) | pub async fn call_async(ident: String, prop: PropType, lock: bool) -> cr...
function instance_call_async (line 595) | pub async fn instance_call_async(
type Plugin (line 620) | pub struct Plugin {
function list (line 634) | pub fn list() -> crate::Result<Vec<Plugin>> {
function instance_list (line 639) | pub fn instance_list(instance: &Instance) -> crate::Result<Vec<Plugin>> {
function list_async (line 647) | pub async fn list_async() -> crate::Result<Vec<Plugin>> {
function instance_list_async (line 653) | pub async fn instance_list_async(instance: &Instance) -> crate::Result<V...
function load (line 662) | pub fn load(path: &Path) -> crate::Result<()> {
function instance_load (line 667) | pub fn instance_load(instance: &Instance, path: &Path) -> crate::Result<...
function load_async (line 678) | pub async fn load_async(path: &Path) -> crate::Result<()> {
function instance_load_async (line 684) | pub async fn instance_load_async(instance: &Instance, path: &Path) -> cr...
function unload (line 696) | pub fn unload(path: &Path) -> crate::Result<()> {
function instance_unload (line 701) | pub fn instance_unload(instance: &Instance, path: &Path) -> crate::Resul...
function unload_async (line 712) | pub async fn unload_async(path: &Path) -> crate::Result<()> {
function instance_unload_async (line 718) | pub async fn instance_unload_async(instance: &Instance, path: &Path) -> ...
type Instance (line 739) | pub struct Instance {
function instance_list (line 751) | pub fn instance_list() -> crate::Result<Vec<Instance>> {
function parse_instance_entry (line 764) | fn parse_instance_entry(entry: DirEntry) -> Option<Instance> {
FILE: dep-crates/hyprland-rs/src/data/helpers.rs
type FullscreenState (line 6) | pub struct FullscreenState(
method bool (line 34) | pub fn bool(self) -> bool {
method get (line 12) | fn get() -> crate::Result<Self> {
method get_async (line 16) | async fn get_async() -> crate::Result<Self> {
method instance_get (line 19) | fn instance_get(instance: &crate::instance::Instance) -> crate::Result<S...
method instance_get_async (line 23) | async fn instance_get_async(instance: &crate::instance::Instance) -> cra...
FILE: dep-crates/hyprland-rs/src/data/regular.rs
type DataCommands (line 11) | pub(crate) enum DataCommands {
type WorkspaceBasic (line 40) | pub struct WorkspaceBasic {
type Transforms (line 50) | pub enum Transforms {
type Monitor (line 71) | pub struct Monitor {
method get_active (line 113) | fn get_active() -> crate::Result<Self> {
method get_active_async (line 117) | async fn get_active_async() -> crate::Result<Self> {
method instance_get_active (line 120) | fn instance_get_active(instance: &Instance) -> crate::Result<Self> {
method instance_get_active_async (line 129) | async fn instance_get_active_async(instance: &Instance) -> crate::Result...
type Workspace (line 149) | pub struct Workspace {
method get_active (line 173) | fn get_active() -> crate::Result<Self> {
method get_active_async (line 177) | async fn get_active_async() -> crate::Result<Self> {
method instance_get_active (line 180) | fn instance_get_active(instance: &Instance) -> crate::Result<Self> {
method instance_get_active_async (line 186) | async fn instance_get_active_async(instance: &Instance) -> crate::Result...
type FullscreenMode (line 206) | pub enum FullscreenMode {
type Client (line 219) | pub struct Client {
type Empty (line 266) | struct Empty {}
method get_active (line 269) | fn get_active() -> crate::Result<Option<Self>> {
method get_active_async (line 273) | async fn get_active_async() -> crate::Result<Option<Self>> {
method instance_get_active (line 276) | fn instance_get_active(instance: &Instance) -> crate::Result<Option<Self...
method instance_get_active_async (line 287) | async fn instance_get_active_async(instance: &Instance) -> crate::Result...
type LayerClient (line 311) | pub struct LayerClient {
type LayerDisplay (line 328) | pub struct LayerDisplay {
type Mouse (line 352) | pub struct Mouse {
type Keyboard (line 361) | pub struct Keyboard {
type TabletType (line 384) | pub enum TabletType {
type TabletBelongsTo (line 396) | pub enum TabletBelongsTo {
type Tablet (line 410) | pub struct Tablet {
type Devices (line 425) | pub struct Devices {
type Version (line 437) | pub struct Version {
type CursorPosition (line 492) | pub struct CursorPosition {
type Bind (line 502) | pub struct Bind {
type AnimationStyle (line 535) | pub enum AnimationStyle {
method from (line 559) | fn from(value: String) -> Self {
type BezierIdent (line 586) | pub enum BezierIdent {
method from (line 599) | fn from(value: String) -> Self {
type RawBezierIdent (line 609) | struct RawBezierIdent {
type Bezier (line 615) | pub struct Bezier {
type AnimationRaw (line 630) | struct AnimationRaw {
type Animation (line 647) | pub struct Animation {
type AnimationsRaw (line 663) | struct AnimationsRaw(Vec<AnimationRaw>, Vec<RawBezierIdent>);
type Animations (line 667) | pub struct Animations(pub Vec<Animation>, pub Vec<BezierIdent>);
method get (line 670) | fn get() -> crate::Result<Self> {
method get_async (line 675) | async fn get_async() -> crate::Result<Self> {
method instance_get (line 679) | fn instance_get(instance: &Instance) -> crate::Result<Self> {
method instance_get_async (line 698) | async fn instance_get_async(instance: &Instance) -> crate::Result<Self> {
type WorkspaceRuleset (line 724) | pub struct WorkspaceRuleset {
FILE: dep-crates/hyprland-rs/src/dispatch.rs
type WindowIdentifier (line 26) | pub enum WindowIdentifier<'a> {
type FullscreenType (line 43) | pub enum FullscreenType {
type Direction (line 58) | pub enum Direction {
type Position (line 71) | pub enum Position {
method fmt (line 79) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type CycleDirection (line 91) | pub enum CycleDirection {
type WindowSwitchDirection (line 101) | pub enum WindowSwitchDirection {
type MonitorIdentifier (line 110) | pub enum MonitorIdentifier<'a> {
function fmt (line 124) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type Corner (line 139) | pub enum Corner {
type WorkspaceOptions (line 148) | pub enum WorkspaceOptions {
type FirstEmpty (line 159) | pub struct FirstEmpty {
method fmt (line 167) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type WorkspaceIdentifierWithSpecial (line 181) | pub enum WorkspaceIdentifierWithSpecial<'a> {
function format_special_workspace_ident (line 215) | pub(super) fn format_special_workspace_ident<'a>(opt: &'a Option<&'a str...
function format_relative (line 223) | pub(super) fn format_relative(int: i32, extra: &'_ str) -> String {
type WorkspaceIdentifier (line 236) | pub enum WorkspaceIdentifier<'a> {
function fmt (line 256) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type WindowMove (line 275) | pub enum WindowMove<'a> {
type DispatchType (line 284) | pub enum DispatchType<'a> {
type LockType (line 446) | pub enum LockType {
type SwapWithMasterParam (line 460) | pub enum SwapWithMasterParam {
type FocusMasterParam (line 474) | pub enum FocusMasterParam {
function gen_dispatch_str (line 483) | pub(crate) fn gen_dispatch_str(cmd: DispatchType, dispatch: bool) -> cra...
type Dispatch (line 580) | pub struct Dispatch;
method call (line 593) | pub fn call(dispatch_type: DispatchType) -> crate::Result<()> {
method instance_call (line 608) | pub fn instance_call(
method call_async (line 633) | pub async fn call_async(dispatch_type: DispatchType<'_>) -> crate::Res...
method instance_call_async (line 649) | pub async fn instance_call_async(
FILE: dep-crates/hyprland-rs/src/error.rs
type HyprError (line 3) | pub enum HyprError {
method try_as_cloned (line 27) | pub fn try_as_cloned(&self) -> Result<Self, &Self> {
method other (line 41) | pub fn other<S: Into<String>>(other: S) -> Self {
method from (line 47) | fn from(error: io::Error) -> Self {
method from (line 53) | fn from(error: serde_json::Error) -> Self {
method from (line 59) | fn from(error: std::string::FromUtf8Error) -> Self {
FILE: dep-crates/hyprland-rs/src/event_listener/async_im.rs
type AsyncEventListener (line 22) | pub struct AsyncEventListener {
method new (line 39) | pub fn new() -> Self {
method start_listener_async (line 58) | pub async fn start_listener_async(&mut self) -> crate::Result<()> {
method instance_start_listener_async (line 77) | pub async fn instance_start_listener_async(
method default (line 27) | fn default() -> Self {
FILE: dep-crates/hyprland-rs/src/event_listener/immutable.rs
type EventListener (line 22) | pub struct EventListener {
method new (line 39) | pub fn new() -> EventListener {
method start_listener_async (line 59) | pub async fn start_listener_async(&mut self) -> crate::Result<()> {
method instance_start_listener_async (line 79) | pub async fn instance_start_listener_async(
method start_listener (line 117) | pub fn start_listener(&mut self) -> crate::Result<()> {
method instance_start_listener (line 135) | pub fn instance_start_listener(&mut self, instance: &Instance) -> crat...
method default (line 27) | fn default() -> Self {
FILE: dep-crates/hyprland-rs/src/event_listener/shared.rs
type ActiveWindowValue (line 5) | pub(crate) enum ActiveWindowValue<T> {
function reset (line 12) | pub fn reset(&mut self) {
function is_empty (line 15) | pub fn is_empty(&self) -> bool {
type ActiveWindowState (line 21) | pub(crate) struct ActiveWindowState {
method execute (line 145) | pub fn execute<T: HasExecutor>(&mut self, listener: &mut T) -> crate::...
method get_event (line 160) | pub fn get_event(&mut self) -> Option<Event> {
method ready (line 177) | pub fn ready(&self) -> bool {
method reset (line 180) | pub fn reset(&mut self) {
method new (line 185) | pub fn new() -> Self {
type HasExecutor (line 27) | pub(crate) trait HasExecutor {
method event_executor (line 28) | fn event_executor(&mut self, event: Event) -> crate::Result<()>;
method event_primer (line 30) | fn event_primer(&mut self, event: Event, abuf: &mut Vec<ActiveWindowSt...
function event_primer_noexec (line 76) | pub(crate) fn event_primer_noexec(
type HasAsyncExecutor (line 126) | pub(crate) trait HasAsyncExecutor {
method event_executor_async (line 127) | async fn event_executor_async(&mut self, event: Event) -> crate::Resul...
method event_primer_exec_async (line 129) | async fn event_primer_exec_async(
function from (line 195) | fn from(value: Option<T>) -> Self {
function into (line 203) | pub(crate) fn into<T>(from: Option<(T, T)>) -> (ActiveWindowValue<T>, Ac...
type EventType (line 214) | pub(crate) type EventType<T> = Box<T>;
type AsyncEventType (line 215) | pub(crate) type AsyncEventType<T> = Pin<Box<T>>;
type VoidFuture (line 217) | pub(crate) type VoidFuture = Pin<Box<dyn std::future::Future<Output = ()...
type EmptyClosure (line 219) | pub(crate) type EmptyClosure = EventType<dyn Fn()>;
type Closure (line 220) | pub(crate) type Closure<T> = EventType<dyn Fn(T)>;
type AsyncClosure (line 221) | pub(crate) type AsyncClosure<T> = AsyncEventType<dyn Sync + Send + Fn(T)...
type EmptyAsyncClosure (line 222) | pub(crate) type EmptyAsyncClosure = AsyncEventType<dyn Sync + Send + Fn(...
type Closures (line 223) | pub(crate) type Closures<T> = Vec<Closure<T>>;
type AsyncClosures (line 224) | pub(crate) type AsyncClosures<T> = Vec<AsyncClosure<T>>;
type ScreencastEventData (line 228) | pub struct ScreencastEventData {
type WindowMoveEvent (line 237) | pub struct WindowMoveEvent {
type WindowOpenEvent (line 248) | pub struct WindowOpenEvent {
type LayoutEvent (line 261) | pub struct LayoutEvent {
type State (line 270) | pub struct State {
method execute_state (line 282) | pub async fn execute_state(self, old: State) -> crate::Result<Self> {
method instance_execute_state (line 288) | pub async fn instance_execute_state(
method execute_state_sync (line 333) | pub fn execute_state_sync(self, old: State) -> crate::Result<Self> {
method instance_execute_state_sync (line 338) | pub fn instance_execute_state_sync(
function execute_empty_closure (line 380) | pub(crate) fn execute_empty_closure(f: &EmptyClosure) {
function execute_closure (line 384) | pub(crate) fn execute_closure<T: Clone>(f: &Closure<T>, val: T) {
function execute_empty_closure_async (line 389) | pub(crate) async fn execute_empty_closure_async(f: &EmptyAsyncClosure) {
function execute_closure_async (line 394) | pub(crate) async fn execute_closure_async<T>(f: &AsyncClosure<T>, val: T) {
type WorkspaceEventData (line 400) | pub struct WorkspaceEventData {
type NonSpecialWorkspaceEventData (line 410) | pub struct NonSpecialWorkspaceEventData {
type WorkspaceMovedEventData (line 419) | pub struct WorkspaceMovedEventData {
type WindowEventData (line 430) | pub struct WindowEventData {
type MonitorEventData (line 441) | pub struct MonitorEventData {
type ChangedSpecialEventData (line 450) | pub struct ChangedSpecialEventData {
type MonitorAddedEventData (line 459) | pub struct MonitorAddedEventData {
type WindowFloatEventData (line 470) | pub struct WindowFloatEventData {
type WindowPinEventData (line 479) | pub struct WindowPinEventData {
type WindowTitleEventData (line 488) | pub struct WindowTitleEventData {
type UnknownEventData (line 499) | pub struct UnknownEventData {
method parse_args (line 508) | pub fn parse_args(self, count: usize) -> Vec<String> {
type GroupToggledEventData (line 517) | pub struct GroupToggledEventData {
type Event (line 526) | pub enum Event {
function parse_string_as_work (line 628) | fn parse_string_as_work(str: String) -> WorkspaceType {
type ParsedEventType (line 646) | pub(crate) enum ParsedEventType {
type KnownEvent (line 730) | type KnownEvent = (ParsedEventType, Vec<String>);
type UnknownEvent (line 731) | type UnknownEvent = (String, String);
function new_event_parser (line 733) | fn new_event_parser(input: &str) -> crate::Result<Either<KnownEvent, Unk...
function event_parser (line 785) | pub(crate) fn event_parser(event: String) -> crate::Result<Vec<Event>> {
FILE: dep-crates/hyprland-rs/src/event_listener/stream.rs
type EventStream (line 32) | pub struct EventStream {
method new (line 43) | pub fn new() -> Self {
method instance_new (line 71) | pub fn instance_new(instance: Instance) -> Self {
method default (line 36) | fn default() -> Self {
type Item (line 100) | type Item = crate::Result<Event>;
method poll_next (line 102) | fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Opt...
FILE: dep-crates/hyprland-rs/src/hyprpaper.rs
type Response (line 25) | pub enum Response {
function hyprpaper (line 35) | pub fn hyprpaper(keyword: Keyword) -> crate::Result<Response> {
function instance_hyprpaper (line 40) | pub fn instance_hyprpaper(instance: &Instance, keyword: Keyword) -> crat...
function hyprpaper_async (line 52) | pub async fn hyprpaper_async(keyword: Keyword) -> crate::Result<Response> {
function instance_hyprpaper_async (line 57) | pub async fn instance_hyprpaper_async(
FILE: dep-crates/hyprland-rs/src/hyprpaper/error.rs
type Error (line 3) | pub enum Error {
FILE: dep-crates/hyprland-rs/src/hyprpaper/keyword.rs
type Keyword (line 5) | pub enum Keyword {
method expected_response (line 58) | pub(super) fn expected_response(&self) -> ExpectedResponse {
method fmt (line 71) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
type ExpectedResponse (line 20) | pub(super) enum ExpectedResponse {
method is_expected (line 27) | pub(super) fn is_expected(&self, response: String) -> crate::Result<Re...
function check (line 88) | fn check(command: Keyword, expected_string: &str) {
function test_preload_string (line 94) | fn test_preload_string() {
function test_wallpaper (line 102) | fn test_wallpaper() {
function test_unload (line 140) | fn test_unload() {
FILE: dep-crates/hyprland-rs/src/hyprpaper/monitor.rs
type Monitor (line 2) | pub enum Monitor {
method fmt (line 10) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function check (line 23) | fn check(monitor: Monitor, expected: &str) {
function test_port (line 28) | fn test_port() {
function test_description (line 34) | fn test_description() {
FILE: dep-crates/hyprland-rs/src/hyprpaper/preload.rs
type Preload (line 2) | pub struct Preload {
method fmt (line 8) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function test_preload (line 18) | fn test_preload() {
FILE: dep-crates/hyprland-rs/src/hyprpaper/reload.rs
type Reload (line 7) | pub struct Reload {
method fmt (line 19) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function check (line 37) | fn check(reload: Reload, expected: &str) {
function test_reload_format_no_monitor_no_mode (line 42) | fn test_reload_format_no_monitor_no_mode() {
function test_reload_format_with_monitor_with_mode (line 52) | fn test_reload_format_with_monitor_with_mode() {
FILE: dep-crates/hyprland-rs/src/hyprpaper/unload.rs
type Unload (line 2) | pub enum Unload {
method fmt (line 10) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function check (line 24) | fn check(unload: Unload, expected: &str) {
function test_unload_path (line 29) | fn test_unload_path() {
function test_unload_all (line 35) | fn test_unload_all() {
FILE: dep-crates/hyprland-rs/src/hyprpaper/wallpaper.rs
type Wallpaper (line 4) | pub struct Wallpaper {
method fmt (line 16) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
function check (line 34) | fn check(wallpaper: Wallpaper, expected: &str) {
function test_wallpaper_no_monitor_no_mode (line 39) | fn test_wallpaper_no_monitor_no_mode() {
function test_wallpaper_with_monitor_with_mode (line 49) | fn test_wallpaper_with_monitor_with_mode() {
FILE: dep-crates/hyprland-rs/src/hyprpaper/wallpaper_listing.rs
type WallpaperListing (line 6) | pub struct WallpaperListing {
type Error (line 15) | type Error = HyprError;
method try_from (line 17) | fn try_from(s: &str) -> Result<Self, Self::Error> {
function check_ok (line 39) | fn check_ok(s: &str, expected_monitor: Option<&str>, expected_wallpaper_...
function test_ok_no_monitor (line 47) | fn test_ok_no_monitor() {
function test_ok_with_monitor (line 53) | fn test_ok_with_monitor() {
function test_err (line 59) | fn test_err() {
FILE: dep-crates/hyprland-rs/src/hyprpaper/wallpaper_mode.rs
type WallpaperMode (line 3) | pub enum WallpaperMode {
method fmt (line 15) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
FILE: dep-crates/hyprland-rs/src/instance.rs
type Instance (line 8) | pub struct Instance {
method eq (line 21) | fn eq(&self, other: &Self) -> bool {
method from_current_env (line 28) | pub fn from_current_env() -> crate::Result<Self> {
method from_instance (line 36) | pub fn from_instance(name: String) -> crate::Result<Self> {
method from_base_socket_path (line 43) | pub fn from_base_socket_path(path: PathBuf) -> crate::Result<Self> {
method write_to_socket (line 62) | pub(crate) fn write_to_socket(&self, content: CommandContent) -> crate...
method write_to_socket_async (line 73) | pub(crate) async fn write_to_socket_async(
method write_to_hyprpaper_socket (line 87) | pub(crate) fn write_to_hyprpaper_socket(
method write_to_hyprpaper_socket_async (line 101) | pub(crate) async fn write_to_hyprpaper_socket_async(
method get_event_stream (line 115) | pub(crate) fn get_event_stream(&self) -> crate::Result<std::os::unix::...
method get_event_stream_async (line 121) | pub(crate) async fn get_event_stream_async(
function get_env_name (line 129) | fn get_env_name() -> crate::Result<String> {
FILE: dep-crates/hyprland-rs/src/keyword.rs
type OptionRaw (line 25) | pub(crate) struct OptionRaw {
type OptionValue (line 35) | pub enum OptionValue {
method from (line 58) | fn from(str: Str) -> Self {
method from (line 48) | fn from(opt: OptionValue) -> Self {
type IsString (line 53) | trait IsString {}
type Keyword (line 93) | pub struct Keyword {
method parse_opts (line 103) | fn parse_opts(
method set (line 132) | pub fn set<Str: ToString, Opt: Into<OptionValue>>(key: Str, value: Opt...
method instance_set (line 137) | pub fn instance_set<Str: ToString, Opt: Into<OptionValue>>(
method set_async (line 153) | pub async fn set_async<Str: ToString, Opt: Into<OptionValue>>(
method instance_set_async (line 162) | pub async fn instance_set_async<Str: ToString, Opt: Into<OptionValue>>(
method get (line 179) | pub fn get<Str: ToString>(key: Str) -> crate::Result<Self> {
method instance_get (line 184) | pub fn instance_get<Str: ToString>(instance: &Instance, key: Str) -> c...
method get_async (line 193) | pub async fn get_async<Str: ToString>(key: Str) -> crate::Result<Self> {
method instance_get_async (line 199) | pub async fn instance_get_async<Str: ToString>(
FILE: dep-crates/hyprland-rs/src/lib.rs
type Result (line 75) | pub type Result<T> = std::result::Result<T, HyprError>;
function default_instance (line 80) | pub fn default_instance() -> std::result::Result<&'static Instance, Hypr...
function default_instance_panic (line 91) | pub fn default_instance_panic() -> &'static Instance {
FILE: dep-crates/hyprland-rs/src/shared.rs
type Address (line 15) | pub struct Address(String);
method fmt_new (line 18) | pub(crate) fn fmt_new(address: &str) -> Self {
method new (line 23) | pub fn new<T: ToString>(string: T) -> Self {
type HyprData (line 34) | pub trait HyprData {
method get (line 36) | fn get() -> crate::Result<Self>
method get_async (line 41) | async fn get_async() -> crate::Result<Self>
method instance_get (line 45) | fn instance_get(instance: &Instance) -> crate::Result<Self>
method instance_get_async (line 50) | async fn instance_get_async(instance: &Instance) -> crate::Result<Self>
type HyprDataVec (line 56) | pub trait HyprDataVec<T>: HyprData {
method to_vec (line 58) | fn to_vec(self) -> Vec<T>;
type HyprDataActive (line 62) | pub trait HyprDataActive {
method get_active (line 64) | fn get_active() -> crate::Result<Self>
method get_active_async (line 69) | async fn get_active_async() -> crate::Result<Self>
method instance_get_active (line 73) | fn instance_get_active(instance: &Instance) -> crate::Result<Self>
method instance_get_active_async (line 78) | async fn instance_get_active_async(instance: &Instance) -> crate::Resu...
type HyprDataActiveOptional (line 84) | pub trait HyprDataActiveOptional {
method get_active (line 86) | fn get_active() -> crate::Result<Option<Self>>
method get_active_async (line 91) | async fn get_active_async() -> crate::Result<Option<Self>>
method instance_get_active (line 95) | fn instance_get_active(instance: &Instance) -> crate::Result<Option<Se...
method instance_get_active_async (line 100) | async fn instance_get_active_async(instance: &Instance) -> crate::Resu...
type WorkspaceId (line 107) | pub type WorkspaceId = i32;
type MonitorId (line 111) | pub type MonitorId = i128;
function ser_spec_opt (line 114) | fn ser_spec_opt(opt: &Option<String>) -> String {
type WorkspaceType (line 124) | pub enum WorkspaceType {
method from (line 139) | fn from(value: &WorkspaceType) -> Self {
method hash (line 161) | fn hash<H: Hasher>(&self, state: &mut H) {
function get_hypr_path (line 172) | pub(crate) fn get_hypr_path() -> crate::Result<PathBuf> {
type CommandFlag (line 186) | pub enum CommandFlag {
type CommandContent (line 196) | pub struct CommandContent {
method as_bytes (line 215) | pub fn as_bytes(&self) -> Vec<u8> {
method fmt (line 232) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
FILE: dep-crates/wl-clipboard-rs/src/common.rs
type State (line 18) | pub struct State {
method event (line 44) | fn event(
type Error (line 24) | pub enum Error {
function initialize (line 60) | pub fn initialize<S>(
FILE: dep-crates/wl-clipboard-rs/src/copy.rs
type ClipboardType (line 31) | pub enum ClipboardType {
type MimeType (line 50) | pub enum MimeType {
type Source (line 63) | pub enum Source {
type MimeSource (line 77) | pub struct MimeSource {
type Seat (line 84) | pub enum Seat {
type ServeRequests (line 94) | pub enum ServeRequests {
type Options (line 104) | pub struct Options {
method new (line 343) | pub fn new() -> Self {
method clipboard (line 349) | pub fn clipboard(&mut self, clipboard: ClipboardType) -> &mut Self {
method seat (line 356) | pub fn seat(&mut self, seat: Seat) -> &mut Self {
method trim_newline (line 365) | pub fn trim_newline(&mut self, trim_newline: bool) -> &mut Self {
method foreground (line 375) | pub fn foreground(&mut self, foreground: bool) -> &mut Self {
method serve_requests (line 387) | pub fn serve_requests(&mut self, serve_requests: ServeRequests) -> &mu...
method omit_additional_text_mime_types (line 397) | pub fn omit_additional_text_mime_types(
method copy (line 421) | pub fn copy(self, source: Source, mime_type: MimeType) -> Result<(), E...
method copy_multi (line 444) | pub fn copy_multi(self, sources: Vec<MimeSource>) -> Result<(), Error> {
method prepare_copy (line 472) | pub fn prepare_copy(self, source: Source, mime_type: MimeType) -> Resu...
method prepare_copy_multi (line 503) | pub fn prepare_copy_multi(self, sources: Vec<MimeSource>) -> Result<Pr...
type PreparedCopy (line 138) | pub struct PreparedCopy {
method serve (line 513) | pub fn serve(mut self) -> Result<(), Error> {
type SourceCreationError (line 146) | pub enum SourceCreationError {
type Error (line 177) | pub enum Error {
method from (line 217) | fn from(x: common::Error) -> Self {
type DataSourceError (line 230) | pub enum DataSourceError {
type State (line 238) | struct State {
method as_mut (line 253) | fn as_mut(&mut self) -> &mut common::State {
method event (line 259) | fn event(
function make_source (line 562) | fn make_source(
function get_devices (line 628) | fn get_devices(
function clear (line 720) | pub fn clear(clipboard: ClipboardType, seat: Seat) -> Result<(), Error> {
function clear_internal (line 724) | pub(crate) fn clear_internal(
function prepare_copy (line 781) | pub fn prepare_copy(
function prepare_copy_multi (line 832) | pub fn prepare_copy_multi(
function prepare_copy_internal (line 841) | fn prepare_copy_internal(
function copy (line 982) | pub fn copy(options: Options, source: Source, mime_type: MimeType) -> Re...
function copy_multi (line 1013) | pub fn copy_multi(options: Options, sources: Vec<MimeSource>) -> Result<...
function copy_internal (line 1017) | pub(crate) fn copy_internal(
FILE: dep-crates/wl-clipboard-rs/src/data_control.rs
type Manager (line 19) | pub enum Manager {
method get_data_device (line 43) | pub fn get_data_device<D, U>(&self, seat: &WlSeat, qh: &QueueHandle<D>...
method create_data_source (line 55) | pub fn create_data_source<D>(&self, qh: &QueueHandle<D>) -> Source
type Device (line 25) | pub enum Device {
method destroy (line 68) | pub fn destroy(&self) {
method set_selection (line 76) | pub fn set_selection(&self, source: Option<&Source>) {
method set_primary_selection (line 84) | pub fn set_primary_selection(&self, source: Option<&Source>) {
type Source (line 31) | pub enum Source {
method destroy (line 93) | pub fn destroy(&self) {
method offer (line 100) | pub fn offer(&self, mime_type: String) {
method is_alive (line 107) | pub fn is_alive(&self) -> bool {
method zwlr (line 115) | pub fn zwlr(&self) -> &ZwlrDataControlSourceV1 {
method ext (line 124) | pub fn ext(&self) -> &ExtDataControlSourceV1 {
method from (line 150) | fn from(v: ZwlrDataControlSourceV1) -> Self {
method from (line 156) | fn from(v: ExtDataControlSourceV1) -> Self {
type Offer (line 37) | pub enum Offer {
method destroy (line 134) | pub fn destroy(&self) {
method receive (line 141) | pub fn receive(&self, mime_type: String, fd: BorrowedFd) {
method from (line 162) | fn from(v: ZwlrDataControlOfferV1) -> Self {
method from (line 168) | fn from(v: ExtDataControlOfferV1) -> Self {
FILE: dep-crates/wl-clipboard-rs/src/paste.rs
type ClipboardType (line 29) | pub enum ClipboardType {
type MimeType (line 42) | pub enum MimeType<'a> {
type Seat (line 65) | pub enum Seat<'a> {
type State (line 75) | struct State {
method as_mut (line 86) | fn as_mut(&mut self) -> &mut common::State {
method event (line 147) | fn event(
type Error (line 97) | pub enum Error {
method from (line 134) | fn from(x: common::Error) -> Self {
function get_offer (line 192) | fn get_offer(
function get_mime_types (line 270) | pub fn get_mime_types(clipboard: ClipboardType, seat: Seat<'_>) -> Resul...
function get_mime_types_internal (line 275) | pub(crate) fn get_mime_types_internal(
function get_contents (line 322) | pub fn get_contents(
function get_contents_internal (line 331) | pub(crate) fn get_contents_internal(
function get_contents_channel (line 416) | pub fn get_contents_channel(
function get_contents_channel_internal (line 423) | pub(crate) fn get_contents_channel_internal(
function run_dispatch_loop (line 445) | fn run_dispatch_loop(
function get_all_contents_callback (line 554) | pub fn get_all_contents_callback(
type CallbackData (line 561) | pub type CallbackData<'a> = Result<
function get_all_contents_callback_internal (line 569) | pub(crate) fn get_all_contents_callback_internal(
function run_callback_dispatch_loop (line 590) | fn run_callback_dispatch_loop(
function create_load_mime_fn (line 630) | fn create_load_mime_fn<'a>(
function get_seat (line 648) | fn get_seat<'a>(state: &'a mut State, seat: Seat) -> Option<&'a mut Seat...
function check_mime_type (line 659) | fn check_mime_type(mut mime_types: HashSet<String>, mime_type: MimeType)...
FILE: dep-crates/wl-clipboard-rs/src/seat_data.rs
type SeatData (line 4) | pub struct SeatData {
method set_name (line 20) | pub fn set_name(&mut self, name: String) {
method set_device (line 27) | pub fn set_device(&mut self, device: Option<Device>) {
method set_offer (line 39) | pub fn set_offer(&mut self, new_offer: Option<Offer>) {
method set_primary_offer (line 51) | pub fn set_primary_offer(&mut self, new_offer: Option<Offer>) {
FILE: dep-crates/wl-clipboard-rs/src/tests/copy.rs
function clear_test (line 16) | fn clear_test() {
function copy_test (line 51) | fn copy_test() {
function copy_multi_test (line 103) | fn copy_multi_test() {
function copy_multi_no_additional_text_mime_types_test (line 197) | fn copy_multi_no_additional_text_mime_types_test() {
function copy_large (line 278) | fn copy_large() {
FILE: dep-crates/wl-clipboard-rs/src/tests/mod.rs
type TestServer (line 17) | pub struct TestServer<S: 'static> {
type ClientCounter (line 23) | struct ClientCounter(AtomicU8);
method disconnected (line 26) | fn disconnected(
function new (line 36) | pub fn new() -> Self {
function socket_name (line 64) | pub fn socket_name(&self) -> &OsStr {
function run (line 68) | pub fn run(self, mut state: S) {
function run_mutex (line 72) | pub fn run_mutex(self, state: Arc<Mutex<S>>) {
function run_internal (line 79) | fn run_internal(mut self, state: &mut S) {
FILE: dep-crates/wl-clipboard-rs/src/tests/paste.rs
function get_mime_types_test (line 12) | fn get_mime_types_test() {
function get_mime_types_no_data_control (line 49) | fn get_mime_types_no_data_control() {
function get_mime_types_no_data_control_2 (line 78) | fn get_mime_types_no_data_control_2() {
function get_mime_types_no_seats (line 107) | fn get_mime_types_no_seats() {
function get_mime_types_empty_clipboard (line 128) | fn get_mime_types_empty_clipboard() {
function get_mime_types_specific_seat (line 155) | fn get_mime_types_specific_seat() {
function get_mime_types_primary (line 203) | fn get_mime_types_primary() {
function get_contents_test (line 240) | fn get_contents_test() {
function get_contents_wrong_mime_type (line 280) | fn get_contents_wrong_mime_type() {
function get_contents_channel_test (line 314) | fn get_contents_channel_test() {
function get_contents_channel_no_protocol (line 359) | fn get_contents_channel_no_protocol() {
function get_contents_channel_wrong_mime_type (line 391) | fn get_contents_channel_wrong_mime_type() {
function get_contents_channel_test_multiple_mime (line 434) | fn get_contents_channel_test_multiple_mime() {
FILE: dep-crates/wl-clipboard-rs/src/tests/state.rs
type OfferInfo (line 38) | pub enum OfferInfo {
method mime_types (line 58) | fn mime_types(&self, state: &State) -> Vec<String> {
method data (line 65) | pub fn data(&self) -> &HashMap<String, Vec<u8>> {
method default (line 50) | fn default() -> Self {
type SeatInfo (line 74) | pub struct SeatInfo {
type State (line 80) | pub struct State {
method create_seats (line 93) | pub fn create_seats(&self, server: &TestServer<Self>) {
method bind (line 104) | fn bind(
method request (line 118) | fn request(
method request (line 131) | fn request(
method request (line 186) | fn request(
method request (line 240) | fn request(
method request (line 275) | fn request(
FILE: dep-crates/wl-clipboard-rs/src/tests/utils.rs
type State (line 16) | struct State {
method request (line 24) | fn request(
method request (line 44) | fn request(
function is_primary_selection_supported_test (line 64) | fn is_primary_selection_supported_test() {
function is_primary_selection_supported_primary_selection_unsupported (line 87) | fn is_primary_selection_supported_primary_selection_unsupported() {
function is_primary_selection_supported_data_control_v1 (line 110) | fn is_primary_selection_supported_data_control_v1() {
function is_primary_selection_supported_no_seats (line 133) | fn is_primary_selection_supported_no_seats() {
function supports_v2_seats (line 152) | fn supports_v2_seats() {
function is_primary_selection_supported_no_data_control (line 175) | fn is_primary_selection_supported_no_data_control() {
function is_primary_selection_supported_ext_data_control (line 197) | fn is_primary_selection_supported_ext_data_control() {
function is_primary_selection_supported_primary_selection_unsupported_ext_data_control (line 220) | fn is_primary_selection_supported_primary_selection_unsupported_ext_data...
function is_primary_selection_supported_data_control_v1_and_ext_data_control (line 243) | fn is_primary_selection_supported_data_control_v1_and_ext_data_control() {
FILE: dep-crates/wl-clipboard-rs/src/utils.rs
function is_text (line 30) | pub fn is_text(mime_type: &str) -> bool {
type PrimarySelectionState (line 38) | struct PrimarySelectionState {
method event (line 47) | fn event(
method event (line 86) | fn event(
type PrimarySelectionCheckError (line 109) | pub enum PrimarySelectionCheckError {
function is_primary_selection_supported (line 164) | pub fn is_primary_selection_supported() -> Result<bool, PrimarySelection...
function is_primary_selection_supported_internal (line 168) | pub(crate) fn is_primary_selection_supported_internal(
FILE: src/cli.rs
type App (line 12) | pub struct App {
type GlobalOpts (line 21) | pub struct GlobalOpts {
type Command (line 53) | pub enum Command {
type ConfigCommand (line 102) | pub enum ConfigCommand {
type DataCommand (line 125) | pub enum DataCommand {
type DebugCommand (line 134) | pub enum DebugCommand {
type DefaultApplicationsCommand (line 170) | pub enum DefaultApplicationsCommand {
FILE: src/completions.rs
function generate (line 8) | pub fn generate(shell: &str, path: Option<PathBuf>, delete: bool) -> any...
FILE: src/data.rs
function launch_history (line 6) | pub fn launch_history(
FILE: src/debug.rs
function check_class (line 11) | pub fn check_class(class: Option<String>) -> anyhow::Result<()> {
function check_icon (line 33) | fn check_icon(class: &str) {
function list_icons (line 51) | pub fn list_icons() -> anyhow::Result<()> {
function list_desktop_files (line 63) | pub fn list_desktop_files() {
function search (line 90) | pub fn search(text: &str, all: bool, config_file: &Path, data_dir: &Path) {
function info (line 105) | pub fn info(
function count_dir (line 139) | fn count_dir(path: &Path) -> (usize, usize) {
FILE: src/default_apps.rs
function get (line 12) | pub fn get(mime: &str) -> anyhow::Result<()> {
function set_default (line 43) | pub fn set_default(mime: &str, value: &str) -> anyhow::Result<()> {
function add_association (line 74) | pub fn add_association(mime: &str, value: &str) -> anyhow::Result<()> {
constant USED_MIME_TYPES (line 105) | const USED_MIME_TYPES: &[&str] = &["x-scheme-handler/https", "inode/dire...
function list (line 107) | pub fn list(all: bool) {
function check (line 157) | pub fn check() {
FILE: src/explain.rs
function explain_config (line 6) | pub fn explain_config(config_file: &Path, add_how_to_explain_again: bool) {
FILE: src/keybinds.rs
function configure_wm (line 8) | pub fn configure_wm(config: &Config, hyprland_version: &semver::Version)...
function plugin (line 28) | fn plugin(config: &Config, hyprland_version: &semver::Version) -> anyhow...
function apply_binds (line 41) | fn apply_binds(config: &Config) -> anyhow::Result<()> {
FILE: src/main.rs
function main (line 28) | fn main() -> anyhow::Result<()> {
function check_features (line 233) | fn check_features() {
function check_env (line 248) | fn check_env() {
FILE: src/receive_handle.rs
function event_handler (line 14) | pub async fn event_handler(
function r#type (line 42) | fn r#type(global: &mut Globals, text: &str, event_sender: &Sender<Transf...
function open_overview (line 50) | fn open_overview(global: &mut Globals, event_sender: &Sender<TransferTyp...
function open_switch (line 83) | fn open_switch(global: &mut Globals, config: &OpenSwitch) {
function switch_switch (line 115) | fn switch_switch(global: &mut Globals, config: &SwitchSwitchConfig) {
function switch_overview (line 127) | fn switch_overview(global: &mut Globals, config: &SwitchOverviewConfig) {
function exit (line 143) | fn exit(global: &mut Globals) {
function close_overview (line 155) | fn close_overview(global: &mut Globals, config: CloseOverviewConfig) {
function close_switch (line 200) | fn close_switch(global: &mut Globals) {
function restart (line 212) | fn restart(global: &Globals) {
FILE: src/socket.rs
function socket_handler (line 12) | pub fn socket_handler(event_sender: &Sender<TransferType>) {
function handle_client (line 43) | fn handle_client(
FILE: src/start.rs
function start (line 36) | pub fn start(
type Globals (line 109) | pub struct Globals {
type WindowsGlobal (line 115) | pub struct WindowsGlobal {
function activate (line 122) | fn activate(
function create_windows (line 220) | fn create_windows(
function apply_css (line 260) | fn apply_css(custom_css: &Path) -> anyhow::Result<()> {
function register_event_restarter (line 288) | pub fn register_event_restarter(
function setup_restart_listener (line 344) | fn setup_restart_listener(config_file: &Path, css_path: &Path, restart_t...
FILE: src/util.rs
function preactivate (line 16) | pub fn preactivate() -> anyhow::Result<()> {
function reload_icons (line 28) | pub fn reload_icons(background: bool) {
function reload_desktop_data (line 35) | pub fn reload_desktop_data() -> anyhow::Result<()> {
function init_gtk (line 45) | pub fn init_gtk() {
function check_themes (line 49) | pub fn check_themes() {
function handle_sigterm (line 61) | fn handle_sigterm() {
function get_icon_data (line 79) | fn get_icon_data() -> (Vec<String>, Vec<PathBuf>) {
constant NEW_VERSION_INFOS (line 96) | const NEW_VERSION_INFOS: &[(&str, &str)] = &[
function check_new_version (line 113) | pub fn check_new_version(cache_dir: &Path) -> anyhow::Result<(Ordering, ...
function filter_version_messages (line 138) | fn filter_version_messages(
function v (line 174) | fn v(s: &str) -> Version {
function test_empty_versions (line 180) | fn test_empty_versions() {
function test_older_current_version (line 187) | fn test_older_current_version() {
function test_newer_current_version (line 195) | fn test_newer_current_version() {
function test_same_version (line 203) | fn test_same_version() {
function test_multiple_versions (line 211) | fn test_multiple_versions() {
function test_all_versions (line 223) | fn test_all_versions() {
Condensed preview — 331 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,359K chars).
[
{
"path": ".githooks/pre-commit",
"chars": 11,
"preview": "just check\n"
},
{
"path": ".github/workflows/publish.yml",
"chars": 6159,
"preview": "name: publish\n\non:\n push:\n tags:\n - 'v*'\n\njobs:\n check:\n runs-on: ubuntu-latest\n outputs:\n should_p"
},
{
"path": ".github/workflows/release-please.yml",
"chars": 476,
"preview": "name: release-please\n\non:\n push:\n branches:\n - 'hyprshell'\n - 'hyprshell-patch-**'\n\njobs:\n release-please"
},
{
"path": ".github/workflows/test.yml",
"chars": 2494,
"preview": "name: test\n\non:\n push:\n branches-ignore:\n - 'release-please-**'\n - 'hyprshell-release'\n\nconcurrency:\n gro"
},
{
"path": ".github/workflows/update.yml",
"chars": 882,
"preview": "name: update flake.lock\n\non:\n workflow_dispatch: # allows manual triggering\n schedule:\n - cron: '30 2 1,15 * *' # A"
},
{
"path": ".gitignore",
"chars": 37,
"preview": "/target\n/*/target\n/result\n\n/test-data"
},
{
"path": ".idea/.gitignore",
"chars": 176,
"preview": "# Default ignored files\n/shelf/\n/workspace.xml\n# Editor-based HTTP Client requests\n/httpRequests/\n# Datasource local sto"
},
{
"path": ".idea/copilot.data.migration.agent.xml",
"chars": 190,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"AgentMigrationStateService\">\n <option"
},
{
"path": ".idea/copilot.data.migration.ask.xml",
"chars": 188,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"AskMigrationStateService\">\n <option n"
},
{
"path": ".idea/copilot.data.migration.ask2agent.xml",
"chars": 194,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"Ask2AgentMigrationStateService\">\n <op"
},
{
"path": ".idea/copilot.data.migration.edit.xml",
"chars": 189,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"EditMigrationStateService\">\n <option "
},
{
"path": ".idea/file.template.settings.xml",
"chars": 287,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"ExportableFileTemplateSettings\">\n <j2"
},
{
"path": ".idea/hyprshell.iml",
"chars": 2636,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"EMPTY_MODULE\" version=\"4\">\n <component name=\"NewModuleRootManager\""
},
{
"path": ".idea/inspectionProfiles/Project_Default.xml",
"chars": 385,
"preview": "<component name=\"InspectionProjectProfileManager\">\n <profile version=\"1.0\">\n <option name=\"myName\" value=\"Project De"
},
{
"path": ".idea/modules.xml",
"chars": 270,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"ProjectModuleManager\">\n <modules>\n "
},
{
"path": ".idea/rust.xml",
"chars": 169,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"RsVcsConfiguration\">\n <option name=\"r"
},
{
"path": ".idea/vcs.xml",
"chars": 180,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"VcsDirectoryMappings\">\n <mapping dire"
},
{
"path": ".release-please-manifest.json",
"chars": 18,
"preview": "{\n \".\": \"4.9.5\"\n}"
},
{
"path": "CHANGELOG.md",
"chars": 46720,
"preview": "# Changelog\n\n## [4.9.5](https://github.com/H3rmt/hyprshell/compare/v4.9.4...v4.9.5) (2026-03-31)\n\n\n### Bug Fixes\n\n* use "
},
{
"path": "Cargo.toml",
"chars": 4398,
"preview": "[workspace]\nmembers = [\"crates/exec-lib\", \"crates/core-lib\", \"crates/windows-lib\", \"crates/launcher-lib\", \"crates/config"
},
{
"path": "DEVELOPMENT.md",
"chars": 2723,
"preview": "# Development Guide\n\nWelcome to the Hyprshell development guide. This document provides information on how to set up you"
},
{
"path": "LICENSE",
"chars": 1071,
"preview": "MIT License\n\nCopyright (c) 2025 Enrico Stemmer\n\nPermission is hereby granted, free of charge, to any person obtaining a "
},
{
"path": "README.md",
"chars": 6154,
"preview": "# Hyprshell\n\n[](https://crates.io/crates/hyprshell) []\n\n#[derive(Debug, Clone)]\npub struct Config {\n pub encryption: Encryption,\n pub compression: C"
},
{
"path": "crates/clipboard-lib/src/lib.rs",
"chars": 48,
"preview": "mod config;\npub mod store;\npub(crate) mod util;\n"
},
{
"path": "crates/clipboard-lib/src/store/listen.rs",
"chars": 3732,
"preview": "use crate::config::{Compression, Config, ConvolutionFilterType, Encryption};\nuse crate::store::mime::{filer_mimes, get_p"
},
{
"path": "crates/clipboard-lib/src/store/mime.rs",
"chars": 1958,
"preview": "use std::collections::HashSet;\nuse tracing::trace;\n\nstatic MIME_TYPES_PRIO: &[&str] = &[\n \"image/png\",\n \"image/jpg"
},
{
"path": "crates/clipboard-lib/src/store/mod.rs",
"chars": 132,
"preview": "mod listen;\nmod mime;\nmod save_image;\nmod save_map;\nmod save_text;\npub(crate) mod util;\nmod write;\n\npub use listen::test"
},
{
"path": "crates/clipboard-lib/src/store/save_image.rs",
"chars": 2393,
"preview": "use crate::store::util::create_storage_path;\nuse anyhow::Context;\nuse image::{ImageEncoder, ImageReader};\nuse std::fs::F"
},
{
"path": "crates/clipboard-lib/src/store/save_map.rs",
"chars": 3790,
"preview": "use crate::config::Config;\nuse crate::store::util::create_storage_path;\nuse crate::store::write::get_storage_writer;\nuse"
},
{
"path": "crates/clipboard-lib/src/store/save_text.rs",
"chars": 1134,
"preview": "use crate::config::Config;\nuse crate::store::util::create_storage_path;\nuse crate::store::write::get_storage_writer;\nuse"
},
{
"path": "crates/clipboard-lib/src/store/util.rs",
"chars": 773,
"preview": "use anyhow::Context;\nuse core_lib::util::get_boot_id;\nuse std::fs;\nuse std::path::{Path, PathBuf};\nuse std::time::{Syste"
},
{
"path": "crates/clipboard-lib/src/store/write.rs",
"chars": 2028,
"preview": "use crate::config::{Compression, Config, Encryption};\nuse std::io::Write;\n\npub fn get_storage_writer<'a, I: Write + 'a>("
},
{
"path": "crates/clipboard-lib/src/util/brotli_compressor.rs",
"chars": 931,
"preview": "use brotli::CompressorWriter;\n\nuse brotli::enc::BrotliEncoderParams;\nuse std::io::Write;\nuse tracing::warn;\n\npub struct "
},
{
"path": "crates/clipboard-lib/src/util/crypt.rs",
"chars": 3840,
"preview": "use anyhow::Context;\nuse crypto_common::Generate;\nuse std::io::Write;\nuse tracing::trace;\n\n#[cfg(feature = \"encrypt_chac"
},
{
"path": "crates/clipboard-lib/src/util/lz4_compressor.rs",
"chars": 746,
"preview": "use lz4_flex::frame::FrameEncoder;\nuse std::io::Write;\nuse tracing::warn;\n\npub struct LZ4CompressWriter<W: Write> {\n "
},
{
"path": "crates/clipboard-lib/src/util/mod.rs",
"chars": 376,
"preview": "#[cfg(feature = \"compress_brotli\")]\npub mod brotli_compressor;\n#[cfg(any(feature = \"encrypt_chacha20poly1305\", feature ="
},
{
"path": "crates/clipboard-lib/src/util/secret_service.rs",
"chars": 1764,
"preview": "use crate::util::crypt::generate_new_key;\nuse anyhow::Context;\nuse secret_service::EncryptionType;\nuse secret_service::b"
},
{
"path": "crates/clipboard-lib/src/util/zstd_compressor.rs",
"chars": 990,
"preview": "use std::io::Write;\nuse tracing::warn;\nuse zstd::Encoder;\n\npub struct ZstdCompressWriter<'a, W: Write> {\n encoder: En"
},
{
"path": "crates/config-edit-lib/Cargo.toml",
"chars": 683,
"preview": "[package]\nname = \"hyprshell-config-edit-lib\"\ndocumentation = \"https://docs.rs/hyprshell-config-edit-lib\"\nversion = \"4.9."
},
{
"path": "crates/config-edit-lib/src/components/changes.rs",
"chars": 22363,
"preview": "use crate::flags_csv;\nuse crate::structs::{Config, Plugins};\nuse relm4::adw::ActionRow;\nuse relm4::adw::gtk::SelectionMo"
},
{
"path": "crates/config-edit-lib/src/components/footer.rs",
"chars": 4311,
"preview": "use relm4::adw::prelude::*;\nuse relm4::gtk::Orientation;\nuse relm4::{ComponentParts, ComponentSender, SimpleComponent, g"
},
{
"path": "crates/config-edit-lib/src/components/generate/main.rs",
"chars": 17366,
"preview": "use crate::components::generate::step0::{Step0, Step0Init, Step0Input};\nuse crate::components::generate::step1::{Launche"
},
{
"path": "crates/config-edit-lib/src/components/generate/mod.rs",
"chars": 82,
"preview": "mod main;\npub use main::*;\nmod step0;\nmod step1;\nmod step2;\nmod step3;\nmod step4;\n"
},
{
"path": "crates/config-edit-lib/src/components/generate/step0.rs",
"chars": 8901,
"preview": "use crate::components::shortcut_dialog::{\n KeyboardShortcut, KeyboardShortcutInit, KeyboardShortcutInput, KeyboardSho"
},
{
"path": "crates/config-edit-lib/src/components/generate/step1.rs",
"chars": 6695,
"preview": "use relm4::adw::prelude::*;\nuse relm4::gtk::{Align, Justification, SelectionMode};\nuse relm4::{ComponentParts, Component"
},
{
"path": "crates/config-edit-lib/src/components/generate/step2.rs",
"chars": 11015,
"preview": "use crate::util::{SelectRow, SetTextIfDifferent};\nuse core_lib::util::find_command;\nuse relm4::adw::prelude::*;\nuse relm"
},
{
"path": "crates/config-edit-lib/src/components/generate/step3.rs",
"chars": 6924,
"preview": "use relm4::adw::prelude::*;\nuse relm4::gtk::{Align, Justification, SelectionMode};\nuse relm4::{ComponentParts, Component"
},
{
"path": "crates/config-edit-lib/src/components/generate/step4.rs",
"chars": 8912,
"preview": "use crate::components::shortcut_dialog::{\n KeyboardShortcut, KeyboardShortcutInit, KeyboardShortcutInput, KeyboardSho"
},
{
"path": "crates/config-edit-lib/src/components/launcher.rs",
"chars": 9564,
"preview": "use crate::components::launcher_plugins::{\n LauncherPlugins, LauncherPluginsInit, LauncherPluginsInput, LauncherPlugi"
},
{
"path": "crates/config-edit-lib/src/components/launcher_plugins/actions.rs",
"chars": 10171,
"preview": "use crate::util::SetCursor;\nuse config_lib::actions::ToAction;\nuse config_lib::{ActionsPluginAction, ActionsPluginAction"
},
{
"path": "crates/config-edit-lib/src/components/launcher_plugins/applications.rs",
"chars": 6721,
"preview": "use crate::util::SetCursor;\nuse relm4::adw::gtk::{Adjustment, Align};\nuse relm4::adw::prelude::*;\nuse relm4::{ComponentP"
},
{
"path": "crates/config-edit-lib/src/components/launcher_plugins/main.rs",
"chars": 8510,
"preview": "use crate::components::launcher_plugins::actions::{\n Actions, ActionsInit, ActionsInput, ActionsOutput,\n};\nuse crate:"
},
{
"path": "crates/config-edit-lib/src/components/launcher_plugins/mod.rs",
"chars": 102,
"preview": "pub mod actions;\npub mod applications;\nmod main;\npub mod simple;\npub mod websearch;\n\npub use main::*;\n"
},
{
"path": "crates/config-edit-lib/src/components/launcher_plugins/simple.rs",
"chars": 2751,
"preview": "use crate::util::SetCursor;\nuse relm4::adw::prelude::*;\nuse relm4::gtk::Align;\nuse relm4::{ComponentParts, ComponentSend"
},
{
"path": "crates/config-edit-lib/src/components/launcher_plugins/websearch.rs",
"chars": 8706,
"preview": "use crate::util::SetCursor;\nuse config_lib::SearchEngine;\nuse relm4::adw::prelude::*;\nuse relm4::gtk::{Align, SelectionM"
},
{
"path": "crates/config-edit-lib/src/components/mod.rs",
"chars": 201,
"preview": "pub mod changes;\nmod footer;\nmod generate;\nmod launcher;\nmod launcher_plugins;\npub mod nix_preview;\npub mod root;\nmod sh"
},
{
"path": "crates/config-edit-lib/src/components/nix_preview.rs",
"chars": 1037,
"preview": "use relm4::adw::prelude::*;\nuse relm4::gtk;\nuse relm4::{ComponentParts, ComponentSender, RelmWidgetExt, SimpleComponent}"
},
{
"path": "crates/config-edit-lib/src/components/root.rs",
"chars": 29783,
"preview": "use crate::components::changes::{\n Changes, ChangesInit, ChangesInput, ChangesOutput, generate_items,\n};\nuse crate::c"
},
{
"path": "crates/config-edit-lib/src/components/shortcut_dialog.rs",
"chars": 6348,
"preview": "use crate::structs::ConfigModifier;\nuse crate::util::{handle_key, mod_key_to_string};\nuse relm4::adw::prelude::*;\nuse re"
},
{
"path": "crates/config-edit-lib/src/components/switch.rs",
"chars": 10520,
"preview": "use crate::components::shortcut_dialog::{\n KeyboardShortcut, KeyboardShortcutInit, KeyboardShortcutInput, KeyboardSho"
},
{
"path": "crates/config-edit-lib/src/components/theme.rs",
"chars": 9954,
"preview": "use crate::util::{ScrollToPosition, SetCursor};\nuse config_lib::style::Theme;\nuse relm4::abstractions::Toaster;\nuse relm"
},
{
"path": "crates/config-edit-lib/src/components/windows.rs",
"chars": 7767,
"preview": "use crate::components::switch::{Switch, SwitchInit, SwitchInput, SwitchOutput};\nuse crate::components::windows_overview:"
},
{
"path": "crates/config-edit-lib/src/components/windows_overview.rs",
"chars": 9394,
"preview": "use crate::components::shortcut_dialog::{\n KeyboardShortcut, KeyboardShortcutInit, KeyboardShortcutInput, KeyboardSho"
},
{
"path": "crates/config-edit-lib/src/lib.rs",
"chars": 209,
"preview": "mod components;\nmod start;\nmod structs;\nmod util;\n\npub const APPLICATION_EDIT_ID: &str = \"com.github.h3rmt.hyprshell-edi"
},
{
"path": "crates/config-edit-lib/src/start.rs",
"chars": 1101,
"preview": "use crate::APPLICATION_EDIT_ID;\nuse crate::components::root::{Root, RootInit};\nuse relm4::RelmApp;\nuse relm4::adw::gdk::"
},
{
"path": "crates/config-edit-lib/src/structs.rs",
"chars": 12754,
"preview": "use std::fmt;\nuse std::fmt::Formatter;\n\n#[derive(Debug, Clone)]\npub struct Config {\n pub windows: Windows,\n}\n\n#[deriv"
},
{
"path": "crates/config-edit-lib/src/styles.css",
"chars": 2529,
"preview": "/* border around full expander row + items */\n.enable-frame > box {\n padding: 4px;\n border-radius: 18px;\n borde"
},
{
"path": "crates/config-edit-lib/src/util.rs",
"chars": 4726,
"preview": "use crate::structs::ConfigModifier;\nuse relm4::gtk::gdk::{Cursor, Key, ModifierType};\nuse relm4::gtk::prelude::{Cast, Ed"
},
{
"path": "crates/config-lib/Cargo.toml",
"chars": 837,
"preview": "[package]\nname = \"hyprshell-config-lib\"\ndocumentation = \"https://docs.rs/hyprshell-config-lib\"\nversion = \"4.9.5\"\ndescrip"
},
{
"path": "crates/config-lib/src/actions.rs",
"chars": 2337,
"preview": "use crate::{ActionsPluginAction, ActionsPluginActionCustom};\nuse std::path::PathBuf;\n\npub trait ToAction {\n fn to_act"
},
{
"path": "crates/config-lib/src/check.rs",
"chars": 5486,
"preview": "use crate::Config;\nuse anyhow::bail;\n\npub fn check(config: &Config) -> anyhow::Result<()> {\n if config\n .windo"
},
{
"path": "crates/config-lib/src/explain.rs",
"chars": 10545,
"preview": "use crate::Config;\nuse std::fmt::Write;\nuse std::path::Path;\n\nconst BOLD: &str = \"\\x1b[1m\";\nconst ITALIC: &str = \"\\x1b[3"
},
{
"path": "crates/config-lib/src/lib.rs",
"chars": 317,
"preview": "pub mod actions;\nmod check;\nmod explain;\nmod load;\nmod migrate;\nmod modifier;\nmod save;\nmod structs;\npub mod style;\n\npub"
},
{
"path": "crates/config-lib/src/load.rs",
"chars": 3883,
"preview": "use crate::Config;\nuse crate::migrate::check_migration_needed;\nuse anyhow::{Context, bail};\nuse ron::Options;\nuse ron::e"
},
{
"path": "crates/config-lib/src/migrate/check.rs",
"chars": 1167,
"preview": "use crate::CURRENT_CONFIG_VERSION;\nuse crate::load::load_config_file;\nuse anyhow::{Context, bail};\nuse serde::Deserializ"
},
{
"path": "crates/config-lib/src/migrate/m1t2/convert.rs",
"chars": 2441,
"preview": "use crate::migrate::m1t2::{NEXT_CONFIG_VERSION, old_structs};\nuse crate::migrate::m2t3;\n\nimpl From<old_structs::Config> "
},
{
"path": "crates/config-lib/src/migrate/m1t2/mod.rs",
"chars": 135,
"preview": "pub const PREV_CONFIG_VERSION: u16 = 1;\npub const NEXT_CONFIG_VERSION: u16 = 2;\nmod convert;\nmod old_structs;\n\npub use o"
},
{
"path": "crates/config-lib/src/migrate/m1t2/old_structs.rs",
"chars": 3003,
"preview": "use crate::migrate::m2t3;\nuse serde::Deserialize;\nuse smart_default::SmartDefault;\nuse std::fmt::Display;\n\n#[derive(Smar"
},
{
"path": "crates/config-lib/src/migrate/m2t3/convert.rs",
"chars": 1883,
"preview": "use crate::migrate::m2t3::{NEXT_CONFIG_VERSION, old_structs};\n\nimpl From<old_structs::Config> for crate::Config {\n fn"
},
{
"path": "crates/config-lib/src/migrate/m2t3/mod.rs",
"chars": 135,
"preview": "pub const PREV_CONFIG_VERSION: u16 = 2;\npub const NEXT_CONFIG_VERSION: u16 = 3;\nmod convert;\nmod old_structs;\n\npub use o"
},
{
"path": "crates/config-lib/src/migrate/m2t3/old_structs.rs",
"chars": 2293,
"preview": "use serde::Deserialize;\nuse smart_default::SmartDefault;\n\n#[derive(SmartDefault, Debug, Clone, Deserialize)]\n#[serde(def"
},
{
"path": "crates/config-lib/src/migrate/migrate_config.rs",
"chars": 1559,
"preview": "use crate::load::load_config_file;\nuse crate::migrate::check::get_config_version;\nuse crate::{CURRENT_CONFIG_VERSION, mi"
},
{
"path": "crates/config-lib/src/migrate/mod.rs",
"chars": 124,
"preview": "mod check;\nmod m1t2;\nmod m2t3;\nmod migrate_config;\n\npub use check::check_migration_needed;\npub use migrate_config::migra"
},
{
"path": "crates/config-lib/src/modifier.rs",
"chars": 2533,
"preview": "use anyhow::bail;\nuse serde::de::Visitor;\nuse serde::{Deserialize, Deserializer, Serialize, Serializer};\nuse std::fmt;\n\n"
},
{
"path": "crates/config-lib/src/save.rs",
"chars": 2672,
"preview": "use crate::Config;\nuse anyhow::{Context, bail};\nuse ron::Options;\nuse ron::extensions::Extensions;\nuse ron::ser::PrettyC"
},
{
"path": "crates/config-lib/src/structs.rs",
"chars": 6498,
"preview": "use crate::Modifier;\nuse serde::{Deserialize, Serialize};\nuse smart_default::SmartDefault;\nuse std::path::Path;\n\n#[deriv"
},
{
"path": "crates/config-lib/src/style/load.rs",
"chars": 4279,
"preview": "use crate::style::ThemeData;\nuse crate::style::structs::Theme;\nuse anyhow::{Context, bail};\nuse core_lib::ini::IniFile;\n"
},
{
"path": "crates/config-lib/src/style/mod.rs",
"chars": 71,
"preview": "mod load;\nmod structs;\n\npub use load::load_themes;\npub use structs::*;\n"
},
{
"path": "crates/config-lib/src/style/structs.rs",
"chars": 341,
"preview": "use std::path::PathBuf;\n\n#[derive(Debug)]\npub struct Theme {\n pub name: String,\n pub path: PathBuf,\n pub style:"
},
{
"path": "crates/core-lib/Cargo.toml",
"chars": 674,
"preview": "[package]\nname = \"hyprshell-core-lib\"\ndocumentation = \"https://docs.rs/hyprshell-core-lib\"\nversion = \"4.9.5\"\nedition.wor"
},
{
"path": "crates/core-lib/src/binds/mod.rs",
"chars": 132,
"preview": "mod structs;\nmod transfer;\n\npub use structs::*;\npub use transfer::{generate_transfer, generate_transfer_socat, get_hyprs"
},
{
"path": "crates/core-lib/src/binds/structs.rs",
"chars": 121,
"preview": "#[derive(Debug)]\npub struct ExecBind {\n pub mods: Vec<&'static str>,\n pub key: Box<str>,\n pub exec: Box<str>,\n}"
},
{
"path": "crates/core-lib/src/binds/transfer.rs",
"chars": 788,
"preview": "use crate::transfer::TransferType;\nuse std::env;\n\n/// # Panics\n/// if the current executable couldn't be found\n#[must_us"
},
{
"path": "crates/core-lib/src/const.rs",
"chars": 543,
"preview": "pub const APPLICATION_ID: &str = \"com.github.h3rmt.hyprshell\";\npub const OVERVIEW_NAMESPACE: &str = \"hyprshell_overview\""
},
{
"path": "crates/core-lib/src/data.rs",
"chars": 1863,
"preview": "pub type WorkspaceId = i32;\npub type MonitorId = i128;\npub type ClientId = u64;\n\n#[derive(Debug, Clone, Copy, Eq, Partia"
},
{
"path": "crates/core-lib/src/default/mod.rs",
"chars": 7128,
"preview": "use crate::ini_owned::IniFileOwned;\nuse crate::util::{collect_desktop_files, collect_mime_files};\nuse anyhow::bail;\nuse "
},
{
"path": "crates/core-lib/src/ini.rs",
"chars": 10736,
"preview": "use std::collections::HashMap;\nuse std::collections::hash_map::Entry;\nuse std::fmt::Write;\nuse std::path::Path;\nuse trac"
},
{
"path": "crates/core-lib/src/ini_owned.rs",
"chars": 10438,
"preview": "use std::collections::HashMap;\nuse std::collections::hash_map::Entry;\nuse std::fmt::Write;\nuse std::path::Path;\nuse trac"
},
{
"path": "crates/core-lib/src/lib.rs",
"chars": 282,
"preview": "pub mod binds;\nmod r#const;\nmod data;\npub mod default;\npub mod ini;\npub mod ini_owned;\npub mod listener;\nmod notify;\npub"
},
{
"path": "crates/core-lib/src/listener.rs",
"chars": 3309,
"preview": "use crate::WarnWithDetails;\nuse anyhow::{Context, bail};\nuse notify::event::{DataChange, ModifyKind};\nuse notify::{Confi"
},
{
"path": "crates/core-lib/src/notify.rs",
"chars": 1009,
"preview": "use notify_rust::{Hint, Notification};\nuse std::time::Duration;\nuse tracing::{info, warn};\n\npub fn notify(body: &str, du"
},
{
"path": "crates/core-lib/src/path.rs",
"chars": 3988,
"preview": "use std::env;\nuse std::path::PathBuf;\nuse tracing::trace;\n\npub fn get_default_config_file() -> PathBuf {\n let mut pat"
},
{
"path": "crates/core-lib/src/transfer/mod.rs",
"chars": 94,
"preview": "mod receive;\nmod send;\nmod structs;\n\npub use receive::*;\npub use send::*;\npub use structs::*;\n"
},
{
"path": "crates/core-lib/src/transfer/receive.rs",
"chars": 540,
"preview": "use crate::transfer::TransferType;\nuse anyhow::Context;\nuse tracing::debug;\n\npub fn receive_from_buffer(mut buffer: Vec<"
},
{
"path": "crates/core-lib/src/transfer/send.rs",
"chars": 1041,
"preview": "use crate::util::get_daemon_socket_path_buff;\nuse anyhow::Context;\nuse std::io::{BufRead, BufReader, Write};\nuse std::os"
},
{
"path": "crates/core-lib/src/transfer/structs.rs",
"chars": 2766,
"preview": "use crate::{ClientId, WorkspaceId};\nuse serde::{Deserialize, Serialize};\n\n#[derive(Debug, Serialize, Deserialize)]\npub e"
},
{
"path": "crates/core-lib/src/util/boot.rs",
"chars": 836,
"preview": "use anyhow::Context;\nuse std::fs::File;\nuse std::io::Read;\nuse std::sync::OnceLock;\nuse tracing::{instrument, warn};\n\npu"
},
{
"path": "crates/core-lib/src/util/exec.rs",
"chars": 5426,
"preview": "#[derive(Debug, Clone)]\npub enum ExecType {\n Flatpak(Box<str>, Box<str>),\n PWA(Box<str>, Box<str>),\n FlatpakPWA"
},
{
"path": "crates/core-lib/src/util/exists.rs",
"chars": 3350,
"preview": "use std::env;\nuse std::env::split_paths;\nuse std::fs;\nuse std::path::{Path, PathBuf};\n\n#[cfg(unix)]\nuse std::os::unix::f"
},
{
"path": "crates/core-lib/src/util/helpers.rs",
"chars": 2236,
"preview": "use std::fmt;\nuse tracing::{debug, warn};\n\npub trait GetFirstOrLast: Iterator + Sized {\n fn get_first_or_last(self, l"
},
{
"path": "crates/core-lib/src/util/mod.rs",
"chars": 1162,
"preview": "mod boot;\nmod exec;\nmod exists;\nmod helpers;\nmod path;\n\npub use boot::*;\npub use exec::*;\npub use exists::*;\npub use hel"
},
{
"path": "crates/core-lib/src/util/path.rs",
"chars": 2690,
"preview": "use crate::path::{get_config_dirs, get_config_home, get_data_dirs, get_data_home};\nuse std::fs::DirEntry;\nuse tracing::{"
},
{
"path": "crates/exec-lib/Cargo.toml",
"chars": 717,
"preview": "[package]\nname = \"hyprshell-exec-lib\"\ndocumentation = \"https://docs.rs/hyprshell-exec-lib\"\nversion = \"4.9.5\"\nedition.wor"
},
{
"path": "crates/exec-lib/src/binds.rs",
"chars": 1888,
"preview": "use anyhow::Context;\nuse core_lib::binds::ExecBind;\nuse core_lib::{LAUNCHER_NAMESPACE, OVERVIEW_NAMESPACE, SWITCH_NAMESP"
},
{
"path": "crates/exec-lib/src/collect.rs",
"chars": 5611,
"preview": "use crate::to_client_id;\nuse anyhow::Context;\nuse core_lib::{\n ClientData, ClientId, FindByFirst, MonitorData, Monito"
},
{
"path": "crates/exec-lib/src/lib.rs",
"chars": 124,
"preview": "pub mod collect;\npub mod listener;\npub mod switch;\nmod util;\n\npub mod binds;\npub mod plugin;\npub mod run;\n\npub use util:"
},
{
"path": "crates/exec-lib/src/listener.rs",
"chars": 1228,
"preview": "use core_lib::WarnWithDetails;\nuse tracing::info;\n\n#[allow(clippy::future_not_send)]\npub async fn monitor_listener<F>(ca"
},
{
"path": "crates/exec-lib/src/plugin.rs",
"chars": 3476,
"preview": "use anyhow::{Context, bail};\nuse config_lib::Modifier;\nuse hyprland::ctl::plugin;\nuse hyprland_plugin::PluginConfig;\nuse"
},
{
"path": "crates/exec-lib/src/run.rs",
"chars": 3400,
"preview": "use anyhow::{Context, bail};\nuse core_lib::TERMINALS;\nuse std::ffi::OsString;\nuse std::os::unix::prelude::CommandExt;\nus"
},
{
"path": "crates/exec-lib/src/switch.rs",
"chars": 3717,
"preview": "use anyhow::Context;\nuse core_lib::Warn;\nuse hyprland::data::{Client, Monitors, Workspace, Workspaces};\nuse hyprland::di"
},
{
"path": "crates/exec-lib/src/util.rs",
"chars": 5312,
"preview": "use anyhow::{Context, anyhow};\nuse core_lib::{Active, ClientId, notify_warn};\nuse hyprland::ctl::reload;\nuse hyprland::d"
},
{
"path": "crates/hyprland-plugin/Cargo.toml",
"chars": 723,
"preview": "[package]\nname = \"hyprshell-hyprland-plugin\"\ndocumentation = \"https://docs.rs/hyprshell-hyprland-plugin\"\nversion = \"4.9."
},
{
"path": "crates/hyprland-plugin/build.rs",
"chars": 3422,
"preview": "use std::fs::read_dir;\nuse std::io::{Read, Write};\nuse std::path::PathBuf;\nuse std::{env, fs, fs::File, io, path::Path};"
},
{
"path": "crates/hyprland-plugin/plugin/.gitignore",
"chars": 16,
"preview": "out\nhyprshell.so"
},
{
"path": "crates/hyprland-plugin/plugin/.idea/copilot.data.migration.agent.xml",
"chars": 190,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"AgentMigrationStateService\">\n <option"
},
{
"path": "crates/hyprland-plugin/plugin/.idea/copilot.data.migration.ask2agent.xml",
"chars": 194,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"Ask2AgentMigrationStateService\">\n <op"
},
{
"path": "crates/hyprland-plugin/plugin/.idea/copilot.data.migration.edit.xml",
"chars": 189,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"EditMigrationStateService\">\n <option "
},
{
"path": "crates/hyprland-plugin/plugin/.idea/dictionaries/project.xml",
"chars": 148,
"preview": "<component name=\"ProjectDictionaryState\">\n <dictionary name=\"project\">\n <words>\n <w>combinded</w>\n </words>\n"
},
{
"path": "crates/hyprland-plugin/plugin/.idea/editor.xml",
"chars": 52798,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"BackendCodeEditorSettings\">\n <option "
},
{
"path": "crates/hyprland-plugin/plugin/.idea/misc.xml",
"chars": 852,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"CidrRootsConfiguration\">\n <sourceRoot"
},
{
"path": "crates/hyprland-plugin/plugin/.idea/vcs.xml",
"chars": 189,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"VcsDirectoryMappings\">\n <mapping dire"
},
{
"path": "crates/hyprland-plugin/plugin/.idea/workspace.xml",
"chars": 29355,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"AutoImportSettings\">\n <option name=\"a"
},
{
"path": "crates/hyprland-plugin/plugin/Makefile",
"chars": 1584,
"preview": "SHELL := /bin/bash\n\n.PHONY: all clean combine prepare-combined copy-defs build build-combined test test-combined\n\nSRCS_D"
},
{
"path": "crates/hyprland-plugin/plugin/README.md",
"chars": 448,
"preview": "# Plugin build at runtime of Hyprshell\n\nThe Makefile includes all necessary steps to develop.\n\nFor performance reasons a"
},
{
"path": "crates/hyprland-plugin/plugin/src-52/defs-test.h",
"chars": 613,
"preview": "#pragma once\n\n#define HYPRSHELL_PLUGIN_NAME \"HYPSHELL PLUGIN TEST\"\n\n#define HYPRSHELL_PRINT_DEBUG 1\n#define HYPRSHELL_SO"
},
{
"path": "crates/hyprland-plugin/plugin/src-52/defs.h",
"chars": 1272,
"preview": "#pragma once\n\n#include <hyprland/src/plugins/PluginAPI.hpp>\n\nconst CHyprColor RED{1.0, 0.2, 0.2, 1.0};\nconst CHyprColor "
},
{
"path": "crates/hyprland-plugin/plugin/src-52/exit.cpp",
"chars": 191,
"preview": "#include \"globals.h\"\n\nvoid exit() {\n if constexpr (HYPRSHELL_PRINT_DEBUG == 1) {\n HyprlandAPI::addNotification"
},
{
"path": "crates/hyprland-plugin/plugin/src-52/globals.h",
"chars": 423,
"preview": "#pragma once\n#include <hyprland/src/devices/IPointer.hpp>\n#include <hyprland/src/desktop/view/LayerSurface.hpp>\n#include"
},
{
"path": "crates/hyprland-plugin/plugin/src-52/handlers.h",
"chars": 431,
"preview": "#pragma once\n#include <hyprland/src/devices/IPointer.hpp>\n#include <hyprland/src/desktop/view/LayerSurface.hpp>\n#include"
},
{
"path": "crates/hyprland-plugin/plugin/src-52/init.cpp",
"chars": 3120,
"preview": "#include \"globals.h\"\n#include \"handlers.h\"\n#include \"defs.h\"\n\nPluginDescriptionInfo init(HANDLE handle) {\n PHANDLE = "
},
{
"path": "crates/hyprland-plugin/plugin/src-52/key-press.cpp",
"chars": 8290,
"preview": "#include <strings.h>\n#include <hyprland/src/plugins/PluginAPI.hpp>\n#include <hyprland/src/devices/IKeyboard.hpp>\n#includ"
},
{
"path": "crates/hyprland-plugin/plugin/src-52/keyboard-focus.cpp",
"chars": 341,
"preview": "#include \"globals.h\"\n#include <hyprland/src/desktop/view/LayerSurface.hpp>\n\nvoid onKeyboardFocus(const SP<CWLSurfaceReso"
},
{
"path": "crates/hyprland-plugin/plugin/src-52/layer-change.cpp",
"chars": 457,
"preview": "#include <hyprland/src/plugins/PluginAPI.hpp>\n#include <hyprland/src/desktop/view/LayerSurface.hpp>\n\n#include \"globals.h"
},
{
"path": "crates/hyprland-plugin/plugin/src-52/main.cpp",
"chars": 425,
"preview": "#include <hyprland/src/plugins/PluginAPI.hpp>\n#include \"globals.h\"\n\n// Do NOT change this function.\nAPICALL EXPORT std::"
},
{
"path": "crates/hyprland-plugin/plugin/src-52/mouse-button.cpp",
"chars": 336,
"preview": "#include <hyprland/src/devices/IPointer.hpp>\n\n#include \"globals.h\"\n\nvoid onMouseButton(const IPointer::SButtonEvent even"
},
{
"path": "crates/hyprland-plugin/plugin/src-52/send.cpp",
"chars": 589,
"preview": "#include \"send.h\"\n\n#include <sys/socket.h>\n#include <sys/un.h>\n#include <cstring>\n\n#include \"defs.h\"\n\nvoid sendStringToH"
},
{
"path": "crates/hyprland-plugin/plugin/src-52/send.h",
"chars": 94,
"preview": "#pragma once\n#include <string>\n\nvoid sendStringToHyprshellSocket(const std::string &message);\n"
},
{
"path": "crates/hyprland-plugin/plugin/src-54/defs-test.h",
"chars": 613,
"preview": "#pragma once\n\n#define HYPRSHELL_PLUGIN_NAME \"HYPSHELL PLUGIN TEST\"\n\n#define HYPRSHELL_PRINT_DEBUG 1\n#define HYPRSHELL_SO"
},
{
"path": "crates/hyprland-plugin/plugin/src-54/defs.h",
"chars": 1272,
"preview": "#pragma once\n\n#include <hyprland/src/plugins/PluginAPI.hpp>\n\nconst CHyprColor RED{1.0, 0.2, 0.2, 1.0};\nconst CHyprColor "
},
{
"path": "crates/hyprland-plugin/plugin/src-54/exit.cpp",
"chars": 191,
"preview": "#include \"globals.h\"\n\nvoid exit() {\n if constexpr (HYPRSHELL_PRINT_DEBUG == 1) {\n HyprlandAPI::addNotification"
},
{
"path": "crates/hyprland-plugin/plugin/src-54/globals.h",
"chars": 369,
"preview": "#pragma once\n#include <hyprland/src/plugins/PluginAPI.hpp>\n#include <hyprland/src/devices/IKeyboard.hpp>\n\n#include \"defs"
},
{
"path": "crates/hyprland-plugin/plugin/src-54/handlers.h",
"chars": 431,
"preview": "#pragma once\n#include <hyprland/src/devices/IPointer.hpp>\n#include <hyprland/src/desktop/view/LayerSurface.hpp>\n#include"
},
{
"path": "crates/hyprland-plugin/plugin/src-54/init.cpp",
"chars": 2803,
"preview": "#include \"globals.h\"\n#include \"handlers.h\"\n#include \"defs.h\"\n\n#include <hyprland/src/event/EventBus.hpp>\n#include <hyprl"
},
{
"path": "crates/hyprland-plugin/plugin/src-54/key-press.cpp",
"chars": 8175,
"preview": "#include <strings.h>\n#include <hyprland/src/plugins/PluginAPI.hpp>\n#include <hyprland/src/devices/IKeyboard.hpp>\n#includ"
},
{
"path": "crates/hyprland-plugin/plugin/src-54/keyboard-focus.cpp",
"chars": 341,
"preview": "#include \"globals.h\"\n#include <hyprland/src/desktop/view/LayerSurface.hpp>\n\nvoid onKeyboardFocus(const SP<CWLSurfaceReso"
},
{
"path": "crates/hyprland-plugin/plugin/src-54/layer-change.cpp",
"chars": 457,
"preview": "#include <hyprland/src/plugins/PluginAPI.hpp>\n#include <hyprland/src/desktop/view/LayerSurface.hpp>\n\n#include \"globals.h"
},
{
"path": "crates/hyprland-plugin/plugin/src-54/main.cpp",
"chars": 425,
"preview": "#include <hyprland/src/plugins/PluginAPI.hpp>\n#include \"globals.h\"\n\n// Do NOT change this function.\nAPICALL EXPORT std::"
},
{
"path": "crates/hyprland-plugin/plugin/src-54/mouse-button.cpp",
"chars": 401,
"preview": "#include <hyprland/src/devices/IPointer.hpp>\n#include <hyprland/src/event/EventBus.hpp>\n\n#include \"globals.h\"\n\nvoid onMo"
},
{
"path": "crates/hyprland-plugin/plugin/src-54/send.cpp",
"chars": 589,
"preview": "#include \"send.h\"\n\n#include <sys/socket.h>\n#include <sys/un.h>\n#include <cstring>\n\n#include \"defs.h\"\n\nvoid sendStringToH"
},
{
"path": "crates/hyprland-plugin/plugin/src-54/send.h",
"chars": 94,
"preview": "#pragma once\n#include <string>\n\nvoid sendStringToHyprshellSocket(const std::string &message);\n"
},
{
"path": "crates/hyprland-plugin/plugin/test-hyprland.conf",
"chars": 1424,
"preview": "monitor=,preferred,auto,1\n\nenv = XCURSOR_SIZE,24\nenv = HYPRCURSOR_SIZE,24\n\n# https://wiki.hyprland.org/Configuring/Varia"
},
{
"path": "crates/hyprland-plugin/src/build.rs",
"chars": 1476,
"preview": "use crate::PLUGIN_OUTPUT_PATH;\nuse anyhow::{Context, bail};\nuse std::env;\nuse std::process::{Command, Stdio};\nuse tempfi"
},
{
"path": "crates/hyprland-plugin/src/configure.rs",
"chars": 4108,
"preview": "use crate::{PLUGIN_AUTHOR, PLUGIN_DESC, PLUGIN_NAME, PLUGIN_VERSION};\nuse anyhow::Context;\nuse core_lib::binds::generate"
},
{
"path": "crates/hyprland-plugin/src/extract.rs",
"chars": 1124,
"preview": "use crate::ASSET_ZIP_52;\nuse crate::ASSET_ZIP_54;\nuse std::fs::File;\nuse std::io::{Cursor, copy};\nuse tempfile::TempDir;"
},
{
"path": "crates/hyprland-plugin/src/lib.rs",
"chars": 1112,
"preview": "mod build;\nmod configure;\nmod extract;\nmod test;\n\nuse anyhow::Context;\nuse tracing::{debug_span, trace};\n\npub const PLUG"
},
{
"path": "crates/hyprland-plugin/src/test.rs",
"chars": 946,
"preview": "#[cfg(test)]\nmod tests {\n use crate::{PluginConfig, build, configure, extract};\n use tracing::info;\n\n #[test_lo"
},
{
"path": "crates/launcher-lib/Cargo.toml",
"chars": 773,
"preview": "[package]\nname = \"hyprshell-launcher-lib\"\ndocumentation = \"https://docs.rs/hyprshell-launcher-lib\"\nversion = \"4.9.5\"\nedi"
},
{
"path": "crates/launcher-lib/src/close.rs",
"chars": 3590,
"preview": "use crate::plugins::PluginReturn;\nuse crate::{LauncherData, plugins};\nuse core_lib::transfer::Identifier;\nuse gtk4_layer"
},
{
"path": "crates/launcher-lib/src/create.rs",
"chars": 12660,
"preview": "use crate::global::{LauncherConfig, LauncherData};\nuse crate::plugins;\nuse crate::plugins::get_static_options_chars;\nuse"
},
{
"path": "crates/launcher-lib/src/css.rs",
"chars": 515,
"preview": "use anyhow::Context;\nuse relm4::adw::gtk::gdk::Display;\nuse relm4::adw::gtk::{\n CssProvider, STYLE_PROVIDER_PRIORITY_"
},
{
"path": "crates/launcher-lib/src/debug.rs",
"chars": 1158,
"preview": "#![allow(clippy::print_stderr, clippy::print_stdout)]\n\nuse crate::plugins::get_sortable_launch_options;\nuse crate::reloa"
},
{
"path": "crates/launcher-lib/src/global.rs",
"chars": 847,
"preview": "use config_lib::{Modifier, Plugins};\nuse core_lib::transfer::Identifier;\nuse relm4::gtk;\nuse std::collections::HashMap;\n"
},
{
"path": "crates/launcher-lib/src/lib.rs",
"chars": 460,
"preview": "mod close;\nmod create;\nmod css;\npub mod debug;\nmod global;\nmod open;\nmod plugins;\nmod stop;\nmod update;\n\npub use close::"
},
{
"path": "crates/launcher-lib/src/open.rs",
"chars": 920,
"preview": "use crate::LauncherData;\nuse gtk4_layer_shell::{KeyboardMode, LayerShell};\nuse relm4::adw::gtk::glib;\nuse relm4::adw::gt"
},
{
"path": "crates/launcher-lib/src/plugins/actions.rs",
"chars": 3099,
"preview": "use crate::plugins::{Identifier, PluginNames, PluginReturn, SortableLaunchOption};\nuse config_lib::actions::ToAction;\nus"
},
{
"path": "crates/launcher-lib/src/plugins/applications/data.rs",
"chars": 3441,
"preview": "use anyhow::Context;\nuse chrono::{DateTime, Datelike, Utc};\nuse serde_json::from_reader;\nuse std::collections::HashMap;\n"
},
{
"path": "crates/launcher-lib/src/plugins/applications/map.rs",
"chars": 4832,
"preview": "use anyhow::Context;\nuse core_lib::default::get_all_desktop_files;\nuse core_lib::util::{ExecType, analyse_exec};\nuse std"
},
{
"path": "crates/launcher-lib/src/plugins/applications/mod.rs",
"chars": 173,
"preview": "mod data;\nmod map;\nmod plugin;\n\npub use data::get_stored_runs;\npub use map::reload_desktop_entries_map;\npub use plugin::"
},
{
"path": "crates/launcher-lib/src/plugins/applications/plugin.rs",
"chars": 7604,
"preview": "use crate::plugins::applications::data::{get_stored_runs, save_run};\nuse crate::plugins::applications::map::{DesktopEntr"
},
{
"path": "crates/launcher-lib/src/plugins/calc.rs",
"chars": 4921,
"preview": "use crate::plugins::{Identifier, PluginNames, SortableLaunchOption};\nuse core_lib::WarnWithDetails;\nuse relm4::adw::gtk:"
},
{
"path": "crates/launcher-lib/src/plugins/mod.rs",
"chars": 5112,
"preview": "use config_lib::Plugins;\nuse relm4::adw::gtk::gdk::Key;\nuse std::path::Path;\nuse tracing::debug_span;\n\nmod actions;\nmod "
},
{
"path": "crates/launcher-lib/src/plugins/path.rs",
"chars": 3264,
"preview": "use crate::plugins::{Identifier, PluginNames, PluginReturn, SortableLaunchOption};\nuse core_lib::WarnWithDetails;\nuse co"
},
{
"path": "crates/launcher-lib/src/plugins/search.rs",
"chars": 4953,
"preview": "use crate::plugins::{Identifier, PluginNames, PluginReturn, StaticLaunchOption};\nuse config_lib::SearchEngine;\nuse core_"
},
{
"path": "crates/launcher-lib/src/plugins/shell.rs",
"chars": 1044,
"preview": "use crate::plugins::{Identifier, PluginNames, PluginReturn, StaticLaunchOption};\nuse core_lib::WarnWithDetails;\nuse exec"
},
{
"path": "crates/launcher-lib/src/plugins/terminal.rs",
"chars": 1547,
"preview": "use crate::plugins::{Identifier, PluginNames, PluginReturn, StaticLaunchOption};\nuse core_lib::WarnWithDetails;\nuse exec"
},
{
"path": "crates/launcher-lib/src/stop.rs",
"chars": 274,
"preview": "use crate::LauncherData;\nuse relm4::adw::gtk::prelude::*;\nuse tracing::{debug_span, trace};\n\npub fn stop_launcher(data: "
},
{
"path": "crates/launcher-lib/src/styles.css",
"chars": 3273,
"preview": ".launcher {\n padding: var(--window-padding, 2px);\n\n box-shadow: 0 0 16px 5px var(--bg-window-color, rgba(20, 30, 4"
},
{
"path": "crates/launcher-lib/src/update.rs",
"chars": 9820,
"preview": "use crate::LauncherData;\nuse crate::plugins::{\n SortableLaunchOption, StaticLaunchOption, get_sortable_launch_options"
},
{
"path": "crates/windows-lib/Cargo.toml",
"chars": 639,
"preview": "[package]\nname = \"hyprshell-windows-lib\"\ndocumentation = \"https://docs.rs/hyprshell-windows-lib\"\nversion = \"4.9.5\"\nediti"
},
{
"path": "crates/windows-lib/src/css.rs",
"chars": 515,
"preview": "use anyhow::Context;\nuse relm4::adw::gtk::gdk::Display;\nuse relm4::adw::gtk::{\n CssProvider, STYLE_PROVIDER_PRIORITY_"
},
{
"path": "crates/windows-lib/src/data.rs",
"chars": 3377,
"preview": "use crate::sort::{\n sort_clients_by_position, sort_clients_by_recent, sort_monitor_by_x,\n sort_workspaces_by_posit"
},
{
"path": "crates/windows-lib/src/desktop_map.rs",
"chars": 4870,
"preview": "use anyhow::Context;\nuse core_lib::default::get_all_desktop_files;\nuse std::collections::HashMap;\nuse std::path::Path;\nu"
},
{
"path": "crates/windows-lib/src/global.rs",
"chars": 1746,
"preview": "use core_lib::{Active, ClientId, HyprlandData, MonitorId, WorkspaceId};\nuse relm4::adw::gtk::{ApplicationWindow, Button,"
},
{
"path": "crates/windows-lib/src/icon.rs",
"chars": 2794,
"preview": "use crate::desktop_map::{add_path_for_icon_by_pid_exec, get_icon_name_by_name_from_desktop_files};\nuse core_lib::{WarnWi"
},
{
"path": "crates/windows-lib/src/keybinds.rs",
"chars": 1382,
"preview": "use config_lib::Windows;\nuse core_lib::binds::{ExecBind, generate_transfer_socat};\nuse core_lib::transfer::{OpenSwitch, "
},
{
"path": "crates/windows-lib/src/lib.rs",
"chars": 664,
"preview": "mod css;\nmod data;\nmod desktop_map;\nmod global;\nmod icon;\nmod keybinds;\nmod next;\nmod overview;\nmod sort;\nmod switch;\n\np"
},
{
"path": "crates/windows-lib/src/next.rs",
"chars": 19133,
"preview": "use core_lib::transfer::Direction;\nuse core_lib::{\n Active, ClientData, ClientId, GetFirstOrLast, HyprlandData, RevIf"
},
{
"path": "crates/windows-lib/src/overview/close.rs",
"chars": 2853,
"preview": "use crate::global::WindowsOverviewData;\nuse core_lib::transfer::WindowsOverride;\nuse core_lib::{FindByFirst, WarnWithDet"
}
]
// ... and 131 more files (download for full content)
About this extraction
This page contains the full source code of the H3rmt/hyprswitch GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 331 files (1.2 MB), approximately 316.8k tokens, and a symbol index with 1370 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.