Merge branch 'hyprwm:main' into main

This commit is contained in:
Kaeeraa 2024-09-13 20:43:10 +03:00 committed by GitHub
commit 23c324950d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
51 changed files with 585 additions and 284 deletions

View file

@ -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

View file

@ -16,17 +16,12 @@ jobs:
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 'git+https://github.com/hyprwm/Hyprland?ref=${{ github.ref }}&submodules=1#${{ matrix.package }}' -L --extra-substituters "https://hyprland.cachix.org"

View file

@ -9,7 +9,6 @@ jobs:
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

View file

@ -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)

View file

@ -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 ./buildZ
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

View file

@ -1 +1 @@
0.42.0 0.43.0

0
assets/install/lockdead.png Executable file → Normal file
View file

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

View file

@ -2,5 +2,9 @@ globber = run_command('sh', '-c', 'find . -type f -not -name "*.build"', check:
files = globber.stdout().strip().split('\n') files = globber.stdout().strip().split('\n')
foreach file : files foreach file : files
install_data(file, install_dir: join_paths(get_option('datadir'), 'hypr'), install_tag: 'runtime') install_data(
file,
install_dir: join_paths(get_option('datadir'), 'hypr'),
install_tag: 'runtime',
)
endforeach endforeach

View file

@ -1,2 +1,7 @@
install_data('hyprland-portals.conf', install_dir: join_paths(get_option('datadir'), 'xdg-desktop-portal'), install_tag: 'runtime') install_data(
'hyprland-portals.conf',
install_dir: join_paths(get_option('datadir'), 'xdg-desktop-portal'),
install_tag: 'runtime',
)
subdir('install') subdir('install')

View file

@ -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.

View file

@ -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.

View file

@ -1,2 +1,2 @@
install_man ('Hyprland.1') install_man('Hyprland.1')
install_man ('hyprctl.1') install_man('hyprctl.1')

View file

@ -228,6 +228,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 ###

View file

@ -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',
)

View file

@ -16,11 +16,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1725199881, "lastModified": 1725753098,
"narHash": "sha256-jsmipf/u1GFZE5tBUkr56CHMN6VpUWCAjfLIhvQijU0=", "narHash": "sha256-/NO/h/qD/eJXAQr/fHA4mdDgYsNT9thHQ+oT6KPi2ac=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "aquamarine", "repo": "aquamarine",
"rev": "f8a687dd29ff019657498f1bd14da2fbbf0e604b", "rev": "e4a13203112a036fc7f437d391c7810f3dd5ab52",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -93,11 +93,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1725188252, "lastModified": 1725997860,
"narHash": "sha256-yBH8c4GDaEAtBrh+BqIlrx5vp6gG/Gu8fQQK63KAQgs=", "narHash": "sha256-d/rZ/fHR5l1n7PeyLw0StWMNLXVU9c4HFyfskw568so=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprlang", "repo": "hyprlang",
"rev": "c12ab785ce1982f82594aff03b3104c598186ddd", "rev": "dfeb5811dd6485490cce18d6cc1e38a055eea876",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -154,11 +154,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1725103162, "lastModified": 1725983898,
"narHash": "sha256-Ym04C5+qovuQDYL/rKWSR+WESseQBbNAe5DsXNx5trY=", "narHash": "sha256-4b3A9zPpxAxLnkF9MawJNHDtOOl6ruL0r6Og1TEDGCE=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "12228ff1752d7b7624a54e9c1af4b222b3c1073b", "rev": "1355a0cbfeac61d785b7183c0caaec1f97361b43",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -209,11 +209,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1725203932, "lastModified": 1726046979,
"narHash": "sha256-VLULC/OnI+6R9KEP2OIGk+uLJJsfRlaLouZ5gyFd2+Y=", "narHash": "sha256-6SEsjurq9cdTkITA6d49ncAJe4O/8CgRG5/F//s6Xh8=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland", "repo": "xdg-desktop-portal-hyprland",
"rev": "2425e8f541525fa7409d9f26a8ffaf92a3767251", "rev": "e695669fd8e1d1be9eaae40f35e00f8bd8b64c18",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -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',
)

View file

@ -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',
)

View file

@ -1,13 +1,17 @@
project('Hyprland', 'cpp', 'c', project(
version : run_command('cat', join_paths(meson.source_root(), 'VERSION'), check: true).stdout().strip(), 'Hyprland',
default_options : [ 'cpp',
'c',
version: run_command('cat', join_paths(meson.project_source_root(), 'VERSION'), check: true).stdout().strip(),
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++26', '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,10 +20,10 @@ 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,
], ],
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')
@ -34,7 +38,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'))
gio_dep = dependency('gio-2.0', required:true) gio_dep = dependency('gio-2.0', required: true)
cmake = import('cmake') cmake = import('cmake')
udis = cmake.subproject('udis86') udis = cmake.subproject('udis86')
@ -47,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
@ -59,8 +64,10 @@ 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
@ -75,6 +82,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(

View file

@ -4,6 +4,7 @@
pkg-config, pkg-config,
pkgconf, pkgconf,
makeWrapper, makeWrapper,
meson,
cmake, cmake,
ninja, ninja,
aquamarine, aquamarine,
@ -39,6 +40,7 @@
wrapRuntimeDeps ? true, wrapRuntimeDeps ? true,
version ? "git", version ? "git",
commit, commit,
revCount,
date, date,
# deprecated flags # deprecated flags
enableNvidiaPatches ? false, enableNvidiaPatches ? false,
@ -60,11 +62,6 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov
src = lib.cleanSource ../.; src = lib.cleanSource ../.;
}; };
patches = [
# forces GCC to use -std=c++26
./stdcxx.patch
];
postPatch = '' postPatch = ''
# Fix hardcoded paths to /usr installation # Fix hardcoded paths to /usr installation
sed -i "s#/usr#$out#" src/render/OpenGL.cpp sed -i "s#/usr#$out#" src/render/OpenGL.cpp
@ -73,7 +70,7 @@ 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 = lib.optionalString (commit == "") "dirty";
HASH = commit; HASH = commit;
@ -86,6 +83,7 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov
hyprwayland-scanner hyprwayland-scanner
jq jq
makeWrapper makeWrapper
meson
cmake cmake
ninja ninja
pkg-config pkg-config
@ -139,18 +137,18 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov
(lib.optionals withSystemd [systemd]) (lib.optionals withSystemd [systemd])
]; ];
cmakeBuildType = mesonBuildType =
if debug if debug
then "Debug" then "debug"
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 = [
(lib.cmakeBool "NO_XWAYLAND" (!enableXWayland)) (lib.mesonEnable "xwayland" enableXWayland)
(lib.cmakeBool "LEGACY_RENDERER" legacyRenderer) (lib.mesonEnable "legacy_renderer" legacyRenderer)
(lib.cmakeBool "NO_SYSTEMD" (!withSystemd)) (lib.mesonEnable "systemd" withSystemd)
]; ];
postInstall = '' postInstall = ''

View file

@ -34,6 +34,7 @@ in {
stdenv = final.gcc14Stdenv; 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;};

View file

