Merge branch 'hyprwm:main' into main
19
.github/ISSUE_TEMPLATE/bug.yml
vendored
|
@ -2,12 +2,13 @@ name: Bug Report
|
||||||
description: Something is not working right
|
description: Something is not working right
|
||||||
labels: ["bug"]
|
labels: ["bug"]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: checkboxes
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
label: Already reported ? *
|
||||||
## Before opening a new issue, please take a moment to search through the current open and closed issues to check if it already exists.
|
description: Before opening a new bug report, please take a moment to search through the current open and closed issues to check if it already exists.
|
||||||
|
options:
|
||||||
---
|
- label: I have searched the existing open and closed issues.
|
||||||
|
required: true
|
||||||
|
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
id: type
|
id: type
|
||||||
|
@ -28,10 +29,10 @@ body:
|
||||||
attributes:
|
attributes:
|
||||||
label: System Info and Version
|
label: System Info and Version
|
||||||
description: |
|
description: |
|
||||||
Paste the output of `hyprctl systeminfo -c` here (If you are on a
|
Paste the output of `hyprctl systeminfo -c` here. If you can't
|
||||||
version that shows you help menu, omit the `-c` and attach config files
|
launch Hyprland, paste the output of `Hyprland --systeminfo`.
|
||||||
to the issue). If you have configs outside of the main config shown
|
If `Hyprland --systeminfo` errors out (added in 0.44.0), find
|
||||||
here, please attach.
|
and paste the Hyprland version manually.
|
||||||
value: "<details>
|
value: "<details>
|
||||||
<summary>System/Version info</summary>
|
<summary>System/Version info</summary>
|
||||||
|
|
||||||
|
|
16
.github/workflows/nix-build.yml
vendored
|
@ -1,3 +1,5 @@
|
||||||
|
name: Nix (Build)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
secrets:
|
secrets:
|
||||||
|
@ -10,21 +12,17 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
package:
|
package:
|
||||||
- hyprland
|
- hyprland
|
||||||
|
- hyprland-cross
|
||||||
- xdg-desktop-portal-hyprland
|
- xdg-desktop-portal-hyprland
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- uses: DeterminateSystems/nix-installer-action@main
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: ${{ github.ref }}
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- uses: cachix/install-nix-action@v27
|
|
||||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||||
|
|
||||||
- uses: cachix/cachix-action@v15
|
- uses: cachix/cachix-action@v15
|
||||||
with:
|
with:
|
||||||
name: hyprland
|
name: hyprland
|
||||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||||
|
|
||||||
- run: nix build '.?submodules=1#${{ matrix.package }}' -L --extra-substituters "https://hyprland.cachix.org"
|
- run: nix build 'github:hyprwm/Hyprland?ref=${{ github.ref }}#${{ matrix.package }}' -L --extra-substituters "https://hyprland.cachix.org"
|
||||||
|
|
7
.github/workflows/nix-ci.yml
vendored
|
@ -1,15 +1,14 @@
|
||||||
name: Nix
|
name: Nix (CI)
|
||||||
|
|
||||||
on: [push, pull_request, workflow_dispatch]
|
on: [push, pull_request, workflow_dispatch]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update-inputs:
|
update-inputs:
|
||||||
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
|
||||||
uses: ./.github/workflows/nix-update-inputs.yml
|
uses: ./.github/workflows/nix-update-inputs.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
build:
|
build:
|
||||||
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork) && !contains(needs.*.result, 'failure')
|
if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork)
|
||||||
needs: update-inputs
|
|
||||||
uses: ./.github/workflows/nix-build.yml
|
uses: ./.github/workflows/nix-build.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
3
.github/workflows/nix-update-inputs.yml
vendored
|
@ -1,4 +1,4 @@
|
||||||
name: Nix
|
name: Nix (Update Inputs)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
@ -8,6 +8,7 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update:
|
update:
|
||||||
|
if: github.repository == 'hyprwm/Hyprland'
|
||||||
name: inputs
|
name: inputs
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
1
.github/workflows/release.yaml
vendored
|
@ -20,7 +20,6 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
git fetch --unshallow || echo "failed unshallowing"
|
git fetch --unshallow || echo "failed unshallowing"
|
||||||
bash -c scripts/generateVersion.sh
|
bash -c scripts/generateVersion.sh
|
||||||
mv scripts/generateVersion.sh scripts/generateVersion.sh.bak
|
|
||||||
|
|
||||||
- name: Create tarball with submodules
|
- name: Create tarball with submodules
|
||||||
id: tar
|
id: tar
|
||||||
|
|
8
.github/workflows/stale.yml
vendored
|
@ -7,12 +7,12 @@ name: Mark stale issues and pull requests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '7 */4 * * *'
|
- cron: "7 */4 * * *"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
stale:
|
stale:
|
||||||
|
if: github.repository == 'hyprwm/Hyprland'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
issues: write
|
issues: write
|
||||||
|
@ -22,7 +22,7 @@ jobs:
|
||||||
- uses: actions/stale@v5
|
- uses: actions/stale@v5
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.STALEBOT_PAT }}
|
repo-token: ${{ secrets.STALEBOT_PAT }}
|
||||||
stale-issue-label: 'stale'
|
stale-issue-label: "stale"
|
||||||
stale-pr-label: 'stale'
|
stale-pr-label: "stale"
|
||||||
operations-per-run: 40
|
operations-per-run: 40
|
||||||
days-before-close: -1
|
days-before-close: -1
|
||||||
|
|
6
.gitignore
vendored
|
@ -14,6 +14,7 @@ _deps
|
||||||
|
|
||||||
build/
|
build/
|
||||||
result*
|
result*
|
||||||
|
/.pre-commit-config.yaml
|
||||||
/.vscode/
|
/.vscode/
|
||||||
/.idea/
|
/.idea/
|
||||||
.envrc
|
.envrc
|
||||||
|
@ -37,3 +38,8 @@ gmon.out
|
||||||
PKGBUILD
|
PKGBUILD
|
||||||
|
|
||||||
src/version.h
|
src/version.h
|
||||||
|
hyprpm/Makefile
|
||||||
|
hyprctl/Makefile
|
||||||
|
|
||||||
|
**/.#*.*
|
||||||
|
**/#*.*#
|
||||||
|
|
103
CMakeLists.txt
|
@ -1,4 +1,4 @@
|
||||||
cmake_minimum_required(VERSION 3.27)
|
cmake_minimum_required(VERSION 3.30)
|
||||||
|
|
||||||
# Get version
|
# Get version
|
||||||
file(READ "${CMAKE_SOURCE_DIR}/VERSION" VER_RAW)
|
file(READ "${CMAKE_SOURCE_DIR}/VERSION" VER_RAW)
|
||||||
|
@ -25,8 +25,18 @@ message(STATUS "Gathering git info")
|
||||||
execute_process(COMMAND ./scripts/generateVersion.sh
|
execute_process(COMMAND ./scripts/generateVersion.sh
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||||
|
|
||||||
# udis
|
find_package(PkgConfig REQUIRED)
|
||||||
|
|
||||||
|
# Try to find canihavesomecoffee's udis86 using pkgconfig vmd/udis86 does not
|
||||||
|
# provide a .pc file and won't be detected this way
|
||||||
|
pkg_check_modules(udis_dep IMPORTED_TARGET udis86>=1.7.2)
|
||||||
|
|
||||||
|
# Fallback to subproject
|
||||||
|
if(NOT udis_dep_FOUND)
|
||||||
add_subdirectory("subprojects/udis86")
|
add_subdirectory("subprojects/udis86")
|
||||||
|
include_directories("subprojects/udis86")
|
||||||
|
message(STATUS "udis86 dependency not found, falling back to subproject")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE)
|
if(CMAKE_BUILD_TYPE)
|
||||||
string(TOLOWER ${CMAKE_BUILD_TYPE} BUILDTYPE_LOWER)
|
string(TOLOWER ${CMAKE_BUILD_TYPE} BUILDTYPE_LOWER)
|
||||||
|
@ -47,11 +57,11 @@ else()
|
||||||
set(BUILDTYPE_LOWER "release")
|
set(BUILDTYPE_LOWER "release")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
|
||||||
|
|
||||||
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
|
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
|
||||||
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
|
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
|
||||||
pkg_get_variable(WAYLAND_SERVER_DIR wayland-server pkgdatadir)
|
pkg_get_variable(WAYLAND_SCANNER_PKGDATA_DIR wayland-scanner pkgdatadir)
|
||||||
|
message(
|
||||||
|
STATUS "Found wayland-scanner pkgdatadir at ${WAYLAND_SCANNER_PKGDATA_DIR}")
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||||
message(STATUS "Configuring Hyprland in Debug with CMake")
|
message(STATUS "Configuring Hyprland in Debug with CMake")
|
||||||
|
@ -61,8 +71,11 @@ else()
|
||||||
message(STATUS "Configuring Hyprland in Release with CMake")
|
message(STATUS "Configuring Hyprland in Release with CMake")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories(. "src/" "subprojects/udis86/" "protocols/")
|
add_compile_definitions(HYPRLAND_VERSION="${HYPRLAND_VERSION}")
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
|
||||||
|
include_directories(. "src/" "protocols/")
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 26)
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
-Wall
|
-Wall
|
||||||
-Wextra
|
-Wextra
|
||||||
|
@ -87,16 +100,19 @@ else()
|
||||||
endif()
|
endif()
|
||||||
find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION})
|
find_package(OpenGL REQUIRED COMPONENTS ${GLES_VERSION})
|
||||||
|
|
||||||
|
pkg_check_modules(hyprctl_deps REQUIRED IMPORTED_TARGET hyprutils>=0.2.1)
|
||||||
|
|
||||||
|
pkg_check_modules(aquamarine_dep REQUIRED IMPORTED_TARGET aquamarine>=0.4.2)
|
||||||
|
|
||||||
|
add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}")
|
||||||
|
|
||||||
pkg_check_modules(
|
pkg_check_modules(
|
||||||
deps
|
deps
|
||||||
REQUIRED
|
REQUIRED
|
||||||
IMPORTED_TARGET
|
IMPORTED_TARGET
|
||||||
aquamarine
|
|
||||||
xkbcommon
|
xkbcommon
|
||||||
uuid
|
uuid
|
||||||
wayland-server
|
wayland-server>=1.22.90
|
||||||
wayland-client
|
|
||||||
wayland-cursor
|
|
||||||
wayland-protocols
|
wayland-protocols
|
||||||
cairo
|
cairo
|
||||||
pango
|
pango
|
||||||
|
@ -105,15 +121,11 @@ pkg_check_modules(
|
||||||
xcursor
|
xcursor
|
||||||
libdrm
|
libdrm
|
||||||
libinput
|
libinput
|
||||||
hwdata
|
|
||||||
libseat
|
|
||||||
libdisplay-info
|
|
||||||
libliftoff
|
|
||||||
libudev
|
|
||||||
gbm
|
gbm
|
||||||
|
gio-2.0
|
||||||
hyprlang>=0.3.2
|
hyprlang>=0.3.2
|
||||||
hyprcursor>=0.1.7
|
hyprcursor>=0.1.7
|
||||||
hyprutils>=0.2.1)
|
hyprutils>=0.2.3)
|
||||||
|
|
||||||
find_package(hyprwayland-scanner 0.3.10 REQUIRED)
|
find_package(hyprwayland-scanner 0.3.10 REQUIRED)
|
||||||
|
|
||||||
|
@ -195,14 +207,11 @@ else()
|
||||||
REQUIRED
|
REQUIRED
|
||||||
IMPORTED_TARGET
|
IMPORTED_TARGET
|
||||||
xcb
|
xcb
|
||||||
xwayland
|
|
||||||
xcb-util
|
|
||||||
xcb-render
|
xcb-render
|
||||||
xcb-xfixes
|
xcb-xfixes
|
||||||
xcb-icccm
|
xcb-icccm
|
||||||
xcb-composite
|
xcb-composite
|
||||||
xcb-res
|
xcb-res
|
||||||
xcb-ewmh
|
|
||||||
xcb-errors)
|
xcb-errors)
|
||||||
target_link_libraries(Hyprland PkgConfig::xdeps)
|
target_link_libraries(Hyprland PkgConfig::xdeps)
|
||||||
endif()
|
endif()
|
||||||
|
@ -225,14 +234,19 @@ target_precompile_headers(Hyprland PRIVATE
|
||||||
|
|
||||||
message(STATUS "Setting link libraries")
|
message(STATUS "Setting link libraries")
|
||||||
|
|
||||||
target_link_libraries(Hyprland rt PkgConfig::deps)
|
target_link_libraries(Hyprland rt PkgConfig::aquamarine_dep PkgConfig::deps)
|
||||||
|
if(udis_dep_FOUND)
|
||||||
|
target_link_libraries(Hyprland PkgConfig::udis_dep)
|
||||||
|
else()
|
||||||
|
target_link_libraries(Hyprland libudis86)
|
||||||
|
endif()
|
||||||
|
|
||||||
# used by `make installheaders`, to ensure the headers are generated
|
# used by `make installheaders`, to ensure the headers are generated
|
||||||
add_custom_target(generate-protocol-headers)
|
add_custom_target(generate-protocol-headers)
|
||||||
|
|
||||||
function(protocolnew protoPath protoName external)
|
function(protocolnew protoPath protoName external)
|
||||||
if(external)
|
if(external)
|
||||||
set(path ${CMAKE_SOURCE_DIR}/${protoPath})
|
set(path ${protoPath})
|
||||||
else()
|
else()
|
||||||
set(path ${WAYLAND_PROTOCOLS_DIR}/${protoPath})
|
set(path ${WAYLAND_PROTOCOLS_DIR}/${protoPath})
|
||||||
endif()
|
endif()
|
||||||
|
@ -251,22 +265,31 @@ function(protocolWayland)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${CMAKE_SOURCE_DIR}/protocols/wayland.cpp
|
OUTPUT ${CMAKE_SOURCE_DIR}/protocols/wayland.cpp
|
||||||
${CMAKE_SOURCE_DIR}/protocols/wayland.hpp
|
${CMAKE_SOURCE_DIR}/protocols/wayland.hpp
|
||||||
COMMAND hyprwayland-scanner --wayland-enums
|
COMMAND
|
||||||
${WAYLAND_SERVER_DIR}/wayland.xml ${CMAKE_SOURCE_DIR}/protocols/
|
hyprwayland-scanner --wayland-enums
|
||||||
|
${WAYLAND_SCANNER_PKGDATA_DIR}/wayland.xml ${CMAKE_SOURCE_DIR}/protocols/
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||||
target_sources(Hyprland PRIVATE protocols/wayland.cpp protocols/wayland.hpp)
|
target_sources(Hyprland PRIVATE protocols/wayland.cpp protocols/wayland.hpp)
|
||||||
target_sources(generate-protocol-headers
|
target_sources(generate-protocol-headers
|
||||||
PRIVATE ${CMAKE_SOURCE_DIR}/protocols/wayland.hpp)
|
PRIVATE ${CMAKE_SOURCE_DIR}/protocols/wayland.hpp)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
target_link_libraries(Hyprland OpenGL::EGL OpenGL::GL Threads::Threads
|
target_link_libraries(Hyprland OpenGL::EGL OpenGL::GL Threads::Threads)
|
||||||
libudis86 uuid)
|
|
||||||
|
|
||||||
protocolnew("subprojects/hyprland-protocols/protocols"
|
pkg_check_modules(hyprland_protocols_dep hyprland-protocols>=0.4.0)
|
||||||
"hyprland-global-shortcuts-v1" true)
|
if(hyprland_protocols_dep_FOUND)
|
||||||
|
pkg_get_variable(HYPRLAND_PROTOCOLS hyprland-protocols pkgdatadir)
|
||||||
|
message(STATUS "hyprland-protocols dependency set to ${HYPRLAND_PROTOCOLS}")
|
||||||
|
else()
|
||||||
|
set(HYPRLAND_PROTOCOLS "subprojects/hyprland-protocols")
|
||||||
|
message(STATUS "hyprland-protocols subproject set to ${HYPRLAND_PROTOCOLS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-global-shortcuts-v1"
|
||||||
|
true)
|
||||||
protocolnew("unstable/text-input" "text-input-unstable-v1" false)
|
protocolnew("unstable/text-input" "text-input-unstable-v1" false)
|
||||||
protocolnew("subprojects/hyprland-protocols/protocols"
|
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-toplevel-export-v1"
|
||||||
"hyprland-toplevel-export-v1" true)
|
true)
|
||||||
protocolnew("protocols" "wlr-screencopy-unstable-v1" true)
|
protocolnew("protocols" "wlr-screencopy-unstable-v1" true)
|
||||||
protocolnew("protocols" "wlr-gamma-control-unstable-v1" true)
|
protocolnew("protocols" "wlr-gamma-control-unstable-v1" true)
|
||||||
protocolnew("protocols" "wlr-foreign-toplevel-management-unstable-v1" true)
|
protocolnew("protocols" "wlr-foreign-toplevel-management-unstable-v1" true)
|
||||||
|
@ -277,10 +300,11 @@ protocolnew("protocols" "input-method-unstable-v2" true)
|
||||||
protocolnew("protocols" "wlr-output-management-unstable-v1" true)
|
protocolnew("protocols" "wlr-output-management-unstable-v1" true)
|
||||||
protocolnew("protocols" "kde-server-decoration" true)
|
protocolnew("protocols" "kde-server-decoration" true)
|
||||||
protocolnew("protocols" "wlr-data-control-unstable-v1" true)
|
protocolnew("protocols" "wlr-data-control-unstable-v1" true)
|
||||||
protocolnew("subprojects/hyprland-protocols/protocols" "hyprland-focus-grab-v1"
|
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-focus-grab-v1" true)
|
||||||
true)
|
|
||||||
protocolnew("protocols" "wlr-layer-shell-unstable-v1" true)
|
protocolnew("protocols" "wlr-layer-shell-unstable-v1" true)
|
||||||
protocolnew("protocols" "wayland-drm" true)
|
protocolnew("protocols" "wayland-drm" true)
|
||||||
|
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-ctm-control-v1" true)
|
||||||
|
|
||||||
protocolnew("staging/tearing-control" "tearing-control-v1" false)
|
protocolnew("staging/tearing-control" "tearing-control-v1" false)
|
||||||
protocolnew("staging/fractional-scale" "fractional-scale-v1" false)
|
protocolnew("staging/fractional-scale" "fractional-scale-v1" false)
|
||||||
protocolnew("unstable/xdg-output" "xdg-output-unstable-v1" false)
|
protocolnew("unstable/xdg-output" "xdg-output-unstable-v1" false)
|
||||||
|
@ -309,6 +333,9 @@ protocolnew("stable/viewporter" "viewporter" false)
|
||||||
protocolnew("stable/linux-dmabuf" "linux-dmabuf-v1" false)
|
protocolnew("stable/linux-dmabuf" "linux-dmabuf-v1" false)
|
||||||
protocolnew("staging/drm-lease" "drm-lease-v1" false)
|
protocolnew("staging/drm-lease" "drm-lease-v1" false)
|
||||||
protocolnew("staging/linux-drm-syncobj" "linux-drm-syncobj-v1" false)
|
protocolnew("staging/linux-drm-syncobj" "linux-drm-syncobj-v1" false)
|
||||||
|
protocolnew("staging/xdg-dialog" "xdg-dialog-v1" false)
|
||||||
|
protocolnew("staging/single-pixel-buffer" "single-pixel-buffer-v1" false)
|
||||||
|
protocolnew("staging/security-context" "security-context-v1" false)
|
||||||
|
|
||||||
protocolwayland()
|
protocolwayland()
|
||||||
|
|
||||||
|
@ -323,19 +350,21 @@ install(
|
||||||
CODE "execute_process( \
|
CODE "execute_process( \
|
||||||
COMMAND ${CMAKE_COMMAND} -E create_symlink \
|
COMMAND ${CMAKE_COMMAND} -E create_symlink \
|
||||||
${CMAKE_INSTALL_FULL_BINDIR}/Hyprland \
|
${CMAKE_INSTALL_FULL_BINDIR}/Hyprland \
|
||||||
${CMAKE_INSTALL_FULL_BINDIR}/hyprland
|
\"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_BINDIR}/hyprland\" \
|
||||||
)")
|
)")
|
||||||
|
|
||||||
# session file
|
# session file
|
||||||
install(FILES ${CMAKE_SOURCE_DIR}/example/hyprland.desktop
|
install(FILES ${CMAKE_SOURCE_DIR}/example/hyprland.desktop
|
||||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/wayland-sessions)
|
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/wayland-sessions)
|
||||||
|
|
||||||
# allow Hyprland to find wallpapers
|
# allow Hyprland to find assets
|
||||||
add_compile_definitions(DATAROOTDIR="${CMAKE_INSTALL_FULL_DATAROOTDIR}")
|
add_compile_definitions(DATAROOTDIR="${CMAKE_INSTALL_FULL_DATAROOTDIR}")
|
||||||
|
|
||||||
# wallpapers
|
# installable assets
|
||||||
file(GLOB_RECURSE WALLPAPERS "assets/wall*")
|
file(GLOB_RECURSE INSTALLABLE_ASSETS "assets/install/*")
|
||||||
install(FILES ${WALLPAPERS} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/hypr)
|
list(FILTER INSTALLABLE_ASSETS EXCLUDE REGEX "meson.build")
|
||||||
|
install(FILES ${INSTALLABLE_ASSETS}
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/hypr)
|
||||||
|
|
||||||
# default config
|
# default config
|
||||||
install(FILES ${CMAKE_SOURCE_DIR}/example/hyprland.conf
|
install(FILES ${CMAKE_SOURCE_DIR}/example/hyprland.conf
|
||||||
|
|
28
Makefile
|
@ -1,28 +1,24 @@
|
||||||
PREFIX = /usr/local
|
PREFIX = /usr/local
|
||||||
|
|
||||||
legacyrenderer:
|
legacyrenderer:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build -G Ninja
|
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build
|
||||||
cmake --build ./build --config Release --target all
|
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||||
chmod -R 777 ./build
|
|
||||||
|
|
||||||
legacyrendererdebug:
|
legacyrendererdebug:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build -G Ninja
|
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DLEGACY_RENDERER:BOOL=true -S . -B ./build
|
||||||
cmake --build ./build --config Release --target all
|
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||||
chmod -R 777 ./build
|
|
||||||
|
|
||||||
release:
|
release:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build -G Ninja
|
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build
|
||||||
cmake --build ./build --config Release --target all
|
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||||
chmod -R 777 ./build
|
|
||||||
|
|
||||||
debug:
|
debug:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build -G Ninja
|
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -S . -B ./build
|
||||||
cmake --build ./build --config Debug --target all
|
cmake --build ./build --config Debug --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||||
chmod -R 777 ./build
|
|
||||||
|
|
||||||
nopch:
|
nopch:
|
||||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON -S . -B ./build -G Ninja
|
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=${PREFIX} -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON -S . -B ./build
|
||||||
cmake --build ./build --config Release --target all
|
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||||
|
|
||||||
clear:
|
clear:
|
||||||
rm -rf build
|
rm -rf build
|
||||||
|
@ -87,8 +83,8 @@ asan:
|
||||||
#git reset --hard
|
#git reset --hard
|
||||||
|
|
||||||
@echo -en "If you want to apply a patch, input its path (leave empty for none):\n"
|
@echo -en "If you want to apply a patch, input its path (leave empty for none):\n"
|
||||||
@read patchvar
|
@read patchvar; \
|
||||||
@if [-n "$patchvar"]; then patch -p1 < $patchvar || echo ""; else echo "No patch specified"; fi
|
if [ -n "$$patchvar" ]; then patch -p1 < "$$patchvar" || echo ""; else echo "No patch specified"; fi
|
||||||
|
|
||||||
git clone --recursive https://gitlab.freedesktop.org/wayland/wayland
|
git clone --recursive https://gitlab.freedesktop.org/wayland/wayland
|
||||||
cd wayland && patch -p1 < ../scripts/waylandStatic.diff && meson setup build --buildtype=debug -Db_sanitize=address -Ddocumentation=false && ninja -C build && cd ..
|
cd wayland && patch -p1 < ../scripts/waylandStatic.diff && meson setup build --buildtype=debug -Db_sanitize=address -Ddocumentation=false && ninja -C build && cd ..
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div align = center>
|
<div align = center>
|
||||||
|
|
||||||
<img src="https://raw.githubusercontent.com/vaxerski/Hyprland/main/assets/header.svg" width="750" height="300" alt="banner">
|
<img src="https://raw.githubusercontent.com/hyprwm/Hyprland/main/assets/header.svg" width="750" height="300" alt="banner">
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -125,7 +125,6 @@ easy IPC, much more QoL stuff than other compositors and more...
|
||||||
|
|
||||||
<!----------------------------------{ Images }--------------------------------->
|
<!----------------------------------{ Images }--------------------------------->
|
||||||
|
|
||||||
[Stars Preview]: https://starchart.cc/vaxerski/Hyprland.svg
|
|
||||||
[Preview A]: https://i.ibb.co/C1yTb0r/falf.png
|
[Preview A]: https://i.ibb.co/C1yTb0r/falf.png
|
||||||
[Preview B]: https://linfindel.github.io/cdn/hyprland-preview-b.png
|
[Preview B]: https://linfindel.github.io/cdn/hyprland-preview-b.png
|
||||||
[Preview C]: https://i.ibb.co/B3GJg28/20221126-20h53m26s-grim.png
|
[Preview C]: https://i.ibb.co/B3GJg28/20221126-20h53m26s-grim.png
|
||||||
|
|
2
VERSION
|
@ -1 +1 @@
|
||||||
0.41.2
|
0.44.0
|
||||||
|
|
BIN
assets/install/lockdead.png
Normal file
After Width: | Height: | Size: 110 KiB |
BIN
assets/install/lockdead2.png
Normal file
After Width: | Height: | Size: 48 KiB |
10
assets/install/meson.build
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
globber = run_command('sh', '-c', 'find . -type f -not -name "*.build"', check: true)
|
||||||
|
files = globber.stdout().strip().split('\n')
|
||||||
|
|
||||||
|
foreach file : files
|
||||||
|
install_data(
|
||||||
|
file,
|
||||||
|
install_dir: join_paths(get_option('datadir'), 'hypr'),
|
||||||
|
install_tag: 'runtime',
|
||||||
|
)
|
||||||
|
endforeach
|
Before Width: | Height: | Size: 14 MiB After Width: | Height: | Size: 14 MiB |
Before Width: | Height: | Size: 5.9 MiB After Width: | Height: | Size: 5.9 MiB |
Before Width: | Height: | Size: 27 MiB After Width: | Height: | Size: 27 MiB |
|
@ -1,7 +1,7 @@
|
||||||
wallpapers = ['0', '1', '2']
|
install_data(
|
||||||
|
'hyprland-portals.conf',
|
||||||
|
install_dir: join_paths(get_option('datadir'), 'xdg-desktop-portal'),
|
||||||
|
install_tag: 'runtime',
|
||||||
|
)
|
||||||
|
|
||||||
foreach type : wallpapers
|
subdir('install')
|
||||||
install_data(f'wall@type@.png', install_dir: join_paths(get_option('datadir'), 'hypr'), install_tag: 'runtime')
|
|
||||||
endforeach
|
|
||||||
|
|
||||||
install_data('hyprland-portals.conf', install_dir: join_paths(get_option('datadir'), 'xdg-desktop-portal'), install_tag: 'runtime')
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ Hyprland - Dynamic tiling Wayland compositor
|
||||||
\f[B]Hyprland\f[R] [\f[I]arg [...]\f[R]].
|
\f[B]Hyprland\f[R] [\f[I]arg [...]\f[R]].
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.PP
|
.PP
|
||||||
\f[B]Hyprland\f[R] is a dynamic tiling Wayland compositor based on
|
\f[B]Hyprland\f[R] is an independent, highly customizable, dynamic
|
||||||
wlroots that doesn\[aq]t sacrifice on its looks.
|
tiling Wayland compositor that doesn\[aq]t sacrifice on its looks.
|
||||||
.PP
|
.PP
|
||||||
You can launch Hyprland by either going into a TTY and executing
|
You can launch Hyprland by either going into a TTY and executing
|
||||||
\f[B]Hyprland\f[R], or with a login manager.
|
\f[B]Hyprland\f[R], or with a login manager.
|
||||||
|
|
|
@ -14,8 +14,8 @@ SYNOPSIS
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
===========
|
===========
|
||||||
|
|
||||||
**Hyprland** is a dynamic tiling Wayland compositor based on
|
**Hyprland** is an independent, highly customizable,
|
||||||
wlroots that doesn't sacrifice on its looks.
|
dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
|
||||||
|
|
||||||
You can launch Hyprland by either going into a TTY and
|
You can launch Hyprland by either going into a TTY and
|
||||||
executing **Hyprland**, or with a login manager.
|
executing **Hyprland**, or with a login manager.
|
||||||
|
|
14
example/hyprland-session.service
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Hyprland - Tiling compositor with the looks
|
||||||
|
Documentation=man:Hyprland(1)
|
||||||
|
BindsTo=graphical-session.target
|
||||||
|
Before=graphical-session.target
|
||||||
|
Wants=graphical-session-pre.target
|
||||||
|
After=graphical-session-pre.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
ExecStart=/usr/bin/Hyprland
|
||||||
|
ExecStop=/usr/bin/hyprctl dispatch exit
|
||||||
|
Restart=on-failure
|
||||||
|
Slice=session.slice
|
5
example/hyprland-systemd.desktop
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Hyprland
|
||||||
|
Comment=An intelligent dynamic tiling Wayland compositor
|
||||||
|
Exec=systemctl --user start --wait hyprland-session
|
||||||
|
Type=Application
|
|
@ -117,6 +117,13 @@ animations {
|
||||||
animation = workspaces, 1, 6, default
|
animation = workspaces, 1, 6, default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Ref https://wiki.hyprland.org/Configuring/Workspace-Rules/
|
||||||
|
# "Smart gaps" / "No gaps when only"
|
||||||
|
# uncomment all three if you wish to use that.
|
||||||
|
# workspace = w[t1], gapsout:0, gapsin:0, border: 0, rounding:0
|
||||||
|
# workspace = w[tg1], gapsout:0, gapsin:0, border: 0, rounding:0
|
||||||
|
# workspace = f[1], gapsout:0, gapsin:0, border: 0, rounding:0
|
||||||
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
||||||
dwindle {
|
dwindle {
|
||||||
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
||||||
|
@ -169,9 +176,9 @@ device {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
####################
|
###################
|
||||||
### KEYBINDINGSS ###
|
### KEYBINDINGS ###
|
||||||
####################
|
###################
|
||||||
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Keywords/
|
# See https://wiki.hyprland.org/Configuring/Keywords/
|
||||||
$mainMod = SUPER # Sets "Windows" key as main modifier
|
$mainMod = SUPER # Sets "Windows" key as main modifier
|
||||||
|
@ -228,6 +235,19 @@ bind = $mainMod, mouse_up, workspace, e-1
|
||||||
bindm = $mainMod, mouse:272, movewindow
|
bindm = $mainMod, mouse:272, movewindow
|
||||||
bindm = $mainMod, mouse:273, resizewindow
|
bindm = $mainMod, mouse:273, resizewindow
|
||||||
|
|
||||||
|
# Laptop multimedia keys for volume and LCD brightness
|
||||||
|
bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+
|
||||||
|
bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
||||||
|
bindel = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
||||||
|
bindel = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
|
||||||
|
bindel = ,XF86MonBrightnessUp, exec, brightnessctl s 10%+
|
||||||
|
bindel = ,XF86MonBrightnessDown, exec, brightnessctl s 10%-
|
||||||
|
|
||||||
|
# Requires playerctl
|
||||||
|
bindl = , XF86AudioNext, exec, playerctl next
|
||||||
|
bindl = , XF86AudioPause, exec, playerctl play-pause
|
||||||
|
bindl = , XF86AudioPlay, exec, playerctl play-pause
|
||||||
|
bindl = , XF86AudioPrev, exec, playerctl previous
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
### WINDOWS AND WORKSPACES ###
|
### WINDOWS AND WORKSPACES ###
|
||||||
|
@ -242,4 +262,8 @@ bindm = $mainMod, mouse:273, resizewindow
|
||||||
# Example windowrule v2
|
# Example windowrule v2
|
||||||
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
||||||
|
|
||||||
windowrulev2 = suppressevent maximize, class:.* # You'll probably like this.
|
# Ignore maximize requests from apps. You'll probably like this.
|
||||||
|
windowrulev2 = suppressevent maximize, class:.*
|
||||||
|
|
||||||
|
# Fix some dragging issues with XWayland
|
||||||
|
windowrulev2 = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0
|
||||||
|
|
|
@ -3,3 +3,5 @@ Name=Hyprland
|
||||||
Comment=An intelligent dynamic tiling Wayland compositor
|
Comment=An intelligent dynamic tiling Wayland compositor
|
||||||
Exec=Hyprland
|
Exec=Hyprland
|
||||||
Type=Application
|
Type=Application
|
||||||
|
DesktopNames=Hyprland
|
||||||
|
Keywords=tiling;wayland;compositor;
|
||||||
|
|
|
@ -1,2 +1,10 @@
|
||||||
install_data('hyprland.conf', install_dir: join_paths(get_option('datadir'), 'hypr'), install_tag: 'runtime')
|
install_data(
|
||||||
install_data('hyprland.desktop', install_dir: join_paths(get_option('datadir'), 'wayland-sessions'), install_tag: 'runtime')
|
'hyprland.conf',
|
||||||
|
install_dir: join_paths(get_option('datadir'), 'hypr'),
|
||||||
|
install_tag: 'runtime',
|
||||||
|
)
|
||||||
|
install_data(
|
||||||
|
'hyprland.desktop',
|
||||||
|
install_dir: join_paths(get_option('datadir'), 'wayland-sessions'),
|
||||||
|
install_tag: 'runtime',
|
||||||
|
)
|
||||||
|
|
138
flake.lock
|
@ -16,11 +16,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1722347739,
|
"lastModified": 1728902391,
|
||||||
"narHash": "sha256-rAoh+K6KG+b1DwSWtqRVocdojnH6nGk6q07mNltoUSM=",
|
"narHash": "sha256-44bnoY0nAvbBQ/lVjmn511yL39Sv7SknV0BDxn34P3Q=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "aquamarine",
|
"repo": "aquamarine",
|
||||||
"rev": "7c3565f9bedc7cb601cc0baa14792247e4dc1d5a",
|
"rev": "9874e08eec85b5542ca22494e127b0cdce46b786",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -29,6 +29,43 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-compat": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1696426674,
|
||||||
|
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gitignore": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"pre-commit-hooks",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1709087332,
|
||||||
|
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "gitignore.nix",
|
||||||
|
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "gitignore.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"hyprcursor": {
|
"hyprcursor": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"hyprlang": [
|
"hyprlang": [
|
||||||
|
@ -42,11 +79,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1721330371,
|
"lastModified": 1728669738,
|
||||||
"narHash": "sha256-aYlHTWylczLt6ERJyg6E66Y/XSCbVL7leVcRuJmVbpI=",
|
"narHash": "sha256-EDNAU9AYcx8OupUzbTbWE1d3HYdeG0wO6Msg3iL1muk=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprcursor",
|
"repo": "hyprcursor",
|
||||||
"rev": "4493a972b48f9c3014befbbf381ed5fff91a65dc",
|
"rev": "0264e698149fcb857a66a53018157b41f8d97bb0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -58,20 +95,18 @@
|
||||||
"hyprland-protocols": {
|
"hyprland-protocols": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"xdph",
|
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
"systems": [
|
"systems": [
|
||||||
"xdph",
|
|
||||||
"systems"
|
"systems"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1721326555,
|
"lastModified": 1728345020,
|
||||||
"narHash": "sha256-zCu4R0CSHEactW9JqYki26gy8h9f6rHmSwj4XJmlHgg=",
|
"narHash": "sha256-xGbkc7U/Roe0/Cv3iKlzijIaFBNguasI31ynL2IlEoM=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprland-protocols",
|
"repo": "hyprland-protocols",
|
||||||
"rev": "5a11232266bf1a1f5952d5b179c3f4b2facaaa84",
|
"rev": "a7c183800e74f337753de186522b9017a07a8cee",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -93,11 +128,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1721324361,
|
"lastModified": 1728168612,
|
||||||
"narHash": "sha256-BiJKO0IIdnSwHQBSrEJlKlFr753urkLE48wtt0UhNG4=",
|
"narHash": "sha256-AnB1KfiXINmuiW7BALYrKqcjCnsLZPifhb/7BsfPbns=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprlang",
|
"repo": "hyprlang",
|
||||||
"rev": "adbefbf49664a6c2c8bf36b6487fd31e3eb68086",
|
"rev": "f054f2e44d6a0b74607a6bc0f52dba337a3db38e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -116,11 +151,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1722098849,
|
"lastModified": 1728941256,
|
||||||
"narHash": "sha256-D3wIZlBNh7LuZ0NaoCpY/Pvu+xHxIVtSN+KkWZYvvVs=",
|
"narHash": "sha256-WRypmcZ2Bw94lLmcmxYokVOHPJSZ7T06V49QZ4tkZeQ=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprutils",
|
"repo": "hyprutils",
|
||||||
"rev": "5dcbbc1e3de40b2cecfd2007434d86e924468f1f",
|
"rev": "fd4be8b9ca932f7384e454bcd923c5451ef2aa85",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -139,11 +174,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1721324119,
|
"lastModified": 1726874836,
|
||||||
"narHash": "sha256-SOOqIT27/X792+vsLSeFdrNTF+OSRp5qXv6Te+fb2Qg=",
|
"narHash": "sha256-VKR0sf0PSNCB0wPHVKSAn41mCNVCnegWmgkrneKDhHM=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "hyprwayland-scanner",
|
"repo": "hyprwayland-scanner",
|
||||||
"rev": "a048a6cb015340bd82f97c1f40a4b595ca85cc30",
|
"rev": "500c81a9e1a76760371049a8d99e008ea77aa59e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -154,11 +189,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1722185531,
|
"lastModified": 1728888510,
|
||||||
"narHash": "sha256-veKR07psFoJjINLC8RK4DiLniGGMgF3QMlS4tb74S6k=",
|
"narHash": "sha256-nsNdSldaAyu6PE3YUA+YQLqUDJh+gRbBooMMekZJwvI=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "52ec9ac3b12395ad677e8b62106f0b98c1f8569d",
|
"rev": "a3c0b3b21515f74fd2665903d4ce6bc4dc81c77c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -168,14 +203,55 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs-stable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1720386169,
|
||||||
|
"narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "194846768975b7ad2c4988bdb82572c00222c0d7",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-24.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pre-commit-hooks": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"gitignore": "gitignore",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"nixpkgs-stable": "nixpkgs-stable"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1728778939,
|
||||||
|
"narHash": "sha256-WybK5E3hpGxtCYtBwpRj1E9JoiVxe+8kX83snTNaFHE=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"rev": "ff68f91754be6f3427e4986d7949e6273659be1d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"aquamarine": "aquamarine",
|
"aquamarine": "aquamarine",
|
||||||
"hyprcursor": "hyprcursor",
|
"hyprcursor": "hyprcursor",
|
||||||
|
"hyprland-protocols": "hyprland-protocols",
|
||||||
"hyprlang": "hyprlang",
|
"hyprlang": "hyprlang",
|
||||||
"hyprutils": "hyprutils",
|
"hyprutils": "hyprutils",
|
||||||
"hyprwayland-scanner": "hyprwayland-scanner",
|
"hyprwayland-scanner": "hyprwayland-scanner",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
|
"pre-commit-hooks": "pre-commit-hooks",
|
||||||
"systems": "systems",
|
"systems": "systems",
|
||||||
"xdph": "xdph"
|
"xdph": "xdph"
|
||||||
}
|
}
|
||||||
|
@ -197,10 +273,18 @@
|
||||||
},
|
},
|
||||||
"xdph": {
|
"xdph": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"hyprland-protocols": "hyprland-protocols",
|
"hyprland-protocols": [
|
||||||
|
"hyprland-protocols"
|
||||||
|
],
|
||||||
"hyprlang": [
|
"hyprlang": [
|
||||||
"hyprlang"
|
"hyprlang"
|
||||||
],
|
],
|
||||||
|
"hyprutils": [
|
||||||
|
"hyprutils"
|
||||||
|
],
|
||||||
|
"hyprwayland-scanner": [
|
||||||
|
"hyprwayland-scanner"
|
||||||
|
],
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
|
@ -209,11 +293,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1722365976,
|
"lastModified": 1728166987,
|
||||||
"narHash": "sha256-Khdm+mDzYA//XaU0M+hftod+rKr5q9SSHSEuiQ0/9ow=",
|
"narHash": "sha256-w6dVTguAn9zJ+7aPOhBQgDz8bn6YZ7b56cY8Kg5HJRI=",
|
||||||
"owner": "hyprwm",
|
"owner": "hyprwm",
|
||||||
"repo": "xdg-desktop-portal-hyprland",
|
"repo": "xdg-desktop-portal-hyprland",
|
||||||
"rev": "7f2a77ddf60390248e2a3de2261d7102a13e5341",
|
"rev": "fb9c8d665af0588bb087f97d0f673ddf0d501787",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
45
flake.nix
|
@ -22,6 +22,12 @@
|
||||||
inputs.hyprlang.follows = "hyprlang";
|
inputs.hyprlang.follows = "hyprlang";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hyprland-protocols = {
|
||||||
|
url = "github:hyprwm/hyprland-protocols";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.systems.follows = "systems";
|
||||||
|
};
|
||||||
|
|
||||||
hyprlang = {
|
hyprlang = {
|
||||||
url = "github:hyprwm/hyprlang";
|
url = "github:hyprwm/hyprlang";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
@ -45,7 +51,15 @@
|
||||||
url = "github:hyprwm/xdg-desktop-portal-hyprland";
|
url = "github:hyprwm/xdg-desktop-portal-hyprland";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
inputs.systems.follows = "systems";
|
inputs.systems.follows = "systems";
|
||||||
|
inputs.hyprland-protocols.follows = "hyprland-protocols";
|
||||||
inputs.hyprlang.follows = "hyprlang";
|
inputs.hyprlang.follows = "hyprlang";
|
||||||
|
inputs.hyprutils.follows = "hyprutils";
|
||||||
|
inputs.hyprwayland-scanner.follows = "hyprwayland-scanner";
|
||||||
|
};
|
||||||
|
|
||||||
|
pre-commit-hooks = {
|
||||||
|
url = "github:cachix/git-hooks.nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -65,6 +79,15 @@
|
||||||
hyprland-extras
|
hyprland-extras
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
pkgsCrossFor = eachSystem (system: crossSystem:
|
||||||
|
import nixpkgs {
|
||||||
|
localSystem = system;
|
||||||
|
inherit crossSystem;
|
||||||
|
overlays = with self.overlays; [
|
||||||
|
hyprland-packages
|
||||||
|
hyprland-extras
|
||||||
|
];
|
||||||
|
});
|
||||||
in {
|
in {
|
||||||
overlays = import ./nix/overlays.nix {inherit self lib inputs;};
|
overlays = import ./nix/overlays.nix {inherit self lib inputs;};
|
||||||
|
|
||||||
|
@ -74,6 +97,18 @@
|
||||||
self.packages.${system})
|
self.packages.${system})
|
||||||
// {
|
// {
|
||||||
inherit (self.packages.${system}) xdg-desktop-portal-hyprland;
|
inherit (self.packages.${system}) xdg-desktop-portal-hyprland;
|
||||||
|
pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
|
||||||
|
src = ./.;
|
||||||
|
hooks = {
|
||||||
|
hyprland-treewide-formatter = {
|
||||||
|
enable = true;
|
||||||
|
entry = "${self.formatter.${system}}/bin/hyprland-treewide-formatter";
|
||||||
|
pass_filenames = false;
|
||||||
|
excludes = ["subprojects"];
|
||||||
|
always_run = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
packages = eachSystem (system: {
|
packages = eachSystem (system: {
|
||||||
|
@ -90,25 +125,23 @@
|
||||||
|
|
||||||
xdg-desktop-portal-hyprland
|
xdg-desktop-portal-hyprland
|
||||||
;
|
;
|
||||||
|
hyprland-cross = (pkgsCrossFor.${system} "aarch64-linux").hyprland;
|
||||||
});
|
});
|
||||||
|
|
||||||
devShells = eachSystem (system: {
|
devShells = eachSystem (system: {
|
||||||
default =
|
default =
|
||||||
pkgsFor.${system}.mkShell.override {
|
pkgsFor.${system}.mkShell.override {
|
||||||
stdenv = pkgsFor.${system}.gcc13Stdenv;
|
inherit (self.packages.${system}.default) stdenv;
|
||||||
} {
|
} {
|
||||||
name = "hyprland-shell";
|
name = "hyprland-shell";
|
||||||
nativeBuildInputs = with pkgsFor.${system}; [
|
|
||||||
expat
|
|
||||||
libxml2
|
|
||||||
];
|
|
||||||
hardeningDisable = ["fortify"];
|
hardeningDisable = ["fortify"];
|
||||||
inputsFrom = [pkgsFor.${system}.hyprland];
|
inputsFrom = [pkgsFor.${system}.hyprland];
|
||||||
packages = [pkgsFor.${system}.clang-tools];
|
packages = [pkgsFor.${system}.clang-tools];
|
||||||
|
inherit (self.checks.${system}.pre-commit-check) shellHook;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
formatter = eachSystem (system: nixpkgs.legacyPackages.${system}.alejandra);
|
formatter = eachSystem (system: pkgsFor.${system}.callPackage ./nix/formatter.nix {});
|
||||||
|
|
||||||
nixosModules.default = import ./nix/module.nix inputs;
|
nixosModules.default = import ./nix/module.nix inputs;
|
||||||
homeManagerModules.default = import ./nix/hm-module.nix self;
|
homeManagerModules.default = import ./nix/hm-module.nix self;
|
||||||
|
|
|
@ -9,7 +9,7 @@ pkg_check_modules(deps REQUIRED IMPORTED_TARGET hyprutils>=0.1.1)
|
||||||
|
|
||||||
add_executable(hyprctl "main.cpp")
|
add_executable(hyprctl "main.cpp")
|
||||||
|
|
||||||
target_link_libraries(hyprctl PUBLIC PkgConfig::deps)
|
target_link_libraries(hyprctl PUBLIC PkgConfig::hyprctl_deps)
|
||||||
|
|
||||||
# binary
|
# binary
|
||||||
install(TARGETS hyprctl)
|
install(TARGETS hyprctl)
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
all:
|
|
||||||
$(CXX) $(CXXFLAGS) -std=c++2b ./main.cpp -o ./hyprctl
|
|
||||||
clean:
|
|
||||||
rm ./hyprctl
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
const std::string_view USAGE = R"#(usage: hyprctl [flags] <command> [args...|--help]
|
const std::string_view USAGE = R"#(usage: hyprctl [flags] <command> [args...|--help]
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
_hyprctl_cmd_2 () {
|
_hyprctl_cmd_1 () {
|
||||||
hyprctl monitors | awk '/Monitor/{ print $2 }'
|
hyprctl monitors | awk '/Monitor/{ print $2 }'
|
||||||
}
|
}
|
||||||
|
|
||||||
_hyprctl_cmd_3 () {
|
_hyprctl_cmd_3 () {
|
||||||
hyprpm list | awk '/Plugin/{ print $4 }'
|
|
||||||
}
|
|
||||||
|
|
||||||
_hyprctl_cmd_0 () {
|
|
||||||
hyprctl clients | awk '/class/{print $2}'
|
hyprctl clients | awk '/class/{print $2}'
|
||||||
}
|
}
|
||||||
|
|
||||||
_hyprctl_cmd_1 () {
|
_hyprctl_cmd_2 () {
|
||||||
hyprctl devices | sed -n '/Keyboard at/{n; s/^\s\+//; p}'
|
hyprctl devices | sed -n '/Keyboard at/{n; s/^\s\+//; p}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_hyprctl_cmd_0 () {
|
||||||
|
hyprpm list | awk '/Plugin/{print $4}'
|
||||||
|
}
|
||||||
|
|
||||||
_hyprctl () {
|
_hyprctl () {
|
||||||
if [[ $(type -t _get_comp_words_by_ref) != function ]]; then
|
if [[ $(type -t _get_comp_words_by_ref) != function ]]; then
|
||||||
echo _get_comp_words_by_ref: function not defined. Make sure the bash-completions system package is installed
|
echo _get_comp_words_by_ref: function not defined. Make sure the bash-completions system package is installed
|
||||||
|
@ -23,25 +23,25 @@ _hyprctl () {
|
||||||
local words cword
|
local words cword
|
||||||
_get_comp_words_by_ref -n "$COMP_WORDBREAKS" words cword
|
_get_comp_words_by_ref -n "$COMP_WORDBREAKS" words cword
|
||||||
|
|
||||||
local -a literals=("cyclenext" "globalshortcuts" "cursorpos" "bordersize" "renameworkspace" "animationstyle" "focuswindow" "0" "auto" "swapnext" "forceallowsinput" "moveactive" "activebordercolor" "alphafullscreen" "wayland" "layers" "minsize" "monitors" "1" "kill" "settiled" "3" "focusmonitor" "swapwindow" "moveoutofgroup" "notify" "movecursor" "setcursor" "seterror" "movecurrentworkspacetomonitor" "4" "nomaxsize" "forcenoanims" "setprop" "-i" "-q" "togglefloating" "workspacerules" "movetoworkspace" "disable" "setignoregrouplock" "workspaces" "movegroupwindow" "closewindow" "0" "--instance" "binds" "movewindow" "splitratio" "alpha" "denywindowfromgroup" "workspace" "configerrors" "togglegroup" "getoption" "forceopaque" "keepaspectratio" "killactive" "pass" "decorations" "devices" "focuscurrentorlast" "submap" "global" "alphafullscreenoverride" "forcerendererreload" "movewindowpixel" "headless" "version" "dpms" "resizeactive" "moveintogroup" "5" "alphaoverride" "setfloating" "rollinglog" "::=" "rounding" "layouts" "moveworkspacetomonitor" "exec" "alphainactiveoverride" "alterzorder" "fakefullscreen" "nofocus" "keyword" "forcenoborder" "forcenodim" "--quiet" "pin" "output" "forcenoblur" "togglespecialworkspace" "fullscreen" "toggleopaque" "focusworkspaceoncurrentmonitor" "next" "changegroupactive" "-j" "instances" "execr" "exit" "clients" "all" "--batch" "dismissnotify" "inactivebordercolor" "switchxkblayout" "movetoworkspacesilent" "tagwindow" "movewindoworgroup" "-r" "movefocus" "focusurgentorlast" "remove" "activeworkspace" "dispatch" "create" "centerwindow" "2" "hyprpaper" "-1" "reload" "alphainactive" "systeminfo" "plugin" "dimaround" "activewindow" "swapactiveworkspaces" "splash" "sendshortcut" "maxsize" "lockactivegroup" "windowdancecompat" "forceopaqueoverriden" "lockgroups" "movecursortocorner" "x11" "prev" "1" "resizewindowpixel" "forcenoshadow")
|
declare -a literals=(resizeactive 2 changegroupactive -r moveintogroup forceallowsinput 4 ::= systeminfo all layouts setprop animationstyle switchxkblayout create denywindowfromgroup headless activebordercolor exec setcursor wayland focusurgentorlast workspacerules movecurrentworkspacetomonitor movetoworkspacesilent hyprpaper alpha inactivebordercolor movegroupwindow movecursortocorner movewindowpixel prev movewindow globalshortcuts clients dimaround setignoregrouplock splash execr monitors 0 forcenoborder -q animations 1 nomaxsize splitratio moveactive pass swapnext devices layers rounding lockactivegroup 5 moveworkspacetomonitor -f -i --quiet forcenodim pin 0 1 forceopaque forcenoshadow setfloating minsize alphaoverride sendshortcut workspaces cyclenext alterzorder togglegroup lockgroups bordersize dpms focuscurrentorlast -1 --batch notify remove instances 1 3 moveoutofgroup killactive 2 movetoworkspace movecursor configerrors closewindow swapwindow tagwindow forcerendererreload centerwindow auto focuswindow seterror nofocus alphafullscreen binds version -h togglespecialworkspace fullscreen windowdancecompat 0 keyword toggleopaque 3 --instance togglefloating renameworkspace alphafullscreenoverride activeworkspace x11 kill forceopaqueoverriden output global dispatch reload forcenoblur -j event --help disable -1 activewindow keepaspectratio dismissnotify focusmonitor movefocus plugin exit workspace fullscreenstate getoption alphainactiveoverride alphainactive decorations settiled config-only descriptions resizewindowpixel fakefullscreen rollinglog swapactiveworkspaces submap next movewindoworgroup cursorpos forcenoanims focusworkspaceoncurrentmonitor maxsize)
|
||||||
|
|
||||||
declare -A literal_transitions
|
declare -A literal_transitions
|
||||||
literal_transitions[0]="([105]=1 [75]=2 [33]=3 [35]=4 [1]=2 [2]=2 [78]=2 [107]=5 [37]=2 [111]=4 [41]=2 [46]=2 [115]=2 [85]=6 [116]=8 [52]=2 [88]=4 [54]=2 [90]=9 [120]=2 [122]=2 [124]=2 [15]=2 [59]=10 [60]=2 [17]=11 [125]=12 [19]=2 [127]=2 [129]=2 [25]=13 [68]=2 [98]=4 [99]=2 [27]=2 [28]=14 [102]=2 [104]=4)"
|
literal_transitions[0]="([120]=14 [43]=2 [125]=21 [81]=2 [3]=21 [51]=2 [50]=2 [128]=2 [89]=2 [58]=21 [8]=2 [10]=2 [11]=3 [130]=4 [13]=5 [97]=6 [101]=2 [102]=21 [133]=7 [100]=2 [137]=2 [22]=2 [19]=2 [140]=8 [25]=2 [143]=2 [107]=9 [146]=10 [69]=2 [33]=2 [34]=2 [78]=21 [114]=2 [37]=2 [151]=2 [116]=2 [121]=13 [123]=21 [39]=11 [42]=21 [79]=15 [118]=12)"
|
||||||
literal_transitions[3]="([73]=17 [13]=2 [32]=17 [55]=17 [56]=17 [91]=17 [106]=2 [123]=2 [77]=1 [16]=2 [126]=17 [3]=1 [5]=2 [64]=17 [131]=2 [133]=17 [81]=17 [134]=17 [84]=17 [31]=17 [49]=2 [12]=2 [86]=17 [10]=17 [87]=17 [141]=17)"
|
literal_transitions[1]="([81]=2 [51]=2 [50]=2 [128]=2 [8]=2 [89]=2 [10]=2 [11]=3 [130]=4 [13]=5 [97]=6 [101]=2 [133]=7 [100]=2 [22]=2 [19]=2 [137]=2 [140]=8 [25]=2 [143]=2 [107]=9 [146]=10 [69]=2 [33]=2 [34]=2 [114]=2 [37]=2 [151]=2 [116]=2 [39]=11 [118]=12 [121]=13 [120]=14 [79]=15 [43]=2)"
|
||||||
literal_transitions[7]="([105]=1 [75]=2 [33]=3 [1]=2 [2]=2 [78]=2 [107]=5 [37]=2 [41]=2 [46]=2 [115]=2 [85]=6 [116]=8 [52]=2 [54]=2 [90]=9 [120]=2 [122]=2 [124]=2 [15]=2 [59]=10 [60]=2 [17]=11 [125]=12 [19]=2 [127]=2 [129]=2 [25]=13 [68]=2 [99]=2 [27]=2 [28]=14 [102]=2)"
|
literal_transitions[3]="([139]=2 [63]=16 [64]=16 [45]=16 [105]=16 [27]=2 [26]=2 [52]=4 [5]=16 [66]=2 [67]=16 [129]=16 [113]=16 [12]=2 [74]=4 [99]=2 [35]=16 [152]=16 [98]=16 [59]=16 [117]=16 [41]=16 [17]=2 [138]=16 [154]=2 [122]=16)"
|
||||||
literal_transitions[8]="([101]=2 [130]=2 [132]=2 [0]=2 [74]=2 [36]=2 [108]=2 [109]=2 [38]=2 [110]=2 [4]=2 [79]=2 [40]=2 [80]=2 [113]=2 [6]=2 [42]=2 [43]=2 [82]=2 [83]=2 [47]=2 [48]=2 [9]=2 [50]=2 [51]=2 [53]=2 [11]=2 [112]=2 [89]=2 [118]=2 [57]=2 [92]=2 [58]=2 [93]=2 [94]=2 [61]=2 [62]=2 [128]=2 [95]=2 [63]=2 [20]=2 [97]=2 [22]=2 [23]=2 [65]=2 [66]=2 [135]=2 [136]=2 [24]=2 [26]=2 [69]=2 [100]=2 [70]=2 [140]=2 [29]=2 [71]=2)"
|
literal_transitions[6]="([126]=2)"
|
||||||
literal_transitions[9]="([117]=20 [114]=16)"
|
literal_transitions[10]="([56]=2)"
|
||||||
literal_transitions[11]="([103]=2)"
|
literal_transitions[11]="([9]=2)"
|
||||||
literal_transitions[13]="([21]=1 [119]=1 [30]=1 [139]=1 [121]=1 [44]=1 [72]=1)"
|
literal_transitions[12]="([14]=19 [80]=22)"
|
||||||
literal_transitions[14]="([39]=2)"
|
literal_transitions[13]="([142]=2)"
|
||||||
literal_transitions[15]="([138]=2 [96]=2)"
|
literal_transitions[14]="([0]=2 [84]=2 [2]=2 [85]=2 [4]=2 [87]=2 [88]=2 [90]=2 [91]=2 [92]=2 [93]=2 [94]=2 [96]=2 [15]=2 [18]=2 [103]=2 [21]=2 [104]=2 [23]=2 [24]=2 [28]=2 [29]=2 [30]=2 [108]=2 [111]=2 [32]=2 [112]=2 [36]=2 [38]=2 [119]=2 [124]=2 [46]=2 [47]=2 [48]=2 [49]=2 [53]=2 [55]=2 [131]=2 [132]=2 [134]=2 [135]=2 [60]=2 [136]=20 [141]=2 [65]=2 [144]=2 [145]=2 [68]=2 [147]=2 [70]=2 [71]=2 [72]=2 [73]=2 [148]=2 [75]=2 [76]=2 [150]=2 [153]=2)"
|
||||||
literal_transitions[17]="([18]=2 [7]=2)"
|
literal_transitions[15]="([86]=4 [6]=4 [109]=4 [61]=4 [77]=4 [54]=4 [62]=4)"
|
||||||
literal_transitions[18]="([76]=19)"
|
literal_transitions[16]="([40]=2 [44]=2)"
|
||||||
literal_transitions[19]="([34]=4 [45]=4)"
|
literal_transitions[17]="([7]=23)"
|
||||||
literal_transitions[20]="([8]=2 [67]=2 [14]=2 [137]=2)"
|
literal_transitions[18]="([31]=2 [149]=2)"
|
||||||
|
literal_transitions[19]="([95]=2 [16]=2 [115]=2 [20]=2)"
|
||||||
declare -A match_anything_transitions
|
literal_transitions[20]="([106]=2 [82]=2 [127]=2 [1]=2 [83]=2)"
|
||||||
match_anything_transitions=([1]=2 [0]=7 [6]=2 [15]=2 [10]=2 [5]=15 [14]=18 [7]=7 [2]=18 [16]=2 [12]=2 [11]=18)
|
literal_transitions[23]="([57]=21 [110]=21)"
|
||||||
|
declare -A match_anything_transitions=([6]=17 [7]=2 [0]=1 [22]=2 [5]=18 [4]=2 [2]=17 [18]=2 [11]=17 [8]=2 [9]=2 [13]=17 [10]=17 [1]=1)
|
||||||
declare -A subword_transitions
|
declare -A subword_transitions
|
||||||
|
|
||||||
local state=0
|
local state=0
|
||||||
|
@ -79,21 +79,9 @@ _hyprctl () {
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
|
local -a matches=()
|
||||||
|
|
||||||
local prefix="${words[$cword]}"
|
local prefix="${words[$cword]}"
|
||||||
|
|
||||||
local shortest_suffix="$word"
|
|
||||||
for ((i=0; i < ${#COMP_WORDBREAKS}; i++)); do
|
|
||||||
local char="${COMP_WORDBREAKS:$i:1}"
|
|
||||||
local candidate="${word##*$char}"
|
|
||||||
if [[ ${#candidate} -lt ${#shortest_suffix} ]]; then
|
|
||||||
shortest_suffix=$candidate
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
local superfluous_prefix=""
|
|
||||||
if [[ "$shortest_suffix" != "$word" ]]; then
|
|
||||||
local superfluous_prefix=${word%$shortest_suffix}
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -v "literal_transitions[$state]" ]]; then
|
if [[ -v "literal_transitions[$state]" ]]; then
|
||||||
local state_transitions_initializer=${literal_transitions[$state]}
|
local state_transitions_initializer=${literal_transitions[$state]}
|
||||||
declare -A state_transitions
|
declare -A state_transitions
|
||||||
|
@ -102,25 +90,38 @@ _hyprctl () {
|
||||||
for literal_id in "${!state_transitions[@]}"; do
|
for literal_id in "${!state_transitions[@]}"; do
|
||||||
local literal="${literals[$literal_id]}"
|
local literal="${literals[$literal_id]}"
|
||||||
if [[ $literal = "${prefix}"* ]]; then
|
if [[ $literal = "${prefix}"* ]]; then
|
||||||
local completion=${literal#"$superfluous_prefix"}
|
matches+=("$literal ")
|
||||||
COMPREPLY+=("$completion ")
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
declare -A commands
|
declare -A commands
|
||||||
commands=([5]=1 [16]=2 [12]=3 [10]=0)
|
commands=([7]=0 [22]=1 [8]=3 [5]=2)
|
||||||
if [[ -v "commands[$state]" ]]; then
|
if [[ -v "commands[$state]" ]]; then
|
||||||
local command_id=${commands[$state]}
|
local command_id=${commands[$state]}
|
||||||
local completions=()
|
local completions=()
|
||||||
mapfile -t completions < <(_hyprctl_cmd_${command_id} "$prefix" | cut -f1)
|
readarray -t completions < <(_hyprctl_cmd_${command_id} "$prefix" | cut -f1)
|
||||||
for item in "${completions[@]}"; do
|
for item in "${completions[@]}"; do
|
||||||
if [[ $item = "${prefix}"* ]]; then
|
if [[ $item = "${prefix}"* ]]; then
|
||||||
COMPREPLY+=("$item")
|
matches+=("$item")
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
local shortest_suffix="$prefix"
|
||||||
|
for ((i=0; i < ${#COMP_WORDBREAKS}; i++)); do
|
||||||
|
local char="${COMP_WORDBREAKS:$i:1}"
|
||||||
|
local candidate=${prefix##*$char}
|
||||||
|
if [[ ${#candidate} -lt ${#shortest_suffix} ]]; then
|
||||||
|
shortest_suffix=$candidate
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
local superfluous_prefix=""
|
||||||
|
if [[ "$shortest_suffix" != "$prefix" ]]; then
|
||||||
|
local superfluous_prefix=${prefix%$shortest_suffix}
|
||||||
|
fi
|
||||||
|
COMPREPLY=("${matches[@]#$superfluous_prefix}")
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
function _hyprctl_3
|
function _hyprctl_2
|
||||||
set 1 $argv[1]
|
set 1 $argv[1]
|
||||||
hyprctl monitors | awk '/Monitor/{ print $2 }'
|
hyprctl monitors | awk '/Monitor/{ print $2 }'
|
||||||
end
|
end
|
||||||
|
|
||||||
function _hyprctl_4
|
function _hyprctl_4
|
||||||
set 1 $argv[1]
|
set 1 $argv[1]
|
||||||
hyprpm list | awk '/Plugin/{ print $4 }'
|
hyprctl clients | awk '/class/{print $2}'
|
||||||
|
end
|
||||||
|
|
||||||
|
function _hyprctl_3
|
||||||
|
set 1 $argv[1]
|
||||||
|
hyprctl devices | sed -n '/Keyboard at/{n; s/^\s\+//; p}'
|
||||||
end
|
end
|
||||||
|
|
||||||
function _hyprctl_1
|
function _hyprctl_1
|
||||||
set 1 $argv[1]
|
set 1 $argv[1]
|
||||||
hyprctl clients | awk '/class/{ print $2 }'
|
hyprpm list | awk '/Plugin/{print $4}'
|
||||||
end
|
|
||||||
|
|
||||||
function _hyprctl_2
|
|
||||||
set 1 $argv[1]
|
|
||||||
hyprctl devices | sed -n '/Keyboard at/{n; s/^\s\+//; p}'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function _hyprctl
|
function _hyprctl
|
||||||
|
@ -29,145 +29,160 @@ function _hyprctl
|
||||||
set COMP_CWORD (count $COMP_WORDS)
|
set COMP_CWORD (count $COMP_WORDS)
|
||||||
end
|
end
|
||||||
|
|
||||||
set --local literals "cyclenext" "globalshortcuts" "cursorpos" "bordersize" "renameworkspace" "animationstyle" "focuswindow" "0" "auto" "swapnext" "forceallowsinput" "moveactive" "activebordercolor" "alphafullscreen" "wayland" "layers" "minsize" "monitors" "1" "kill" "settiled" "3" "focusmonitor" "swapwindow" "moveoutofgroup" "notify" "movecursor" "setcursor" "seterror" "movecurrentworkspacetomonitor" "4" "nomaxsize" "forcenoanims" "setprop" "-i" "-q" "togglefloating" "workspacerules" "movetoworkspace" "disable" "setignoregrouplock" "workspaces" "movegroupwindow" "closewindow" "0" "--instance" "binds" "movewindow" "splitratio" "alpha" "denywindowfromgroup" "workspace" "configerrors" "togglegroup" "getoption" "forceopaque" "keepaspectratio" "killactive" "pass" "decorations" "devices" "focuscurrentorlast" "submap" "global" "alphafullscreenoverride" "forcerendererreload" "movewindowpixel" "headless" "version" "dpms" "resizeactive" "moveintogroup" "5" "alphaoverride" "setfloating" "rollinglog" "::=" "rounding" "layouts" "moveworkspacetomonitor" "exec" "alphainactiveoverride" "alterzorder" "fakefullscreen" "nofocus" "keyword" "forcenoborder" "forcenodim" "--quiet" "pin" "output" "forcenoblur" "togglespecialworkspace" "fullscreen" "toggleopaque" "focusworkspaceoncurrentmonitor" "next" "changegroupactive" "-j" "instances" "execr" "exit" "clients" "all" "--batch" "dismissnotify" "inactivebordercolor" "switchxkblayout" "movetoworkspacesilent" "tagwindow" "movewindoworgroup" "-r" "movefocus" "focusurgentorlast" "remove" "activeworkspace" "dispatch" "create" "centerwindow" "2" "hyprpaper" "-1" "reload" "alphainactive" "systeminfo" "plugin" "dimaround" "activewindow" "swapactiveworkspaces" "splash" "sendshortcut" "maxsize" "lockactivegroup" "windowdancecompat" "forceopaqueoverriden" "lockgroups" "movecursortocorner" "x11" "prev" "1" "resizewindowpixel" "forcenoshadow"
|
set literals "resizeactive" "2" "changegroupactive" "-r" "moveintogroup" "forceallowsinput" "4" "::=" "systeminfo" "all" "layouts" "setprop" "animationstyle" "switchxkblayout" "create" "denywindowfromgroup" "headless" "activebordercolor" "exec" "setcursor" "wayland" "focusurgentorlast" "workspacerules" "movecurrentworkspacetomonitor" "movetoworkspacesilent" "hyprpaper" "alpha" "inactivebordercolor" "movegroupwindow" "movecursortocorner" "movewindowpixel" "prev" "movewindow" "globalshortcuts" "clients" "dimaround" "setignoregrouplock" "splash" "execr" "monitors" "0" "forcenoborder" "-q" "animations" "1" "nomaxsize" "splitratio" "moveactive" "pass" "swapnext" "devices" "layers" "rounding" "lockactivegroup" "5" "moveworkspacetomonitor" "-f" "-i" "--quiet" "forcenodim" "pin" "0" "1" "forceopaque" "forcenoshadow" "setfloating" "minsize" "alphaoverride" "sendshortcut" "workspaces" "cyclenext" "alterzorder" "togglegroup" "lockgroups" "bordersize" "dpms" "focuscurrentorlast" "-1" "--batch" "notify" "remove" "instances" "1" "3" "moveoutofgroup" "killactive" "2" "movetoworkspace" "movecursor" "configerrors" "closewindow" "swapwindow" "tagwindow" "forcerendererreload" "centerwindow" "auto" "focuswindow" "seterror" "nofocus" "alphafullscreen" "binds" "version" "-h" "togglespecialworkspace" "fullscreen" "windowdancecompat" "0" "keyword" "toggleopaque" "3" "--instance" "togglefloating" "renameworkspace" "alphafullscreenoverride" "activeworkspace" "x11" "kill" "forceopaqueoverriden" "output" "global" "dispatch" "reload" "forcenoblur" "-j" "event" "--help" "disable" "-1" "activewindow" "keepaspectratio" "dismissnotify" "focusmonitor" "movefocus" "plugin" "exit" "workspace" "fullscreenstate" "getoption" "alphainactiveoverride" "alphainactive" "decorations" "settiled" "config-only" "descriptions" "resizewindowpixel" "fakefullscreen" "rollinglog" "swapactiveworkspaces" "submap" "next" "movewindoworgroup" "cursorpos" "forcenoanims" "focusworkspaceoncurrentmonitor" "maxsize"
|
||||||
|
|
||||||
set --local descriptions
|
set descriptions
|
||||||
set descriptions[1] "Focus the next window on a workspace"
|
set descriptions[1] "Resize the active window"
|
||||||
set descriptions[3] "Get the current cursor pos in global layout coordinates"
|
set descriptions[2] "Fullscreen"
|
||||||
set descriptions[5] "Rename a workspace"
|
set descriptions[3] "Switch to the next window in a group"
|
||||||
set descriptions[7] "Focus the first window matching"
|
set descriptions[4] "Refresh state after issuing the command"
|
||||||
set descriptions[10] "Swap the focused window with the next window"
|
set descriptions[5] "Move the active window into a group"
|
||||||
set descriptions[12] "Move the active window"
|
set descriptions[7] "CONFUSED"
|
||||||
set descriptions[16] "List the layers"
|
set descriptions[9] "Print system info"
|
||||||
set descriptions[18] "List active outputs with their properties"
|
set descriptions[11] "List all layouts available (including plugin ones)"
|
||||||
set descriptions[20] "Get into a kill mode, where you can kill an app by clicking on it"
|
set descriptions[12] "Set a property of a window"
|
||||||
set descriptions[21] "Set the current window's floating state to false"
|
set descriptions[14] "Set the xkb layout index for a keyboard"
|
||||||
set descriptions[22] "ERROR"
|
set descriptions[16] "Prohibit the active window from becoming or being inserted into group"
|
||||||
set descriptions[23] "Focus a monitor"
|
set descriptions[19] "Execute a shell command"
|
||||||
set descriptions[24] "Swap the active window with another window"
|
set descriptions[20] "Set the cursor theme and reloads the cursor manager"
|
||||||
set descriptions[25] "Move the active window out of a group"
|
set descriptions[22] "Focus the urgent window or the last window"
|
||||||
set descriptions[26] "Send a notification using the built-in Hyprland notification system"
|
set descriptions[23] "Get the list of defined workspace rules"
|
||||||
set descriptions[27] "Move the cursor to a specified position"
|
set descriptions[24] "Move the active workspace to a monitor"
|
||||||
set descriptions[28] "Set the cursor theme and reloads the cursor manager"
|
set descriptions[25] "Move window doesnt switch to the workspace"
|
||||||
set descriptions[29] "Set the hyprctl error string"
|
set descriptions[26] "Interact with hyprpaper if present"
|
||||||
set descriptions[30] "Move the active workspace to a monitor"
|
set descriptions[29] "Swap the active window with the next or previous in a group"
|
||||||
set descriptions[31] "CONFUSED"
|
set descriptions[30] "Move the cursor to the corner of the active window"
|
||||||
set descriptions[34] "Set a property of a window"
|
set descriptions[31] "Move a selected window"
|
||||||
set descriptions[35] "Specify the Hyprland instance"
|
set descriptions[33] "Move the active window in a direction or to a monitor"
|
||||||
set descriptions[36] "Disable output"
|
set descriptions[34] "Lists all global shortcuts"
|
||||||
set descriptions[37] "Toggle the current window's floating state"
|
set descriptions[35] "List all windows with their properties"
|
||||||
set descriptions[38] "Get the list of defined workspace rules"
|
set descriptions[37] "Temporarily enable or disable binds:ignore_group_lock"
|
||||||
set descriptions[39] "Move the focused window to a workspace"
|
set descriptions[38] "Print the current random splash"
|
||||||
set descriptions[41] "Temporarily enable or disable binds:ignore_group_lock"
|
set descriptions[39] "Execute a raw shell command"
|
||||||
set descriptions[42] "List all workspaces with their properties"
|
set descriptions[40] "List active outputs with their properties"
|
||||||
set descriptions[43] "Swap the active window with the next or previous in a group"
|
set descriptions[43] "Disable output"
|
||||||
set descriptions[44] "Close a specified window"
|
set descriptions[44] "Gets the current config info about animations and beziers"
|
||||||
set descriptions[45] "WARNING"
|
set descriptions[47] "Change the split ratio"
|
||||||
set descriptions[46] "Specify the Hyprland instance"
|
set descriptions[48] "Move the active window"
|
||||||
set descriptions[47] "List all registered binds"
|
set descriptions[49] "Pass the key to a specified window"
|
||||||
set descriptions[48] "Move the active window in a direction or to a monitor"
|
set descriptions[50] "Swap the focused window with the next window"
|
||||||
set descriptions[49] "Change the split ratio"
|
set descriptions[51] "List all connected keyboards and mice"
|
||||||
set descriptions[51] "Prohibit the active window from becoming or being inserted into group"
|
set descriptions[52] "List the layers"
|
||||||
set descriptions[52] "Change the workspace"
|
set descriptions[54] "Lock the focused group"
|
||||||
set descriptions[53] "List all current config parsing errors"
|
set descriptions[55] "OK"
|
||||||
set descriptions[54] "Toggle the current active window into a group"
|
set descriptions[56] "Move a workspace to a monitor"
|
||||||
set descriptions[55] "Get the config option status (values)"
|
set descriptions[58] "Specify the Hyprland instance"
|
||||||
set descriptions[58] "Close the active window"
|
set descriptions[59] "Disable output"
|
||||||
set descriptions[59] "Pass the key to a specified window"
|
set descriptions[61] "Pin a window"
|
||||||
set descriptions[60] "List all decorations and their info"
|
set descriptions[62] "WARNING"
|
||||||
set descriptions[61] "List all connected keyboards and mice"
|
set descriptions[63] "INFO"
|
||||||
set descriptions[62] "Switch focus from current to previously focused window"
|
set descriptions[66] "Set the current window's floating state to true"
|
||||||
set descriptions[63] "Change the current mapping group"
|
set descriptions[69] "On shortcut X sends shortcut Y to a specified window"
|
||||||
set descriptions[64] "Execute a Global Shortcut using the GlobalShortcuts portal"
|
set descriptions[70] "List all workspaces with their properties"
|
||||||
set descriptions[66] "Force the renderer to reload all resources and outputs"
|
set descriptions[71] "Focus the next window on a workspace"
|
||||||
set descriptions[67] "Move a selected window"
|
set descriptions[72] "Modify the window stack order of the active or specified window"
|
||||||
set descriptions[69] "Print the Hyprland version: flags, commit and branch of build"
|
set descriptions[73] "Toggle the current active window into a group"
|
||||||
set descriptions[70] "Set all monitors' DPMS status"
|
set descriptions[74] "Lock the groups"
|
||||||
set descriptions[71] "Resize the active window"
|
set descriptions[76] "Set all monitors' DPMS status"
|
||||||
set descriptions[72] "Move the active window into a group"
|
set descriptions[77] "Switch focus from current to previously focused window"
|
||||||
set descriptions[73] "OK"
|
set descriptions[78] "No Icon"
|
||||||
set descriptions[75] "Set the current window's floating state to true"
|
set descriptions[79] "Execute a batch of commands separated by ;"
|
||||||
set descriptions[76] "Print tail of the log"
|
set descriptions[80] "Send a notification using the built-in Hyprland notification system"
|
||||||
set descriptions[79] "List all layouts available (including plugin ones)"
|
set descriptions[82] "List all running Hyprland instances and their info"
|
||||||
set descriptions[80] "Move a workspace to a monitor"
|
set descriptions[83] "Maximize no fullscreen"
|
||||||
set descriptions[81] "Execute a shell command"
|
set descriptions[84] "Maximize and fullscreen"
|
||||||
set descriptions[83] "Modify the window stack order of the active or specified window"
|
set descriptions[85] "Move the active window out of a group"
|
||||||
set descriptions[84] "Toggle the focused window's internal fullscreen state"
|
set descriptions[86] "Close the active window"
|
||||||
set descriptions[86] "Issue a keyword to call a config keyword dynamically"
|
set descriptions[87] "HINT"
|
||||||
set descriptions[89] "Disable output"
|
set descriptions[88] "Move the focused window to a workspace"
|
||||||
set descriptions[90] "Pin a window"
|
set descriptions[89] "Move the cursor to a specified position"
|
||||||
set descriptions[91] "Allows adding/removing fake outputs to a specific backend"
|
set descriptions[90] "List all current config parsing errors"
|
||||||
set descriptions[93] "Toggle a special workspace on/off"
|
set descriptions[91] "Close a specified window"
|
||||||
set descriptions[94] "Toggle the focused window's fullscreen state"
|
set descriptions[92] "Swap the active window with another window"
|
||||||
set descriptions[95] "Toggle the current window to always be opaque"
|
set descriptions[93] "Apply a tag to the window"
|
||||||
set descriptions[96] "Focus the requested workspace"
|
set descriptions[94] "Force the renderer to reload all resources and outputs"
|
||||||
set descriptions[98] "Switch to the next window in a group"
|
set descriptions[95] "Center the active window"
|
||||||
set descriptions[99] "Output in JSON format"
|
set descriptions[97] "Focus the first window matching"
|
||||||
set descriptions[100] "List all running Hyprland instances and their info"
|
set descriptions[98] "Set the hyprctl error string"
|
||||||
set descriptions[101] "Execute a raw shell command"
|
set descriptions[101] "List all registered binds"
|
||||||
set descriptions[102] "Exit the compositor with no questions asked"
|
set descriptions[102] "Print the Hyprland version: flags, commit and branch of build"
|
||||||
set descriptions[103] "List all windows with their properties"
|
set descriptions[103] "Prints the help message"
|
||||||
set descriptions[105] "Execute a batch of commands separated by ;"
|
set descriptions[104] "Toggle a special workspace on/off"
|
||||||
set descriptions[106] "Dismiss all or up to amount of notifications"
|
set descriptions[105] "Toggle the focused window's fullscreen state"
|
||||||
set descriptions[108] "Set the xkb layout index for a keyboard"
|
set descriptions[107] "None"
|
||||||
set descriptions[109] "Move window doesnt switch to the workspace"
|
set descriptions[108] "Issue a keyword to call a config keyword dynamically"
|
||||||
set descriptions[110] "Apply a tag to the window"
|
set descriptions[109] "Toggle the current window to always be opaque"
|
||||||
set descriptions[111] "Behave as moveintogroup"
|
set descriptions[110] "ERROR"
|
||||||
set descriptions[112] "Refresh state after issuing the command"
|
set descriptions[111] "Specify the Hyprland instance"
|
||||||
set descriptions[113] "Move the focus in a direction"
|
set descriptions[112] "Toggle the current window's floating state"
|
||||||
set descriptions[114] "Focus the urgent window or the last window"
|
set descriptions[113] "Rename a workspace"
|
||||||
set descriptions[116] "Get the active workspace name and its properties"
|
set descriptions[115] "Get the active workspace name and its properties"
|
||||||
set descriptions[117] "Issue a dispatch to call a keybind dispatcher with an arg"
|
set descriptions[117] "Get into a kill mode, where you can kill an app by clicking on it"
|
||||||
set descriptions[119] "Center the active window"
|
set descriptions[119] "Allows adding/removing fake outputs to a specific backend"
|
||||||
set descriptions[120] "HINT"
|
set descriptions[120] "Execute a Global Shortcut using the GlobalShortcuts portal"
|
||||||
set descriptions[121] "Interact with hyprpaper if present"
|
set descriptions[121] "Issue a dispatch to call a keybind dispatcher with an arg"
|
||||||
set descriptions[122] "No Icon"
|
set descriptions[122] "Force reload the config"
|
||||||
set descriptions[123] "Force reload the config"
|
set descriptions[124] "Output in JSON format"
|
||||||
set descriptions[125] "Print system info"
|
set descriptions[125] "Emits a custom event to socket2"
|
||||||
set descriptions[126] "Interact with a plugin"
|
set descriptions[126] "Prints the help message"
|
||||||
set descriptions[128] "Get the active window name and its properties"
|
set descriptions[128] "Current"
|
||||||
set descriptions[129] "Swap the active workspaces between two monitors"
|
set descriptions[129] "Get the active window name and its properties"
|
||||||
set descriptions[130] "Print the current random splash"
|
set descriptions[131] "Dismiss all or up to amount of notifications"
|
||||||
set descriptions[131] "On shortcut X sends shortcut Y to a specified window"
|
set descriptions[132] "Focus a monitor"
|
||||||
set descriptions[133] "Lock the focused group"
|
set descriptions[133] "Move the focus in a direction"
|
||||||
set descriptions[136] "Lock the groups"
|
set descriptions[134] "Interact with a plugin"
|
||||||
set descriptions[137] "Move the cursor to the corner of the active window"
|
set descriptions[135] "Exit the compositor with no questions asked"
|
||||||
set descriptions[140] "INFO"
|
set descriptions[136] "Change the workspace"
|
||||||
set descriptions[141] "Resize a selected window"
|
set descriptions[137] "Sets the focused window’s fullscreen mode and the one sent to the client"
|
||||||
|
set descriptions[138] "Get the config option status (values)"
|
||||||
|
set descriptions[141] "List all decorations and their info"
|
||||||
|
set descriptions[142] "Set the current window's floating state to false"
|
||||||
|
set descriptions[144] "Return a parsable JSON with all the config options, descriptions, value types and ranges"
|
||||||
|
set descriptions[145] "Resize a selected window"
|
||||||
|
set descriptions[146] "Toggle the focused window's internal fullscreen state"
|
||||||
|
set descriptions[147] "Print tail of the log"
|
||||||
|
set descriptions[148] "Swap the active workspaces between two monitors"
|
||||||
|
set descriptions[149] "Change the current mapping group"
|
||||||
|
set descriptions[151] "Behave as moveintogroup"
|
||||||
|
set descriptions[152] "Get the current cursor pos in global layout coordinates"
|
||||||
|
set descriptions[154] "Focus the requested workspace"
|
||||||
|
|
||||||
set --local literal_transitions
|
set literal_transitions
|
||||||
set literal_transitions[1] "set inputs 106 76 34 36 2 3 79 108 38 112 42 47 116 86 117 53 89 55 91 121 123 125 16 60 61 18 126 20 128 130 26 69 99 100 28 29 103 105; set tos 2 3 4 5 3 3 3 6 3 5 3 3 3 7 9 3 5 3 10 3 3 3 3 11 3 12 13 3 3 3 14 3 5 3 3 15 3 5"
|
set literal_transitions[1] "set inputs 121 44 126 82 4 52 51 129 90 59 9 11 12 131 14 98 102 103 134 101 138 23 20 141 26 144 108 147 70 34 35 79 115 38 152 117 122 124 40 43 80 119; set tos 15 3 22 3 22 3 3 3 3 22 3 3 4 5 6 7 3 22 8 3 3 3 3 9 3 3 10 11 3 3 3 22 3 3 3 3 14 22 12 22 16 13"
|
||||||
set literal_transitions[4] "set inputs 74 14 33 56 57 92 107 124 78 17 127 4 6 65 132 134 82 135 85 32 50 13 87 11 88 142; set tos 18 3 18 18 18 18 3 3 2 3 18 2 3 18 3 18 18 18 18 18 3 3 18 18 18 18"
|
set literal_transitions[2] "set inputs 82 52 51 129 9 90 11 12 131 14 98 102 134 101 23 20 138 141 26 144 108 147 70 34 35 115 38 152 117 40 119 122 121 80 44; set tos 3 3 3 3 3 3 3 4 5 6 7 3 8 3 3 3 3 9 3 3 10 11 3 3 3 3 3 3 3 12 13 14 15 16 3"
|
||||||
set literal_transitions[8] "set inputs 106 76 34 2 3 79 108 38 42 47 116 86 117 53 55 91 121 123 125 16 60 61 18 126 20 128 130 26 69 100 28 29 103; set tos 2 3 4 3 3 3 6 3 3 3 3 7 9 3 3 10 3 3 3 3 11 3 12 13 3 3 3 14 3 3 3 15 3"
|
set literal_transitions[4] "set inputs 140 64 65 46 106 28 27 53 6 67 68 130 114 13 75 100 36 153 99 60 118 42 18 139 155 123; set tos 3 17 17 17 17 3 3 5 17 3 17 17 17 3 5 3 17 17 17 17 17 17 3 17 3 17"
|
||||||
set literal_transitions[9] "set inputs 102 131 133 1 75 37 109 110 39 111 5 80 41 81 114 7 43 44 83 84 48 49 10 51 52 54 12 113 90 119 58 93 59 94 95 62 63 129 96 64 21 98 23 24 66 67 136 137 25 27 70 101 71 141 30 72; set tos 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"
|
set literal_transitions[7] "set inputs 127; set tos 3"
|
||||||
set literal_transitions[10] "set inputs 118 115; set tos 21 17"
|
set literal_transitions[11] "set inputs 57; set tos 3"
|
||||||
set literal_transitions[12] "set inputs 104; set tos 3"
|
set literal_transitions[12] "set inputs 10; set tos 3"
|
||||||
set literal_transitions[14] "set inputs 22 120 31 140 122 45 73; set tos 2 2 2 2 2 2 2"
|
set literal_transitions[13] "set inputs 15 81; set tos 20 23"
|
||||||
set literal_transitions[15] "set inputs 40; set tos 3"
|
set literal_transitions[14] "set inputs 143; set tos 3"
|
||||||
set literal_transitions[16] "set inputs 139 97; set tos 3 3"
|
set literal_transitions[15] "set inputs 1 85 3 86 5 88 89 91 92 93 94 95 97 16 19 104 22 105 24 25 29 30 31 109 112 33 113 37 39 120 125 47 48 49 50 54 56 132 133 135 136 61 137 142 66 145 146 69 148 71 72 73 74 149 76 77 151 154; set tos 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 21 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"
|
||||||
set literal_transitions[18] "set inputs 19 8; set tos 3 3"
|
set literal_transitions[16] "set inputs 87 7 110 62 78 55 63; set tos 5 5 5 5 5 5 5"
|
||||||
set literal_transitions[19] "set inputs 77; set tos 20"
|
set literal_transitions[17] "set inputs 41 45; set tos 3 3"
|
||||||
set literal_transitions[20] "set inputs 35 46; set tos 5 5"
|
set literal_transitions[18] "set inputs 8; set tos 24"
|
||||||
set literal_transitions[21] "set inputs 9 68 15 138; set tos 3 3 3 3"
|
set literal_transitions[19] "set inputs 32 150; set tos 3 3"
|
||||||
|
set literal_transitions[20] "set inputs 96 17 116 21; set tos 3 3 3 3"
|
||||||
|
set literal_transitions[21] "set inputs 107 83 128 2 84; set tos 3 3 3 3 3"
|
||||||
|
set literal_transitions[24] "set inputs 58 111; set tos 22 22"
|
||||||
|
|
||||||
set --local match_anything_transitions_from 2 1 7 16 11 6 15 8 3 17 13 12
|
set match_anything_transitions_from 7 8 1 23 6 5 3 19 12 9 10 14 11 2
|
||||||
set --local match_anything_transitions_to 3 8 3 3 3 16 19 8 19 3 3 19
|
set match_anything_transitions_to 18 3 2 3 19 3 18 3 18 3 3 18 18 2
|
||||||
|
|
||||||
set --local state 1
|
set state 1
|
||||||
set --local word_index 2
|
set word_index 2
|
||||||
while test $word_index -lt $COMP_CWORD
|
while test $word_index -lt $COMP_CWORD
|
||||||
set --local -- word $COMP_WORDS[$word_index]
|
set -- word $COMP_WORDS[$word_index]
|
||||||
|
|
||||||
if set --query literal_transitions[$state] && test -n $literal_transitions[$state]
|
if set --query literal_transitions[$state] && test -n $literal_transitions[$state]
|
||||||
set --local --erase inputs
|
set --erase inputs
|
||||||
set --local --erase tos
|
set --erase tos
|
||||||
eval $literal_transitions[$state]
|
eval $literal_transitions[$state]
|
||||||
|
|
||||||
if contains -- $word $literals
|
if contains -- $word $literals
|
||||||
set --local literal_matched 0
|
set literal_matched 0
|
||||||
for literal_id in (seq 1 (count $literals))
|
for literal_id in (seq 1 (count $literals))
|
||||||
if test $literals[$literal_id] = $word
|
if test $literals[$literal_id] = $word
|
||||||
set --local index (contains --index -- $literal_id $inputs)
|
set index (contains --index -- $literal_id $inputs)
|
||||||
set state $tos[$index]
|
set state $tos[$index]
|
||||||
set word_index (math $word_index + 1)
|
set word_index (math $word_index + 1)
|
||||||
set literal_matched 1
|
set literal_matched 1
|
||||||
|
@ -181,7 +196,7 @@ function _hyprctl
|
||||||
end
|
end
|
||||||
|
|
||||||
if set --query match_anything_transitions_from[$state] && test -n $match_anything_transitions_from[$state]
|
if set --query match_anything_transitions_from[$state] && test -n $match_anything_transitions_from[$state]
|
||||||
set --local index (contains --index -- $state $match_anything_transitions_from)
|
set index (contains --index -- $state $match_anything_transitions_from)
|
||||||
set state $match_anything_transitions_to[$index]
|
set state $match_anything_transitions_to[$index]
|
||||||
set word_index (math $word_index + 1)
|
set word_index (math $word_index + 1)
|
||||||
continue
|
continue
|
||||||
|
@ -191,8 +206,8 @@ function _hyprctl
|
||||||
end
|
end
|
||||||
|
|
||||||
if set --query literal_transitions[$state] && test -n $literal_transitions[$state]
|
if set --query literal_transitions[$state] && test -n $literal_transitions[$state]
|
||||||
set --local --erase inputs
|
set --erase inputs
|
||||||
set --local --erase tos
|
set --erase tos
|
||||||
eval $literal_transitions[$state]
|
eval $literal_transitions[$state]
|
||||||
for literal_id in $inputs
|
for literal_id in $inputs
|
||||||
if test -n $descriptions[$literal_id]
|
if test -n $descriptions[$literal_id]
|
||||||
|
@ -203,14 +218,14 @@ function _hyprctl
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
set command_states 6 17 13 11
|
set command_states 8 23 9 6
|
||||||
set command_ids 2 3 4 1
|
set command_ids 1 2 4 3
|
||||||
if contains $state $command_states
|
if contains $state $command_states
|
||||||
set --local index (contains --index $state $command_states)
|
set index (contains --index $state $command_states)
|
||||||
set --local function_id $command_ids[$index]
|
set function_id $command_ids[$index]
|
||||||
set --local function_name _hyprctl_$function_id
|
set function_name _hyprctl_$function_id
|
||||||
set --local --erase inputs
|
set --erase inputs
|
||||||
set --local --erase tos
|
set --erase tos
|
||||||
$function_name "$COMP_WORDS[$COMP_CWORD]"
|
$function_name "$COMP_WORDS[$COMP_CWORD]"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ hyprctl [<OPTIONS>]... <ARGUMENTS>
|
||||||
| (-r) "Refresh state after issuing the command"
|
| (-r) "Refresh state after issuing the command"
|
||||||
| (--batch) "Execute a batch of commands separated by ;"
|
| (--batch) "Execute a batch of commands separated by ;"
|
||||||
| (-q | --quiet) "Disable output"
|
| (-q | --quiet) "Disable output"
|
||||||
|
| (-h | --help) "Prints the help message"
|
||||||
;
|
;
|
||||||
|
|
||||||
<WINDOWS> ::= {{{ hyprctl clients | awk '/class/{print $2}' }}};
|
<WINDOWS> ::= {{{ hyprctl clients | awk '/class/{print $2}' }}};
|
||||||
|
@ -59,16 +60,18 @@ hyprctl [<OPTIONS>]... <ARGUMENTS>
|
||||||
|
|
||||||
<ARGUMENTS> ::= (activewindow) "Get the active window name and its properties"
|
<ARGUMENTS> ::= (activewindow) "Get the active window name and its properties"
|
||||||
| (activeworkspace) "Get the active workspace name and its properties"
|
| (activeworkspace) "Get the active workspace name and its properties"
|
||||||
|
| (animations) "Gets the current config info about animations and beziers"
|
||||||
| (binds) "List all registered binds"
|
| (binds) "List all registered binds"
|
||||||
| (clients) "List all windows with their properties"
|
| (clients) "List all windows with their properties"
|
||||||
| (configerrors) "List all current config parsing errors"
|
| (configerrors) "List all current config parsing errors"
|
||||||
| (cursorpos) "Get the current cursor pos in global layout coordinates"
|
| (cursorpos) "Get the current cursor pos in global layout coordinates"
|
||||||
| (decorations <WINDOWS>) "List all decorations and their info"
|
| (decorations <WINDOWS>) "List all decorations and their info"
|
||||||
|
| (descriptions) "Return a parsable JSON with all the config options, descriptions, value types and ranges"
|
||||||
| (devices) "List all connected keyboards and mice"
|
| (devices) "List all connected keyboards and mice"
|
||||||
| (dismissnotify <NUM>) "Dismiss all or up to amount of notifications"
|
| (dismissnotify <NUM>) "Dismiss all or up to amount of notifications"
|
||||||
| (dispatch <DISPATCHERS>) "Issue a dispatch to call a keybind dispatcher with an arg"
|
| (dispatch <DISPATCHERS>) "Issue a dispatch to call a keybind dispatcher with an arg"
|
||||||
| (getoption) "Get the config option status (values)"
|
| (getoption) "Get the config option status (values)"
|
||||||
| (globalshortcuts) ""
|
| (globalshortcuts) "Lists all global shortcuts"
|
||||||
| (hyprpaper) "Interact with hyprpaper if present"
|
| (hyprpaper) "Interact with hyprpaper if present"
|
||||||
| (instances) "List all running Hyprland instances and their info"
|
| (instances) "List all running Hyprland instances and their info"
|
||||||
| (keyword <KEYWORDS>) "Issue a keyword to call a config keyword dynamically"
|
| (keyword <KEYWORDS>) "Issue a keyword to call a config keyword dynamically"
|
||||||
|
@ -79,8 +82,8 @@ hyprctl [<OPTIONS>]... <ARGUMENTS>
|
||||||
| (notify <NOTIFICATION_TYPES> <NUM>) "Send a notification using the built-in Hyprland notification system"
|
| (notify <NOTIFICATION_TYPES> <NUM>) "Send a notification using the built-in Hyprland notification system"
|
||||||
| (output (create (wayland | x11 | headless | auto) | remove <MONITORS>)) "Allows adding/removing fake outputs to a specific backend"
|
| (output (create (wayland | x11 | headless | auto) | remove <MONITORS>)) "Allows adding/removing fake outputs to a specific backend"
|
||||||
| (plugin <AVAILABLE_PLUGINS>) "Interact with a plugin"
|
| (plugin <AVAILABLE_PLUGINS>) "Interact with a plugin"
|
||||||
| (reload) "Force reload the config"
|
| (reload [config-only]) "Force reload the config"
|
||||||
| (rollinglog) "Print tail of the log"
|
| (rollinglog [-f]) "Print tail of the log"
|
||||||
| (setcursor) "Set the cursor theme and reloads the cursor manager"
|
| (setcursor) "Set the cursor theme and reloads the cursor manager"
|
||||||
| (seterror [disable]) "Set the hyprctl error string"
|
| (seterror [disable]) "Set the hyprctl error string"
|
||||||
| (setprop <PROPS>) "Set a property of a window"
|
| (setprop <PROPS>) "Set a property of a window"
|
||||||
|
@ -92,6 +95,13 @@ hyprctl [<OPTIONS>]... <ARGUMENTS>
|
||||||
| (workspaces) "List all workspaces with their properties"
|
| (workspaces) "List all workspaces with their properties"
|
||||||
;
|
;
|
||||||
|
|
||||||
|
<WINDOW_STATE> ::= (-1) "Current"
|
||||||
|
| (0) "None"
|
||||||
|
| (1) "Maximize no fullscreen"
|
||||||
|
| (2) "Fullscreen"
|
||||||
|
| (3) "Maximize and fullscreen"
|
||||||
|
;
|
||||||
|
|
||||||
<DISPATCHERS> ::= (exec) "Execute a shell command"
|
<DISPATCHERS> ::= (exec) "Execute a shell command"
|
||||||
| (execr) "Execute a raw shell command"
|
| (execr) "Execute a raw shell command"
|
||||||
| (pass) "Pass the key to a specified window"
|
| (pass) "Pass the key to a specified window"
|
||||||
|
@ -106,6 +116,7 @@ hyprctl [<OPTIONS>]... <ARGUMENTS>
|
||||||
| (settiled) "Set the current window's floating state to false"
|
| (settiled) "Set the current window's floating state to false"
|
||||||
| (fullscreen) "Toggle the focused window's fullscreen state"
|
| (fullscreen) "Toggle the focused window's fullscreen state"
|
||||||
| (fakefullscreen) "Toggle the focused window's internal fullscreen state"
|
| (fakefullscreen) "Toggle the focused window's internal fullscreen state"
|
||||||
|
| (fullscreenstate <WINDOW_STATE>) "Sets the focused window’s fullscreen mode and the one sent to the client"
|
||||||
| (dpms) "Set all monitors' DPMS status"
|
| (dpms) "Set all monitors' DPMS status"
|
||||||
| (pin) "Pin a window"
|
| (pin) "Pin a window"
|
||||||
| (movefocus) "Move the focus in a direction"
|
| (movefocus) "Move the focus in a direction"
|
||||||
|
@ -148,4 +159,5 @@ hyprctl [<OPTIONS>]... <ARGUMENTS>
|
||||||
| (setignoregrouplock) "Temporarily enable or disable binds:ignore_group_lock"
|
| (setignoregrouplock) "Temporarily enable or disable binds:ignore_group_lock"
|
||||||
| (global) "Execute a Global Shortcut using the GlobalShortcuts portal"
|
| (global) "Execute a Global Shortcut using the GlobalShortcuts portal"
|
||||||
| (submap) "Change the current mapping group"
|
| (submap) "Change the current mapping group"
|
||||||
|
| (event) "Emits a custom event to socket2"
|
||||||
;
|
;
|
||||||
|
|
|
@ -1,145 +1,160 @@
|
||||||
#compdef hyprctl
|
#compdef hyprctl
|
||||||
|
|
||||||
_hyprctl_cmd_2 () {
|
_hyprctl_cmd_1 () {
|
||||||
hyprctl monitors | awk '/Monitor/{ print $2 }'
|
hyprctl monitors | awk '/Monitor/{ print $2 }'
|
||||||
}
|
}
|
||||||
|
|
||||||
_hyprctl_cmd_3 () {
|
_hyprctl_cmd_3 () {
|
||||||
hyprpm list | awk '/Plugin/{ print $4 }'
|
|
||||||
}
|
|
||||||
|
|
||||||
_hyprctl_cmd_0 () {
|
|
||||||
hyprctl clients | awk '/class/{print $2}'
|
hyprctl clients | awk '/class/{print $2}'
|
||||||
}
|
}
|
||||||
|
|
||||||
_hyprctl_cmd_1 () {
|
_hyprctl_cmd_2 () {
|
||||||
hyprctl devices | sed -n '/Keyboard at/{n; s/^\s\+//; p}'
|
hyprctl devices | sed -n '/Keyboard at/{n; s/^\s\+//; p}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_hyprctl_cmd_0 () {
|
||||||
|
hyprpm list | awk '/Plugin/{print $4}'
|
||||||
|
}
|
||||||
|
|
||||||
_hyprctl () {
|
_hyprctl () {
|
||||||
local -a literals=("cyclenext" "globalshortcuts" "cursorpos" "bordersize" "renameworkspace" "animationstyle" "focuswindow" "0" "auto" "swapnext" "forceallowsinput" "moveactive" "activebordercolor" "alphafullscreen" "wayland" "layers" "minsize" "monitors" "1" "kill" "settiled" "3" "focusmonitor" "swapwindow" "moveoutofgroup" "notify" "movecursor" "setcursor" "seterror" "movecurrentworkspacetomonitor" "4" "nomaxsize" "forcenoanims" "setprop" "-i" "-q" "togglefloating" "workspacerules" "movetoworkspace" "disable" "setignoregrouplock" "workspaces" "movegroupwindow" "closewindow" "0" "--instance" "binds" "movewindow" "splitratio" "alpha" "denywindowfromgroup" "workspace" "configerrors" "togglegroup" "getoption" "forceopaque" "keepaspectratio" "killactive" "pass" "decorations" "devices" "focuscurrentorlast" "submap" "global" "alphafullscreenoverride" "forcerendererreload" "movewindowpixel" "headless" "version" "dpms" "resizeactive" "moveintogroup" "5" "alphaoverride" "setfloating" "rollinglog" "::=" "rounding" "layouts" "moveworkspacetomonitor" "exec" "alphainactiveoverride" "alterzorder" "fakefullscreen" "nofocus" "keyword" "forcenoborder" "forcenodim" "--quiet" "pin" "output" "forcenoblur" "togglespecialworkspace" "fullscreen" "toggleopaque" "focusworkspaceoncurrentmonitor" "next" "changegroupactive" "-j" "instances" "execr" "exit" "clients" "all" "--batch" "dismissnotify" "inactivebordercolor" "switchxkblayout" "movetoworkspacesilent" "tagwindow" "movewindoworgroup" "-r" "movefocus" "focusurgentorlast" "remove" "activeworkspace" "dispatch" "create" "centerwindow" "2" "hyprpaper" "-1" "reload" "alphainactive" "systeminfo" "plugin" "dimaround" "activewindow" "swapactiveworkspaces" "splash" "sendshortcut" "maxsize" "lockactivegroup" "windowdancecompat" "forceopaqueoverriden" "lockgroups" "movecursortocorner" "x11" "prev" "1" "resizewindowpixel" "forcenoshadow")
|
local -a literals=("resizeactive" "2" "changegroupactive" "-r" "moveintogroup" "forceallowsinput" "4" "::=" "systeminfo" "all" "layouts" "setprop" "animationstyle" "switchxkblayout" "create" "denywindowfromgroup" "headless" "activebordercolor" "exec" "setcursor" "wayland" "focusurgentorlast" "workspacerules" "movecurrentworkspacetomonitor" "movetoworkspacesilent" "hyprpaper" "alpha" "inactivebordercolor" "movegroupwindow" "movecursortocorner" "movewindowpixel" "prev" "movewindow" "globalshortcuts" "clients" "dimaround" "setignoregrouplock" "splash" "execr" "monitors" "0" "forcenoborder" "-q" "animations" "1" "nomaxsize" "splitratio" "moveactive" "pass" "swapnext" "devices" "layers" "rounding" "lockactivegroup" "5" "moveworkspacetomonitor" "-f" "-i" "--quiet" "forcenodim" "pin" "0" "1" "forceopaque" "forcenoshadow" "setfloating" "minsize" "alphaoverride" "sendshortcut" "workspaces" "cyclenext" "alterzorder" "togglegroup" "lockgroups" "bordersize" "dpms" "focuscurrentorlast" "-1" "--batch" "notify" "remove" "instances" "1" "3" "moveoutofgroup" "killactive" "2" "movetoworkspace" "movecursor" "configerrors" "closewindow" "swapwindow" "tagwindow" "forcerendererreload" "centerwindow" "auto" "focuswindow" "seterror" "nofocus" "alphafullscreen" "binds" "version" "-h" "togglespecialworkspace" "fullscreen" "windowdancecompat" "0" "keyword" "toggleopaque" "3" "--instance" "togglefloating" "renameworkspace" "alphafullscreenoverride" "activeworkspace" "x11" "kill" "forceopaqueoverriden" "output" "global" "dispatch" "reload" "forcenoblur" "-j" "event" "--help" "disable" "-1" "activewindow" "keepaspectratio" "dismissnotify" "focusmonitor" "movefocus" "plugin" "exit" "workspace" "fullscreenstate" "getoption" "alphainactiveoverride" "alphainactive" "decorations" "settiled" "config-only" "descriptions" "resizewindowpixel" "fakefullscreen" "rollinglog" "swapactiveworkspaces" "submap" "next" "movewindoworgroup" "cursorpos" "forcenoanims" "focusworkspaceoncurrentmonitor" "maxsize")
|
||||||
|
|
||||||
local -A descriptions
|
local -A descriptions
|
||||||
descriptions[1]="Focus the next window on a workspace"
|
descriptions[1]="Resize the active window"
|
||||||
descriptions[3]="Get the current cursor pos in global layout coordinates"
|
descriptions[2]="Fullscreen"
|
||||||
descriptions[5]="Rename a workspace"
|
descriptions[3]="Switch to the next window in a group"
|
||||||
descriptions[7]="Focus the first window matching"
|
descriptions[4]="Refresh state after issuing the command"
|
||||||
descriptions[10]="Swap the focused window with the next window"
|
descriptions[5]="Move the active window into a group"
|
||||||
descriptions[12]="Move the active window"
|
descriptions[7]="CONFUSED"
|
||||||
descriptions[16]="List the layers"
|
descriptions[9]="Print system info"
|
||||||
descriptions[18]="List active outputs with their properties"
|
descriptions[11]="List all layouts available (including plugin ones)"
|
||||||
descriptions[20]="Get into a kill mode, where you can kill an app by clicking on it"
|
descriptions[12]="Set a property of a window"
|
||||||
descriptions[21]="Set the current window's floating state to false"
|
descriptions[14]="Set the xkb layout index for a keyboard"
|
||||||
descriptions[22]="ERROR"
|
descriptions[16]="Prohibit the active window from becoming or being inserted into group"
|
||||||
descriptions[23]="Focus a monitor"
|
descriptions[19]="Execute a shell command"
|
||||||
descriptions[24]="Swap the active window with another window"
|
descriptions[20]="Set the cursor theme and reloads the cursor manager"
|
||||||
descriptions[25]="Move the active window out of a group"
|
descriptions[22]="Focus the urgent window or the last window"
|
||||||
descriptions[26]="Send a notification using the built-in Hyprland notification system"
|
descriptions[23]="Get the list of defined workspace rules"
|
||||||
descriptions[27]="Move the cursor to a specified position"
|
descriptions[24]="Move the active workspace to a monitor"
|
||||||
descriptions[28]="Set the cursor theme and reloads the cursor manager"
|
descriptions[25]="Move window doesnt switch to the workspace"
|
||||||
descriptions[29]="Set the hyprctl error string"
|
descriptions[26]="Interact with hyprpaper if present"
|
||||||
descriptions[30]="Move the active workspace to a monitor"
|
descriptions[29]="Swap the active window with the next or previous in a group"
|
||||||
descriptions[31]="CONFUSED"
|
descriptions[30]="Move the cursor to the corner of the active window"
|
||||||
descriptions[34]="Set a property of a window"
|
descriptions[31]="Move a selected window"
|
||||||
descriptions[35]="Specify the Hyprland instance"
|
descriptions[33]="Move the active window in a direction or to a monitor"
|
||||||
descriptions[36]="Disable output"
|
descriptions[34]="Lists all global shortcuts"
|
||||||
descriptions[37]="Toggle the current window's floating state"
|
descriptions[35]="List all windows with their properties"
|
||||||
descriptions[38]="Get the list of defined workspace rules"
|
descriptions[37]="Temporarily enable or disable binds:ignore_group_lock"
|
||||||
descriptions[39]="Move the focused window to a workspace"
|
descriptions[38]="Print the current random splash"
|
||||||
descriptions[41]="Temporarily enable or disable binds:ignore_group_lock"
|
descriptions[39]="Execute a raw shell command"
|
||||||
descriptions[42]="List all workspaces with their properties"
|
descriptions[40]="List active outputs with their properties"
|
||||||
descriptions[43]="Swap the active window with the next or previous in a group"
|
descriptions[43]="Disable output"
|
||||||
descriptions[44]="Close a specified window"
|
descriptions[44]="Gets the current config info about animations and beziers"
|
||||||
descriptions[45]="WARNING"
|
descriptions[47]="Change the split ratio"
|
||||||
descriptions[46]="Specify the Hyprland instance"
|
descriptions[48]="Move the active window"
|
||||||
descriptions[47]="List all registered binds"
|
descriptions[49]="Pass the key to a specified window"
|
||||||
descriptions[48]="Move the active window in a direction or to a monitor"
|
descriptions[50]="Swap the focused window with the next window"
|
||||||
descriptions[49]="Change the split ratio"
|
descriptions[51]="List all connected keyboards and mice"
|
||||||
descriptions[51]="Prohibit the active window from becoming or being inserted into group"
|
descriptions[52]="List the layers"
|
||||||
descriptions[52]="Change the workspace"
|
descriptions[54]="Lock the focused group"
|
||||||
descriptions[53]="List all current config parsing errors"
|
descriptions[55]="OK"
|
||||||
descriptions[54]="Toggle the current active window into a group"
|
descriptions[56]="Move a workspace to a monitor"
|
||||||
descriptions[55]="Get the config option status (values)"
|
descriptions[58]="Specify the Hyprland instance"
|
||||||
descriptions[58]="Close the active window"
|
descriptions[59]="Disable output"
|
||||||
descriptions[59]="Pass the key to a specified window"
|
descriptions[61]="Pin a window"
|
||||||
descriptions[60]="List all decorations and their info"
|
descriptions[62]="WARNING"
|
||||||
descriptions[61]="List all connected keyboards and mice"
|
descriptions[63]="INFO"
|
||||||
descriptions[62]="Switch focus from current to previously focused window"
|
descriptions[66]="Set the current window's floating state to true"
|
||||||
descriptions[63]="Change the current mapping group"
|
descriptions[69]="On shortcut X sends shortcut Y to a specified window"
|
||||||
descriptions[64]="Execute a Global Shortcut using the GlobalShortcuts portal"
|
descriptions[70]="List all workspaces with their properties"
|
||||||
descriptions[66]="Force the renderer to reload all resources and outputs"
|
descriptions[71]="Focus the next window on a workspace"
|
||||||
descriptions[67]="Move a selected window"
|
descriptions[72]="Modify the window stack order of the active or specified window"
|
||||||
descriptions[69]="Print the Hyprland version: flags, commit and branch of build"
|
descriptions[73]="Toggle the current active window into a group"
|
||||||
descriptions[70]="Set all monitors' DPMS status"
|
descriptions[74]="Lock the groups"
|
||||||
descriptions[71]="Resize the active window"
|
descriptions[76]="Set all monitors' DPMS status"
|
||||||
descriptions[72]="Move the active window into a group"
|
descriptions[77]="Switch focus from current to previously focused window"
|
||||||
descriptions[73]="OK"
|
descriptions[78]="No Icon"
|
||||||
descriptions[75]="Set the current window's floating state to true"
|
descriptions[79]="Execute a batch of commands separated by ;"
|
||||||
descriptions[76]="Print tail of the log"
|
descriptions[80]="Send a notification using the built-in Hyprland notification system"
|
||||||
descriptions[79]="List all layouts available (including plugin ones)"
|
descriptions[82]="List all running Hyprland instances and their info"
|
||||||
descriptions[80]="Move a workspace to a monitor"
|
descriptions[83]="Maximize no fullscreen"
|
||||||
descriptions[81]="Execute a shell command"
|
descriptions[84]="Maximize and fullscreen"
|
||||||
descriptions[83]="Modify the window stack order of the active or specified window"
|
descriptions[85]="Move the active window out of a group"
|
||||||
descriptions[84]="Toggle the focused window's internal fullscreen state"
|
descriptions[86]="Close the active window"
|
||||||
descriptions[86]="Issue a keyword to call a config keyword dynamically"
|
descriptions[87]="HINT"
|
||||||
descriptions[89]="Disable output"
|
descriptions[88]="Move the focused window to a workspace"
|
||||||
descriptions[90]="Pin a window"
|
descriptions[89]="Move the cursor to a specified position"
|
||||||
descriptions[91]="Allows adding/removing fake outputs to a specific backend"
|
descriptions[90]="List all current config parsing errors"
|
||||||
descriptions[93]="Toggle a special workspace on/off"
|
descriptions[91]="Close a specified window"
|
||||||
descriptions[94]="Toggle the focused window's fullscreen state"
|
descriptions[92]="Swap the active window with another window"
|
||||||
descriptions[95]="Toggle the current window to always be opaque"
|
descriptions[93]="Apply a tag to the window"
|
||||||
descriptions[96]="Focus the requested workspace"
|
descriptions[94]="Force the renderer to reload all resources and outputs"
|
||||||
descriptions[98]="Switch to the next window in a group"
|
descriptions[95]="Center the active window"
|
||||||
descriptions[99]="Output in JSON format"
|
descriptions[97]="Focus the first window matching"
|
||||||
descriptions[100]="List all running Hyprland instances and their info"
|
descriptions[98]="Set the hyprctl error string"
|
||||||
descriptions[101]="Execute a raw shell command"
|
descriptions[101]="List all registered binds"
|
||||||
descriptions[102]="Exit the compositor with no questions asked"
|
descriptions[102]="Print the Hyprland version: flags, commit and branch of build"
|
||||||
descriptions[103]="List all windows with their properties"
|
descriptions[103]="Prints the help message"
|
||||||
descriptions[105]="Execute a batch of commands separated by ;"
|
descriptions[104]="Toggle a special workspace on/off"
|
||||||
descriptions[106]="Dismiss all or up to amount of notifications"
|
descriptions[105]="Toggle the focused window's fullscreen state"
|
||||||
descriptions[108]="Set the xkb layout index for a keyboard"
|
descriptions[107]="None"
|
||||||
descriptions[109]="Move window doesnt switch to the workspace"
|
descriptions[108]="Issue a keyword to call a config keyword dynamically"
|
||||||
descriptions[110]="Apply a tag to the window"
|
descriptions[109]="Toggle the current window to always be opaque"
|
||||||
descriptions[111]="Behave as moveintogroup"
|
descriptions[110]="ERROR"
|
||||||
descriptions[112]="Refresh state after issuing the command"
|
descriptions[111]="Specify the Hyprland instance"
|
||||||
descriptions[113]="Move the focus in a direction"
|
descriptions[112]="Toggle the current window's floating state"
|
||||||
descriptions[114]="Focus the urgent window or the last window"
|
descriptions[113]="Rename a workspace"
|
||||||
descriptions[116]="Get the active workspace name and its properties"
|
descriptions[115]="Get the active workspace name and its properties"
|
||||||
descriptions[117]="Issue a dispatch to call a keybind dispatcher with an arg"
|
descriptions[117]="Get into a kill mode, where you can kill an app by clicking on it"
|
||||||
descriptions[119]="Center the active window"
|
descriptions[119]="Allows adding/removing fake outputs to a specific backend"
|
||||||
descriptions[120]="HINT"
|
descriptions[120]="Execute a Global Shortcut using the GlobalShortcuts portal"
|
||||||
descriptions[121]="Interact with hyprpaper if present"
|
descriptions[121]="Issue a dispatch to call a keybind dispatcher with an arg"
|
||||||
descriptions[122]="No Icon"
|
descriptions[122]="Force reload the config"
|
||||||
descriptions[123]="Force reload the config"
|
descriptions[124]="Output in JSON format"
|
||||||
descriptions[125]="Print system info"
|
descriptions[125]="Emits a custom event to socket2"
|
||||||
descriptions[126]="Interact with a plugin"
|
descriptions[126]="Prints the help message"
|
||||||
descriptions[128]="Get the active window name and its properties"
|
descriptions[128]="Current"
|
||||||
descriptions[129]="Swap the active workspaces between two monitors"
|
descriptions[129]="Get the active window name and its properties"
|
||||||
descriptions[130]="Print the current random splash"
|
descriptions[131]="Dismiss all or up to amount of notifications"
|
||||||
descriptions[131]="On shortcut X sends shortcut Y to a specified window"
|
descriptions[132]="Focus a monitor"
|
||||||
descriptions[133]="Lock the focused group"
|
descriptions[133]="Move the focus in a direction"
|
||||||
descriptions[136]="Lock the groups"
|
descriptions[134]="Interact with a plugin"
|
||||||
descriptions[137]="Move the cursor to the corner of the active window"
|
descriptions[135]="Exit the compositor with no questions asked"
|
||||||
descriptions[140]="INFO"
|
descriptions[136]="Change the workspace"
|
||||||
descriptions[141]="Resize a selected window"
|
descriptions[137]="Sets the focused window’s fullscreen mode and the one sent to the client"
|
||||||
|
descriptions[138]="Get the config option status (values)"
|
||||||
|
descriptions[141]="List all decorations and their info"
|
||||||
|
descriptions[142]="Set the current window's floating state to false"
|
||||||
|
descriptions[144]="Return a parsable JSON with all the config options, descriptions, value types and ranges"
|
||||||
|
descriptions[145]="Resize a selected window"
|
||||||
|
descriptions[146]="Toggle the focused window's internal fullscreen state"
|
||||||
|
descriptions[147]="Print tail of the log"
|
||||||
|
descriptions[148]="Swap the active workspaces between two monitors"
|
||||||
|
descriptions[149]="Change the current mapping group"
|
||||||
|
descriptions[151]="Behave as moveintogroup"
|
||||||
|
descriptions[152]="Get the current cursor pos in global layout coordinates"
|
||||||
|
descriptions[154]="Focus the requested workspace"
|
||||||
|
|
||||||
local -A literal_transitions
|
local -A literal_transitions
|
||||||
literal_transitions[1]="([106]=2 [76]=3 [34]=4 [36]=5 [2]=3 [3]=3 [79]=3 [108]=6 [38]=3 [112]=5 [42]=3 [47]=3 [116]=3 [86]=7 [117]=9 [53]=3 [89]=5 [55]=3 [91]=10 [121]=3 [123]=3 [125]=3 [16]=3 [60]=11 [61]=3 [18]=12 [126]=13 [20]=3 [128]=3 [130]=3 [26]=14 [69]=3 [99]=5 [100]=3 [28]=3 [29]=15 [103]=3 [105]=5)"
|
literal_transitions[1]="([121]=15 [44]=3 [126]=22 [82]=3 [4]=22 [52]=3 [51]=3 [129]=3 [90]=3 [59]=22 [9]=3 [11]=3 [12]=4 [131]=5 [14]=6 [98]=7 [102]=3 [103]=22 [134]=8 [101]=3 [138]=3 [23]=3 [20]=3 [141]=9 [26]=3 [144]=3 [108]=10 [147]=11 [70]=3 [34]=3 [35]=3 [79]=22 [115]=3 [38]=3 [152]=3 [117]=3 [122]=14 [124]=22 [40]=12 [43]=22 [80]=16 [119]=13)"
|
||||||
literal_transitions[4]="([74]=18 [14]=3 [33]=18 [56]=18 [57]=18 [92]=18 [107]=3 [124]=3 [78]=2 [17]=3 [127]=18 [4]=2 [6]=3 [65]=18 [132]=3 [134]=18 [82]=18 [135]=18 [85]=18 [32]=18 [50]=3 [13]=3 [87]=18 [11]=18 [88]=18 [142]=18)"
|
literal_transitions[2]="([82]=3 [52]=3 [51]=3 [129]=3 [9]=3 [90]=3 [11]=3 [12]=4 [131]=5 [14]=6 [98]=7 [102]=3 [134]=8 [101]=3 [23]=3 [20]=3 [138]=3 [141]=9 [26]=3 [144]=3 [108]=10 [147]=11 [70]=3 [34]=3 [35]=3 [115]=3 [38]=3 [152]=3 [117]=3 [40]=12 [119]=13 [122]=14 [121]=15 [80]=16 [44]=3)"
|
||||||
literal_transitions[8]="([106]=2 [76]=3 [34]=4 [2]=3 [3]=3 [79]=3 [108]=6 [38]=3 [42]=3 [47]=3 [116]=3 [86]=7 [117]=9 [53]=3 [55]=3 [91]=10 [121]=3 [123]=3 [125]=3 [16]=3 [60]=11 [61]=3 [18]=12 [126]=13 [20]=3 [128]=3 [130]=3 [26]=14 [69]=3 [100]=3 [28]=3 [29]=15 [103]=3)"
|
literal_transitions[4]="([140]=3 [64]=17 [65]=17 [46]=17 [106]=17 [28]=3 [27]=3 [53]=5 [6]=17 [67]=3 [68]=17 [130]=17 [114]=17 [13]=3 [75]=5 [100]=3 [36]=17 [153]=17 [99]=17 [60]=17 [118]=17 [42]=17 [18]=3 [139]=17 [155]=3 [123]=17)"
|
||||||
literal_transitions[9]="([102]=3 [131]=3 [133]=3 [1]=3 [75]=3 [37]=3 [109]=3 [110]=3 [39]=3 [111]=3 [5]=3 [80]=3 [41]=3 [81]=3 [114]=3 [7]=3 [43]=3 [44]=3 [83]=3 [84]=3 [48]=3 [49]=3 [10]=3 [51]=3 [52]=3 [54]=3 [12]=3 [113]=3 [90]=3 [119]=3 [58]=3 [93]=3 [59]=3 [94]=3 [95]=3 [62]=3 [63]=3 [129]=3 [96]=3 [64]=3 [21]=3 [98]=3 [23]=3 [24]=3 [66]=3 [67]=3 [136]=3 [137]=3 [25]=3 [27]=3 [70]=3 [101]=3 [71]=3 [141]=3 [30]=3 [72]=3)"
|
literal_transitions[7]="([127]=3)"
|
||||||
literal_transitions[10]="([118]=21 [115]=17)"
|
literal_transitions[11]="([57]=3)"
|
||||||
literal_transitions[12]="([104]=3)"
|
literal_transitions[12]="([10]=3)"
|
||||||
literal_transitions[14]="([22]=2 [120]=2 [31]=2 [140]=2 [122]=2 [45]=2 [73]=2)"
|
literal_transitions[13]="([15]=20 [81]=23)"
|
||||||
literal_transitions[15]="([40]=3)"
|
literal_transitions[14]="([143]=3)"
|
||||||
literal_transitions[16]="([139]=3 [97]=3)"
|
literal_transitions[15]="([1]=3 [85]=3 [3]=3 [86]=3 [5]=3 [88]=3 [89]=3 [91]=3 [92]=3 [93]=3 [94]=3 [95]=3 [97]=3 [16]=3 [19]=3 [104]=3 [22]=3 [105]=3 [24]=3 [25]=3 [29]=3 [30]=3 [31]=3 [109]=3 [112]=3 [33]=3 [113]=3 [37]=3 [39]=3 [120]=3 [125]=3 [47]=3 [48]=3 [49]=3 [50]=3 [54]=3 [56]=3 [132]=3 [133]=3 [135]=3 [136]=3 [61]=3 [137]=21 [142]=3 [66]=3 [145]=3 [146]=3 [69]=3 [148]=3 [71]=3 [72]=3 [73]=3 [74]=3 [149]=3 [76]=3 [77]=3 [151]=3 [154]=3)"
|
||||||
literal_transitions[18]="([19]=3 [8]=3)"
|
literal_transitions[16]="([87]=5 [7]=5 [110]=5 [62]=5 [78]=5 [55]=5 [63]=5)"
|
||||||
literal_transitions[19]="([77]=20)"
|
literal_transitions[17]="([41]=3 [45]=3)"
|
||||||
literal_transitions[20]="([35]=5 [46]=5)"
|
literal_transitions[18]="([8]=24)"
|
||||||
literal_transitions[21]="([9]=3 [68]=3 [15]=3 [138]=3)"
|
literal_transitions[19]="([32]=3 [150]=3)"
|
||||||
|
literal_transitions[20]="([96]=3 [17]=3 [116]=3 [21]=3)"
|
||||||
|
literal_transitions[21]="([107]=3 [83]=3 [128]=3 [2]=3 [84]=3)"
|
||||||
|
literal_transitions[24]="([58]=22 [111]=22)"
|
||||||
|
|
||||||
local -A match_anything_transitions
|
local -A match_anything_transitions
|
||||||
match_anything_transitions=([2]=3 [1]=8 [7]=3 [16]=3 [11]=3 [6]=16 [15]=19 [8]=8 [3]=19 [17]=3 [13]=3 [12]=19)
|
match_anything_transitions=([7]=18 [8]=3 [1]=2 [23]=3 [6]=19 [5]=3 [3]=18 [19]=3 [12]=18 [9]=3 [10]=3 [14]=18 [11]=18 [2]=2)
|
||||||
|
|
||||||
declare -A subword_transitions
|
declare -A subword_transitions
|
||||||
|
|
||||||
|
@ -199,7 +214,7 @@ _hyprctl () {
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
local -A commands=([6]=1 [17]=2 [13]=3 [11]=0)
|
local -A commands=([8]=0 [23]=1 [9]=3 [6]=2)
|
||||||
|
|
||||||
if [[ -v "commands[$state]" ]]; then
|
if [[ -v "commands[$state]" ]]; then
|
||||||
local command_id=${commands[$state]}
|
local command_id=${commands[$state]}
|
||||||
|
@ -252,4 +267,8 @@ _hyprctl () {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if [[ $ZSH_EVAL_CONTEXT =~ :file$ ]]; then
|
||||||
compdef _hyprctl hyprctl
|
compdef _hyprctl hyprctl
|
||||||
|
else
|
||||||
|
_hyprctl
|
||||||
|
fi
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <print>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <hyprutils/string/String.hpp>
|
#include <hyprutils/string/String.hpp>
|
||||||
|
#include <cstring>
|
||||||
using namespace Hyprutils::String;
|
using namespace Hyprutils::String;
|
||||||
|
|
||||||
#include "Strings.hpp"
|
#include "Strings.hpp"
|
||||||
|
@ -43,11 +45,11 @@ struct SInstanceData {
|
||||||
bool valid = true;
|
bool valid = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
void log(std::string str) {
|
void log(const std::string& str) {
|
||||||
if (quiet)
|
if (quiet)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::cout << str << "\n";
|
std::println("{}", str);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getRuntimeDir() {
|
std::string getRuntimeDir() {
|
||||||
|
@ -104,7 +106,7 @@ std::vector<SInstanceData> instances() {
|
||||||
static volatile bool sigintReceived = false;
|
static volatile bool sigintReceived = false;
|
||||||
void intHandler(int sig) {
|
void intHandler(int sig) {
|
||||||
sigintReceived = true;
|
sigintReceived = true;
|
||||||
std::cout << "[hyprctl] SIGINT received, closing connection" << std::endl;
|
std::println("[hyprctl] SIGINT received, closing connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
int rollingRead(const int socket) {
|
int rollingRead(const int socket) {
|
||||||
|
@ -113,13 +115,13 @@ int rollingRead(const int socket) {
|
||||||
|
|
||||||
constexpr size_t BUFFER_SIZE = 8192;
|
constexpr size_t BUFFER_SIZE = 8192;
|
||||||
std::array<char, BUFFER_SIZE> buffer = {0};
|
std::array<char, BUFFER_SIZE> buffer = {0};
|
||||||
int sizeWritten = 0;
|
long sizeWritten = 0;
|
||||||
std::cout << "[hyprctl] reading from socket following up log:" << std::endl;
|
std::println("[hyprctl] reading from socket following up log:");
|
||||||
while (!sigintReceived) {
|
while (!sigintReceived) {
|
||||||
sizeWritten = read(socket, buffer.data(), BUFFER_SIZE);
|
sizeWritten = read(socket, buffer.data(), BUFFER_SIZE);
|
||||||
if (sizeWritten < 0 && errno != EAGAIN) {
|
if (sizeWritten < 0 && errno != EAGAIN) {
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
std::cout << "Couldn't read (5) " << strerror(errno) << ":" << errno << std::endl;
|
std::println("Couldn't read (5): {}: {}", strerror(errno), errno);
|
||||||
close(socket);
|
close(socket);
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +130,7 @@ int rollingRead(const int socket) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (sizeWritten > 0) {
|
if (sizeWritten > 0) {
|
||||||
std::cout << std::string(buffer.data(), sizeWritten);
|
std::println("{}", std::string(buffer.data(), sizeWritten));
|
||||||
buffer.fill('\0');
|
buffer.fill('\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,12 +288,12 @@ void instancesRequest(bool json) {
|
||||||
std::vector<SInstanceData> inst = instances();
|
std::vector<SInstanceData> inst = instances();
|
||||||
|
|
||||||
if (!json) {
|
if (!json) {
|
||||||
for (auto& el : inst) {
|
for (auto const& el : inst) {
|
||||||
result += std::format("instance {}:\n\ttime: {}\n\tpid: {}\n\twl socket: {}\n\n", el.id, el.time, el.pid, el.wlSocket);
|
result += std::format("instance {}:\n\ttime: {}\n\tpid: {}\n\twl socket: {}\n\n", el.id, el.time, el.pid, el.wlSocket);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result += '[';
|
result += '[';
|
||||||
for (auto& el : inst) {
|
for (auto const& el : inst) {
|
||||||
result += std::format(R"#(
|
result += std::format(R"#(
|
||||||
{{
|
{{
|
||||||
"instance": "{}",
|
"instance": "{}",
|
||||||
|
@ -322,7 +324,7 @@ int main(int argc, char** argv) {
|
||||||
bool parseArgs = true;
|
bool parseArgs = true;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
std::cout << USAGE << std::endl;
|
std::println("{}", USAGE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +361,7 @@ int main(int argc, char** argv) {
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
if (i >= ARGS.size()) {
|
if (i >= ARGS.size()) {
|
||||||
std::cout << USAGE << std::endl;
|
std::println("{}", USAGE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,24 +372,24 @@ int main(int argc, char** argv) {
|
||||||
const std::string& cmd = ARGS[0];
|
const std::string& cmd = ARGS[0];
|
||||||
|
|
||||||
if (cmd == "hyprpaper") {
|
if (cmd == "hyprpaper") {
|
||||||
std::cout << HYPRPAPER_HELP << std::endl;
|
std::println("{}", HYPRPAPER_HELP);
|
||||||
} else if (cmd == "notify") {
|
} else if (cmd == "notify") {
|
||||||
std::cout << NOTIFY_HELP << std::endl;
|
std::println("{}", NOTIFY_HELP);
|
||||||
} else if (cmd == "output") {
|
} else if (cmd == "output") {
|
||||||
std::cout << OUTPUT_HELP << std::endl;
|
std::println("{}", OUTPUT_HELP);
|
||||||
} else if (cmd == "plugin") {
|
} else if (cmd == "plugin") {
|
||||||
std::cout << PLUGIN_HELP << std::endl;
|
std::println("{}", PLUGIN_HELP);
|
||||||
} else if (cmd == "setprop") {
|
} else if (cmd == "setprop") {
|
||||||
std::cout << SETPROP_HELP << std::endl;
|
std::println("{}", SETPROP_HELP);
|
||||||
} else if (cmd == "switchxkblayout") {
|
} else if (cmd == "switchxkblayout") {
|
||||||
std::cout << SWITCHXKBLAYOUT_HELP << std::endl;
|
std::println("{}", SWITCHXKBLAYOUT_HELP);
|
||||||
} else {
|
} else {
|
||||||
std::cout << USAGE << std::endl;
|
std::println("{}", USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
std::cout << USAGE << std::endl;
|
std::println("{}", USAGE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +400,7 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fullRequest.empty()) {
|
if (fullRequest.empty()) {
|
||||||
std::cout << USAGE << std::endl;
|
std::println("{}", USAGE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,7 +477,7 @@ int main(int argc, char** argv) {
|
||||||
else if (fullRequest.contains("/decorations"))
|
else if (fullRequest.contains("/decorations"))
|
||||||
exitStatus = request(fullRequest, 1);
|
exitStatus = request(fullRequest, 1);
|
||||||
else if (fullRequest.contains("/--help"))
|
else if (fullRequest.contains("/--help"))
|
||||||
std::cout << USAGE << std::endl;
|
std::println("{}", USAGE);
|
||||||
else if (fullRequest.contains("/rollinglog") && needRoll)
|
else if (fullRequest.contains("/rollinglog") && needRoll)
|
||||||
exitStatus = request(fullRequest, 0, true);
|
exitStatus = request(fullRequest, 0, true);
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1,10 +1,26 @@
|
||||||
executable('hyprctl', 'main.cpp',
|
executable(
|
||||||
|
'hyprctl',
|
||||||
|
'main.cpp',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
dependency('hyprutils', version: '>= 0.1.1'),
|
dependency('hyprutils', version: '>= 0.1.1'),
|
||||||
],
|
],
|
||||||
install: true
|
install: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
install_data('hyprctl.bash', install_dir: join_paths(get_option('datadir'), 'bash-completion/completions'), install_tag: 'runtime', rename: 'hyprctl')
|
install_data(
|
||||||
install_data('hyprctl.fish', install_dir: join_paths(get_option('datadir'), 'fish/vendor_completions.d'), install_tag: 'runtime')
|
'hyprctl.bash',
|
||||||
install_data('hyprctl.zsh', install_dir: join_paths(get_option('datadir'), 'zsh/site-functions'), install_tag: 'runtime', rename: '_hyprctl')
|
install_dir: join_paths(get_option('datadir'), 'bash-completion/completions'),
|
||||||
|
install_tag: 'runtime',
|
||||||
|
rename: 'hyprctl',
|
||||||
|
)
|
||||||
|
install_data(
|
||||||
|
'hyprctl.fish',
|
||||||
|
install_dir: join_paths(get_option('datadir'), 'fish/vendor_completions.d'),
|
||||||
|
install_tag: 'runtime',
|
||||||
|
)
|
||||||
|
install_data(
|
||||||
|
'hyprctl.zsh',
|
||||||
|
install_dir: join_paths(get_option('datadir'), 'zsh/site-functions'),
|
||||||
|
install_tag: 'runtime',
|
||||||
|
rename: '_hyprctl',
|
||||||
|
)
|
||||||
|
|
|
@ -2,6 +2,10 @@ _hyprpm_cmd_0 () {
|
||||||
hyprpm list | awk '/Plugin/{print $4}'
|
hyprpm list | awk '/Plugin/{print $4}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_hyprpm_cmd_1 () {
|
||||||
|
hyprpm list | awk '/Repository/{print $4}' | sed 's/:$//'
|
||||||
|
}
|
||||||
|
|
||||||
_hyprpm () {
|
_hyprpm () {
|
||||||
if [[ $(type -t _get_comp_words_by_ref) != function ]]; then
|
if [[ $(type -t _get_comp_words_by_ref) != function ]]; then
|
||||||
echo _get_comp_words_by_ref: function not defined. Make sure the bash-completions system package is installed
|
echo _get_comp_words_by_ref: function not defined. Make sure the bash-completions system package is installed
|
||||||
|
@ -11,16 +15,13 @@ _hyprpm () {
|
||||||
local words cword
|
local words cword
|
||||||
_get_comp_words_by_ref -n "$COMP_WORDBREAKS" words cword
|
_get_comp_words_by_ref -n "$COMP_WORDBREAKS" words cword
|
||||||
|
|
||||||
local -a literals=("-n" "::=" "list" "disable" "--help" "update" "add" "--verbose" "-v" "--force" "remove" "enable" "--notify" "-h" "reload" "-f")
|
declare -a literals=(--no-shallow -n ::= disable list --help update add --verbose -v --force -s remove enable --notify -h reload -f)
|
||||||
|
|
||||||
declare -A literal_transitions
|
declare -A literal_transitions
|
||||||
literal_transitions[0]="([9]=6 [2]=2 [7]=6 [8]=6 [4]=6 [10]=2 [11]=3 [5]=2 [13]=6 [3]=3 [14]=2 [15]=6 [6]=2)"
|
literal_transitions[0]="([0]=7 [3]=3 [4]=4 [8]=7 [9]=7 [6]=4 [7]=4 [11]=7 [5]=7 [10]=7 [12]=2 [13]=3 [15]=7 [16]=4 [17]=7)"
|
||||||
literal_transitions[1]="([10]=2 [11]=3 [3]=3 [2]=2 [14]=2 [5]=2 [6]=2)"
|
literal_transitions[1]="([12]=2 [13]=3 [3]=3 [4]=4 [16]=4 [6]=4 [7]=4)"
|
||||||
literal_transitions[4]="([1]=5)"
|
literal_transitions[5]="([2]=6)"
|
||||||
literal_transitions[5]="([0]=6 [12]=6)"
|
literal_transitions[6]="([1]=7 [14]=7)"
|
||||||
|
declare -A match_anything_transitions=([1]=1 [4]=5 [3]=4 [2]=4 [0]=1)
|
||||||
declare -A match_anything_transitions
|
|
||||||
match_anything_transitions=([3]=2 [2]=4 [0]=1 [1]=1)
|
|
||||||
declare -A subword_transitions
|
declare -A subword_transitions
|
||||||
|
|
||||||
local state=0
|
local state=0
|
||||||
|
@ -58,21 +59,9 @@ _hyprpm () {
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
|
local -a matches=()
|
||||||
|
|
||||||
local prefix="${words[$cword]}"
|
local prefix="${words[$cword]}"
|
||||||
|
|
||||||
local shortest_suffix="$word"
|
|
||||||
for ((i=0; i < ${#COMP_WORDBREAKS}; i++)); do
|
|
||||||
local char="${COMP_WORDBREAKS:$i:1}"
|
|
||||||
local candidate="${word##*$char}"
|
|
||||||
if [[ ${#candidate} -lt ${#shortest_suffix} ]]; then
|
|
||||||
shortest_suffix=$candidate
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
local superfluous_prefix=""
|
|
||||||
if [[ "$shortest_suffix" != "$word" ]]; then
|
|
||||||
local superfluous_prefix=${word%$shortest_suffix}
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -v "literal_transitions[$state]" ]]; then
|
if [[ -v "literal_transitions[$state]" ]]; then
|
||||||
local state_transitions_initializer=${literal_transitions[$state]}
|
local state_transitions_initializer=${literal_transitions[$state]}
|
||||||
declare -A state_transitions
|
declare -A state_transitions
|
||||||
|
@ -81,25 +70,38 @@ _hyprpm () {
|
||||||
for literal_id in "${!state_transitions[@]}"; do
|
for literal_id in "${!state_transitions[@]}"; do
|
||||||
local literal="${literals[$literal_id]}"
|
local literal="${literals[$literal_id]}"
|
||||||
if [[ $literal = "${prefix}"* ]]; then
|
if [[ $literal = "${prefix}"* ]]; then
|
||||||
local completion=${literal#"$superfluous_prefix"}
|
matches+=("$literal ")
|
||||||
COMPREPLY+=("$completion ")
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
declare -A commands
|
declare -A commands
|
||||||
commands=([3]=0)
|
commands=([3]=0 [2]=1)
|
||||||
if [[ -v "commands[$state]" ]]; then
|
if [[ -v "commands[$state]" ]]; then
|
||||||
local command_id=${commands[$state]}
|
local command_id=${commands[$state]}
|
||||||
local completions=()
|
local completions=()
|
||||||
mapfile -t completions < <(_hyprpm_cmd_${command_id} "$prefix" | cut -f1)
|
readarray -t completions < <(_hyprpm_cmd_${command_id} "$prefix" | cut -f1)
|
||||||
for item in "${completions[@]}"; do
|
for item in "${completions[@]}"; do
|
||||||
if [[ $item = "${prefix}"* ]]; then
|
if [[ $item = "${prefix}"* ]]; then
|
||||||
COMPREPLY+=("$item")
|
matches+=("$item")
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
local shortest_suffix="$prefix"
|
||||||
|
for ((i=0; i < ${#COMP_WORDBREAKS}; i++)); do
|
||||||
|
local char="${COMP_WORDBREAKS:$i:1}"
|
||||||
|
local candidate=${prefix##*$char}
|
||||||
|
if [[ ${#candidate} -lt ${#shortest_suffix} ]]; then
|
||||||
|
shortest_suffix=$candidate
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
local superfluous_prefix=""
|
||||||
|
if [[ "$shortest_suffix" != "$prefix" ]]; then
|
||||||
|
local superfluous_prefix=${prefix%$shortest_suffix}
|
||||||
|
fi
|
||||||
|
COMPREPLY=("${matches[@]#$superfluous_prefix}")
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,11 @@ function _hyprpm_1
|
||||||
hyprpm list | awk '/Plugin/{print $4}'
|
hyprpm list | awk '/Plugin/{print $4}'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function _hyprpm_2
|
||||||
|
set 1 $argv[1]
|
||||||
|
hyprpm list | awk '/Repository/{print $4}' | sed 's/:$//'
|
||||||
|
end
|
||||||
|
|
||||||
function _hyprpm
|
function _hyprpm
|
||||||
set COMP_LINE (commandline --cut-at-cursor)
|
set COMP_LINE (commandline --cut-at-cursor)
|
||||||
|
|
||||||
|
@ -14,49 +19,51 @@ function _hyprpm
|
||||||
set COMP_CWORD (count $COMP_WORDS)
|
set COMP_CWORD (count $COMP_WORDS)
|
||||||
end
|
end
|
||||||
|
|
||||||
set --local literals "-n" "::=" "list" "disable" "--help" "update" "add" "--verbose" "-v" "--force" "remove" "enable" "--notify" "-h" "reload" "-f"
|
set literals "--no-shallow" "-n" "::=" "disable" "list" "--help" "update" "add" "--verbose" "-v" "--force" "-s" "remove" "enable" "--notify" "-h" "reload" "-f"
|
||||||
|
|
||||||
set --local descriptions
|
set descriptions
|
||||||
set descriptions[1] "Send a hyprland notification for important events (e.g. load fail)"
|
set descriptions[1] "Disable shallow cloning of Hyprland sources"
|
||||||
set descriptions[3] "List all installed plugins"
|
set descriptions[2] "Send a hyprland notification for important events (e.g. load fail)"
|
||||||
set descriptions[4] "Unload a plugin"
|
set descriptions[4] "Unload a plugin"
|
||||||
set descriptions[5] "Show help menu"
|
set descriptions[5] "List all installed plugins"
|
||||||
set descriptions[6] "Check and update all plugins if needed"
|
set descriptions[6] "Show help menu"
|
||||||
set descriptions[7] "Install a new plugin repository from git"
|
set descriptions[7] "Check and update all plugins if needed"
|
||||||
set descriptions[8] "Enable too much loggin"
|
set descriptions[8] "Install a new plugin repository from git"
|
||||||
set descriptions[9] "Enable too much loggin"
|
set descriptions[9] "Enable too much loggin"
|
||||||
set descriptions[10] "Force an operation ignoring checks (e.g. update -f)"
|
set descriptions[10] "Enable too much loggin"
|
||||||
set descriptions[11] "Remove a plugin repository"
|
set descriptions[11] "Force an operation ignoring checks (e.g. update -f)"
|
||||||
set descriptions[12] "Load a plugin"
|
set descriptions[12] "Disable shallow cloning of Hyprland sources"
|
||||||
set descriptions[13] "Send a hyprland notification for important events (e.g. load fail)"
|
set descriptions[13] "Remove a plugin repository"
|
||||||
set descriptions[14] "Show help menu"
|
set descriptions[14] "Load a plugin"
|
||||||
set descriptions[15] "Reload all plugins"
|
set descriptions[15] "Send a hyprland notification for important events (e.g. load fail)"
|
||||||
set descriptions[16] "Force an operation ignoring checks (e.g. update -f)"
|
set descriptions[16] "Show help menu"
|
||||||
|
set descriptions[17] "Reload all plugins"
|
||||||
|
set descriptions[18] "Force an operation ignoring checks (e.g. update -f)"
|
||||||
|
|
||||||
set --local literal_transitions
|
set literal_transitions
|
||||||
set literal_transitions[1] "set inputs 10 3 8 9 5 11 12 6 14 4 15 16 7; set tos 7 3 7 7 7 3 4 3 7 4 3 7 3"
|
set literal_transitions[1] "set inputs 1 4 5 9 10 7 8 12 6 11 13 14 16 17 18; set tos 8 4 5 8 8 5 5 8 8 8 3 4 8 5 8"
|
||||||
set literal_transitions[2] "set inputs 11 12 4 3 15 6 7; set tos 3 4 4 3 3 3 3"
|
set literal_transitions[2] "set inputs 13 14 4 5 17 7 8; set tos 3 4 4 5 5 5 5"
|
||||||
set literal_transitions[5] "set inputs 2; set tos 6"
|
set literal_transitions[6] "set inputs 3; set tos 7"
|
||||||
set literal_transitions[6] "set inputs 1 13; set tos 7 7"
|
set literal_transitions[7] "set inputs 2 15; set tos 8 8"
|
||||||
|
|
||||||
set --local match_anything_transitions_from 4 3 1 2
|
set match_anything_transitions_from 2 5 4 3 1
|
||||||
set --local match_anything_transitions_to 3 5 2 2
|
set match_anything_transitions_to 2 6 5 5 2
|
||||||
|
|
||||||
set --local state 1
|
set state 1
|
||||||
set --local word_index 2
|
set word_index 2
|
||||||
while test $word_index -lt $COMP_CWORD
|
while test $word_index -lt $COMP_CWORD
|
||||||
set --local -- word $COMP_WORDS[$word_index]
|
set -- word $COMP_WORDS[$word_index]
|
||||||
|
|
||||||
if set --query literal_transitions[$state] && test -n $literal_transitions[$state]
|
if set --query literal_transitions[$state] && test -n $literal_transitions[$state]
|
||||||
set --local --erase inputs
|
set --erase inputs
|
||||||
set --local --erase tos
|
set --erase tos
|
||||||
eval $literal_transitions[$state]
|
eval $literal_transitions[$state]
|
||||||
|
|
||||||
if contains -- $word $literals
|
if contains -- $word $literals
|
||||||
set --local literal_matched 0
|
set literal_matched 0
|
||||||
for literal_id in (seq 1 (count $literals))
|
for literal_id in (seq 1 (count $literals))
|
||||||
if test $literals[$literal_id] = $word
|
if test $literals[$literal_id] = $word
|
||||||
set --local index (contains --index -- $literal_id $inputs)
|
set index (contains --index -- $literal_id $inputs)
|
||||||
set state $tos[$index]
|
set state $tos[$index]
|
||||||
set word_index (math $word_index + 1)
|
set word_index (math $word_index + 1)
|
||||||
set literal_matched 1
|
set literal_matched 1
|
||||||
|
@ -70,7 +77,7 @@ function _hyprpm
|
||||||
end
|
end
|
||||||
|
|
||||||
if set --query match_anything_transitions_from[$state] && test -n $match_anything_transitions_from[$state]
|
if set --query match_anything_transitions_from[$state] && test -n $match_anything_transitions_from[$state]
|
||||||
set --local index (contains --index -- $state $match_anything_transitions_from)
|
set index (contains --index -- $state $match_anything_transitions_from)
|
||||||
set state $match_anything_transitions_to[$index]
|
set state $match_anything_transitions_to[$index]
|
||||||
set word_index (math $word_index + 1)
|
set word_index (math $word_index + 1)
|
||||||
continue
|
continue
|
||||||
|
@ -80,8 +87,8 @@ function _hyprpm
|
||||||
end
|
end
|
||||||
|
|
||||||
if set --query literal_transitions[$state] && test -n $literal_transitions[$state]
|
if set --query literal_transitions[$state] && test -n $literal_transitions[$state]
|
||||||
set --local --erase inputs
|
set --erase inputs
|
||||||
set --local --erase tos
|
set --erase tos
|
||||||
eval $literal_transitions[$state]
|
eval $literal_transitions[$state]
|
||||||
for literal_id in $inputs
|
for literal_id in $inputs
|
||||||
if test -n $descriptions[$literal_id]
|
if test -n $descriptions[$literal_id]
|
||||||
|
@ -92,14 +99,14 @@ function _hyprpm
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
set command_states 4
|
set command_states 4 3
|
||||||
set command_ids 1
|
set command_ids 1 2
|
||||||
if contains $state $command_states
|
if contains $state $command_states
|
||||||
set --local index (contains --index $state $command_states)
|
set index (contains --index $state $command_states)
|
||||||
set --local function_id $command_ids[$index]
|
set function_id $command_ids[$index]
|
||||||
set --local function_name _hyprpm_$function_id
|
set function_name _hyprpm_$function_id
|
||||||
set --local --erase inputs
|
set --erase inputs
|
||||||
set --local --erase tos
|
set --erase tos
|
||||||
$function_name "$COMP_WORDS[$COMP_CWORD]"
|
$function_name "$COMP_WORDS[$COMP_CWORD]"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,11 @@ hyprpm [<FLAGS>]... <ARGUMENT>
|
||||||
| (--help | -h) "Show help menu"
|
| (--help | -h) "Show help menu"
|
||||||
| (--verbose | -v) "Enable too much loggin"
|
| (--verbose | -v) "Enable too much loggin"
|
||||||
| (--force | -f) "Force an operation ignoring checks (e.g. update -f)"
|
| (--force | -f) "Force an operation ignoring checks (e.g. update -f)"
|
||||||
|
| (--no-shallow | -s) "Disable shallow cloning of Hyprland sources"
|
||||||
;
|
;
|
||||||
|
|
||||||
<ARGUMENT> ::= (add) "Install a new plugin repository from git"
|
<ARGUMENT> ::= (add) "Install a new plugin repository from git"
|
||||||
| (remove) "Remove a plugin repository"
|
| (remove <PLUGIN_REPOS>) "Remove a plugin repository"
|
||||||
| (update) "Check and update all plugins if needed"
|
| (update) "Check and update all plugins if needed"
|
||||||
| (list) "List all installed plugins"
|
| (list) "List all installed plugins"
|
||||||
| (enable <PLUGINS>) "Load a plugin"
|
| (enable <PLUGINS>) "Load a plugin"
|
||||||
|
@ -17,3 +18,4 @@ hyprpm [<FLAGS>]... <ARGUMENT>
|
||||||
;
|
;
|
||||||
|
|
||||||
<PLUGINS> ::= {{{ hyprpm list | awk '/Plugin/{print $4}' }}};
|
<PLUGINS> ::= {{{ hyprpm list | awk '/Plugin/{print $4}' }}};
|
||||||
|
<PLUGIN_REPOS> ::= {{{ hyprpm list | awk '/Repository/{print $4}' | sed 's/:$//' }}};
|
||||||
|
|
|
@ -4,34 +4,40 @@ _hyprpm_cmd_0 () {
|
||||||
hyprpm list | awk '/Plugin/{print $4}'
|
hyprpm list | awk '/Plugin/{print $4}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_hyprpm_cmd_1 () {
|
||||||
|
hyprpm list | awk '/Repository/{print $4}' | sed 's/:$//'
|
||||||
|
}
|
||||||
|
|
||||||
_hyprpm () {
|
_hyprpm () {
|
||||||
local -a literals=("-n" "::=" "list" "disable" "--help" "update" "add" "--verbose" "-v" "--force" "remove" "enable" "--notify" "-h" "reload" "-f")
|
local -a literals=("--no-shallow" "-n" "::=" "disable" "list" "--help" "update" "add" "--verbose" "-v" "--force" "-s" "remove" "enable" "--notify" "-h" "reload" "-f")
|
||||||
|
|
||||||
local -A descriptions
|
local -A descriptions
|
||||||
descriptions[1]="Send a hyprland notification for important events (e.g. load fail)"
|
descriptions[1]="Disable shallow cloning of Hyprland sources"
|
||||||
descriptions[3]="List all installed plugins"
|
descriptions[2]="Send a hyprland notification for important events (e.g. load fail)"
|
||||||
descriptions[4]="Unload a plugin"
|
descriptions[4]="Unload a plugin"
|
||||||
descriptions[5]="Show help menu"
|
descriptions[5]="List all installed plugins"
|
||||||
descriptions[6]="Check and update all plugins if needed"
|
descriptions[6]="Show help menu"
|
||||||
descriptions[7]="Install a new plugin repository from git"
|
descriptions[7]="Check and update all plugins if needed"
|
||||||
descriptions[8]="Enable too much loggin"
|
descriptions[8]="Install a new plugin repository from git"
|
||||||
descriptions[9]="Enable too much loggin"
|
descriptions[9]="Enable too much loggin"
|
||||||
descriptions[10]="Force an operation ignoring checks (e.g. update -f)"
|
descriptions[10]="Enable too much loggin"
|
||||||
descriptions[11]="Remove a plugin repository"
|
descriptions[11]="Force an operation ignoring checks (e.g. update -f)"
|
||||||
descriptions[12]="Load a plugin"
|
descriptions[12]="Disable shallow cloning of Hyprland sources"
|
||||||
descriptions[13]="Send a hyprland notification for important events (e.g. load fail)"
|
descriptions[13]="Remove a plugin repository"
|
||||||
descriptions[14]="Show help menu"
|
descriptions[14]="Load a plugin"
|
||||||
descriptions[15]="Reload all plugins"
|
descriptions[15]="Send a hyprland notification for important events (e.g. load fail)"
|
||||||
descriptions[16]="Force an operation ignoring checks (e.g. update -f)"
|
descriptions[16]="Show help menu"
|
||||||
|
descriptions[17]="Reload all plugins"
|
||||||
|
descriptions[18]="Force an operation ignoring checks (e.g. update -f)"
|
||||||
|
|
||||||
local -A literal_transitions
|
local -A literal_transitions
|
||||||
literal_transitions[1]="([10]=7 [3]=3 [8]=7 [9]=7 [5]=7 [11]=3 [12]=4 [6]=3 [14]=7 [4]=4 [15]=3 [16]=7 [7]=3)"
|
literal_transitions[1]="([1]=8 [4]=4 [5]=5 [9]=8 [10]=8 [7]=5 [8]=5 [12]=8 [6]=8 [11]=8 [13]=3 [14]=4 [16]=8 [17]=5 [18]=8)"
|
||||||
literal_transitions[2]="([11]=3 [12]=4 [4]=4 [3]=3 [15]=3 [6]=3 [7]=3)"
|
literal_transitions[2]="([13]=3 [14]=4 [4]=4 [5]=5 [17]=5 [7]=5 [8]=5)"
|
||||||
literal_transitions[5]="([2]=6)"
|
literal_transitions[6]="([3]=7)"
|
||||||
literal_transitions[6]="([1]=7 [13]=7)"
|
literal_transitions[7]="([2]=8 [15]=8)"
|
||||||
|
|
||||||
local -A match_anything_transitions
|
local -A match_anything_transitions
|
||||||
match_anything_transitions=([4]=3 [3]=5 [1]=2 [2]=2)
|
match_anything_transitions=([2]=2 [5]=6 [4]=5 [3]=5 [1]=2)
|
||||||
|
|
||||||
declare -A subword_transitions
|
declare -A subword_transitions
|
||||||
|
|
||||||
|
@ -91,7 +97,7 @@ _hyprpm () {
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
local -A commands=([4]=0)
|
local -A commands=([4]=0 [3]=1)
|
||||||
|
|
||||||
if [[ -v "commands[$state]" ]]; then
|
if [[ -v "commands[$state]" ]]; then
|
||||||
local command_id=${commands[$state]}
|
local command_id=${commands[$state]}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "DataState.hpp"
|
#include "DataState.hpp"
|
||||||
#include <toml++/toml.hpp>
|
#include <toml++/toml.hpp>
|
||||||
#include <iostream>
|
#include <print>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "PluginManager.hpp"
|
#include "PluginManager.hpp"
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
std::string DataState::getDataStatePath() {
|
std::string DataState::getDataStatePath() {
|
||||||
const auto HOME = getenv("HOME");
|
const auto HOME = getenv("HOME");
|
||||||
if (!HOME) {
|
if (!HOME) {
|
||||||
std::cerr << "DataState: no $HOME\n";
|
std::println(stderr, "DataState: no $HOME");
|
||||||
throw std::runtime_error("no $HOME");
|
throw std::runtime_error("no $HOME");
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ void DataState::addNewPluginRepo(const SPluginRepository& repo) {
|
||||||
{"rev", repo.rev}
|
{"rev", repo.rev}
|
||||||
}}
|
}}
|
||||||
};
|
};
|
||||||
for (auto& p : repo.plugins) {
|
for (auto const& p : repo.plugins) {
|
||||||
// copy .so to the good place
|
// copy .so to the good place
|
||||||
if (std::filesystem::exists(p.filename))
|
if (std::filesystem::exists(p.filename))
|
||||||
std::filesystem::copy_file(p.filename, PATH + "/" + p.name + ".so");
|
std::filesystem::copy_file(p.filename, PATH + "/" + p.name + ".so");
|
||||||
|
|
|
@ -6,7 +6,7 @@ CManifest::CManifest(const eManifestType type, const std::string& path) {
|
||||||
auto manifest = toml::parse_file(path);
|
auto manifest = toml::parse_file(path);
|
||||||
|
|
||||||
if (type == MANIFEST_HYPRLOAD) {
|
if (type == MANIFEST_HYPRLOAD) {
|
||||||
for (auto& [key, val] : manifest) {
|
for (auto const& [key, val] : manifest) {
|
||||||
if (key.str().ends_with(".build"))
|
if (key.str().ends_with(".build"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ CManifest::CManifest(const eManifestType type, const std::string& path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& [key, val] : manifest) {
|
for (auto const& [key, val] : manifest) {
|
||||||
if (key.str() == "repository")
|
if (key.str() == "repository")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
#include "PluginManager.hpp"
|
#include "PluginManager.hpp"
|
||||||
#include "../helpers/Colors.hpp"
|
#include "../helpers/Colors.hpp"
|
||||||
|
#include "../helpers/StringUtils.hpp"
|
||||||
#include "../progress/CProgressBar.hpp"
|
#include "../progress/CProgressBar.hpp"
|
||||||
#include "Manifest.hpp"
|
#include "Manifest.hpp"
|
||||||
#include "DataState.hpp"
|
#include "DataState.hpp"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <print>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -31,6 +34,7 @@ static std::string execAndGet(std::string cmd) {
|
||||||
if (!pipe)
|
if (!pipe)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
|
result.reserve(buffer.size());
|
||||||
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
|
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
|
||||||
result += buffer.data();
|
result += buffer.data();
|
||||||
}
|
}
|
||||||
|
@ -47,10 +51,10 @@ SHyprlandVersion CPluginManager::getHyprlandVersion() {
|
||||||
once = true;
|
once = true;
|
||||||
const auto HLVERCALL = execAndGet("hyprctl version");
|
const auto HLVERCALL = execAndGet("hyprctl version");
|
||||||
if (m_bVerbose)
|
if (m_bVerbose)
|
||||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "version returned: " << HLVERCALL << "\n";
|
std::println("{}", verboseString("version returned: {}", HLVERCALL));
|
||||||
|
|
||||||
if (!HLVERCALL.contains("Tag:")) {
|
if (!HLVERCALL.contains("Tag:")) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " You don't seem to be running Hyprland.";
|
std::println(stderr, "\n{}", failureString("You don't seem to be running Hyprland."));
|
||||||
return SHyprlandVersion{};
|
return SHyprlandVersion{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +80,7 @@ SHyprlandVersion CPluginManager::getHyprlandVersion() {
|
||||||
} catch (...) { ; }
|
} catch (...) { ; }
|
||||||
|
|
||||||
if (m_bVerbose)
|
if (m_bVerbose)
|
||||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "parsed commit " << hlcommit << " at branch " << hlbranch << " on " << hldate << ", commits " << commits << "\n";
|
std::println("{}", verboseString("parsed commit {} at branch {} on {}, commits {}", hlcommit, hlbranch, hldate, commits));
|
||||||
|
|
||||||
ver = SHyprlandVersion{hlbranch, hlcommit, hldate, commits};
|
ver = SHyprlandVersion{hlbranch, hlcommit, hldate, commits};
|
||||||
return ver;
|
return ver;
|
||||||
|
@ -102,20 +106,21 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||||
const auto HLVER = getHyprlandVersion();
|
const auto HLVER = getHyprlandVersion();
|
||||||
|
|
||||||
if (!hasDeps()) {
|
if (!hasDeps()) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not clone the plugin repository. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio\n";
|
std::println(stderr, "\n{}", failureString("Could not clone the plugin repository. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DataState::pluginRepoExists(url)) {
|
if (DataState::pluginRepoExists(url)) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not clone the plugin repository. Repository already installed.\n";
|
std::println(stderr, "\n{}", failureString("Could not clone the plugin repository. Repository already installed."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GLOBALSTATE = DataState::getGlobalState();
|
auto GLOBALSTATE = DataState::getGlobalState();
|
||||||
if (!GLOBALSTATE.dontWarnInstall) {
|
if (!GLOBALSTATE.dontWarnInstall) {
|
||||||
std::cout << Colors::YELLOW << "!" << Colors::RED << " Disclaimer:\n " << Colors::RESET
|
std::println("{}!{} Disclaimer: {}", Colors::YELLOW, Colors::RED, Colors::RESET);
|
||||||
<< "plugins, especially not official, have no guarantee of stability, availablity or security.\n Run them at your own risk.\n "
|
std::println("plugins, especially not official, have no guarantee of stability, availablity or security.\n"
|
||||||
<< "This message will not appear again.\n";
|
"Run them at your own risk.\n"
|
||||||
|
"This message will not appear again.");
|
||||||
GLOBALSTATE.dontWarnInstall = true;
|
GLOBALSTATE.dontWarnInstall = true;
|
||||||
DataState::updateGlobalState(GLOBALSTATE);
|
DataState::updateGlobalState(GLOBALSTATE);
|
||||||
}
|
}
|
||||||
|
@ -129,7 +134,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||||
std::getline(std::cin, input);
|
std::getline(std::cin, input);
|
||||||
|
|
||||||
if (input.size() > 0 && input[0] != 'Y' && input[0] != 'y') {
|
if (input.size() > 0 && input[0] != 'Y' && input[0] != 'y') {
|
||||||
std::cout << "Aborting.\n";
|
std::println(stderr, "Aborting.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +149,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||||
std::filesystem::create_directory("/tmp/hyprpm");
|
std::filesystem::create_directory("/tmp/hyprpm");
|
||||||
std::filesystem::permissions("/tmp/hyprpm", std::filesystem::perms::all, std::filesystem::perm_options::replace);
|
std::filesystem::permissions("/tmp/hyprpm", std::filesystem::perms::all, std::filesystem::perm_options::replace);
|
||||||
} else if (!std::filesystem::is_directory("/tmp/hyprpm")) {
|
} else if (!std::filesystem::is_directory("/tmp/hyprpm")) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not prepare working dir for hyprpm\n";
|
std::println(stderr, "\n{}", failureString("Could not prepare working dir for hyprpm"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,60 +158,60 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||||
m_szWorkingPluginDirectory = "/tmp/hyprpm/" + USERNAME;
|
m_szWorkingPluginDirectory = "/tmp/hyprpm/" + USERNAME;
|
||||||
|
|
||||||
if (!createSafeDirectory(m_szWorkingPluginDirectory)) {
|
if (!createSafeDirectory(m_szWorkingPluginDirectory)) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not prepare working dir for repo\n";
|
std::println(stderr, "\n{}", failureString("Could not prepare working dir for repo"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Cloning " + url);
|
progress.printMessageAbove(infoString("Cloning {}", url));
|
||||||
|
|
||||||
std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive " + url + " " + USERNAME);
|
std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive " + url + " " + USERNAME);
|
||||||
|
|
||||||
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/.git")) {
|
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/.git")) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not clone the plugin repository. shell returned:\n" << ret << "\n";
|
std::println(stderr, "\n{}", failureString("Could not clone the plugin repository. shell returned:\n{}", ret));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rev.empty()) {
|
if (!rev.empty()) {
|
||||||
std::string ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " reset --hard --recurse-submodules " + rev);
|
std::string ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " reset --hard --recurse-submodules " + rev);
|
||||||
if (ret.compare(0, 6, "fatal:") == 0) {
|
if (ret.compare(0, 6, "fatal:") == 0) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not check out revision " << rev << ". shell returned:\n" << ret << "\n";
|
std::println(stderr, "\n{}", failureString("Could not check out revision {}. shell returned:\n{}", rev, ret));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " submodule update --init");
|
ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " submodule update --init");
|
||||||
if (m_bVerbose)
|
if (m_bVerbose)
|
||||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "git submodule update --init returned: " << ret << "\n";
|
std::println("{}", verboseString("git submodule update --init returned: {}", ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.m_iSteps = 1;
|
progress.m_iSteps = 1;
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " cloned");
|
progress.printMessageAbove(successString("cloned"));
|
||||||
progress.m_szCurrentMessage = "Reading the manifest";
|
progress.m_szCurrentMessage = "Reading the manifest";
|
||||||
progress.print();
|
progress.print();
|
||||||
|
|
||||||
std::unique_ptr<CManifest> pManifest;
|
std::unique_ptr<CManifest> pManifest;
|
||||||
|
|
||||||
if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprpm.toml")) {
|
if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprpm.toml")) {
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " found hyprpm manifest");
|
progress.printMessageAbove(successString("found hyprpm manifest"));
|
||||||
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRPM, m_szWorkingPluginDirectory + "/hyprpm.toml");
|
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRPM, m_szWorkingPluginDirectory + "/hyprpm.toml");
|
||||||
} else if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprload.toml")) {
|
} else if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprload.toml")) {
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " found hyprload manifest");
|
progress.printMessageAbove(successString("found hyprload manifest"));
|
||||||
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, m_szWorkingPluginDirectory + "/hyprload.toml");
|
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, m_szWorkingPluginDirectory + "/hyprload.toml");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pManifest) {
|
if (!pManifest) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " The provided plugin repository does not have a valid manifest\n";
|
std::println(stderr, "\n{}", failureString("The provided plugin repository does not have a valid manifest"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pManifest->m_bGood) {
|
if (!pManifest->m_bGood) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " The provided plugin repository has a corrupted manifest\n";
|
std::println(stderr, "\n{}", failureString("The provided plugin repository has a corrupted manifest"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.m_iSteps = 2;
|
progress.m_iSteps = 2;
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " parsed manifest, found " + std::to_string(pManifest->m_vPlugins.size()) + " plugins:");
|
progress.printMessageAbove(successString("parsed manifest, found " + std::to_string(pManifest->m_vPlugins.size()) + " plugins:"));
|
||||||
for (auto& pl : pManifest->m_vPlugins) {
|
for (auto const& pl : pManifest->m_vPlugins) {
|
||||||
std::string message = std::string{Colors::RESET} + " → " + pl.name + " by ";
|
std::string message = "→ " + pl.name + " by ";
|
||||||
for (auto& a : pl.authors) {
|
for (auto const& a : pl.authors) {
|
||||||
message += a + ", ";
|
message += a + ", ";
|
||||||
}
|
}
|
||||||
if (pl.authors.size() > 0) {
|
if (pl.authors.size() > 0) {
|
||||||
|
@ -220,19 +225,19 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||||
if (!pManifest->m_sRepository.commitPins.empty()) {
|
if (!pManifest->m_sRepository.commitPins.empty()) {
|
||||||
// check commit pins
|
// check commit pins
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Manifest has " + std::to_string(pManifest->m_sRepository.commitPins.size()) + " pins, checking");
|
progress.printMessageAbove(infoString("Manifest has {} pins, checking", pManifest->m_sRepository.commitPins.size()));
|
||||||
|
|
||||||
for (auto& [hl, plugin] : pManifest->m_sRepository.commitPins) {
|
for (auto const& [hl, plugin] : pManifest->m_sRepository.commitPins) {
|
||||||
if (hl != HLVER.hash)
|
if (hl != HLVER.hash)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " commit pin " + plugin + " matched hl, resetting");
|
progress.printMessageAbove(successString("commit pin {} matched hl, resetting", plugin));
|
||||||
|
|
||||||
execAndGet("cd " + m_szWorkingPluginDirectory + " && git reset --hard --recurse-submodules " + plugin);
|
execAndGet("cd " + m_szWorkingPluginDirectory + " && git reset --hard --recurse-submodules " + plugin);
|
||||||
|
|
||||||
ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " submodule update --init");
|
ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " submodule update --init");
|
||||||
if (m_bVerbose)
|
if (m_bVerbose)
|
||||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "git submodule update --init returned: " << ret << "\n";
|
std::println("{}", verboseString("git submodule update --init returned: {}", ret));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -244,12 +249,12 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||||
const auto HEADERSSTATUS = headersValid();
|
const auto HEADERSSTATUS = headersValid();
|
||||||
|
|
||||||
if (HEADERSSTATUS != HEADERS_OK) {
|
if (HEADERSSTATUS != HEADERS_OK) {
|
||||||
std::cerr << "\n" << headerError(HEADERSSTATUS);
|
std::println("\n{}", headerError(HEADERSSTATUS));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.m_iSteps = 3;
|
progress.m_iSteps = 3;
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " Hyprland headers OK");
|
progress.printMessageAbove(successString("Hyprland headers OK"));
|
||||||
progress.m_szCurrentMessage = "Building plugin(s)";
|
progress.m_szCurrentMessage = "Building plugin(s)";
|
||||||
progress.print();
|
progress.print();
|
||||||
|
|
||||||
|
@ -257,35 +262,36 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||||
std::string out;
|
std::string out;
|
||||||
|
|
||||||
if (p.since > HLVER.commits && HLVER.commits >= 1 /* for --depth 1 clones, we can't check this. */) {
|
if (p.since > HLVER.commits && HLVER.commits >= 1 /* for --depth 1 clones, we can't check this. */) {
|
||||||
progress.printMessageAbove(std::string{Colors::RED} + "✖" + Colors::RESET + " Not building " + p.name + ": your Hyprland version is too old.\n");
|
progress.printMessageAbove(failureString("Not building {}: your Hyprland version is too old.\n", p.name));
|
||||||
p.failed = true;
|
p.failed = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Building " + p.name);
|
progress.printMessageAbove(infoString("Building {}", p.name));
|
||||||
|
|
||||||
for (auto& bs : p.buildSteps) {
|
for (auto const& bs : p.buildSteps) {
|
||||||
std::string cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
|
const std::string& cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
|
||||||
out += " -> " + cmd + "\n" + execAndGet(cmd) + "\n";
|
out += " -> " + cmd + "\n" + execAndGet(cmd) + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_bVerbose)
|
if (m_bVerbose)
|
||||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "shell returned: " << out << "\n";
|
std::println("{}", verboseString("shell returned: " + out));
|
||||||
|
|
||||||
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/" + p.output)) {
|
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/" + p.output)) {
|
||||||
progress.printMessageAbove(std::string{Colors::RED} + "✖" + Colors::RESET + " Plugin " + p.name + " failed to build.\n" +
|
progress.printMessageAbove(failureString("Plugin {} failed to build.\n"
|
||||||
" This likely means that the plugin is either outdated, not yet available for your version, or broken.\n If you are on -git, update "
|
" This likely means that the plugin is either outdated, not yet available for your version, or broken.\n"
|
||||||
"first.\n Try re-running with -v to see "
|
" If you are on -git, update first\n"
|
||||||
"more verbose output.\n");
|
" Try re-running with -v to see more verbose output.\n",
|
||||||
|
p.name));
|
||||||
|
|
||||||
p.failed = true;
|
p.failed = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " built " + p.name + " into " + p.output);
|
progress.printMessageAbove(successString("built {} into {}", p.name, p.output));
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " all plugins built");
|
progress.printMessageAbove(successString("all plugins built"));
|
||||||
progress.m_iSteps = 4;
|
progress.m_iSteps = 4;
|
||||||
progress.m_szCurrentMessage = "Installing repository";
|
progress.m_szCurrentMessage = "Installing repository";
|
||||||
progress.print();
|
progress.print();
|
||||||
|
@ -299,18 +305,18 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||||
repo.url = url;
|
repo.url = url;
|
||||||
repo.rev = rev;
|
repo.rev = rev;
|
||||||
repo.hash = repohash;
|
repo.hash = repohash;
|
||||||
for (auto& p : pManifest->m_vPlugins) {
|
for (auto const& p : pManifest->m_vPlugins) {
|
||||||
repo.plugins.push_back(SPlugin{p.name, m_szWorkingPluginDirectory + "/" + p.output, false, p.failed});
|
repo.plugins.push_back(SPlugin{p.name, m_szWorkingPluginDirectory + "/" + p.output, false, p.failed});
|
||||||
}
|
}
|
||||||
DataState::addNewPluginRepo(repo);
|
DataState::addNewPluginRepo(repo);
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " installed repository");
|
progress.printMessageAbove(successString("installed repository"));
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " you can now enable the plugin(s) with hyprpm enable");
|
progress.printMessageAbove(successString("you can now enable the plugin(s) with hyprpm enable"));
|
||||||
progress.m_iSteps = 5;
|
progress.m_iSteps = 5;
|
||||||
progress.m_szCurrentMessage = "Done!";
|
progress.m_szCurrentMessage = "Done!";
|
||||||
progress.print();
|
progress.print();
|
||||||
|
|
||||||
std::cout << "\n";
|
std::print("\n");
|
||||||
|
|
||||||
// remove build files
|
// remove build files
|
||||||
std::filesystem::remove_all(m_szWorkingPluginDirectory);
|
std::filesystem::remove_all(m_szWorkingPluginDirectory);
|
||||||
|
@ -320,7 +326,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string&
|
||||||
|
|
||||||
bool CPluginManager::removePluginRepo(const std::string& urlOrName) {
|
bool CPluginManager::removePluginRepo(const std::string& urlOrName) {
|
||||||
if (!DataState::pluginRepoExists(urlOrName)) {
|
if (!DataState::pluginRepoExists(urlOrName)) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not remove the repository. Repository is not installed.\n";
|
std::println(stderr, "\n{}", failureString("Could not remove the repository. Repository is not installed."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +337,7 @@ bool CPluginManager::removePluginRepo(const std::string& urlOrName) {
|
||||||
std::getline(std::cin, input);
|
std::getline(std::cin, input);
|
||||||
|
|
||||||
if (input.size() > 0 && input[0] != 'Y' && input[0] != 'y') {
|
if (input.size() > 0 && input[0] != 'Y' && input[0] != 'y') {
|
||||||
std::cout << "Aborting.\n";
|
std::println("Aborting.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +353,7 @@ eHeadersErrors CPluginManager::headersValid() {
|
||||||
return HEADERS_MISSING;
|
return HEADERS_MISSING;
|
||||||
|
|
||||||
// find headers commit
|
// find headers commit
|
||||||
std::string cmd = std::format("PKG_CONFIG_PATH=\"{}/share/pkgconfig\" pkgconf --cflags --keep-system-cflags hyprland", DataState::getHeadersPath());
|
const std::string& cmd = std::format("PKG_CONFIG_PATH=\"{}/share/pkgconfig\" pkgconf --cflags --keep-system-cflags hyprland", DataState::getHeadersPath());
|
||||||
auto headers = execAndGet(cmd.c_str());
|
auto headers = execAndGet(cmd.c_str());
|
||||||
|
|
||||||
if (!headers.contains("-I/"))
|
if (!headers.contains("-I/"))
|
||||||
|
@ -355,7 +361,7 @@ eHeadersErrors CPluginManager::headersValid() {
|
||||||
|
|
||||||
headers.pop_back(); // pop newline
|
headers.pop_back(); // pop newline
|
||||||
|
|
||||||
std::string verHeader = "";
|
std::string verHeader;
|
||||||
|
|
||||||
while (!headers.empty()) {
|
while (!headers.empty()) {
|
||||||
const auto PATH = headers.substr(0, headers.find(" -I/", 3));
|
const auto PATH = headers.substr(0, headers.find(" -I/", 3));
|
||||||
|
@ -406,7 +412,7 @@ bool CPluginManager::updateHeaders(bool force) {
|
||||||
const auto HLVER = getHyprlandVersion();
|
const auto HLVER = getHyprlandVersion();
|
||||||
|
|
||||||
if (!hasDeps()) {
|
if (!hasDeps()) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not update. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio\n";
|
std::println("\n{}", failureString("Could not update. Dependencies not satisfied. Hyprpm requires: cmake, meson, cpio"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +422,7 @@ bool CPluginManager::updateHeaders(bool force) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!force && headersValid() == HEADERS_OK) {
|
if (!force && headersValid() == HEADERS_OK) {
|
||||||
std::cout << "\n" << std::string{Colors::GREEN} + "✔" + Colors::RESET + " Headers up to date.\n";
|
std::println("\n{}", successString("Headers up to date."));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,74 +436,73 @@ bool CPluginManager::updateHeaders(bool force) {
|
||||||
const auto WORKINGDIR = "/tmp/hyprpm/hyprland-" + USERNAME;
|
const auto WORKINGDIR = "/tmp/hyprpm/hyprland-" + USERNAME;
|
||||||
|
|
||||||
if (!createSafeDirectory(WORKINGDIR)) {
|
if (!createSafeDirectory(WORKINGDIR)) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not prepare working dir for hl\n";
|
std::println("\n{}", failureString("Could not prepare working dir for hl"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::YELLOW} + "!" + Colors::RESET + " Cloning https://github.com/hyprwm/hyprland, this might take a moment.");
|
progress.printMessageAbove(statusString("!", Colors::YELLOW, "Cloning https://github.com/hyprwm/Hyprland, this might take a moment."));
|
||||||
|
|
||||||
const bool bShallow = (HLVER.branch == "main" || HLVER.branch == "") && !m_bNoShallow;
|
const bool bShallow = (HLVER.branch == "main") && !m_bNoShallow;
|
||||||
|
|
||||||
// let us give a bit of leg-room for shallowing
|
// let us give a bit of leg-room for shallowing
|
||||||
// due to timezones, etc.
|
// due to timezones, etc.
|
||||||
const std::string SHALLOW_DATE =
|
const std::string SHALLOW_DATE = trim(HLVER.date).empty() ? "" : execAndGet("LC_TIME=\"en_US.UTF-8\" date --date='" + HLVER.date + " - 1 weeks' '+%a %b %d %H:%M:%S %Y'");
|
||||||
trim(HLVER.date).empty() ? "" : execAndGet("LC_TIME=\"en_US.UTF-8\" date --date='" + HLVER.date + " - 1 weeks' '+\%a \%b \%d \%H:\%M:\%S \%Y'");
|
|
||||||
|
|
||||||
if (m_bVerbose && bShallow)
|
if (m_bVerbose && bShallow)
|
||||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "will shallow since: " + SHALLOW_DATE);
|
progress.printMessageAbove(verboseString("will shallow since: {}", SHALLOW_DATE));
|
||||||
|
|
||||||
std::string ret =
|
std::string ret =
|
||||||
execAndGet("cd /tmp/hyprpm && git clone --recursive https://github.com/hyprwm/hyprland hyprland-" + USERNAME + (bShallow ? " --shallow-since='" + SHALLOW_DATE + "'" : ""));
|
execAndGet("cd /tmp/hyprpm && git clone --recursive https://github.com/hyprwm/Hyprland hyprland-" + USERNAME + (bShallow ? " --shallow-since='" + SHALLOW_DATE + "'" : ""));
|
||||||
|
|
||||||
if (!std::filesystem::exists(WORKINGDIR)) {
|
if (!std::filesystem::exists(WORKINGDIR)) {
|
||||||
progress.printMessageAbove(std::string{Colors::RED} + "✖" + Colors::RESET + " Clone failed. Retrying without shallow.");
|
progress.printMessageAbove(failureString("Clone failed. Retrying without shallow."));
|
||||||
ret = execAndGet("cd /tmp/hyprpm && git clone --recursive https://github.com/hyprwm/hyprland hyprland-" + USERNAME);
|
ret = execAndGet("cd /tmp/hyprpm && git clone --recursive https://github.com/hyprwm/hyprland hyprland-" + USERNAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!std::filesystem::exists(WORKINGDIR + "/.git")) {
|
if (!std::filesystem::exists(WORKINGDIR + "/.git")) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " Could not clone the hyprland repository. shell returned:\n" << ret << "\n";
|
std::println(stderr, "\n{}", failureString("Could not clone the Hyprland repository. shell returned:\n{}", ret));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " cloned");
|
progress.printMessageAbove(successString("Hyprland cloned"));
|
||||||
progress.m_iSteps = 2;
|
progress.m_iSteps = 2;
|
||||||
progress.m_szCurrentMessage = "Checking out sources";
|
progress.m_szCurrentMessage = "Checking out sources";
|
||||||
progress.print();
|
progress.print();
|
||||||
|
|
||||||
if (m_bVerbose)
|
if (m_bVerbose)
|
||||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "will run: " + "cd " + WORKINGDIR + " && git checkout " + HLVER.hash + " 2>&1");
|
progress.printMessageAbove(verboseString("will run: cd {} && git checkout {} 2>&1", WORKINGDIR, HLVER.hash));
|
||||||
|
|
||||||
ret = execAndGet("cd " + WORKINGDIR + " && git checkout " + HLVER.hash + " 2>&1");
|
ret = execAndGet("cd " + WORKINGDIR + " && git checkout " + HLVER.hash + " 2>&1");
|
||||||
|
|
||||||
if (ret.contains("fatal: unable to read tree")) {
|
if (ret.contains("fatal: unable to read tree")) {
|
||||||
std::cerr << "\n"
|
std::println(stderr, "\n{}",
|
||||||
<< Colors::RED << "✖" << Colors::RESET
|
failureString("Could not checkout the running Hyprland commit. If you are on -git, try updating.\n"
|
||||||
<< " Could not checkout the running Hyprland commit. If you are on -git, try updating.\nYou can also try re-running hyprpm update with --no-shallow.\n";
|
"You can also try re-running hyprpm update with --no-shallow."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_bVerbose)
|
if (m_bVerbose)
|
||||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "git returned (co): " + ret);
|
progress.printMessageAbove(verboseString("git returned (co): {}", ret));
|
||||||
|
|
||||||
ret = execAndGet("cd " + WORKINGDIR + " ; git rm subprojects/tracy ; git submodule update --init 2>&1 ; git reset --hard --recurse-submodules " + HLVER.hash);
|
ret = execAndGet("cd " + WORKINGDIR + " ; git rm subprojects/tracy ; git submodule update --init 2>&1 ; git reset --hard --recurse-submodules " + HLVER.hash);
|
||||||
|
|
||||||
if (m_bVerbose)
|
if (m_bVerbose)
|
||||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "git returned (rs): " + ret);
|
progress.printMessageAbove(verboseString("git returned (rs): {}", ret));
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " checked out to running ver");
|
progress.printMessageAbove(successString("checked out to running ver"));
|
||||||
progress.m_iSteps = 3;
|
progress.m_iSteps = 3;
|
||||||
progress.m_szCurrentMessage = "Building Hyprland";
|
progress.m_szCurrentMessage = "Building Hyprland";
|
||||||
progress.print();
|
progress.print();
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::YELLOW} + "!" + Colors::RESET + " configuring Hyprland");
|
progress.printMessageAbove(statusString("!", Colors::YELLOW, "configuring Hyprland"));
|
||||||
|
|
||||||
if (m_bVerbose)
|
if (m_bVerbose)
|
||||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "setting PREFIX for cmake to " + DataState::getHeadersPath());
|
progress.printMessageAbove(verboseString("setting PREFIX for cmake to {}", DataState::getHeadersPath()));
|
||||||
|
|
||||||
ret = execAndGet(std::format("cd {} && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=\"{}\" -S . -B ./build -G Ninja", WORKINGDIR,
|
ret = execAndGet(std::format("cd {} && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:STRING=\"{}\" -S . -B ./build -G Ninja", WORKINGDIR,
|
||||||
DataState::getHeadersPath()));
|
DataState::getHeadersPath()));
|
||||||
if (m_bVerbose)
|
if (m_bVerbose)
|
||||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "cmake returned: " + ret);
|
progress.printMessageAbove(verboseString("cmake returned: {}", ret));
|
||||||
|
|
||||||
if (ret.contains("CMake Error at")) {
|
if (ret.contains("CMake Error at")) {
|
||||||
// missing deps, let the user know.
|
// missing deps, let the user know.
|
||||||
|
@ -506,48 +511,46 @@ bool CPluginManager::updateHeaders(bool force) {
|
||||||
missing = missing.substr(0, missing.find("-- Configuring incomplete"));
|
missing = missing.substr(0, missing.find("-- Configuring incomplete"));
|
||||||
missing = missing.substr(0, missing.find_last_of('\n'));
|
missing = missing.substr(0, missing.find_last_of('\n'));
|
||||||
|
|
||||||
std::cerr << "\n"
|
std::println(stderr, "\n{}",
|
||||||
<< Colors::RED << "✖" << Colors::RESET << " Could not configure the hyprland source, cmake complained:\n"
|
failureString("Could not configure the hyprland source, cmake complained:\n{}\n\n"
|
||||||
<< missing << "\n\nThis likely means that you are missing the above dependencies or they are out of date.\n";
|
"This likely means that you are missing the above dependencies or they are out of date.",
|
||||||
|
missing));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " configured Hyprland");
|
progress.printMessageAbove(successString("configured Hyprland"));
|
||||||
progress.m_iSteps = 4;
|
progress.m_iSteps = 4;
|
||||||
progress.m_szCurrentMessage = "Installing sources";
|
progress.m_szCurrentMessage = "Installing sources";
|
||||||
progress.print();
|
progress.print();
|
||||||
|
|
||||||
std::string cmd =
|
const std::string& cmd =
|
||||||
std::format("sed -i -e \"s#PREFIX = /usr/local#PREFIX = {}#\" {}/Makefile && cd {} && make installheaders", DataState::getHeadersPath(), WORKINGDIR, WORKINGDIR);
|
std::format("sed -i -e \"s#PREFIX = /usr/local#PREFIX = {}#\" {}/Makefile && cd {} && make installheaders", DataState::getHeadersPath(), WORKINGDIR, WORKINGDIR);
|
||||||
if (m_bVerbose)
|
if (m_bVerbose)
|
||||||
progress.printMessageAbove(std::string{Colors::BLUE} + "[v] " + Colors::RESET + "installation will run: " + cmd);
|
progress.printMessageAbove(verboseString("installation will run: {}", cmd));
|
||||||
|
|
||||||
ret = execAndGet(cmd);
|
ret = execAndGet(cmd);
|
||||||
|
|
||||||
if (m_bVerbose)
|
if (m_bVerbose)
|
||||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "installer returned: " << ret << "\n";
|
std::println("{}", verboseString("installer returned: {}", ret));
|
||||||
|
|
||||||
// remove build files
|
// remove build files
|
||||||
std::filesystem::remove_all(WORKINGDIR);
|
std::filesystem::remove_all(WORKINGDIR);
|
||||||
|
|
||||||
auto HEADERSVALID = headersValid();
|
auto HEADERSVALID = headersValid();
|
||||||
if (HEADERSVALID == HEADERS_OK) {
|
if (HEADERSVALID == HEADERS_OK) {
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " installed headers");
|
progress.printMessageAbove(successString("installed headers"));
|
||||||
progress.m_iSteps = 5;
|
progress.m_iSteps = 5;
|
||||||
progress.m_szCurrentMessage = "Done!";
|
progress.m_szCurrentMessage = "Done!";
|
||||||
progress.print();
|
progress.print();
|
||||||
|
|
||||||
std::cout << "\n";
|
std::print("\n");
|
||||||
} else {
|
} else {
|
||||||
progress.printMessageAbove(std::string{Colors::RED} + "✖" + Colors::RESET + " failed to install headers with error code " + std::to_string((int)HEADERSVALID) + " (" +
|
progress.printMessageAbove(failureString("failed to install headers with error code {} ({})", (int)HEADERSVALID, headerErrorShort(HEADERSVALID)));
|
||||||
headerErrorShort(HEADERSVALID) + ")");
|
|
||||||
progress.m_iSteps = 5;
|
progress.m_iSteps = 5;
|
||||||
progress.m_szCurrentMessage = "Failed";
|
progress.m_szCurrentMessage = "Failed";
|
||||||
progress.print();
|
progress.print();
|
||||||
|
|
||||||
std::cout << "\n";
|
std::print(stderr, "\n\n{}", headerError(HEADERSVALID));
|
||||||
|
|
||||||
std::cerr << "\n" << headerError(HEADERSVALID);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -557,14 +560,14 @@ bool CPluginManager::updateHeaders(bool force) {
|
||||||
|
|
||||||
bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||||
if (headersValid() != HEADERS_OK) {
|
if (headersValid() != HEADERS_OK) {
|
||||||
std::cout << "\n" << std::string{Colors::RED} + "✖" + Colors::RESET + " headers are not up-to-date, please run hyprpm update.\n";
|
std::println("{}", failureString("headers are not up-to-date, please run hyprpm update."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto REPOS = DataState::getAllRepositories();
|
const auto REPOS = DataState::getAllRepositories();
|
||||||
|
|
||||||
if (REPOS.size() < 1) {
|
if (REPOS.size() < 1) {
|
||||||
std::cout << "\n" << std::string{Colors::RED} + "✖" + Colors::RESET + " No repos to update.\n";
|
std::println("{}", failureString("No repos to update."));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,32 +582,33 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||||
const std::string USERNAME = getpwuid(getuid())->pw_name;
|
const std::string USERNAME = getpwuid(getuid())->pw_name;
|
||||||
m_szWorkingPluginDirectory = "/tmp/hyprpm/" + USERNAME;
|
m_szWorkingPluginDirectory = "/tmp/hyprpm/" + USERNAME;
|
||||||
|
|
||||||
for (auto& repo : REPOS) {
|
for (auto const& repo : REPOS) {
|
||||||
bool update = forceUpdateAll;
|
bool update = forceUpdateAll;
|
||||||
|
|
||||||
progress.m_iSteps++;
|
progress.m_iSteps++;
|
||||||
progress.m_szCurrentMessage = "Updating " + repo.name;
|
progress.m_szCurrentMessage = "Updating " + repo.name;
|
||||||
progress.print();
|
progress.print();
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::RESET} + " → checking for updates for " + repo.name);
|
progress.printMessageAbove(infoString("checking for updates for {}", repo.name));
|
||||||
|
|
||||||
createSafeDirectory(m_szWorkingPluginDirectory);
|
createSafeDirectory(m_szWorkingPluginDirectory);
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Cloning " + repo.url);
|
progress.printMessageAbove(infoString("Cloning {}", repo.url));
|
||||||
|
|
||||||
std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive " + repo.url + " " + USERNAME);
|
std::string ret = execAndGet("cd /tmp/hyprpm && git clone --recursive " + repo.url + " " + USERNAME);
|
||||||
|
|
||||||
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/.git")) {
|
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/.git")) {
|
||||||
std::cout << "\n" << std::string{Colors::RED} + "✖" + Colors::RESET + " could not clone repo: shell returned:\n" + ret;
|
std::println("{}", failureString("could not clone repo: shell returned: {}", ret));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!repo.rev.empty()) {
|
if (!repo.rev.empty()) {
|
||||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Plugin has revision set, resetting: " + repo.rev);
|
progress.printMessageAbove(infoString("Plugin has revision set, resetting: {}", repo.rev));
|
||||||
|
|
||||||
std::string ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " reset --hard --recurse-submodules " + repo.rev);
|
std::string ret = execAndGet("git -C " + m_szWorkingPluginDirectory + " reset --hard --recurse-submodules " + repo.rev);
|
||||||
if (ret.compare(0, 6, "fatal:") == 0) {
|
if (ret.compare(0, 6, "fatal:") == 0) {
|
||||||
std::cout << "\n" << std::string{Colors::RED} + "✖" + Colors::RESET + " could not check out revision " + repo.rev + ": shell returned:\n" + ret;
|
std::println(stderr, "\n{}", failureString("could not check out revision {}: shell returned:\n{}", repo.rev, ret));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -620,7 +624,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||||
|
|
||||||
if (!update) {
|
if (!update) {
|
||||||
std::filesystem::remove_all(m_szWorkingPluginDirectory);
|
std::filesystem::remove_all(m_szWorkingPluginDirectory);
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " repository " + repo.name + " is up-to-date.");
|
progress.printMessageAbove(successString("repository {} is up-to-date.", repo.name));
|
||||||
progress.m_iSteps++;
|
progress.m_iSteps++;
|
||||||
progress.print();
|
progress.print();
|
||||||
continue;
|
continue;
|
||||||
|
@ -628,41 +632,41 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||||
|
|
||||||
// we need to update
|
// we need to update
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " repository " + repo.name + " has updates.");
|
progress.printMessageAbove(successString("repository {} has updates.", repo.name));
|
||||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Building " + repo.name);
|
progress.printMessageAbove(infoString("Building {}", repo.name));
|
||||||
progress.m_iSteps++;
|
progress.m_iSteps++;
|
||||||
progress.print();
|
progress.print();
|
||||||
|
|
||||||
std::unique_ptr<CManifest> pManifest;
|
std::unique_ptr<CManifest> pManifest;
|
||||||
|
|
||||||
if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprpm.toml")) {
|
if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprpm.toml")) {
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " found hyprpm manifest");
|
progress.printMessageAbove(successString("found hyprpm manifest"));
|
||||||
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRPM, m_szWorkingPluginDirectory + "/hyprpm.toml");
|
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRPM, m_szWorkingPluginDirectory + "/hyprpm.toml");
|
||||||
} else if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprload.toml")) {
|
} else if (std::filesystem::exists(m_szWorkingPluginDirectory + "/hyprload.toml")) {
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " found hyprload manifest");
|
progress.printMessageAbove(successString("found hyprload manifest"));
|
||||||
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, m_szWorkingPluginDirectory + "/hyprload.toml");
|
pManifest = std::make_unique<CManifest>(MANIFEST_HYPRLOAD, m_szWorkingPluginDirectory + "/hyprload.toml");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pManifest) {
|
if (!pManifest) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " The provided plugin repository does not have a valid manifest\n";
|
std::println(stderr, "\n{}", failureString("The provided plugin repository does not have a valid manifest"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pManifest->m_bGood) {
|
if (!pManifest->m_bGood) {
|
||||||
std::cerr << "\n" << Colors::RED << "✖" << Colors::RESET << " The provided plugin repository has a corrupted manifest\n";
|
std::println(stderr, "\n{}", failureString("The provided plugin repository has a corrupted manifest"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (repo.rev.empty() && !pManifest->m_sRepository.commitPins.empty()) {
|
if (repo.rev.empty() && !pManifest->m_sRepository.commitPins.empty()) {
|
||||||
// check commit pins unless a revision is specified
|
// check commit pins unless a revision is specified
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Manifest has " + std::to_string(pManifest->m_sRepository.commitPins.size()) + " pins, checking");
|
progress.printMessageAbove(infoString("Manifest has {} pins, checking", pManifest->m_sRepository.commitPins.size()));
|
||||||
|
|
||||||
for (auto& [hl, plugin] : pManifest->m_sRepository.commitPins) {
|
for (auto const& [hl, plugin] : pManifest->m_sRepository.commitPins) {
|
||||||
if (hl != HLVER.hash)
|
if (hl != HLVER.hash)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " commit pin " + plugin + " matched hl, resetting");
|
progress.printMessageAbove(successString("commit pin {} matched hl, resetting", plugin));
|
||||||
|
|
||||||
execAndGet("cd " + m_szWorkingPluginDirectory + " && git reset --hard --recurse-submodules " + plugin);
|
execAndGet("cd " + m_szWorkingPluginDirectory + " && git reset --hard --recurse-submodules " + plugin);
|
||||||
}
|
}
|
||||||
|
@ -672,32 +676,33 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||||
std::string out;
|
std::string out;
|
||||||
|
|
||||||
if (p.since > HLVER.commits && HLVER.commits >= 1000 /* for shallow clones, we can't check this. 1000 is an arbitrary number I chose. */) {
|
if (p.since > HLVER.commits && HLVER.commits >= 1000 /* for shallow clones, we can't check this. 1000 is an arbitrary number I chose. */) {
|
||||||
progress.printMessageAbove(std::string{Colors::RED} + "✖" + Colors::RESET + " Not building " + p.name + ": your Hyprland version is too old.\n");
|
progress.printMessageAbove(failureString("Not building {}: your Hyprland version is too old.\n", p.name));
|
||||||
p.failed = true;
|
p.failed = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::RESET} + " → Building " + p.name);
|
progress.printMessageAbove(infoString("Building {}", p.name));
|
||||||
|
|
||||||
for (auto& bs : p.buildSteps) {
|
for (auto const& bs : p.buildSteps) {
|
||||||
std::string cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
|
const std::string& cmd = std::format("cd {} && PKG_CONFIG_PATH=\"{}/share/pkgconfig\" {}", m_szWorkingPluginDirectory, DataState::getHeadersPath(), bs);
|
||||||
out += " -> " + cmd + "\n" + execAndGet(cmd) + "\n";
|
out += " -> " + cmd + "\n" + execAndGet(cmd) + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_bVerbose)
|
if (m_bVerbose)
|
||||||
std::cout << Colors::BLUE << "[v] " << Colors::RESET << "shell returned: " << out << "\n";
|
std::println("{}", verboseString("shell returned: {}", out));
|
||||||
|
|
||||||
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/" + p.output)) {
|
if (!std::filesystem::exists(m_szWorkingPluginDirectory + "/" + p.output)) {
|
||||||
std::cerr << "\n"
|
std::println(stderr,
|
||||||
<< Colors::RED << "✖" << Colors::RESET << " Plugin " << p.name << " failed to build.\n"
|
"\n{}\n"
|
||||||
<< " This likely means that the plugin is either outdated, not yet available for your version, or broken.\n If you are on -git, update first.\n Try "
|
" This likely means that the plugin is either outdated, not yet available for your version, or broken.\n"
|
||||||
"re-running with -v to see more verbose "
|
"If you are on -git, update first.\n"
|
||||||
"output.\n";
|
"Try re-running with -v to see more verbose output.",
|
||||||
|
failureString("Plugin {} failed to build.", p.name));
|
||||||
p.failed = true;
|
p.failed = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " built " + p.name + " into " + p.output);
|
progress.printMessageAbove(successString("built {} into {}", p.name, p.output));
|
||||||
}
|
}
|
||||||
|
|
||||||
// add repo toml to DataState
|
// add repo toml to DataState
|
||||||
|
@ -709,7 +714,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||||
if (repohash.length() > 0)
|
if (repohash.length() > 0)
|
||||||
repohash.pop_back();
|
repohash.pop_back();
|
||||||
newrepo.hash = repohash;
|
newrepo.hash = repohash;
|
||||||
for (auto& p : pManifest->m_vPlugins) {
|
for (auto const& p : pManifest->m_vPlugins) {
|
||||||
const auto OLDPLUGINIT = std::find_if(repo.plugins.begin(), repo.plugins.end(), [&](const auto& other) { return other.name == p.name; });
|
const auto OLDPLUGINIT = std::find_if(repo.plugins.begin(), repo.plugins.end(), [&](const auto& other) { return other.name == p.name; });
|
||||||
newrepo.plugins.push_back(SPlugin{p.name, m_szWorkingPluginDirectory + "/" + p.output, OLDPLUGINIT != repo.plugins.end() ? OLDPLUGINIT->enabled : false});
|
newrepo.plugins.push_back(SPlugin{p.name, m_szWorkingPluginDirectory + "/" + p.output, OLDPLUGINIT != repo.plugins.end() ? OLDPLUGINIT->enabled : false});
|
||||||
}
|
}
|
||||||
|
@ -718,7 +723,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||||
|
|
||||||
std::filesystem::remove_all(m_szWorkingPluginDirectory);
|
std::filesystem::remove_all(m_szWorkingPluginDirectory);
|
||||||
|
|
||||||
progress.printMessageAbove(std::string{Colors::GREEN} + "✔" + Colors::RESET + " updated " + repo.name);
|
progress.printMessageAbove(successString("updated {}", repo.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.m_iSteps++;
|
progress.m_iSteps++;
|
||||||
|
@ -733,7 +738,7 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||||
progress.m_szCurrentMessage = "Done!";
|
progress.m_szCurrentMessage = "Done!";
|
||||||
progress.print();
|
progress.print();
|
||||||
|
|
||||||
std::cout << "\n";
|
std::print("\n");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -741,27 +746,27 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
|
||||||
bool CPluginManager::enablePlugin(const std::string& name) {
|
bool CPluginManager::enablePlugin(const std::string& name) {
|
||||||
bool ret = DataState::setPluginEnabled(name, true);
|
bool ret = DataState::setPluginEnabled(name, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
std::cout << Colors::GREEN << "✔" << Colors::RESET << " Enabled " << name << "\n";
|
std::println("{}", successString("Enabled {}", name));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPluginManager::disablePlugin(const std::string& name) {
|
bool CPluginManager::disablePlugin(const std::string& name) {
|
||||||
bool ret = DataState::setPluginEnabled(name, false);
|
bool ret = DataState::setPluginEnabled(name, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
std::cout << Colors::GREEN << "✔" << Colors::RESET << " Disabled " << name << "\n";
|
std::println("{}", successString("Disabled {}", name));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
|
ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
|
||||||
if (headersValid() != HEADERS_OK) {
|
if (headersValid() != HEADERS_OK) {
|
||||||
std::cerr << "\n" << std::string{Colors::RED} + "✖" + Colors::RESET + " headers are not up-to-date, please run hyprpm update.\n";
|
std::println(stderr, "\n{}", failureString("headers are not up-to-date, please run hyprpm update."));
|
||||||
return LOADSTATE_HEADERS_OUTDATED;
|
return LOADSTATE_HEADERS_OUTDATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto HOME = getenv("HOME");
|
const auto HOME = getenv("HOME");
|
||||||
const auto HIS = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
const auto HIS = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
||||||
if (!HOME || !HIS) {
|
if (!HOME || !HIS) {
|
||||||
std::cerr << "PluginManager: no $HOME or HIS\n";
|
std::println(stderr, "PluginManager: no $HOME or HIS");
|
||||||
return LOADSTATE_FAIL;
|
return LOADSTATE_FAIL;
|
||||||
}
|
}
|
||||||
const auto HYPRPMPATH = DataState::getDataStatePath() + "/";
|
const auto HYPRPMPATH = DataState::getDataStatePath() + "/";
|
||||||
|
@ -770,14 +775,14 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
|
||||||
|
|
||||||
std::vector<std::string> loadedPlugins;
|
std::vector<std::string> loadedPlugins;
|
||||||
|
|
||||||
std::cout << Colors::GREEN << "✔" << Colors::RESET << " Ensuring plugin load state\n";
|
std::println("{}", successString("Ensuring plugin load state"));
|
||||||
|
|
||||||
// iterate line by line
|
// iterate line by line
|
||||||
while (!pluginLines.empty()) {
|
while (!pluginLines.empty()) {
|
||||||
auto plLine = pluginLines.substr(0, pluginLines.find("\n"));
|
auto plLine = pluginLines.substr(0, pluginLines.find('\n'));
|
||||||
|
|
||||||
if (pluginLines.find("\n") != std::string::npos)
|
if (pluginLines.find('\n') != std::string::npos)
|
||||||
pluginLines = pluginLines.substr(pluginLines.find("\n") + 1);
|
pluginLines = pluginLines.substr(pluginLines.find('\n') + 1);
|
||||||
else
|
else
|
||||||
pluginLines = "";
|
pluginLines = "";
|
||||||
|
|
||||||
|
@ -794,8 +799,8 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
|
||||||
const auto REPOS = DataState::getAllRepositories();
|
const auto REPOS = DataState::getAllRepositories();
|
||||||
|
|
||||||
auto enabled = [REPOS](const std::string& plugin) -> bool {
|
auto enabled = [REPOS](const std::string& plugin) -> bool {
|
||||||
for (auto& r : REPOS) {
|
for (auto const& r : REPOS) {
|
||||||
for (auto& p : r.plugins) {
|
for (auto const& p : r.plugins) {
|
||||||
if (p.name == plugin && p.enabled)
|
if (p.name == plugin && p.enabled)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -805,8 +810,8 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
|
||||||
};
|
};
|
||||||
|
|
||||||
auto repoForName = [REPOS](const std::string& name) -> std::string {
|
auto repoForName = [REPOS](const std::string& name) -> std::string {
|
||||||
for (auto& r : REPOS) {
|
for (auto const& r : REPOS) {
|
||||||
for (auto& p : r.plugins) {
|
for (auto const& p : r.plugins) {
|
||||||
if (p.name == name)
|
if (p.name == name)
|
||||||
return r.name;
|
return r.name;
|
||||||
}
|
}
|
||||||
|
@ -816,17 +821,17 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
|
||||||
};
|
};
|
||||||
|
|
||||||
// unload disabled plugins
|
// unload disabled plugins
|
||||||
for (auto& p : loadedPlugins) {
|
for (auto const& p : loadedPlugins) {
|
||||||
if (!enabled(p)) {
|
if (!enabled(p)) {
|
||||||
// unload
|
// unload
|
||||||
loadUnloadPlugin(HYPRPMPATH + repoForName(p) + "/" + p + ".so", false);
|
loadUnloadPlugin(HYPRPMPATH + repoForName(p) + "/" + p + ".so", false);
|
||||||
std::cout << Colors::GREEN << "✔" << Colors::RESET << " Unloaded " << p << "\n";
|
std::println("{}", successString("Unloaded {}", p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// load enabled plugins
|
// load enabled plugins
|
||||||
for (auto& r : REPOS) {
|
for (auto const& r : REPOS) {
|
||||||
for (auto& p : r.plugins) {
|
for (auto const& p : r.plugins) {
|
||||||
if (!p.enabled)
|
if (!p.enabled)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -834,11 +839,11 @@ ePluginLoadStateReturn CPluginManager::ensurePluginsLoadState() {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
loadUnloadPlugin(HYPRPMPATH + repoForName(p.name) + "/" + p.filename, true);
|
loadUnloadPlugin(HYPRPMPATH + repoForName(p.name) + "/" + p.filename, true);
|
||||||
std::cout << Colors::GREEN << "✔" << Colors::RESET << " Loaded " << p.name << "\n";
|
std::println("{}", successString("Loaded {}", p.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << Colors::GREEN << "✔" << Colors::RESET << " Plugin load state ensured\n";
|
std::println("{}", successString("Plugin load state ensured"));
|
||||||
|
|
||||||
return LOADSTATE_OK;
|
return LOADSTATE_OK;
|
||||||
}
|
}
|
||||||
|
@ -855,17 +860,18 @@ bool CPluginManager::loadUnloadPlugin(const std::string& path, bool load) {
|
||||||
void CPluginManager::listAllPlugins() {
|
void CPluginManager::listAllPlugins() {
|
||||||
const auto REPOS = DataState::getAllRepositories();
|
const auto REPOS = DataState::getAllRepositories();
|
||||||
|
|
||||||
for (auto& r : REPOS) {
|
for (auto const& r : REPOS) {
|
||||||
std::cout << std::string{Colors::RESET} + " → Repository " + r.name + ":\n";
|
std::println("{}", infoString("Repository {}:", r.name));
|
||||||
|
|
||||||
for (auto& p : r.plugins) {
|
for (auto const& p : r.plugins) {
|
||||||
|
std::println(" │ Plugin {}", p.name);
|
||||||
std::cout << std::string{Colors::RESET} + " │ Plugin " + p.name;
|
|
||||||
|
|
||||||
if (!p.failed)
|
if (!p.failed)
|
||||||
std::cout << "\n └─ enabled: " << (p.enabled ? Colors::GREEN : Colors::RED) << (p.enabled ? "true" : "false") << Colors::RESET << "\n";
|
std::println(" └─ enabled: {}", (p.enabled ? std::string{Colors::GREEN} + "true" : std::string{Colors::RED} + "false"));
|
||||||
else
|
else
|
||||||
std::cout << "\n └─ enabled: " << Colors::RED << "Plugin failed to build" << Colors::RESET << "\n";
|
std::println(" └─ enabled: {}Plugin failed to build", Colors::RED);
|
||||||
|
|
||||||
|
std::println("{}", Colors::RESET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -876,19 +882,19 @@ void CPluginManager::notify(const eNotifyIcons icon, uint32_t color, int duratio
|
||||||
|
|
||||||
std::string CPluginManager::headerError(const eHeadersErrors err) {
|
std::string CPluginManager::headerError(const eHeadersErrors err) {
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case HEADERS_CORRUPTED: return std::string{Colors::RED} + "✖" + Colors::RESET + " Headers corrupted. Please run hyprpm update to fix those.\n";
|
case HEADERS_CORRUPTED: return failureString("Headers corrupted. Please run hyprpm update to fix those.\n");
|
||||||
case HEADERS_MISMATCHED: return std::string{Colors::RED} + "✖" + Colors::RESET + " Headers version mismatch. Please run hyprpm update to fix those.\n";
|
case HEADERS_MISMATCHED: return failureString("Headers version mismatch. Please run hyprpm update to fix those.\n");
|
||||||
case HEADERS_NOT_HYPRLAND: return std::string{Colors::RED} + "✖" + Colors::RESET + " It doesn't seem you are running on hyprland.\n";
|
case HEADERS_NOT_HYPRLAND: return failureString("It doesn't seem you are running on hyprland.\n");
|
||||||
case HEADERS_MISSING: return std::string{Colors::RED} + "✖" + Colors::RESET + " Headers missing. Please run hyprpm update to fix those.\n";
|
case HEADERS_MISSING: return failureString("Headers missing. Please run hyprpm update to fix those.\n");
|
||||||
case HEADERS_DUPLICATED: {
|
case HEADERS_DUPLICATED: {
|
||||||
return std::string{Colors::RED} + "✖" + Colors::RESET + " Headers duplicated!!! This is a very bad sign.\n" +
|
return failureString("Headers duplicated!!! This is a very bad sign.\n"
|
||||||
" This could be due to e.g. installing hyprland manually while a system package of hyprland is also installed.\n" +
|
"This could be due to e.g. installing hyprland manually while a system package of hyprland is also installed.\n"
|
||||||
" If the above doesn't apply, check your /usr/include and /usr/local/include directories\n and remove all the hyprland headers.\n";
|
"If the above doesn't apply, check your /usr/include and /usr/local/include directories\n and remove all the hyprland headers.\n");
|
||||||
}
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::string{Colors::RED} + "✖" + Colors::RESET + " Unknown header error. Please run hyprpm update to fix those.\n";
|
return failureString("Unknown header error. Please run hyprpm update to fix those.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CPluginManager::headerErrorShort(const eHeadersErrors err) {
|
std::string CPluginManager::headerErrorShort(const eHeadersErrors err) {
|
||||||
|
@ -904,9 +910,9 @@ std::string CPluginManager::headerErrorShort(const eHeadersErrors err) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPluginManager::hasDeps() {
|
bool CPluginManager::hasDeps() {
|
||||||
std::vector<std::string> deps = {"meson", "cpio", "cmake"};
|
std::vector<std::string> deps = {"meson", "cpio", "cmake", "pkg-config"};
|
||||||
for (auto& d : deps) {
|
for (auto const& d : deps) {
|
||||||
if (!execAndGet("which " + d + " 2>&1").contains("/"))
|
if (!execAndGet("command -v " + d).contains("/"))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
enum eHeadersErrors {
|
enum eHeadersErrors {
|
||||||
HEADERS_OK = 0,
|
HEADERS_OK = 0,
|
||||||
|
@ -68,7 +69,7 @@ class CPluginManager {
|
||||||
std::string headerError(const eHeadersErrors err);
|
std::string headerError(const eHeadersErrors err);
|
||||||
std::string headerErrorShort(const eHeadersErrors err);
|
std::string headerErrorShort(const eHeadersErrors err);
|
||||||
|
|
||||||
std::string m_szWorkingPluginDirectory = "";
|
std::string m_szWorkingPluginDirectory;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CPluginManager> g_pPluginManager;
|
inline std::unique_ptr<CPluginManager> g_pPluginManager;
|
||||||
|
|
32
hyprpm/src/helpers/StringUtils.hpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <format>
|
||||||
|
#include <string>
|
||||||
|
#include "Colors.hpp"
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
std::string statusString(const std::string_view emoji, const std::string_view color, const std::string_view fmt, Args&&... args) {
|
||||||
|
std::string ret = std::format("{}{}{} ", color, emoji, Colors::RESET);
|
||||||
|
ret += std::vformat(fmt, std::make_format_args(args...));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
std::string successString(const std::string_view fmt, Args&&... args) {
|
||||||
|
return statusString("✔", Colors::GREEN, fmt, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
std::string failureString(const std::string_view fmt, Args&&... args) {
|
||||||
|
return statusString("✖", Colors::RED, fmt, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
std::string verboseString(const std::string_view fmt, Args&&... args) {
|
||||||
|
return statusString("[v]", Colors::BLUE, fmt, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
std::string infoString(const std::string_view fmt, Args&&... args) {
|
||||||
|
return statusString("→", Colors::RESET, fmt, args...);
|
||||||
|
}
|
|
@ -1,15 +1,16 @@
|
||||||
#include "progress/CProgressBar.hpp"
|
|
||||||
#include "helpers/Colors.hpp"
|
#include "helpers/Colors.hpp"
|
||||||
|
#include "helpers/StringUtils.hpp"
|
||||||
#include "core/PluginManager.hpp"
|
#include "core/PluginManager.hpp"
|
||||||
#include "core/DataState.hpp"
|
#include "core/DataState.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <cstdio>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <print>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
const std::string HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
constexpr std::string_view HELP = R"#(┏ hyprpm, a Hyprland Plugin Manager
|
||||||
┃
|
┃
|
||||||
┣ add [url] [git rev] → Install a new plugin repository from git. Git revision
|
┣ add [url] [git rev] → Install a new plugin repository from git. Git revision
|
||||||
┃ is optional, when set, commit locks are ignored.
|
┃ is optional, when set, commit locks are ignored.
|
||||||
|
@ -37,7 +38,7 @@ int main(int argc, char** argv, char** envp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ARGS.size() < 2) {
|
if (ARGS.size() < 2) {
|
||||||
std::cout << HELP;
|
std::println(stderr, "{}", HELP);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ int main(int argc, char** argv, char** envp) {
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
if (ARGS[i].starts_with("-")) {
|
if (ARGS[i].starts_with("-")) {
|
||||||
if (ARGS[i] == "--help" || ARGS[i] == "-h") {
|
if (ARGS[i] == "--help" || ARGS[i] == "-h") {
|
||||||
std::cout << HELP;
|
std::println("{}", HELP);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (ARGS[i] == "--notify" || ARGS[i] == "-n") {
|
} else if (ARGS[i] == "--notify" || ARGS[i] == "-n") {
|
||||||
notify = true;
|
notify = true;
|
||||||
|
@ -57,9 +58,9 @@ int main(int argc, char** argv, char** envp) {
|
||||||
noShallow = true;
|
noShallow = true;
|
||||||
} else if (ARGS[i] == "--force" || ARGS[i] == "-f") {
|
} else if (ARGS[i] == "--force" || ARGS[i] == "-f") {
|
||||||
force = true;
|
force = true;
|
||||||
std::cout << Colors::RED << "!" << Colors::RESET << " Using --force, I hope you know what you are doing.\n";
|
std::println("{}", statusString("!", Colors::RED, "Using --force, I hope you know what you are doing."));
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Unrecognized option " << ARGS[i] << "\n";
|
std::println(stderr, "Unrecognized option {}", ARGS[i]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -68,7 +69,7 @@ int main(int argc, char** argv, char** envp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command.empty()) {
|
if (command.empty()) {
|
||||||
std::cout << HELP;
|
std::println(stderr, "{}", HELP);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +79,7 @@ int main(int argc, char** argv, char** envp) {
|
||||||
|
|
||||||
if (command[0] == "add") {
|
if (command[0] == "add") {
|
||||||
if (command.size() < 2) {
|
if (command.size() < 2) {
|
||||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for add.\n";
|
std::println(stderr, "{}", failureString("Not enough args for add."));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ int main(int argc, char** argv, char** envp) {
|
||||||
return g_pPluginManager->addNewPluginRepo(command[1], rev) ? 0 : 1;
|
return g_pPluginManager->addNewPluginRepo(command[1], rev) ? 0 : 1;
|
||||||
} else if (command[0] == "remove") {
|
} else if (command[0] == "remove") {
|
||||||
if (ARGS.size() < 2) {
|
if (ARGS.size() < 2) {
|
||||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for remove.\n";
|
std::println(stderr, "{}", failureString("Not enough args for remove."));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,12 +117,12 @@ int main(int argc, char** argv, char** envp) {
|
||||||
g_pPluginManager->notify(ICON_ERROR, 0, 10000, "[hyprpm] Couldn't update headers");
|
g_pPluginManager->notify(ICON_ERROR, 0, 10000, "[hyprpm] Couldn't update headers");
|
||||||
} else if (command[0] == "enable") {
|
} else if (command[0] == "enable") {
|
||||||
if (ARGS.size() < 2) {
|
if (ARGS.size() < 2) {
|
||||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for enable.\n";
|
std::println(stderr, "{}", failureString("Not enough args for enable."));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_pPluginManager->enablePlugin(command[1])) {
|
if (!g_pPluginManager->enablePlugin(command[1])) {
|
||||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Couldn't enable plugin (missing?)\n";
|
std::println(stderr, "{}", failureString("Couldn't enable plugin (missing?)"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,12 +131,12 @@ int main(int argc, char** argv, char** envp) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if (command[0] == "disable") {
|
} else if (command[0] == "disable") {
|
||||||
if (command.size() < 2) {
|
if (command.size() < 2) {
|
||||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Not enough args for disable.\n";
|
std::println(stderr, "{}", failureString("Not enough args for disable."));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_pPluginManager->disablePlugin(command[1])) {
|
if (!g_pPluginManager->disablePlugin(command[1])) {
|
||||||
std::cerr << Colors::RED << "✖" << Colors::RESET << " Couldn't disable plugin (missing?)\n";
|
std::println(stderr, "{}", failureString("Couldn't disable plugin (missing?)"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +161,7 @@ int main(int argc, char** argv, char** envp) {
|
||||||
} else if (command[0] == "list") {
|
} else if (command[0] == "list") {
|
||||||
g_pPluginManager->listAllPlugins();
|
g_pPluginManager->listAllPlugins();
|
||||||
} else {
|
} else {
|
||||||
std::cout << HELP;
|
std::println(stderr, "{}", HELP);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,31 @@
|
||||||
globber = run_command('sh', '-c', 'find . -name "*.cpp" | sort', check: true)
|
globber = run_command('sh', '-c', 'find . -name "*.cpp" | sort', check: true)
|
||||||
src = globber.stdout().strip().split('\n')
|
src = globber.stdout().strip().split('\n')
|
||||||
|
|
||||||
executable('hyprpm', src,
|
executable(
|
||||||
|
'hyprpm',
|
||||||
|
src,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
dependency('hyprutils', version: '>= 0.1.1'),
|
dependency('hyprutils', version: '>= 0.1.1'),
|
||||||
dependency('threads'),
|
dependency('threads'),
|
||||||
dependency('tomlplusplus')
|
dependency('tomlplusplus'),
|
||||||
],
|
],
|
||||||
install : true
|
install: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
install_data('../hyprpm.bash', install_dir: join_paths(get_option('datadir'), 'bash-completion/completions'), install_tag: 'runtime', rename: 'hyprpm')
|
install_data(
|
||||||
install_data('../hyprpm.fish', install_dir: join_paths(get_option('datadir'), 'fish/vendor_completions.d'), install_tag: 'runtime')
|
'../hyprpm.bash',
|
||||||
install_data('../hyprpm.zsh', install_dir: join_paths(get_option('datadir'), 'zsh/site-functions'), install_tag: 'runtime', rename: '_hyprpm')
|
install_dir: join_paths(get_option('datadir'), 'bash-completion/completions'),
|
||||||
|
install_tag: 'runtime',
|
||||||
|
rename: 'hyprpm',
|
||||||
|
)
|
||||||
|
install_data(
|
||||||
|
'../hyprpm.fish',
|
||||||
|
install_dir: join_paths(get_option('datadir'), 'fish/vendor_completions.d'),
|
||||||
|
install_tag: 'runtime',
|
||||||
|
)
|
||||||
|
install_data(
|
||||||
|
'../hyprpm.zsh',
|
||||||
|
install_dir: join_paths(get_option('datadir'), 'zsh/site-functions'),
|
||||||
|
install_tag: 'runtime',
|
||||||
|
rename: '_hyprpm',
|
||||||
|
)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#include "CProgressBar.hpp"
|
#include "CProgressBar.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <sys/ioctl.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <format>
|
#include <format>
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <print>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -16,11 +16,12 @@ void CProgressBar::printMessageAbove(const std::string& msg) {
|
||||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||||
|
|
||||||
std::string spaces;
|
std::string spaces;
|
||||||
|
spaces.reserve(w.ws_col);
|
||||||
for (size_t i = 0; i < w.ws_col; ++i) {
|
for (size_t i = 0; i < w.ws_col; ++i) {
|
||||||
spaces += ' ';
|
spaces += ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "\r" << spaces << "\r" << msg << "\n";
|
std::println("\r{}\r{}", spaces, msg);
|
||||||
print();
|
print();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,15 +30,16 @@ void CProgressBar::print() {
|
||||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||||
|
|
||||||
if (m_bFirstPrint)
|
if (m_bFirstPrint)
|
||||||
std::cout << "\n";
|
std::print("\n");
|
||||||
m_bFirstPrint = false;
|
m_bFirstPrint = false;
|
||||||
|
|
||||||
std::string spaces;
|
std::string spaces;
|
||||||
|
spaces.reserve(w.ws_col);
|
||||||
for (size_t i = 0; i < w.ws_col; ++i) {
|
for (size_t i = 0; i < w.ws_col; ++i) {
|
||||||
spaces += ' ';
|
spaces += ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "\r" << spaces << "\r";
|
std::print("\r{}\r", spaces);
|
||||||
|
|
||||||
std::string message = "";
|
std::string message = "";
|
||||||
|
|
||||||
|
@ -74,7 +76,7 @@ void CProgressBar::print() {
|
||||||
message += " " + std::format("{} / {}", m_iSteps, m_iMaxSteps) + " ";
|
message += " " + std::format("{} / {}", m_iSteps, m_iMaxSteps) + " ";
|
||||||
|
|
||||||
// draw message
|
// draw message
|
||||||
std::cout << message + " " + m_szCurrentMessage;
|
std::print("{} {}", message, m_szCurrentMessage);
|
||||||
|
|
||||||
std::fflush(stdout);
|
std::fflush(stdout);
|
||||||
}
|
}
|
38
meson.build
|
@ -1,13 +1,17 @@
|
||||||
project('Hyprland', 'cpp', 'c',
|
project(
|
||||||
version : run_command('cat', join_paths(meson.source_root(), 'VERSION'), check: true).stdout().strip(),
|
'Hyprland',
|
||||||
|
'cpp',
|
||||||
|
'c',
|
||||||
|
version: run_command('cat', join_paths(meson.project_source_root(), 'VERSION'), check: true).stdout().strip(),
|
||||||
default_options: [
|
default_options: [
|
||||||
'warning_level=2',
|
'warning_level=2',
|
||||||
'default_library=static',
|
'default_library=static',
|
||||||
'optimization=3',
|
'optimization=3',
|
||||||
'buildtype=release',
|
'buildtype=release',
|
||||||
'debug=false',
|
'debug=false',
|
||||||
'cpp_std=c++23',
|
'cpp_std=c++26',
|
||||||
])
|
],
|
||||||
|
)
|
||||||
|
|
||||||
datarootdir = '-DDATAROOTDIR="' + get_option('prefix') / get_option('datadir') + '"'
|
datarootdir = '-DDATAROOTDIR="' + get_option('prefix') / get_option('datadir') + '"'
|
||||||
add_project_arguments(
|
add_project_arguments(
|
||||||
|
@ -16,16 +20,20 @@ add_project_arguments(
|
||||||
'-Wno-unused-value',
|
'-Wno-unused-value',
|
||||||
'-Wno-missing-field-initializers',
|
'-Wno-missing-field-initializers',
|
||||||
'-Wno-narrowing',
|
'-Wno-narrowing',
|
||||||
'-Wno-pointer-arith',
|
'-Wno-pointer-arith', datarootdir,
|
||||||
datarootdir,
|
'-DHYPRLAND_VERSION="' + meson.project_version() + '"',
|
||||||
],
|
],
|
||||||
language: 'cpp')
|
language: 'cpp',
|
||||||
|
)
|
||||||
|
|
||||||
cpp_compiler = meson.get_compiler('cpp')
|
cpp_compiler = meson.get_compiler('cpp')
|
||||||
if cpp_compiler.check_header('execinfo.h')
|
if cpp_compiler.check_header('execinfo.h')
|
||||||
add_project_arguments('-DHAS_EXECINFO', language: 'cpp')
|
add_project_arguments('-DHAS_EXECINFO', language: 'cpp')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
aquamarine = dependency('aquamarine', version: '>=0.4.2')
|
||||||
|
add_project_arguments(['-DAQUAMARINE_VERSION="@0@"'.format(aquamarine.version())], language: 'cpp')
|
||||||
|
|
||||||
xcb_dep = dependency('xcb', required: get_option('xwayland'))
|
xcb_dep = dependency('xcb', required: get_option('xwayland'))
|
||||||
xcb_composite_dep = dependency('xcb-composite', required: get_option('xwayland'))
|
xcb_composite_dep = dependency('xcb-composite', required: get_option('xwayland'))
|
||||||
xcb_errors_dep = dependency('xcb-errors', required: get_option('xwayland'))
|
xcb_errors_dep = dependency('xcb-errors', required: get_option('xwayland'))
|
||||||
|
@ -34,9 +42,7 @@ xcb_render_dep = dependency('xcb-render', required: get_option('xwayland'))
|
||||||
xcb_res_dep = dependency('xcb-res', required: get_option('xwayland'))
|
xcb_res_dep = dependency('xcb-res', required: get_option('xwayland'))
|
||||||
xcb_xfixes_dep = dependency('xcb-xfixes', required: get_option('xwayland'))
|
xcb_xfixes_dep = dependency('xcb-xfixes', required: get_option('xwayland'))
|
||||||
|
|
||||||
cmake = import('cmake')
|
gio_dep = dependency('gio-2.0', required: true)
|
||||||
udis = cmake.subproject('udis86')
|
|
||||||
udis86 = udis.dependency('libudis86')
|
|
||||||
|
|
||||||
if not xcb_dep.found()
|
if not xcb_dep.found()
|
||||||
add_project_arguments('-DNO_XWAYLAND', language: 'cpp')
|
add_project_arguments('-DNO_XWAYLAND', language: 'cpp')
|
||||||
|
@ -45,6 +51,7 @@ endif
|
||||||
backtrace_dep = cpp_compiler.find_library('execinfo', required: false)
|
backtrace_dep = cpp_compiler.find_library('execinfo', required: false)
|
||||||
epoll_dep = dependency('epoll-shim', required: false) # timerfd on BSDs
|
epoll_dep = dependency('epoll-shim', required: false) # timerfd on BSDs
|
||||||
|
|
||||||
|
# Handle options
|
||||||
if get_option('systemd').enabled()
|
if get_option('systemd').enabled()
|
||||||
add_project_arguments('-DUSES_SYSTEMD', language: 'cpp')
|
add_project_arguments('-DUSES_SYSTEMD', language: 'cpp')
|
||||||
endif
|
endif
|
||||||
|
@ -57,14 +64,22 @@ if get_option('buildtype') == 'debug'
|
||||||
add_project_arguments('-DHYPRLAND_DEBUG', language: 'cpp')
|
add_project_arguments('-DHYPRLAND_DEBUG', language: 'cpp')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
version_h = run_command('sh', '-c', 'scripts/generateVersion.sh', check: true)
|
# Generate hyprland version and populate version.h
|
||||||
|
run_command('sh', '-c', 'scripts/generateVersion.sh', check: true)
|
||||||
|
|
||||||
|
# Install headers
|
||||||
globber = run_command('find', 'src', '-name', '*.h*', check: true)
|
globber = run_command('find', 'src', '-name', '*.h*', check: true)
|
||||||
headers = globber.stdout().strip().split('\n')
|
headers = globber.stdout().strip().split('\n')
|
||||||
foreach file : headers
|
foreach file : headers
|
||||||
install_headers(file, subdir: 'hyprland', preserve_path: true)
|
install_headers(file, subdir: 'hyprland', preserve_path: true)
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
|
tracy = dependency('tracy', static: true, required: get_option('tracy_enable'))
|
||||||
|
|
||||||
|
if get_option('tracy_enable') and get_option('buildtype') != 'debugoptimized'
|
||||||
|
warning('Profiling builds should set -- buildtype = debugoptimized')
|
||||||
|
endif
|
||||||
|
|
||||||
subdir('protocols')
|
subdir('protocols')
|
||||||
subdir('src')
|
subdir('src')
|
||||||
subdir('hyprctl')
|
subdir('hyprctl')
|
||||||
|
@ -73,6 +88,7 @@ subdir('assets')
|
||||||
subdir('example')
|
subdir('example')
|
||||||
subdir('docs')
|
subdir('docs')
|
||||||
|
|
||||||
|
# Generate hyprland.pc
|
||||||
pkg_install_dir = join_paths(get_option('datadir'), 'pkgconfig')
|
pkg_install_dir = join_paths(get_option('datadir'), 'pkgconfig')
|
||||||
|
|
||||||
import('pkgconfig').generate(
|
import('pkgconfig').generate(
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
option('xwayland', type: 'feature', value: 'auto', description: 'Enable support for X11 applications')
|
option('xwayland', type: 'feature', value: 'auto', description: 'Enable support for X11 applications')
|
||||||
option('systemd', type: 'feature', value: 'auto', description: 'Enable systemd integration')
|
option('systemd', type: 'feature', value: 'auto', description: 'Enable systemd integration')
|
||||||
option('legacy_renderer', type: 'feature', value: 'disabled', description: 'Enable legacy renderer')
|
option('legacy_renderer', type: 'feature', value: 'disabled', description: 'Enable legacy renderer')
|
||||||
|
option('tracy_enable', type: 'boolean', value: false , description: 'Enable profiling')
|
||||||
|
|
118
nix/default.nix
|
@ -1,43 +1,33 @@
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
stdenv,
|
stdenv,
|
||||||
|
stdenvAdapters,
|
||||||
pkg-config,
|
pkg-config,
|
||||||
pkgconf,
|
pkgconf,
|
||||||
makeWrapper,
|
makeWrapper,
|
||||||
cmake,
|
meson,
|
||||||
ninja,
|
ninja,
|
||||||
aquamarine,
|
aquamarine,
|
||||||
binutils,
|
binutils,
|
||||||
cairo,
|
cairo,
|
||||||
expat,
|
|
||||||
fribidi,
|
|
||||||
git,
|
git,
|
||||||
hwdata,
|
|
||||||
hyprcursor,
|
hyprcursor,
|
||||||
|
hyprland-protocols,
|
||||||
hyprlang,
|
hyprlang,
|
||||||
hyprutils,
|
hyprutils,
|
||||||
hyprwayland-scanner,
|
hyprwayland-scanner,
|
||||||
jq,
|
|
||||||
libGL,
|
libGL,
|
||||||
libdatrie,
|
|
||||||
libdisplay-info,
|
|
||||||
libdrm,
|
libdrm,
|
||||||
libexecinfo,
|
libexecinfo,
|
||||||
libinput,
|
libinput,
|
||||||
libliftoff,
|
|
||||||
libselinux,
|
|
||||||
libsepol,
|
|
||||||
libthai,
|
|
||||||
libuuid,
|
|
||||||
libxkbcommon,
|
libxkbcommon,
|
||||||
|
libuuid,
|
||||||
mesa,
|
mesa,
|
||||||
pango,
|
pango,
|
||||||
pciutils,
|
pciutils,
|
||||||
pcre2,
|
|
||||||
python3,
|
|
||||||
seatd,
|
|
||||||
systemd,
|
systemd,
|
||||||
tomlplusplus,
|
tomlplusplus,
|
||||||
|
udis86-hyprland,
|
||||||
wayland,
|
wayland,
|
||||||
wayland-protocols,
|
wayland-protocols,
|
||||||
wayland-scanner,
|
wayland-scanner,
|
||||||
|
@ -50,25 +40,39 @@
|
||||||
wrapRuntimeDeps ? true,
|
wrapRuntimeDeps ? true,
|
||||||
version ? "git",
|
version ? "git",
|
||||||
commit,
|
commit,
|
||||||
|
revCount,
|
||||||
date,
|
date,
|
||||||
# deprecated flags
|
# deprecated flags
|
||||||
enableNvidiaPatches ? false,
|
enableNvidiaPatches ? false,
|
||||||
nvidiaPatches ? false,
|
nvidiaPatches ? false,
|
||||||
hidpiXWayland ? false,
|
hidpiXWayland ? false,
|
||||||
}:
|
}: let
|
||||||
assert lib.assertMsg (!nvidiaPatches) "The option `nvidiaPatches` has been removed.";
|
inherit (builtins) baseNameOf foldl';
|
||||||
assert lib.assertMsg (!enableNvidiaPatches) "The option `enableNvidiaPatches` has been removed.";
|
inherit (lib.asserts) assertMsg;
|
||||||
assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been removed. Please refer https://wiki.hyprland.org/Configuring/XWayland";
|
inherit (lib.attrsets) mapAttrsToList;
|
||||||
stdenv.mkDerivation {
|
inherit (lib.lists) flatten concatLists optional optionals;
|
||||||
pname = "hyprland${lib.optionalString debug "-debug"}";
|
inherit (lib.sources) cleanSourceWith cleanSource;
|
||||||
|
inherit (lib.strings) hasSuffix makeBinPath optionalString mesonBool mesonEnable;
|
||||||
|
|
||||||
|
adapters = flatten [
|
||||||
|
stdenvAdapters.useMoldLinker
|
||||||
|
];
|
||||||
|
|
||||||
|
customStdenv = foldl' (acc: adapter: adapter acc) stdenv adapters;
|
||||||
|
in
|
||||||
|
assert assertMsg (!nvidiaPatches) "The option `nvidiaPatches` has been removed.";
|
||||||
|
assert assertMsg (!enableNvidiaPatches) "The option `enableNvidiaPatches` has been removed.";
|
||||||
|
assert assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been removed. Please refer https://wiki.hyprland.org/Configuring/XWayland";
|
||||||
|
customStdenv.mkDerivation {
|
||||||
|
pname = "hyprland${optionalString debug "-debug"}";
|
||||||
inherit version;
|
inherit version;
|
||||||
|
|
||||||
src = lib.cleanSourceWith {
|
src = cleanSourceWith {
|
||||||
filter = name: type: let
|
filter = name: _type: let
|
||||||
baseName = baseNameOf (toString name);
|
baseName = baseNameOf (toString name);
|
||||||
in
|
in
|
||||||
! (lib.hasSuffix ".nix" baseName);
|
! (hasSuffix ".nix" baseName);
|
||||||
src = lib.cleanSource ../.;
|
src = cleanSource ../.;
|
||||||
};
|
};
|
||||||
|
|
||||||
postPatch = ''
|
postPatch = ''
|
||||||
|
@ -79,20 +83,21 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov
|
||||||
sed -i "s#@PREFIX@/##g" hyprland.pc.in
|
sed -i "s#@PREFIX@/##g" hyprland.pc.in
|
||||||
'';
|
'';
|
||||||
|
|
||||||
COMMITS = commit;
|
COMMITS = revCount;
|
||||||
DATE = date;
|
DATE = date;
|
||||||
DIRTY = lib.optionalString (commit == "") "dirty";
|
DIRTY = optionalString (commit == "") "dirty";
|
||||||
HASH = commit;
|
HASH = commit;
|
||||||
|
|
||||||
|
depsBuildBuild = [
|
||||||
|
pkg-config
|
||||||
|
];
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
hyprwayland-scanner
|
hyprwayland-scanner
|
||||||
jq
|
|
||||||
makeWrapper
|
makeWrapper
|
||||||
cmake
|
meson
|
||||||
ninja
|
ninja
|
||||||
pkg-config
|
pkg-config
|
||||||
python3 # for udis86
|
|
||||||
wayland-scanner
|
|
||||||
];
|
];
|
||||||
|
|
||||||
outputs = [
|
outputs = [
|
||||||
|
@ -101,69 +106,66 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov
|
||||||
"dev"
|
"dev"
|
||||||
];
|
];
|
||||||
|
|
||||||
buildInputs = lib.concatLists [
|
buildInputs = concatLists [
|
||||||
[
|
[
|
||||||
aquamarine
|
aquamarine
|
||||||
cairo
|
cairo
|
||||||
expat
|
|
||||||
fribidi
|
|
||||||
git
|
git
|
||||||
hwdata
|
|
||||||
hyprcursor
|
hyprcursor
|
||||||
|
hyprland-protocols
|
||||||
hyprlang
|
hyprlang
|
||||||
hyprutils
|
hyprutils
|
||||||
libdatrie
|
|
||||||
libdisplay-info
|
|
||||||
libdrm
|
libdrm
|
||||||
libGL
|
libGL
|
||||||
libinput
|
libinput
|
||||||
libliftoff
|
|
||||||
libselinux
|
|
||||||
libsepol
|
|
||||||
libthai
|
|
||||||
libuuid
|
libuuid
|
||||||
libxkbcommon
|
libxkbcommon
|
||||||
mesa
|
mesa
|
||||||
pango
|
pango
|
||||||
pciutils
|
pciutils
|
||||||
pcre2
|
|
||||||
seatd
|
|
||||||
tomlplusplus
|
tomlplusplus
|
||||||
|
udis86-hyprland
|
||||||
wayland
|
wayland
|
||||||
wayland-protocols
|
wayland-protocols
|
||||||
]
|
wayland-scanner
|
||||||
(lib.optionals stdenv.hostPlatform.isMusl [libexecinfo])
|
|
||||||
(lib.optionals enableXWayland [
|
|
||||||
xorg.libxcb
|
|
||||||
xorg.libXcursor
|
xorg.libXcursor
|
||||||
|
]
|
||||||
|
(optionals customStdenv.hostPlatform.isMusl [libexecinfo])
|
||||||
|
(optionals enableXWayland [
|
||||||
|
xorg.libxcb
|
||||||
xorg.libXdmcp
|
xorg.libXdmcp
|
||||||
xorg.xcbutil
|
|
||||||
xorg.xcbutilerrors
|
xorg.xcbutilerrors
|
||||||
xorg.xcbutilrenderutil
|
xorg.xcbutilrenderutil
|
||||||
xorg.xcbutilwm
|
xorg.xcbutilwm
|
||||||
xwayland
|
xwayland
|
||||||
])
|
])
|
||||||
(lib.optionals withSystemd [systemd])
|
(optional withSystemd systemd)
|
||||||
];
|
];
|
||||||
|
|
||||||
cmakeBuildType =
|
mesonBuildType =
|
||||||
if debug
|
if debug
|
||||||
then "Debug"
|
then "debugoptimized"
|
||||||
else "RelWithDebInfo";
|
else "release";
|
||||||
|
|
||||||
# we want as much debug info as possible
|
# we want as much debug info as possible
|
||||||
dontStrip = debug;
|
dontStrip = debug;
|
||||||
|
|
||||||
cmakeFlags = [
|
mesonFlags = flatten [
|
||||||
(lib.cmakeBool "NO_XWAYLAND" (!enableXWayland))
|
(mapAttrsToList mesonEnable {
|
||||||
(lib.cmakeBool "LEGACY_RENDERER" legacyRenderer)
|
"xwayland" = enableXWayland;
|
||||||
(lib.cmakeBool "NO_SYSTEMD" (!withSystemd))
|
"legacy_renderer" = legacyRenderer;
|
||||||
|
"systemd" = withSystemd;
|
||||||
|
})
|
||||||
|
(mapAttrsToList mesonBool {
|
||||||
|
"b_pch" = false;
|
||||||
|
"tracy_enable" = false;
|
||||||
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
${lib.optionalString wrapRuntimeDeps ''
|
${optionalString wrapRuntimeDeps ''
|
||||||
wrapProgram $out/bin/Hyprland \
|
wrapProgram $out/bin/Hyprland \
|
||||||
--suffix PATH : ${lib.makeBinPath [
|
--suffix PATH : ${makeBinPath [
|
||||||
binutils
|
binutils
|
||||||
pciutils
|
pciutils
|
||||||
pkgconf
|
pkgconf
|
||||||
|
|
64
nix/formatter.nix
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
{
|
||||||
|
writeShellApplication,
|
||||||
|
deadnix,
|
||||||
|
statix,
|
||||||
|
alejandra,
|
||||||
|
llvmPackages_19,
|
||||||
|
fd,
|
||||||
|
}:
|
||||||
|
writeShellApplication {
|
||||||
|
name = "hyprland-treewide-formatter";
|
||||||
|
runtimeInputs = [
|
||||||
|
deadnix
|
||||||
|
statix
|
||||||
|
alejandra
|
||||||
|
llvmPackages_19.clang-tools
|
||||||
|
fd
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
# shellcheck disable=SC2148
|
||||||
|
|
||||||
|
# common excludes
|
||||||
|
excludes="subprojects"
|
||||||
|
|
||||||
|
nix_format() {
|
||||||
|
if [ "$*" = 0 ]; then
|
||||||
|
fd '.*\.nix' . -E "$excludes" -x statix fix -- {} \;
|
||||||
|
fd '.*\.nix' . -E "$excludes" -X deadnix -e -- {} \; -X alejandra {} \;
|
||||||
|
elif [ -d "$1" ]; then
|
||||||
|
fd '.*\.nix' "$1" -E "$excludes" -i -x statix fix -- {} \;
|
||||||
|
fd '.*\.nix' "$1" -E "$excludes" -i -X deadnix -e -- {} \; -X alejandra {} \;
|
||||||
|
else
|
||||||
|
statix fix -- "$1"
|
||||||
|
deadnix -e "$1"
|
||||||
|
alejandra "$1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cpp_format() {
|
||||||
|
if [ "$*" = 0 ] || [ "$1" = "." ]; then
|
||||||
|
fd '.*\.cpp' . -E "$excludes" | xargs clang-format --verbose -i
|
||||||
|
elif [ -d "$1" ]; then
|
||||||
|
fd '.*\.cpp' "$1" -E "$excludes" | xargs clang-format --verbose -i
|
||||||
|
else
|
||||||
|
clang-format --verbose -i "$1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in "$@"; do
|
||||||
|
case ''${i##*.} in
|
||||||
|
"nix")
|
||||||
|
nix_format "$i"
|
||||||
|
;;
|
||||||
|
"cpp")
|
||||||
|
cpp_format "$i"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
nix_format "$i"
|
||||||
|
cpp_format "$i"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
}
|
|
@ -22,18 +22,21 @@ in {
|
||||||
# Dependencies
|
# Dependencies
|
||||||
inputs.aquamarine.overlays.default
|
inputs.aquamarine.overlays.default
|
||||||
inputs.hyprcursor.overlays.default
|
inputs.hyprcursor.overlays.default
|
||||||
|
inputs.hyprland-protocols.overlays.default
|
||||||
inputs.hyprlang.overlays.default
|
inputs.hyprlang.overlays.default
|
||||||
inputs.hyprutils.overlays.default
|
inputs.hyprutils.overlays.default
|
||||||
inputs.hyprwayland-scanner.overlays.default
|
inputs.hyprwayland-scanner.overlays.default
|
||||||
|
self.overlays.udis86
|
||||||
|
|
||||||
# Hyprland packages themselves
|
# Hyprland packages themselves
|
||||||
(final: prev: let
|
(final: _prev: let
|
||||||
date = mkDate (self.lastModifiedDate or "19700101");
|
date = mkDate (self.lastModifiedDate or "19700101");
|
||||||
in {
|
in {
|
||||||
hyprland = final.callPackage ./default.nix {
|
hyprland = final.callPackage ./default.nix {
|
||||||
stdenv = final.gcc13Stdenv;
|
stdenv = final.gcc14Stdenv;
|
||||||
version = "${version}+date=${date}_${self.shortRev or "dirty"}";
|
version = "${version}+date=${date}_${self.shortRev or "dirty"}";
|
||||||
commit = self.rev or "";
|
commit = self.rev or "";
|
||||||
|
revCount = self.sourceInfo.revCount or "";
|
||||||
inherit date;
|
inherit date;
|
||||||
};
|
};
|
||||||
hyprland-unwrapped = final.hyprland.override {wrapRuntimeDeps = false;};
|
hyprland-unwrapped = final.hyprland.override {wrapRuntimeDeps = false;};
|
||||||
|
@ -62,4 +65,20 @@ in {
|
||||||
hyprland-extras = lib.composeManyExtensions [
|
hyprland-extras = lib.composeManyExtensions [
|
||||||
inputs.xdph.overlays.xdg-desktop-portal-hyprland
|
inputs.xdph.overlays.xdg-desktop-portal-hyprland
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# udis86 from nixpkgs is too old, and also does not provide a .pc file
|
||||||
|
# this version is the one used in the git submodule, and allows us to
|
||||||
|
# fetch the source without '?submodules=1'
|
||||||
|
udis86 = final: prev: {
|
||||||
|
udis86-hyprland = prev.udis86.overrideAttrs (_self: _super: {
|
||||||
|
src = final.fetchFromGitHub {
|
||||||
|
owner = "canihavesomecoffee";
|
||||||
|
repo = "udis86";
|
||||||
|
rev = "5336633af70f3917760a6d441ff02d93477b0c86";
|
||||||
|
hash = "sha256-HifdUQPGsKQKQprByeIznvRLONdOXeolOsU5nkwIv3g=";
|
||||||
|
};
|
||||||
|
|
||||||
|
patches = [];
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,76 +1,78 @@
|
||||||
wayland_protos = dependency('wayland-protocols',
|
wayland_protos = dependency(
|
||||||
|
'wayland-protocols',
|
||||||
version: '>=1.32',
|
version: '>=1.32',
|
||||||
fallback: 'wayland-protocols',
|
fallback: 'wayland-protocols',
|
||||||
default_options: ['tests=false'],
|
default_options: ['tests=false'],
|
||||||
)
|
)
|
||||||
|
|
||||||
hyprland_protos = dependency('hyprland-protocols',
|
hyprland_protos = dependency(
|
||||||
version: '>=0.2',
|
'hyprland-protocols',
|
||||||
|
version: '>=0.4',
|
||||||
fallback: 'hyprland-protocols',
|
fallback: 'hyprland-protocols',
|
||||||
)
|
)
|
||||||
|
|
||||||
wl_protocol_dir = wayland_protos.get_variable('pkgdatadir')
|
wayland_protocol_dir = wayland_protos.get_variable('pkgdatadir')
|
||||||
hl_protocol_dir = hyprland_protos.get_variable('pkgdatadir')
|
hyprland_protocol_dir = hyprland_protos.get_variable('pkgdatadir')
|
||||||
|
|
||||||
hyprwayland_scanner_dep = dependency('hyprwayland-scanner', version: '>=0.3.8', native: true)
|
hyprwayland_scanner_dep = dependency('hyprwayland-scanner', version: '>=0.3.10', native: true)
|
||||||
hyprwayland_scanner = find_program(
|
hyprwayland_scanner = find_program(
|
||||||
hyprwayland_scanner_dep.get_variable('hyprwayland_scanner'),
|
hyprwayland_scanner_dep.get_variable('hyprwayland_scanner'),
|
||||||
native: true,
|
native: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
new_protocols = [
|
protocols = [
|
||||||
['wlr-gamma-control-unstable-v1.xml'],
|
'wlr-gamma-control-unstable-v1.xml',
|
||||||
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
'wlr-foreign-toplevel-management-unstable-v1.xml',
|
||||||
['wlr-output-power-management-unstable-v1.xml'],
|
'wlr-output-power-management-unstable-v1.xml',
|
||||||
['input-method-unstable-v2.xml'],
|
'input-method-unstable-v2.xml',
|
||||||
['virtual-keyboard-unstable-v1.xml'],
|
'virtual-keyboard-unstable-v1.xml',
|
||||||
['wlr-virtual-pointer-unstable-v1.xml'],
|
'wlr-virtual-pointer-unstable-v1.xml',
|
||||||
['wlr-output-management-unstable-v1.xml'],
|
'wlr-output-management-unstable-v1.xml',
|
||||||
['kde-server-decoration.xml'],
|
'kde-server-decoration.xml',
|
||||||
['wlr-layer-shell-unstable-v1.xml'],
|
'wlr-layer-shell-unstable-v1.xml',
|
||||||
['wayland-drm.xml'],
|
'wayland-drm.xml',
|
||||||
['wlr-data-control-unstable-v1.xml'],
|
'wlr-data-control-unstable-v1.xml',
|
||||||
['wlr-screencopy-unstable-v1.xml'],
|
'wlr-screencopy-unstable-v1.xml',
|
||||||
[hl_protocol_dir, 'protocols/hyprland-global-shortcuts-v1.xml'],
|
hyprland_protocol_dir / 'protocols/hyprland-global-shortcuts-v1.xml',
|
||||||
[hl_protocol_dir, 'protocols/hyprland-toplevel-export-v1.xml'],
|
hyprland_protocol_dir / 'protocols/hyprland-toplevel-export-v1.xml',
|
||||||
[hl_protocol_dir, 'protocols/hyprland-focus-grab-v1.xml'],
|
hyprland_protocol_dir / 'protocols/hyprland-focus-grab-v1.xml',
|
||||||
[wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'],
|
hyprland_protocol_dir / 'protocols/hyprland-ctm-control-v1.xml',
|
||||||
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'],
|
wayland_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml',
|
||||||
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
wayland_protocol_dir / 'staging/fractional-scale/fractional-scale-v1.xml',
|
||||||
[wl_protocol_dir, 'staging/cursor-shape/cursor-shape-v1.xml'],
|
wayland_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'],
|
wayland_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
|
||||||
[wl_protocol_dir, 'unstable/relative-pointer/relative-pointer-unstable-v1.xml'],
|
wayland_protocol_dir / 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml'],
|
wayland_protocol_dir / 'unstable/relative-pointer/relative-pointer-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'staging/alpha-modifier/alpha-modifier-v1.xml'],
|
wayland_protocol_dir / 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml'],
|
wayland_protocol_dir / 'staging/alpha-modifier/alpha-modifier-v1.xml',
|
||||||
[wl_protocol_dir, 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml'],
|
wayland_protocol_dir / 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml',
|
||||||
[wl_protocol_dir, 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml'],
|
wayland_protocol_dir / 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v3.xml'],
|
wayland_protocol_dir / 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'],
|
wayland_protocol_dir / 'unstable/text-input/text-input-unstable-v3.xml',
|
||||||
[wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'],
|
wayland_protocol_dir / 'unstable/text-input/text-input-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'staging/xdg-activation/xdg-activation-v1.xml'],
|
wayland_protocol_dir / 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'staging/ext-idle-notify/ext-idle-notify-v1.xml'],
|
wayland_protocol_dir / 'staging/xdg-activation/xdg-activation-v1.xml',
|
||||||
[wl_protocol_dir, 'staging/ext-session-lock/ext-session-lock-v1.xml'],
|
wayland_protocol_dir / 'staging/ext-idle-notify/ext-idle-notify-v1.xml',
|
||||||
[wl_protocol_dir, 'stable/tablet/tablet-v2.xml'],
|
wayland_protocol_dir / 'staging/ext-session-lock/ext-session-lock-v1.xml',
|
||||||
[wl_protocol_dir, 'stable/presentation-time/presentation-time.xml'],
|
wayland_protocol_dir / 'stable/tablet/tablet-v2.xml',
|
||||||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
wayland_protocol_dir / 'stable/presentation-time/presentation-time.xml',
|
||||||
[wl_protocol_dir, 'unstable/primary-selection/primary-selection-unstable-v1.xml'],
|
wayland_protocol_dir / 'stable/xdg-shell/xdg-shell.xml',
|
||||||
[wl_protocol_dir, 'staging/xwayland-shell/xwayland-shell-v1.xml'],
|
wayland_protocol_dir / 'unstable/primary-selection/primary-selection-unstable-v1.xml',
|
||||||
[wl_protocol_dir, 'stable/viewporter/viewporter.xml'],
|
wayland_protocol_dir / 'staging/xwayland-shell/xwayland-shell-v1.xml',
|
||||||
[wl_protocol_dir, 'stable/linux-dmabuf/linux-dmabuf-v1.xml'],
|
wayland_protocol_dir / 'stable/viewporter/viewporter.xml',
|
||||||
[wl_protocol_dir, 'staging/drm-lease/drm-lease-v1.xml'],
|
wayland_protocol_dir / 'stable/linux-dmabuf/linux-dmabuf-v1.xml',
|
||||||
[wl_protocol_dir, 'staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml'],
|
wayland_protocol_dir / 'staging/drm-lease/drm-lease-v1.xml',
|
||||||
|
wayland_protocol_dir / 'staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml',
|
||||||
|
wayland_protocol_dir / 'staging/xdg-dialog/xdg-dialog-v1.xml',
|
||||||
|
wayland_protocol_dir / 'staging/single-pixel-buffer/single-pixel-buffer-v1.xml',
|
||||||
|
wayland_protocol_dir / 'staging/security-context/security-context-v1.xml',
|
||||||
]
|
]
|
||||||
|
|
||||||
wl_protos_src = []
|
wl_protocols = []
|
||||||
wl_protos_headers = []
|
foreach protocol : protocols
|
||||||
|
wl_protocols += custom_target(
|
||||||
new_wl_protos = []
|
protocol.underscorify(),
|
||||||
foreach p : new_protocols
|
input: protocol,
|
||||||
xml = join_paths(p)
|
|
||||||
new_wl_protos += custom_target(
|
|
||||||
xml.underscorify(),
|
|
||||||
input: xml,
|
|
||||||
install: true,
|
install: true,
|
||||||
install_dir: [false, join_paths(get_option('includedir'), 'hyprland/protocols')],
|
install_dir: [false, join_paths(get_option('includedir'), 'hyprland/protocols')],
|
||||||
output: ['@BASENAME@.cpp', '@BASENAME@.hpp'],
|
output: ['@BASENAME@.cpp', '@BASENAME@.hpp'],
|
||||||
|
@ -78,31 +80,26 @@ foreach p : new_protocols
|
||||||
)
|
)
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
wayland_server_dep = dependency('wayland-server', version: '>=1.20.0')
|
# wayland.xml generation
|
||||||
wayland_server_dir = wayland_server_dep.get_variable('pkgdatadir')
|
wayland_scanner = dependency('wayland-scanner')
|
||||||
|
wayland_scanner_datadir = wayland_scanner.get_variable('pkgdatadir')
|
||||||
|
|
||||||
wl_server_protos = [
|
wayland_xml = wayland_scanner_datadir / 'wayland.xml'
|
||||||
wayland_server_dir / 'wayland.xml'
|
wayland_protocol = custom_target(
|
||||||
]
|
wayland_xml.underscorify(),
|
||||||
wl_server_protos_gen = []
|
input: wayland_xml,
|
||||||
foreach p : wl_server_protos
|
|
||||||
wl_server_protos_gen += custom_target(
|
|
||||||
p.underscorify(),
|
|
||||||
input: p,
|
|
||||||
install: true,
|
install: true,
|
||||||
install_dir: [false, join_paths(get_option('includedir'), 'hyprland/protocols')],
|
install_dir: [false, join_paths(get_option('includedir'), 'hyprland/protocols')],
|
||||||
output: ['@BASENAME@.cpp', '@BASENAME@.hpp'],
|
output: ['@BASENAME@.cpp', '@BASENAME@.hpp'],
|
||||||
command: [hyprwayland_scanner, '--wayland-enums', '@INPUT@', '@OUTDIR@'],
|
command: [hyprwayland_scanner, '--wayland-enums', '@INPUT@', '@OUTDIR@'],
|
||||||
)
|
)
|
||||||
endforeach
|
|
||||||
|
|
||||||
lib_server_protos = static_library(
|
lib_server_protos = static_library(
|
||||||
'server_protos',
|
'server_protos',
|
||||||
wl_protos_src + wl_protos_headers + new_wl_protos + wl_server_protos_gen,
|
wl_protocols + wayland_protocol,
|
||||||
dependencies: wayland_server_dep.partial_dependency(compile_args: true),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
server_protos = declare_dependency(
|
server_protos = declare_dependency(
|
||||||
link_with: lib_server_protos,
|
link_with: lib_server_protos,
|
||||||
sources: wl_protos_headers + new_wl_protos,
|
sources: wl_protocols + wayland_protocol,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||||
index f54cdf5d..ad7c3e73 100755
|
index f26a5c3c..3dfef333 100644
|
||||||
--- a/CMakeLists.txt
|
--- a/CMakeLists.txt
|
||||||
+++ b/CMakeLists.txt
|
+++ b/CMakeLists.txt
|
||||||
@@ -130,6 +130,8 @@ if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
@@ -143,6 +143,8 @@ if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||||
message(STATUS "Enabling ASan")
|
message(STATUS "Enabling ASan")
|
||||||
|
|
||||||
target_link_libraries(Hyprland asan)
|
target_link_libraries(Hyprland asan)
|
||||||
|
|
|
@ -67,7 +67,7 @@ class CCompositor {
|
||||||
std::vector<PHLWINDOWREF> m_vWindowsFadingOut;
|
std::vector<PHLWINDOWREF> m_vWindowsFadingOut;
|
||||||
std::vector<PHLLSREF> m_vSurfacesFadingOut;
|
std::vector<PHLLSREF> m_vSurfacesFadingOut;
|
||||||
|
|
||||||
std::unordered_map<std::string, uint64_t> m_mMonitorIDMap;
|
std::unordered_map<std::string, MONITORID> m_mMonitorIDMap;
|
||||||
|
|
||||||
void initServer(std::string socketName, int socketFd);
|
void initServer(std::string socketName, int socketFd);
|
||||||
void startCompositor();
|
void startCompositor();
|
||||||
|
@ -91,10 +91,13 @@ class CCompositor {
|
||||||
bool m_bNextIsUnsafe = false;
|
bool m_bNextIsUnsafe = false;
|
||||||
CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state
|
CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state
|
||||||
bool m_bIsShuttingDown = false;
|
bool m_bIsShuttingDown = false;
|
||||||
|
bool m_bFinalRequests = false;
|
||||||
|
bool m_bDesktopEnvSet = false;
|
||||||
|
bool m_bEnableXwayland = true;
|
||||||
|
|
||||||
// ------------------------------------------------- //
|
// ------------------------------------------------- //
|
||||||
|
|
||||||
CMonitor* getMonitorFromID(const int&);
|
CMonitor* getMonitorFromID(const MONITORID&);
|
||||||
CMonitor* getMonitorFromName(const std::string&);
|
CMonitor* getMonitorFromName(const std::string&);
|
||||||
CMonitor* getMonitorFromDesc(const std::string&);
|
CMonitor* getMonitorFromDesc(const std::string&);
|
||||||
CMonitor* getMonitorFromCursor();
|
CMonitor* getMonitorFromCursor();
|
||||||
|
@ -114,38 +117,38 @@ class CCompositor {
|
||||||
PHLWINDOW getWindowFromHandle(uint32_t);
|
PHLWINDOW getWindowFromHandle(uint32_t);
|
||||||
bool isWorkspaceVisible(PHLWORKSPACE);
|
bool isWorkspaceVisible(PHLWORKSPACE);
|
||||||
bool isWorkspaceVisibleNotCovered(PHLWORKSPACE);
|
bool isWorkspaceVisibleNotCovered(PHLWORKSPACE);
|
||||||
PHLWORKSPACE getWorkspaceByID(const int&);
|
PHLWORKSPACE getWorkspaceByID(const WORKSPACEID&);
|
||||||
PHLWORKSPACE getWorkspaceByName(const std::string&);
|
PHLWORKSPACE getWorkspaceByName(const std::string&);
|
||||||
PHLWORKSPACE getWorkspaceByString(const std::string&);
|
PHLWORKSPACE getWorkspaceByString(const std::string&);
|
||||||
void sanityCheckWorkspaces();
|
void sanityCheckWorkspaces();
|
||||||
void updateWorkspaceWindowDecos(const int&);
|
void updateWorkspaceWindowDecos(const WORKSPACEID&);
|
||||||
void updateWorkspaceWindowData(const int&);
|
void updateWorkspaceWindowData(const WORKSPACEID&);
|
||||||
int getWindowsOnWorkspace(const int& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
|
int getWindowsOnWorkspace(const WORKSPACEID& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
|
||||||
int getGroupsOnWorkspace(const int& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
|
int getGroupsOnWorkspace(const WORKSPACEID& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
|
||||||
PHLWINDOW getUrgentWindow();
|
PHLWINDOW getUrgentWindow();
|
||||||
bool hasUrgentWindowOnWorkspace(const int&);
|
bool hasUrgentWindowOnWorkspace(const WORKSPACEID&);
|
||||||
PHLWINDOW getFirstWindowOnWorkspace(const int&);
|
PHLWINDOW getFirstWindowOnWorkspace(const WORKSPACEID&);
|
||||||
PHLWINDOW getTopLeftWindowOnWorkspace(const int&);
|
PHLWINDOW getTopLeftWindowOnWorkspace(const WORKSPACEID&);
|
||||||
PHLWINDOW getFullscreenWindowOnWorkspace(const int&);
|
PHLWINDOW getFullscreenWindowOnWorkspace(const WORKSPACEID&);
|
||||||
bool isWindowActive(PHLWINDOW);
|
bool isWindowActive(PHLWINDOW);
|
||||||
void changeWindowZOrder(PHLWINDOW, bool);
|
void changeWindowZOrder(PHLWINDOW, bool);
|
||||||
void cleanupFadingOut(const int& monid);
|
void cleanupFadingOut(const MONITORID& monid);
|
||||||
PHLWINDOW getWindowInDirection(PHLWINDOW, char);
|
PHLWINDOW getWindowInDirection(PHLWINDOW, char);
|
||||||
PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
|
PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
|
||||||
PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
|
PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
|
||||||
int getNextAvailableNamedWorkspace();
|
WORKSPACEID getNextAvailableNamedWorkspace();
|
||||||
bool isPointOnAnyMonitor(const Vector2D&);
|
bool isPointOnAnyMonitor(const Vector2D&);
|
||||||
bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);
|
bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);
|
||||||
CMonitor* getMonitorInDirection(const char&);
|
CMonitor* getMonitorInDirection(const char&);
|
||||||
CMonitor* getMonitorInDirection(CMonitor*, const char&);
|
CMonitor* getMonitorInDirection(CMonitor*, const char&);
|
||||||
void updateAllWindowsAnimatedDecorationValues();
|
void updateAllWindowsAnimatedDecorationValues();
|
||||||
void updateWorkspaceWindows(const int64_t& id);
|
void updateWorkspaceWindows(const WORKSPACEID& id);
|
||||||
void updateWindowAnimatedDecorationValues(PHLWINDOW);
|
void updateWindowAnimatedDecorationValues(PHLWINDOW);
|
||||||
int getNextAvailableMonitorID(std::string const& name);
|
MONITORID getNextAvailableMonitorID(std::string const& name);
|
||||||
void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false);
|
void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false);
|
||||||
void swapActiveWorkspaces(CMonitor*, CMonitor*);
|
void swapActiveWorkspaces(CMonitor*, CMonitor*);
|
||||||
CMonitor* getMonitorFromString(const std::string&);
|
CMonitor* getMonitorFromString(const std::string&);
|
||||||
bool workspaceIDOutOfBounds(const int64_t&);
|
bool workspaceIDOutOfBounds(const WORKSPACEID&);
|
||||||
void setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
void setWindowFullscreenInternal(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
||||||
void setWindowFullscreenClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
void setWindowFullscreenClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
||||||
void setWindowFullscreenState(const PHLWINDOW PWINDOW, const sFullscreenState state);
|
void setWindowFullscreenState(const PHLWINDOW PWINDOW, const sFullscreenState state);
|
||||||
|
@ -162,12 +165,13 @@ class CCompositor {
|
||||||
PHLLS getLayerSurfaceFromSurface(SP<CWLSurfaceResource>);
|
PHLLS getLayerSurfaceFromSurface(SP<CWLSurfaceResource>);
|
||||||
void closeWindow(PHLWINDOW);
|
void closeWindow(PHLWINDOW);
|
||||||
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
|
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
|
||||||
void forceReportSizesToWindowsOnWorkspace(const int&);
|
void forceReportSizesToWindowsOnWorkspace(const WORKSPACEID&);
|
||||||
PHLWORKSPACE createNewWorkspace(const int&, const int&, const std::string& name = "", bool isEmtpy = true); // will be deleted next frame if left empty and unfocused!
|
PHLWORKSPACE createNewWorkspace(const WORKSPACEID&, const MONITORID&, const std::string& name = "",
|
||||||
void renameWorkspace(const int&, const std::string& name = "");
|
bool isEmpty = true); // will be deleted next frame if left empty and unfocused!
|
||||||
|
void renameWorkspace(const WORKSPACEID&, const std::string& name = "");
|
||||||
void setActiveMonitor(CMonitor*);
|
void setActiveMonitor(CMonitor*);
|
||||||
bool isWorkspaceSpecial(const int&);
|
bool isWorkspaceSpecial(const WORKSPACEID&);
|
||||||
int getNewSpecialID();
|
WORKSPACEID getNewSpecialID();
|
||||||
void performUserChecks();
|
void performUserChecks();
|
||||||
void moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWorkspace);
|
void moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWorkspace);
|
||||||
PHLWINDOW getForceFocus();
|
PHLWINDOW getForceFocus();
|
||||||
|
|
|
@ -52,4 +52,8 @@ struct SHyprCtlCommand {
|
||||||
std::function<std::string(eHyprCtlOutputFormat, std::string)> fn;
|
std::function<std::string(eHyprCtlOutputFormat, std::string)> fn;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef int64_t WINDOWID;
|
||||||
|
typedef int64_t MONITORID;
|
||||||
|
typedef int64_t WORKSPACEID;
|
||||||
|
|
||||||
typedef std::function<void(void*, SCallbackInfo&, std::any)> HOOK_CALLBACK_FN;
|
typedef std::function<void(void*, SCallbackInfo&, std::any)> HOOK_CALLBACK_FN;
|
||||||
|
|
1541
src/config/ConfigDescriptions.hpp
Normal file
|
@ -3,8 +3,11 @@
|
||||||
|
|
||||||
#include "../render/decorations/CHyprGroupBarDecoration.hpp"
|
#include "../render/decorations/CHyprGroupBarDecoration.hpp"
|
||||||
#include "config/ConfigDataValues.hpp"
|
#include "config/ConfigDataValues.hpp"
|
||||||
|
#include "config/ConfigValue.hpp"
|
||||||
#include "helpers/varlist/VarList.hpp"
|
#include "helpers/varlist/VarList.hpp"
|
||||||
#include "../protocols/LayerShell.hpp"
|
#include "../protocols/LayerShell.hpp"
|
||||||
|
#include "../xwayland/XWayland.hpp"
|
||||||
|
#include "../protocols/OutputManagement.hpp"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -29,6 +32,8 @@ using namespace Hyprutils::String;
|
||||||
|
|
||||||
extern "C" char** environ;
|
extern "C" char** environ;
|
||||||
|
|
||||||
|
#include "ConfigDescriptions.hpp"
|
||||||
|
|
||||||
static Hyprlang::CParseResult configHandleGradientSet(const char* VALUE, void** data) {
|
static Hyprlang::CParseResult configHandleGradientSet(const char* VALUE, void** data) {
|
||||||
std::string V = VALUE;
|
std::string V = VALUE;
|
||||||
|
|
||||||
|
@ -42,7 +47,7 @@ static Hyprlang::CParseResult configHandleGradientSet(const char* VALUE, void**
|
||||||
|
|
||||||
std::string parseError = "";
|
std::string parseError = "";
|
||||||
|
|
||||||
for (auto& var : varlist) {
|
for (auto const& var : varlist) {
|
||||||
if (var.find("deg") != std::string::npos) {
|
if (var.find("deg") != std::string::npos) {
|
||||||
// last arg
|
// last arg
|
||||||
try {
|
try {
|
||||||
|
@ -137,6 +142,18 @@ static Hyprlang::CParseResult handleExecOnce(const char* c, const char* v) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Hyprlang::CParseResult handleExecShutdown(const char* c, const char* v) {
|
||||||
|
const std::string VALUE = v;
|
||||||
|
const std::string COMMAND = c;
|
||||||
|
|
||||||
|
const auto RESULT = g_pConfigManager->handleExecShutdown(COMMAND, VALUE);
|
||||||
|
|
||||||
|
Hyprlang::CParseResult result;
|
||||||
|
if (RESULT.has_value())
|
||||||
|
result.setError(RESULT.value().c_str());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static Hyprlang::CParseResult handleMonitor(const char* c, const char* v) {
|
static Hyprlang::CParseResult handleMonitor(const char* c, const char* v) {
|
||||||
const std::string VALUE = v;
|
const std::string VALUE = v;
|
||||||
const std::string COMMAND = c;
|
const std::string COMMAND = c;
|
||||||
|
@ -311,8 +328,6 @@ CConfigManager::CConfigManager() {
|
||||||
configPaths.emplace_back(getMainConfigPath());
|
configPaths.emplace_back(getMainConfigPath());
|
||||||
m_pConfig = std::make_unique<Hyprlang::CConfig>(configPaths.begin()->c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true});
|
m_pConfig = std::make_unique<Hyprlang::CConfig>(configPaths.begin()->c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true});
|
||||||
|
|
||||||
m_pConfig->addConfigValue("general:sensitivity", {1.0f});
|
|
||||||
m_pConfig->addConfigValue("general:apply_sens_to_raw", Hyprlang::INT{0});
|
|
||||||
m_pConfig->addConfigValue("general:border_size", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("general:border_size", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("general:no_border_on_floating", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("general:no_border_on_floating", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("general:border_part_of_window", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("general:border_part_of_window", Hyprlang::INT{1});
|
||||||
|
@ -346,7 +361,6 @@ CConfigManager::CConfigManager() {
|
||||||
m_pConfig->addConfigValue("misc:swallow_regex", {STRVAL_EMPTY});
|
m_pConfig->addConfigValue("misc:swallow_regex", {STRVAL_EMPTY});
|
||||||
m_pConfig->addConfigValue("misc:swallow_exception_regex", {STRVAL_EMPTY});
|
m_pConfig->addConfigValue("misc:swallow_exception_regex", {STRVAL_EMPTY});
|
||||||
m_pConfig->addConfigValue("misc:focus_on_activate", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("misc:focus_on_activate", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("misc:no_direct_scanout", Hyprlang::INT{1});
|
|
||||||
m_pConfig->addConfigValue("misc:mouse_move_focuses_monitor", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("misc:mouse_move_focuses_monitor", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("misc:render_ahead_of_time", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("misc:render_ahead_of_time", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("misc:render_ahead_safezone", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("misc:render_ahead_safezone", Hyprlang::INT{1});
|
||||||
|
@ -357,9 +371,15 @@ CConfigManager::CConfigManager() {
|
||||||
m_pConfig->addConfigValue("misc:exit_window_retains_fullscreen", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("misc:exit_window_retains_fullscreen", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("misc:initial_workspace_tracking", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("misc:initial_workspace_tracking", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("misc:middle_click_paste", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("misc:middle_click_paste", Hyprlang::INT{1});
|
||||||
|
m_pConfig->addConfigValue("misc:render_unfocused_fps", Hyprlang::INT{15});
|
||||||
|
m_pConfig->addConfigValue("misc:disable_xdg_env_checks", Hyprlang::INT{0});
|
||||||
|
|
||||||
m_pConfig->addConfigValue("group:insert_after_current", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("group:insert_after_current", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("group:focus_removed_window", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("group:focus_removed_window", Hyprlang::INT{1});
|
||||||
|
m_pConfig->addConfigValue("group:merge_groups_on_drag", Hyprlang::INT{1});
|
||||||
|
m_pConfig->addConfigValue("group:merge_floated_into_tiled_on_groupbar", Hyprlang::INT{0});
|
||||||
|
m_pConfig->addConfigValue("group:auto_group", Hyprlang::INT{1});
|
||||||
|
m_pConfig->addConfigValue("group:drag_into_group", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("group:groupbar:enabled", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("group:groupbar:enabled", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("group:groupbar:font_family", {STRVAL_EMPTY});
|
m_pConfig->addConfigValue("group:groupbar:font_family", {STRVAL_EMPTY});
|
||||||
m_pConfig->addConfigValue("group:groupbar:font_size", Hyprlang::INT{8});
|
m_pConfig->addConfigValue("group:groupbar:font_size", Hyprlang::INT{8});
|
||||||
|
@ -426,9 +446,9 @@ CConfigManager::CConfigManager() {
|
||||||
m_pConfig->addConfigValue("dwindle:preserve_split", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("dwindle:preserve_split", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("dwindle:special_scale_factor", {1.f});
|
m_pConfig->addConfigValue("dwindle:special_scale_factor", {1.f});
|
||||||
m_pConfig->addConfigValue("dwindle:split_width_multiplier", {1.0f});
|
m_pConfig->addConfigValue("dwindle:split_width_multiplier", {1.0f});
|
||||||
m_pConfig->addConfigValue("dwindle:no_gaps_when_only", Hyprlang::INT{0});
|
|
||||||
m_pConfig->addConfigValue("dwindle:use_active_for_splits", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("dwindle:use_active_for_splits", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("dwindle:default_split_ratio", {1.f});
|
m_pConfig->addConfigValue("dwindle:default_split_ratio", {1.f});
|
||||||
|
m_pConfig->addConfigValue("dwindle:split_bias", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("dwindle:smart_split", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("dwindle:smart_split", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("dwindle:smart_resizing", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("dwindle:smart_resizing", Hyprlang::INT{1});
|
||||||
|
|
||||||
|
@ -438,7 +458,6 @@ CConfigManager::CConfigManager() {
|
||||||
m_pConfig->addConfigValue("master:always_center_master", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("master:always_center_master", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("master:new_on_active", {"none"});
|
m_pConfig->addConfigValue("master:new_on_active", {"none"});
|
||||||
m_pConfig->addConfigValue("master:new_on_top", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("master:new_on_top", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("master:no_gaps_when_only", Hyprlang::INT{0});
|
|
||||||
m_pConfig->addConfigValue("master:orientation", {"left"});
|
m_pConfig->addConfigValue("master:orientation", {"left"});
|
||||||
m_pConfig->addConfigValue("master:inherit_fullscreen", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("master:inherit_fullscreen", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("master:allow_small_split", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("master:allow_small_split", Hyprlang::INT{0});
|
||||||
|
@ -449,6 +468,7 @@ CConfigManager::CConfigManager() {
|
||||||
m_pConfig->addConfigValue("animations:first_launch_animation", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("animations:first_launch_animation", Hyprlang::INT{1});
|
||||||
|
|
||||||
m_pConfig->addConfigValue("input:follow_mouse", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("input:follow_mouse", Hyprlang::INT{1});
|
||||||
|
m_pConfig->addConfigValue("input:focus_on_close", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("input:mouse_refocus", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("input:mouse_refocus", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("input:special_fallthrough", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("input:special_fallthrough", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("input:off_window_axis_events", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("input:off_window_axis_events", Hyprlang::INT{1});
|
||||||
|
@ -521,6 +541,7 @@ CConfigManager::CConfigManager() {
|
||||||
m_pConfig->addConfigValue("gestures:workspace_swipe_touch", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("gestures:workspace_swipe_touch", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("gestures:workspace_swipe_touch_invert", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("gestures:workspace_swipe_touch_invert", Hyprlang::INT{0});
|
||||||
|
|
||||||
|
m_pConfig->addConfigValue("xwayland:enabled", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("xwayland:use_nearest_neighbor", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("xwayland:use_nearest_neighbor", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("xwayland:force_zero_scaling", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("xwayland:force_zero_scaling", Hyprlang::INT{0});
|
||||||
|
|
||||||
|
@ -531,7 +552,7 @@ CConfigManager::CConfigManager() {
|
||||||
m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("cursor:min_refresh_rate", Hyprlang::INT{24});
|
m_pConfig->addConfigValue("cursor:min_refresh_rate", Hyprlang::INT{24});
|
||||||
m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("cursor:inactive_timeout", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("cursor:inactive_timeout", {0.f});
|
||||||
m_pConfig->addConfigValue("cursor:no_warps", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("cursor:no_warps", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("cursor:persistent_warps", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("cursor:persistent_warps", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("cursor:warp_on_change_workspace", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("cursor:warp_on_change_workspace", Hyprlang::INT{0});
|
||||||
|
@ -539,6 +560,7 @@ CConfigManager::CConfigManager() {
|
||||||
m_pConfig->addConfigValue("cursor:zoom_factor", {1.f});
|
m_pConfig->addConfigValue("cursor:zoom_factor", {1.f});
|
||||||
m_pConfig->addConfigValue("cursor:zoom_rigid", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("cursor:zoom_rigid", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("cursor:enable_hyprcursor", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("cursor:enable_hyprcursor", Hyprlang::INT{1});
|
||||||
|
m_pConfig->addConfigValue("cursor:sync_gsettings_theme", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("cursor:hide_on_key_press", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("cursor:hide_on_key_press", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("cursor:hide_on_touch", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("cursor:hide_on_touch", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("cursor:allow_dumb_copy", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("cursor:allow_dumb_copy", Hyprlang::INT{0});
|
||||||
|
@ -560,7 +582,9 @@ CConfigManager::CConfigManager() {
|
||||||
m_pConfig->addConfigValue("group:groupbar:col.locked_active", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0x66ff5500"});
|
m_pConfig->addConfigValue("group:groupbar:col.locked_active", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0x66ff5500"});
|
||||||
m_pConfig->addConfigValue("group:groupbar:col.locked_inactive", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0x66775500"});
|
m_pConfig->addConfigValue("group:groupbar:col.locked_inactive", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0x66775500"});
|
||||||
|
|
||||||
m_pConfig->addConfigValue("experimental:explicit_sync", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("render:explicit_sync", Hyprlang::INT{2});
|
||||||
|
m_pConfig->addConfigValue("render:explicit_sync_kms", Hyprlang::INT{2});
|
||||||
|
m_pConfig->addConfigValue("render:direct_scanout", Hyprlang::INT{0});
|
||||||
|
|
||||||
// devices
|
// devices
|
||||||
m_pConfig->addSpecialCategory("device", {"name"});
|
m_pConfig->addSpecialCategory("device", {"name"});
|
||||||
|
@ -601,6 +625,7 @@ CConfigManager::CConfigManager() {
|
||||||
// keywords
|
// keywords
|
||||||
m_pConfig->registerHandler(&::handleRawExec, "exec", {false});
|
m_pConfig->registerHandler(&::handleRawExec, "exec", {false});
|
||||||
m_pConfig->registerHandler(&::handleExecOnce, "exec-once", {false});
|
m_pConfig->registerHandler(&::handleExecOnce, "exec-once", {false});
|
||||||
|
m_pConfig->registerHandler(&::handleExecShutdown, "exec-shutdown", {false});
|
||||||
m_pConfig->registerHandler(&::handleMonitor, "monitor", {false});
|
m_pConfig->registerHandler(&::handleMonitor, "monitor", {false});
|
||||||
m_pConfig->registerHandler(&::handleBind, "bind", {true});
|
m_pConfig->registerHandler(&::handleBind, "bind", {true});
|
||||||
m_pConfig->registerHandler(&::handleUnbind, "unbind", {false});
|
m_pConfig->registerHandler(&::handleUnbind, "unbind", {false});
|
||||||
|
@ -661,6 +686,10 @@ std::string CConfigManager::getMainConfigPath() {
|
||||||
if (!g_pCompositor->explicitConfigPath.empty())
|
if (!g_pCompositor->explicitConfigPath.empty())
|
||||||
return g_pCompositor->explicitConfigPath;
|
return g_pCompositor->explicitConfigPath;
|
||||||
|
|
||||||
|
if (const auto CFG_ENV = getenv("HYPRLAND_CONFIG"); CFG_ENV)
|
||||||
|
return CFG_ENV;
|
||||||
|
Debug::log(TRACE, "Seems as if HYPRLAND_CONFIG isn't set, let's see what we can do with HOME.");
|
||||||
|
|
||||||
static const auto paths = Hyprutils::Path::findConfig(ISDEBUG ? "hyprlandd" : "hyprland");
|
static const auto paths = Hyprutils::Path::findConfig(ISDEBUG ? "hyprlandd" : "hyprland");
|
||||||
if (paths.first.has_value()) {
|
if (paths.first.has_value()) {
|
||||||
return paths.first.value();
|
return paths.first.value();
|
||||||
|
@ -720,7 +749,6 @@ void CConfigManager::setDefaultAnimationVars() {
|
||||||
INITANIMCFG("fade");
|
INITANIMCFG("fade");
|
||||||
INITANIMCFG("border");
|
INITANIMCFG("border");
|
||||||
INITANIMCFG("borderangle");
|
INITANIMCFG("borderangle");
|
||||||
INITANIMCFG("workspaces");
|
|
||||||
|
|
||||||
// windows
|
// windows
|
||||||
INITANIMCFG("windowsIn");
|
INITANIMCFG("windowsIn");
|
||||||
|
@ -741,7 +769,12 @@ void CConfigManager::setDefaultAnimationVars() {
|
||||||
// border
|
// border
|
||||||
|
|
||||||
// workspaces
|
// workspaces
|
||||||
|
INITANIMCFG("workspaces");
|
||||||
|
INITANIMCFG("workspacesIn");
|
||||||
|
INITANIMCFG("workspacesOut");
|
||||||
INITANIMCFG("specialWorkspace");
|
INITANIMCFG("specialWorkspace");
|
||||||
|
INITANIMCFG("specialWorkspaceIn");
|
||||||
|
INITANIMCFG("specialWorkspaceOut");
|
||||||
}
|
}
|
||||||
|
|
||||||
// init the values
|
// init the values
|
||||||
|
@ -770,7 +803,11 @@ void CConfigManager::setDefaultAnimationVars() {
|
||||||
CREATEANIMCFG("fadeLayersIn", "fadeLayers");
|
CREATEANIMCFG("fadeLayersIn", "fadeLayers");
|
||||||
CREATEANIMCFG("fadeLayersOut", "fadeLayers");
|
CREATEANIMCFG("fadeLayersOut", "fadeLayers");
|
||||||
|
|
||||||
|
CREATEANIMCFG("workspacesIn", "workspaces");
|
||||||
|
CREATEANIMCFG("workspacesOut", "workspaces");
|
||||||
CREATEANIMCFG("specialWorkspace", "workspaces");
|
CREATEANIMCFG("specialWorkspace", "workspaces");
|
||||||
|
CREATEANIMCFG("specialWorkspaceIn", "specialWorkspace");
|
||||||
|
CREATEANIMCFG("specialWorkspaceOut", "specialWorkspace");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> CConfigManager::resetHLConfig() {
|
std::optional<std::string> CConfigManager::resetHLConfig() {
|
||||||
|
@ -785,6 +822,7 @@ std::optional<std::string> CConfigManager::resetHLConfig() {
|
||||||
m_vDeclaredPlugins.clear();
|
m_vDeclaredPlugins.clear();
|
||||||
m_dLayerRules.clear();
|
m_dLayerRules.clear();
|
||||||
m_vFailedPluginConfigValues.clear();
|
m_vFailedPluginConfigValues.clear();
|
||||||
|
finalExecRequests.clear();
|
||||||
|
|
||||||
// paths
|
// paths
|
||||||
configPaths.clear();
|
configPaths.clear();
|
||||||
|
@ -798,11 +836,14 @@ std::optional<std::string> CConfigManager::resetHLConfig() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
static const auto PENABLEEXPLICIT = CConfigValue<Hyprlang::INT>("render:explicit_sync");
|
||||||
|
static int prevEnabledExplicit = *PENABLEEXPLICIT;
|
||||||
|
|
||||||
|
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||||
w->uncacheWindowDecos();
|
w->uncacheWindowDecos();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors)
|
for (auto const& m : g_pCompositor->m_vMonitors)
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||||
|
|
||||||
// Update the keyboard layout to the cfg'd one if this is not the first launch
|
// Update the keyboard layout to the cfg'd one if this is not the first launch
|
||||||
|
@ -826,8 +867,12 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
||||||
if (result.error && !std::any_cast<Hyprlang::INT>(m_pConfig->getConfigValue("debug:suppress_errors")))
|
if (result.error && !std::any_cast<Hyprlang::INT>(m_pConfig->getConfigValue("debug:suppress_errors")))
|
||||||
g_pHyprError->queueCreate(result.getError(), CColor(1.0, 50.0 / 255.0, 50.0 / 255.0, 1.0));
|
g_pHyprError->queueCreate(result.getError(), CColor(1.0, 50.0 / 255.0, 50.0 / 255.0, 1.0));
|
||||||
else if (std::any_cast<Hyprlang::INT>(m_pConfig->getConfigValue("autogenerated")) == 1)
|
else if (std::any_cast<Hyprlang::INT>(m_pConfig->getConfigValue("autogenerated")) == 1)
|
||||||
g_pHyprError->queueCreate("Warning: You're using an autogenerated config! (config file: " + getMainConfigPath() + " )\nSUPER+Q -> kitty\nSUPER+M -> exit Hyprland",
|
g_pHyprError->queueCreate(
|
||||||
|
"Warning: You're using an autogenerated config! (config file: " + getMainConfigPath() +
|
||||||
|
" )\nSUPER+Q -> kitty (if it doesn't launch, make sure it's installed or choose a different terminal in the config)\nSUPER+M -> exit Hyprland",
|
||||||
CColor(1.0, 1.0, 70.0 / 255.0, 1.0));
|
CColor(1.0, 1.0, 70.0 / 255.0, 1.0));
|
||||||
|
else if (*PENABLEEXPLICIT != prevEnabledExplicit)
|
||||||
|
g_pHyprError->queueCreate("Warning: You changed the render:explicit_sync option, this requires you to restart Hyprland.", CColor(0.9, 0.76, 0.221, 1.0));
|
||||||
else
|
else
|
||||||
g_pHyprError->destroy();
|
g_pHyprError->destroy();
|
||||||
|
|
||||||
|
@ -842,11 +887,34 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
||||||
ensureVRR();
|
ensureVRR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NO_XWAYLAND
|
||||||
|
const auto PENABLEXWAYLAND = std::any_cast<Hyprlang::INT>(m_pConfig->getConfigValue("xwayland:enabled"));
|
||||||
|
// enable/disable xwayland usage
|
||||||
|
if (!isFirstLaunch) {
|
||||||
|
bool prevEnabledXwayland = g_pCompositor->m_bEnableXwayland;
|
||||||
|
if (PENABLEXWAYLAND != prevEnabledXwayland) {
|
||||||
|
g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND;
|
||||||
|
if (PENABLEXWAYLAND) {
|
||||||
|
Debug::log(LOG, "xwayland has been enabled");
|
||||||
|
} else {
|
||||||
|
Debug::log(LOG, "xwayland has been disabled, cleaning up...");
|
||||||
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
|
if (w->m_pXDGSurface || !w->m_bIsX11)
|
||||||
|
continue;
|
||||||
|
g_pCompositor->closeWindow(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_pXWayland = std::make_unique<CXWayland>(g_pCompositor->m_bEnableXwayland);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
g_pCompositor->m_bEnableXwayland = PENABLEXWAYLAND;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!isFirstLaunch && !g_pCompositor->m_bUnsafeState)
|
if (!isFirstLaunch && !g_pCompositor->m_bUnsafeState)
|
||||||
refreshGroupBarGradients();
|
refreshGroupBarGradients();
|
||||||
|
|
||||||
// Updates dynamic window and workspace rules
|
// Updates dynamic window and workspace rules
|
||||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
for (auto const& w : g_pCompositor->m_vWorkspaces) {
|
||||||
if (w->inert())
|
if (w->inert())
|
||||||
continue;
|
continue;
|
||||||
g_pCompositor->updateWorkspaceWindows(w->m_iID);
|
g_pCompositor->updateWorkspaceWindows(w->m_iID);
|
||||||
|
@ -874,7 +942,7 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
||||||
|
|
||||||
Debug::coloredLogs = reinterpret_cast<int64_t* const*>(m_pConfig->getConfigValuePtr("debug:colored_stdout_logs")->getDataStaticPtr());
|
Debug::coloredLogs = reinterpret_cast<int64_t* const*>(m_pConfig->getConfigValuePtr("debug:colored_stdout_logs")->getDataStaticPtr());
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||||
// mark blur dirty
|
// mark blur dirty
|
||||||
g_pHyprOpenGL->markBlurDirtyForMonitor(m.get());
|
g_pHyprOpenGL->markBlurDirtyForMonitor(m.get());
|
||||||
|
|
||||||
|
@ -884,7 +952,7 @@ void CConfigManager::postConfigReload(const Hyprlang::CParseResult& result) {
|
||||||
m->forceFullFrames = 2;
|
m->forceFullFrames = 2;
|
||||||
|
|
||||||
// also force mirrors, as the aspect ratio could've changed
|
// also force mirrors, as the aspect ratio could've changed
|
||||||
for (auto& mirror : m->mirrors)
|
for (auto const& mirror : m->mirrors)
|
||||||
mirror->forceFullFrames = 3;
|
mirror->forceFullFrames = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -916,14 +984,24 @@ void CConfigManager::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::string& VALUE) {
|
std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::string& VALUE) {
|
||||||
|
static const auto PENABLEEXPLICIT = CConfigValue<Hyprlang::INT>("render:explicit_sync");
|
||||||
|
static int prevEnabledExplicit = *PENABLEEXPLICIT;
|
||||||
|
|
||||||
const auto RET = m_pConfig->parseDynamic(COMMAND.c_str(), VALUE.c_str());
|
const auto RET = m_pConfig->parseDynamic(COMMAND.c_str(), VALUE.c_str());
|
||||||
|
|
||||||
// invalidate layouts if they changed
|
// invalidate layouts if they changed
|
||||||
if (COMMAND == "monitor" || COMMAND.contains("gaps_") || COMMAND.starts_with("dwindle:") || COMMAND.starts_with("master:")) {
|
if (COMMAND == "monitor" || COMMAND.contains("gaps_") || COMMAND.starts_with("dwindle:") || COMMAND.starts_with("master:")) {
|
||||||
for (auto& m : g_pCompositor->m_vMonitors)
|
for (auto const& m : g_pCompositor->m_vMonitors)
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (COMMAND.contains("explicit")) {
|
||||||
|
if (*PENABLEEXPLICIT != prevEnabledExplicit)
|
||||||
|
g_pHyprError->queueCreate("Warning: You changed the render:explicit_sync option, this requires you to restart Hyprland.", CColor(0.9, 0.76, 0.221, 1.0));
|
||||||
|
else
|
||||||
|
g_pHyprError->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
// Update window border colors
|
// Update window border colors
|
||||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||||
|
|
||||||
|
@ -951,7 +1029,7 @@ void CConfigManager::tick() {
|
||||||
|
|
||||||
bool parse = false;
|
bool parse = false;
|
||||||
|
|
||||||
for (auto& cf : configPaths) {
|
for (auto const& cf : configPaths) {
|
||||||
struct stat fileStat;
|
struct stat fileStat;
|
||||||
int err = stat(cf.c_str(), &fileStat);
|
int err = stat(cf.c_str(), &fileStat);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
|
@ -1006,33 +1084,74 @@ std::string CConfigManager::getDeviceString(const std::string& dev, const std::s
|
||||||
return VAL;
|
return VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SMonitorRule CConfigManager::getMonitorRuleFor(const CMonitor& PMONITOR) {
|
SMonitorRule CConfigManager::getMonitorRuleFor(const SP<CMonitor> PMONITOR) {
|
||||||
for (auto& r : m_dMonitorRules | std::views::reverse) {
|
auto applyWlrOutputConfig = [PMONITOR](SMonitorRule rule) -> SMonitorRule {
|
||||||
if (PMONITOR.matchesStaticSelector(r.name)) {
|
const auto CONFIG = PROTO::outputManagement->getOutputStateFor(PMONITOR);
|
||||||
return r;
|
|
||||||
|
if (!CONFIG)
|
||||||
|
return rule;
|
||||||
|
|
||||||
|
Debug::log(LOG, "CConfigManager::getMonitorRuleFor: found a wlr_output_manager override for {}", PMONITOR->szName);
|
||||||
|
|
||||||
|
Debug::log(LOG, " > overriding enabled: {} -> {}", !rule.disabled, !CONFIG->enabled);
|
||||||
|
rule.disabled = !CONFIG->enabled;
|
||||||
|
|
||||||
|
if ((CONFIG->committedProperties & OUTPUT_HEAD_COMMITTED_MODE) || (CONFIG->committedProperties & OUTPUT_HEAD_COMMITTED_CUSTOM_MODE)) {
|
||||||
|
Debug::log(LOG, " > overriding mode: {:.0f}x{:.0f}@{:.2f}Hz -> {:.0f}x{:.0f}@{:.2f}Hz", rule.resolution.x, rule.resolution.y, rule.refreshRate, CONFIG->resolution.x,
|
||||||
|
CONFIG->resolution.y, CONFIG->refresh / 1000.F);
|
||||||
|
rule.resolution = CONFIG->resolution;
|
||||||
|
rule.refreshRate = CONFIG->refresh / 1000.F;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CONFIG->committedProperties & OUTPUT_HEAD_COMMITTED_POSITION) {
|
||||||
|
Debug::log(LOG, " > overriding offset: {:.0f}, {:.0f} -> {:.0f}, {:.0f}", rule.offset.x, rule.offset.y, CONFIG->position.x, CONFIG->position.y);
|
||||||
|
rule.offset = CONFIG->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CONFIG->committedProperties & OUTPUT_HEAD_COMMITTED_TRANSFORM) {
|
||||||
|
Debug::log(LOG, " > overriding transform: {} -> {}", (uint8_t)rule.transform, (uint8_t)CONFIG->transform);
|
||||||
|
rule.transform = CONFIG->transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CONFIG->committedProperties & OUTPUT_HEAD_COMMITTED_SCALE) {
|
||||||
|
Debug::log(LOG, " > overriding scale: {} -> {}", (uint8_t)rule.scale, (uint8_t)CONFIG->scale);
|
||||||
|
rule.scale = CONFIG->scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CONFIG->committedProperties & OUTPUT_HEAD_COMMITTED_ADAPTIVE_SYNC) {
|
||||||
|
Debug::log(LOG, " > overriding vrr: {} -> {}", rule.vrr.value_or(0), CONFIG->adaptiveSync);
|
||||||
|
rule.vrr = (int)CONFIG->adaptiveSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rule;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto const& r : m_dMonitorRules | std::views::reverse) {
|
||||||
|
if (PMONITOR->matchesStaticSelector(r.name)) {
|
||||||
|
return applyWlrOutputConfig(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(WARN, "No rule found for {}, trying to use the first.", PMONITOR.szName);
|
Debug::log(WARN, "No rule found for {}, trying to use the first.", PMONITOR->szName);
|
||||||
|
|
||||||
for (auto& r : m_dMonitorRules) {
|
for (auto const& r : m_dMonitorRules) {
|
||||||
if (r.name.empty()) {
|
if (r.name.empty()) {
|
||||||
return r;
|
return applyWlrOutputConfig(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(WARN, "No rules configured. Using the default hardcoded one.");
|
Debug::log(WARN, "No rules configured. Using the default hardcoded one.");
|
||||||
|
|
||||||
return SMonitorRule{.autoDir = eAutoDirs::DIR_AUTO_RIGHT,
|
return applyWlrOutputConfig(SMonitorRule{.autoDir = eAutoDirs::DIR_AUTO_RIGHT,
|
||||||
.name = "",
|
.name = "",
|
||||||
.resolution = Vector2D(0, 0),
|
.resolution = Vector2D(0, 0),
|
||||||
.offset = Vector2D(-INT32_MAX, -INT32_MAX),
|
.offset = Vector2D(-INT32_MAX, -INT32_MAX),
|
||||||
.scale = -1}; // 0, 0 is preferred and -1, -1 is auto
|
.scale = -1}); // 0, 0 is preferred and -1, -1 is auto
|
||||||
}
|
}
|
||||||
|
|
||||||
SWorkspaceRule CConfigManager::getWorkspaceRuleFor(PHLWORKSPACE pWorkspace) {
|
SWorkspaceRule CConfigManager::getWorkspaceRuleFor(PHLWORKSPACE pWorkspace) {
|
||||||
SWorkspaceRule mergedRule{};
|
SWorkspaceRule mergedRule{};
|
||||||
for (auto& rule : m_dWorkspaceRules) {
|
for (auto const& rule : m_dWorkspaceRules) {
|
||||||
if (!pWorkspace->matchesStaticSelector(rule.workspaceString))
|
if (!pWorkspace->matchesStaticSelector(rule.workspaceString))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1105,7 +1224,7 @@ std::vector<SWindowRule> CConfigManager::getMatchingRules(PHLWINDOW pWindow, boo
|
||||||
// local tags for dynamic tag rule match
|
// local tags for dynamic tag rule match
|
||||||
auto tags = pWindow->m_tags;
|
auto tags = pWindow->m_tags;
|
||||||
|
|
||||||
for (auto& rule : m_dWindowRules) {
|
for (auto const& rule : m_dWindowRules) {
|
||||||
// check if we have a matching rule
|
// check if we have a matching rule
|
||||||
if (!rule.v2) {
|
if (!rule.v2) {
|
||||||
try {
|
try {
|
||||||
|
@ -1185,6 +1304,32 @@ std::vector<SWindowRule> CConfigManager::getMatchingRules(PHLWINDOW pWindow, boo
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!rule.szFullscreenState.empty()) {
|
||||||
|
const auto ARGS = CVarList(rule.szFullscreenState, 2, ' ');
|
||||||
|
//
|
||||||
|
std::optional<eFullscreenMode> internalMode, clientMode;
|
||||||
|
|
||||||
|
if (ARGS[0] == "*")
|
||||||
|
internalMode = std::nullopt;
|
||||||
|
else if (isNumber(ARGS[0]))
|
||||||
|
internalMode = (eFullscreenMode)std::stoi(ARGS[0]);
|
||||||
|
else
|
||||||
|
throw std::runtime_error("szFullscreenState internal mode not valid");
|
||||||
|
|
||||||
|
if (ARGS[1] == "*")
|
||||||
|
clientMode = std::nullopt;
|
||||||
|
else if (isNumber(ARGS[1]))
|
||||||
|
clientMode = (eFullscreenMode)std::stoi(ARGS[1]);
|
||||||
|
else
|
||||||
|
throw std::runtime_error("szFullscreenState client mode not valid");
|
||||||
|
|
||||||
|
if (internalMode.has_value() && pWindow->m_sFullscreenState.internal != internalMode)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (clientMode.has_value() && pWindow->m_sFullscreenState.client != clientMode)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!rule.szOnWorkspace.empty()) {
|
if (!rule.szOnWorkspace.empty()) {
|
||||||
const auto PWORKSPACE = pWindow->m_pWorkspace;
|
const auto PWORKSPACE = pWindow->m_pWorkspace;
|
||||||
if (!PWORKSPACE || !PWORKSPACE->matchesStaticSelector(rule.szOnWorkspace))
|
if (!PWORKSPACE || !PWORKSPACE->matchesStaticSelector(rule.szOnWorkspace))
|
||||||
|
@ -1244,7 +1389,7 @@ std::vector<SWindowRule> CConfigManager::getMatchingRules(PHLWINDOW pWindow, boo
|
||||||
|
|
||||||
bool anyExecFound = false;
|
bool anyExecFound = false;
|
||||||
|
|
||||||
for (auto& er : execRequestedRules) {
|
for (auto const& er : execRequestedRules) {
|
||||||
if (std::ranges::any_of(PIDs, [&](const auto& pid) { return pid == er.iPid; })) {
|
if (std::ranges::any_of(PIDs, [&](const auto& pid) { return pid == er.iPid; })) {
|
||||||
returns.push_back({er.szRule, "execRule"});
|
returns.push_back({er.szRule, "execRule"});
|
||||||
anyExecFound = true;
|
anyExecFound = true;
|
||||||
|
@ -1264,7 +1409,7 @@ std::vector<SLayerRule> CConfigManager::getMatchingRules(PHLLS pLS) {
|
||||||
if (!pLS->layerSurface || pLS->fadingOut)
|
if (!pLS->layerSurface || pLS->fadingOut)
|
||||||
return returns;
|
return returns;
|
||||||
|
|
||||||
for (auto& lr : m_dLayerRules) {
|
for (auto const& lr : m_dLayerRules) {
|
||||||
if (lr.targetNamespace.starts_with("address:0x")) {
|
if (lr.targetNamespace.starts_with("address:0x")) {
|
||||||
if (std::format("address:0x{:x}", (uintptr_t)pLS.get()) != lr.targetNamespace)
|
if (std::format("address:0x{:x}", (uintptr_t)pLS.get()) != lr.targetNamespace)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1301,7 +1446,7 @@ void CConfigManager::dispatchExecOnce() {
|
||||||
firstExecDispatched = true;
|
firstExecDispatched = true;
|
||||||
isLaunchingExecOnce = true;
|
isLaunchingExecOnce = true;
|
||||||
|
|
||||||
for (auto& c : firstExecRequests) {
|
for (auto const& c : firstExecRequests) {
|
||||||
handleRawExec("", c);
|
handleRawExec("", c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1318,6 +1463,24 @@ void CConfigManager::dispatchExecOnce() {
|
||||||
g_pCompositor->performUserChecks();
|
g_pCompositor->performUserChecks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CConfigManager::dispatchExecShutdown() {
|
||||||
|
if (finalExecRequests.empty()) {
|
||||||
|
g_pCompositor->m_bFinalRequests = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pCompositor->m_bFinalRequests = true;
|
||||||
|
|
||||||
|
for (auto const& c : finalExecRequests) {
|
||||||
|
handleExecShutdown("", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
finalExecRequests.clear();
|
||||||
|
|
||||||
|
// Actually exit now
|
||||||
|
handleExecShutdown("", "hyprctl dispatch exit");
|
||||||
|
}
|
||||||
|
|
||||||
void CConfigManager::appendMonitorRule(const SMonitorRule& r) {
|
void CConfigManager::appendMonitorRule(const SMonitorRule& r) {
|
||||||
m_dMonitorRules.emplace_back(r);
|
m_dMonitorRules.emplace_back(r);
|
||||||
}
|
}
|
||||||
|
@ -1338,11 +1501,11 @@ void CConfigManager::performMonitorReload() {
|
||||||
|
|
||||||
bool overAgain = false;
|
bool overAgain = false;
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
for (auto const& m : g_pCompositor->m_vRealMonitors) {
|
||||||
if (!m->output || m->isUnsafeFallback)
|
if (!m->output || m->isUnsafeFallback)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto rule = getMonitorRuleFor(*m);
|
auto rule = getMonitorRuleFor(m);
|
||||||
|
|
||||||
if (!g_pHyprRenderer->applyMonitorRule(m.get(), &rule)) {
|
if (!g_pHyprRenderer->applyMonitorRule(m.get(), &rule)) {
|
||||||
overAgain = true;
|
overAgain = true;
|
||||||
|
@ -1385,7 +1548,7 @@ bool CConfigManager::deviceConfigExists(const std::string& dev) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CConfigManager::shouldBlurLS(const std::string& ns) {
|
bool CConfigManager::shouldBlurLS(const std::string& ns) {
|
||||||
for (auto& bls : m_dBlurLSNamespaces) {
|
for (auto const& bls : m_dBlurLSNamespaces) {
|
||||||
if (bls == ns) {
|
if (bls == ns) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1395,11 +1558,11 @@ bool CConfigManager::shouldBlurLS(const std::string& ns) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConfigManager::ensureMonitorStatus() {
|
void CConfigManager::ensureMonitorStatus() {
|
||||||
for (auto& rm : g_pCompositor->m_vRealMonitors) {
|
for (auto const& rm : g_pCompositor->m_vRealMonitors) {
|
||||||
if (!rm->output || rm->isUnsafeFallback)
|
if (!rm->output || rm->isUnsafeFallback)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto rule = getMonitorRuleFor(*rm);
|
auto rule = getMonitorRuleFor(rm);
|
||||||
|
|
||||||
if (rule.disabled == rm->m_bEnabled)
|
if (rule.disabled == rm->m_bEnabled)
|
||||||
g_pHyprRenderer->applyMonitorRule(rm.get(), &rule);
|
g_pHyprRenderer->applyMonitorRule(rm.get(), &rule);
|
||||||
|
@ -1417,7 +1580,7 @@ void CConfigManager::ensureVRR(CMonitor* pMonitor) {
|
||||||
|
|
||||||
if (USEVRR == 0) {
|
if (USEVRR == 0) {
|
||||||
if (m->vrrActive) {
|
if (m->vrrActive) {
|
||||||
|
m->output->state->resetExplicitFences();
|
||||||
m->output->state->setAdaptiveSync(false);
|
m->output->state->setAdaptiveSync(false);
|
||||||
|
|
||||||
if (!m->state.commit())
|
if (!m->state.commit())
|
||||||
|
@ -1427,6 +1590,7 @@ void CConfigManager::ensureVRR(CMonitor* pMonitor) {
|
||||||
return;
|
return;
|
||||||
} else if (USEVRR == 1) {
|
} else if (USEVRR == 1) {
|
||||||
if (!m->vrrActive) {
|
if (!m->vrrActive) {
|
||||||
|
m->output->state->resetExplicitFences();
|
||||||
m->output->state->setAdaptiveSync(true);
|
m->output->state->setAdaptiveSync(true);
|
||||||
|
|
||||||
if (!m->state.test()) {
|
if (!m->state.test()) {
|
||||||
|
@ -1451,6 +1615,7 @@ void CConfigManager::ensureVRR(CMonitor* pMonitor) {
|
||||||
const auto WORKSPACEFULL = PWORKSPACE->m_bHasFullscreenWindow && (PWORKSPACE->m_efFullscreenMode & FSMODE_FULLSCREEN);
|
const auto WORKSPACEFULL = PWORKSPACE->m_bHasFullscreenWindow && (PWORKSPACE->m_efFullscreenMode & FSMODE_FULLSCREEN);
|
||||||
|
|
||||||
if (WORKSPACEFULL) {
|
if (WORKSPACEFULL) {
|
||||||
|
m->output->state->resetExplicitFences();
|
||||||
m->output->state->setAdaptiveSync(true);
|
m->output->state->setAdaptiveSync(true);
|
||||||
|
|
||||||
if (!m->state.test()) {
|
if (!m->state.test()) {
|
||||||
|
@ -1462,6 +1627,7 @@ void CConfigManager::ensureVRR(CMonitor* pMonitor) {
|
||||||
Debug::log(ERR, "Couldn't commit output {} in ensureVRR -> true", m->output->name);
|
Debug::log(ERR, "Couldn't commit output {} in ensureVRR -> true", m->output->name);
|
||||||
|
|
||||||
} else if (!WORKSPACEFULL) {
|
} else if (!WORKSPACEFULL) {
|
||||||
|
m->output->state->resetExplicitFences();
|
||||||
m->output->state->setAdaptiveSync(false);
|
m->output->state->setAdaptiveSync(false);
|
||||||
|
|
||||||
if (!m->state.commit())
|
if (!m->state.commit())
|
||||||
|
@ -1475,7 +1641,7 @@ void CConfigManager::ensureVRR(CMonitor* pMonitor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||||
ensureVRRForDisplay(m.get());
|
ensureVRRForDisplay(m.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1497,7 +1663,7 @@ CMonitor* CConfigManager::getBoundMonitorForWS(const std::string& wsname) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CConfigManager::getBoundMonitorStringForWS(const std::string& wsname) {
|
std::string CConfigManager::getBoundMonitorStringForWS(const std::string& wsname) {
|
||||||
for (auto& wr : m_dWorkspaceRules) {
|
for (auto const& wr : m_dWorkspaceRules) {
|
||||||
const auto WSNAME = wr.workspaceName.starts_with("name:") ? wr.workspaceName.substr(5) : wr.workspaceName;
|
const auto WSNAME = wr.workspaceName.starts_with("name:") ? wr.workspaceName.substr(5) : wr.workspaceName;
|
||||||
|
|
||||||
if (WSNAME == wsname)
|
if (WSNAME == wsname)
|
||||||
|
@ -1568,7 +1734,7 @@ void CConfigManager::addPluginKeyword(HANDLE handle, const std::string& name, Hy
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConfigManager::removePluginConfig(HANDLE handle) {
|
void CConfigManager::removePluginConfig(HANDLE handle) {
|
||||||
for (auto& k : pluginKeywords) {
|
for (auto const& k : pluginKeywords) {
|
||||||
if (k.handle != handle)
|
if (k.handle != handle)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1576,7 +1742,7 @@ void CConfigManager::removePluginConfig(HANDLE handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::erase_if(pluginKeywords, [&](const auto& other) { return other.handle == handle; });
|
std::erase_if(pluginKeywords, [&](const auto& other) { return other.handle == handle; });
|
||||||
for (auto& [h, n] : pluginVariables) {
|
for (auto const& [h, n] : pluginVariables) {
|
||||||
if (h != handle)
|
if (h != handle)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1591,7 +1757,7 @@ std::string CConfigManager::getDefaultWorkspaceFor(const std::string& name) {
|
||||||
if (other->monitor == name)
|
if (other->monitor == name)
|
||||||
return other->workspaceString;
|
return other->workspaceString;
|
||||||
if (other->monitor.substr(0, 5) == "desc:") {
|
if (other->monitor.substr(0, 5) == "desc:") {
|
||||||
auto monitor = g_pCompositor->getMonitorFromDesc(other->monitor.substr(5));
|
auto const monitor = g_pCompositor->getMonitorFromDesc(other->monitor.substr(5));
|
||||||
if (monitor && monitor->szName == name)
|
if (monitor && monitor->szName == name)
|
||||||
return other->workspaceString;
|
return other->workspaceString;
|
||||||
}
|
}
|
||||||
|
@ -1617,6 +1783,16 @@ std::optional<std::string> CConfigManager::handleExecOnce(const std::string& com
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> CConfigManager::handleExecShutdown(const std::string& command, const std::string& args) {
|
||||||
|
if (g_pCompositor->m_bFinalRequests) {
|
||||||
|
g_pKeybindManager->spawn(args);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
finalExecRequests.push_back(args);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
static bool parseModeLine(const std::string& modeline, drmModeModeInfo& mode) {
|
static bool parseModeLine(const std::string& modeline, drmModeModeInfo& mode) {
|
||||||
auto args = CVarList(modeline, 0, 's');
|
auto args = CVarList(modeline, 0, 's');
|
||||||
|
|
||||||
|
@ -1664,7 +1840,7 @@ static bool parseModeLine(const std::string& modeline, drmModeModeInfo& mode) {
|
||||||
if (it != flagsmap.end())
|
if (it != flagsmap.end())
|
||||||
mode.flags |= it->second;
|
mode.flags |= it->second;
|
||||||
else
|
else
|
||||||
Debug::log(ERR, "invalid flag {} in modeline", it->first);
|
Debug::log(ERR, "invalid flag {} in modeline", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(mode.name, sizeof(mode.name), "%dx%d@%d", mode.hdisplay, mode.vdisplay, mode.vrefresh / 1000);
|
snprintf(mode.name, sizeof(mode.name), "%dx%d@%d", mode.hdisplay, mode.vdisplay, mode.vrefresh / 1000);
|
||||||
|
@ -1988,7 +2164,7 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command
|
||||||
bool dontInhibit = false;
|
bool dontInhibit = false;
|
||||||
const auto BINDARGS = command.substr(4);
|
const auto BINDARGS = command.substr(4);
|
||||||
|
|
||||||
for (auto& arg : BINDARGS) {
|
for (auto const& arg : BINDARGS) {
|
||||||
if (arg == 'l') {
|
if (arg == 'l') {
|
||||||
locked = true;
|
locked = true;
|
||||||
} else if (arg == 'r') {
|
} else if (arg == 'r') {
|
||||||
|
@ -2099,7 +2275,7 @@ std::optional<std::string> CConfigManager::handleUnbind(const std::string& comma
|
||||||
|
|
||||||
bool windowRuleValid(const std::string& RULE) {
|
bool windowRuleValid(const std::string& RULE) {
|
||||||
static const auto rules = std::unordered_set<std::string>{
|
static const auto rules = std::unordered_set<std::string>{
|
||||||
"float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile",
|
"float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile", "renderunfocused",
|
||||||
};
|
};
|
||||||
static const auto rulesPrefix = std::vector<std::string>{
|
static const auto rulesPrefix = std::vector<std::string>{
|
||||||
"animation", "bordercolor", "bordersize", "center", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", "monitor",
|
"animation", "bordercolor", "bordersize", "center", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", "monitor",
|
||||||
|
@ -2114,7 +2290,7 @@ bool windowRuleValid(const std::string& RULE) {
|
||||||
|
|
||||||
bool layerRuleValid(const std::string& RULE) {
|
bool layerRuleValid(const std::string& RULE) {
|
||||||
static const auto rules = std::unordered_set<std::string>{"noanim", "blur", "blurpopups", "dimaround"};
|
static const auto rules = std::unordered_set<std::string>{"noanim", "blur", "blurpopups", "dimaround"};
|
||||||
static const auto rulesPrefix = std::vector<std::string>{"ignorealpha", "ignorezero", "xray", "animation"};
|
static const auto rulesPrefix = std::vector<std::string>{"ignorealpha", "ignorezero", "xray", "animation", "order"};
|
||||||
|
|
||||||
return rules.contains(RULE) || std::any_of(rulesPrefix.begin(), rulesPrefix.end(), [&RULE](auto prefix) { return RULE.starts_with(prefix); });
|
return rules.contains(RULE) || std::any_of(rulesPrefix.begin(), rulesPrefix.end(), [&RULE](auto prefix) { return RULE.starts_with(prefix); });
|
||||||
}
|
}
|
||||||
|
@ -2166,9 +2342,9 @@ std::optional<std::string> CConfigManager::handleLayerRule(const std::string& co
|
||||||
|
|
||||||
m_dLayerRules.push_back({VALUE, RULE});
|
m_dLayerRules.push_back({VALUE, RULE});
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors)
|
for (auto const& m : g_pCompositor->m_vMonitors)
|
||||||
for (auto& lsl : m->m_aLayerSurfaceLayers)
|
for (auto const& lsl : m->m_aLayerSurfaceLayers)
|
||||||
for (auto& ls : lsl)
|
for (auto const& ls : lsl)
|
||||||
ls->applyRules();
|
ls->applyRules();
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -2199,6 +2375,7 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
|
||||||
const auto FULLSCREENPOS = VALUE.find("fullscreen:");
|
const auto FULLSCREENPOS = VALUE.find("fullscreen:");
|
||||||
const auto PINNEDPOS = VALUE.find("pinned:");
|
const auto PINNEDPOS = VALUE.find("pinned:");
|
||||||
const auto FOCUSPOS = VALUE.find("focus:");
|
const auto FOCUSPOS = VALUE.find("focus:");
|
||||||
|
const auto FULLSCREENSTATEPOS = VALUE.find("fullscreenstate:");
|
||||||
const auto ONWORKSPACEPOS = VALUE.find("onworkspace:");
|
const auto ONWORKSPACEPOS = VALUE.find("onworkspace:");
|
||||||
|
|
||||||
// find workspacepos that isn't onworkspacepos
|
// find workspacepos that isn't onworkspacepos
|
||||||
|
@ -2212,9 +2389,8 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
|
||||||
currentPos = VALUE.find("workspace:", currentPos + 1);
|
currentPos = VALUE.find("workspace:", currentPos + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto checkPos = std::unordered_set{
|
const auto checkPos = std::unordered_set{TAGPOS, TITLEPOS, CLASSPOS, INITIALTITLEPOS, INITIALCLASSPOS, X11POS, FLOATPOS,
|
||||||
TAGPOS, TITLEPOS, CLASSPOS, INITIALTITLEPOS, INITIALCLASSPOS, X11POS, FLOATPOS, FULLSCREENPOS, PINNEDPOS, WORKSPACEPOS, FOCUSPOS, ONWORKSPACEPOS,
|
FULLSCREENPOS, PINNEDPOS, FULLSCREENSTATEPOS, WORKSPACEPOS, FOCUSPOS, ONWORKSPACEPOS};
|
||||||
};
|
|
||||||
if (checkPos.size() == 1 && checkPos.contains(std::string::npos)) {
|
if (checkPos.size() == 1 && checkPos.contains(std::string::npos)) {
|
||||||
Debug::log(ERR, "Invalid rulev2 syntax: {}", VALUE);
|
Debug::log(ERR, "Invalid rulev2 syntax: {}", VALUE);
|
||||||
return "Invalid rulev2 syntax: " + VALUE;
|
return "Invalid rulev2 syntax: " + VALUE;
|
||||||
|
@ -2243,6 +2419,8 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
|
||||||
min = FULLSCREENPOS;
|
min = FULLSCREENPOS;
|
||||||
if (PINNEDPOS > pos && PINNEDPOS < min)
|
if (PINNEDPOS > pos && PINNEDPOS < min)
|
||||||
min = PINNEDPOS;
|
min = PINNEDPOS;
|
||||||
|
if (FULLSCREENSTATEPOS > pos && FULLSCREENSTATEPOS < min)
|
||||||
|
min = FULLSCREENSTATEPOS;
|
||||||
if (ONWORKSPACEPOS > pos && ONWORKSPACEPOS < min)
|
if (ONWORKSPACEPOS > pos && ONWORKSPACEPOS < min)
|
||||||
min = ONWORKSPACEPOS;
|
min = ONWORKSPACEPOS;
|
||||||
if (WORKSPACEPOS > pos && WORKSPACEPOS < min)
|
if (WORKSPACEPOS > pos && WORKSPACEPOS < min)
|
||||||
|
@ -2287,6 +2465,9 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
|
||||||
if (PINNEDPOS != std::string::npos)
|
if (PINNEDPOS != std::string::npos)
|
||||||
rule.bPinned = extract(PINNEDPOS + 7) == "1" ? 1 : 0;
|
rule.bPinned = extract(PINNEDPOS + 7) == "1" ? 1 : 0;
|
||||||
|
|
||||||
|
if (FULLSCREENSTATEPOS != std::string::npos)
|
||||||
|
rule.szFullscreenState = extract(FULLSCREENSTATEPOS + 16);
|
||||||
|
|
||||||
if (WORKSPACEPOS != std::string::npos)
|
if (WORKSPACEPOS != std::string::npos)
|
||||||
rule.szWorkspace = extract(WORKSPACEPOS + 10);
|
rule.szWorkspace = extract(WORKSPACEPOS + 10);
|
||||||
|
|
||||||
|
@ -2328,6 +2509,9 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
|
||||||
if (rule.bPinned != -1 && rule.bPinned != other.bPinned)
|
if (rule.bPinned != -1 && rule.bPinned != other.bPinned)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!rule.szFullscreenState.empty() && rule.szFullscreenState != other.szFullscreenState)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!rule.szWorkspace.empty() && rule.szWorkspace != other.szWorkspace)
|
if (!rule.szWorkspace.empty() && rule.szWorkspace != other.szWorkspace)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -2359,9 +2543,9 @@ void CConfigManager::updateBlurredLS(const std::string& name, const bool forceBl
|
||||||
matchName = matchName.substr(8);
|
matchName = matchName.substr(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||||
for (auto& lsl : m->m_aLayerSurfaceLayers) {
|
for (auto const& lsl : m->m_aLayerSurfaceLayers) {
|
||||||
for (auto& ls : lsl) {
|
for (auto const& ls : lsl) {
|
||||||
if (BYADDRESS) {
|
if (BYADDRESS) {
|
||||||
if (std::format("0x{:x}", (uintptr_t)ls.get()) == matchName)
|
if (std::format("0x{:x}", (uintptr_t)ls.get()) == matchName)
|
||||||
ls->forceBlur = forceBlur;
|
ls->forceBlur = forceBlur;
|
||||||
|
@ -2414,7 +2598,7 @@ std::optional<std::string> CConfigManager::handleWorkspaceRules(const std::strin
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const static std::string ruleOnCreatedEmpty = "on-created-empty:";
|
const static std::string ruleOnCreatedEmpty = "on-created-empty:";
|
||||||
const static int ruleOnCreatedEmptyLen = ruleOnCreatedEmpty.length();
|
const static auto ruleOnCreatedEmptyLen = ruleOnCreatedEmpty.length();
|
||||||
|
|
||||||
auto assignRule = [&](std::string rule) -> std::optional<std::string> {
|
auto assignRule = [&](std::string rule) -> std::optional<std::string> {
|
||||||
size_t delim = std::string::npos;
|
size_t delim = std::string::npos;
|
||||||
|
@ -2470,7 +2654,7 @@ std::optional<std::string> CConfigManager::handleWorkspaceRules(const std::strin
|
||||||
};
|
};
|
||||||
|
|
||||||
CVarList rulesList{rules, 0, ',', true};
|
CVarList rulesList{rules, 0, ',', true};
|
||||||
for (auto& r : rulesList) {
|
for (auto const& r : rulesList) {
|
||||||
const auto R = assignRule(r);
|
const auto R = assignRule(r);
|
||||||
if (R.has_value())
|
if (R.has_value())
|
||||||
return R;
|
return R;
|
||||||
|
@ -2586,3 +2770,60 @@ std::optional<std::string> CConfigManager::handlePlugin(const std::string& comma
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<SConfigOptionDescription>& CConfigManager::getAllDescriptions() {
|
||||||
|
return CONFIG_OPTIONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SConfigOptionDescription::jsonify() const {
|
||||||
|
auto parseData = [this]() -> std::string {
|
||||||
|
return std::visit(
|
||||||
|
[](auto&& val) {
|
||||||
|
using T = std::decay_t<decltype(val)>;
|
||||||
|
if constexpr (std::is_same_v<T, SStringData>) {
|
||||||
|
return std::format(R"#( "value": "{}")#", val.value);
|
||||||
|
} else if constexpr (std::is_same_v<T, SRangeData>) {
|
||||||
|
return std::format(R"#( "value": {},
|
||||||
|
"min": {},
|
||||||
|
"max": {})#",
|
||||||
|
val.value, val.min, val.max);
|
||||||
|
} else if constexpr (std::is_same_v<T, SFloatData>) {
|
||||||
|
return std::format(R"#( "value": {},
|
||||||
|
"min": {},
|
||||||
|
"max": {})#",
|
||||||
|
val.value, val.min, val.max);
|
||||||
|
} else if constexpr (std::is_same_v<T, SColorData>) {
|
||||||
|
return std::format(R"#( "value": {})#", val.color.getAsHex());
|
||||||
|
} else if constexpr (std::is_same_v<T, SBoolData>) {
|
||||||
|
return std::format(R"#( "value": {})#", val.value);
|
||||||
|
} else if constexpr (std::is_same_v<T, SChoiceData>) {
|
||||||
|
return std::format(R"#( "value": {})#", val.choices);
|
||||||
|
} else if constexpr (std::is_same_v<T, SVectorData>) {
|
||||||
|
return std::format(R"#( "x": {},
|
||||||
|
"y": {},
|
||||||
|
"min_x": {},
|
||||||
|
"min_y": {},
|
||||||
|
"max_x": {},
|
||||||
|
"max_y": {})#",
|
||||||
|
val.vec.x, val.vec.y, val.min.x, val.min.y, val.max.x, val.max.y);
|
||||||
|
} else if constexpr (std::is_same_v<T, SGradientData>) {
|
||||||
|
return std::format(R"#( "value": "{}")#", val.gradient);
|
||||||
|
}
|
||||||
|
return std::string{""};
|
||||||
|
},
|
||||||
|
data);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string json = std::format(R"#({{
|
||||||
|
"value": "{}",
|
||||||
|
"description": "{}",
|
||||||
|
"type": {},
|
||||||
|
"flags": {},
|
||||||
|
"data": {{
|
||||||
|
{}
|
||||||
|
}}
|
||||||
|
}})#",
|
||||||
|
value, description, (uint16_t)type, (uint32_t)flags, parseData());
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "../debug/Log.hpp"
|
#include "../debug/Log.hpp"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -33,7 +34,7 @@ struct SWorkspaceRule {
|
||||||
std::string monitor = "";
|
std::string monitor = "";
|
||||||
std::string workspaceString = "";
|
std::string workspaceString = "";
|
||||||
std::string workspaceName = "";
|
std::string workspaceName = "";
|
||||||
int workspaceId = -1;
|
WORKSPACEID workspaceId = -1;
|
||||||
bool isDefault = false;
|
bool isDefault = false;
|
||||||
bool isPersistent = false;
|
bool isPersistent = false;
|
||||||
std::optional<CCssGapData> gapsIn;
|
std::optional<CCssGapData> gapsIn;
|
||||||
|
@ -83,6 +84,70 @@ struct SExecRequestedRule {
|
||||||
uint64_t iPid = 0;
|
uint64_t iPid = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum eConfigOptionType : uint16_t {
|
||||||
|
CONFIG_OPTION_BOOL = 0,
|
||||||
|
CONFIG_OPTION_INT = 1, /* e.g. 0/1/2*/
|
||||||
|
CONFIG_OPTION_FLOAT = 2,
|
||||||
|
CONFIG_OPTION_STRING_SHORT = 3, /* e.g. "auto" */
|
||||||
|
CONFIG_OPTION_STRING_LONG = 4, /* e.g. a command */
|
||||||
|
CONFIG_OPTION_COLOR = 5,
|
||||||
|
CONFIG_OPTION_CHOICE = 6, /* e.g. "one", "two", "three" */
|
||||||
|
CONFIG_OPTION_GRADIENT = 7,
|
||||||
|
CONFIG_OPTION_VECTOR = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum eConfigOptionFlags : uint32_t {
|
||||||
|
CONFIG_OPTION_FLAG_PERCENTAGE = (1 << 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SConfigOptionDescription {
|
||||||
|
|
||||||
|
struct SBoolData {
|
||||||
|
bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SRangeData {
|
||||||
|
int value = 0, min = 0, max = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SFloatData {
|
||||||
|
float value = 0, min = 0, max = 100;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SStringData {
|
||||||
|
std::string value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SColorData {
|
||||||
|
CColor color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SChoiceData {
|
||||||
|
int firstIndex = 0;
|
||||||
|
std::string choices; // comma-separated
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SGradientData {
|
||||||
|
std::string gradient;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SVectorData {
|
||||||
|
Vector2D vec, min, max;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string value; // e.g. general:gaps_in
|
||||||
|
std::string description;
|
||||||
|
std::string specialCategory; // if value is special (e.g. device:abc) value will be abc and special device
|
||||||
|
bool specialKey = false;
|
||||||
|
eConfigOptionType type = CONFIG_OPTION_BOOL;
|
||||||
|
uint32_t flags = 0; // eConfigOptionFlags
|
||||||
|
|
||||||
|
std::string jsonify() const;
|
||||||
|
|
||||||
|
//
|
||||||
|
std::variant<SBoolData, SRangeData, SFloatData, SStringData, SColorData, SChoiceData, SGradientData, SVectorData> data;
|
||||||
|
};
|
||||||
|
|
||||||
class CConfigManager {
|
class CConfigManager {
|
||||||
public:
|
public:
|
||||||
CConfigManager();
|
CConfigManager();
|
||||||
|
@ -104,7 +169,7 @@ class CConfigManager {
|
||||||
static std::string getMainConfigPath();
|
static std::string getMainConfigPath();
|
||||||
const std::string getConfigString();
|
const std::string getConfigString();
|
||||||
|
|
||||||
SMonitorRule getMonitorRuleFor(const CMonitor&);
|
SMonitorRule getMonitorRuleFor(const SP<CMonitor>);
|
||||||
SWorkspaceRule getWorkspaceRuleFor(PHLWORKSPACE workspace);
|
SWorkspaceRule getWorkspaceRuleFor(PHLWORKSPACE workspace);
|
||||||
std::string getDefaultWorkspaceFor(const std::string&);
|
std::string getDefaultWorkspaceFor(const std::string&);
|
||||||
|
|
||||||
|
@ -115,6 +180,8 @@ class CConfigManager {
|
||||||
std::vector<SWindowRule> getMatchingRules(PHLWINDOW, bool dynamic = true, bool shadowExec = false);
|
std::vector<SWindowRule> getMatchingRules(PHLWINDOW, bool dynamic = true, bool shadowExec = false);
|
||||||
std::vector<SLayerRule> getMatchingRules(PHLLS);
|
std::vector<SLayerRule> getMatchingRules(PHLLS);
|
||||||
|
|
||||||
|
const std::vector<SConfigOptionDescription>& getAllDescriptions();
|
||||||
|
|
||||||
std::unordered_map<std::string, SMonitorAdditionalReservedArea> m_mAdditionalReservedAreas;
|
std::unordered_map<std::string, SMonitorAdditionalReservedArea> m_mAdditionalReservedAreas;
|
||||||
|
|
||||||
std::unordered_map<std::string, SAnimationPropertyConfig> getAnimationConfig();
|
std::unordered_map<std::string, SAnimationPropertyConfig> getAnimationConfig();
|
||||||
|
@ -125,6 +192,7 @@ class CConfigManager {
|
||||||
|
|
||||||
// no-op when done.
|
// no-op when done.
|
||||||
void dispatchExecOnce();
|
void dispatchExecOnce();
|
||||||
|
void dispatchExecShutdown();
|
||||||
|
|
||||||
void performMonitorReload();
|
void performMonitorReload();
|
||||||
void appendMonitorRule(const SMonitorRule&);
|
void appendMonitorRule(const SMonitorRule&);
|
||||||
|
@ -146,6 +214,7 @@ class CConfigManager {
|
||||||
// keywords
|
// keywords
|
||||||
std::optional<std::string> handleRawExec(const std::string&, const std::string&);
|
std::optional<std::string> handleRawExec(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleExecOnce(const std::string&, const std::string&);
|
std::optional<std::string> handleExecOnce(const std::string&, const std::string&);
|
||||||
|
std::optional<std::string> handleExecShutdown(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleMonitor(const std::string&, const std::string&);
|
std::optional<std::string> handleMonitor(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleBind(const std::string&, const std::string&);
|
std::optional<std::string> handleBind(const std::string&, const std::string&);
|
||||||
std::optional<std::string> handleUnbind(const std::string&, const std::string&);
|
std::optional<std::string> handleUnbind(const std::string&, const std::string&);
|
||||||
|
@ -222,6 +291,7 @@ class CConfigManager {
|
||||||
bool firstExecDispatched = false;
|
bool firstExecDispatched = false;
|
||||||
bool m_bManualCrashInitiated = false;
|
bool m_bManualCrashInitiated = false;
|
||||||
std::deque<std::string> firstExecRequests;
|
std::deque<std::string> firstExecRequests;
|
||||||
|
std::deque<std::string> finalExecRequests;
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> m_vFailedPluginConfigValues; // for plugin values of unloaded plugins
|
std::vector<std::pair<std::string, std::string>> m_vFailedPluginConfigValues; // for plugin values of unloaded plugins
|
||||||
std::string m_szConfigErrors = "";
|
std::string m_szConfigErrors = "";
|
||||||
|
|
|
@ -130,6 +130,13 @@ animations {
|
||||||
animation = workspaces, 1, 6, default
|
animation = workspaces, 1, 6, default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Ref https://wiki.hyprland.org/Configuring/Workspace-Rules/
|
||||||
|
# "Smart gaps" / "No gaps when only"
|
||||||
|
# uncomment all three if you wish to use that.
|
||||||
|
# workspace = w[t1], gapsout:0, gapsin:0, border: 0, rounding:0
|
||||||
|
# workspace = w[tg1], gapsout:0, gapsin:0, border: 0, rounding:0
|
||||||
|
# workspace = f[1], gapsout:0, gapsin:0, border: 0, rounding:0
|
||||||
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
||||||
dwindle {
|
dwindle {
|
||||||
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
pseudotile = true # Master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
|
||||||
|
@ -182,9 +189,9 @@ device {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
####################
|
###################
|
||||||
### KEYBINDINGSS ###
|
### KEYBINDINGS ###
|
||||||
####################
|
###################
|
||||||
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Keywords/
|
# See https://wiki.hyprland.org/Configuring/Keywords/
|
||||||
$mainMod = SUPER # Sets "Windows" key as main modifier
|
$mainMod = SUPER # Sets "Windows" key as main modifier
|
||||||
|
@ -241,6 +248,19 @@ bind = $mainMod, mouse_up, workspace, e-1
|
||||||
bindm = $mainMod, mouse:272, movewindow
|
bindm = $mainMod, mouse:272, movewindow
|
||||||
bindm = $mainMod, mouse:273, resizewindow
|
bindm = $mainMod, mouse:273, resizewindow
|
||||||
|
|
||||||
|
# Laptop multimedia keys for volume and LCD brightness
|
||||||
|
bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
|
||||||
|
bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
||||||
|
bindel = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
||||||
|
bindel = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
|
||||||
|
bindel = ,XF86MonBrightnessUp, exec, brightnessctl s 10%+
|
||||||
|
bindel = ,XF86MonBrightnessDown, exec, brightnessctl s 10%-
|
||||||
|
|
||||||
|
# Requires playerctl
|
||||||
|
bindl = , XF86AudioNext, exec, playerctl next
|
||||||
|
bindl = , XF86AudioPause, exec, playerctl play-pause
|
||||||
|
bindl = , XF86AudioPlay, exec, playerctl play-pause
|
||||||
|
bindl = , XF86AudioPrev, exec, playerctl previous
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
### WINDOWS AND WORKSPACES ###
|
### WINDOWS AND WORKSPACES ###
|
||||||
|
@ -255,5 +275,9 @@ bindm = $mainMod, mouse:273, resizewindow
|
||||||
# Example windowrule v2
|
# Example windowrule v2
|
||||||
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
|
||||||
|
|
||||||
windowrulev2 = suppressevent maximize, class:.* # You'll probably like this.
|
# Ignore maximize requests from apps. You'll probably like this.
|
||||||
|
windowrulev2 = suppressevent maximize, class:.*
|
||||||
|
|
||||||
|
# Fix some dragging issues with XWayland
|
||||||
|
windowrulev2 = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0
|
||||||
)#";
|
)#";
|
||||||
|
|
|
@ -86,7 +86,7 @@ void CrashReporter::createAndSaveCrash(int sig) {
|
||||||
stderr.flush();
|
stderr.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
reportFd = open(reportPath.get_str(), O_WRONLY | O_CREAT, S_IRWXU);
|
reportFd = open(reportPath.get_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
|
||||||
if (reportFd < 0) {
|
if (reportFd < 0) {
|
||||||
exit_with_error("Failed to open crash report path for writing");
|
exit_with_error("Failed to open crash report path for writing");
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ static std::string formatToString(uint32_t drmFormat) {
|
||||||
static std::string availableModesForOutput(CMonitor* pMonitor, eHyprCtlOutputFormat format) {
|
static std::string availableModesForOutput(CMonitor* pMonitor, eHyprCtlOutputFormat format) {
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
||||||
for (auto& m : pMonitor->output->modes) {
|
for (auto const& m : pMonitor->output->modes) {
|
||||||
if (format == FORMAT_NORMAL)
|
if (format == FORMAT_NORMAL)
|
||||||
result += std::format("{}x{}@{:.2f}Hz ", m->pixelSize.x, m->pixelSize.y, m->refreshRate / 1000.0);
|
result += std::format("{}x{}@{:.2f}Hz ", m->pixelSize.x, m->pixelSize.y, m->refreshRate / 1000.0);
|
||||||
else
|
else
|
||||||
|
@ -71,7 +71,7 @@ static std::string availableModesForOutput(CMonitor* pMonitor, eHyprCtlOutputFor
|
||||||
|
|
||||||
std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer<CMonitor> m, eHyprCtlOutputFormat format) {
|
std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer<CMonitor> m, eHyprCtlOutputFormat format) {
|
||||||
std::string result;
|
std::string result;
|
||||||
if (!m->output || m->ID == -1ull)
|
if (!m->output || m->ID == -1)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||||
|
@ -103,6 +103,7 @@ std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer<CMonitor>
|
||||||
"focused": {},
|
"focused": {},
|
||||||
"dpmsStatus": {},
|
"dpmsStatus": {},
|
||||||
"vrr": {},
|
"vrr": {},
|
||||||
|
"solitary": "{:x}",
|
||||||
"activelyTearing": {},
|
"activelyTearing": {},
|
||||||
"disabled": {},
|
"disabled": {},
|
||||||
"currentFormat": "{}",
|
"currentFormat": "{}",
|
||||||
|
@ -114,19 +115,20 @@ std::string CHyprCtl::getMonitorData(Hyprutils::Memory::CSharedPointer<CMonitor>
|
||||||
m->activeWorkspaceID(), (!m->activeWorkspace ? "" : escapeJSONStrings(m->activeWorkspace->m_szName)), m->activeSpecialWorkspaceID(),
|
m->activeWorkspaceID(), (!m->activeWorkspace ? "" : escapeJSONStrings(m->activeWorkspace->m_szName)), m->activeSpecialWorkspaceID(),
|
||||||
escapeJSONStrings(m->activeSpecialWorkspace ? m->activeSpecialWorkspace->m_szName : ""), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y,
|
escapeJSONStrings(m->activeSpecialWorkspace ? m->activeSpecialWorkspace->m_szName : ""), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y,
|
||||||
(int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m == g_pCompositor->m_pLastMonitor ? "true" : "false"),
|
(int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m == g_pCompositor->m_pLastMonitor ? "true" : "false"),
|
||||||
(m->dpmsStatus ? "true" : "false"), (m->output->state->state().adaptiveSync ? "true" : "false"), (m->tearingState.activelyTearing ? "true" : "false"),
|
(m->dpmsStatus ? "true" : "false"), (m->output->state->state().adaptiveSync ? "true" : "false"), (uint64_t)m->solitaryClient.get(),
|
||||||
(m->m_bEnabled ? "false" : "true"), formatToString(m->output->state->state().drmFormat), availableModesForOutput(m.get(), format));
|
(m->tearingState.activelyTearing ? "true" : "false"), (m->m_bEnabled ? "false" : "true"), formatToString(m->output->state->state().drmFormat),
|
||||||
|
availableModesForOutput(m.get(), format));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
result += std::format("Monitor {} (ID {}):\n\t{}x{}@{:.5f} at {}x{}\n\tdescription: {}\n\tmake: {}\n\tmodel: {}\n\tserial: {}\n\tactive workspace: {} ({})\n\t"
|
result += std::format("Monitor {} (ID {}):\n\t{}x{}@{:.5f} at {}x{}\n\tdescription: {}\n\tmake: {}\n\tmodel: {}\n\tserial: {}\n\tactive workspace: {} ({})\n\t"
|
||||||
"special workspace: {} ({})\n\treserved: {} {} {} {}\n\tscale: {:.2f}\n\ttransform: {}\n\tfocused: {}\n\t"
|
"special workspace: {} ({})\n\treserved: {} {} {} {}\n\tscale: {:.2f}\n\ttransform: {}\n\tfocused: {}\n\t"
|
||||||
"dpmsStatus: {}\n\tvrr: {}\n\tactivelyTearing: {}\n\tdisabled: {}\n\tcurrentFormat: {}\n\tavailableModes: {}\n\n",
|
"dpmsStatus: {}\n\tvrr: {}\n\tsolitary: {:x}\n\tactivelyTearing: {}\n\tdisabled: {}\n\tcurrentFormat: {}\n\tavailableModes: {}\n\n",
|
||||||
m->szName, m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->szShortDescription,
|
m->szName, m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->szShortDescription,
|
||||||
m->output->make, m->output->model, m->output->serial, m->activeWorkspaceID(), (!m->activeWorkspace ? "" : m->activeWorkspace->m_szName),
|
m->output->make, m->output->model, m->output->serial, m->activeWorkspaceID(), (!m->activeWorkspace ? "" : m->activeWorkspace->m_szName),
|
||||||
m->activeSpecialWorkspaceID(), (m->activeSpecialWorkspace ? m->activeSpecialWorkspace->m_szName : ""), (int)m->vecReservedTopLeft.x,
|
m->activeSpecialWorkspaceID(), (m->activeSpecialWorkspace ? m->activeSpecialWorkspace->m_szName : ""), (int)m->vecReservedTopLeft.x,
|
||||||
(int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform,
|
(int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform,
|
||||||
(m == g_pCompositor->m_pLastMonitor ? "yes" : "no"), (int)m->dpmsStatus, m->output->state->state().adaptiveSync, m->tearingState.activelyTearing,
|
(m == g_pCompositor->m_pLastMonitor ? "yes" : "no"), (int)m->dpmsStatus, m->output->state->state().adaptiveSync, (uint64_t)m->solitaryClient.get(),
|
||||||
!m->m_bEnabled, formatToString(m->output->state->state().drmFormat), availableModesForOutput(m.get(), format));
|
m->tearingState.activelyTearing, !m->m_bEnabled, formatToString(m->output->state->state().drmFormat), availableModesForOutput(m.get(), format));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -146,7 +148,7 @@ std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||||
result += "[";
|
result += "[";
|
||||||
|
|
||||||
for (auto& m : allMonitors ? g_pCompositor->m_vRealMonitors : g_pCompositor->m_vMonitors) {
|
for (auto const& m : allMonitors ? g_pCompositor->m_vRealMonitors : g_pCompositor->m_vMonitors) {
|
||||||
result += CHyprCtl::getMonitorData(m, format);
|
result += CHyprCtl::getMonitorData(m, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,20 +156,11 @@ std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
|
|
||||||
result += "]";
|
result += "]";
|
||||||
} else {
|
} else {
|
||||||
for (auto& m : allMonitors ? g_pCompositor->m_vRealMonitors : g_pCompositor->m_vMonitors) {
|
for (auto const& m : allMonitors ? g_pCompositor->m_vRealMonitors : g_pCompositor->m_vMonitors) {
|
||||||
if (!m->output || m->ID == -1ull)
|
if (!m->output || m->ID == -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
result +=
|
result += CHyprCtl::getMonitorData(m, format);
|
||||||
std::format("Monitor {} (ID {}):\n\t{}x{}@{:.5f} at {}x{}\n\tdescription: {}\n\tmake: {}\n\tmodel: {}\n\tserial: {}\n\tactive workspace: {} ({})\n\t"
|
|
||||||
"special workspace: {} ({})\n\treserved: {} {} {} {}\n\tscale: {:.2f}\n\ttransform: {}\n\tfocused: {}\n\t"
|
|
||||||
"dpmsStatus: {}\n\tvrr: {}\n\tactivelyTearing: {}\n\tdisabled: {}\n\tcurrentFormat: {}\n\tavailableModes: {}\n\n",
|
|
||||||
m->szName, m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->szShortDescription,
|
|
||||||
m->output->make, m->output->model, m->output->serial, m->activeWorkspaceID(), (!m->activeWorkspace ? "" : m->activeWorkspace->m_szName),
|
|
||||||
m->activeSpecialWorkspaceID(), (m->activeSpecialWorkspace ? m->activeSpecialWorkspace->m_szName : ""), (int)m->vecReservedTopLeft.x,
|
|
||||||
(int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform,
|
|
||||||
(m == g_pCompositor->m_pLastMonitor ? "yes" : "no"), (int)m->dpmsStatus, (int)(m->output->state ? m->output->state->state().adaptiveSync : false),
|
|
||||||
m->tearingState.activelyTearing, !m->m_bEnabled, formatToString(m->output->state->state().drmFormat), availableModesForOutput(m.get(), format));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +265,7 @@ std::string clientsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||||
result += "[";
|
result += "[";
|
||||||
|
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||||
if (!w->m_bIsMapped && !g_pHyprCtl->m_sCurrentRequestParams.all)
|
if (!w->m_bIsMapped && !g_pHyprCtl->m_sCurrentRequestParams.all)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -283,7 +276,7 @@ std::string clientsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
|
|
||||||
result += "]";
|
result += "]";
|
||||||
} else {
|
} else {
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||||
if (!w->m_bIsMapped && !g_pHyprCtl->m_sCurrentRequestParams.all)
|
if (!w->m_bIsMapped && !g_pHyprCtl->m_sCurrentRequestParams.all)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -334,11 +327,13 @@ static std::string getWorkspaceRuleData(const SWorkspaceRule& r, eHyprCtlOutputF
|
||||||
const std::string rounding = (bool)(r.noRounding) ? std::format(",\n \"rounding\": {}", boolToString(!r.noRounding.value())) : "";
|
const std::string rounding = (bool)(r.noRounding) ? std::format(",\n \"rounding\": {}", boolToString(!r.noRounding.value())) : "";
|
||||||
const std::string decorate = (bool)(r.decorate) ? std::format(",\n \"decorate\": {}", boolToString(r.decorate.value())) : "";
|
const std::string decorate = (bool)(r.decorate) ? std::format(",\n \"decorate\": {}", boolToString(r.decorate.value())) : "";
|
||||||
const std::string shadow = (bool)(r.noShadow) ? std::format(",\n \"shadow\": {}", boolToString(!r.noShadow.value())) : "";
|
const std::string shadow = (bool)(r.noShadow) ? std::format(",\n \"shadow\": {}", boolToString(!r.noShadow.value())) : "";
|
||||||
|
const std::string defaultName = r.defaultName.has_value() ? std::format(",\n \"defaultName\": \"{}\"", escapeJSONStrings(r.defaultName.value())) : "";
|
||||||
|
|
||||||
std::string result = std::format(R"#({{
|
std::string result =
|
||||||
"workspaceString": "{}"{}{}{}{}{}{}{}{}
|
std::format(R"#({{
|
||||||
|
"workspaceString": "{}"{}{}{}{}{}{}{}{}{}{}{}
|
||||||
}})#",
|
}})#",
|
||||||
escapeJSONStrings(r.workspaceString), monitor, default_, persistent, gapsIn, gapsOut, borderSize, border, rounding, decorate, shadow);
|
escapeJSONStrings(r.workspaceString), monitor, default_, persistent, gapsIn, gapsOut, borderSize, border, rounding, decorate, shadow, defaultName);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
@ -356,9 +351,10 @@ static std::string getWorkspaceRuleData(const SWorkspaceRule& r, eHyprCtlOutputF
|
||||||
const std::string rounding = std::format("\trounding: {}\n", (bool)(r.noRounding) ? boolToString(!r.noRounding.value()) : "<unset>");
|
const std::string rounding = std::format("\trounding: {}\n", (bool)(r.noRounding) ? boolToString(!r.noRounding.value()) : "<unset>");
|
||||||
const std::string decorate = std::format("\tdecorate: {}\n", (bool)(r.decorate) ? boolToString(r.decorate.value()) : "<unset>");
|
const std::string decorate = std::format("\tdecorate: {}\n", (bool)(r.decorate) ? boolToString(r.decorate.value()) : "<unset>");
|
||||||
const std::string shadow = std::format("\tshadow: {}\n", (bool)(r.noShadow) ? boolToString(!r.noShadow.value()) : "<unset>");
|
const std::string shadow = std::format("\tshadow: {}\n", (bool)(r.noShadow) ? boolToString(!r.noShadow.value()) : "<unset>");
|
||||||
|
const std::string defaultName = std::format("\tdefaultName: {}\n", r.defaultName.value_or("<unset>"));
|
||||||
|
|
||||||
std::string result = std::format("Workspace rule {}:\n{}{}{}{}{}{}{}{}{}{}\n", escapeJSONStrings(r.workspaceString), monitor, default_, persistent, gapsIn, gapsOut,
|
std::string result = std::format("Workspace rule {}:\n{}{}{}{}{}{}{}{}{}{}{}\n", escapeJSONStrings(r.workspaceString), monitor, default_, persistent, gapsIn, gapsOut,
|
||||||
borderSize, border, rounding, decorate, shadow);
|
borderSize, border, rounding, decorate, shadow, defaultName);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -381,7 +377,7 @@ std::string workspacesRequest(eHyprCtlOutputFormat format, std::string request)
|
||||||
|
|
||||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||||
result += "[";
|
result += "[";
|
||||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
for (auto const& w : g_pCompositor->m_vWorkspaces) {
|
||||||
result += CHyprCtl::getWorkspaceData(w, format);
|
result += CHyprCtl::getWorkspaceData(w, format);
|
||||||
result += ",";
|
result += ",";
|
||||||
}
|
}
|
||||||
|
@ -389,7 +385,7 @@ std::string workspacesRequest(eHyprCtlOutputFormat format, std::string request)
|
||||||
trimTrailingComma(result);
|
trimTrailingComma(result);
|
||||||
result += "]";
|
result += "]";
|
||||||
} else {
|
} else {
|
||||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
for (auto const& w : g_pCompositor->m_vWorkspaces) {
|
||||||
result += CHyprCtl::getWorkspaceData(w, format);
|
result += CHyprCtl::getWorkspaceData(w, format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -401,7 +397,7 @@ std::string workspaceRulesRequest(eHyprCtlOutputFormat format, std::string reque
|
||||||
std::string result = "";
|
std::string result = "";
|
||||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||||
result += "[";
|
result += "[";
|
||||||
for (auto& r : g_pConfigManager->getAllWorkspaceRules()) {
|
for (auto const& r : g_pConfigManager->getAllWorkspaceRules()) {
|
||||||
result += getWorkspaceRuleData(r, format);
|
result += getWorkspaceRuleData(r, format);
|
||||||
result += ",";
|
result += ",";
|
||||||
}
|
}
|
||||||
|
@ -409,7 +405,7 @@ std::string workspaceRulesRequest(eHyprCtlOutputFormat format, std::string reque
|
||||||
trimTrailingComma(result);
|
trimTrailingComma(result);
|
||||||
result += "]";
|
result += "]";
|
||||||
} else {
|
} else {
|
||||||
for (auto& r : g_pConfigManager->getAllWorkspaceRules()) {
|
for (auto const& r : g_pConfigManager->getAllWorkspaceRules()) {
|
||||||
result += getWorkspaceRuleData(r, format);
|
result += getWorkspaceRuleData(r, format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,7 +433,7 @@ std::string layersRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||||
result += "{\n";
|
result += "{\n";
|
||||||
|
|
||||||
for (auto& mon : g_pCompositor->m_vMonitors) {
|
for (auto const& mon : g_pCompositor->m_vMonitors) {
|
||||||
result += std::format(
|
result += std::format(
|
||||||
R"#("{}": {{
|
R"#("{}": {{
|
||||||
"levels": {{
|
"levels": {{
|
||||||
|
@ -445,13 +441,13 @@ std::string layersRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
escapeJSONStrings(mon->szName));
|
escapeJSONStrings(mon->szName));
|
||||||
|
|
||||||
int layerLevel = 0;
|
int layerLevel = 0;
|
||||||
for (auto& level : mon->m_aLayerSurfaceLayers) {
|
for (auto const& level : mon->m_aLayerSurfaceLayers) {
|
||||||
result += std::format(
|
result += std::format(
|
||||||
R"#(
|
R"#(
|
||||||
"{}": [
|
"{}": [
|
||||||
)#",
|
)#",
|
||||||
layerLevel);
|
layerLevel);
|
||||||
for (auto& layer : level) {
|
for (auto const& layer : level) {
|
||||||
result += std::format(
|
result += std::format(
|
||||||
R"#( {{
|
R"#( {{
|
||||||
"address": "0x{:x}",
|
"address": "0x{:x}",
|
||||||
|
@ -484,14 +480,14 @@ std::string layersRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
result += "\n}\n";
|
result += "\n}\n";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (auto& mon : g_pCompositor->m_vMonitors) {
|
for (auto const& mon : g_pCompositor->m_vMonitors) {
|
||||||
result += std::format("Monitor {}:\n", mon->szName);
|
result += std::format("Monitor {}:\n", mon->szName);
|
||||||
int layerLevel = 0;
|
int layerLevel = 0;
|
||||||
static const std::array<std::string, 4> levelNames = {"background", "bottom", "top", "overlay"};
|
static const std::array<std::string, 4> levelNames = {"background", "bottom", "top", "overlay"};
|
||||||
for (auto& level : mon->m_aLayerSurfaceLayers) {
|
for (auto const& level : mon->m_aLayerSurfaceLayers) {
|
||||||
result += std::format("\tLayer level {} ({}):\n", layerLevel, levelNames[layerLevel]);
|
result += std::format("\tLayer level {} ({}):\n", layerLevel, levelNames[layerLevel]);
|
||||||
|
|
||||||
for (auto& layer : level) {
|
for (auto const& layer : level) {
|
||||||
result += std::format("\t\tLayer {:x}: xywh: {} {} {} {}, namespace: {}\n", (uintptr_t)layer.get(), layer->geometry.x, layer->geometry.y, layer->geometry.width,
|
result += std::format("\t\tLayer {:x}: xywh: {} {} {} {}, namespace: {}\n", (uintptr_t)layer.get(), layer->geometry.x, layer->geometry.y, layer->geometry.width,
|
||||||
layer->geometry.height, layer->szNamespace);
|
layer->geometry.height, layer->szNamespace);
|
||||||
}
|
}
|
||||||
|
@ -510,7 +506,7 @@ std::string layoutsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||||
result += "[";
|
result += "[";
|
||||||
|
|
||||||
for (auto& m : g_pLayoutManager->getAllLayoutNames()) {
|
for (auto const& m : g_pLayoutManager->getAllLayoutNames()) {
|
||||||
result += std::format(
|
result += std::format(
|
||||||
R"#(
|
R"#(
|
||||||
"{}",)#",
|
"{}",)#",
|
||||||
|
@ -520,7 +516,7 @@ std::string layoutsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
|
|
||||||
result += "\n]\n";
|
result += "\n]\n";
|
||||||
} else {
|
} else {
|
||||||
for (auto& m : g_pLayoutManager->getAllLayoutNames()) {
|
for (auto const& m : g_pLayoutManager->getAllLayoutNames()) {
|
||||||
result += std::format("{}\n", m);
|
result += std::format("{}\n", m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -557,7 +553,7 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
result += "{\n";
|
result += "{\n";
|
||||||
result += "\"mice\": [\n";
|
result += "\"mice\": [\n";
|
||||||
|
|
||||||
for (auto& m : g_pInputManager->m_vPointers) {
|
for (auto const& m : g_pInputManager->m_vPointers) {
|
||||||
result += std::format(
|
result += std::format(
|
||||||
R"#( {{
|
R"#( {{
|
||||||
"address": "0x{:x}",
|
"address": "0x{:x}",
|
||||||
|
@ -572,7 +568,7 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
result += "\n],\n";
|
result += "\n],\n";
|
||||||
|
|
||||||
result += "\"keyboards\": [\n";
|
result += "\"keyboards\": [\n";
|
||||||
for (auto& k : g_pInputManager->m_vKeyboards) {
|
for (auto const& k : g_pInputManager->m_vKeyboards) {
|
||||||
const auto KM = k->getActiveLayout();
|
const auto KM = k->getActiveLayout();
|
||||||
result += std::format(
|
result += std::format(
|
||||||
R"#( {{
|
R"#( {{
|
||||||
|
@ -596,7 +592,7 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
|
|
||||||
result += "\"tablets\": [\n";
|
result += "\"tablets\": [\n";
|
||||||
|
|
||||||
for (auto& d : g_pInputManager->m_vTabletPads) {
|
for (auto const& d : g_pInputManager->m_vTabletPads) {
|
||||||
result += std::format(
|
result += std::format(
|
||||||
R"#( {{
|
R"#( {{
|
||||||
"address": "0x{:x}",
|
"address": "0x{:x}",
|
||||||
|
@ -609,7 +605,7 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
(uintptr_t)d.get(), (uintptr_t)d->parent.get(), escapeJSONStrings(d->parent ? d->parent->hlName : ""));
|
(uintptr_t)d.get(), (uintptr_t)d->parent.get(), escapeJSONStrings(d->parent ? d->parent->hlName : ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& d : g_pInputManager->m_vTablets) {
|
for (auto const& d : g_pInputManager->m_vTablets) {
|
||||||
result += std::format(
|
result += std::format(
|
||||||
R"#( {{
|
R"#( {{
|
||||||
"address": "0x{:x}",
|
"address": "0x{:x}",
|
||||||
|
@ -618,7 +614,7 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
(uintptr_t)d.get(), escapeJSONStrings(d->hlName));
|
(uintptr_t)d.get(), escapeJSONStrings(d->hlName));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& d : g_pInputManager->m_vTabletTools) {
|
for (auto const& d : g_pInputManager->m_vTabletTools) {
|
||||||
result += std::format(
|
result += std::format(
|
||||||
R"#( {{
|
R"#( {{
|
||||||
"address": "0x{:x}",
|
"address": "0x{:x}",
|
||||||
|
@ -632,7 +628,7 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
|
|
||||||
result += "\"touch\": [\n";
|
result += "\"touch\": [\n";
|
||||||
|
|
||||||
for (auto& d : g_pInputManager->m_vTouches) {
|
for (auto const& d : g_pInputManager->m_vTouches) {
|
||||||
result += std::format(
|
result += std::format(
|
||||||
R"#( {{
|
R"#( {{
|
||||||
"address": "0x{:x}",
|
"address": "0x{:x}",
|
||||||
|
@ -646,7 +642,7 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
|
|
||||||
result += "\"switches\": [\n";
|
result += "\"switches\": [\n";
|
||||||
|
|
||||||
for (auto& d : g_pInputManager->m_lSwitches) {
|
for (auto const& d : g_pInputManager->m_lSwitches) {
|
||||||
result += std::format(
|
result += std::format(
|
||||||
R"#( {{
|
R"#( {{
|
||||||
"address": "0x{:x}",
|
"address": "0x{:x}",
|
||||||
|
@ -663,14 +659,14 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
} else {
|
} else {
|
||||||
result += "mice:\n";
|
result += "mice:\n";
|
||||||
|
|
||||||
for (auto& m : g_pInputManager->m_vPointers) {
|
for (auto const& m : g_pInputManager->m_vPointers) {
|
||||||
result += std::format("\tMouse at {:x}:\n\t\t{}\n\t\t\tdefault speed: {:.5f}\n", (uintptr_t)m.get(), m->hlName,
|
result += std::format("\tMouse at {:x}:\n\t\t{}\n\t\t\tdefault speed: {:.5f}\n", (uintptr_t)m.get(), m->hlName,
|
||||||
(m->aq() && m->aq()->getLibinputHandle() ? libinput_device_config_accel_get_default_speed(m->aq()->getLibinputHandle()) : 0.f));
|
(m->aq() && m->aq()->getLibinputHandle() ? libinput_device_config_accel_get_default_speed(m->aq()->getLibinputHandle()) : 0.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
result += "\n\nKeyboards:\n";
|
result += "\n\nKeyboards:\n";
|
||||||
|
|
||||||
for (auto& k : g_pInputManager->m_vKeyboards) {
|
for (auto const& k : g_pInputManager->m_vKeyboards) {
|
||||||
const auto KM = k->getActiveLayout();
|
const auto KM = k->getActiveLayout();
|
||||||
result += std::format("\tKeyboard at {:x}:\n\t\t{}\n\t\t\trules: r \"{}\", m \"{}\", l \"{}\", v \"{}\", o \"{}\"\n\t\t\tactive keymap: {}\n\t\t\tmain: {}\n",
|
result += std::format("\tKeyboard at {:x}:\n\t\t{}\n\t\t\trules: r \"{}\", m \"{}\", l \"{}\", v \"{}\", o \"{}\"\n\t\t\tactive keymap: {}\n\t\t\tmain: {}\n",
|
||||||
(uintptr_t)k.get(), k->hlName, k->currentRules.rules, k->currentRules.model, k->currentRules.layout, k->currentRules.variant,
|
(uintptr_t)k.get(), k->hlName, k->currentRules.rules, k->currentRules.model, k->currentRules.layout, k->currentRules.variant,
|
||||||
|
@ -679,27 +675,27 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
|
|
||||||
result += "\n\nTablets:\n";
|
result += "\n\nTablets:\n";
|
||||||
|
|
||||||
for (auto& d : g_pInputManager->m_vTabletPads) {
|
for (auto const& d : g_pInputManager->m_vTabletPads) {
|
||||||
result += std::format("\tTablet Pad at {:x} (belongs to {:x} -> {})\n", (uintptr_t)d.get(), (uintptr_t)d->parent.get(), d->parent ? d->parent->hlName : "");
|
result += std::format("\tTablet Pad at {:x} (belongs to {:x} -> {})\n", (uintptr_t)d.get(), (uintptr_t)d->parent.get(), d->parent ? d->parent->hlName : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& d : g_pInputManager->m_vTablets) {
|
for (auto const& d : g_pInputManager->m_vTablets) {
|
||||||
result += std::format("\tTablet at {:x}:\n\t\t{}\n\t\t\tsize: {}x{}mm\n", (uintptr_t)d.get(), d->hlName, d->aq()->physicalSize.x, d->aq()->physicalSize.y);
|
result += std::format("\tTablet at {:x}:\n\t\t{}\n\t\t\tsize: {}x{}mm\n", (uintptr_t)d.get(), d->hlName, d->aq()->physicalSize.x, d->aq()->physicalSize.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& d : g_pInputManager->m_vTabletTools) {
|
for (auto const& d : g_pInputManager->m_vTabletTools) {
|
||||||
result += std::format("\tTablet Tool at {:x}\n", (uintptr_t)d.get());
|
result += std::format("\tTablet Tool at {:x}\n", (uintptr_t)d.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
result += "\n\nTouch:\n";
|
result += "\n\nTouch:\n";
|
||||||
|
|
||||||
for (auto& d : g_pInputManager->m_vTouches) {
|
for (auto const& d : g_pInputManager->m_vTouches) {
|
||||||
result += std::format("\tTouch Device at {:x}:\n\t\t{}\n", (uintptr_t)d.get(), d->hlName);
|
result += std::format("\tTouch Device at {:x}:\n\t\t{}\n", (uintptr_t)d.get(), d->hlName);
|
||||||
}
|
}
|
||||||
|
|
||||||
result += "\n\nSwitches:\n";
|
result += "\n\nSwitches:\n";
|
||||||
|
|
||||||
for (auto& d : g_pInputManager->m_lSwitches) {
|
for (auto const& d : g_pInputManager->m_lSwitches) {
|
||||||
result += std::format("\tSwitch Device at {:x}:\n\t\t{}\n", (uintptr_t)&d, d.pDevice ? d.pDevice->getName() : "");
|
result += std::format("\tSwitch Device at {:x}:\n\t\t{}\n", (uintptr_t)&d, d.pDevice ? d.pDevice->getName() : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -712,21 +708,21 @@ std::string animationsRequest(eHyprCtlOutputFormat format, std::string request)
|
||||||
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
||||||
ret += "animations:\n";
|
ret += "animations:\n";
|
||||||
|
|
||||||
for (auto& ac : g_pConfigManager->getAnimationConfig()) {
|
for (auto const& ac : g_pConfigManager->getAnimationConfig()) {
|
||||||
ret += std::format("\n\tname: {}\n\t\toverriden: {}\n\t\tbezier: {}\n\t\tenabled: {}\n\t\tspeed: {:.2f}\n\t\tstyle: {}\n", ac.first, (int)ac.second.overridden,
|
ret += std::format("\n\tname: {}\n\t\toverriden: {}\n\t\tbezier: {}\n\t\tenabled: {}\n\t\tspeed: {:.2f}\n\t\tstyle: {}\n", ac.first, (int)ac.second.overridden,
|
||||||
ac.second.internalBezier, ac.second.internalEnabled, ac.second.internalSpeed, ac.second.internalStyle);
|
ac.second.internalBezier, ac.second.internalEnabled, ac.second.internalSpeed, ac.second.internalStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret += "beziers:\n";
|
ret += "beziers:\n";
|
||||||
|
|
||||||
for (auto& bz : g_pAnimationManager->getAllBeziers()) {
|
for (auto const& bz : g_pAnimationManager->getAllBeziers()) {
|
||||||
ret += std::format("\n\tname: {}\n", bz.first);
|
ret += std::format("\n\tname: {}\n", bz.first);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// json
|
// json
|
||||||
|
|
||||||
ret += "[[";
|
ret += "[[";
|
||||||
for (auto& ac : g_pConfigManager->getAnimationConfig()) {
|
for (auto const& ac : g_pConfigManager->getAnimationConfig()) {
|
||||||
ret += std::format(R"#(
|
ret += std::format(R"#(
|
||||||
{{
|
{{
|
||||||
"name": "{}",
|
"name": "{}",
|
||||||
|
@ -744,7 +740,7 @@ std::string animationsRequest(eHyprCtlOutputFormat format, std::string request)
|
||||||
|
|
||||||
ret += ",\n[";
|
ret += ",\n[";
|
||||||
|
|
||||||
for (auto& bz : g_pAnimationManager->getAllBeziers()) {
|
for (auto const& bz : g_pAnimationManager->getAllBeziers()) {
|
||||||
ret += std::format(R"#(
|
ret += std::format(R"#(
|
||||||
{{
|
{{
|
||||||
"name": "{}"
|
"name": "{}"
|
||||||
|
@ -778,11 +774,11 @@ std::string globalShortcutsRequest(eHyprCtlOutputFormat format, std::string requ
|
||||||
std::string ret = "";
|
std::string ret = "";
|
||||||
const auto SHORTCUTS = PROTO::globalShortcuts->getAllShortcuts();
|
const auto SHORTCUTS = PROTO::globalShortcuts->getAllShortcuts();
|
||||||
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
||||||
for (auto& sh : SHORTCUTS)
|
for (auto const& sh : SHORTCUTS)
|
||||||
ret += std::format("{}:{} -> {}\n", sh.appid, sh.id, sh.description);
|
ret += std::format("{}:{} -> {}\n", sh.appid, sh.id, sh.description);
|
||||||
} else {
|
} else {
|
||||||
ret += "[";
|
ret += "[";
|
||||||
for (auto& sh : SHORTCUTS) {
|
for (auto const& sh : SHORTCUTS) {
|
||||||
ret += std::format(R"#(
|
ret += std::format(R"#(
|
||||||
{{
|
{{
|
||||||
"name": "{}",
|
"name": "{}",
|
||||||
|
@ -800,7 +796,7 @@ std::string globalShortcutsRequest(eHyprCtlOutputFormat format, std::string requ
|
||||||
std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) {
|
std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
std::string ret = "";
|
std::string ret = "";
|
||||||
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
||||||
for (auto& kb : g_pKeybindManager->m_lKeybinds) {
|
for (auto const& kb : g_pKeybindManager->m_lKeybinds) {
|
||||||
ret += "bind";
|
ret += "bind";
|
||||||
if (kb.locked)
|
if (kb.locked)
|
||||||
ret += "l";
|
ret += "l";
|
||||||
|
@ -821,7 +817,7 @@ std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
} else {
|
} else {
|
||||||
// json
|
// json
|
||||||
ret += "[";
|
ret += "[";
|
||||||
for (auto& kb : g_pKeybindManager->m_lKeybinds) {
|
for (auto const& kb : g_pKeybindManager->m_lKeybinds) {
|
||||||
ret += std::format(
|
ret += std::format(
|
||||||
R"#(
|
R"#(
|
||||||
{{
|
{{
|
||||||
|
@ -857,37 +853,47 @@ std::string versionRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
std::replace(commitMsg.begin(), commitMsg.end(), '#', ' ');
|
std::replace(commitMsg.begin(), commitMsg.end(), '#', ' ');
|
||||||
|
|
||||||
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
if (format == eHyprCtlOutputFormat::FORMAT_NORMAL) {
|
||||||
std::string result = "Hyprland, built from branch " + std::string(GIT_BRANCH) + " at commit " + GIT_COMMIT_HASH + " " + GIT_DIRTY + " (" + commitMsg +
|
std::string result = std::format("Hyprland {} built from branch {} at commit {} {} ({}).\n"
|
||||||
").\nDate: " + GIT_COMMIT_DATE + "\nTag: " + GIT_TAG + ", commits: " + GIT_COMMITS + "\n\nflags: (if any)\n";
|
"Date: {}\n"
|
||||||
|
"Tag: {}, commits: {}\n"
|
||||||
|
"built against aquamarine {}\n\n\n",
|
||||||
|
HYPRLAND_VERSION, GIT_BRANCH, GIT_COMMIT_HASH, GIT_DIRTY, commitMsg, GIT_COMMIT_DATE, GIT_TAG, GIT_COMMITS, AQUAMARINE_VERSION);
|
||||||
|
|
||||||
|
#if (!defined(LEGACY_RENDERER) && !defined(ISDEBUG) && !defined(NO_XWAYLAND))
|
||||||
|
result += "no flags were set\n";
|
||||||
|
#else
|
||||||
|
result += "flags set:\n";
|
||||||
#ifdef LEGACY_RENDERER
|
#ifdef LEGACY_RENDERER
|
||||||
result += "legacyrenderer\n";
|
result += "legacyrenderer\n";
|
||||||
#endif
|
#endif
|
||||||
#ifndef ISDEBUG
|
#ifdef ISDEBUG
|
||||||
result += "debug\n";
|
result += "debug\n";
|
||||||
#endif
|
#endif
|
||||||
#ifdef NO_XWAYLAND
|
#ifdef NO_XWAYLAND
|
||||||
result += "no xwayland\n";
|
result += "no xwayland\n";
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
std::string result = std::format(
|
std::string result = std::format(
|
||||||
R"#({{
|
R"#({{
|
||||||
"branch": "{}",
|
"branch": "{}",
|
||||||
"commit": "{}",
|
"commit": "{}",
|
||||||
|
"version": "{}",
|
||||||
"dirty": {},
|
"dirty": {},
|
||||||
"commit_message": "{}",
|
"commit_message": "{}",
|
||||||
"commit_date": "{}",
|
"commit_date": "{}",
|
||||||
"tag": "{}",
|
"tag": "{}",
|
||||||
"commits": "{}",
|
"commits": "{}",
|
||||||
|
"buildAquamarine": "{}",
|
||||||
"flags": [)#",
|
"flags": [)#",
|
||||||
GIT_BRANCH, GIT_COMMIT_HASH, (strcmp(GIT_DIRTY, "dirty") == 0 ? "true" : "false"), escapeJSONStrings(commitMsg), GIT_COMMIT_DATE, GIT_TAG, GIT_COMMITS);
|
GIT_BRANCH, GIT_COMMIT_HASH, HYPRLAND_VERSION, (strcmp(GIT_DIRTY, "dirty") == 0 ? "true" : "false"), escapeJSONStrings(commitMsg), GIT_COMMIT_DATE, GIT_TAG,
|
||||||
|
GIT_COMMITS, AQUAMARINE_VERSION);
|
||||||
|
|
||||||
#ifdef LEGACY_RENDERER
|
#ifdef LEGACY_RENDERER
|
||||||
result += "\"legacyrenderer\",";
|
result += "\"legacyrenderer\",";
|
||||||
#endif
|
#endif
|
||||||
#ifndef ISDEBUG
|
#ifdef ISDEBUG
|
||||||
result += "\"debug\",";
|
result += "\"debug\",";
|
||||||
#endif
|
#endif
|
||||||
#ifdef NO_XWAYLAND
|
#ifdef NO_XWAYLAND
|
||||||
|
@ -935,11 +941,14 @@ std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request)
|
||||||
result += "os-release: " + execAndGet("cat /etc/os-release") + "\n\n";
|
result += "os-release: " + execAndGet("cat /etc/os-release") + "\n\n";
|
||||||
|
|
||||||
result += "plugins:\n";
|
result += "plugins:\n";
|
||||||
for (auto& pl : g_pPluginSystem->getAllPlugins()) {
|
if (g_pPluginSystem) {
|
||||||
|
for (auto const& pl : g_pPluginSystem->getAllPlugins()) {
|
||||||
result += std::format(" {} by {} ver {}\n", pl->name, pl->author, pl->version);
|
result += std::format(" {} by {} ver {}\n", pl->name, pl->author, pl->version);
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
result += "\tunknown: not runtime\n";
|
||||||
|
|
||||||
if (g_pHyprCtl->m_sCurrentRequestParams.sysInfoConfig) {
|
if (g_pHyprCtl && g_pHyprCtl->m_sCurrentRequestParams.sysInfoConfig) {
|
||||||
result += "\n======Config-Start======\n";
|
result += "\n======Config-Start======\n";
|
||||||
result += g_pConfigManager->getConfigString();
|
result += g_pConfigManager->getConfigString();
|
||||||
result += "\n======Config-End========\n";
|
result += "\n======Config-End========\n";
|
||||||
|
@ -962,20 +971,34 @@ std::string dispatchRequest(eHyprCtlOutputFormat format, std::string in) {
|
||||||
if (DISPATCHER == g_pKeybindManager->m_mDispatchers.end())
|
if (DISPATCHER == g_pKeybindManager->m_mDispatchers.end())
|
||||||
return "Invalid dispatcher";
|
return "Invalid dispatcher";
|
||||||
|
|
||||||
DISPATCHER->second(DISPATCHARG);
|
SDispatchResult res = DISPATCHER->second(DISPATCHARG);
|
||||||
|
|
||||||
Debug::log(LOG, "Hyprctl: dispatcher {} : {}", DISPATCHSTR, DISPATCHARG);
|
Debug::log(LOG, "Hyprctl: dispatcher {} : {}{}", DISPATCHSTR, DISPATCHARG, res.success ? "" : " -> " + res.error);
|
||||||
|
|
||||||
return "ok";
|
return res.success ? "ok" : res.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in) {
|
std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in) {
|
||||||
// get rid of the keyword keyword
|
// Find the first space to strip the keyword keyword
|
||||||
in = in.substr(in.find_first_of(' ') + 1);
|
auto const firstSpacePos = in.find_first_of(' ');
|
||||||
|
if (firstSpacePos == std::string::npos) // Handle the case where there's no space found (invalid input)
|
||||||
|
return "Invalid input: no space found";
|
||||||
|
|
||||||
const auto COMMAND = in.substr(0, in.find_first_of(' '));
|
// Strip the keyword
|
||||||
|
in = in.substr(firstSpacePos + 1);
|
||||||
|
|
||||||
const auto VALUE = in.substr(in.find_first_of(' ') + 1);
|
// Find the next space for the COMMAND and VALUE
|
||||||
|
auto const secondSpacePos = in.find_first_of(' ');
|
||||||
|
if (secondSpacePos == std::string::npos) // Handle the case where there's no second space (invalid input)
|
||||||
|
return "Invalid input: command and value not properly formatted";
|
||||||
|
|
||||||
|
// Extract COMMAND and VALUE
|
||||||
|
const auto COMMAND = in.substr(0, secondSpacePos);
|
||||||
|
const auto VALUE = in.substr(secondSpacePos + 1);
|
||||||
|
|
||||||
|
// If COMMAND is empty, handle accordingly
|
||||||
|
if (COMMAND.empty())
|
||||||
|
return "Invalid input: command is empty";
|
||||||
|
|
||||||
std::string retval = g_pConfigManager->parseKeyword(COMMAND, VALUE);
|
std::string retval = g_pConfigManager->parseKeyword(COMMAND, VALUE);
|
||||||
|
|
||||||
|
@ -1006,7 +1029,7 @@ std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in) {
|
||||||
|
|
||||||
// decorations will probably need a repaint
|
// decorations will probably need a repaint
|
||||||
if (COMMAND.contains("decoration:") || COMMAND.contains("border") || COMMAND == "workspace" || COMMAND.contains("zoom_factor") || COMMAND == "source") {
|
if (COMMAND.contains("decoration:") || COMMAND.contains("border") || COMMAND == "workspace" || COMMAND.contains("zoom_factor") || COMMAND == "source") {
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||||
g_pHyprRenderer->damageMonitor(m.get());
|
g_pHyprRenderer->damageMonitor(m.get());
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||||
}
|
}
|
||||||
|
@ -1127,15 +1150,9 @@ std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string requ
|
||||||
const auto KB = vars[1];
|
const auto KB = vars[1];
|
||||||
const auto CMD = vars[2];
|
const auto CMD = vars[2];
|
||||||
|
|
||||||
// get kb
|
SP<IKeyboard> pKeyboard;
|
||||||
const auto PKEYBOARD = std::find_if(g_pInputManager->m_vKeyboards.begin(), g_pInputManager->m_vKeyboards.end(),
|
|
||||||
[&](const auto& other) { return other->hlName == g_pInputManager->deviceNameToInternalString(KB); });
|
|
||||||
|
|
||||||
if (PKEYBOARD == g_pInputManager->m_vKeyboards.end())
|
|
||||||
return "device not found";
|
|
||||||
|
|
||||||
const auto KEEB = *PKEYBOARD;
|
|
||||||
|
|
||||||
|
auto updateKeyboard = [](const SP<IKeyboard> KEEB, const std::string& CMD) -> std::optional<std::string> {
|
||||||
const auto LAYOUTS = xkb_keymap_num_layouts(KEEB->xkbKeymap);
|
const auto LAYOUTS = xkb_keymap_num_layouts(KEEB->xkbKeymap);
|
||||||
xkb_layout_index_t activeLayout = 0;
|
xkb_layout_index_t activeLayout = 0;
|
||||||
while (activeLayout < LAYOUTS) {
|
while (activeLayout < LAYOUTS) {
|
||||||
|
@ -1162,6 +1179,43 @@ std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string requ
|
||||||
KEEB->updateModifiers(KEEB->modifiersState.depressed, KEEB->modifiersState.latched, KEEB->modifiersState.locked, requestedLayout);
|
KEEB->updateModifiers(KEEB->modifiersState.depressed, KEEB->modifiersState.latched, KEEB->modifiersState.locked, requestedLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (KB == "main" || KB == "active" || KB == "current") {
|
||||||
|
for (auto const& k : g_pInputManager->m_vKeyboards) {
|
||||||
|
if (!k->active)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pKeyboard = k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (KB == "all") {
|
||||||
|
std::string result = "";
|
||||||
|
for (auto const& k : g_pInputManager->m_vKeyboards) {
|
||||||
|
auto res = updateKeyboard(k, CMD);
|
||||||
|
if (res.has_value())
|
||||||
|
result += *res + "\n";
|
||||||
|
}
|
||||||
|
return result.empty() ? "ok" : result;
|
||||||
|
} else {
|
||||||
|
auto k = std::find_if(g_pInputManager->m_vKeyboards.begin(), g_pInputManager->m_vKeyboards.end(),
|
||||||
|
[&](const auto& other) { return other->hlName == g_pInputManager->deviceNameToInternalString(KB); });
|
||||||
|
|
||||||
|
if (k == g_pInputManager->m_vKeyboards.end())
|
||||||
|
return "device not found";
|
||||||
|
|
||||||
|
pKeyboard = *k;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pKeyboard)
|
||||||
|
return "no device";
|
||||||
|
|
||||||
|
auto result = updateKeyboard(pKeyboard, CMD);
|
||||||
|
|
||||||
|
if (result.has_value())
|
||||||
|
return *result;
|
||||||
|
|
||||||
return "ok";
|
return "ok";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1286,7 +1340,7 @@ std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) {
|
||||||
g_pCompositor->focusWindow(PLASTWINDOW);
|
g_pCompositor->focusWindow(PLASTWINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors)
|
for (auto const& m : g_pCompositor->m_vMonitors)
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||||
|
|
||||||
return "ok";
|
return "ok";
|
||||||
|
@ -1359,7 +1413,7 @@ std::string decorationRequest(eHyprCtlOutputFormat format, std::string request)
|
||||||
std::string result = "";
|
std::string result = "";
|
||||||
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
|
||||||
result += "[";
|
result += "[";
|
||||||
for (auto& wd : PWINDOW->m_dWindowDecorations) {
|
for (auto const& wd : PWINDOW->m_dWindowDecorations) {
|
||||||
result += "{\n\"decorationName\": \"" + wd->getDisplayName() + "\",\n\"priority\": " + std::to_string(wd->getPositioningInfo().priority) + "\n},";
|
result += "{\n\"decorationName\": \"" + wd->getDisplayName() + "\",\n\"priority\": " + std::to_string(wd->getPositioningInfo().priority) + "\n},";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1367,7 +1421,7 @@ std::string decorationRequest(eHyprCtlOutputFormat format, std::string request)
|
||||||
result += "]";
|
result += "]";
|
||||||
} else {
|
} else {
|
||||||
result = +"Decoration\tPriority\n";
|
result = +"Decoration\tPriority\n";
|
||||||
for (auto& wd : PWINDOW->m_dWindowDecorations) {
|
for (auto const& wd : PWINDOW->m_dWindowDecorations) {
|
||||||
result += wd->getDisplayName() + "\t" + std::to_string(wd->getPositioningInfo().priority) + "\n";
|
result += wd->getDisplayName() + "\t" + std::to_string(wd->getPositioningInfo().priority) + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1386,7 +1440,7 @@ std::string dispatchOutput(eHyprCtlOutputFormat format, std::string request) {
|
||||||
bool added = false;
|
bool added = false;
|
||||||
|
|
||||||
if (!vars[3].empty()) {
|
if (!vars[3].empty()) {
|
||||||
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
for (auto const& m : g_pCompositor->m_vRealMonitors) {
|
||||||
if (m->szName == vars[3])
|
if (m->szName == vars[3])
|
||||||
return "Name already taken";
|
return "Name already taken";
|
||||||
}
|
}
|
||||||
|
@ -1396,7 +1450,7 @@ std::string dispatchOutput(eHyprCtlOutputFormat format, std::string request) {
|
||||||
if (g_pCompositor->getMonitorFromName(vars[3]))
|
if (g_pCompositor->getMonitorFromName(vars[3]))
|
||||||
return "A real monitor already uses that name.";
|
return "A real monitor already uses that name.";
|
||||||
|
|
||||||
for (auto& impl : g_pCompositor->m_pAqBackend->getImplementations() | std::views::reverse) {
|
for (auto const& impl : g_pCompositor->m_pAqBackend->getImplementations() | std::views::reverse) {
|
||||||
auto type = impl->type();
|
auto type = impl->type();
|
||||||
|
|
||||||
if (type == Aquamarine::AQ_BACKEND_HEADLESS && (vars[2] == "headless" || vars[2] == "auto")) {
|
if (type == Aquamarine::AQ_BACKEND_HEADLESS && (vars[2] == "headless" || vars[2] == "auto")) {
|
||||||
|
@ -1464,7 +1518,7 @@ std::string dispatchPlugin(eHyprCtlOutputFormat format, std::string request) {
|
||||||
return "no plugins loaded";
|
return "no plugins loaded";
|
||||||
|
|
||||||
std::string list = "";
|
std::string list = "";
|
||||||
for (auto& p : PLUGINS) {
|
for (auto const& p : PLUGINS) {
|
||||||
list += std::format("\nPlugin {} by {}:\n\tHandle: {:x}\n\tVersion: {}\n\tDescription: {}\n", p->name, p->author, (uintptr_t)p->m_pHandle, p->version, p->description);
|
list += std::format("\nPlugin {} by {}:\n\tHandle: {:x}\n\tVersion: {}\n\tDescription: {}\n", p->name, p->author, (uintptr_t)p->m_pHandle, p->version, p->description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1561,6 +1615,29 @@ std::string getIsLocked(eHyprCtlOutputFormat format, std::string request) {
|
||||||
return lockedStr;
|
return lockedStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getDescriptions(eHyprCtlOutputFormat format, std::string request) {
|
||||||
|
std::string json = "{";
|
||||||
|
const auto& DESCS = g_pConfigManager->getAllDescriptions();
|
||||||
|
|
||||||
|
for (const auto& d : DESCS) {
|
||||||
|
json += d.jsonify() + ",\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
json.pop_back();
|
||||||
|
json.pop_back();
|
||||||
|
|
||||||
|
json += "}\n";
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string submapRequest(eHyprCtlOutputFormat format, std::string request) {
|
||||||
|
std::string submap = g_pKeybindManager->getCurrentSubmap();
|
||||||
|
if (submap.empty())
|
||||||
|
submap = "default";
|
||||||
|
|
||||||
|
return format == FORMAT_JSON ? std::format("{{\"{}\"}}\n", escapeJSONStrings(submap)) : (submap + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
CHyprCtl::CHyprCtl() {
|
CHyprCtl::CHyprCtl() {
|
||||||
registerCommand(SHyprCtlCommand{"workspaces", true, workspacesRequest});
|
registerCommand(SHyprCtlCommand{"workspaces", true, workspacesRequest});
|
||||||
registerCommand(SHyprCtlCommand{"workspacerules", true, workspaceRulesRequest});
|
registerCommand(SHyprCtlCommand{"workspacerules", true, workspaceRulesRequest});
|
||||||
|
@ -1581,6 +1658,8 @@ CHyprCtl::CHyprCtl() {
|
||||||
registerCommand(SHyprCtlCommand{"layouts", true, layoutsRequest});
|
registerCommand(SHyprCtlCommand{"layouts", true, layoutsRequest});
|
||||||
registerCommand(SHyprCtlCommand{"configerrors", true, configErrorsRequest});
|
registerCommand(SHyprCtlCommand{"configerrors", true, configErrorsRequest});
|
||||||
registerCommand(SHyprCtlCommand{"locked", true, getIsLocked});
|
registerCommand(SHyprCtlCommand{"locked", true, getIsLocked});
|
||||||
|
registerCommand(SHyprCtlCommand{"descriptions", true, getDescriptions});
|
||||||
|
registerCommand(SHyprCtlCommand{"submap", true, submapRequest});
|
||||||
|
|
||||||
registerCommand(SHyprCtlCommand{"monitors", false, monitorsRequest});
|
registerCommand(SHyprCtlCommand{"monitors", false, monitorsRequest});
|
||||||
registerCommand(SHyprCtlCommand{"reload", false, reloadRequest});
|
registerCommand(SHyprCtlCommand{"reload", false, reloadRequest});
|
||||||
|
@ -1657,7 +1736,7 @@ std::string CHyprCtl::getReply(std::string request) {
|
||||||
std::string result = "";
|
std::string result = "";
|
||||||
|
|
||||||
// parse exact cmds first, then non-exact.
|
// parse exact cmds first, then non-exact.
|
||||||
for (auto& cmd : m_vCommands) {
|
for (auto const& cmd : m_vCommands) {
|
||||||
if (!cmd->exact)
|
if (!cmd->exact)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1668,7 +1747,7 @@ std::string CHyprCtl::getReply(std::string request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.empty())
|
if (result.empty())
|
||||||
for (auto& cmd : m_vCommands) {
|
for (auto const& cmd : m_vCommands) {
|
||||||
if (cmd->exact)
|
if (cmd->exact)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1699,7 +1778,7 @@ std::string CHyprCtl::getReply(std::string request) {
|
||||||
rd.blurFBDirty = true;
|
rd.blurFBDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||||
g_pHyprRenderer->damageMonitor(m.get());
|
g_pHyprRenderer->damageMonitor(m.get());
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
#include "../helpers/MiscFunctions.hpp"
|
#include "../helpers/MiscFunctions.hpp"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
// exposed for main.cpp
|
||||||
|
std::string systemInfoRequest(eHyprCtlOutputFormat format, std::string request);
|
||||||
|
std::string versionRequest(eHyprCtlOutputFormat format, std::string request);
|
||||||
|
|
||||||
class CHyprCtl {
|
class CHyprCtl {
|
||||||
public:
|
public:
|
||||||
CHyprCtl();
|
CHyprCtl();
|
||||||
|
|
|
@ -7,8 +7,8 @@ CHyprDebugOverlay::CHyprDebugOverlay() {
|
||||||
m_pTexture = makeShared<CTexture>();
|
m_pTexture = makeShared<CTexture>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float µs) {
|
void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float durationUs) {
|
||||||
m_dLastRenderTimes.push_back(µs / 1000.f);
|
m_dLastRenderTimes.push_back(durationUs / 1000.f);
|
||||||
|
|
||||||
if (m_dLastRenderTimes.size() > (long unsigned int)pMonitor->refreshRate)
|
if (m_dLastRenderTimes.size() > (long unsigned int)pMonitor->refreshRate)
|
||||||
m_dLastRenderTimes.pop_front();
|
m_dLastRenderTimes.pop_front();
|
||||||
|
@ -17,8 +17,8 @@ void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float µs) {
|
||||||
m_pMonitor = pMonitor;
|
m_pMonitor = pMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprMonitorDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float µs) {
|
void CHyprMonitorDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float durationUs) {
|
||||||
m_dLastRenderTimesNoOverlay.push_back(µs / 1000.f);
|
m_dLastRenderTimesNoOverlay.push_back(durationUs / 1000.f);
|
||||||
|
|
||||||
if (m_dLastRenderTimesNoOverlay.size() > (long unsigned int)pMonitor->refreshRate)
|
if (m_dLastRenderTimesNoOverlay.size() > (long unsigned int)pMonitor->refreshRate)
|
||||||
m_dLastRenderTimesNoOverlay.pop_front();
|
m_dLastRenderTimesNoOverlay.pop_front();
|
||||||
|
@ -57,7 +57,7 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
||||||
float avgFrametime = 0;
|
float avgFrametime = 0;
|
||||||
float maxFrametime = 0;
|
float maxFrametime = 0;
|
||||||
float minFrametime = 9999;
|
float minFrametime = 9999;
|
||||||
for (auto& ft : m_dLastFrametimes) {
|
for (auto const& ft : m_dLastFrametimes) {
|
||||||
if (ft > maxFrametime)
|
if (ft > maxFrametime)
|
||||||
maxFrametime = ft;
|
maxFrametime = ft;
|
||||||
if (ft < minFrametime)
|
if (ft < minFrametime)
|
||||||
|
@ -70,7 +70,7 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
||||||
float avgRenderTime = 0;
|
float avgRenderTime = 0;
|
||||||
float maxRenderTime = 0;
|
float maxRenderTime = 0;
|
||||||
float minRenderTime = 9999;
|
float minRenderTime = 9999;
|
||||||
for (auto& rt : m_dLastRenderTimes) {
|
for (auto const& rt : m_dLastRenderTimes) {
|
||||||
if (rt > maxRenderTime)
|
if (rt > maxRenderTime)
|
||||||
maxRenderTime = rt;
|
maxRenderTime = rt;
|
||||||
if (rt < minRenderTime)
|
if (rt < minRenderTime)
|
||||||
|
@ -83,7 +83,7 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
||||||
float avgRenderTimeNoOverlay = 0;
|
float avgRenderTimeNoOverlay = 0;
|
||||||
float maxRenderTimeNoOverlay = 0;
|
float maxRenderTimeNoOverlay = 0;
|
||||||
float minRenderTimeNoOverlay = 9999;
|
float minRenderTimeNoOverlay = 9999;
|
||||||
for (auto& rt : m_dLastRenderTimesNoOverlay) {
|
for (auto const& rt : m_dLastRenderTimesNoOverlay) {
|
||||||
if (rt > maxRenderTimeNoOverlay)
|
if (rt > maxRenderTimeNoOverlay)
|
||||||
maxRenderTimeNoOverlay = rt;
|
maxRenderTimeNoOverlay = rt;
|
||||||
if (rt < minRenderTimeNoOverlay)
|
if (rt < minRenderTimeNoOverlay)
|
||||||
|
@ -96,7 +96,7 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
||||||
float avgAnimMgrTick = 0;
|
float avgAnimMgrTick = 0;
|
||||||
float maxAnimMgrTick = 0;
|
float maxAnimMgrTick = 0;
|
||||||
float minAnimMgrTick = 9999;
|
float minAnimMgrTick = 9999;
|
||||||
for (auto& at : m_dLastAnimationTicks) {
|
for (auto const& at : m_dLastAnimationTicks) {
|
||||||
if (at > maxAnimMgrTick)
|
if (at > maxAnimMgrTick)
|
||||||
maxAnimMgrTick = at;
|
maxAnimMgrTick = at;
|
||||||
if (at < minAnimMgrTick)
|
if (at < minAnimMgrTick)
|
||||||
|
@ -188,12 +188,12 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
||||||
return posY - offset;
|
return posY - offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDebugOverlay::renderData(CMonitor* pMonitor, float µs) {
|
void CHyprDebugOverlay::renderData(CMonitor* pMonitor, float durationUs) {
|
||||||
m_mMonitorOverlays[pMonitor].renderData(pMonitor, µs);
|
m_mMonitorOverlays[pMonitor].renderData(pMonitor, durationUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float µs) {
|
void CHyprDebugOverlay::renderDataNoOverlay(CMonitor* pMonitor, float durationUs) {
|
||||||
m_mMonitorOverlays[pMonitor].renderDataNoOverlay(pMonitor, µs);
|
m_mMonitorOverlays[pMonitor].renderDataNoOverlay(pMonitor, durationUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprDebugOverlay::frameData(CMonitor* pMonitor) {
|
void CHyprDebugOverlay::frameData(CMonitor* pMonitor) {
|
||||||
|
@ -217,7 +217,7 @@ void CHyprDebugOverlay::draw() {
|
||||||
|
|
||||||
// draw the things
|
// draw the things
|
||||||
int offsetY = 0;
|
int offsetY = 0;
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||||
offsetY += m_mMonitorOverlays[m.get()].draw(offsetY);
|
offsetY += m_mMonitorOverlays[m.get()].draw(offsetY);
|
||||||
offsetY += 5; // for padding between mons
|
offsetY += 5; // for padding between mons
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,8 @@ class CHyprMonitorDebugOverlay {
|
||||||
public:
|
public:
|
||||||
int draw(int offset);
|
int draw(int offset);
|
||||||
|
|
||||||
void renderData(CMonitor* pMonitor, float µs);
|
void renderData(CMonitor* pMonitor, float durationUs);
|
||||||
void renderDataNoOverlay(CMonitor* pMonitor, float µs);
|
void renderDataNoOverlay(CMonitor* pMonitor, float durationUs);
|
||||||
void frameData(CMonitor* pMonitor);
|
void frameData(CMonitor* pMonitor);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -33,8 +33,8 @@ class CHyprDebugOverlay {
|
||||||
public:
|
public:
|
||||||
CHyprDebugOverlay();
|
CHyprDebugOverlay();
|
||||||
void draw();
|
void draw();
|
||||||
void renderData(CMonitor*, float µs);
|
void renderData(CMonitor*, float durationUs);
|
||||||
void renderDataNoOverlay(CMonitor*, float µs);
|
void renderDataNoOverlay(CMonitor*, float durationUs);
|
||||||
void frameData(CMonitor*);
|
void frameData(CMonitor*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -37,14 +37,14 @@ CHyprNotificationOverlay::~CHyprNotificationOverlay() {
|
||||||
void CHyprNotificationOverlay::addNotification(const std::string& text, const CColor& color, const float timeMs, const eIcons icon, const float fontSize) {
|
void CHyprNotificationOverlay::addNotification(const std::string& text, const CColor& color, const float timeMs, const eIcons icon, const float fontSize) {
|
||||||
const auto PNOTIF = m_dNotifications.emplace_back(std::make_unique<SNotification>()).get();
|
const auto PNOTIF = m_dNotifications.emplace_back(std::make_unique<SNotification>()).get();
|
||||||
|
|
||||||
PNOTIF->text = text;
|
PNOTIF->text = icon != eIcons::ICON_NONE ? " " + text /* tiny bit of padding otherwise icon touches text */ : text;
|
||||||
PNOTIF->color = color == CColor(0) ? ICONS_COLORS[icon] : color;
|
PNOTIF->color = color == CColor(0) ? ICONS_COLORS[icon] : color;
|
||||||
PNOTIF->started.reset();
|
PNOTIF->started.reset();
|
||||||
PNOTIF->timeMs = timeMs;
|
PNOTIF->timeMs = timeMs;
|
||||||
PNOTIF->icon = icon;
|
PNOTIF->icon = icon;
|
||||||
PNOTIF->fontSize = fontSize;
|
PNOTIF->fontSize = fontSize;
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||||
g_pCompositor->scheduleFrameForMonitor(m.get());
|
g_pCompositor->scheduleFrameForMonitor(m.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) {
|
||||||
const auto iconBackendID = iconBackendFromLayout(layout);
|
const auto iconBackendID = iconBackendFromLayout(layout);
|
||||||
const auto PBEZIER = g_pAnimationManager->getBezier("default");
|
const auto PBEZIER = g_pAnimationManager->getBezier("default");
|
||||||
|
|
||||||
for (auto& notif : m_dNotifications) {
|
for (auto const& notif : m_dNotifications) {
|
||||||
const auto ICONPADFORNOTIF = notif->icon == ICON_NONE ? 0 : ICON_PAD;
|
const auto ICONPADFORNOTIF = notif->icon == ICON_NONE ? 0 : ICON_PAD;
|
||||||
const auto FONTSIZE = std::clamp((int)(notif->fontSize * ((pMonitor->vecPixelSize.x * SCALE) / 1920.f)), 8, 40);
|
const auto FONTSIZE = std::clamp((int)(notif->fontSize * ((pMonitor->vecPixelSize.x * SCALE) / 1920.f)), 8, 40);
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,14 @@
|
||||||
#include "RollingLogFollow.hpp"
|
#include "RollingLogFollow.hpp"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <print>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
void Debug::init(const std::string& IS) {
|
void Debug::init(const std::string& IS) {
|
||||||
logFile = IS + (ISDEBUG ? "/hyprlandd.log" : "/hyprland.log");
|
logFile = IS + (ISDEBUG ? "/hyprlandd.log" : "/hyprland.log");
|
||||||
logOfs.open(logFile, std::ios::out | std::ios::app);
|
logOfs.open(logFile, std::ios::out | std::ios::app);
|
||||||
|
auto handle = logOfs.native_handle();
|
||||||
|
fcntl(handle, F_SETFD, FD_CLOEXEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debug::close() {
|
void Debug::close() {
|
||||||
|
@ -66,5 +69,5 @@ void Debug::log(LogLevel level, std::string str) {
|
||||||
|
|
||||||
// log it to the stdout too.
|
// log it to the stdout too.
|
||||||
if (!disableStdout)
|
if (!disableStdout)
|
||||||
std::cout << ((coloredLogs && !**coloredLogs) ? str : coloredStr) << "\n";
|
std::println("{}", ((coloredLogs && !**coloredLogs) ? str : coloredStr));
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,8 @@ namespace Debug {
|
||||||
// print date and time to the ofs
|
// print date and time to the ofs
|
||||||
if (disableTime && !**disableTime) {
|
if (disableTime && !**disableTime) {
|
||||||
#ifndef _LIBCPP_VERSION
|
#ifndef _LIBCPP_VERSION
|
||||||
const auto zt = std::chrono::zoned_time{std::chrono::current_zone(), std::chrono::system_clock::now()};
|
static auto current_zone = std::chrono::current_zone();
|
||||||
|
const auto zt = std::chrono::zoned_time{current_zone, std::chrono::system_clock::now()};
|
||||||
const auto hms = std::chrono::hh_mm_ss{zt.get_local_time() - std::chrono::floor<std::chrono::days>(zt.get_local_time())};
|
const auto hms = std::chrono::hh_mm_ss{zt.get_local_time() - std::chrono::floor<std::chrono::days>(zt.get_local_time())};
|
||||||
#else
|
#else
|
||||||
// TODO: current clang 17 does not support `zoned_time`, remove this once clang 19 is ready
|
// TODO: current clang 17 does not support `zoned_time`, remove this once clang 19 is ready
|
||||||
|
@ -72,6 +73,5 @@ namespace Debug {
|
||||||
logMsg += std::vformat(fmt.get(), std::make_format_args(args...));
|
logMsg += std::vformat(fmt.get(), std::make_format_args(args...));
|
||||||
|
|
||||||
log(level, logMsg);
|
log(level, logMsg);
|
||||||
logMutex.unlock();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "includes.hpp"
|
#include "includes.hpp"
|
||||||
#include "debug/Log.hpp"
|
#include "debug/Log.hpp"
|
||||||
#include "helpers/WLListener.hpp"
|
|
||||||
#include "helpers/Color.hpp"
|
#include "helpers/Color.hpp"
|
||||||
#include "macros.hpp"
|
#include "macros.hpp"
|
||||||
#include "desktop/DesktopTypes.hpp"
|
#include "desktop/DesktopTypes.hpp"
|
||||||
|
|
|
@ -71,6 +71,12 @@ CLayerSurface::~CLayerSurface() {
|
||||||
surface->unassign();
|
surface->unassign();
|
||||||
g_pHyprRenderer->makeEGLCurrent();
|
g_pHyprRenderer->makeEGLCurrent();
|
||||||
std::erase_if(g_pHyprOpenGL->m_mLayerFramebuffers, [&](const auto& other) { return other.first.expired() || other.first.lock() == self.lock(); });
|
std::erase_if(g_pHyprOpenGL->m_mLayerFramebuffers, [&](const auto& other) { return other.first.expired() || other.first.lock() == self.lock(); });
|
||||||
|
|
||||||
|
for (auto const& mon : g_pCompositor->m_vRealMonitors) {
|
||||||
|
for (auto& lsl : mon->m_aLayerSurfaceLayers) {
|
||||||
|
std::erase_if(lsl, [this](auto& ls) { return ls.expired() || ls.get() == this; });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLayerSurface::onDestroy() {
|
void CLayerSurface::onDestroy() {
|
||||||
|
@ -360,7 +366,7 @@ void CLayerSurface::applyRules() {
|
||||||
xray = -1;
|
xray = -1;
|
||||||
animationStyle.reset();
|
animationStyle.reset();
|
||||||
|
|
||||||
for (auto& rule : g_pConfigManager->getMatchingRules(self.lock())) {
|
for (auto const& rule : g_pConfigManager->getMatchingRules(self.lock())) {
|
||||||
if (rule.rule == "noanim")
|
if (rule.rule == "noanim")
|
||||||
noAnimations = true;
|
noAnimations = true;
|
||||||
else if (rule.rule == "blur")
|
else if (rule.rule == "blur")
|
||||||
|
@ -388,6 +394,11 @@ void CLayerSurface::applyRules() {
|
||||||
} else if (rule.rule.starts_with("animation")) {
|
} else if (rule.rule.starts_with("animation")) {
|
||||||
CVarList vars{rule.rule, 2, 's'};
|
CVarList vars{rule.rule, 2, 's'};
|
||||||
animationStyle = vars[1];
|
animationStyle = vars[1];
|
||||||
|
} else if (rule.rule.starts_with("order")) {
|
||||||
|
CVarList vars{rule.rule, 2, 's'};
|
||||||
|
try {
|
||||||
|
order = std::stoi(vars[1]);
|
||||||
|
} catch (...) { Debug::log(ERR, "Invalid value passed to order"); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ class CLayerSurface {
|
||||||
bool mapped = false;
|
bool mapped = false;
|
||||||
uint32_t layer = 0;
|
uint32_t layer = 0;
|
||||||
|
|
||||||
int monitorID = -1;
|
MONITORID monitorID = -1;
|
||||||
|
|
||||||
bool fadingOut = false;
|
bool fadingOut = false;
|
||||||
bool readyToDelete = false;
|
bool readyToDelete = false;
|
||||||
|
@ -51,10 +51,11 @@ class CLayerSurface {
|
||||||
|
|
||||||
bool forceBlur = false;
|
bool forceBlur = false;
|
||||||
bool forceBlurPopups = false;
|
bool forceBlurPopups = false;
|
||||||
int xray = -1;
|
int64_t xray = -1;
|
||||||
bool ignoreAlpha = false;
|
bool ignoreAlpha = false;
|
||||||
float ignoreAlphaValue = 0.f;
|
float ignoreAlphaValue = 0.f;
|
||||||
bool dimAround = false;
|
bool dimAround = false;
|
||||||
|
int64_t order = 0;
|
||||||
|
|
||||||
std::optional<std::string> animationStyle;
|
std::optional<std::string> animationStyle;
|
||||||
|
|
||||||
|
|
|
@ -202,6 +202,13 @@ void CPopup::reposition() {
|
||||||
m_pResource->applyPositioning(box, COORDS);
|
m_pResource->applyPositioning(box, COORDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SP<CWLSurface> CPopup::getT1Owner() {
|
||||||
|
if (m_pWindowOwner)
|
||||||
|
return m_pWindowOwner->m_pWLSurface;
|
||||||
|
else
|
||||||
|
return m_pLayerOwner->surface;
|
||||||
|
}
|
||||||
|
|
||||||
Vector2D CPopup::coordsRelativeToParent() {
|
Vector2D CPopup::coordsRelativeToParent() {
|
||||||
Vector2D offset;
|
Vector2D offset;
|
||||||
|
|
||||||
|
@ -251,7 +258,7 @@ void CPopup::recheckTree() {
|
||||||
|
|
||||||
void CPopup::recheckChildrenRecursive() {
|
void CPopup::recheckChildrenRecursive() {
|
||||||
auto cpy = m_vChildren;
|
auto cpy = m_vChildren;
|
||||||
for (auto& c : cpy) {
|
for (auto const& c : cpy) {
|
||||||
c->onCommit(true);
|
c->onCommit(true);
|
||||||
c->recheckChildrenRecursive();
|
c->recheckChildrenRecursive();
|
||||||
}
|
}
|
||||||
|
@ -282,14 +289,14 @@ bool CPopup::visible() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPopup::bfHelper(std::vector<CPopup*> nodes, std::function<void(CPopup*, void*)> fn, void* data) {
|
void CPopup::bfHelper(std::vector<CPopup*> nodes, std::function<void(CPopup*, void*)> fn, void* data) {
|
||||||
for (auto& n : nodes) {
|
for (auto const& n : nodes) {
|
||||||
fn(n, data);
|
fn(n, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CPopup*> nodes2;
|
std::vector<CPopup*> nodes2;
|
||||||
|
|
||||||
for (auto& n : nodes) {
|
for (auto const& n : nodes) {
|
||||||
for (auto& c : n->m_vChildren) {
|
for (auto const& c : n->m_vChildren) {
|
||||||
nodes2.push_back(c.get());
|
nodes2.push_back(c.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,7 +315,7 @@ CPopup* CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
|
||||||
std::vector<CPopup*> popups;
|
std::vector<CPopup*> popups;
|
||||||
breadthfirst([](CPopup* popup, void* data) { ((std::vector<CPopup*>*)data)->push_back(popup); }, &popups);
|
breadthfirst([](CPopup* popup, void* data) { ((std::vector<CPopup*>*)data)->push_back(popup); }, &popups);
|
||||||
|
|
||||||
for (auto& p : popups | std::views::reverse) {
|
for (auto const& p : popups | std::views::reverse) {
|
||||||
if (!p->m_pResource)
|
if (!p->m_pResource)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ class CPopup {
|
||||||
|
|
||||||
~CPopup();
|
~CPopup();
|
||||||
|
|
||||||
|
SP<CWLSurface> getT1Owner();
|
||||||
Vector2D coordsRelativeToParent();
|
Vector2D coordsRelativeToParent();
|
||||||
Vector2D coordsGlobal();
|
Vector2D coordsGlobal();
|
||||||
|
|
||||||
|
|
|
@ -30,13 +30,7 @@ CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, CPopup* pOwner)
|
||||||
}
|
}
|
||||||
|
|
||||||
CSubsurface::~CSubsurface() {
|
CSubsurface::~CSubsurface() {
|
||||||
hyprListener_newSubsurface.removeCallback();
|
;
|
||||||
|
|
||||||
if (!m_pSubsurface)
|
|
||||||
return;
|
|
||||||
|
|
||||||
hyprListener_commitSubsurface.removeCallback();
|
|
||||||
hyprListener_destroySubsurface.removeCallback();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSubsurface::initSignals() {
|
void CSubsurface::initSignals() {
|
||||||
|
@ -65,7 +59,7 @@ void CSubsurface::checkSiblingDamage() {
|
||||||
|
|
||||||
const double SCALE = m_pWindowParent.lock() && m_pWindowParent->m_bIsX11 ? 1.0 / m_pWindowParent->m_fX11SurfaceScaledBy : 1.0;
|
const double SCALE = m_pWindowParent.lock() && m_pWindowParent->m_bIsX11 ? 1.0 / m_pWindowParent->m_fX11SurfaceScaledBy : 1.0;
|
||||||
|
|
||||||
for (auto& n : m_pParent->m_vChildren) {
|
for (auto const& n : m_pParent->m_vChildren) {
|
||||||
if (n.get() == this)
|
if (n.get() == this)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -75,7 +69,7 @@ void CSubsurface::checkSiblingDamage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSubsurface::recheckDamageForSubsurfaces() {
|
void CSubsurface::recheckDamageForSubsurfaces() {
|
||||||
for (auto& n : m_vChildren) {
|
for (auto const& n : m_vChildren) {
|
||||||
const auto COORDS = n->coordsGlobal();
|
const auto COORDS = n->coordsGlobal();
|
||||||
g_pHyprRenderer->damageSurface(n->m_pWLSurface->resource(), COORDS.x, COORDS.y);
|
g_pHyprRenderer->damageSurface(n->m_pWLSurface->resource(), COORDS.x, COORDS.y);
|
||||||
}
|
}
|
||||||
|
@ -183,7 +177,7 @@ Vector2D CSubsurface::coordsGlobal() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSubsurface::initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface) {
|
void CSubsurface::initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface) {
|
||||||
for (auto& s : pSurface->subsurfaces) {
|
for (auto const& s : pSurface->subsurfaces) {
|
||||||
if (!s || s->surface->hlSurface /* already assigned */)
|
if (!s || s->surface->hlSurface /* already assigned */)
|
||||||
continue;
|
continue;
|
||||||
onNewSubsurface(s.lock());
|
onNewSubsurface(s.lock());
|
||||||
|
|
|
@ -35,10 +35,6 @@ class CSubsurface {
|
||||||
void recheckDamageForSubsurfaces();
|
void recheckDamageForSubsurfaces();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DYNLISTENER(destroySubsurface);
|
|
||||||
DYNLISTENER(commitSubsurface);
|
|
||||||
DYNLISTENER(newSubsurface);
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
CHyprSignalListener destroySubsurface;
|
CHyprSignalListener destroySubsurface;
|
||||||
CHyprSignalListener commitSubsurface;
|
CHyprSignalListener commitSubsurface;
|
||||||
|
|
|
@ -62,7 +62,7 @@ bool CWLSurface::small() const {
|
||||||
|
|
||||||
const auto O = m_pWindowOwner.lock();
|
const auto O = m_pWindowOwner.lock();
|
||||||
|
|
||||||
return O->m_vReportedSize.x > m_pResource->current.bufferSize.x + 1 || O->m_vReportedSize.y > m_pResource->current.bufferSize.y + 1;
|
return O->m_vReportedSize.x > m_pResource->current.size.x + 1 || O->m_vReportedSize.y > m_pResource->current.size.y + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2D CWLSurface::correctSmallVec() const {
|
Vector2D CWLSurface::correctSmallVec() const {
|
||||||
|
|
|
@ -21,7 +21,6 @@ PHLWINDOW CWindow::create(SP<CXWaylandSurface> surface) {
|
||||||
|
|
||||||
pWindow->m_pSelf = pWindow;
|
pWindow->m_pSelf = pWindow;
|
||||||
pWindow->m_bIsX11 = true;
|
pWindow->m_bIsX11 = true;
|
||||||
pWindow->m_iX11Type = surface->overrideRedirect ? 2 : 1;
|
|
||||||
|
|
||||||
pWindow->m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
pWindow->m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||||
pWindow->m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
pWindow->m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), pWindow, AVARDAMAGE_ENTIRE);
|
||||||
|
@ -31,6 +30,7 @@ PHLWINDOW CWindow::create(SP<CXWaylandSurface> surface) {
|
||||||
pWindow->m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE);
|
pWindow->m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE);
|
||||||
pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW);
|
pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW);
|
||||||
pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE);
|
pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE);
|
||||||
|
pWindow->m_fMovingToWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE);
|
||||||
|
|
||||||
pWindow->addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(pWindow));
|
pWindow->addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(pWindow));
|
||||||
pWindow->addWindowDeco(std::make_unique<CHyprBorderDecoration>(pWindow));
|
pWindow->addWindowDeco(std::make_unique<CHyprBorderDecoration>(pWindow));
|
||||||
|
@ -52,6 +52,7 @@ PHLWINDOW CWindow::create(SP<CXDGSurfaceResource> resource) {
|
||||||
pWindow->m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE);
|
pWindow->m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), pWindow, AVARDAMAGE_ENTIRE);
|
||||||
pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW);
|
pWindow->m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), pWindow, AVARDAMAGE_SHADOW);
|
||||||
pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE);
|
pWindow->m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), pWindow, AVARDAMAGE_ENTIRE);
|
||||||
|
pWindow->m_fMovingToWorkspaceAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeOut"), pWindow, AVARDAMAGE_ENTIRE);
|
||||||
|
|
||||||
pWindow->addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(pWindow));
|
pWindow->addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(pWindow));
|
||||||
pWindow->addWindowDeco(std::make_unique<CHyprBorderDecoration>(pWindow));
|
pWindow->addWindowDeco(std::make_unique<CHyprBorderDecoration>(pWindow));
|
||||||
|
@ -252,7 +253,7 @@ void CWindow::updateWindowDecos() {
|
||||||
if (!m_bIsMapped || isHidden())
|
if (!m_bIsMapped || isHidden())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (auto& wd : m_vDecosToRemove) {
|
for (auto const& wd : m_vDecosToRemove) {
|
||||||
for (auto it = m_dWindowDecorations.begin(); it != m_dWindowDecorations.end(); it++) {
|
for (auto it = m_dWindowDecorations.begin(); it != m_dWindowDecorations.end(); it++) {
|
||||||
if (it->get() == wd) {
|
if (it->get() == wd) {
|
||||||
g_pDecorationPositioner->uncacheDecoration(it->get());
|
g_pDecorationPositioner->uncacheDecoration(it->get());
|
||||||
|
@ -270,11 +271,11 @@ void CWindow::updateWindowDecos() {
|
||||||
// make a copy because updateWindow can remove decos.
|
// make a copy because updateWindow can remove decos.
|
||||||
std::vector<IHyprWindowDecoration*> decos;
|
std::vector<IHyprWindowDecoration*> decos;
|
||||||
|
|
||||||
for (auto& wd : m_dWindowDecorations) {
|
for (auto const& wd : m_dWindowDecorations) {
|
||||||
decos.push_back(wd.get());
|
decos.push_back(wd.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& wd : decos) {
|
for (auto const& wd : decos) {
|
||||||
if (std::find_if(m_dWindowDecorations.begin(), m_dWindowDecorations.end(), [wd](const auto& other) { return other.get() == wd; }) == m_dWindowDecorations.end())
|
if (std::find_if(m_dWindowDecorations.begin(), m_dWindowDecorations.end(), [wd](const auto& other) { return other.get() == wd; }) == m_dWindowDecorations.end())
|
||||||
continue;
|
continue;
|
||||||
wd->updateWindow(m_pSelf.lock());
|
wd->updateWindow(m_pSelf.lock());
|
||||||
|
@ -296,7 +297,7 @@ void CWindow::removeWindowDeco(IHyprWindowDecoration* deco) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWindow::uncacheWindowDecos() {
|
void CWindow::uncacheWindowDecos() {
|
||||||
for (auto& wd : m_dWindowDecorations) {
|
for (auto const& wd : m_dWindowDecorations) {
|
||||||
g_pDecorationPositioner->uncacheDecoration(wd.get());
|
g_pDecorationPositioner->uncacheDecoration(wd.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,7 +306,7 @@ bool CWindow::checkInputOnDecos(const eInputType type, const Vector2D& mouseCoor
|
||||||
if (type != INPUT_TYPE_DRAG_END && hasPopupAt(mouseCoords))
|
if (type != INPUT_TYPE_DRAG_END && hasPopupAt(mouseCoords))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (auto& wd : m_dWindowDecorations) {
|
for (auto const& wd : m_dWindowDecorations) {
|
||||||
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
|
if (!(wd->getDecorationFlags() & DECORATION_ALLOWS_MOUSE_INPUT))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -337,7 +338,7 @@ pid_t CWindow::getPID() {
|
||||||
}
|
}
|
||||||
|
|
||||||
IHyprWindowDecoration* CWindow::getDecorationByType(eDecorationType type) {
|
IHyprWindowDecoration* CWindow::getDecorationByType(eDecorationType type) {
|
||||||
for (auto& wd : m_dWindowDecorations) {
|
for (auto const& wd : m_dWindowDecorations) {
|
||||||
if (wd->getDecorationType() == type)
|
if (wd->getDecorationType() == type)
|
||||||
return wd.get();
|
return wd.get();
|
||||||
}
|
}
|
||||||
|
@ -407,6 +408,11 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
|
||||||
|
|
||||||
const auto OLDWORKSPACE = m_pWorkspace;
|
const auto OLDWORKSPACE = m_pWorkspace;
|
||||||
|
|
||||||
|
m_iMonitorMovedFrom = OLDWORKSPACE ? OLDWORKSPACE->m_iMonitorID : -1;
|
||||||
|
m_fMovingToWorkspaceAlpha.setValueAndWarp(1.F);
|
||||||
|
m_fMovingToWorkspaceAlpha = 0.F;
|
||||||
|
m_fMovingToWorkspaceAlpha.setCallbackOnEnd([this](void* thisptr) { m_iMonitorMovedFrom = -1; });
|
||||||
|
|
||||||
m_pWorkspace = pWorkspace;
|
m_pWorkspace = pWorkspace;
|
||||||
|
|
||||||
setAnimationsToMove();
|
setAnimationsToMove();
|
||||||
|
@ -446,15 +452,21 @@ PHLWINDOW CWindow::X11TransientFor() {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto s = m_pXWaylandSurface->parent;
|
auto s = m_pXWaylandSurface->parent;
|
||||||
auto oldParent = s;
|
std::vector<SP<CXWaylandSurface>> visited;
|
||||||
while (s) {
|
while (s) {
|
||||||
// break cyclic loop of m_pXWaylandSurface being parent of itself, #TODO reject this from even being created?
|
// break loops. Some X apps make them, and it seems like it's valid behavior?!?!?!
|
||||||
if (!s->parent || s->parent == oldParent)
|
// TODO: we should reject loops being created in the first place.
|
||||||
|
if (std::find(visited.begin(), visited.end(), s) != visited.end())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
visited.emplace_back(s.lock());
|
||||||
s = s->parent;
|
s = s->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
if (s == m_pXWaylandSurface)
|
||||||
|
return nullptr; // dead-ass circle
|
||||||
|
|
||||||
|
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||||
if (w->m_pXWaylandSurface != s)
|
if (w->m_pXWaylandSurface != s)
|
||||||
continue;
|
continue;
|
||||||
return w;
|
return w;
|
||||||
|
@ -464,7 +476,7 @@ PHLWINDOW CWindow::X11TransientFor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWindow::removeDecorationByType(eDecorationType type) {
|
void CWindow::removeDecorationByType(eDecorationType type) {
|
||||||
for (auto& wd : m_dWindowDecorations) {
|
for (auto const& wd : m_dWindowDecorations) {
|
||||||
if (wd->getDecorationType() == type)
|
if (wd->getDecorationType() == type)
|
||||||
m_vDecosToRemove.push_back(wd.get());
|
m_vDecosToRemove.push_back(wd.get());
|
||||||
}
|
}
|
||||||
|
@ -502,6 +514,7 @@ void CWindow::onUnmap() {
|
||||||
m_fAlpha.setCallbackOnEnd(unregisterVar);
|
m_fAlpha.setCallbackOnEnd(unregisterVar);
|
||||||
m_cRealShadowColor.setCallbackOnEnd(unregisterVar);
|
m_cRealShadowColor.setCallbackOnEnd(unregisterVar);
|
||||||
m_fDimPercent.setCallbackOnEnd(unregisterVar);
|
m_fDimPercent.setCallbackOnEnd(unregisterVar);
|
||||||
|
m_fMovingToWorkspaceAlpha.setCallbackOnEnd(unregisterVar);
|
||||||
|
|
||||||
m_vRealSize.setCallbackOnBegin(nullptr);
|
m_vRealSize.setCallbackOnBegin(nullptr);
|
||||||
|
|
||||||
|
@ -542,6 +555,7 @@ void CWindow::onMap() {
|
||||||
m_fAlpha.resetAllCallbacks();
|
m_fAlpha.resetAllCallbacks();
|
||||||
m_cRealShadowColor.resetAllCallbacks();
|
m_cRealShadowColor.resetAllCallbacks();
|
||||||
m_fDimPercent.resetAllCallbacks();
|
m_fDimPercent.resetAllCallbacks();
|
||||||
|
m_fMovingToWorkspaceAlpha.resetAllCallbacks();
|
||||||
|
|
||||||
m_vRealPosition.registerVar();
|
m_vRealPosition.registerVar();
|
||||||
m_vRealSize.registerVar();
|
m_vRealSize.registerVar();
|
||||||
|
@ -551,6 +565,7 @@ void CWindow::onMap() {
|
||||||
m_fAlpha.registerVar();
|
m_fAlpha.registerVar();
|
||||||
m_cRealShadowColor.registerVar();
|
m_cRealShadowColor.registerVar();
|
||||||
m_fDimPercent.registerVar();
|
m_fDimPercent.registerVar();
|
||||||
|
m_fMovingToWorkspaceAlpha.registerVar();
|
||||||
|
|
||||||
m_fBorderAngleAnimationProgress.setCallbackOnEnd([&](void* ptr) { onBorderAngleAnimEnd(ptr); }, false);
|
m_fBorderAngleAnimationProgress.setCallbackOnEnd([&](void* ptr) { onBorderAngleAnimEnd(ptr); }, false);
|
||||||
|
|
||||||
|
@ -617,7 +632,7 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
|
||||||
|
|
||||||
int opacityIDX = 0;
|
int opacityIDX = 0;
|
||||||
|
|
||||||
for (auto& r : vars) {
|
for (auto const& r : vars) {
|
||||||
if (r == "opacity")
|
if (r == "opacity")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -666,7 +681,7 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& token : colorsAndAngles) {
|
for (auto const& token : colorsAndAngles) {
|
||||||
// The first angle, or an explicit "0deg", splits the two gradients
|
// The first angle, or an explicit "0deg", splits the two gradients
|
||||||
if (active && token.contains("deg")) {
|
if (active && token.contains("deg")) {
|
||||||
activeBorderGradient.m_fAngle = std::stoi(token.substr(0, token.size() - 3)) * (PI / 180.0);
|
activeBorderGradient.m_fAngle = std::stoi(token.substr(0, token.size() - 3)) * (PI / 180.0);
|
||||||
|
@ -727,9 +742,8 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sWindowData.maxSize = CWindowOverridableVar(VEC, priority);
|
m_sWindowData.maxSize = CWindowOverridableVar(VEC, priority);
|
||||||
m_vRealSize =
|
clampWindowSize(std::nullopt, m_sWindowData.maxSize.value());
|
||||||
Vector2D(std::min((double)m_sWindowData.maxSize.value().x, m_vRealSize.goal().x), std::min((double)m_sWindowData.maxSize.value().y, m_vRealSize.goal().y));
|
|
||||||
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.goal());
|
|
||||||
} catch (std::exception& e) { Debug::log(ERR, "maxsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
|
} catch (std::exception& e) { Debug::log(ERR, "maxsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
|
||||||
} else if (r.szRule.starts_with("minsize")) {
|
} else if (r.szRule.starts_with("minsize")) {
|
||||||
try {
|
try {
|
||||||
|
@ -742,12 +756,14 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sWindowData.minSize = CWindowOverridableVar(VEC, priority);
|
m_sWindowData.minSize = CWindowOverridableVar(VEC, priority);
|
||||||
m_vRealSize =
|
clampWindowSize(m_sWindowData.minSize.value(), std::nullopt);
|
||||||
Vector2D(std::max((double)m_sWindowData.minSize.value().x, m_vRealSize.goal().x), std::max((double)m_sWindowData.minSize.value().y, m_vRealSize.goal().y));
|
|
||||||
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), m_vRealSize.goal());
|
|
||||||
if (m_sGroupData.pNextWindow.expired())
|
if (m_sGroupData.pNextWindow.expired())
|
||||||
setHidden(false);
|
setHidden(false);
|
||||||
} catch (std::exception& e) { Debug::log(ERR, "minsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
|
} catch (std::exception& e) { Debug::log(ERR, "minsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
|
||||||
|
} else if (r.szRule == "renderunfocused") {
|
||||||
|
m_sWindowData.renderUnfocused = CWindowOverridableVar(true, priority);
|
||||||
|
g_pHyprRenderer->addWindowToRenderUnfocused(m_pSelf.lock());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,12 +781,14 @@ void CWindow::updateDynamicRules() {
|
||||||
m_sWindowData.activeBorderColor.unset(PRIORITY_WINDOW_RULE);
|
m_sWindowData.activeBorderColor.unset(PRIORITY_WINDOW_RULE);
|
||||||
m_sWindowData.inactiveBorderColor.unset(PRIORITY_WINDOW_RULE);
|
m_sWindowData.inactiveBorderColor.unset(PRIORITY_WINDOW_RULE);
|
||||||
|
|
||||||
|
m_sWindowData.renderUnfocused.unset(PRIORITY_WINDOW_RULE);
|
||||||
|
|
||||||
m_eIdleInhibitMode = IDLEINHIBIT_NONE;
|
m_eIdleInhibitMode = IDLEINHIBIT_NONE;
|
||||||
|
|
||||||
m_tags.removeDynamicTags();
|
m_tags.removeDynamicTags();
|
||||||
|
|
||||||
m_vMatchedRules = g_pConfigManager->getMatchingRules(m_pSelf.lock());
|
m_vMatchedRules = g_pConfigManager->getMatchingRules(m_pSelf.lock());
|
||||||
for (auto& r : m_vMatchedRules) {
|
for (auto const& r : m_vMatchedRules) {
|
||||||
applyDynamicRule(r);
|
applyDynamicRule(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -881,7 +899,7 @@ void CWindow::destroyGroup() {
|
||||||
addresses += std::format("{:x},", (uintptr_t)curr.get());
|
addresses += std::format("{:x},", (uintptr_t)curr.get());
|
||||||
} while (curr.get() != this);
|
} while (curr.get() != this);
|
||||||
|
|
||||||
for (auto& w : members) {
|
for (auto const& w : members) {
|
||||||
if (w->m_sGroupData.head)
|
if (w->m_sGroupData.head)
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(curr);
|
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(curr);
|
||||||
w->m_sGroupData.head = false;
|
w->m_sGroupData.head = false;
|
||||||
|
@ -889,7 +907,7 @@ void CWindow::destroyGroup() {
|
||||||
|
|
||||||
const bool GROUPSLOCKEDPREV = g_pKeybindManager->m_bGroupsLocked;
|
const bool GROUPSLOCKEDPREV = g_pKeybindManager->m_bGroupsLocked;
|
||||||
g_pKeybindManager->m_bGroupsLocked = true;
|
g_pKeybindManager->m_bGroupsLocked = true;
|
||||||
for (auto& w : members) {
|
for (auto const& w : members) {
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowCreated(w);
|
g_pLayoutManager->getCurrentLayout()->onWindowCreated(w);
|
||||||
w->updateWindowDecos();
|
w->updateWindowDecos();
|
||||||
}
|
}
|
||||||
|
@ -937,12 +955,16 @@ int CWindow::getGroupSize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWindow::canBeGroupedInto(PHLWINDOW pWindow) {
|
bool CWindow::canBeGroupedInto(PHLWINDOW pWindow) {
|
||||||
|
static auto ALLOWGROUPMERGE = CConfigValue<Hyprlang::INT>("group:merge_groups_on_drag");
|
||||||
|
bool isGroup = m_sGroupData.pNextWindow;
|
||||||
|
bool disallowDragIntoGroup = g_pInputManager->m_bWasDraggingWindow && isGroup && !bool(*ALLOWGROUPMERGE);
|
||||||
return !g_pKeybindManager->m_bGroupsLocked // global group lock disengaged
|
return !g_pKeybindManager->m_bGroupsLocked // global group lock disengaged
|
||||||
&& ((m_eGroupRules & GROUP_INVADE && m_bFirstMap) // window ignore local group locks, or
|
&& ((m_eGroupRules & GROUP_INVADE && m_bFirstMap) // window ignore local group locks, or
|
||||||
|| (!pWindow->getGroupHead()->m_sGroupData.locked // target unlocked
|
|| (!pWindow->getGroupHead()->m_sGroupData.locked // target unlocked
|
||||||
&& !(m_sGroupData.pNextWindow.lock() && getGroupHead()->m_sGroupData.locked))) // source unlocked or isn't group
|
&& !(m_sGroupData.pNextWindow.lock() && getGroupHead()->m_sGroupData.locked))) // source unlocked or isn't group
|
||||||
&& !m_sGroupData.deny // source is not denied entry
|
&& !m_sGroupData.deny // source is not denied entry
|
||||||
&& !(m_eGroupRules & GROUP_BARRED && m_bFirstMap); // group rule doesn't prevent adding window
|
&& !(m_eGroupRules & GROUP_BARRED && m_bFirstMap) // group rule doesn't prevent adding window
|
||||||
|
&& !disallowDragIntoGroup; // config allows groups to be merged
|
||||||
}
|
}
|
||||||
|
|
||||||
PHLWINDOW CWindow::getGroupWindowByIndex(int index) {
|
PHLWINDOW CWindow::getGroupWindowByIndex(int index) {
|
||||||
|
@ -973,7 +995,7 @@ void CWindow::setGroupCurrent(PHLWINDOW pWindow) {
|
||||||
const auto PCURRENT = getGroupCurrent();
|
const auto PCURRENT = getGroupCurrent();
|
||||||
const bool FULLSCREEN = PCURRENT->isFullscreen();
|
const bool FULLSCREEN = PCURRENT->isFullscreen();
|
||||||
const auto WORKSPACE = PCURRENT->m_pWorkspace;
|
const auto WORKSPACE = PCURRENT->m_pWorkspace;
|
||||||
const auto MODE = PCURRENT->m_sFullscreenState.client;
|
const auto MODE = PCURRENT->m_sFullscreenState.internal;
|
||||||
|
|
||||||
const auto PWINDOWSIZE = PCURRENT->m_vRealSize.goal();
|
const auto PWINDOWSIZE = PCURRENT->m_vRealSize.goal();
|
||||||
const auto PWINDOWPOS = PCURRENT->m_vRealPosition.goal();
|
const auto PWINDOWPOS = PCURRENT->m_vRealPosition.goal();
|
||||||
|
@ -1235,6 +1257,16 @@ int CWindow::surfacesCount() {
|
||||||
return no;
|
return no;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWindow::clampWindowSize(const std::optional<Vector2D> minSize, const std::optional<Vector2D> maxSize) {
|
||||||
|
const Vector2D REALSIZE = m_vRealSize.goal();
|
||||||
|
const Vector2D NEWSIZE = REALSIZE.clamp(minSize.value_or(Vector2D{0.f, 0.f}), maxSize.value_or(Vector2D{INFINITY, INFINITY}));
|
||||||
|
const Vector2D DELTA = REALSIZE - NEWSIZE;
|
||||||
|
|
||||||
|
m_vRealPosition = m_vRealPosition.goal() + DELTA / 2.0;
|
||||||
|
m_vRealSize = NEWSIZE;
|
||||||
|
g_pXWaylandManager->setWindowSize(m_pSelf.lock(), NEWSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
bool CWindow::isFullscreen() {
|
bool CWindow::isFullscreen() {
|
||||||
return m_sFullscreenState.internal != FSMODE_NONE;
|
return m_sFullscreenState.internal != FSMODE_NONE;
|
||||||
}
|
}
|
||||||
|
@ -1243,7 +1275,7 @@ bool CWindow::isEffectiveInternalFSMode(const eFullscreenMode MODE) {
|
||||||
return (eFullscreenMode)std::bit_floor((uint8_t)m_sFullscreenState.internal) == MODE;
|
return (eFullscreenMode)std::bit_floor((uint8_t)m_sFullscreenState.internal) == MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CWindow::workspaceID() {
|
WORKSPACEID CWindow::workspaceID() {
|
||||||
return m_pWorkspace ? m_pWorkspace->m_iID : m_iLastWorkspace;
|
return m_pWorkspace ? m_pWorkspace->m_iID : m_iLastWorkspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1282,7 +1314,7 @@ std::unordered_map<std::string, std::string> CWindow::getEnv() {
|
||||||
|
|
||||||
CVarList envs(std::string{buffer.data(), buffer.size() - 1}, 0, '\n', true);
|
CVarList envs(std::string{buffer.data(), buffer.size() - 1}, 0, '\n', true);
|
||||||
|
|
||||||
for (auto& e : envs) {
|
for (auto const& e : envs) {
|
||||||
if (!e.contains('='))
|
if (!e.contains('='))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1307,6 +1339,11 @@ void CWindow::activate(bool force) {
|
||||||
if (!force && (!m_sWindowData.focusOnActivate.valueOr(*PFOCUSONACTIVATE) || (m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY) || (m_eSuppressedEvents & SUPPRESS_ACTIVATE)))
|
if (!force && (!m_sWindowData.focusOnActivate.valueOr(*PFOCUSONACTIVATE) || (m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY) || (m_eSuppressedEvents & SUPPRESS_ACTIVATE)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!m_bIsMapped) {
|
||||||
|
Debug::log(LOG, "Ignoring CWindow::activate focus/warp, window is not mapped yet.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_bIsFloating)
|
if (m_bIsFloating)
|
||||||
g_pCompositor->changeWindowZOrder(m_pSelf.lock(), true);
|
g_pCompositor->changeWindowZOrder(m_pSelf.lock(), true);
|
||||||
|
|
||||||
|
@ -1511,7 +1548,7 @@ PHLWINDOW CWindow::getSwallower() {
|
||||||
if (!currentPid)
|
if (!currentPid)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||||
if (!w->m_bIsMapped || w->isHidden())
|
if (!w->m_bIsMapped || w->isHidden())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1536,7 +1573,7 @@ PHLWINDOW CWindow::getSwallower() {
|
||||||
return candidates.at(0);
|
return candidates.at(0);
|
||||||
|
|
||||||
// walk up the focus history and find the last focused
|
// walk up the focus history and find the last focused
|
||||||
for (auto& w : g_pCompositor->m_vWindowFocusHistory) {
|
for (auto const& w : g_pCompositor->m_vWindowFocusHistory) {
|
||||||
if (!w)
|
if (!w)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1556,3 +1593,11 @@ void CWindow::unsetWindowData(eOverridePriority priority) {
|
||||||
element.second(m_pSelf.lock())->unset(priority);
|
element.second(m_pSelf.lock())->unset(priority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CWindow::isX11OverrideRedirect() {
|
||||||
|
return m_pXWaylandSurface && m_pXWaylandSurface->overrideRedirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWindow::isModal() {
|
||||||
|
return (m_pXWaylandSurface && m_pXWaylandSurface->modal);
|
||||||
|
}
|
||||||
|
|
|
@ -174,6 +174,7 @@ struct SWindowData {
|
||||||
CWindowOverridableVar<bool> syncFullscreen = true;
|
CWindowOverridableVar<bool> syncFullscreen = true;
|
||||||
CWindowOverridableVar<bool> tearing = false;
|
CWindowOverridableVar<bool> tearing = false;
|
||||||
CWindowOverridableVar<bool> xray = false;
|
CWindowOverridableVar<bool> xray = false;
|
||||||
|
CWindowOverridableVar<bool> renderUnfocused = false;
|
||||||
|
|
||||||
CWindowOverridableVar<int> rounding;
|
CWindowOverridableVar<int> rounding;
|
||||||
CWindowOverridableVar<int> borderSize;
|
CWindowOverridableVar<int> borderSize;
|
||||||
|
@ -201,6 +202,7 @@ struct SWindowRule {
|
||||||
int bFullscreen = -1;
|
int bFullscreen = -1;
|
||||||
int bPinned = -1;
|
int bPinned = -1;
|
||||||
int bFocus = -1;
|
int bFocus = -1;
|
||||||
|
std::string szFullscreenState = ""; // empty means any
|
||||||
std::string szOnWorkspace = ""; // empty means any
|
std::string szOnWorkspace = ""; // empty means any
|
||||||
std::string szWorkspace = ""; // empty means any
|
std::string szWorkspace = ""; // empty means any
|
||||||
};
|
};
|
||||||
|
@ -270,7 +272,7 @@ class CWindow {
|
||||||
bool m_bDraggingTiled = false; // for dragging around tiled windows
|
bool m_bDraggingTiled = false; // for dragging around tiled windows
|
||||||
bool m_bWasMaximized = false;
|
bool m_bWasMaximized = false;
|
||||||
sFullscreenState m_sFullscreenState = {.internal = FSMODE_NONE, .client = FSMODE_NONE};
|
sFullscreenState m_sFullscreenState = {.internal = FSMODE_NONE, .client = FSMODE_NONE};
|
||||||
uint64_t m_iMonitorID = -1;
|
MONITORID m_iMonitorID = -1;
|
||||||
std::string m_szTitle = "";
|
std::string m_szTitle = "";
|
||||||
std::string m_szClass = "";
|
std::string m_szClass = "";
|
||||||
std::string m_szInitialTitle = "";
|
std::string m_szInitialTitle = "";
|
||||||
|
@ -287,8 +289,6 @@ class CWindow {
|
||||||
// XWayland stuff
|
// XWayland stuff
|
||||||
bool m_bIsX11 = false;
|
bool m_bIsX11 = false;
|
||||||
PHLWINDOWREF m_pX11Parent;
|
PHLWINDOWREF m_pX11Parent;
|
||||||
uint64_t m_iX11Type = 0;
|
|
||||||
bool m_bIsModal = false;
|
|
||||||
bool m_bX11DoesntWantBorders = false;
|
bool m_bX11DoesntWantBorders = false;
|
||||||
bool m_bX11ShouldntFocus = false;
|
bool m_bX11ShouldntFocus = false;
|
||||||
float m_fX11SurfaceScaledBy = 1.f;
|
float m_fX11SurfaceScaledBy = 1.f;
|
||||||
|
@ -351,6 +351,10 @@ class CWindow {
|
||||||
// animated tint
|
// animated tint
|
||||||
CAnimatedVariable<float> m_fDimPercent;
|
CAnimatedVariable<float> m_fDimPercent;
|
||||||
|
|
||||||
|
// animate moving to an invisible workspace
|
||||||
|
int m_iMonitorMovedFrom = -1; // -1 means not moving
|
||||||
|
CAnimatedVariable<float> m_fMovingToWorkspaceAlpha;
|
||||||
|
|
||||||
// swallowing
|
// swallowing
|
||||||
PHLWINDOWREF m_pSwallowed;
|
PHLWINDOWREF m_pSwallowed;
|
||||||
|
|
||||||
|
@ -358,8 +362,8 @@ class CWindow {
|
||||||
bool m_bStayFocused = false;
|
bool m_bStayFocused = false;
|
||||||
|
|
||||||
// for toplevel monitor events
|
// for toplevel monitor events
|
||||||
uint64_t m_iLastToplevelMonitorID = -1;
|
MONITORID m_iLastToplevelMonitorID = -1;
|
||||||
uint64_t m_iLastSurfaceMonitorID = -1;
|
MONITORID m_iLastSurfaceMonitorID = -1;
|
||||||
|
|
||||||
// for idle inhibiting windows
|
// for idle inhibiting windows
|
||||||
eIdleInhibitMode m_eIdleInhibitMode = IDLEINHIBIT_NONE;
|
eIdleInhibitMode m_eIdleInhibitMode = IDLEINHIBIT_NONE;
|
||||||
|
@ -421,10 +425,11 @@ class CWindow {
|
||||||
bool canBeTorn();
|
bool canBeTorn();
|
||||||
void setSuspended(bool suspend);
|
void setSuspended(bool suspend);
|
||||||
bool visibleOnMonitor(CMonitor* pMonitor);
|
bool visibleOnMonitor(CMonitor* pMonitor);
|
||||||
int workspaceID();
|
WORKSPACEID workspaceID();
|
||||||
bool onSpecialWorkspace();
|
bool onSpecialWorkspace();
|
||||||
void activate(bool force = false);
|
void activate(bool force = false);
|
||||||
int surfacesCount();
|
int surfacesCount();
|
||||||
|
void clampWindowSize(const std::optional<Vector2D> minSize, const std::optional<Vector2D> maxSize);
|
||||||
|
|
||||||
bool isFullscreen();
|
bool isFullscreen();
|
||||||
bool isEffectiveInternalFSMode(const eFullscreenMode);
|
bool isEffectiveInternalFSMode(const eFullscreenMode);
|
||||||
|
@ -463,6 +468,8 @@ class CWindow {
|
||||||
void warpCursor();
|
void warpCursor();
|
||||||
PHLWINDOW getSwallower();
|
PHLWINDOW getSwallower();
|
||||||
void unsetWindowData(eOverridePriority priority);
|
void unsetWindowData(eOverridePriority priority);
|
||||||
|
bool isX11OverrideRedirect();
|
||||||
|
bool isModal();
|
||||||
|
|
||||||
// listeners
|
// listeners
|
||||||
void onAck(uint32_t serial);
|
void onAck(uint32_t serial);
|
||||||
|
@ -492,7 +499,7 @@ class CWindow {
|
||||||
// For hidden windows and stuff
|
// For hidden windows and stuff
|
||||||
bool m_bHidden = false;
|
bool m_bHidden = false;
|
||||||
bool m_bSuspended = false;
|
bool m_bSuspended = false;
|
||||||
int m_iLastWorkspace = WORKSPACE_INVALID;
|
WORKSPACEID m_iLastWorkspace = WORKSPACE_INVALID;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool valid(PHLWINDOW w) {
|
inline bool valid(PHLWINDOW w) {
|
||||||
|
|
|
@ -5,27 +5,28 @@
|
||||||
#include <hyprutils/string/String.hpp>
|
#include <hyprutils/string/String.hpp>
|
||||||
using namespace Hyprutils::String;
|
using namespace Hyprutils::String;
|
||||||
|
|
||||||
PHLWORKSPACE CWorkspace::create(int id, int monitorID, std::string name, bool special, bool isEmtpy) {
|
PHLWORKSPACE CWorkspace::create(WORKSPACEID id, MONITORID monitorID, std::string name, bool special, bool isEmpty) {
|
||||||
PHLWORKSPACE workspace = makeShared<CWorkspace>(id, monitorID, name, special, isEmtpy);
|
PHLWORKSPACE workspace = makeShared<CWorkspace>(id, monitorID, name, special, isEmpty);
|
||||||
workspace->init(workspace);
|
workspace->init(workspace);
|
||||||
return workspace;
|
return workspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
CWorkspace::CWorkspace(int id, int monitorID, std::string name, bool special, bool isEmtpy) {
|
CWorkspace::CWorkspace(WORKSPACEID id, MONITORID monitorID, std::string name, bool special, bool isEmpty) {
|
||||||
m_iMonitorID = monitorID;
|
m_iMonitorID = monitorID;
|
||||||
m_iID = id;
|
m_iID = id;
|
||||||
m_szName = name;
|
m_szName = name;
|
||||||
m_bIsSpecialWorkspace = special;
|
m_bIsSpecialWorkspace = special;
|
||||||
m_bWasCreatedEmtpy = isEmtpy;
|
m_bWasCreatedEmpty = isEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWorkspace::init(PHLWORKSPACE self) {
|
void CWorkspace::init(PHLWORKSPACE self) {
|
||||||
m_pSelf = self;
|
m_pSelf = self;
|
||||||
|
|
||||||
m_vRenderOffset.create(m_bIsSpecialWorkspace ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"),
|
m_vRenderOffset.create(m_bIsSpecialWorkspace ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspaceIn") :
|
||||||
|
g_pConfigManager->getAnimationPropertyConfig("workspacesIn"),
|
||||||
self, AVARDAMAGE_ENTIRE);
|
self, AVARDAMAGE_ENTIRE);
|
||||||
m_fAlpha.create(AVARTYPE_FLOAT,
|
m_fAlpha.create(AVARTYPE_FLOAT,
|
||||||
m_bIsSpecialWorkspace ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), self,
|
m_bIsSpecialWorkspace ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspaceIn") : g_pConfigManager->getAnimationPropertyConfig("workspacesIn"), self,
|
||||||
AVARDAMAGE_ENTIRE);
|
AVARDAMAGE_ENTIRE);
|
||||||
m_fAlpha.setValueAndWarp(1.f);
|
m_fAlpha.setValueAndWarp(1.f);
|
||||||
|
|
||||||
|
@ -48,9 +49,9 @@ void CWorkspace::init(PHLWORKSPACE self) {
|
||||||
const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(self);
|
const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(self);
|
||||||
m_bPersistent = WORKSPACERULE.isPersistent;
|
m_bPersistent = WORKSPACERULE.isPersistent;
|
||||||
|
|
||||||
if (self->m_bWasCreatedEmtpy)
|
if (self->m_bWasCreatedEmpty)
|
||||||
if (auto cmd = WORKSPACERULE.onCreatedEmptyRunCmd)
|
if (auto cmd = WORKSPACERULE.onCreatedEmptyRunCmd)
|
||||||
g_pKeybindManager->spawn(*cmd);
|
g_pKeybindManager->spawnWithRules(*cmd, self);
|
||||||
|
|
||||||
g_pEventManager->postEvent({"createworkspace", m_szName});
|
g_pEventManager->postEvent({"createworkspace", m_szName});
|
||||||
g_pEventManager->postEvent({"createworkspacev2", std::format("{},{}", m_iID, m_szName)});
|
g_pEventManager->postEvent({"createworkspacev2", std::format("{},{}", m_iID, m_szName)});
|
||||||
|
@ -81,12 +82,19 @@ CWorkspace::~CWorkspace() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
||||||
|
if (!instant) {
|
||||||
|
const std::string ANIMNAME = std::format("{}{}", m_bIsSpecialWorkspace ? "specialWorkspace" : "workspaces", in ? "In" : "Out");
|
||||||
|
|
||||||
|
m_fAlpha.m_pConfig = g_pConfigManager->getAnimationPropertyConfig(ANIMNAME);
|
||||||
|
m_vRenderOffset.m_pConfig = g_pConfigManager->getAnimationPropertyConfig(ANIMNAME);
|
||||||
|
}
|
||||||
|
|
||||||
const auto ANIMSTYLE = m_fAlpha.m_pConfig->pValues->internalStyle;
|
const auto ANIMSTYLE = m_fAlpha.m_pConfig->pValues->internalStyle;
|
||||||
static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
|
static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
|
||||||
|
|
||||||
// set floating windows offset callbacks
|
// set floating windows offset callbacks
|
||||||
m_vRenderOffset.setUpdateCallback([&](void*) {
|
m_vRenderOffset.setUpdateCallback([&](void*) {
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||||
if (!validMapped(w) || w->workspaceID() != m_iID)
|
if (!validMapped(w) || w->workspaceID() != m_iID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -190,7 +198,7 @@ void CWorkspace::setActive(bool on) {
|
||||||
; // empty until https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/40
|
; // empty until https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/40
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWorkspace::moveToMonitor(const int& id) {
|
void CWorkspace::moveToMonitor(const MONITORID& id) {
|
||||||
; // empty until https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/40
|
; // empty until https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/40
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +283,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) {
|
||||||
i = std::min(NEXTSPACE, std::string::npos - 1);
|
i = std::min(NEXTSPACE, std::string::npos - 1);
|
||||||
|
|
||||||
if (cur == 'r') {
|
if (cur == 'r') {
|
||||||
int from = 0, to = 0;
|
WORKSPACEID from = 0, to = 0;
|
||||||
if (!prop.starts_with("r[") || !prop.ends_with("]")) {
|
if (!prop.starts_with("r[") || !prop.ends_with("]")) {
|
||||||
Debug::log(LOG, "Invalid selector {}", selector);
|
Debug::log(LOG, "Invalid selector {}", selector);
|
||||||
return false;
|
return false;
|
||||||
|
@ -365,7 +373,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur == 'w') {
|
if (cur == 'w') {
|
||||||
int from = 0, to = 0;
|
WORKSPACEID from = 0, to = 0;
|
||||||
if (!prop.starts_with("w[") || !prop.ends_with("]")) {
|
if (!prop.starts_with("w[") || !prop.ends_with("]")) {
|
||||||
Debug::log(LOG, "Invalid selector {}", selector);
|
Debug::log(LOG, "Invalid selector {}", selector);
|
||||||
return false;
|
return false;
|
||||||
|
@ -378,7 +386,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) {
|
||||||
bool wantsCountVisible = false;
|
bool wantsCountVisible = false;
|
||||||
|
|
||||||
int flagCount = 0;
|
int flagCount = 0;
|
||||||
for (auto& flag : prop) {
|
for (auto const& flag : prop) {
|
||||||
if (flag == 't' && wantsOnlyTiled == -1) {
|
if (flag == 't' && wantsOnlyTiled == -1) {
|
||||||
wantsOnlyTiled = 1;
|
wantsOnlyTiled = 1;
|
||||||
flagCount++;
|
flagCount++;
|
||||||
|
@ -446,7 +454,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int count;
|
WORKSPACEID count;
|
||||||
if (wantsCountGroup)
|
if (wantsCountGroup)
|
||||||
count = g_pCompositor->getGroupsOnWorkspace(m_iID, wantsOnlyTiled == -1 ? std::nullopt : std::optional<bool>((bool)wantsOnlyTiled),
|
count = g_pCompositor->getGroupsOnWorkspace(m_iID, wantsOnlyTiled == -1 ? std::nullopt : std::optional<bool>((bool)wantsOnlyTiled),
|
||||||
wantsCountVisible ? std::optional<bool>(wantsCountVisible) : std::nullopt);
|
wantsCountVisible ? std::optional<bool>(wantsCountVisible) : std::nullopt);
|
||||||
|
@ -506,7 +514,7 @@ bool CWorkspace::matchesStaticSelector(const std::string& selector_) {
|
||||||
void CWorkspace::markInert() {
|
void CWorkspace::markInert() {
|
||||||
m_bInert = true;
|
m_bInert = true;
|
||||||
m_iID = WORKSPACE_INVALID;
|
m_iID = WORKSPACE_INVALID;
|
||||||
m_iMonitorID = -1;
|
m_iMonitorID = MONITOR_INVALID;
|
||||||
m_bVisible = false;
|
m_bVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,16 +17,16 @@ class CWindow;
|
||||||
|
|
||||||
class CWorkspace {
|
class CWorkspace {
|
||||||
public:
|
public:
|
||||||
static PHLWORKSPACE create(int id, int monitorID, std::string name, bool special = false, bool isEmtpy = true);
|
static PHLWORKSPACE create(WORKSPACEID id, MONITORID monitorID, std::string name, bool special = false, bool isEmpty = true);
|
||||||
// use create() don't use this
|
// use create() don't use this
|
||||||
CWorkspace(int id, int monitorID, std::string name, bool special = false, bool isEmpty = true);
|
CWorkspace(WORKSPACEID id, MONITORID monitorID, std::string name, bool special = false, bool isEmpty = true);
|
||||||
~CWorkspace();
|
~CWorkspace();
|
||||||
|
|
||||||
// Workspaces ID-based have IDs > 0
|
// Workspaces ID-based have IDs > 0
|
||||||
// and workspaces name-based have IDs starting with -1337
|
// and workspaces name-based have IDs starting with -1337
|
||||||
int m_iID = -1;
|
WORKSPACEID m_iID = WORKSPACE_INVALID;
|
||||||
std::string m_szName = "";
|
std::string m_szName = "";
|
||||||
uint64_t m_iMonitorID = -1;
|
MONITORID m_iMonitorID = MONITOR_INVALID;
|
||||||
// Previous workspace ID and name is stored during a workspace change, allowing travel
|
// Previous workspace ID and name is stored during a workspace change, allowing travel
|
||||||
// to the previous workspace.
|
// to the previous workspace.
|
||||||
SWorkspaceIDName m_sPrevWorkspace, m_sPrevWorkspacePerMonitor;
|
SWorkspaceIDName m_sPrevWorkspace, m_sPrevWorkspacePerMonitor;
|
||||||
|
@ -57,7 +57,7 @@ class CWorkspace {
|
||||||
// last monitor (used on reconnect)
|
// last monitor (used on reconnect)
|
||||||
std::string m_szLastMonitor = "";
|
std::string m_szLastMonitor = "";
|
||||||
|
|
||||||
bool m_bWasCreatedEmtpy = true;
|
bool m_bWasCreatedEmpty = true;
|
||||||
|
|
||||||
bool m_bPersistent = false;
|
bool m_bPersistent = false;
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ class CWorkspace {
|
||||||
void startAnim(bool in, bool left, bool instant = false);
|
void startAnim(bool in, bool left, bool instant = false);
|
||||||
void setActive(bool on);
|
void setActive(bool on);
|
||||||
|
|
||||||
void moveToMonitor(const int&);
|
void moveToMonitor(const MONITORID&);
|
||||||
|
|
||||||
PHLWINDOW getLastFocusedWindow();
|
PHLWINDOW getLastFocusedWindow();
|
||||||
void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace);
|
void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace);
|
||||||
|
|
|
@ -119,7 +119,8 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) {
|
||||||
if (IDX != XKB_MOD_INVALID)
|
if (IDX != XKB_MOD_INVALID)
|
||||||
modifiersState.locked |= (uint32_t)1 << IDX;
|
modifiersState.locked |= (uint32_t)1 << IDX;
|
||||||
|
|
||||||
updateModifiers(modifiersState.depressed, modifiersState.latched, modifiersState.locked, modifiersState.group);
|
// 0 to avoid mods getting stuck if depressed during reload
|
||||||
|
updateModifiers(0, 0, modifiersState.locked, modifiersState.group);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < LEDNAMES.size(); ++i) {
|
for (size_t i = 0; i < LEDNAMES.size(); ++i) {
|
||||||
|
@ -177,13 +178,18 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
|
||||||
if (xkbState)
|
if (xkbState)
|
||||||
xkb_state_unref(xkbState);
|
xkb_state_unref(xkbState);
|
||||||
|
|
||||||
|
if (xkbSymState)
|
||||||
|
xkb_state_unref(xkbSymState);
|
||||||
|
|
||||||
xkbState = nullptr;
|
xkbState = nullptr;
|
||||||
xkbStaticState = nullptr;
|
xkbStaticState = nullptr;
|
||||||
|
xkbSymState = nullptr;
|
||||||
|
|
||||||
if (keymap) {
|
if (keymap) {
|
||||||
Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this);
|
Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this);
|
||||||
xkbStaticState = xkb_state_new(keymap);
|
xkbStaticState = xkb_state_new(keymap);
|
||||||
xkbState = xkb_state_new(keymap);
|
xkbState = xkb_state_new(keymap);
|
||||||
|
xkbSymState = xkb_state_new(keymap);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,6 +235,7 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
|
||||||
|
|
||||||
xkbState = xkb_state_new(KEYMAP);
|
xkbState = xkb_state_new(KEYMAP);
|
||||||
xkbStaticState = xkb_state_new(KEYMAP);
|
xkbStaticState = xkb_state_new(KEYMAP);
|
||||||
|
xkbSymState = xkb_state_new(KEYMAP);
|
||||||
|
|
||||||
xkb_keymap_unref(KEYMAP);
|
xkb_keymap_unref(KEYMAP);
|
||||||
xkb_context_unref(PCONTEXT);
|
xkb_context_unref(PCONTEXT);
|
||||||
|
@ -251,6 +258,7 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
|
||||||
|
|
||||||
xkbState = xkb_state_new(NEWKEYMAP);
|
xkbState = xkb_state_new(NEWKEYMAP);
|
||||||
xkbStaticState = xkb_state_new(NEWKEYMAP);
|
xkbStaticState = xkb_state_new(NEWKEYMAP);
|
||||||
|
xkbSymState = xkb_state_new(NEWKEYMAP);
|
||||||
|
|
||||||
xkb_keymap_unref(NEWKEYMAP);
|
xkb_keymap_unref(NEWKEYMAP);
|
||||||
xkb_context_unref(PCONTEXT);
|
xkb_context_unref(PCONTEXT);
|
||||||
|
@ -331,6 +339,9 @@ void IKeyboard::updateModifiers(uint32_t depressed, uint32_t latched, uint32_t l
|
||||||
|
|
||||||
xkb_state_update_mask(xkbState, depressed, latched, locked, 0, 0, group);
|
xkb_state_update_mask(xkbState, depressed, latched, locked, 0, 0, group);
|
||||||
|
|
||||||
|
if (xkbSymState)
|
||||||
|
xkb_state_update_mask(xkbSymState, 0, 0, 0, 0, 0, group);
|
||||||
|
|
||||||
if (!updateModifiersState())
|
if (!updateModifiersState())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -381,6 +392,9 @@ void IKeyboard::updateXkbStateWithKey(uint32_t xkbKey, bool pressed) {
|
||||||
xkb_state_update_key(xkbState, xkbKey, pressed ? XKB_KEY_DOWN : XKB_KEY_UP);
|
xkb_state_update_key(xkbState, xkbKey, pressed ? XKB_KEY_DOWN : XKB_KEY_UP);
|
||||||
|
|
||||||
if (updateModifiersState()) {
|
if (updateModifiersState()) {
|
||||||
|
if (xkbSymState)
|
||||||
|
xkb_state_update_mask(xkbSymState, 0, 0, 0, 0, 0, modifiersState.group);
|
||||||
|
|
||||||
keyboardEvents.modifiers.emit(SModifiersEvent{
|
keyboardEvents.modifiers.emit(SModifiersEvent{
|
||||||
.depressed = modifiersState.depressed,
|
.depressed = modifiersState.depressed,
|
||||||
.latched = modifiersState.latched,
|
.latched = modifiersState.latched,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IHID.hpp"
|
#include "IHID.hpp"
|
||||||
#include "../helpers/WLListener.hpp"
|
|
||||||
#include "../macros.hpp"
|
#include "../macros.hpp"
|
||||||
#include "../helpers/math/Math.hpp"
|
#include "../helpers/math/Math.hpp"
|
||||||
|
|
||||||
|
@ -83,7 +82,8 @@ class IKeyboard : public IHID {
|
||||||
bool keymapOverridden = false;
|
bool keymapOverridden = false;
|
||||||
|
|
||||||
xkb_layout_index_t activeLayout = 0;
|
xkb_layout_index_t activeLayout = 0;
|
||||||
xkb_state * xkbState = nullptr, *xkbStaticState /* Static state: never gets modifiers or layout changes sent, used for keybinds. */ = nullptr;
|
xkb_state * xkbState = nullptr, *xkbStaticState /* Static state: never gets modifiers or layout changes sent, used for keybinds. */ = nullptr,
|
||||||
|
*xkbSymState = nullptr /* Same as static but gets layouts */;
|
||||||
xkb_keymap* xkbKeymap = nullptr;
|
xkb_keymap* xkbKeymap = nullptr;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IHID.hpp"
|
#include "IHID.hpp"
|
||||||
#include "../helpers/WLListener.hpp"
|
|
||||||
#include "../macros.hpp"
|
#include "../macros.hpp"
|
||||||
#include "../helpers/math/Math.hpp"
|
#include "../helpers/math/Math.hpp"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IHID.hpp"
|
#include "IHID.hpp"
|
||||||
#include "../helpers/WLListener.hpp"
|
|
||||||
#include "../macros.hpp"
|
#include "../macros.hpp"
|
||||||
#include "../helpers/math/Math.hpp"
|
#include "../helpers/math/Math.hpp"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IHID.hpp"
|
#include "IHID.hpp"
|
||||||
#include "../helpers/WLListener.hpp"
|
|
||||||
#include "../macros.hpp"
|
#include "../macros.hpp"
|
||||||
#include "../helpers/math/Math.hpp"
|
#include "../helpers/math/Math.hpp"
|
||||||
#include "../helpers/math/Math.hpp"
|
#include "../helpers/math/Math.hpp"
|
||||||
|
|
|
@ -27,7 +27,6 @@ namespace Events {
|
||||||
|
|
||||||
// Monitor part 2 the sequel
|
// Monitor part 2 the sequel
|
||||||
DYNLISTENFUNC(monitorFrame);
|
DYNLISTENFUNC(monitorFrame);
|
||||||
DYNLISTENFUNC(monitorDestroy);
|
|
||||||
DYNLISTENFUNC(monitorStateRequest);
|
DYNLISTENFUNC(monitorStateRequest);
|
||||||
DYNLISTENFUNC(monitorDamage);
|
DYNLISTENFUNC(monitorDamage);
|
||||||
DYNLISTENFUNC(monitorNeedsFrame);
|
DYNLISTENFUNC(monitorNeedsFrame);
|
||||||
|
|
|
@ -85,31 +85,6 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_monitorDestroy(void* owner, void* data) {
|
|
||||||
CMonitor* pMonitor = (CMonitor*)owner;
|
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
|
||||||
if (m->output == pMonitor->output) {
|
|
||||||
pMonitor = m.get();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pMonitor)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Debug::log(LOG, "Destroy called for monitor {}", pMonitor->output->name);
|
|
||||||
|
|
||||||
pMonitor->onDisconnect(true);
|
|
||||||
|
|
||||||
pMonitor->output = nullptr;
|
|
||||||
pMonitor->m_bRenderingInitPassed = false;
|
|
||||||
|
|
||||||
Debug::log(LOG, "Removing monitor {} from realMonitors", pMonitor->szName);
|
|
||||||
|
|
||||||
std::erase_if(g_pCompositor->m_vRealMonitors, [&](SP<CMonitor>& el) { return el.get() == pMonitor; });
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::listener_monitorNeedsFrame(void* owner, void* data) {
|
void Events::listener_monitorNeedsFrame(void* owner, void* data) {
|
||||||
const auto PMONITOR = (CMonitor*)owner;
|
const auto PMONITOR = (CMonitor*)owner;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "../protocols/core/Compositor.hpp"
|
#include "../protocols/core/Compositor.hpp"
|
||||||
#include "../protocols/ToplevelExport.hpp"
|
#include "../protocols/ToplevelExport.hpp"
|
||||||
#include "../xwayland/XSurface.hpp"
|
#include "../xwayland/XSurface.hpp"
|
||||||
|
#include "managers/PointerManager.hpp"
|
||||||
|
|
||||||
#include <hyprutils/string/String.hpp>
|
#include <hyprutils/string/String.hpp>
|
||||||
using namespace Hyprutils::String;
|
using namespace Hyprutils::String;
|
||||||
|
@ -120,7 +121,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
PWINDOW->m_bRequestsFloat = true;
|
PWINDOW->m_bRequestsFloat = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PWINDOW->m_bX11ShouldntFocus = PWINDOW->m_bX11ShouldntFocus || (PWINDOW->m_bIsX11 && PWINDOW->m_iX11Type == 2 && !PWINDOW->m_pXWaylandSurface->wantsFocus());
|
PWINDOW->m_bX11ShouldntFocus = PWINDOW->m_bX11ShouldntFocus || (PWINDOW->m_bIsX11 && PWINDOW->isX11OverrideRedirect() && !PWINDOW->m_pXWaylandSurface->wantsFocus());
|
||||||
|
|
||||||
if (PWORKSPACE->m_bDefaultFloating)
|
if (PWORKSPACE->m_bDefaultFloating)
|
||||||
PWINDOW->m_bIsFloating = true;
|
PWINDOW->m_bIsFloating = true;
|
||||||
|
@ -139,7 +140,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
if (PWINDOW->m_bWantsInitialFullscreen || (PWINDOW->m_bIsX11 && PWINDOW->m_pXWaylandSurface->fullscreen))
|
if (PWINDOW->m_bWantsInitialFullscreen || (PWINDOW->m_bIsX11 && PWINDOW->m_pXWaylandSurface->fullscreen))
|
||||||
requestedClientFSMode = FSMODE_FULLSCREEN;
|
requestedClientFSMode = FSMODE_FULLSCREEN;
|
||||||
|
|
||||||
for (auto& r : PWINDOW->m_vMatchedRules) {
|
for (auto const& r : PWINDOW->m_vMatchedRules) {
|
||||||
if (r.szRule.starts_with("monitor")) {
|
if (r.szRule.starts_with("monitor")) {
|
||||||
try {
|
try {
|
||||||
const auto MONITORSTR = trim(r.szRule.substr(r.szRule.find(' ')));
|
const auto MONITORSTR = trim(r.szRule.substr(r.szRule.find(' ')));
|
||||||
|
@ -148,7 +149,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||||
} else {
|
} else {
|
||||||
if (isNumber(MONITORSTR)) {
|
if (isNumber(MONITORSTR)) {
|
||||||
const long int MONITOR = std::stoi(MONITORSTR);
|
const MONITORID MONITOR = std::stoi(MONITORSTR);
|
||||||
if (!g_pCompositor->getMonitorFromID(MONITOR))
|
if (!g_pCompositor->getMonitorFromID(MONITOR))
|
||||||
PWINDOW->m_iMonitorID = 0;
|
PWINDOW->m_iMonitorID = 0;
|
||||||
else
|
else
|
||||||
|
@ -322,11 +323,11 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
PWINDOW->updateWindowData();
|
PWINDOW->updateWindowData();
|
||||||
|
|
||||||
if (PWINDOW->m_bIsFloating) {
|
if (PWINDOW->m_bIsFloating) {
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowCreatedFloating(PWINDOW);
|
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
|
||||||
PWINDOW->m_bCreatedOverFullscreen = true;
|
PWINDOW->m_bCreatedOverFullscreen = true;
|
||||||
|
|
||||||
// size and move rules
|
// size and move rules
|
||||||
for (auto& r : PWINDOW->m_vMatchedRules) {
|
for (auto const& r : PWINDOW->m_vMatchedRules) {
|
||||||
if (r.szRule.starts_with("size")) {
|
if (r.szRule.starts_with("size")) {
|
||||||
try {
|
try {
|
||||||
const auto VALUE = r.szRule.substr(r.szRule.find(' ') + 1);
|
const auto VALUE = r.szRule.substr(r.szRule.find(' ') + 1);
|
||||||
|
@ -345,6 +346,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
Debug::log(LOG, "Rule size, applying to {}", PWINDOW);
|
Debug::log(LOG, "Rule size, applying to {}", PWINDOW);
|
||||||
|
|
||||||
PWINDOW->m_vRealSize = Vector2D(SIZEX, SIZEY);
|
PWINDOW->m_vRealSize = Vector2D(SIZEX, SIZEY);
|
||||||
|
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goal();
|
||||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
|
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
|
||||||
|
|
||||||
PWINDOW->setHidden(false);
|
PWINDOW->setHidden(false);
|
||||||
|
@ -449,7 +451,35 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
} else {
|
} else {
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
|
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
|
||||||
|
|
||||||
// Set the pseudo size here too so that it doesnt end up being 0x0
|
bool setPseudo = false;
|
||||||
|
|
||||||
|
for (auto const& r : PWINDOW->m_vMatchedRules) {
|
||||||
|
if (r.szRule.starts_with("size")) {
|
||||||
|
try {
|
||||||
|
const auto VALUE = r.szRule.substr(r.szRule.find(' ') + 1);
|
||||||
|
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' '));
|
||||||
|
const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1);
|
||||||
|
|
||||||
|
const auto MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(PWINDOW);
|
||||||
|
|
||||||
|
const auto SIZEX = SIZEXSTR == "max" ?
|
||||||
|
std::clamp(MAXSIZE.x, 20.0, PMONITOR->vecSize.x) :
|
||||||
|
(!SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stof(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.x);
|
||||||
|
const auto SIZEY = SIZEYSTR == "max" ?
|
||||||
|
std::clamp(MAXSIZE.y, 20.0, PMONITOR->vecSize.y) :
|
||||||
|
(!SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stof(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01 * PMONITOR->vecSize.y);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Rule size (tiled), applying to {}", PWINDOW);
|
||||||
|
|
||||||
|
setPseudo = true;
|
||||||
|
PWINDOW->m_vPseudoSize = Vector2D(SIZEX, SIZEY);
|
||||||
|
|
||||||
|
PWINDOW->setHidden(false);
|
||||||
|
} catch (...) { Debug::log(LOG, "Rule size failed, rule: {} -> {}", r.szRule, r.szValue); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!setPseudo)
|
||||||
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goal() - Vector2D(10, 10);
|
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goal() - Vector2D(10, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,7 +507,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PWINDOW->m_sWindowData.noFocus.valueOrDefault() && !PWINDOW->m_bNoInitialFocus &&
|
if (!PWINDOW->m_sWindowData.noFocus.valueOrDefault() && !PWINDOW->m_bNoInitialFocus &&
|
||||||
(PWINDOW->m_iX11Type != 2 || (PWINDOW->m_bIsX11 && PWINDOW->m_pXWaylandSurface->wantsFocus())) && !workspaceSilent && (!PFORCEFOCUS || PFORCEFOCUS == PWINDOW) &&
|
(!PWINDOW->isX11OverrideRedirect() || (PWINDOW->m_bIsX11 && PWINDOW->m_pXWaylandSurface->wantsFocus())) && !workspaceSilent && (!PFORCEFOCUS || PFORCEFOCUS == PWINDOW) &&
|
||||||
!g_pInputManager->isConstrained()) {
|
!g_pInputManager->isConstrained()) {
|
||||||
g_pCompositor->focusWindow(PWINDOW);
|
g_pCompositor->focusWindow(PWINDOW);
|
||||||
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA);
|
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA);
|
||||||
|
@ -577,7 +607,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
|
|
||||||
g_pCompositor->updateWorkspaceWindows(PWINDOW->workspaceID());
|
g_pCompositor->updateWorkspaceWindows(PWINDOW->workspaceID());
|
||||||
|
|
||||||
if (PMONITOR && PWINDOW->m_iX11Type == 2)
|
if (PMONITOR && PWINDOW->isX11OverrideRedirect())
|
||||||
PWINDOW->m_fX11SurfaceScaledBy = PMONITOR->scale;
|
PWINDOW->m_fX11SurfaceScaledBy = PMONITOR->scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,7 +678,12 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||||
|
|
||||||
// refocus on a new window if needed
|
// refocus on a new window if needed
|
||||||
if (wasLastWindow) {
|
if (wasLastWindow) {
|
||||||
const auto PWINDOWCANDIDATE = g_pLayoutManager->getCurrentLayout()->getNextWindowCandidate(PWINDOW);
|
static auto FOCUSONCLOSE = CConfigValue<Hyprlang::INT>("input:focus_on_close");
|
||||||
|
PHLWINDOW PWINDOWCANDIDATE = nullptr;
|
||||||
|
if (*FOCUSONCLOSE)
|
||||||
|
PWINDOWCANDIDATE = (g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING));
|
||||||
|
else
|
||||||
|
PWINDOWCANDIDATE = g_pLayoutManager->getCurrentLayout()->getNextWindowCandidate(PWINDOW);
|
||||||
|
|
||||||
Debug::log(LOG, "On closed window, new focused candidate is {}", PWINDOWCANDIDATE);
|
Debug::log(LOG, "On closed window, new focused candidate is {}", PWINDOWCANDIDATE);
|
||||||
|
|
||||||
|
@ -717,41 +752,35 @@ void Events::listener_commitWindow(void* owner, void* data) {
|
||||||
const auto MINSIZE = PWINDOW->m_pXDGSurface->toplevel->current.minSize;
|
const auto MINSIZE = PWINDOW->m_pXDGSurface->toplevel->current.minSize;
|
||||||
const auto MAXSIZE = PWINDOW->m_pXDGSurface->toplevel->current.maxSize;
|
const auto MAXSIZE = PWINDOW->m_pXDGSurface->toplevel->current.maxSize;
|
||||||
|
|
||||||
if (MAXSIZE > Vector2D{1, 1}) {
|
PWINDOW->clampWindowSize(MINSIZE, MAXSIZE > Vector2D{1, 1} ? std::optional<Vector2D>{MAXSIZE} : std::nullopt);
|
||||||
const auto REALSIZE = PWINDOW->m_vRealSize.goal();
|
|
||||||
Vector2D newSize = REALSIZE;
|
|
||||||
|
|
||||||
if (MAXSIZE.x < newSize.x)
|
|
||||||
newSize.x = MAXSIZE.x;
|
|
||||||
if (MAXSIZE.y < newSize.y)
|
|
||||||
newSize.y = MAXSIZE.y;
|
|
||||||
if (MINSIZE.x > newSize.x)
|
|
||||||
newSize.x = MINSIZE.x;
|
|
||||||
if (MINSIZE.y > newSize.y)
|
|
||||||
newSize.y = MINSIZE.y;
|
|
||||||
|
|
||||||
const Vector2D DELTA = REALSIZE - newSize;
|
|
||||||
|
|
||||||
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goal() + DELTA / 2.0;
|
|
||||||
PWINDOW->m_vRealSize = newSize;
|
|
||||||
g_pXWaylandManager->setWindowSize(PWINDOW, newSize);
|
|
||||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!PWINDOW->m_pWorkspace->m_bVisible)
|
if (!PWINDOW->m_pWorkspace->m_bVisible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||||
|
|
||||||
|
PMONITOR->debugLastPresentation(g_pSeatManager->isPointerFrameCommit ? "listener_commitWindow skip" : "listener_commitWindow");
|
||||||
|
if (g_pSeatManager->isPointerFrameCommit) {
|
||||||
|
g_pSeatManager->isPointerFrameSkipped = false;
|
||||||
|
g_pSeatManager->isPointerFrameCommit = false;
|
||||||
|
} else
|
||||||
g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface->resource(), PWINDOW->m_vRealPosition.goal().x, PWINDOW->m_vRealPosition.goal().y,
|
g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface->resource(), PWINDOW->m_vRealPosition.goal().x, PWINDOW->m_vRealPosition.goal().y,
|
||||||
PWINDOW->m_bIsX11 ? 1.0 / PWINDOW->m_fX11SurfaceScaledBy : 1.0);
|
PWINDOW->m_bIsX11 ? 1.0 / PWINDOW->m_fX11SurfaceScaledBy : 1.0);
|
||||||
|
|
||||||
|
if (g_pSeatManager->isPointerFrameSkipped) {
|
||||||
|
g_pPointerManager->sendStoredMovement();
|
||||||
|
g_pSeatManager->sendPointerFrame();
|
||||||
|
g_pSeatManager->isPointerFrameCommit = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!PWINDOW->m_bIsX11) {
|
if (!PWINDOW->m_bIsX11) {
|
||||||
PWINDOW->m_pSubsurfaceHead->recheckDamageForSubsurfaces();
|
PWINDOW->m_pSubsurfaceHead->recheckDamageForSubsurfaces();
|
||||||
PWINDOW->m_pPopupHead->recheckTree();
|
PWINDOW->m_pPopupHead->recheckTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
// tearing: if solitary, redraw it. This still might be a single surface window
|
// tearing: if solitary, redraw it. This still might be a single surface window
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
|
||||||
if (PMONITOR && PMONITOR->solitaryClient.lock() == PWINDOW && PWINDOW->canBeTorn() && PMONITOR->tearingState.canTear && PWINDOW->m_pWLSurface->resource()->current.texture) {
|
if (PMONITOR && PMONITOR->solitaryClient.lock() == PWINDOW && PWINDOW->canBeTorn() && PMONITOR->tearingState.canTear && PWINDOW->m_pWLSurface->resource()->current.texture) {
|
||||||
CRegion damageBox{PWINDOW->m_pWLSurface->resource()->accumulateCurrentBufferDamage()};
|
CRegion damageBox{PWINDOW->m_pWLSurface->resource()->accumulateCurrentBufferDamage()};
|
||||||
|
|
||||||
|
@ -811,7 +840,7 @@ void Events::listener_activateX11(void* owner, void* data) {
|
||||||
|
|
||||||
Debug::log(LOG, "X11 Activate request for window {}", PWINDOW);
|
Debug::log(LOG, "X11 Activate request for window {}", PWINDOW);
|
||||||
|
|
||||||
if (PWINDOW->m_iX11Type == 2) {
|
if (PWINDOW->isX11OverrideRedirect()) {
|
||||||
|
|
||||||
Debug::log(LOG, "Unmanaged X11 {} requests activate", PWINDOW);
|
Debug::log(LOG, "Unmanaged X11 {} requests activate", PWINDOW);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ void CBezierCurve::setup(std::vector<Vector2D>* pVec) {
|
||||||
|
|
||||||
m_dPoints.emplace_back(Vector2D(0, 0));
|
m_dPoints.emplace_back(Vector2D(0, 0));
|
||||||
|
|
||||||
for (auto& p : *pVec) {
|
for (auto const& p : *pVec) {
|
||||||
m_dPoints.push_back(p);
|
m_dPoints.push_back(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
54
src/helpers/ByteOperations.hpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#define ULL unsigned long long
|
||||||
|
#define LD long double
|
||||||
|
|
||||||
|
constexpr ULL operator""_kB(const ULL BYTES) {
|
||||||
|
return BYTES * 1024;
|
||||||
|
}
|
||||||
|
constexpr ULL operator""_MB(const ULL BYTES) {
|
||||||
|
return BYTES * 1024 * 1024;
|
||||||
|
}
|
||||||
|
constexpr ULL operator""_GB(const ULL BYTES) {
|
||||||
|
return BYTES * 1024 * 1024 * 1024;
|
||||||
|
}
|
||||||
|
constexpr ULL operator""_TB(const ULL BYTES) {
|
||||||
|
return BYTES * 1024 * 1024 * 1024 * 1024;
|
||||||
|
}
|
||||||
|
constexpr LD operator""_kB(const LD BYTES) {
|
||||||
|
return BYTES * 1024;
|
||||||
|
}
|
||||||
|
constexpr LD operator""_MB(const LD BYTES) {
|
||||||
|
return BYTES * 1024 * 1024;
|
||||||
|
}
|
||||||
|
constexpr LD operator""_GB(const LD BYTES) {
|
||||||
|
return BYTES * 1024 * 1024 * 1024;
|
||||||
|
}
|
||||||
|
constexpr LD operator""_TB(const LD BYTES) {
|
||||||
|
return BYTES * 1024 * 1024 * 1024 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using __acceptable_byte_operation_type = typename std::enable_if<std::is_trivially_constructible<T, ULL>::value || std::is_trivially_constructible<T, LD>::value>::type;
|
||||||
|
|
||||||
|
template <typename X, typename = __acceptable_byte_operation_type<X>>
|
||||||
|
constexpr X kBtoBytes(const X kB) {
|
||||||
|
return kB * 1024;
|
||||||
|
}
|
||||||
|
template <typename X, typename = __acceptable_byte_operation_type<X>>
|
||||||
|
constexpr X MBtoBytes(const X MB) {
|
||||||
|
return MB * 1024 * 1024;
|
||||||
|
}
|
||||||
|
template <typename X, typename = __acceptable_byte_operation_type<X>>
|
||||||
|
constexpr X GBtoBytes(const X GB) {
|
||||||
|
return GB * 1024 * 1024 * 1024;
|
||||||
|
}
|
||||||
|
template <typename X, typename = __acceptable_byte_operation_type<X>>
|
||||||
|
constexpr X TBtoBytes(const X TB) {
|
||||||
|
return TB * 1024 * 1024 * 1024 * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ULL
|
||||||
|
#undef LD
|
|
@ -21,6 +21,6 @@ CColor::CColor(uint64_t hex) {
|
||||||
this->a = ALPHA(hex);
|
this->a = ALPHA(hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t CColor::getAsHex() {
|
uint32_t CColor::getAsHex() const {
|
||||||
return (uint32_t)(a * 255.f) * 0x1000000 + (uint32_t)(r * 255.f) * 0x10000 + (uint32_t)(g * 255.f) * 0x100 + (uint32_t)(b * 255.f) * 0x1;
|
return (uint32_t)(a * 255.f) * 0x1000000 + (uint32_t)(r * 255.f) * 0x10000 + (uint32_t)(g * 255.f) * 0x100 + (uint32_t)(b * 255.f) * 0x1;
|
||||||
}
|
}
|
|
@ -10,7 +10,8 @@ class CColor {
|
||||||
|
|
||||||
float r = 0, g = 0, b = 0, a = 1.f;
|
float r = 0, g = 0, b = 0, a = 1.f;
|
||||||
|
|
||||||
uint32_t getAsHex();
|
// AR32
|
||||||
|
uint32_t getAsHex() const;
|
||||||
|
|
||||||
CColor operator-(const CColor& c2) const {
|
CColor operator-(const CColor& c2) const {
|
||||||
return CColor(r - c2.r, g - c2.g, b - c2.b, a - c2.a);
|
return CColor(r - c2.r, g - c2.g, b - c2.b, a - c2.a);
|
||||||
|
|
|
@ -252,7 +252,7 @@ DRMFormat FormatUtils::shmToDRM(SHMFormat shm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const SPixelFormat* FormatUtils::getPixelFormatFromDRM(DRMFormat drm) {
|
const SPixelFormat* FormatUtils::getPixelFormatFromDRM(DRMFormat drm) {
|
||||||
for (auto& fmt : GLES3_FORMATS) {
|
for (auto const& fmt : GLES3_FORMATS) {
|
||||||
if (fmt.drmFormat == drm)
|
if (fmt.drmFormat == drm)
|
||||||
return &fmt;
|
return &fmt;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +261,7 @@ const SPixelFormat* FormatUtils::getPixelFormatFromDRM(DRMFormat drm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const SPixelFormat* FormatUtils::getPixelFormatFromGL(uint32_t glFormat, uint32_t glType, bool alpha) {
|
const SPixelFormat* FormatUtils::getPixelFormatFromGL(uint32_t glFormat, uint32_t glType, bool alpha) {
|
||||||
for (auto& fmt : GLES3_FORMATS) {
|
for (auto const& fmt : GLES3_FORMATS) {
|
||||||
if (fmt.glFormat == (int)glFormat && fmt.glType == (int)glType && fmt.withAlpha == alpha)
|
if (fmt.glFormat == (int)glFormat && fmt.glType == (int)glType && fmt.withAlpha == alpha)
|
||||||
return &fmt;
|
return &fmt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ void handleNoop(struct wl_listener* listener, void* data) {
|
||||||
|
|
||||||
std::string escapeJSONStrings(const std::string& str) {
|
std::string escapeJSONStrings(const std::string& str) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
for (auto& c : str) {
|
for (auto const& c : str) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '"': oss << "\\\""; break;
|
case '"': oss << "\\\""; break;
|
||||||
case '\\': oss << "\\\\"; break;
|
case '\\': oss << "\\\\"; break;
|
||||||
|
@ -249,17 +249,17 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
return {WORKSPACE_INVALID};
|
return {WORKSPACE_INVALID};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<int> invalidWSes;
|
std::set<WORKSPACEID> invalidWSes;
|
||||||
if (same_mon) {
|
if (same_mon) {
|
||||||
for (auto& rule : g_pConfigManager->getAllWorkspaceRules()) {
|
for (auto const& rule : g_pConfigManager->getAllWorkspaceRules()) {
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromName(rule.monitor);
|
const auto PMONITOR = g_pCompositor->getMonitorFromName(rule.monitor);
|
||||||
if (PMONITOR && (PMONITOR->ID != g_pCompositor->m_pLastMonitor->ID))
|
if (PMONITOR && (PMONITOR->ID != g_pCompositor->m_pLastMonitor->ID))
|
||||||
invalidWSes.insert(rule.workspaceId);
|
invalidWSes.insert(rule.workspaceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int id = next ? g_pCompositor->m_pLastMonitor->activeWorkspaceID() : 0;
|
WORKSPACEID id = next ? g_pCompositor->m_pLastMonitor->activeWorkspaceID() : 0;
|
||||||
while (++id < INT_MAX) {
|
while (++id < LONG_MAX) {
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(id);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(id);
|
||||||
if (!invalidWSes.contains(id) && (!PWORKSPACE || g_pCompositor->getWindowsOnWorkspace(id) == 0)) {
|
if (!invalidWSes.contains(id) && (!PWORKSPACE || g_pCompositor->getWindowsOnWorkspace(id) == 0)) {
|
||||||
result.id = id;
|
result.id = id;
|
||||||
|
@ -296,18 +296,18 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
|
|
||||||
result.id = (int)PLUSMINUSRESULT.value();
|
result.id = (int)PLUSMINUSRESULT.value();
|
||||||
|
|
||||||
int remains = (int)result.id;
|
WORKSPACEID remains = result.id;
|
||||||
|
|
||||||
std::set<int> invalidWSes;
|
std::set<WORKSPACEID> invalidWSes;
|
||||||
|
|
||||||
// Collect all the workspaces we can't jump to.
|
// Collect all the workspaces we can't jump to.
|
||||||
for (auto& ws : g_pCompositor->m_vWorkspaces) {
|
for (auto const& ws : g_pCompositor->m_vWorkspaces) {
|
||||||
if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID)) {
|
if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID)) {
|
||||||
// Can't jump to this workspace
|
// Can't jump to this workspace
|
||||||
invalidWSes.insert(ws->m_iID);
|
invalidWSes.insert(ws->m_iID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto& rule : g_pConfigManager->getAllWorkspaceRules()) {
|
for (auto const& rule : g_pConfigManager->getAllWorkspaceRules()) {
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromName(rule.monitor);
|
const auto PMONITOR = g_pCompositor->getMonitorFromName(rule.monitor);
|
||||||
if (!PMONITOR || PMONITOR->ID == g_pCompositor->m_pLastMonitor->ID) {
|
if (!PMONITOR || PMONITOR->ID == g_pCompositor->m_pLastMonitor->ID) {
|
||||||
// Can't be invalid
|
// Can't be invalid
|
||||||
|
@ -318,8 +318,8 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare all named workspaces in case when we need them
|
// Prepare all named workspaces in case when we need them
|
||||||
std::vector<int> namedWSes;
|
std::vector<WORKSPACEID> namedWSes;
|
||||||
for (auto& ws : g_pCompositor->m_vWorkspaces) {
|
for (auto const& ws : g_pCompositor->m_vWorkspaces) {
|
||||||
if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID) || ws->m_iID >= 0)
|
if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID) || ws->m_iID >= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -347,19 +347,19 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Just take a blind guess at where we'll probably end up
|
// Just take a blind guess at where we'll probably end up
|
||||||
int activeWSID = g_pCompositor->m_pLastMonitor->activeWorkspace ? g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID : 1;
|
WORKSPACEID activeWSID = g_pCompositor->m_pLastMonitor->activeWorkspace ? g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID : 1;
|
||||||
int predictedWSID = activeWSID + remains;
|
WORKSPACEID predictedWSID = activeWSID + remains;
|
||||||
int remainingWSes = 0;
|
int remainingWSes = 0;
|
||||||
char walkDir = in[1];
|
char walkDir = in[1];
|
||||||
|
|
||||||
// sanitize. 0 means invalid oob in -
|
// sanitize. 0 means invalid oob in -
|
||||||
predictedWSID = std::max(predictedWSID, 0);
|
predictedWSID = std::max(predictedWSID, static_cast<int64_t>(0));
|
||||||
|
|
||||||
// Count how many invalidWSes are in between (how bad the prediction was)
|
// Count how many invalidWSes are in between (how bad the prediction was)
|
||||||
int beginID = in[1] == '+' ? activeWSID + 1 : predictedWSID;
|
WORKSPACEID beginID = in[1] == '+' ? activeWSID + 1 : predictedWSID;
|
||||||
int endID = in[1] == '+' ? predictedWSID : activeWSID;
|
WORKSPACEID endID = in[1] == '+' ? predictedWSID : activeWSID;
|
||||||
auto begin = invalidWSes.upper_bound(beginID - 1); // upper_bound is >, we want >=
|
auto begin = invalidWSes.upper_bound(beginID - 1); // upper_bound is >, we want >=
|
||||||
for (auto it = begin; *it <= endID && it != invalidWSes.end(); it++) {
|
for (auto it = begin; it != invalidWSes.end() && *it <= endID; it++) {
|
||||||
remainingWSes++;
|
remainingWSes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +367,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
if (activeWSID < 0) {
|
if (activeWSID < 0) {
|
||||||
// Behaviour similar to 'm'
|
// Behaviour similar to 'm'
|
||||||
// Find current
|
// Find current
|
||||||
int currentItem = -1;
|
size_t currentItem = -1;
|
||||||
for (size_t i = 0; i < namedWSes.size(); i++) {
|
for (size_t i = 0; i < namedWSes.size(); i++) {
|
||||||
if (namedWSes[i] == activeWSID) {
|
if (namedWSes[i] == activeWSID) {
|
||||||
currentItem = i;
|
currentItem = i;
|
||||||
|
@ -376,15 +376,15 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
}
|
}
|
||||||
|
|
||||||
currentItem += remains;
|
currentItem += remains;
|
||||||
currentItem = std::max(currentItem, 0);
|
currentItem = std::max(currentItem, static_cast<size_t>(0));
|
||||||
if (currentItem >= (int)namedWSes.size()) {
|
if (currentItem >= namedWSes.size()) {
|
||||||
// At the seam between namedWSes and normal WSes. Behave like r+[diff] at imaginary ws 0
|
// At the seam between namedWSes and normal WSes. Behave like r+[diff] at imaginary ws 0
|
||||||
int diff = currentItem - (namedWSes.size() - 1);
|
size_t diff = currentItem - (namedWSes.size() - 1);
|
||||||
predictedWSID = diff;
|
predictedWSID = diff;
|
||||||
int beginID = 1;
|
WORKSPACEID beginID = 1;
|
||||||
int endID = predictedWSID;
|
WORKSPACEID endID = predictedWSID;
|
||||||
auto begin = invalidWSes.upper_bound(beginID - 1); // upper_bound is >, we want >=
|
auto begin = invalidWSes.upper_bound(beginID - 1); // upper_bound is >, we want >=
|
||||||
for (auto it = begin; *it <= endID && it != invalidWSes.end(); it++) {
|
for (auto it = begin; it != invalidWSes.end() && *it <= endID; it++) {
|
||||||
remainingWSes++;
|
remainingWSes++;
|
||||||
}
|
}
|
||||||
walkDir = '+';
|
walkDir = '+';
|
||||||
|
@ -397,10 +397,10 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
|
|
||||||
// Go in the search direction for remainingWSes
|
// Go in the search direction for remainingWSes
|
||||||
// The performance impact is directly proportional to the number of open and bound workspaces
|
// The performance impact is directly proportional to the number of open and bound workspaces
|
||||||
int finalWSID = predictedWSID;
|
WORKSPACEID finalWSID = predictedWSID;
|
||||||
if (walkDir == '-') {
|
if (walkDir == '-') {
|
||||||
int beginID = finalWSID;
|
WORKSPACEID beginID = finalWSID;
|
||||||
int curID = finalWSID;
|
WORKSPACEID curID = finalWSID;
|
||||||
while (--curID > 0 && remainingWSes > 0) {
|
while (--curID > 0 && remainingWSes > 0) {
|
||||||
if (!invalidWSes.contains(curID)) {
|
if (!invalidWSes.contains(curID)) {
|
||||||
remainingWSes--;
|
remainingWSes--;
|
||||||
|
@ -411,9 +411,9 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
if (namedWSes.size()) {
|
if (namedWSes.size()) {
|
||||||
// Go to the named workspaces
|
// Go to the named workspaces
|
||||||
// Need remainingWSes more
|
// Need remainingWSes more
|
||||||
int namedWSIdx = namedWSes.size() - remainingWSes;
|
auto namedWSIdx = namedWSes.size() - remainingWSes;
|
||||||
// Sanitze
|
// Sanitze
|
||||||
namedWSIdx = std::clamp(namedWSIdx, 0, (int)namedWSes.size() - 1);
|
namedWSIdx = std::clamp(namedWSIdx, static_cast<size_t>(0), namedWSes.size() - static_cast<size_t>(1));
|
||||||
finalWSID = namedWSes[namedWSIdx];
|
finalWSID = namedWSes[namedWSIdx];
|
||||||
} else {
|
} else {
|
||||||
// Couldn't find valid workspace in negative direction, search last first one back up positive direction
|
// Couldn't find valid workspace in negative direction, search last first one back up positive direction
|
||||||
|
@ -425,7 +425,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (walkDir == '+') {
|
if (walkDir == '+') {
|
||||||
int curID = finalWSID;
|
WORKSPACEID curID = finalWSID;
|
||||||
while (++curID < INT32_MAX && remainingWSes > 0) {
|
while (++curID < INT32_MAX && remainingWSes > 0) {
|
||||||
if (!invalidWSes.contains(curID)) {
|
if (!invalidWSes.contains(curID)) {
|
||||||
remainingWSes--;
|
remainingWSes--;
|
||||||
|
@ -462,8 +462,8 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
// result now has +/- what we should move on mon
|
// result now has +/- what we should move on mon
|
||||||
int remains = (int)result.id;
|
int remains = (int)result.id;
|
||||||
|
|
||||||
std::vector<int> validWSes;
|
std::vector<WORKSPACEID> validWSes;
|
||||||
for (auto& ws : g_pCompositor->m_vWorkspaces) {
|
for (auto const& ws : g_pCompositor->m_vWorkspaces) {
|
||||||
if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID && !onAllMonitors))
|
if (ws->m_bIsSpecialWorkspace || (ws->m_iMonitorID != g_pCompositor->m_pLastMonitor->ID && !onAllMonitors))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -472,7 +472,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
|
|
||||||
std::sort(validWSes.begin(), validWSes.end());
|
std::sort(validWSes.begin(), validWSes.end());
|
||||||
|
|
||||||
int currentItem = -1;
|
ssize_t currentItem = -1;
|
||||||
|
|
||||||
if (absolute) {
|
if (absolute) {
|
||||||
// 1-index
|
// 1-index
|
||||||
|
@ -481,7 +481,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
// clamp
|
// clamp
|
||||||
if (currentItem < 0) {
|
if (currentItem < 0) {
|
||||||
currentItem = 0;
|
currentItem = 0;
|
||||||
} else if (currentItem >= (int)validWSes.size()) {
|
} else if (currentItem >= (ssize_t)validWSes.size()) {
|
||||||
currentItem = validWSes.size() - 1;
|
currentItem = validWSes.size() - 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -489,8 +489,8 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
remains = remains < 0 ? -((-remains) % validWSes.size()) : remains % validWSes.size();
|
remains = remains < 0 ? -((-remains) % validWSes.size()) : remains % validWSes.size();
|
||||||
|
|
||||||
// get the current item
|
// get the current item
|
||||||
int activeWSID = g_pCompositor->m_pLastMonitor->activeWorkspace ? g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID : 1;
|
WORKSPACEID activeWSID = g_pCompositor->m_pLastMonitor->activeWorkspace ? g_pCompositor->m_pLastMonitor->activeWorkspace->m_iID : 1;
|
||||||
for (size_t i = 0; i < validWSes.size(); i++) {
|
for (ssize_t i = 0; i < (ssize_t)validWSes.size(); i++) {
|
||||||
if (validWSes[i] == activeWSID) {
|
if (validWSes[i] == activeWSID) {
|
||||||
currentItem = i;
|
currentItem = i;
|
||||||
break;
|
break;
|
||||||
|
@ -501,7 +501,7 @@ SWorkspaceIDName getWorkspaceIDNameFromString(const std::string& in) {
|
||||||
currentItem += remains;
|
currentItem += remains;
|
||||||
|
|
||||||
// sanitize
|
// sanitize
|
||||||
if (currentItem >= (int)validWSes.size()) {
|
if (currentItem >= (ssize_t)validWSes.size()) {
|
||||||
currentItem = currentItem % validWSes.size();
|
currentItem = currentItem % validWSes.size();
|
||||||
} else if (currentItem < 0) {
|
} else if (currentItem < 0) {
|
||||||
currentItem = validWSes.size() + currentItem;
|
currentItem = validWSes.size() + currentItem;
|
||||||
|
@ -547,7 +547,7 @@ std::optional<std::string> cleanCmdForWorkspace(const std::string& inWorkspaceNa
|
||||||
const std::string workspaceRule = "workspace " + inWorkspaceName;
|
const std::string workspaceRule = "workspace " + inWorkspaceName;
|
||||||
|
|
||||||
if (cmd[0] == '[') {
|
if (cmd[0] == '[') {
|
||||||
const int closingBracketIdx = cmd.find_last_of(']');
|
const auto closingBracketIdx = cmd.find_last_of(']');
|
||||||
auto tmpRules = cmd.substr(1, closingBracketIdx - 1);
|
auto tmpRules = cmd.substr(1, closingBracketIdx - 1);
|
||||||
cmd = cmd.substr(closingBracketIdx + 1);
|
cmd = cmd.substr(closingBracketIdx + 1);
|
||||||
|
|
||||||
|
@ -628,27 +628,6 @@ void logSystemInfo() {
|
||||||
Debug::log(NONE, "{}", execAndGet("cat /etc/os-release"));
|
Debug::log(NONE, "{}", execAndGet("cat /etc/os-release"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void matrixProjection(float mat[9], int w, int h, wl_output_transform tr) {
|
|
||||||
memset(mat, 0, sizeof(*mat) * 9);
|
|
||||||
|
|
||||||
const float* t = transforms[tr];
|
|
||||||
float x = 2.0f / w;
|
|
||||||
float y = 2.0f / h;
|
|
||||||
|
|
||||||
// Rotation + reflection
|
|
||||||
mat[0] = x * t[0];
|
|
||||||
mat[1] = x * t[1];
|
|
||||||
mat[3] = y * t[3];
|
|
||||||
mat[4] = y * t[4];
|
|
||||||
|
|
||||||
// Translation
|
|
||||||
mat[2] = -copysign(1.0f, mat[0] + mat[1]);
|
|
||||||
mat[5] = -copysign(1.0f, mat[3] + mat[4]);
|
|
||||||
|
|
||||||
// Identity
|
|
||||||
mat[8] = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t getPPIDof(int64_t pid) {
|
int64_t getPPIDof(int64_t pid) {
|
||||||
#if defined(KERN_PROC_PID)
|
#if defined(KERN_PROC_PID)
|
||||||
int mib[] = {
|
int mib[] = {
|
||||||
|
@ -785,13 +764,13 @@ std::vector<SCallstackFrameInfo> getBacktrace() {
|
||||||
|
|
||||||
#ifdef HAS_EXECINFO
|
#ifdef HAS_EXECINFO
|
||||||
void* bt[1024];
|
void* bt[1024];
|
||||||
size_t btSize;
|
int btSize;
|
||||||
char** btSymbols;
|
char** btSymbols;
|
||||||
|
|
||||||
btSize = backtrace(bt, 1024);
|
btSize = backtrace(bt, 1024);
|
||||||
btSymbols = backtrace_symbols(bt, btSize);
|
btSymbols = backtrace_symbols(bt, btSize);
|
||||||
|
|
||||||
for (size_t i = 0; i < btSize; ++i) {
|
for (auto i = 0; i < btSize; ++i) {
|
||||||
callstack.emplace_back(SCallstackFrameInfo{bt[i], std::string{btSymbols[i]}});
|
callstack.emplace_back(SCallstackFrameInfo{bt[i], std::string{btSymbols[i]}});
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include "math/Math.hpp"
|
#include "math/Math.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <format>
|
#include <format>
|
||||||
|
#include "../SharedDefs.hpp"
|
||||||
|
#include "../macros.hpp"
|
||||||
|
|
||||||
struct SCallstackFrameInfo {
|
struct SCallstackFrameInfo {
|
||||||
void* adr = nullptr;
|
void* adr = nullptr;
|
||||||
|
@ -13,7 +15,7 @@ struct SCallstackFrameInfo {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SWorkspaceIDName {
|
struct SWorkspaceIDName {
|
||||||
int id = -1;
|
WORKSPACEID id = WORKSPACE_INVALID;
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,7 +34,6 @@ int64_t getPPIDof(int64_t pid);
|
||||||
int64_t configStringToInt(const std::string&);
|
int64_t configStringToInt(const std::string&);
|
||||||
Vector2D configStringToVector2D(const std::string&);
|
Vector2D configStringToVector2D(const std::string&);
|
||||||
std::optional<float> getPlusMinusKeywordResult(std::string in, float relative);
|
std::optional<float> getPlusMinusKeywordResult(std::string in, float relative);
|
||||||
void matrixProjection(float mat[9], int w, int h, wl_output_transform tr);
|
|
||||||
double normalizeAngleRad(double ang);
|
double normalizeAngleRad(double ang);
|
||||||
std::vector<SCallstackFrameInfo> getBacktrace();
|
std::vector<SCallstackFrameInfo> getBacktrace();
|
||||||
void throwError(const std::string& err);
|
void throwError(const std::string& err);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "Monitor.hpp"
|
#include "Monitor.hpp"
|
||||||
#include "MiscFunctions.hpp"
|
#include "MiscFunctions.hpp"
|
||||||
#include "math/Math.hpp"
|
#include "math/Math.hpp"
|
||||||
|
#include "sync/SyncReleaser.hpp"
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../config/ConfigValue.hpp"
|
#include "../config/ConfigValue.hpp"
|
||||||
#include "../protocols/GammaControl.hpp"
|
#include "../protocols/GammaControl.hpp"
|
||||||
|
@ -8,13 +9,18 @@
|
||||||
#include "../protocols/LayerShell.hpp"
|
#include "../protocols/LayerShell.hpp"
|
||||||
#include "../protocols/PresentationTime.hpp"
|
#include "../protocols/PresentationTime.hpp"
|
||||||
#include "../protocols/DRMLease.hpp"
|
#include "../protocols/DRMLease.hpp"
|
||||||
|
#include "../protocols/DRMSyncobj.hpp"
|
||||||
#include "../protocols/core/Output.hpp"
|
#include "../protocols/core/Output.hpp"
|
||||||
#include "../managers/PointerManager.hpp"
|
#include "../managers/PointerManager.hpp"
|
||||||
|
#include "../managers/eventLoop/EventLoopManager.hpp"
|
||||||
#include "../protocols/core/Compositor.hpp"
|
#include "../protocols/core/Compositor.hpp"
|
||||||
#include "sync/SyncTimeline.hpp"
|
#include "sync/SyncTimeline.hpp"
|
||||||
#include <aquamarine/output/Output.hpp>
|
#include <aquamarine/output/Output.hpp>
|
||||||
|
#include "debug/Log.hpp"
|
||||||
#include <hyprutils/string/String.hpp>
|
#include <hyprutils/string/String.hpp>
|
||||||
|
#include <hyprutils/utils/ScopeGuard.hpp>
|
||||||
using namespace Hyprutils::String;
|
using namespace Hyprutils::String;
|
||||||
|
using namespace Hyprutils::Utils;
|
||||||
|
|
||||||
int ratHandler(void* data) {
|
int ratHandler(void* data) {
|
||||||
g_pHyprRenderer->renderMonitor((CMonitor*)data);
|
g_pHyprRenderer->renderMonitor((CMonitor*)data);
|
||||||
|
@ -22,7 +28,7 @@ int ratHandler(void* data) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CMonitor::CMonitor() : state(this) {
|
CMonitor::CMonitor(SP<Aquamarine::IOutput> output_) : state(this), output(output_) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +37,7 @@ CMonitor::~CMonitor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMonitor::onConnect(bool noRule) {
|
void CMonitor::onConnect(bool noRule) {
|
||||||
|
CScopeGuard x = {[]() { g_pCompositor->arrangeMonitors(); }};
|
||||||
|
|
||||||
if (output->supportsExplicit) {
|
if (output->supportsExplicit) {
|
||||||
inTimeline = CSyncTimeline::create(output->getBackend()->drmFD());
|
inTimeline = CSyncTimeline::create(output->getBackend()->drmFD());
|
||||||
|
@ -38,13 +45,26 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
}
|
}
|
||||||
|
|
||||||
listeners.frame = output->events.frame.registerListener([this](std::any d) { Events::listener_monitorFrame(this, nullptr); });
|
listeners.frame = output->events.frame.registerListener([this](std::any d) { Events::listener_monitorFrame(this, nullptr); });
|
||||||
listeners.destroy = output->events.destroy.registerListener([this](std::any d) { Events::listener_monitorDestroy(this, nullptr); });
|
|
||||||
listeners.commit = output->events.commit.registerListener([this](std::any d) { Events::listener_monitorCommit(this, nullptr); });
|
listeners.commit = output->events.commit.registerListener([this](std::any d) { Events::listener_monitorCommit(this, nullptr); });
|
||||||
listeners.needsFrame =
|
listeners.needsFrame =
|
||||||
output->events.needsFrame.registerListener([this](std::any d) { g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); });
|
output->events.needsFrame.registerListener([this](std::any d) { g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); });
|
||||||
|
|
||||||
listeners.presented = output->events.present.registerListener([this](std::any d) {
|
listeners.presented = output->events.present.registerListener([this](std::any d) {
|
||||||
auto E = std::any_cast<Aquamarine::IOutput::SPresentEvent>(d);
|
auto E = std::any_cast<Aquamarine::IOutput::SPresentEvent>(d);
|
||||||
PROTO::presentation->onPresented(this, E.when, E.refresh, E.seq, E.flags);
|
PROTO::presentation->onPresented(self.lock(), E.when, E.refresh, E.seq, E.flags);
|
||||||
|
});
|
||||||
|
|
||||||
|
listeners.destroy = output->events.destroy.registerListener([this](std::any d) {
|
||||||
|
Debug::log(LOG, "Destroy called for monitor {}", szName);
|
||||||
|
|
||||||
|
onDisconnect(true);
|
||||||
|
|
||||||
|
output = nullptr;
|
||||||
|
m_bRenderingInitPassed = false;
|
||||||
|
|
||||||
|
Debug::log(LOG, "Removing monitor {} from realMonitors", szName);
|
||||||
|
|
||||||
|
std::erase_if(g_pCompositor->m_vRealMonitors, [&](SP<CMonitor>& el) { return el.get() == this; });
|
||||||
});
|
});
|
||||||
|
|
||||||
listeners.state = output->events.state.registerListener([this](std::any d) {
|
listeners.state = output->events.state.registerListener([this](std::any d) {
|
||||||
|
@ -77,6 +97,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
tearingState.canTear = output->getBackend()->type() == Aquamarine::AQ_BACKEND_DRM;
|
tearingState.canTear = output->getBackend()->type() == Aquamarine::AQ_BACKEND_DRM;
|
||||||
|
|
||||||
if (m_bEnabled) {
|
if (m_bEnabled) {
|
||||||
|
output->state->resetExplicitFences();
|
||||||
output->state->setEnabled(true);
|
output->state->setEnabled(true);
|
||||||
state.commit();
|
state.commit();
|
||||||
return;
|
return;
|
||||||
|
@ -96,11 +117,12 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
createdByUser = true; // should be true. WL and Headless backends should be addable / removable
|
createdByUser = true; // should be true. WL and Headless backends should be addable / removable
|
||||||
|
|
||||||
// get monitor rule that matches
|
// get monitor rule that matches
|
||||||
SMonitorRule monitorRule = g_pConfigManager->getMonitorRuleFor(*this);
|
SMonitorRule monitorRule = g_pConfigManager->getMonitorRuleFor(self.lock());
|
||||||
|
|
||||||
// if it's disabled, disable and ignore
|
// if it's disabled, disable and ignore
|
||||||
if (monitorRule.disabled) {
|
if (monitorRule.disabled) {
|
||||||
|
|
||||||
|
output->state->resetExplicitFences();
|
||||||
output->state->setEnabled(false);
|
output->state->setEnabled(false);
|
||||||
|
|
||||||
if (!state.commit())
|
if (!state.commit())
|
||||||
|
@ -137,6 +159,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
|
|
||||||
m_bEnabled = true;
|
m_bEnabled = true;
|
||||||
|
|
||||||
|
output->state->resetExplicitFences();
|
||||||
output->state->setEnabled(true);
|
output->state->setEnabled(true);
|
||||||
|
|
||||||
// set mode, also applies
|
// set mode, also applies
|
||||||
|
@ -152,7 +175,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
|
|
||||||
setupDefaultWS(monitorRule);
|
setupDefaultWS(monitorRule);
|
||||||
|
|
||||||
for (auto& ws : g_pCompositor->m_vWorkspaces) {
|
for (auto const& ws : g_pCompositor->m_vWorkspaces) {
|
||||||
if (!valid(ws))
|
if (!valid(ws))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -173,10 +196,6 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
if (!activeMonitorRule.mirrorOf.empty())
|
if (!activeMonitorRule.mirrorOf.empty())
|
||||||
setMirror(activeMonitorRule.mirrorOf);
|
setMirror(activeMonitorRule.mirrorOf);
|
||||||
|
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent{"monitoradded", szName});
|
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent{"monitoraddedv2", std::format("{},{},{}", ID, szName, szShortDescription)});
|
|
||||||
EMIT_HOOK_EVENT("monitorAdded", this);
|
|
||||||
|
|
||||||
if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet
|
if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet
|
||||||
g_pCompositor->setActiveMonitor(this);
|
g_pCompositor->setActiveMonitor(this);
|
||||||
|
|
||||||
|
@ -188,7 +207,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
|
|
||||||
// verify last mon valid
|
// verify last mon valid
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||||
if (m == g_pCompositor->m_pLastMonitor) {
|
if (m == g_pCompositor->m_pLastMonitor) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
@ -205,9 +224,20 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
PROTO::gamma->applyGammaToState(this);
|
PROTO::gamma->applyGammaToState(this);
|
||||||
|
|
||||||
events.connect.emit();
|
events.connect.emit();
|
||||||
|
|
||||||
|
g_pEventManager->postEvent(SHyprIPCEvent{"monitoradded", szName});
|
||||||
|
g_pEventManager->postEvent(SHyprIPCEvent{"monitoraddedv2", std::format("{},{},{}", ID, szName, szShortDescription)});
|
||||||
|
EMIT_HOOK_EVENT("monitorAdded", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMonitor::onDisconnect(bool destroy) {
|
void CMonitor::onDisconnect(bool destroy) {
|
||||||
|
CScopeGuard x = {[this]() {
|
||||||
|
if (g_pCompositor->m_bIsShuttingDown)
|
||||||
|
return;
|
||||||
|
g_pEventManager->postEvent(SHyprIPCEvent{"monitorremoved", szName});
|
||||||
|
EMIT_HOOK_EVENT("monitorRemoved", this);
|
||||||
|
g_pCompositor->arrangeMonitors();
|
||||||
|
}};
|
||||||
|
|
||||||
if (renderTimer) {
|
if (renderTimer) {
|
||||||
wl_event_source_remove(renderTimer);
|
wl_event_source_remove(renderTimer);
|
||||||
|
@ -223,7 +253,7 @@ void CMonitor::onDisconnect(bool destroy) {
|
||||||
|
|
||||||
// Cleanup everything. Move windows back, snap cursor, shit.
|
// Cleanup everything. Move windows back, snap cursor, shit.
|
||||||
CMonitor* BACKUPMON = nullptr;
|
CMonitor* BACKUPMON = nullptr;
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||||
if (m.get() != this) {
|
if (m.get() != this) {
|
||||||
BACKUPMON = m.get();
|
BACKUPMON = m.get();
|
||||||
break;
|
break;
|
||||||
|
@ -240,7 +270,7 @@ void CMonitor::onDisconnect(bool destroy) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mirrors.empty()) {
|
if (!mirrors.empty()) {
|
||||||
for (auto& m : mirrors) {
|
for (auto const& m : mirrors) {
|
||||||
m->setMirror("");
|
m->setMirror("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +283,7 @@ void CMonitor::onDisconnect(bool destroy) {
|
||||||
listeners.commit.reset();
|
listeners.commit.reset();
|
||||||
|
|
||||||
for (size_t i = 0; i < 4; ++i) {
|
for (size_t i = 0; i < 4; ++i) {
|
||||||
for (auto& ls : m_aLayerSurfaceLayers[i]) {
|
for (auto const& ls : m_aLayerSurfaceLayers[i]) {
|
||||||
if (ls->layerSurface && !ls->fadingOut)
|
if (ls->layerSurface && !ls->fadingOut)
|
||||||
ls->layerSurface->sendClosed();
|
ls->layerSurface->sendClosed();
|
||||||
}
|
}
|
||||||
|
@ -262,9 +292,6 @@ void CMonitor::onDisconnect(bool destroy) {
|
||||||
|
|
||||||
Debug::log(LOG, "Removed monitor {}!", szName);
|
Debug::log(LOG, "Removed monitor {}!", szName);
|
||||||
|
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent{"monitorremoved", szName});
|
|
||||||
EMIT_HOOK_EVENT("monitorRemoved", this);
|
|
||||||
|
|
||||||
if (!BACKUPMON) {
|
if (!BACKUPMON) {
|
||||||
Debug::log(WARN, "Unplugged last monitor, entering an unsafe state. Good luck my friend.");
|
Debug::log(WARN, "Unplugged last monitor, entering an unsafe state. Good luck my friend.");
|
||||||
g_pCompositor->enterUnsafeState();
|
g_pCompositor->enterUnsafeState();
|
||||||
|
@ -279,13 +306,13 @@ void CMonitor::onDisconnect(bool destroy) {
|
||||||
|
|
||||||
// move workspaces
|
// move workspaces
|
||||||
std::deque<PHLWORKSPACE> wspToMove;
|
std::deque<PHLWORKSPACE> wspToMove;
|
||||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
for (auto const& w : g_pCompositor->m_vWorkspaces) {
|
||||||
if (w->m_iMonitorID == ID || !g_pCompositor->getMonitorFromID(w->m_iMonitorID)) {
|
if (w->m_iMonitorID == ID || !g_pCompositor->getMonitorFromID(w->m_iMonitorID)) {
|
||||||
wspToMove.push_back(w);
|
wspToMove.push_back(w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& w : wspToMove) {
|
for (auto const& w : wspToMove) {
|
||||||
w->m_szLastMonitor = szName;
|
w->m_szLastMonitor = szName;
|
||||||
g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON);
|
g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON);
|
||||||
w->startAnim(true, true, true);
|
w->startAnim(true, true, true);
|
||||||
|
@ -300,6 +327,7 @@ void CMonitor::onDisconnect(bool destroy) {
|
||||||
activeWorkspace->m_bVisible = false;
|
activeWorkspace->m_bVisible = false;
|
||||||
activeWorkspace.reset();
|
activeWorkspace.reset();
|
||||||
|
|
||||||
|
output->state->resetExplicitFences();
|
||||||
output->state->setEnabled(false);
|
output->state->setEnabled(false);
|
||||||
|
|
||||||
if (!state.commit())
|
if (!state.commit())
|
||||||
|
@ -312,7 +340,7 @@ void CMonitor::onDisconnect(bool destroy) {
|
||||||
int mostHz = 0;
|
int mostHz = 0;
|
||||||
CMonitor* pMonitorMostHz = nullptr;
|
CMonitor* pMonitorMostHz = nullptr;
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||||
if (m->refreshRate > mostHz && m.get() != this) {
|
if (m->refreshRate > mostHz && m.get() != this) {
|
||||||
pMonitorMostHz = m.get();
|
pMonitorMostHz = m.get();
|
||||||
mostHz = m->refreshRate;
|
mostHz = m->refreshRate;
|
||||||
|
@ -357,7 +385,7 @@ bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() {
|
||||||
*PNOBREAK && output->state->state().adaptiveSync && activeWorkspace && activeWorkspace->m_bHasFullscreenWindow && activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN;
|
*PNOBREAK && output->state->state().adaptiveSync && activeWorkspace && activeWorkspace->m_bHasFullscreenWindow && activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN;
|
||||||
|
|
||||||
// keep requested minimum refresh rate
|
// keep requested minimum refresh rate
|
||||||
if (shouldSkip && *PMINRR && lastPresentationTimer.getMillis() > 1000 / *PMINRR) {
|
if (shouldSkip && *PMINRR && lastPresentationTimer.getMillis() > 1000.0f / *PMINRR) {
|
||||||
// damage whole screen because some previous cursor box damages were skipped
|
// damage whole screen because some previous cursor box damages were skipped
|
||||||
damage.damageEntire();
|
damage.damageEntire();
|
||||||
return false;
|
return false;
|
||||||
|
@ -382,8 +410,8 @@ bool CMonitor::matchesStaticSelector(const std::string& selector) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int CMonitor::findAvailableDefaultWS() {
|
WORKSPACEID CMonitor::findAvailableDefaultWS() {
|
||||||
for (size_t i = 1; i < INT32_MAX; ++i) {
|
for (WORKSPACEID i = 1; i < LONG_MAX; ++i) {
|
||||||
if (g_pCompositor->getWorkspaceByID(i))
|
if (g_pCompositor->getWorkspaceByID(i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -393,7 +421,7 @@ int CMonitor::findAvailableDefaultWS() {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return INT32_MAX; // shouldn't be reachable
|
return LONG_MAX; // shouldn't be reachable
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) {
|
void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) {
|
||||||
|
@ -468,7 +496,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||||
pMirrorOf = nullptr;
|
pMirrorOf = nullptr;
|
||||||
|
|
||||||
// set rule
|
// set rule
|
||||||
const auto RULE = g_pConfigManager->getMonitorRuleFor(*this);
|
const auto RULE = g_pConfigManager->getMonitorRuleFor(self.lock());
|
||||||
|
|
||||||
vecPosition = RULE.offset;
|
vecPosition = RULE.offset;
|
||||||
|
|
||||||
|
@ -496,7 +524,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||||
g_pHyprRenderer->applyMonitorRule(this, (SMonitorRule*)&RULE, true); // will apply the offset and stuff
|
g_pHyprRenderer->applyMonitorRule(this, (SMonitorRule*)&RULE, true); // will apply the offset and stuff
|
||||||
} else {
|
} else {
|
||||||
CMonitor* BACKUPMON = nullptr;
|
CMonitor* BACKUPMON = nullptr;
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto const& m : g_pCompositor->m_vMonitors) {
|
||||||
if (m.get() != this) {
|
if (m.get() != this) {
|
||||||
BACKUPMON = m.get();
|
BACKUPMON = m.get();
|
||||||
break;
|
break;
|
||||||
|
@ -505,13 +533,13 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||||
|
|
||||||
// move all the WS
|
// move all the WS
|
||||||
std::deque<PHLWORKSPACE> wspToMove;
|
std::deque<PHLWORKSPACE> wspToMove;
|
||||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
for (auto const& w : g_pCompositor->m_vWorkspaces) {
|
||||||
if (w->m_iMonitorID == ID) {
|
if (w->m_iMonitorID == ID) {
|
||||||
wspToMove.push_back(w);
|
wspToMove.push_back(w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& w : wspToMove) {
|
for (auto const& w : wspToMove) {
|
||||||
g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON);
|
g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON);
|
||||||
w->startAnim(true, true, true);
|
w->startAnim(true, true, true);
|
||||||
}
|
}
|
||||||
|
@ -585,7 +613,7 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
|
||||||
pWorkspace->startAnim(true, ANIMTOLEFT);
|
pWorkspace->startAnim(true, ANIMTOLEFT);
|
||||||
|
|
||||||
// move pinned windows
|
// move pinned windows
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||||
if (w->m_pWorkspace == POLDWORKSPACE && w->m_bPinned)
|
if (w->m_pWorkspace == POLDWORKSPACE && w->m_bPinned)
|
||||||
w->moveToWorkspace(pWorkspace);
|
w->moveToWorkspace(pWorkspace);
|
||||||
}
|
}
|
||||||
|
@ -631,7 +659,7 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
|
||||||
g_pCompositor->updateFullscreenFadeOnWorkspace(activeSpecialWorkspace);
|
g_pCompositor->updateFullscreenFadeOnWorkspace(activeSpecialWorkspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMonitor::changeWorkspace(const int& id, bool internal, bool noMouseMove, bool noFocus) {
|
void CMonitor::changeWorkspace(const WORKSPACEID& id, bool internal, bool noMouseMove, bool noFocus) {
|
||||||
changeWorkspace(g_pCompositor->getWorkspaceByID(id), internal, noMouseMove, noFocus);
|
changeWorkspace(g_pCompositor->getWorkspaceByID(id), internal, noMouseMove, noFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -694,14 +722,14 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||||
if (animate)
|
if (animate)
|
||||||
pWorkspace->startAnim(true, true);
|
pWorkspace->startAnim(true, true);
|
||||||
|
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
for (auto const& w : g_pCompositor->m_vWindows) {
|
||||||
if (w->m_pWorkspace == pWorkspace) {
|
if (w->m_pWorkspace == pWorkspace) {
|
||||||
w->m_iMonitorID = ID;
|
w->m_iMonitorID = ID;
|
||||||
w->updateSurfaceScaleTransformDetails();
|
w->updateSurfaceScaleTransformDetails();
|
||||||
w->setAnimationsToMove();
|
w->setAnimationsToMove();
|
||||||
|
|
||||||
const auto MIDDLE = w->middle();
|
const auto MIDDLE = w->middle();
|
||||||
if (w->m_bIsFloating && !VECINRECT(MIDDLE, vecPosition.x, vecPosition.y, vecPosition.x + vecSize.x, vecPosition.y + vecSize.y) && w->m_iX11Type != 2) {
|
if (w->m_bIsFloating && !VECINRECT(MIDDLE, vecPosition.x, vecPosition.y, vecPosition.x + vecSize.x, vecPosition.y + vecSize.y) && !w->isX11OverrideRedirect()) {
|
||||||
// if it's floating and the middle isnt on the current mon, move it to the center
|
// if it's floating and the middle isnt on the current mon, move it to the center
|
||||||
const auto PMONFROMMIDDLE = g_pCompositor->getMonitorFromVector(MIDDLE);
|
const auto PMONFROMMIDDLE = g_pCompositor->getMonitorFromVector(MIDDLE);
|
||||||
Vector2D pos = w->m_vRealPosition.goal();
|
Vector2D pos = w->m_vRealPosition.goal();
|
||||||
|
@ -738,7 +766,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||||
g_pCompositor->updateSuspendedStates();
|
g_pCompositor->updateSuspendedStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMonitor::setSpecialWorkspace(const int& id) {
|
void CMonitor::setSpecialWorkspace(const WORKSPACEID& id) {
|
||||||
setSpecialWorkspace(g_pCompositor->getWorkspaceByID(id));
|
setSpecialWorkspace(g_pCompositor->getWorkspaceByID(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,19 +779,16 @@ Vector2D CMonitor::middle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMonitor::updateMatrix() {
|
void CMonitor::updateMatrix() {
|
||||||
matrixIdentity(projMatrix.data());
|
projMatrix = Mat3x3::identity();
|
||||||
if (transform != WL_OUTPUT_TRANSFORM_NORMAL) {
|
if (transform != WL_OUTPUT_TRANSFORM_NORMAL)
|
||||||
matrixTranslate(projMatrix.data(), vecPixelSize.x / 2.0, vecPixelSize.y / 2.0);
|
projMatrix.translate(vecPixelSize / 2.0).transform(wlTransformToHyprutils(transform)).translate(-vecTransformedSize / 2.0);
|
||||||
matrixTransform(projMatrix.data(), wlTransformToHyprutils(transform));
|
|
||||||
matrixTranslate(projMatrix.data(), -vecTransformedSize.x / 2.0, -vecTransformedSize.y / 2.0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t CMonitor::activeWorkspaceID() {
|
WORKSPACEID CMonitor::activeWorkspaceID() {
|
||||||
return activeWorkspace ? activeWorkspace->m_iID : 0;
|
return activeWorkspace ? activeWorkspace->m_iID : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t CMonitor::activeSpecialWorkspaceID() {
|
WORKSPACEID CMonitor::activeSpecialWorkspaceID() {
|
||||||
return activeSpecialWorkspace ? activeSpecialWorkspace->m_iID : 0;
|
return activeSpecialWorkspace ? activeSpecialWorkspace->m_iID : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -771,20 +796,28 @@ CBox CMonitor::logicalBox() {
|
||||||
return {vecPosition, vecSize};
|
return {vecPosition, vecSize};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void onDoneSource(void* data) {
|
void CMonitor::scheduleDone() {
|
||||||
auto pMonitor = (CMonitor*)data;
|
if (doneScheduled)
|
||||||
|
|
||||||
if (!PROTO::outputs.contains(pMonitor->szName))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PROTO::outputs.at(pMonitor->szName)->sendDone();
|
doneScheduled = true;
|
||||||
|
|
||||||
|
g_pEventLoopManager->doLater([M = self] {
|
||||||
|
if (!M) // if M is gone, we got destroyed, doesn't matter.
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!PROTO::outputs.contains(M->szName))
|
||||||
|
return;
|
||||||
|
|
||||||
|
PROTO::outputs.at(M->szName)->sendDone();
|
||||||
|
M->doneScheduled = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMonitor::scheduleDone() {
|
void CMonitor::setCTM(const Mat3x3& ctm_) {
|
||||||
if (doneSource)
|
ctm = ctm_;
|
||||||
return;
|
ctmUpdated = true;
|
||||||
|
g_pCompositor->scheduleFrameForMonitor(this, Aquamarine::IOutput::scheduleFrameReason::AQ_SCHEDULE_NEEDS_FRAME);
|
||||||
doneSource = wl_event_loop_add_idle(g_pCompositor->m_sWLEventLoop, ::onDoneSource, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMonitor::attemptDirectScanout() {
|
bool CMonitor::attemptDirectScanout() {
|
||||||
|
@ -808,28 +841,92 @@ bool CMonitor::attemptDirectScanout() {
|
||||||
if (!PSURFACE->current.buffer || !PSURFACE->current.texture || !PSURFACE->current.texture->m_pEglImage /* dmabuf */)
|
if (!PSURFACE->current.buffer || !PSURFACE->current.texture || !PSURFACE->current.texture->m_pEglImage /* dmabuf */)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Debug::log(TRACE, "attemptDirectScanout: surface {:x} passed, will attempt", (uintptr_t)PSURFACE.get());
|
||||||
|
|
||||||
// FIXME: make sure the buffer actually follows the available scanout dmabuf formats
|
// FIXME: make sure the buffer actually follows the available scanout dmabuf formats
|
||||||
// and comes from the appropriate device. This may implode on multi-gpu!!
|
// and comes from the appropriate device. This may implode on multi-gpu!!
|
||||||
|
|
||||||
|
const auto params = PSURFACE->current.buffer->buffer->dmabuf();
|
||||||
|
// scanout buffer isn't dmabuf, so no scanout
|
||||||
|
if (!params.success)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// entering into scanout, so save monitor format
|
||||||
|
if (lastScanout.expired())
|
||||||
|
prevDrmFormat = drmFormat;
|
||||||
|
|
||||||
|
if (drmFormat != params.format) {
|
||||||
|
output->state->setFormat(params.format);
|
||||||
|
drmFormat = params.format;
|
||||||
|
}
|
||||||
|
|
||||||
output->state->setBuffer(PSURFACE->current.buffer->buffer.lock());
|
output->state->setBuffer(PSURFACE->current.buffer->buffer.lock());
|
||||||
output->state->setPresentationMode(tearingState.activelyTearing ? Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_IMMEDIATE :
|
output->state->setPresentationMode(tearingState.activelyTearing ? Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_IMMEDIATE :
|
||||||
Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_VSYNC);
|
Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_VSYNC);
|
||||||
|
|
||||||
if (!state.test())
|
if (!state.test()) {
|
||||||
|
Debug::log(TRACE, "attemptDirectScanout: failed basic test");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto explicitOptions = g_pHyprRenderer->getExplicitSyncSettings();
|
||||||
|
|
||||||
|
// wait for the explicit fence if present, and if kms explicit is allowed
|
||||||
|
bool DOEXPLICIT = PSURFACE->syncobj && PSURFACE->syncobj->current.acquireTimeline && PSURFACE->syncobj->current.acquireTimeline->timeline && explicitOptions.explicitKMSEnabled;
|
||||||
|
int explicitWaitFD = -1;
|
||||||
|
if (DOEXPLICIT) {
|
||||||
|
explicitWaitFD = PSURFACE->syncobj->current.acquireTimeline->timeline->exportAsSyncFileFD(PSURFACE->syncobj->current.acquirePoint);
|
||||||
|
if (explicitWaitFD < 0)
|
||||||
|
Debug::log(TRACE, "attemptDirectScanout: failed to acquire an explicit wait fd");
|
||||||
|
}
|
||||||
|
DOEXPLICIT = DOEXPLICIT && explicitWaitFD >= 0;
|
||||||
|
|
||||||
|
auto cleanup = CScopeGuard([explicitWaitFD, this]() {
|
||||||
|
output->state->resetExplicitFences();
|
||||||
|
if (explicitWaitFD >= 0)
|
||||||
|
close(explicitWaitFD);
|
||||||
|
});
|
||||||
|
|
||||||
timespec now;
|
timespec now;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
Debug::log(TRACE, "presentFeedback for DS");
|
PSURFACE->presentFeedback(&now, self.lock());
|
||||||
PSURFACE->presentFeedback(&now, this, true);
|
|
||||||
|
|
||||||
output->state->addDamage(CBox{{}, vecPixelSize});
|
output->state->addDamage(CBox{{}, vecPixelSize});
|
||||||
|
output->state->resetExplicitFences();
|
||||||
|
|
||||||
if (state.commit()) {
|
if (DOEXPLICIT) {
|
||||||
|
Debug::log(TRACE, "attemptDirectScanout: setting IN_FENCE for aq to {}", explicitWaitFD);
|
||||||
|
output->state->setExplicitInFence(explicitWaitFD);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok = output->commit();
|
||||||
|
|
||||||
|
if (!ok && DOEXPLICIT) {
|
||||||
|
Debug::log(TRACE, "attemptDirectScanout: EXPLICIT SYNC FAILED: commit() returned false. Resetting fences and retrying, might result in glitches.");
|
||||||
|
output->state->resetExplicitFences();
|
||||||
|
|
||||||
|
ok = output->commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
if (lastScanout.expired()) {
|
if (lastScanout.expired()) {
|
||||||
lastScanout = PCANDIDATE;
|
lastScanout = PCANDIDATE;
|
||||||
Debug::log(LOG, "Entered a direct scanout to {:x}: \"{}\"", (uintptr_t)PCANDIDATE.get(), PCANDIDATE->m_szTitle);
|
Debug::log(LOG, "Entered a direct scanout to {:x}: \"{}\"", (uintptr_t)PCANDIDATE.get(), PCANDIDATE->m_szTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delay explicit sync feedback until kms release of the buffer
|
||||||
|
if (DOEXPLICIT) {
|
||||||
|
Debug::log(TRACE, "attemptDirectScanout: Delaying explicit sync release feedback until kms release");
|
||||||
|
PSURFACE->current.buffer->releaser->drop();
|
||||||
|
|
||||||
|
PSURFACE->current.buffer->buffer->hlEvents.backendRelease2 = PSURFACE->current.buffer->buffer->events.backendRelease.registerListener([PSURFACE](std::any d) {
|
||||||
|
const bool DOEXPLICIT = PSURFACE->syncobj && PSURFACE->syncobj->current.releaseTimeline && PSURFACE->syncobj->current.releaseTimeline->timeline;
|
||||||
|
if (DOEXPLICIT)
|
||||||
|
PSURFACE->syncobj->current.releaseTimeline->timeline->signal(PSURFACE->syncobj->current.releasePoint);
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
Debug::log(TRACE, "attemptDirectScanout: failed to scanout surface");
|
||||||
lastScanout.reset();
|
lastScanout.reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -837,6 +934,11 @@ bool CMonitor::attemptDirectScanout() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMonitor::debugLastPresentation(const std::string& message) {
|
||||||
|
Debug::log(TRACE, "{} (last presentation {} - {} fps)", message, lastPresentationTimer.getMillis(),
|
||||||
|
lastPresentationTimer.getMillis() > 0 ? 1000.0f / lastPresentationTimer.getMillis() : 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
CMonitorState::CMonitorState(CMonitor* owner) {
|
CMonitorState::CMonitorState(CMonitor* owner) {
|
||||||
m_pOwner = owner;
|
m_pOwner = owner;
|
||||||
}
|
}
|
||||||
|
@ -846,17 +948,20 @@ CMonitorState::~CMonitorState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMonitorState::ensureBufferPresent() {
|
void CMonitorState::ensureBufferPresent() {
|
||||||
if (!m_pOwner->output->state->state().enabled) {
|
const auto STATE = m_pOwner->output->state->state();
|
||||||
|
if (!STATE.enabled) {
|
||||||
Debug::log(TRACE, "CMonitorState::ensureBufferPresent: Ignoring, monitor is not enabled");
|
Debug::log(TRACE, "CMonitorState::ensureBufferPresent: Ignoring, monitor is not enabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pOwner->output->state->state().buffer)
|
if (STATE.buffer) {
|
||||||
|
if (const auto params = STATE.buffer->dmabuf(); params.success && params.format == m_pOwner->drmFormat)
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// this is required for modesetting being possible and might be missing in case of first tests in the renderer
|
// this is required for modesetting being possible and might be missing in case of first tests in the renderer
|
||||||
// where we test modes and buffers
|
// where we test modes and buffers
|
||||||
Debug::log(LOG, "CMonitorState::ensureBufferPresent: no buffer, attaching one from the swapchain for modeset being possible");
|
Debug::log(LOG, "CMonitorState::ensureBufferPresent: no buffer or mismatched format, attaching one from the swapchain for modeset being possible");
|
||||||
m_pOwner->output->state->setBuffer(m_pOwner->output->swapchain->next(nullptr));
|
m_pOwner->output->state->setBuffer(m_pOwner->output->swapchain->next(nullptr));
|
||||||
m_pOwner->output->swapchain->rollback(); // restore the counter, don't advance the swapchain
|
m_pOwner->output->swapchain->rollback(); // restore the counter, don't advance the swapchain
|
||||||
}
|
}
|
||||||
|
@ -890,7 +995,7 @@ bool CMonitorState::updateSwapchain() {
|
||||||
Debug::log(WARN, "updateSwapchain: No mode?");
|
Debug::log(WARN, "updateSwapchain: No mode?");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
options.format = STATE.drmFormat;
|
options.format = m_pOwner->drmFormat;
|
||||||
options.scanout = true;
|
options.scanout = true;
|
||||||
options.length = 2;
|
options.length = 2;
|
||||||
options.size = MODE->pixelSize;
|
options.size = MODE->pixelSize;
|
||||||
|
|
|
@ -59,7 +59,7 @@ class CMonitorState {
|
||||||
|
|
||||||
class CMonitor {
|
class CMonitor {
|
||||||
public:
|
public:
|
||||||
CMonitor();
|
CMonitor(SP<Aquamarine::IOutput> output);
|
||||||
~CMonitor();
|
~CMonitor();
|
||||||
|
|
||||||
Vector2D vecPosition = Vector2D(-1, -1); // means unset
|
Vector2D vecPosition = Vector2D(-1, -1); // means unset
|
||||||
|
@ -70,7 +70,7 @@ class CMonitor {
|
||||||
|
|
||||||
bool primary = false;
|
bool primary = false;
|
||||||
|
|
||||||
uint64_t ID = -1;
|
MONITORID ID = MONITOR_INVALID;
|
||||||
PHLWORKSPACE activeWorkspace = nullptr;
|
PHLWORKSPACE activeWorkspace = nullptr;
|
||||||
PHLWORKSPACE activeSpecialWorkspace = nullptr;
|
PHLWORKSPACE activeSpecialWorkspace = nullptr;
|
||||||
float setScale = 1; // scale set by cfg
|
float setScale = 1; // scale set by cfg
|
||||||
|
@ -96,10 +96,12 @@ class CMonitor {
|
||||||
bool scheduledRecalc = false;
|
bool scheduledRecalc = false;
|
||||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
float xwaylandScale = 1.f;
|
float xwaylandScale = 1.f;
|
||||||
std::array<float, 9> projMatrix = {0};
|
Mat3x3 projMatrix;
|
||||||
std::optional<Vector2D> forceSize;
|
std::optional<Vector2D> forceSize;
|
||||||
SP<Aquamarine::SOutputMode> currentMode;
|
SP<Aquamarine::SOutputMode> currentMode;
|
||||||
SP<Aquamarine::CSwapchain> cursorSwapchain;
|
SP<Aquamarine::CSwapchain> cursorSwapchain;
|
||||||
|
uint32_t drmFormat = DRM_FORMAT_INVALID;
|
||||||
|
uint32_t prevDrmFormat = DRM_FORMAT_INVALID;
|
||||||
|
|
||||||
bool dpmsStatus = true;
|
bool dpmsStatus = true;
|
||||||
bool vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it.
|
bool vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it.
|
||||||
|
@ -121,7 +123,6 @@ class CMonitor {
|
||||||
// explicit sync
|
// explicit sync
|
||||||
SP<CSyncTimeline> inTimeline;
|
SP<CSyncTimeline> inTimeline;
|
||||||
SP<CSyncTimeline> outTimeline;
|
SP<CSyncTimeline> outTimeline;
|
||||||
uint64_t lastWaitPoint = 0;
|
|
||||||
uint64_t commitSeq = 0;
|
uint64_t commitSeq = 0;
|
||||||
|
|
||||||
WP<CMonitor> self;
|
WP<CMonitor> self;
|
||||||
|
@ -130,6 +131,10 @@ class CMonitor {
|
||||||
CMonitor* pMirrorOf = nullptr;
|
CMonitor* pMirrorOf = nullptr;
|
||||||
std::vector<CMonitor*> mirrors;
|
std::vector<CMonitor*> mirrors;
|
||||||
|
|
||||||
|
// ctm
|
||||||
|
Mat3x3 ctm = Mat3x3::identity();
|
||||||
|
bool ctmUpdated = false;
|
||||||
|
|
||||||
// for tearing
|
// for tearing
|
||||||
PHLWINDOWREF solitaryClient;
|
PHLWINDOWREF solitaryClient;
|
||||||
|
|
||||||
|
@ -167,17 +172,20 @@ class CMonitor {
|
||||||
bool matchesStaticSelector(const std::string& selector) const;
|
bool matchesStaticSelector(const std::string& selector) const;
|
||||||
float getDefaultScale();
|
float getDefaultScale();
|
||||||
void changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal = false, bool noMouseMove = false, bool noFocus = false);
|
void changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal = false, bool noMouseMove = false, bool noFocus = false);
|
||||||
void changeWorkspace(const int& id, bool internal = false, bool noMouseMove = false, bool noFocus = false);
|
void changeWorkspace(const WORKSPACEID& id, bool internal = false, bool noMouseMove = false, bool noFocus = false);
|
||||||
void setSpecialWorkspace(const PHLWORKSPACE& pWorkspace);
|
void setSpecialWorkspace(const PHLWORKSPACE& pWorkspace);
|
||||||
void setSpecialWorkspace(const int& id);
|
void setSpecialWorkspace(const WORKSPACEID& id);
|
||||||
void moveTo(const Vector2D& pos);
|
void moveTo(const Vector2D& pos);
|
||||||
Vector2D middle();
|
Vector2D middle();
|
||||||
void updateMatrix();
|
void updateMatrix();
|
||||||
int64_t activeWorkspaceID();
|
WORKSPACEID activeWorkspaceID();
|
||||||
int64_t activeSpecialWorkspaceID();
|
WORKSPACEID activeSpecialWorkspaceID();
|
||||||
CBox logicalBox();
|
CBox logicalBox();
|
||||||
void scheduleDone();
|
void scheduleDone();
|
||||||
bool attemptDirectScanout();
|
bool attemptDirectScanout();
|
||||||
|
void setCTM(const Mat3x3& ctm);
|
||||||
|
|
||||||
|
void debugLastPresentation(const std::string& message);
|
||||||
|
|
||||||
bool m_bEnabled = false;
|
bool m_bEnabled = false;
|
||||||
bool m_bRenderingInitPassed = false;
|
bool m_bRenderingInitPassed = false;
|
||||||
|
@ -190,9 +198,9 @@ class CMonitor {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupDefaultWS(const SMonitorRule&);
|
void setupDefaultWS(const SMonitorRule&);
|
||||||
int findAvailableDefaultWS();
|
WORKSPACEID findAvailableDefaultWS();
|
||||||
|
|
||||||
wl_event_source* doneSource = nullptr;
|
bool doneScheduled = false;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
CHyprSignalListener frame;
|
CHyprSignalListener frame;
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
namespace Systemd {
|
namespace Systemd {
|
||||||
int SdBooted(void) {
|
int SdBooted(void) {
|
||||||
|
|