@ -1,12 +0,0 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cfbd431f..73e8e0c2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -64,6 +64,7 @@ endif()
include_directories(. "src/" "subprojects/udis86/" "protocols/")
set(CMAKE_CXX_STANDARD 26)
add_compile_options(
+ -std=c++26
-Wall
-Wextra
-Wno-unused-parameter

View file

@ -1,77 +1,75 @@
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(
'hyprland-protocols',
version: '>=0.2', version: '>=0.2',
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'], wayland_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml',
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'], wayland_protocol_dir / 'staging/fractional-scale/fractional-scale-v1.xml',
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'], wayland_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml',
[wl_protocol_dir, 'staging/cursor-shape/cursor-shape-v1.xml'], wayland_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
[wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'], wayland_protocol_dir / 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml',
[wl_protocol_dir, 'unstable/relative-pointer/relative-pointer-unstable-v1.xml'], wayland_protocol_dir / 'unstable/relative-pointer/relative-pointer-unstable-v1.xml',
[wl_protocol_dir, 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml'], wayland_protocol_dir / 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml',
[wl_protocol_dir, 'staging/alpha-modifier/alpha-modifier-v1.xml'], wayland_protocol_dir / 'staging/alpha-modifier/alpha-modifier-v1.xml',
[wl_protocol_dir, 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml'], wayland_protocol_dir / 'staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml',
[wl_protocol_dir, 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml'], wayland_protocol_dir / 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml',
[wl_protocol_dir, 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml'], wayland_protocol_dir / 'unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml',
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v3.xml'], wayland_protocol_dir / 'unstable/text-input/text-input-unstable-v3.xml',
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'], wayland_protocol_dir / 'unstable/text-input/text-input-unstable-v1.xml',
[wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'], wayland_protocol_dir / 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml',
[wl_protocol_dir, 'staging/xdg-activation/xdg-activation-v1.xml'], wayland_protocol_dir / 'staging/xdg-activation/xdg-activation-v1.xml',
[wl_protocol_dir, 'staging/ext-idle-notify/ext-idle-notify-v1.xml'], wayland_protocol_dir / 'staging/ext-idle-notify/ext-idle-notify-v1.xml',
[wl_protocol_dir, 'staging/ext-session-lock/ext-session-lock-v1.xml'], wayland_protocol_dir / 'staging/ext-session-lock/ext-session-lock-v1.xml',
[wl_protocol_dir, 'stable/tablet/tablet-v2.xml'], wayland_protocol_dir / 'stable/tablet/tablet-v2.xml',
[wl_protocol_dir, 'stable/presentation-time/presentation-time.xml'], wayland_protocol_dir / 'stable/presentation-time/presentation-time.xml',
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'], wayland_protocol_dir / 'stable/xdg-shell/xdg-shell.xml',
[wl_protocol_dir, 'unstable/primary-selection/primary-selection-unstable-v1.xml'], wayland_protocol_dir / 'unstable/primary-selection/primary-selection-unstable-v1.xml',
[wl_protocol_dir, 'staging/xwayland-shell/xwayland-shell-v1.xml'], wayland_protocol_dir / 'staging/xwayland-shell/xwayland-shell-v1.xml',
[wl_protocol_dir, 'stable/viewporter/viewporter.xml'], wayland_protocol_dir / 'stable/viewporter/viewporter.xml',
[wl_protocol_dir, 'stable/linux-dmabuf/linux-dmabuf-v1.xml'], wayland_protocol_dir / 'stable/linux-dmabuf/linux-dmabuf-v1.xml',
[wl_protocol_dir, 'staging/drm-lease/drm-lease-v1.xml'], wayland_protocol_dir / 'staging/drm-lease/drm-lease-v1.xml',
[wl_protocol_dir, 'staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml'], wayland_protocol_dir / 'staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml',
[wl_protocol_dir, 'staging/xdg-dialog/xdg-dialog-v1.xml'], wayland_protocol_dir / 'staging/xdg-dialog/xdg-dialog-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'],
@ -79,31 +77,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,
) )

View file

@ -91,6 +91,7 @@ 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_bDesktopEnvSet = false;
bool m_bEnableXwayland = true; bool m_bEnableXwayland = true;

View file

@ -141,6 +141,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;
@ -609,6 +621,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});
@ -801,6 +814,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();
@ -1398,6 +1412,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);
} }
@ -1700,6 +1732,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');
@ -2197,7 +2239,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); });
} }

View file

@ -192,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&);
@ -213,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&);
@ -289,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 = "";

View file

@ -241,6 +241,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 ###

View file

@ -394,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"); }
} }
} }
} }

View file

@ -55,6 +55,7 @@ class CLayerSurface {
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;

View file

@ -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;

View file

@ -18,6 +18,7 @@ class CPopup {
~CPopup(); ~CPopup();
SP<CWLSurface> getT1Owner();
Vector2D coordsRelativeToParent(); Vector2D coordsRelativeToParent();
Vector2D coordsGlobal(); Vector2D coordsGlobal();

View file

@ -51,7 +51,7 @@ void CWorkspace::init(PHLWORKSPACE self) {
if (self->m_bWasCreatedEmpty) 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)});

View file

@ -345,6 +345,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 +450,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);
} }

View file

@ -34,7 +34,7 @@ using namespace Hyprutils::String;
#include <sys/consio.h> #include <sys/consio.h>
#endif #endif
static std::vector<std::pair<std::string, std::string>> getHyprlandLaunchEnv() { static std::vector<std::pair<std::string, std::string>> getHyprlandLaunchEnv(PHLWORKSPACE pInitialWorkspace) {
static auto PINITIALWSTRACKING = CConfigValue<Hyprlang::INT>("misc:initial_workspace_tracking"); static auto PINITIALWSTRACKING = CConfigValue<Hyprlang::INT>("misc:initial_workspace_tracking");
if (!*PINITIALWSTRACKING || g_pConfigManager->isLaunchingExecOnce) if (!*PINITIALWSTRACKING || g_pConfigManager->isLaunchingExecOnce)
@ -46,11 +46,15 @@ static std::vector<std::pair<std::string, std::string>> getHyprlandLaunchEnv() {
std::vector<std::pair<std::string, std::string>> result; std::vector<std::pair<std::string, std::string>> result;
result.push_back(std::make_pair<>( if (!pInitialWorkspace) {
"HL_INITIAL_WORKSPACE_TOKEN", if (PMONITOR->activeSpecialWorkspace)
g_pTokenManager->registerNewToken( pInitialWorkspace = PMONITOR->activeSpecialWorkspace;
SInitialWorkspaceToken{{}, PMONITOR->activeSpecialWorkspace ? PMONITOR->activeSpecialWorkspace->getConfigName() : PMONITOR->activeWorkspace->getConfigName()}, else
std::chrono::months(1337)))); pInitialWorkspace = PMONITOR->activeWorkspace;
}
result.push_back(std::make_pair<>("HL_INITIAL_WORKSPACE_TOKEN",
g_pTokenManager->registerNewToken(SInitialWorkspaceToken{{}, pInitialWorkspace->getConfigName()}, std::chrono::months(1337))));
return result; return result;
} }
@ -846,8 +850,12 @@ bool CKeybindManager::handleInternalKeybinds(xkb_keysym_t keysym) {
} }
// Dispatchers // Dispatchers
SDispatchResult CKeybindManager::spawn(std::string args) { SDispatchResult CKeybindManager::spawn(std::string args) {
const uint64_t PROC = spawnWithRules(args, nullptr);
return {.success = PROC > 0, .error = std::format("Failed to start process {}", args)};
}
uint64_t CKeybindManager::spawnWithRules(std::string args, PHLWORKSPACE pInitialWorkspace) {
args = trim(args); args = trim(args);
@ -859,7 +867,7 @@ SDispatchResult CKeybindManager::spawn(std::string args) {
args = args.substr(args.find_first_of(']') + 1); args = args.substr(args.find_first_of(']') + 1);
} }
const uint64_t PROC = spawnRawProc(args); const uint64_t PROC = spawnRawProc(args, pInitialWorkspace);
if (!RULES.empty()) { if (!RULES.empty()) {
const auto RULESLIST = CVarList(RULES, 0, ';'); const auto RULESLIST = CVarList(RULES, 0, ';');
@ -871,18 +879,18 @@ SDispatchResult CKeybindManager::spawn(std::string args) {
Debug::log(LOG, "Applied {} rule arguments for exec.", RULESLIST.size()); Debug::log(LOG, "Applied {} rule arguments for exec.", RULESLIST.size());
} }
return {.success = PROC > 0, .error = std::format("Failed to start process {}", args)}; return PROC;
} }
SDispatchResult CKeybindManager::spawnRaw(std::string args) { SDispatchResult CKeybindManager::spawnRaw(std::string args) {
const uint64_t PROC = spawnRawProc(args); const uint64_t PROC = spawnRawProc(args, nullptr);
return {.success = PROC > 0, .error = std::format("Failed to start process {}", args)}; return {.success = PROC > 0, .error = std::format("Failed to start process {}", args)};
} }
uint64_t CKeybindManager::spawnRawProc(std::string args) { uint64_t CKeybindManager::spawnRawProc(std::string args, PHLWORKSPACE pInitialWorkspace) {
Debug::log(LOG, "Executing {}", args); Debug::log(LOG, "Executing {}", args);
const auto HLENV = getHyprlandLaunchEnv(); const auto HLENV = getHyprlandLaunchEnv(pInitialWorkspace);
int socket[2]; int socket[2];
if (pipe(socket) != 0) { if (pipe(socket) != 0) {
@ -1773,6 +1781,11 @@ SDispatchResult CKeybindManager::renameWorkspace(std::string args) {
} }
SDispatchResult CKeybindManager::exitHyprland(std::string argz) { SDispatchResult CKeybindManager::exitHyprland(std::string argz) {
g_pConfigManager->dispatchExecShutdown();
if (g_pCompositor->m_bFinalRequests)
return {}; // Exiting deferred until requests complete
g_pCompositor->stopCompositor(); g_pCompositor->stopCompositor();
return {}; return {};
} }

View file

@ -149,7 +149,8 @@ class CKeybindManager {
static void moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir = ""); static void moveWindowOutOfGroup(PHLWINDOW pWindow, const std::string& dir = "");
static void moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowInDirection); static void moveWindowIntoGroup(PHLWINDOW pWindow, PHLWINDOW pWindowInDirection);
static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO); static void switchToWindow(PHLWINDOW PWINDOWTOCHANGETO);
static uint64_t spawnRawProc(std::string); static uint64_t spawnRawProc(std::string, PHLWORKSPACE pInitialWorkspace);
static uint64_t spawnWithRules(std::string, PHLWORKSPACE pInitialWorkspace);
// -------------- Dispatchers -------------- // // -------------- Dispatchers -------------- //
static SDispatchResult killActive(std::string); static SDispatchResult killActive(std::string);
@ -220,6 +221,7 @@ class CKeybindManager {
friend class CInputManager; friend class CInputManager;
friend class CConfigManager; friend class CConfigManager;
friend class CWorkspace; friend class CWorkspace;
friend class CPointerManager;
}; };
inline std::unique_ptr<CKeybindManager> g_pKeybindManager; inline std::unique_ptr<CKeybindManager> g_pKeybindManager;

View file

@ -3,6 +3,7 @@
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../protocols/PointerGestures.hpp" #include "../protocols/PointerGestures.hpp"
#include "../protocols/FractionalScale.hpp" #include "../protocols/FractionalScale.hpp"
#include "../protocols/IdleNotify.hpp"
#include "../protocols/core/Compositor.hpp" #include "../protocols/core/Compositor.hpp"
#include "../protocols/core/Seat.hpp" #include "../protocols/core/Seat.hpp"
#include "eventLoop/EventLoopManager.hpp" #include "eventLoop/EventLoopManager.hpp"
@ -674,7 +675,7 @@ void CPointerManager::damageIfSoftware() {
static auto PNOHW = CConfigValue<Hyprlang::INT>("cursor:no_hardware_cursors"); static auto PNOHW = CConfigValue<Hyprlang::INT>("cursor:no_hardware_cursors");
for (auto const& mw : monitorStates) { for (auto const& mw : monitorStates) {
if (mw->monitor.expired()) if (mw->monitor.expired() || !mw->monitor->output)
continue; continue;
if ((mw->softwareLocks > 0 || mw->hardwareFailed || *PNOHW) && b.overlaps({mw->monitor->vecPosition, mw->monitor->vecSize})) { if ((mw->softwareLocks > 0 || mw->hardwareFailed || *PNOHW) && b.overlaps({mw->monitor->vecPosition, mw->monitor->vecSize})) {
@ -788,7 +789,7 @@ void CPointerManager::warpAbsolute(Vector2D abs, SP<IHID> dev) {
void CPointerManager::onMonitorLayoutChange() { void CPointerManager::onMonitorLayoutChange() {
currentMonitorLayout.monitorBoxes.clear(); currentMonitorLayout.monitorBoxes.clear();
for (auto const& m : g_pCompositor->m_vMonitors) { for (auto const& m : g_pCompositor->m_vMonitors) {
if (m->isMirror() || !m->m_bEnabled) if (m->isMirror() || !m->m_bEnabled || !m->output)
continue; continue;
currentMonitorLayout.monitorBoxes.emplace_back(CBox{m->vecPosition, m->vecSize}); currentMonitorLayout.monitorBoxes.emplace_back(CBox{m->vecPosition, m->vecSize});
@ -820,6 +821,9 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
if (!pointer) if (!pointer)
return; return;
static auto PMOUSEDPMS = CConfigValue<Hyprlang::INT>("misc:mouse_move_enables_dpms");
//
auto listener = pointerListeners.emplace_back(makeShared<SPointerListener>()); auto listener = pointerListeners.emplace_back(makeShared<SPointerListener>());
listener->pointer = pointer; listener->pointer = pointer;
@ -833,24 +837,38 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
auto E = std::any_cast<IPointer::SMotionEvent>(e); auto E = std::any_cast<IPointer::SMotionEvent>(e);
g_pInputManager->onMouseMoved(E); g_pInputManager->onMouseMoved(E);
PROTO::idle->onActivity();
if (!g_pCompositor->m_bDPMSStateON && *PMOUSEDPMS)
g_pKeybindManager->dpms("on");
}); });
listener->motionAbsolute = pointer->pointerEvents.motionAbsolute.registerListener([this] (std::any e) { listener->motionAbsolute = pointer->pointerEvents.motionAbsolute.registerListener([this] (std::any e) {
auto E = std::any_cast<IPointer::SMotionAbsoluteEvent>(e); auto E = std::any_cast<IPointer::SMotionAbsoluteEvent>(e);
g_pInputManager->onMouseWarp(E); g_pInputManager->onMouseWarp(E);
PROTO::idle->onActivity();
if (!g_pCompositor->m_bDPMSStateON && *PMOUSEDPMS)
g_pKeybindManager->dpms("on");
}); });
listener->button = pointer->pointerEvents.button.registerListener([this] (std::any e) { listener->button = pointer->pointerEvents.button.registerListener([this] (std::any e) {
auto E = std::any_cast<IPointer::SButtonEvent>(e); auto E = std::any_cast<IPointer::SButtonEvent>(e);
g_pInputManager->onMouseButton(E); g_pInputManager->onMouseButton(E);
PROTO::idle->onActivity();
}); });
listener->axis = pointer->pointerEvents.axis.registerListener([this] (std::any e) { listener->axis = pointer->pointerEvents.axis.registerListener([this] (std::any e) {
auto E = std::any_cast<IPointer::SAxisEvent>(e); auto E = std::any_cast<IPointer::SAxisEvent>(e);
g_pInputManager->onMouseWheel(E); g_pInputManager->onMouseWheel(E);
PROTO::idle->onActivity();
}); });
listener->frame = pointer->pointerEvents.frame.registerListener([this] (std::any e) { listener->frame = pointer->pointerEvents.frame.registerListener([this] (std::any e) {
@ -861,48 +879,70 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
auto E = std::any_cast<IPointer::SSwipeBeginEvent>(e); auto E = std::any_cast<IPointer::SSwipeBeginEvent>(e);
g_pInputManager->onSwipeBegin(E); g_pInputManager->onSwipeBegin(E);
PROTO::idle->onActivity();
if (!g_pCompositor->m_bDPMSStateON && *PMOUSEDPMS)
g_pKeybindManager->dpms("on");
}); });
listener->swipeEnd = pointer->pointerEvents.swipeEnd.registerListener([this] (std::any e) { listener->swipeEnd = pointer->pointerEvents.swipeEnd.registerListener([this] (std::any e) {
auto E = std::any_cast<IPointer::SSwipeEndEvent>(e); auto E = std::any_cast<IPointer::SSwipeEndEvent>(e);
g_pInputManager->onSwipeEnd(E); g_pInputManager->onSwipeEnd(E);
PROTO::idle->onActivity();
}); });
listener->swipeUpdate = pointer->pointerEvents.swipeUpdate.registerListener([this] (std::any e) { listener->swipeUpdate = pointer->pointerEvents.swipeUpdate.registerListener([this] (std::any e) {
auto E = std::any_cast<IPointer::SSwipeUpdateEvent>(e); auto E = std::any_cast<IPointer::SSwipeUpdateEvent>(e);
g_pInputManager->onSwipeUpdate(E); g_pInputManager->onSwipeUpdate(E);
PROTO::idle->onActivity();
}); });
listener->pinchBegin = pointer->pointerEvents.pinchBegin.registerListener([this] (std::any e) { listener->pinchBegin = pointer->pointerEvents.pinchBegin.registerListener([this] (std::any e) {
auto E = std::any_cast<IPointer::SPinchBeginEvent>(e); auto E = std::any_cast<IPointer::SPinchBeginEvent>(e);
PROTO::pointerGestures->pinchBegin(E.timeMs, E.fingers); PROTO::pointerGestures->pinchBegin(E.timeMs, E.fingers);
PROTO::idle->onActivity();
if (!g_pCompositor->m_bDPMSStateON && *PMOUSEDPMS)
g_pKeybindManager->dpms("on");
}); });
listener->pinchEnd = pointer->pointerEvents.pinchEnd.registerListener([this] (std::any e) { listener->pinchEnd = pointer->pointerEvents.pinchEnd.registerListener([this] (std::any e) {
auto E = std::any_cast<IPointer::SPinchEndEvent>(e); auto E = std::any_cast<IPointer::SPinchEndEvent>(e);
PROTO::pointerGestures->pinchEnd(E.timeMs, E.cancelled); PROTO::pointerGestures->pinchEnd(E.timeMs, E.cancelled);
PROTO::idle->onActivity();
}); });
listener->pinchUpdate = pointer->pointerEvents.pinchUpdate.registerListener([this] (std::any e) { listener->pinchUpdate = pointer->pointerEvents.pinchUpdate.registerListener([this] (std::any e) {
auto E = std::any_cast<IPointer::SPinchUpdateEvent>(e); auto E = std::any_cast<IPointer::SPinchUpdateEvent>(e);
PROTO::pointerGestures->pinchUpdate(E.timeMs, E.delta, E.scale, E.rotation); PROTO::pointerGestures->pinchUpdate(E.timeMs, E.delta, E.scale, E.rotation);
PROTO::idle->onActivity();
}); });
listener->holdBegin = pointer->pointerEvents.holdBegin.registerListener([this] (std::any e) { listener->holdBegin = pointer->pointerEvents.holdBegin.registerListener([this] (std::any e) {
auto E = std::any_cast<IPointer::SHoldBeginEvent>(e); auto E = std::any_cast<IPointer::SHoldBeginEvent>(e);
PROTO::pointerGestures->holdBegin(E.timeMs, E.fingers); PROTO::pointerGestures->holdBegin(E.timeMs, E.fingers);
PROTO::idle->onActivity();
}); });
listener->holdEnd = pointer->pointerEvents.holdEnd.registerListener([this] (std::any e) { listener->holdEnd = pointer->pointerEvents.holdEnd.registerListener([this] (std::any e) {
auto E = std::any_cast<IPointer::SHoldEndEvent>(e); auto E = std::any_cast<IPointer::SHoldEndEvent>(e);
PROTO::pointerGestures->holdEnd(E.timeMs, E.cancelled); PROTO::pointerGestures->holdEnd(E.timeMs, E.cancelled);
PROTO::idle->onActivity();
}); });
// clang-format on // clang-format on
@ -913,6 +953,9 @@ void CPointerManager::attachTouch(SP<ITouch> touch) {
if (!touch) if (!touch)
return; return;
static auto PMOUSEDPMS = CConfigValue<Hyprlang::INT>("misc:mouse_move_enables_dpms");
//
auto listener = touchListeners.emplace_back(makeShared<STouchListener>()); auto listener = touchListeners.emplace_back(makeShared<STouchListener>());
listener->touch = touch; listener->touch = touch;
@ -926,18 +969,27 @@ void CPointerManager::attachTouch(SP<ITouch> touch) {
auto E = std::any_cast<ITouch::SDownEvent>(e); auto E = std::any_cast<ITouch::SDownEvent>(e);
g_pInputManager->onTouchDown(E); g_pInputManager->onTouchDown(E);
PROTO::idle->onActivity();
if (!g_pCompositor->m_bDPMSStateON && *PMOUSEDPMS)
g_pKeybindManager->dpms("on");
}); });
listener->up = touch->touchEvents.up.registerListener([this] (std::any e) { listener->up = touch->touchEvents.up.registerListener([this] (std::any e) {
auto E = std::any_cast<ITouch::SUpEvent>(e); auto E = std::any_cast<ITouch::SUpEvent>(e);
g_pInputManager->onTouchUp(E); g_pInputManager->onTouchUp(E);
PROTO::idle->onActivity();
}); });
listener->motion = touch->touchEvents.motion.registerListener([this] (std::any e) { listener->motion = touch->touchEvents.motion.registerListener([this] (std::any e) {
auto E = std::any_cast<ITouch::SMotionEvent>(e); auto E = std::any_cast<ITouch::SMotionEvent>(e);
g_pInputManager->onTouchMove(E); g_pInputManager->onTouchMove(E);
PROTO::idle->onActivity();
}); });
listener->cancel = touch->touchEvents.cancel.registerListener([this] (std::any e) { listener->cancel = touch->touchEvents.cancel.registerListener([this] (std::any e) {
@ -956,6 +1008,9 @@ void CPointerManager::attachTablet(SP<CTablet> tablet) {
if (!tablet) if (!tablet)
return; return;
static auto PMOUSEDPMS = CConfigValue<Hyprlang::INT>("misc:mouse_move_enables_dpms");
//
auto listener = tabletListeners.emplace_back(makeShared<STabletListener>()); auto listener = tabletListeners.emplace_back(makeShared<STabletListener>());
listener->tablet = tablet; listener->tablet = tablet;
@ -969,24 +1024,38 @@ void CPointerManager::attachTablet(SP<CTablet> tablet) {
auto E = std::any_cast<CTablet::SAxisEvent>(e); auto E = std::any_cast<CTablet::SAxisEvent>(e);
g_pInputManager->onTabletAxis(E); g_pInputManager->onTabletAxis(E);
PROTO::idle->onActivity();
if (!g_pCompositor->m_bDPMSStateON && *PMOUSEDPMS)
g_pKeybindManager->dpms("on");
}); });
listener->proximity = tablet->tabletEvents.proximity.registerListener([this] (std::any e) { listener->proximity = tablet->tabletEvents.proximity.registerListener([this] (std::any e) {
auto E = std::any_cast<CTablet::SProximityEvent>(e); auto E = std::any_cast<CTablet::SProximityEvent>(e);
g_pInputManager->onTabletProximity(E); g_pInputManager->onTabletProximity(E);
PROTO::idle->onActivity();
}); });
listener->tip = tablet->tabletEvents.tip.registerListener([this] (std::any e) { listener->tip = tablet->tabletEvents.tip.registerListener([this] (std::any e) {
auto E = std::any_cast<CTablet::STipEvent>(e); auto E = std::any_cast<CTablet::STipEvent>(e);
g_pInputManager->onTabletTip(E); g_pInputManager->onTabletTip(E);
PROTO::idle->onActivity();
if (!g_pCompositor->m_bDPMSStateON && *PMOUSEDPMS)
g_pKeybindManager->dpms("on");
}); });
listener->button = tablet->tabletEvents.button.registerListener([this] (std::any e) { listener->button = tablet->tabletEvents.button.registerListener([this] (std::any e) {
auto E = std::any_cast<CTablet::SButtonEvent>(e); auto E = std::any_cast<CTablet::SButtonEvent>(e);
g_pInputManager->onTabletButton(E); g_pInputManager->onTabletButton(E);
PROTO::idle->onActivity();
}); });
// clang-format on // clang-format on

View file

@ -6,6 +6,7 @@
#include "../protocols/core/Compositor.hpp" #include "../protocols/core/Compositor.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../devices/IKeyboard.hpp" #include "../devices/IKeyboard.hpp"
#include "wlr-layer-shell-unstable-v1.hpp"
#include <algorithm> #include <algorithm>
#include <ranges> #include <ranges>
@ -584,6 +585,36 @@ void CSeatManager::setGrab(SP<CSeatGrab> grab) {
auto oldGrab = seatGrab; auto oldGrab = seatGrab;
seatGrab.reset(); seatGrab.reset();
g_pInputManager->refocus(); g_pInputManager->refocus();
auto currentFocus = state.keyboardFocus.lock();
auto refocus = !currentFocus;
SP<CWLSurface> surf;
PHLLS layer;
if (!refocus) {
surf = CWLSurface::fromResource(currentFocus);
layer = surf->getLayer();
}
if (!refocus && !layer) {
auto popup = surf->getPopup();
if (popup) {
auto parent = popup->getT1Owner();
layer = parent->getLayer();
}
}
if (!refocus && layer)
refocus = layer->interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE;
if (refocus) {
auto candidate = g_pCompositor->m_pLastWindow.lock();
if (candidate)
g_pCompositor->focusWindow(candidate);
}
if (oldGrab->onEnd) if (oldGrab->onEnd)
oldGrab->onEnd(); oldGrab->onEnd();
} }

View file

@ -46,11 +46,8 @@ void CHyprXWaylandManager::activateSurface(SP<CWLSurfaceResource> pSurface, bool
PWINDOW->m_pXWaylandSurface->restackToTop(); PWINDOW->m_pXWaylandSurface->restackToTop();
} }
PWINDOW->m_pXWaylandSurface->activate(activate); PWINDOW->m_pXWaylandSurface->activate(activate);
} else if (!PWINDOW->m_bIsX11 && PWINDOW->m_pXDGSurface) { } else if (!PWINDOW->m_bIsX11 && PWINDOW->m_pXDGSurface)
PWINDOW->m_pXDGSurface->toplevel->setActive(activate); PWINDOW->m_pXDGSurface->toplevel->setActive(activate);
if (g_pCompositor->m_pLastFocus && g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow->m_bIsX11)
activateSurface(g_pCompositor->m_pLastFocus.lock(), false);
}
} }
void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) { void CHyprXWaylandManager::activateWindow(PHLWINDOW pWindow, bool activate) {

View file

@ -28,6 +28,7 @@
#include "../../managers/PointerManager.hpp" #include "../../managers/PointerManager.hpp"
#include "../../managers/SeatManager.hpp" #include "../../managers/SeatManager.hpp"
#include "../../managers/KeybindManager.hpp"
#include <aquamarine/input/Input.hpp> #include <aquamarine/input/Input.hpp>
@ -111,7 +112,7 @@ void CInputManager::simulateMouseMovement() {
timespec now; timespec now;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
m_vLastCursorPosFloored = m_vLastCursorPosFloored - Vector2D(1, 1); // hack: force the mouseMoveUnified to report without making this a refocus. m_vLastCursorPosFloored = m_vLastCursorPosFloored - Vector2D(1, 1); // hack: force the mouseMoveUnified to report without making this a refocus.
mouseMoveUnified(now.tv_sec * 1000 + now.tv_nsec / 10000000, false, true); mouseMoveUnified(now.tv_sec * 1000 + now.tv_nsec / 10000000);
} }
void CInputManager::sendMotionEventsToFocused() { void CInputManager::sendMotionEventsToFocused() {
@ -132,10 +133,9 @@ void CInputManager::sendMotionEventsToFocused() {
g_pSeatManager->setPointerFocus(g_pCompositor->m_pLastFocus.lock(), LOCAL); g_pSeatManager->setPointerFocus(g_pCompositor->m_pLastFocus.lock(), LOCAL);
} }
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool silent) { void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse"); static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto PMOUSEREFOCUS = CConfigValue<Hyprlang::INT>("input:mouse_refocus"); static auto PMOUSEREFOCUS = CConfigValue<Hyprlang::INT>("input:mouse_refocus");
static auto PMOUSEDPMS = CConfigValue<Hyprlang::INT>("misc:mouse_move_enables_dpms");
static auto PFOLLOWONDND = CConfigValue<Hyprlang::INT>("misc:always_follow_on_dnd"); static auto PFOLLOWONDND = CConfigValue<Hyprlang::INT>("misc:always_follow_on_dnd");
static auto PFLOATBEHAVIOR = CConfigValue<Hyprlang::INT>("input:float_switch_override_focus"); static auto PFLOATBEHAVIOR = CConfigValue<Hyprlang::INT>("input:float_switch_override_focus");
static auto PMOUSEFOCUSMON = CConfigValue<Hyprlang::INT>("misc:mouse_move_focuses_monitor"); static auto PMOUSEFOCUSMON = CConfigValue<Hyprlang::INT>("misc:mouse_move_focuses_monitor");
@ -157,11 +157,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool silent) {
if (!g_pCompositor->m_bReadyToProcess || g_pCompositor->m_bIsShuttingDown || g_pCompositor->m_bUnsafeState) if (!g_pCompositor->m_bReadyToProcess || g_pCompositor->m_bIsShuttingDown || g_pCompositor->m_bUnsafeState)
return; return;
if (!g_pCompositor->m_bDPMSStateON && *PMOUSEDPMS) {
// enable dpms
g_pKeybindManager->dpms("on");
}
Vector2D mouseCoords = getMouseCoordsInternal(); Vector2D mouseCoords = getMouseCoordsInternal();
const auto MOUSECOORDSFLOORED = mouseCoords.floor(); const auto MOUSECOORDSFLOORED = mouseCoords.floor();
@ -170,9 +165,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool silent) {
EMIT_HOOK_EVENT_CANCELLABLE("mouseMove", MOUSECOORDSFLOORED); EMIT_HOOK_EVENT_CANCELLABLE("mouseMove", MOUSECOORDSFLOORED);
if (time && !silent)
PROTO::idle->onActivity();
m_vLastCursorPosFloored = MOUSECOORDSFLOORED; m_vLastCursorPosFloored = MOUSECOORDSFLOORED;
const auto PMONITOR = g_pCompositor->getMonitorFromCursor(); const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
@ -508,6 +500,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool silent) {
} }
} }
if (g_pSeatManager->state.keyboardFocus == nullptr)
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
m_bLastFocusOnLS = false; m_bLastFocusOnLS = false;
} else { } else {
if (*PRESIZEONBORDER && *PRESIZECURSORICON && m_eBorderIconDirection != BORDERICON_NONE) { if (*PRESIZEONBORDER && *PRESIZECURSORICON && m_eBorderIconDirection != BORDERICON_NONE) {
@ -531,8 +526,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool silent) {
void CInputManager::onMouseButton(IPointer::SButtonEvent e) { void CInputManager::onMouseButton(IPointer::SButtonEvent e) {
EMIT_HOOK_EVENT_CANCELLABLE("mouseButton", e); EMIT_HOOK_EVENT_CANCELLABLE("mouseButton", e);
PROTO::idle->onActivity();
m_tmrLastCursorMovement.reset(); m_tmrLastCursorMovement.reset();
if (e.state == WL_POINTER_BUTTON_STATE_PRESSED) { if (e.state == WL_POINTER_BUTTON_STATE_PRESSED) {
@ -767,8 +760,6 @@ void CInputManager::onMouseWheel(IPointer::SAxisEvent e) {
bool passEvent = g_pKeybindManager->onAxisEvent(e); bool passEvent = g_pKeybindManager->onAxisEvent(e);
PROTO::idle->onActivity();
if (!passEvent) if (!passEvent)
return; return;
@ -858,6 +849,8 @@ void CInputManager::newVirtualKeyboard(SP<CVirtualKeyboardV1Resource> keyboard)
} }
void CInputManager::setupKeyboard(SP<IKeyboard> keeb) { void CInputManager::setupKeyboard(SP<IKeyboard> keeb) {
static auto PDPMS = CConfigValue<Hyprlang::INT>("misc:key_press_enables_dpms");
m_vHIDs.push_back(keeb); m_vHIDs.push_back(keeb);
try { try {
@ -883,6 +876,12 @@ void CInputManager::setupKeyboard(SP<IKeyboard> keeb) {
auto PKEEB = ((IKeyboard*)owner)->self.lock(); auto PKEEB = ((IKeyboard*)owner)->self.lock();
onKeyboardKey(data, PKEEB); onKeyboardKey(data, PKEEB);
if (PKEEB->enabled)
PROTO::idle->onActivity();
if (PKEEB->enabled && *PDPMS && !g_pCompositor->m_bDPMSStateON)
g_pKeybindManager->dpms("on");
}, },
keeb.get()); keeb.get());
@ -891,6 +890,12 @@ void CInputManager::setupKeyboard(SP<IKeyboard> keeb) {
auto PKEEB = ((IKeyboard*)owner)->self.lock(); auto PKEEB = ((IKeyboard*)owner)->self.lock();
onKeyboardMod(PKEEB); onKeyboardMod(PKEEB);
if (PKEEB->enabled)
PROTO::idle->onActivity();
if (PKEEB->enabled && *PDPMS && !g_pCompositor->m_bDPMSStateON)
g_pKeybindManager->dpms("on");
}, },
keeb.get()); keeb.get());
@ -1282,18 +1287,10 @@ void CInputManager::onKeyboardKey(std::any event, SP<IKeyboard> pKeyboard) {
const auto EMAP = std::unordered_map<std::string, std::any>{{"keyboard", pKeyboard}, {"event", event}}; const auto EMAP = std::unordered_map<std::string, std::any>{{"keyboard", pKeyboard}, {"event", event}};
EMIT_HOOK_EVENT_CANCELLABLE("keyPress", EMAP); EMIT_HOOK_EVENT_CANCELLABLE("keyPress", EMAP);
static auto PDPMS = CConfigValue<Hyprlang::INT>("misc:key_press_enables_dpms");
if (*PDPMS && !g_pCompositor->m_bDPMSStateON) {
// enable dpms
g_pKeybindManager->dpms("on");
}
bool passEvent = DISALLOWACTION || g_pKeybindManager->onKeyEvent(event, pKeyboard); bool passEvent = DISALLOWACTION || g_pKeybindManager->onKeyEvent(event, pKeyboard);
auto e = std::any_cast<IKeyboard::SKeyEvent>(event); auto e = std::any_cast<IKeyboard::SKeyEvent>(event);
PROTO::idle->onActivity();
if (passEvent) { if (passEvent) {
const auto IME = m_sIMERelay.m_pIME.lock(); const auto IME = m_sIMERelay.m_pIME.lock();

View file

@ -237,7 +237,7 @@ class CInputManager {
uint32_t m_uiCapabilities = 0; uint32_t m_uiCapabilities = 0;
void mouseMoveUnified(uint32_t, bool refocus = false, bool silent = false); void mouseMoveUnified(uint32_t, bool refocus = false);
SP<CTabletTool> ensureTabletToolPresent(SP<Aquamarine::ITabletTool>); SP<CTabletTool> ensureTabletToolPresent(SP<Aquamarine::ITabletTool>);

View file

@ -106,19 +106,21 @@ void CInputMethodRelay::updateAllPopups() {
} }
} }
void CInputMethodRelay::activateIME(CTextInput* pInput) { void CInputMethodRelay::activateIME(CTextInput* pInput, bool shouldCommit) {
if (m_pIME.expired()) if (m_pIME.expired())
return; return;
m_pIME->activate(); m_pIME->activate();
if (shouldCommit)
commitIMEState(pInput); commitIMEState(pInput);
} }
void CInputMethodRelay::deactivateIME(CTextInput* pInput) { void CInputMethodRelay::deactivateIME(CTextInput* pInput, bool shouldCommit) {
if (m_pIME.expired()) if (m_pIME.expired())
return; return;
m_pIME->deactivate(); m_pIME->deactivate();
if (shouldCommit)
commitIMEState(pInput); commitIMEState(pInput);
} }

View file

@ -21,8 +21,8 @@ class CInputMethodRelay {
void onNewTextInput(WP<CTextInputV3> tiv3); void onNewTextInput(WP<CTextInputV3> tiv3);
void onNewTextInput(WP<CTextInputV1> pTIV1); void onNewTextInput(WP<CTextInputV1> pTIV1);
void activateIME(CTextInput* pInput); void activateIME(CTextInput* pInput, bool shouldCommit = true);
void deactivateIME(CTextInput* pInput); void deactivateIME(CTextInput* pInput, bool shouldCommit = true);
void commitIMEState(CTextInput* pInput); void commitIMEState(CTextInput* pInput);
void removeTextInput(CTextInput* pInput); void removeTextInput(CTextInput* pInput);

View file

@ -1,6 +1,5 @@
#include "InputManager.hpp" #include "InputManager.hpp"
#include "../../Compositor.hpp" #include "../../Compositor.hpp"
#include "../../protocols/IdleNotify.hpp"
#include "../../protocols/Tablet.hpp" #include "../../protocols/Tablet.hpp"
#include "../../devices/Tablet.hpp" #include "../../devices/Tablet.hpp"
#include "../../managers/PointerManager.hpp" #include "../../managers/PointerManager.hpp"
@ -155,8 +154,6 @@ void CInputManager::onTabletAxis(CTablet::SAxisEvent e) {
if (e.updatedAxes & (CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_TILT_X | CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_TILT_Y)) if (e.updatedAxes & (CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_TILT_X | CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_TILT_Y))
PROTO::tablet->tilt(PTOOL, PTOOL->tilt); PROTO::tablet->tilt(PTOOL, PTOOL->tilt);
PROTO::idle->onActivity();
} }
void CInputManager::onTabletTip(CTablet::STipEvent e) { void CInputManager::onTabletTip(CTablet::STipEvent e) {
@ -171,8 +168,6 @@ void CInputManager::onTabletTip(CTablet::STipEvent e) {
PROTO::tablet->up(PTOOL); PROTO::tablet->up(PTOOL);
PTOOL->isDown = e.in; PTOOL->isDown = e.in;
PROTO::idle->onActivity();
} }
void CInputManager::onTabletButton(CTablet::SButtonEvent e) { void CInputManager::onTabletButton(CTablet::SButtonEvent e) {
@ -184,8 +179,6 @@ void CInputManager::onTabletButton(CTablet::SButtonEvent e) {
PTOOL->buttonsDown.push_back(e.button); PTOOL->buttonsDown.push_back(e.button);
else else
std::erase(PTOOL->buttonsDown, e.button); std::erase(PTOOL->buttonsDown, e.button);
PROTO::idle->onActivity();
} }
void CInputManager::onTabletProximity(CTablet::SProximityEvent e) { void CInputManager::onTabletProximity(CTablet::SProximityEvent e) {
@ -201,8 +194,6 @@ void CInputManager::onTabletProximity(CTablet::SProximityEvent e) {
simulateMouseMovement(); simulateMouseMovement();
refocusTablet(PTAB, PTOOL); refocusTablet(PTAB, PTOOL);
} }
PROTO::idle->onActivity();
} }
void CInputManager::newTablet(SP<Aquamarine::ITablet> pDevice) { void CInputManager::newTablet(SP<Aquamarine::ITablet> pDevice) {

View file

@ -22,11 +22,17 @@ void CTextInput::initCallbacks() {
listeners.enable = INPUT->events.enable.registerListener([this](std::any p) { onEnabled(); }); listeners.enable = INPUT->events.enable.registerListener([this](std::any p) { onEnabled(); });
listeners.disable = INPUT->events.disable.registerListener([this](std::any p) { onDisabled(); }); listeners.disable = INPUT->events.disable.registerListener([this](std::any p) { onDisabled(); });
listeners.commit = INPUT->events.onCommit.registerListener([this](std::any p) { onCommit(); }); listeners.commit = INPUT->events.onCommit.registerListener([this](std::any p) { onCommit(); });
listeners.reset = INPUT->events.reset.registerListener([this](std::any p) { onReset(); });
listeners.destroy = INPUT->events.destroy.registerListener([this](std::any p) { listeners.destroy = INPUT->events.destroy.registerListener([this](std::any p) {
listeners.surfaceUnmap.reset();
listeners.surfaceDestroy.reset();
g_pInputManager->m_sIMERelay.removeTextInput(this); g_pInputManager->m_sIMERelay.removeTextInput(this);
if (!g_pInputManager->m_sIMERelay.getFocusedTextInput()) if (!g_pInputManager->m_sIMERelay.getFocusedTextInput())
g_pInputManager->m_sIMERelay.deactivateIME(this); g_pInputManager->m_sIMERelay.deactivateIME(this);
}); });
if (!g_pCompositor->m_pLastFocus.expired() && g_pCompositor->m_pLastFocus->client() == INPUT->client())
enter(g_pCompositor->m_pLastFocus.lock());
} else { } else {
const auto INPUT = pV1Input.lock(); const auto INPUT = pV1Input.lock();
@ -36,6 +42,7 @@ void CTextInput::initCallbacks() {
}); });
listeners.disable = INPUT->events.disable.registerListener([this](std::any p) { onDisabled(); }); listeners.disable = INPUT->events.disable.registerListener([this](std::any p) { onDisabled(); });
listeners.commit = INPUT->events.onCommit.registerListener([this](std::any p) { onCommit(); }); listeners.commit = INPUT->events.onCommit.registerListener([this](std::any p) { onCommit(); });
listeners.reset = INPUT->events.reset.registerListener([this](std::any p) { onReset(); });
listeners.destroy = INPUT->events.destroy.registerListener([this](std::any p) { listeners.destroy = INPUT->events.destroy.registerListener([this](std::any p) {
listeners.surfaceUnmap.reset(); listeners.surfaceUnmap.reset();
listeners.surfaceDestroy.reset(); listeners.surfaceDestroy.reset();
@ -72,25 +79,37 @@ void CTextInput::onDisabled() {
return; return;
} }
if (!focusedSurface())
return;
if (!isV3()) if (!isV3())
leave(); leave();
listeners.surfaceUnmap.reset(); listeners.surfaceUnmap.reset();
listeners.surfaceDestroy.reset(); listeners.surfaceDestroy.reset();
if (!focusedSurface())
return;
const auto PFOCUSEDTI = g_pInputManager->m_sIMERelay.getFocusedTextInput();
if (!PFOCUSEDTI || PFOCUSEDTI != this)
return;
g_pInputManager->m_sIMERelay.deactivateIME(this); g_pInputManager->m_sIMERelay.deactivateIME(this);
} }
void CTextInput::onReset() {
if (g_pInputManager->m_sIMERelay.m_pIME.expired())
return;
g_pInputManager->m_sIMERelay.deactivateIME(this, false);
g_pInputManager->m_sIMERelay.activateIME(this);
}
void CTextInput::onCommit() { void CTextInput::onCommit() {
if (g_pInputManager->m_sIMERelay.m_pIME.expired()) { if (g_pInputManager->m_sIMERelay.m_pIME.expired()) {
// Debug::log(WARN, "Committing TextInput on no IME!"); // Debug::log(WARN, "Committing TextInput on no IME!");
return; return;
} }
if (!(isV3() ? pV3Input->current.enabled : pV1Input->active)) { if (!(isV3() ? pV3Input->current.enabled.value : pV1Input->active)) {
Debug::log(WARN, "Disabled TextInput commit?"); Debug::log(WARN, "Disabled TextInput commit?");
return; return;
} }
@ -104,12 +123,12 @@ void CTextInput::setFocusedSurface(SP<CWLSurfaceResource> pSurface) {
pFocusedSurface = pSurface; pFocusedSurface = pSurface;
listeners.surfaceUnmap.reset();
listeners.surfaceDestroy.reset();
if (!pSurface) if (!pSurface)
return; return;
listeners.surfaceUnmap.reset();
listeners.surfaceDestroy.reset();
listeners.surfaceUnmap = pSurface->events.unmap.registerListener([this](std::any d) { listeners.surfaceUnmap = pSurface->events.unmap.registerListener([this](std::any d) {
Debug::log(LOG, "Unmap TI owner1"); Debug::log(LOG, "Unmap TI owner1");
@ -118,6 +137,16 @@ void CTextInput::setFocusedSurface(SP<CWLSurfaceResource> pSurface) {
pFocusedSurface.reset(); pFocusedSurface.reset();
listeners.surfaceUnmap.reset(); listeners.surfaceUnmap.reset();
listeners.surfaceDestroy.reset(); listeners.surfaceDestroy.reset();
if (isV3() && !pV3Input.expired() && pV3Input->current.enabled.value) {
pV3Input->pending.enabled.value = false;
pV3Input->pending.enabled.isDisablePending = false;
pV3Input->pending.enabled.isEnablePending = false;
pV3Input->current.enabled.value = false;
}
if (!g_pInputManager->m_sIMERelay.getFocusedTextInput())
g_pInputManager->m_sIMERelay.deactivateIME(this);
}); });
listeners.surfaceDestroy = pSurface->events.destroy.registerListener([this](std::any d) { listeners.surfaceDestroy = pSurface->events.destroy.registerListener([this](std::any d) {
@ -128,6 +157,16 @@ void CTextInput::setFocusedSurface(SP<CWLSurfaceResource> pSurface) {
pFocusedSurface.reset(); pFocusedSurface.reset();
listeners.surfaceUnmap.reset(); listeners.surfaceUnmap.reset();
listeners.surfaceDestroy.reset(); listeners.surfaceDestroy.reset();
if (isV3() && !pV3Input.expired() && pV3Input->current.enabled.value) {
pV3Input->pending.enabled.value = false;
pV3Input->pending.enabled.isDisablePending = false;
pV3Input->pending.enabled.isEnablePending = false;
pV3Input->current.enabled.value = false;
}
if (!g_pInputManager->m_sIMERelay.getFocusedTextInput())
g_pInputManager->m_sIMERelay.deactivateIME(this);
}); });
} }
@ -142,10 +181,8 @@ void CTextInput::enter(SP<CWLSurfaceResource> pSurface) {
if (pSurface == focusedSurface()) if (pSurface == focusedSurface())
return; return;
if (focusedSurface()) { if (focusedSurface())
leave(); leave();
setFocusedSurface(nullptr);
}
enterLocks++; enterLocks++;
if (enterLocks != 1) { if (enterLocks != 1) {
@ -173,11 +210,10 @@ void CTextInput::leave() {
enterLocks = 0; enterLocks = 0;
} }
if (isV3() && focusedSurface()) if (isV3())
pV3Input->leave(focusedSurface()); pV3Input->leave(focusedSurface());
else if (focusedSurface() && pV1Input) { else
pV1Input->leave(); pV1Input->leave();
}
setFocusedSurface(nullptr); setFocusedSurface(nullptr);
@ -242,7 +278,7 @@ void CTextInput::updateIMEState(SP<CInputMethodV2> ime) {
INPUT->preeditStyling(0, std::string(ime->current.preeditString.string).length(), ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT); INPUT->preeditStyling(0, std::string(ime->current.preeditString.string).length(), ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT);
INPUT->preeditString(pV1Input->serial, ime->current.preeditString.string.c_str(), ""); INPUT->preeditString(pV1Input->serial, ime->current.preeditString.string.c_str(), "");
} else { } else {
INPUT->preeditCursor(ime->current.preeditString.begin); INPUT->preeditCursor(0);
INPUT->preeditStyling(0, 0, ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT); INPUT->preeditStyling(0, 0, ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT);
INPUT->preeditString(pV1Input->serial, "", ""); INPUT->preeditString(pV1Input->serial, "", "");
} }

View file

@ -29,6 +29,7 @@ class CTextInput {
void onEnabled(SP<CWLSurfaceResource> surfV1 = nullptr); void onEnabled(SP<CWLSurfaceResource> surfV1 = nullptr);
void onDisabled(); void onDisabled();
void onCommit(); void onCommit();
void onReset();
bool hasCursorRectangle(); bool hasCursorRectangle();
CBox cursorBox(); CBox cursorBox();
@ -47,6 +48,7 @@ class CTextInput {
struct { struct {
CHyprSignalListener enable; CHyprSignalListener enable;
CHyprSignalListener disable; CHyprSignalListener disable;
CHyprSignalListener reset;
CHyprSignalListener commit; CHyprSignalListener commit;
CHyprSignalListener destroy; CHyprSignalListener destroy;
CHyprSignalListener surfaceUnmap; CHyprSignalListener surfaceUnmap;

View file

@ -1,7 +1,6 @@
#include "InputManager.hpp" #include "InputManager.hpp"
#include "../../Compositor.hpp" #include "../../Compositor.hpp"
#include "../../config/ConfigValue.hpp" #include "../../config/ConfigValue.hpp"
#include "../../protocols/IdleNotify.hpp"
#include "../../devices/ITouch.hpp" #include "../../devices/ITouch.hpp"
#include "../SeatManager.hpp" #include "../SeatManager.hpp"
@ -78,8 +77,6 @@ void CInputManager::onTouchDown(ITouch::SDownEvent e) {
return; // oops, nothing found. return; // oops, nothing found.
g_pSeatManager->sendTouchDown(m_sTouchData.touchFocusSurface.lock(), e.timeMs, e.touchID, local); g_pSeatManager->sendTouchDown(m_sTouchData.touchFocusSurface.lock(), e.timeMs, e.touchID, local);
PROTO::idle->onActivity();
} }
void CInputManager::onTouchUp(ITouch::SUpEvent e) { void CInputManager::onTouchUp(ITouch::SUpEvent e) {

View file

@ -1,7 +1,9 @@
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('Hyprland', src, executable(
'Hyprland',
src,
link_args: '-rdynamic', link_args: '-rdynamic',
cpp_pch: 'pch/pch.hpp', cpp_pch: 'pch/pch.hpp',
dependencies: [ dependencies: [
@ -38,5 +40,5 @@ executable('Hyprland', src,
dependency('pangocairo'), dependency('pangocairo'),
dependency('uuid'), dependency('uuid'),
], ],
install : true install: true,
) )

View file

@ -31,6 +31,7 @@ CTextInputV1::CTextInputV1(SP<CZwpTextInputV1> resource_) : resource(resource_)
resource->setReset([this](CZwpTextInputV1* pMgr) { resource->setReset([this](CZwpTextInputV1* pMgr) {
pendingSurrounding.isPending = false; pendingSurrounding.isPending = false;
pendingContentType.isPending = false; pendingContentType.isPending = false;
events.reset.emit();
}); });
resource->setSetSurroundingText( resource->setSetSurroundingText(

View file

@ -37,6 +37,7 @@ class CTextInputV1 {
CSignal onCommit; CSignal onCommit;
CSignal enable; CSignal enable;
CSignal disable; CSignal disable;
CSignal reset;
CSignal destroy; CSignal destroy;
} events; } events;

View file

@ -19,18 +19,22 @@ CTextInputV3::CTextInputV3(SP<CZwpTextInputV3> resource_) : resource(resource_)
resource->setOnDestroy([this](CZwpTextInputV3* r) { PROTO::textInputV3->destroyTextInput(this); }); resource->setOnDestroy([this](CZwpTextInputV3* r) { PROTO::textInputV3->destroyTextInput(this); });
resource->setCommit([this](CZwpTextInputV3* r) { resource->setCommit([this](CZwpTextInputV3* r) {
bool wasEnabled = current.enabled; bool wasEnabled = current.enabled.value;
current = pending; current = pending;
serial++; serial++;
if (wasEnabled && !current.enabled) { if (wasEnabled && !current.enabled.value)
current.reset();
events.disable.emit(); events.disable.emit();
} else if (!wasEnabled && current.enabled) else if (!wasEnabled && current.enabled.value)
events.enable.emit(); events.enable.emit();
else if (current.enabled.value && current.enabled.isEnablePending && current.enabled.isDisablePending)
events.reset.emit();
else else
events.onCommit.emit(); events.onCommit.emit();
pending.enabled.isEnablePending = false;
pending.enabled.isDisablePending = false;
}); });
resource->setSetSurroundingText([this](CZwpTextInputV3* r, const char* text, int32_t cursor, int32_t anchor) { resource->setSetSurroundingText([this](CZwpTextInputV3* r, const char* text, int32_t cursor, int32_t anchor) {
@ -53,11 +57,15 @@ CTextInputV3::CTextInputV3(SP<CZwpTextInputV3> resource_) : resource(resource_)
pending.box.cursorBox = {x, y, w, h}; pending.box.cursorBox = {x, y, w, h};
}); });
resource->setEnable([this](CZwpTextInputV3* r) { pending.enabled = true; }); resource->setEnable([this](CZwpTextInputV3* r) {
pending.reset();
pending.enabled.value = true;
pending.enabled.isEnablePending = true;
});
resource->setDisable([this](CZwpTextInputV3* r) { resource->setDisable([this](CZwpTextInputV3* r) {
pending.enabled = false; pending.enabled.value = false;
pending.reset(); pending.enabled.isDisablePending = true;
}); });
} }

View file

@ -31,6 +31,7 @@ class CTextInputV3 {
CSignal onCommit; CSignal onCommit;
CSignal enable; CSignal enable;
CSignal disable; CSignal disable;
CSignal reset;
CSignal destroy; CSignal destroy;
} events; } events;
@ -53,7 +54,11 @@ class CTextInputV3 {
CBox cursorBox; CBox cursorBox;
} box; } box;
bool enabled = false; struct {
bool isEnablePending = false;
bool isDisablePending = false;
bool value = false;
} enabled;
zwpTextInputV3ChangeCause cause = ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD; zwpTextInputV3ChangeCause cause = ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD;

View file

@ -1742,6 +1742,10 @@ void CHyprRenderer::arrangeLayersForMonitor(const MONITORID& monitor) {
CBox usableArea = {PMONITOR->vecPosition.x, PMONITOR->vecPosition.y, PMONITOR->vecSize.x, PMONITOR->vecSize.y}; CBox usableArea = {PMONITOR->vecPosition.x, PMONITOR->vecPosition.y, PMONITOR->vecSize.x, PMONITOR->vecSize.y};
for (auto& la : PMONITOR->m_aLayerSurfaceLayers) {
std::stable_sort(la.begin(), la.end(), [](const PHLLSREF& a, const PHLLSREF& b) { return a->order > b->order; });
}
for (auto const& la : PMONITOR->m_aLayerSurfaceLayers) for (auto const& la : PMONITOR->m_aLayerSurfaceLayers)
arrangeLayerArray(PMONITOR, la, true, &usableArea); arrangeLayerArray(PMONITOR, la, true, &usableArea);