Compare commits

..

66 Commits

Author SHA1 Message Date
Mihai Fufezan
f9985a36b3 nix & meson: 0.6.2 -> 0.7.0 2022-07-12 20:12:59 +03:00
vaxerski
ad03360665 fix device sections shadowing parse errors 2022-07-12 16:07:51 +02:00
vaxerski
3914672dd5 mention more config options in cfgs 2022-07-12 15:41:42 +02:00
vaxerski
78c6371743 default vfr to off 2022-07-12 15:41:28 +02:00
Vaxry
f789a14527 updated issue guidelines 2022-07-12 15:35:23 +02:00
vaxerski
b1e3430405 only set xwayland size/pos on reasonable deltas 2022-07-12 14:14:12 +02:00
vaxerski
a4f82491b7 active opacity is now animated 2022-07-12 13:40:55 +02:00
Mathias Zhang
da83ef7b96 add config drag_lock for touchpad (#353)
* add config drag_lock for touchpad

* fix err

* Update ConfigManager.cpp
2022-07-12 13:11:54 +02:00
vaxerski
2d856ac4b0 Added yes/no values to int parsing 2022-07-12 10:28:42 +02:00
vaxerski
29e2bb27f6 added misc:no_vfr 2022-07-12 10:02:12 +02:00
vaxerski
2f3b2db83d fixed tiled popups going behind windows 2022-07-12 09:49:56 +02:00
vaxerski
bf8bd87d11 added active monitor to hyprctl monitors 2022-07-12 00:16:28 +02:00
vaxerski
c0c75db621 roll VFR for everyone 2022-07-11 23:56:24 +02:00
vaxerski
f461ea3105 squish oversized subsurfaces while animating 2022-07-11 23:38:10 +02:00
vaxerski
668dc9bd9c [gha] bump flake inputs 2022-07-11 21:11:07 +00:00
vaxerski
b55b6c95f2 update wlroots dep 2022-07-11 23:09:35 +02:00
vaxerski
676e4c36c5 fix focus on layers when constrained 2022-07-11 22:51:20 +02:00
vaxerski
ad66c158ba don't refocus on virt ptrs 2022-07-11 20:23:16 +02:00
vaxerski
ab44aabbd7 update decos on setgeometry x11 2022-07-11 19:07:59 +02:00
vaxerski
4c4c36096b fix config reload on fullscreen mode maximized 2022-07-11 15:40:41 +02:00
vaxerski
c923b0e538 respect size in setgeo unmanaged x11 2022-07-11 15:31:31 +02:00
vaxerski
2936368e80 minor event fixes 2022-07-11 14:13:15 +02:00
vaxerski
5eaf93697a clear kb focus on focusSurface null 2022-07-11 12:29:50 +02:00
vaxerski
11c88e2503 apply surface width to ls geo on commit 2022-07-10 20:36:32 +02:00
vaxerski
4b334594dc Added splashes 2022-07-10 15:41:26 +02:00
vaxerski
06c0be5ea6 clear with 17 2022-07-10 11:45:50 +02:00
vaxerski
6f7377f381 accumulate mods from all kbs for keybind processing 2022-07-09 23:24:08 +02:00
vaxerski
c44cafda97 added cyclenext param previous 2022-07-09 18:39:41 +02:00
vaxerski
ddc4cbbd7e allow focus to modal 2022-07-08 23:37:55 +02:00
vaxerski
e6872bddf4 fix minor issues with floating windows and fullscreen 2022-07-08 21:52:52 +02:00
Mihai Fufezan
a7a3c0fc1d nix: add devShell 2022-07-08 18:34:23 +03:00
Fernando Ayats
c8c5e0b90a nix: fix wallpaper location (#334) 2022-07-08 17:46:42 +03:00
vaxerski
8482063157 fixed layersurface focus quirks 2022-07-08 13:19:57 +02:00
vaxerski
92e17f2925 added rules to hyprctl devices and fixed rules 2022-07-08 12:27:05 +02:00
vaxerski
491b99c61e handle unmanaged X11 setGeometry 2022-07-08 11:24:07 +02:00
vaxerski
75a580feda Disallow focus to modal and override_redirect X11 windows 2022-07-08 10:36:21 +02:00
vaxerski
91249675de fix corner artifacts 2022-07-08 09:43:55 +02:00
vaxerski
46306e59eb added keycode support to unbind 2022-07-08 09:32:09 +02:00
vaxerski
cd0a01f4de Added binding by keycodes 2022-07-08 09:27:17 +02:00
vaxerski
75c2a378e3 unfocus keyboard on refocus null 2022-07-07 21:47:59 +02:00
vaxerski
96f19d706a fix possible swipe crash 2022-07-07 20:53:22 +02:00
vaxerski
3278db67a2 added general:disable_hyprland_logo 2022-07-07 20:16:40 +02:00
vaxerski
aa3bc65342 fix special status when workspace is changed 2022-07-07 19:16:16 +02:00
vaxerski
a7b595d968 allow windowrule special again 2022-07-07 19:01:42 +02:00
vaxerski
05736bc1e3 I am an idiot, fixed special ws deletion 2022-07-07 19:00:34 +02:00
vaxerski
3bf172a37e fix hyprerror on scaled outputs 2022-07-07 18:45:01 +02:00
vaxerski
22c4ecf496 fixed swiping with one ws 2022-07-07 13:57:26 +02:00
Vaxry
3f43f94dc4 Merge pull request #318 from hyprwm/swipes
Added swipe workspace gestures
2022-07-07 13:49:43 +02:00
vaxerski
4b796d30c1 Added swipe workspace gestures 2022-07-07 13:49:04 +02:00
vaxerski
5762e3b9e2 fix stretched ls 2022-07-07 12:40:32 +02:00
vaxerski
1cf2f378d4 added ls blurring 2022-07-06 22:12:03 +02:00
vaxerski
6a16f11d63 add namespace to hyprctl layers 2022-07-06 21:57:35 +02:00
vaxerski
a545992891 fixed hyprctl layers crash 2022-07-06 21:57:15 +02:00
Mihai Fufezan
f5936f97d6 nix: use gcc12Stdenv 2022-07-06 18:41:20 +03:00
vaxerski
141f9810bb fix meson C++23 2022-07-06 17:02:12 +02:00
vaxerski
1599dc47d1 set proper C++23 std to meson as well 2022-07-06 16:55:49 +02:00
vaxerski
42d18143e5 use std::unreachable in avars 2022-07-06 16:54:45 +02:00
vaxerski
f9756d10d4 changed C++ std to C++23, use std::string::contains 2022-07-06 16:50:11 +02:00
vaxerski
0d7a8cca79 use C++ throw methods instead of printf and exit 2022-07-06 16:17:58 +02:00
vaxerski
9655d0c138 added support for wlr_idle_inhibitor_v1 2022-07-06 15:42:37 +02:00
vaxerski
5a22335b8d refocus after group toggles 2022-07-06 15:08:21 +02:00
vaxerski
0277f4c6bd support relative paths in source= 2022-07-06 15:05:23 +02:00
vaxerski
8d05dddb98 fix focus on maximized windows with special open 2022-07-06 14:58:46 +02:00
vaxerski
0d54451c67 fix incorrect mouse pos in fullscreen xdg 2022-07-06 11:12:27 +02:00
vaxerski
cda0c4577e find floating special windows in vector methods 2022-07-06 11:07:23 +02:00
vaxerski
239aa2cec4 fix internal workspace changes being clamped 2022-07-06 11:02:21 +02:00
48 changed files with 1091 additions and 246 deletions

1
.gitignore vendored
View File

@@ -12,6 +12,7 @@ _deps
build/
result
/.vscode/
.envrc
*.o
*-protocol.c

View File

@@ -37,7 +37,7 @@ execute_process(
include_directories(. PRIVATE "subprojects/wlroots/include/")
include_directories(. PRIVATE "subprojects/wlroots/build/include/")
add_compile_options(-std=c++20 -DWLR_USE_UNSTABLE )
add_compile_options(-std=c++23 -DWLR_USE_UNSTABLE )
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-narrowing)
find_package(Threads REQUIRED)

View File

@@ -26,6 +26,7 @@ If your bug is one that doesn't crash Hyprland, but feels like invalid behavior,
If your bug crashes Hyprland, append additionally:
- The Hyprland log
- Coredump / Coredump analysis (with a stacktrace)
- Your config
**Important**: Please do NOT use any package for reporting bugs! Clone and compile from source.

View File

@@ -3,6 +3,11 @@
#
# Refer to the wiki for more information.
#
# Please note not all available settings / options are set here.
# For a full list, see the wiki (basic and advanced configuring)
#
monitor=,1280x720@60,0x0,1
workspace=DP-1,1

12
flake.lock generated
View File

@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1656239181,
"narHash": "sha256-wW1xRFBn376yGloXZ4QzBE4hjipMawpV18Lshd9QSPw=",
"lastModified": 1657447684,
"narHash": "sha256-FCP9AuU1q6PE3vOeM5SFf58f/UKPBAsoSGDUGamNBbo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f2537a505d45c31fe5d9c27ea9829b6f4c4e6ac5",
"rev": "5f43d8b088d3771274bcfb69d3c7435b1121ac88",
"type": "github"
},
"original": {
@@ -26,11 +26,11 @@
"flake": false,
"locked": {
"host": "gitlab.freedesktop.org",
"lastModified": 1655824477,
"narHash": "sha256-1kskHOLsnisR3kqIL5IHrQbQG/4xoXxeEf1ExMV6/RU=",
"lastModified": 1656865312,
"narHash": "sha256-xtQ0zwJZwN8sciruveM10CzKz6TWxBY8SyXa8E4jly4=",
"owner": "wlroots",
"repo": "wlroots",
"rev": "5c4384a1330faedf975c8b8644881d50390f3613",
"rev": "5dc1d4671dd2ca3c1f0f09587c463fdbb542f0a4",
"type": "gitlab"
},
"original": {

View File

@@ -32,7 +32,8 @@
src = inputs.wlroots;
});
hyprland = prev.callPackage ./nix/default.nix {
version = "0.6.2beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101"));
stdenv = prev.gcc12Stdenv;
version = "0.7.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101"));
wlroots = wlroots-hyprland;
};
hyprland-debug = hyprland.override {debug = true;};
@@ -47,6 +48,16 @@
default = self.packages.${system}.hyprland;
});
devShells = genSystems (system: {
default = pkgsFor.${system}.mkShell.override {stdenv = pkgsFor.${system}.gcc12Stdenv;} {
name = "hyprland-shell";
inputsFrom = [
self.packages.${system}.wlroots-hyprland
self.packages.${system}.hyprland
];
};
});
formatter = genSystems (system: pkgsFor.${system}.alejandra);
nixosModules.default = import ./nix/module.nix self;

View File

@@ -27,6 +27,7 @@ const std::string USAGE = R"#(usage: hyprctl [command] [(opt)args]
keyword
version
kill
splash
hyprpaper
reload)#";
@@ -201,6 +202,7 @@ int main(int argc, char** argv) {
else if (!strcmp(argv[1], "layers")) request("layers");
else if (!strcmp(argv[1], "version")) request("version");
else if (!strcmp(argv[1], "kill")) request("kill");
else if (!strcmp(argv[1], "splash")) request("splash");
else if (!strcmp(argv[1], "devices")) request("devices");
else if (!strcmp(argv[1], "reload")) request("reload");
else if (!strcmp(argv[1], "dispatch")) dispatchRequest(argc, argv);

View File

@@ -1,6 +1,8 @@
project('Hyprland', 'cpp', 'c',
version : '0.6.2beta',
default_options : ['warning_level=2', 'cpp_std=c++20', 'default_library=static', 'optimization=3'])
version : '0.7.0beta',
default_options : ['warning_level=2', 'default_library=static', 'optimization=3'])
add_global_arguments('-std=c++23', language: 'cpp')
add_project_arguments(
[

View File

@@ -61,6 +61,11 @@ stdenv.mkDerivation {
./meson-build.patch
];
# Fix hardcoded paths to /usr installation
postPatch = ''
sed -i "s#/usr#$out#" src/render/OpenGL.cpp
'';
passthru.providedSessions = ["hyprland"];
meta = with lib; {

View File

@@ -1,4 +1,6 @@
#include "Compositor.hpp"
#include "helpers/Splashes.hpp"
#include <random>
CCompositor::CCompositor() {
m_szInstanceSignature = GIT_COMMIT_HASH + std::string("_") + std::to_string(time(NULL));
@@ -22,29 +24,30 @@ CCompositor::CCompositor() {
Debug::log(INFO, "If you are crashing, or encounter any bugs, please consult https://github.com/hyprwm/Hyprland/wiki/Crashing-and-bugs\n\n");
setRandomSplash();
Debug::log(LOG, "\nCurrent splash: %s\n\n", m_szCurrentSplash.c_str());
m_sWLDisplay = wl_display_create();
m_sWLRBackend = wlr_backend_autocreate(m_sWLDisplay);
if (!m_sWLRBackend) {
Debug::log(CRIT, "m_sWLRBackend was NULL!");
RIP("m_sWLRBackend NULL!");
return;
throw std::runtime_error("wlr_backend_autocreate() failed!");
}
m_iDRMFD = wlr_backend_get_drm_fd(m_sWLRBackend);
if (m_iDRMFD < 0) {
Debug::log(CRIT, "Couldn't query the DRM FD!");
RIP("DRMFD NULL!");
return;
throw std::runtime_error("wlr_backend_get_drm_fd() failed!");
}
m_sWLRRenderer = wlr_gles2_renderer_create_with_drm_fd(m_iDRMFD);
if (!m_sWLRRenderer) {
Debug::log(CRIT, "m_sWLRRenderer was NULL!");
RIP("m_sWLRRenderer NULL!");
return;
throw std::runtime_error("wlr_gles2_renderer_create_with_drm_fd() failed!");
}
wlr_renderer_init_wl_display(m_sWLRRenderer, m_sWLDisplay);
@@ -53,16 +56,14 @@ CCompositor::CCompositor() {
if (!m_sWLRAllocator) {
Debug::log(CRIT, "m_sWLRAllocator was NULL!");
RIP("m_sWLRAllocator NULL!");
return;
throw std::runtime_error("wlr_allocator_autocreate() failed!");
}
m_sWLREGL = wlr_gles2_renderer_get_egl(m_sWLRRenderer);
if (!m_sWLREGL) {
Debug::log(CRIT, "m_sWLREGL was NULL!");
RIP("m_sWLREGL NULL!");
return;
throw std::runtime_error("wlr_gles2_renderer_get_egl() failed!");
}
m_sWLRCompositor = wlr_compositor_create(m_sWLDisplay, m_sWLRRenderer);
@@ -124,8 +125,12 @@ CCompositor::CCompositor() {
m_sWLRForeignRegistry = wlr_xdg_foreign_registry_create(m_sWLDisplay);
m_sWLRIdleInhibitMgr = wlr_idle_inhibit_v1_create(m_sWLDisplay);
wlr_xdg_foreign_v1_create(m_sWLDisplay, m_sWLRForeignRegistry);
wlr_xdg_foreign_v2_create(m_sWLDisplay, m_sWLRForeignRegistry);
m_sWLRPointerGestures = wlr_pointer_gestures_v1_create(m_sWLDisplay);
}
CCompositor::~CCompositor() {
@@ -137,6 +142,14 @@ void handleCritSignal(int signo) {
exit(signo);
}
void CCompositor::setRandomSplash() {
std::random_device dev;
std::mt19937 engine(dev());
std::uniform_int_distribution<> distribution(0, SPLASHES.size() - 1);
m_szCurrentSplash = SPLASHES[distribution(engine)];
}
void CCompositor::initAllSignals() {
addWLSignal(&m_sWLRBackend->events.new_output, &Events::listen_newOutput, m_sWLRBackend, "Backend");
addWLSignal(&m_sWLRXDGShell->events.new_surface, &Events::listen_newXDGSurface, m_sWLRXDGShell, "XDG Shell");
@@ -145,6 +158,9 @@ void CCompositor::initAllSignals() {
addWLSignal(&m_sWLRCursor->events.button, &Events::listen_mouseButton, m_sWLRCursor, "WLRCursor");
addWLSignal(&m_sWLRCursor->events.axis, &Events::listen_mouseAxis, m_sWLRCursor, "WLRCursor");
addWLSignal(&m_sWLRCursor->events.frame, &Events::listen_mouseFrame, m_sWLRCursor, "WLRCursor");
addWLSignal(&m_sWLRCursor->events.swipe_begin, &Events::listen_swipeBegin, m_sWLRCursor, "WLRCursor");
addWLSignal(&m_sWLRCursor->events.swipe_update, &Events::listen_swipeUpdate, m_sWLRCursor, "WLRCursor");
addWLSignal(&m_sWLRCursor->events.swipe_end, &Events::listen_swipeEnd, m_sWLRCursor, "WLRCursor");
addWLSignal(&m_sWLRBackend->events.new_input, &Events::listen_newInput, m_sWLRBackend, "Backend");
addWLSignal(&m_sSeat.seat->events.request_set_cursor, &Events::listen_requestMouse, &m_sSeat, "Seat");
addWLSignal(&m_sSeat.seat->events.request_set_selection, &Events::listen_requestSetSel, &m_sSeat, "Seat");
@@ -160,6 +176,7 @@ void CCompositor::initAllSignals() {
addWLSignal(&m_sWLRXDGDecoMgr->events.new_toplevel_decoration, &Events::listen_NewXDGDeco, m_sWLRXDGDecoMgr, "XDGDecoMgr");
addWLSignal(&m_sWLRVirtPtrMgr->events.new_virtual_pointer, &Events::listen_newVirtPtr, m_sWLRVirtPtrMgr, "VirtPtrMgr");
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
addWLSignal(&m_sWLRIdleInhibitMgr->events.new_inhibitor, &Events::listen_newIdleInhibitor, m_sWLRIdleInhibitMgr, "WLRIdleInhibitMgr");
signal(SIGINT, handleCritSignal);
signal(SIGTERM, handleCritSignal);
@@ -245,7 +262,7 @@ void CCompositor::startCompositor() {
if (!m_szWLDisplaySocket) {
Debug::log(CRIT, "m_szWLDisplaySocket NULL!");
wlr_backend_destroy(m_sWLRBackend);
RIP("m_szWLDisplaySocket NULL!");
throw std::runtime_error("m_szWLDisplaySocket was null! (wl_display_add_socket_auto failed)");
}
setenv("WAYLAND_DISPLAY", m_szWLDisplaySocket, 1);
@@ -258,7 +275,7 @@ void CCompositor::startCompositor() {
Debug::log(CRIT, "Backend did not start!");
wlr_backend_destroy(m_sWLRBackend);
wl_display_destroy(m_sWLDisplay);
RIP("Backend did not start!");
throw std::runtime_error("The backend could not start!");
}
wlr_xcursor_manager_set_cursor_image(m_sWLRXCursorMgr, "left_ptr", m_sWLRCursor);
@@ -361,6 +378,12 @@ CWindow* CCompositor::vectorToWindow(const Vector2D& pos) {
const auto PMONITOR = getMonitorFromVector(pos);
if (PMONITOR->specialWorkspaceOpen) {
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->m_bHidden)
return (*w).get();
}
for (auto& w : m_vWindows) {
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && !w->m_bIsFloating && !w->m_bHidden)
@@ -404,14 +427,29 @@ CWindow* CCompositor::vectorToWindowTiled(const Vector2D& pos) {
return nullptr;
}
void findExtensionForVector2D(wlr_surface* surface, int x, int y, void* data) {
const auto DATA = (SExtensionFindingData*)data;
wlr_box box = {DATA->origin.x + x, DATA->origin.y + y, surface->current.width, surface->current.height};
if (wlr_box_contains_point(&box, DATA->vec.x, DATA->vec.y))
*DATA->found = surface;
}
CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
const auto PMONITOR = getMonitorFromVector(pos);
// special workspace
if (PMONITOR->specialWorkspaceOpen) {
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->m_bHidden && (*w)->m_iX11Type != 2)
return (*w).get();
}
for (auto& w : m_vWindows) {
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !w->m_bHidden)
if (!w->m_bIsFloating && w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !w->m_bHidden && w->m_iX11Type != 2)
return w.get();
}
}
@@ -419,13 +457,37 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden)
return w->get();
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && (*w)->m_iX11Type != 2) {
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y))
return w->get();
if (!(*w)->m_bIsX11) {
wlr_surface* resultSurf = nullptr;
Vector2D origin =(*w)->m_vRealPosition.vec();
SExtensionFindingData data = {origin, pos, &resultSurf};
wlr_xdg_surface_for_each_popup_surface((*w)->m_uSurface.xdg, findExtensionForVector2D, &data);
if (resultSurf)
return w->get();
}
}
}
// for windows, we need to check their extensions too, first.
for (auto& w : m_vWindows) {
if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bHidden && w->m_iX11Type != 2) {
wlr_surface* resultSurf = nullptr;
Vector2D origin = w->m_vRealPosition.vec();
SExtensionFindingData data = {origin, pos, &resultSurf};
wlr_xdg_surface_for_each_popup_surface(w->m_uSurface.xdg, findExtensionForVector2D, &data);
if (resultSurf)
return w.get();
}
}
for (auto& w : m_vWindows) {
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
if (!w->m_bIsFloating && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bHidden)
if (!w->m_bIsFloating && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bHidden && w->m_iX11Type != 2)
return w.get();
}
@@ -436,6 +498,12 @@ CWindow* CCompositor::windowFromCursor() {
const auto PMONITOR = getMonitorFromCursor();
if (PMONITOR->specialWorkspaceOpen) {
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && !(*w)->m_bHidden)
return (*w).get();
}
for (auto& w : m_vWindows) {
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w->m_bIsMapped)
@@ -536,7 +604,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
// we need to make the PLASTWINDOW not equal to m_pLastWindow so that RENDERDATA is correct for an unfocused window
if (windowValidMapped(PLASTWINDOW)) {
updateWindowBorderColor(PLASTWINDOW);
updateWindowAnimatedDecorationValues(PLASTWINDOW);
if (PLASTWINDOW->m_bIsX11) {
wlr_seat_keyboard_notify_clear_focus(m_sSeat.seat);
@@ -559,7 +627,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
const auto POINTERLOCAL = g_pInputManager->getMouseCoordsInternal() - pWindow->m_vRealPosition.goalv();
wlr_seat_pointer_notify_enter(m_sSeat.seat, PWINDOWSURFACE, POINTERLOCAL.x, POINTERLOCAL.y);
updateWindowBorderColor(pWindow);
updateWindowAnimatedDecorationValues(pWindow);
// Send an event
g_pEventManager->postEvent(SHyprIPCEvent("activewindow", g_pXWaylandManager->getAppIDClass(pWindow) + "," + pWindow->m_szTitle));
@@ -573,12 +641,16 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
if (m_sSeat.seat->keyboard_state.focused_surface == pSurface || (pWindowOwner && m_sSeat.seat->keyboard_state.focused_surface == g_pXWaylandManager->getWindowSurface(pWindowOwner)))
return; // Don't focus when already focused on this.
if (!pSurface)
return;
// Unfocus last surface if should
if (m_pLastFocus && m_sSeat.seat->keyboard_state.focused_surface && wlr_surface_is_xdg_surface(m_pLastFocus))
wlr_xdg_toplevel_set_activated(wlr_xdg_surface_from_wlr_surface(m_pLastFocus)->toplevel, false);
if (m_pLastFocus && ((m_sSeat.seat->keyboard_state.focused_surface && wlr_surface_is_xdg_surface(m_pLastFocus)) || !pSurface))
g_pXWaylandManager->activateSurface(m_pLastFocus, false);
if (!pSurface) {
wlr_seat_keyboard_clear_focus(m_sSeat.seat);
g_pEventManager->postEvent(SHyprIPCEvent("activewindow", ",")); // unfocused
return;
}
const auto KEYBOARD = wlr_seat_get_keyboard(m_sSeat.seat);
@@ -598,6 +670,9 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
Debug::log(LOG, "Set keyboard focus to surface %x, with window name: %s", pSurface, pWindowOwner->m_szTitle.c_str());
else
Debug::log(LOG, "Set keyboard focus to surface %x", pSurface);
g_pXWaylandManager->activateSurface(pSurface, false);
m_pLastFocus = pSurface;
}
bool CCompositor::windowValidMapped(CWindow* pWindow) {
@@ -689,6 +764,8 @@ void CCompositor::sanityCheckWorkspaces() {
if (it == m_vWorkspaces.end())
break;
continue;
}
if ((*it)->m_iID == SPECIAL_WORKSPACE_ID && WINDOWSONWORKSPACE == 0) {
@@ -700,6 +777,8 @@ void CCompositor::sanityCheckWorkspaces() {
if (it == m_vWorkspaces.end())
break;
continue;
}
}
}
@@ -910,6 +989,29 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow) {
return nullptr;
}
CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow) {
bool gotToWindow = false;
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) {
if (it->get() != pWindow && !gotToWindow)
continue;
if (it->get() == pWindow) {
gotToWindow = true;
continue;
}
if ((*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden)
return it->get();
}
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) {
if (it->get() != pWindow && (*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden)
return it->get();
}
return nullptr;
}
int CCompositor::getNextAvailableNamedWorkspace() {
int lowest = -1337 + 1;
for (auto& w : m_vWorkspaces) {
@@ -1032,25 +1134,50 @@ SMonitor* CCompositor::getMonitorInDirection(const char& dir) {
return nullptr;
}
void CCompositor::updateAllWindowsBorders() {
void CCompositor::updateAllWindowsAnimatedDecorationValues() {
for (auto& w : m_vWindows) {
if (!w->m_bIsMapped)
continue;
updateWindowBorderColor(w.get());
updateWindowAnimatedDecorationValues(w.get());
}
}
void CCompositor::updateWindowBorderColor(CWindow* pWindow) {
void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
// optimization
static int64_t* ACTIVECOL = &g_pConfigManager->getConfigValuePtr("general:col.active_border")->intValue;
static int64_t* INACTIVECOL = &g_pConfigManager->getConfigValuePtr("general:col.inactive_border")->intValue;
static auto *const PINACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:inactive_opacity")->floatValue;
static auto *const PACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:active_opacity")->floatValue;
static auto *const PFULLSCREENALPHA = &g_pConfigManager->getConfigValuePtr("decoration:fullscreen_opacity")->floatValue;
// border
const auto RENDERDATA = g_pLayoutManager->getCurrentLayout()->requestRenderHints(pWindow);
if (RENDERDATA.isBorderColor)
pWindow->m_cRealBorderColor = RENDERDATA.borderColor;
else
pWindow->m_cRealBorderColor = CColor(pWindow == m_pLastWindow ? *ACTIVECOL : *INACTIVECOL);
// opacity
if (pWindow->m_bIsFullscreen) {
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL)
pWindow->m_fActiveInactiveAlpha = *PFULLSCREENALPHA;
else {
if (pWindow == m_pLastWindow)
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alpha != -1 ? pWindow->m_sSpecialRenderData.alpha : *PACTIVEALPHA;
else
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive != -1 ? pWindow->m_sSpecialRenderData.alphaInactive : *PINACTIVEALPHA;
}
} else {
if (pWindow == m_pLastWindow)
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alpha != -1 ? pWindow->m_sSpecialRenderData.alpha : *PACTIVEALPHA;
else
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive != -1 ? pWindow->m_sSpecialRenderData.alphaInactive : *PINACTIVEALPHA;
}
}
void CCompositor::moveWindowToWorkspace(CWindow* pWindow, const std::string& work) {
@@ -1188,4 +1315,13 @@ CWindow* CCompositor::getX11Parent(CWindow* pWindow) {
}
return nullptr;
}
}
void CCompositor::updateWorkspaceWindowDecos(const int& id) {
for (auto& w : m_vWindows) {
if (w->m_iWorkspaceID != id)
continue;
w->updateWindowDecos();
}
}

View File

@@ -61,11 +61,14 @@ public:
wlr_foreign_toplevel_manager_v1* m_sWLRToplevelMgr;
wlr_tablet_manager_v2* m_sWLRTabletManager;
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
wlr_idle_inhibit_manager_v1* m_sWLRIdleInhibitMgr;
wlr_pointer_gestures_v1* m_sWLRPointerGestures;
// ------------------------------------------------- //
const char* m_szWLDisplaySocket;
std::string m_szInstanceSignature = "";
std::string m_szCurrentSplash = "error";
std::vector<std::unique_ptr<SMonitor>> m_vMonitors;
std::vector<std::unique_ptr<CWindow>> m_vWindows;
@@ -99,7 +102,7 @@ public:
bool windowExists(CWindow*);
bool windowValidMapped(CWindow*);
CWindow* vectorToWindow(const Vector2D&);
CWindow* vectorToWindowIdeal(const Vector2D&);
CWindow* vectorToWindowIdeal(const Vector2D&); // used only for finding a window to focus on, basically a "findFocusableWindow"
CWindow* vectorToWindowTiled(const Vector2D&);
wlr_surface* vectorToLayerSurface(const Vector2D&, std::list<SLayerSurface*>*, Vector2D*, SLayerSurface**);
wlr_surface* vectorWindowToSurface(const Vector2D&, CWindow*, Vector2D& sl);
@@ -113,6 +116,7 @@ public:
CWorkspace* getWorkspaceByName(const std::string&);
CWorkspace* getWorkspaceByString(const std::string&);
void sanityCheckWorkspaces();
void updateWorkspaceWindowDecos(const int&);
int getWindowsOnWorkspace(const int&);
CWindow* getFirstWindowOnWorkspace(const int&);
void fixXWaylandWindowsOnWorkspace(const int&);
@@ -124,12 +128,13 @@ public:
CWindow* getWindowInDirection(CWindow*, char);
void deactivateAllWLRWorkspaces(wlr_ext_workspace_handle_v1* exclude = nullptr);
CWindow* getNextWindowOnWorkspace(CWindow*);
CWindow* getPrevWindowOnWorkspace(CWindow*);
int getNextAvailableNamedWorkspace();
bool isPointOnAnyMonitor(const Vector2D&);
CWindow* getConstraintWindow(SMouse*);
SMonitor* getMonitorInDirection(const char&);
void updateAllWindowsBorders();
void updateWindowBorderColor(CWindow*);
void updateAllWindowsAnimatedDecorationValues();
void updateWindowAnimatedDecorationValues(CWindow*);
void moveWindowToWorkspace(CWindow*, const std::string&);
int getNextAvailableMonitorID();
void moveWorkspaceToMonitor(CWorkspace*, SMonitor*);
@@ -140,6 +145,7 @@ public:
private:
void initAllSignals();
void setRandomSplash();
};

View File

@@ -7,6 +7,7 @@ CWindow::CWindow() {
m_vRealSize.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, &g_pConfigManager->getConfigValuePtr("animations:windows_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
m_cRealBorderColor.create(AVARTYPE_COLOR, &g_pConfigManager->getConfigValuePtr("animations:borders_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:borders")->intValue, &g_pConfigManager->getConfigValuePtr("animations:borders_curve")->strValue, (void*)this, AVARDAMAGE_BORDER);
m_fAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, &g_pConfigManager->getConfigValuePtr("animations:fadein_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
m_fActiveInactiveAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, &g_pConfigManager->getConfigValuePtr("animations:fadein_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
m_dWindowDecorations.emplace_back(std::make_unique<CHyprDropShadowDecoration>(this)); // put the shadow so it's the first deco (has to be rendered first)
}

View File

@@ -28,6 +28,7 @@ public:
DYNLISTENER(unmapWindow);
DYNLISTENER(destroyWindow);
DYNLISTENER(setTitleWindow);
DYNLISTENER(setGeometryX11U);
DYNLISTENER(fullscreenWindow);
DYNLISTENER(newPopupXDG);
// DYNLISTENER(newSubsurfaceWindow);
@@ -105,6 +106,9 @@ public:
SWindowSpecialRenderData m_sSpecialRenderData;
SWindowAdditionalConfigData m_sAdditionalConfigData;
// for alpha
CAnimatedVariable m_fActiveInactiveAlpha;
// For the list lookup
bool operator==(const CWindow& rhs) {
return m_uSurface.xdg == rhs.m_uSurface.xdg && m_uSurface.xwayland == rhs.m_uSurface.xwayland && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize && m_bFadingOut == rhs.m_bFadingOut;

View File

@@ -36,6 +36,10 @@ void CConfigManager::setDefaultVars() {
configValues["general:col.active_border"].intValue = 0xffffffff;
configValues["general:col.inactive_border"].intValue = 0xff444444;
configValues["general:cursor_inactive_timeout"].intValue = 0;
configValues["misc:disable_hyprland_logo"].intValue = 0;
configValues["misc:disable_splash_rendering"].intValue = 0;
configValues["misc:no_vfr"].intValue = 1;
configValues["debug:int"].intValue = 0;
configValues["debug:log_damage"].intValue = 0;
@@ -43,8 +47,6 @@ void CConfigManager::setDefaultVars() {
configValues["debug:damage_blink"].intValue = 0;
configValues["debug:disable_logs"].intValue = 0;
configValues["experimental:vfr"].intValue = 0;
configValues["decoration:rounding"].intValue = 1;
configValues["decoration:blur"].intValue = 1;
configValues["decoration:blur_size"].intValue = 8;
@@ -104,6 +106,13 @@ void CConfigManager::setDefaultVars() {
configValues["input:touchpad:clickfinger_behavior"].intValue = 0;
configValues["input:touchpad:middle_button_emulation"].intValue = 0;
configValues["input:touchpad:tap-to-click"].intValue = 1;
configValues["input:touchpad:drag_lock"].intValue = 0;
configValues["gestures:workspace_swipe"].intValue = 0;
configValues["gestures:workspace_swipe_distance"].intValue = 300;
configValues["gestures:workspace_swipe_invert"].intValue = 1;
configValues["gestures:workspace_swipe_min_speed_to_force"].intValue = 30;
configValues["gestures:workspace_swipe_cancel_ratio"].floatValue = 0.5f;
configValues["input:follow_mouse"].intValue = 1;
@@ -126,6 +135,7 @@ void CConfigManager::setDeviceDefaultVars(const std::string& dev) {
cfgValues["clickfinger_behavior"].intValue = 0;
cfgValues["middle_button_emulation"].intValue = 0;
cfgValues["tap-to-click"].intValue = 1;
cfgValues["drag_lock"].intValue = 0;
}
void CConfigManager::init() {
@@ -149,17 +159,15 @@ void CConfigManager::init() {
void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::string& VALUE) {
if (configValues.find(COMMAND) == configValues.end()) {
if (COMMAND[0] == '$') {
// register a dynamic var
Debug::log(LOG, "Registered dynamic var \"%s\" -> %s", COMMAND.c_str(), VALUE.c_str());
configDynamicVars[COMMAND.substr(1)] = VALUE;
} else {
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field.";
}
if (COMMAND.find("device:") != 0 /* devices parsed later */) {
if (COMMAND[0] == '$') {
// register a dynamic var
Debug::log(LOG, "Registered dynamic var \"%s\" -> %s", COMMAND.c_str(), VALUE.c_str());
configDynamicVars[COMMAND.substr(1)] = VALUE;
} else {
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field.";
}
if (COMMAND.find("device:") == 0 /* devices parsed later */) {
parseError = "";
} else {
return;
}
}
@@ -193,7 +201,12 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
// Values with 0x are hex
const auto VALUEWITHOUTHEX = VALUE.substr(2);
CONFIGENTRY->intValue = stol(VALUEWITHOUTHEX, nullptr, 16);
} else
} else if (VALUE.find("true") == 0 || VALUE.find("on") == 0 || VALUE.find("yes") == 0) {
CONFIGENTRY->intValue = 1;
} else if (VALUE.find("false") == 0 || VALUE.find("off") == 0 || VALUE.find("no") == 0) {
CONFIGENTRY->intValue = 0;
}
else
CONFIGENTRY->intValue = stol(VALUE);
} catch (...) {
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
@@ -356,7 +369,7 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
newrule.resolution.x = stoi(curitem.substr(0, curitem.find_first_of('x')));
newrule.resolution.y = stoi(curitem.substr(curitem.find_first_of('x') + 1, curitem.find_first_of('@')));
if (curitem.find_first_of('@') != std::string::npos)
if (curitem.contains("@"))
newrule.refreshRate = stof(curitem.substr(curitem.find_first_of('@') + 1));
nextItem();
@@ -505,8 +518,13 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
return;
}
if (KEY != "")
g_pKeybindManager->addKeybind(SKeybind{KEY, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap});
if (KEY != "") {
if (isNumber(KEY) && std::stoi(KEY) > 9)
g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap});
else
g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap});
}
}
void CConfigManager::handleUnbind(const std::string& command, const std::string& value) {
@@ -552,6 +570,10 @@ void CConfigManager::handleWindowRule(const std::string& command, const std::str
}
void CConfigManager::handleBlurLS(const std::string& command, const std::string& value) {
m_dBlurLSNamespaces.emplace_back(value);
}
void CConfigManager::handleDefaultWorkspace(const std::string& command, const std::string& value) {
const auto DISPLAY = value.substr(0, value.find_first_of(','));
@@ -577,6 +599,23 @@ void CConfigManager::handleSource(const std::string& command, const std::string&
auto value = rawpath;
if (value.length() < 2) {
Debug::log(ERR, "source= path garbage");
parseError = "source path " + value + " bogus!";
return;
}
if (value[0] == '.') {
auto currentDir = configCurrentPath.substr(0, configCurrentPath.find_last_of('/'));
if (value[1] == '.') {
auto parentDir = currentDir.substr(0, currentDir.find_last_of('/'));
value.replace(0, 2, parentDir);
} else {
value.replace(0, 1, currentDir);
}
}
if (value[0] == '~') {
value.replace(0, 1, std::string(ENVHOME));
}
@@ -653,6 +692,7 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
else if (COMMAND == "animation") handleAnimation(COMMAND, VALUE);
else if (COMMAND == "source") handleSource(COMMAND, VALUE);
else if (COMMAND == "submap") handleSubmap(COMMAND, VALUE);
else if (COMMAND == "blurls") handleBlurLS(COMMAND, VALUE);
else
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
@@ -665,7 +705,7 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
// Update window border colors
g_pCompositor->updateAllWindowsBorders();
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
return retval;
}
@@ -705,7 +745,7 @@ void CConfigManager::parseLine(std::string& line) {
line = line.substr(1);
}
if (line.find(" {") != std::string::npos) {
if (line.contains(" {")) {
auto cat = line.substr(0, line.find(" {"));
transform(cat.begin(), cat.end(), cat.begin(), ::tolower);
if (currentCategory.length() != 0) {
@@ -719,7 +759,7 @@ void CConfigManager::parseLine(std::string& line) {
return;
}
if (line.find("}") != std::string::npos && currentCategory != "") {
if (line.contains("}") && currentCategory != "") {
currentCategory = "";
return;
}
@@ -755,6 +795,7 @@ void CConfigManager::loadConfigLoadVars() {
m_mAdditionalReservedAreas.clear();
configDynamicVars.clear();
deviceConfigs.clear();
m_dBlurLSNamespaces.clear();
// paths
configPaths.clear();
@@ -856,7 +897,7 @@ void CConfigManager::loadConfigLoadVars() {
}
// Update window border colors
g_pCompositor->updateAllWindowsBorders();
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
// Force the compositor to fully re-render all monitors
for (auto& m : g_pCompositor->m_vMonitors)
@@ -1086,3 +1127,12 @@ bool CConfigManager::deviceConfigExists(const std::string& dev) {
return it != deviceConfigs.end();
}
bool CConfigManager::shouldBlurLS(const std::string& ns) {
for (auto& bls : m_dBlurLSNamespaces) {
if (bls == ns) {
return true;
}
}
return false;
}

View File

@@ -65,6 +65,7 @@ public:
float getDeviceFloat(const std::string&, const std::string&);
std::string getDeviceString(const std::string&, const std::string&);
bool deviceConfigExists(const std::string&);
bool shouldBlurLS(const std::string&);
SConfigValue* getConfigValuePtr(std::string);
@@ -102,6 +103,7 @@ private:
std::deque<SMonitorRule> m_dMonitorRules;
std::deque<SWindowRule> m_dWindowRules;
std::deque<std::string> m_dBlurLSNamespaces;
bool firstExecDispatched = false;
std::deque<std::string> firstExecRequests;
@@ -127,6 +129,7 @@ private:
void handleAnimation(const std::string&, const std::string&);
void handleSource(const std::string&, const std::string&);
void handleSubmap(const std::string&, const std::string&);
void handleBlurLS(const std::string&, const std::string&);
};
inline std::unique_ptr<CConfigManager> g_pConfigManager;

View File

@@ -9,6 +9,12 @@ PLEASE USE THE CONFIG PROVIDED IN THE GIT REPO /examples/hypr.conf AND EDIT IT,
OR EDIT THIS ONE ACCORDING TO THE WIKI INSTRUCTIONS.
########################################################################################
#
# Please note not all available settings / options are set here.
# For a full list, see the wiki (basic and advanced configuring)
#
autogenerated=1 # remove this line to get rid of the warning on top.
monitor=,1920x1080@60,0x0,1

View File

@@ -16,8 +16,8 @@
std::string monitorsRequest() {
std::string result = "";
for (auto& m : g_pCompositor->m_vMonitors) {
result += getFormat("Monitor %s (ID %i):\n\t%ix%i@%f at %ix%i\n\tactive workspace: %i (%s)\n\treserved: %i %i %i %i\n\tscale: %.2f\n\ttransform: %i\n\n",
m->szName.c_str(), m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->activeWorkspace, g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName.c_str(), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform);
result += getFormat("Monitor %s (ID %i):\n\t%ix%i@%f at %ix%i\n\tactive workspace: %i (%s)\n\treserved: %i %i %i %i\n\tscale: %.2f\n\ttransform: %i\n\tactive: %s\n\n",
m->szName.c_str(), m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->activeWorkspace, g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName.c_str(), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m.get() == g_pCompositor->m_pLastMonitor ? "yes" : "no"));
}
return result;
@@ -58,13 +58,13 @@ std::string layersRequest() {
std::string result = "";
for (auto& mon : g_pCompositor->m_vMonitors) {
result += getFormat("Monitor %s:\n");
result += getFormat("Monitor %s:\n", mon->szName.c_str());
int layerLevel = 0;
for (auto& level : mon->m_aLayerSurfaceLists) {
result += getFormat("\tLayer level %i:\n", layerLevel);
for (auto& layer : level) {
result += getFormat("\t\tLayer %x: xywh: %i %i %i %i\n", layer, layer->geometry.x, layer->geometry.y, layer->geometry.width, layer->geometry.height);
result += getFormat("\t\tLayer %x: xywh: %i %i %i %i, namespace: %s\n", layer, layer->geometry.x, layer->geometry.y, layer->geometry.width, layer->geometry.height, layer->szNamespace.c_str());
}
layerLevel++;
@@ -87,7 +87,7 @@ std::string devicesRequest() {
result += "\n\nKeyboards:\n";
for (auto& k : g_pInputManager->m_lKeyboards) {
result += getFormat("\tKeyboard at %x:\n\t\t%s\n", &k, k.keyboard->name);
result += getFormat("\tKeyboard at %x:\n\t\t%s\n\t\t\trules: r \"%s\", m \"%s\", l \"%s\", v \"%s\", o \"%s\"\n", &k, k.keyboard->name, k.currentRules.rules.c_str(), k.currentRules.model.c_str(), k.currentRules.layout.c_str(), k.currentRules.variant.c_str(), k.currentRules.options.c_str());
}
result += "\n\nTablets:\n";
@@ -158,7 +158,7 @@ std::string dispatchKeyword(std::string in) {
if (COMMAND == "monitor")
g_pConfigManager->m_bWantsMonitorReload = true; // for monitor keywords
if (COMMAND.find("input") != std::string::npos)
if (COMMAND.contains("input"))
g_pInputManager->setKeyboardLayout(); // update kb layout
Debug::log(LOG, "Hyprctl: keyword %s : %s", COMMAND.c_str(), VALUE.c_str());
@@ -181,6 +181,10 @@ std::string killRequest() {
return "ok";
}
std::string splashRequest() {
return g_pCompositor->m_szCurrentSplash;
}
std::string getReply(std::string);
std::string dispatchBatch(std::string request) {
@@ -234,6 +238,8 @@ std::string getReply(std::string request) {
return reloadRequest();
else if (request == "devices")
return devicesRequest();
else if (request == "splash")
return splashRequest();
else if (request.find("dispatch") == 0)
return dispatchRequest(request);
else if (request.find("keyword") == 0)
@@ -265,12 +271,14 @@ void HyprCtl::tickHyprCtl() {
std::string getRequestFromThread(std::string rq) {
// we need to do something to wake hyprland up if VFR is enabled
static auto *const VFRENABLED = &g_pConfigManager->getConfigValuePtr("experimental:vfr")->intValue;
if (*VFRENABLED) {
// TODO: is this safe...?
// this might be a race condition
static auto *const PNOVFR = &g_pConfigManager->getConfigValuePtr("misc:no_vfr")->intValue;
// TODO: is this safe...?
// this might be a race condition
// tested with 2 instances of `watch -n 0.1 hyprctl splash` and seems to not crash so I'll take that as a yes
if (!*PNOVFR)
wlr_output_schedule_frame(g_pCompositor->m_vMonitors.front()->output);
}
while (HyprCtl::request != "" || HyprCtl::requestMade || HyprCtl::requestReady) {
std::this_thread::sleep_for(std::chrono::milliseconds(5));

View File

@@ -16,8 +16,6 @@
#define ISDEBUG false
#endif
#define RIP(format, ... ) { fprintf(stderr, format "\n", ##__VA_ARGS__); exit(EXIT_FAILURE); }
#define LISTENER(name) void listener_##name(wl_listener*, void*); inline wl_listener listen_##name = { .notify = listener_##name };
#define DYNLISTENFUNC(name) void listener_##name(void*, void*);
#define DYNLISTENER(name) CHyprWLListener hyprListener_##name;

View File

@@ -151,11 +151,29 @@ void Events::listener_newVirtPtr(wl_listener* listener, void* data) {
const auto POINTER = EV->new_pointer;
const auto DEVICE = &POINTER->pointer.base;
g_pInputManager->newMouse(DEVICE);
g_pInputManager->newMouse(DEVICE, true);
}
void Events::listener_destroyMouse(void* owner, void* data) {
const auto PMOUSE = (SMouse*)owner;
g_pInputManager->destroyMouse(PMOUSE->mouse);
}
}
void Events::listener_swipeBegin(wl_listener* listener, void* data) {
const auto EVENT = (wlr_pointer_swipe_begin_event*)data;
g_pInputManager->onSwipeBegin(EVENT);
}
void Events::listener_swipeUpdate(wl_listener* listener, void* data) {
const auto EVENT = (wlr_pointer_swipe_update_event*)data;
g_pInputManager->onSwipeUpdate(EVENT);
}
void Events::listener_swipeEnd(wl_listener* listener, void* data) {
const auto EVENT = (wlr_pointer_swipe_end_event*)data;
g_pInputManager->onSwipeEnd(EVENT);
}

View File

@@ -49,6 +49,7 @@ namespace Events {
DYNLISTENFUNC(fullscreenWindow);
DYNLISTENFUNC(activateX11);
DYNLISTENFUNC(configureX11);
DYNLISTENFUNC(unmanagedSetGeometry);
// Window subsurfaces
// LISTENER(newSubsurfaceWindow);
@@ -112,4 +113,10 @@ namespace Events {
// Renderer destroy
LISTENER(RendererDestroy);
LISTENER(newIdleInhibitor);
LISTENER(swipeBegin);
LISTENER(swipeEnd);
LISTENER(swipeUpdate);
};

View File

@@ -32,8 +32,9 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
}
const auto PMONITOR = (SMonitor*)g_pCompositor->getMonitorFromOutput(WLRLAYERSURFACE->output);
PMONITOR->m_aLayerSurfaceLists[WLRLAYERSURFACE->pending.layer].push_back(new SLayerSurface());
SLayerSurface* layerSurface = PMONITOR->m_aLayerSurfaceLists[WLRLAYERSURFACE->pending.layer].back();
SLayerSurface* layerSurface = PMONITOR->m_aLayerSurfaceLists[WLRLAYERSURFACE->pending.layer].emplace_back(new SLayerSurface());
layerSurface->szNamespace = WLRLAYERSURFACE->_namespace;
if (!WLRLAYERSURFACE->output) {
WLRLAYERSURFACE->output = g_pCompositor->m_vMonitors.front()->output; // TODO: current mon
@@ -50,6 +51,8 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
WLRLAYERSURFACE->data = layerSurface;
layerSurface->monitorID = PMONITOR->ID;
layerSurface->forceBlur = g_pConfigManager->shouldBlurLS(layerSurface->szNamespace);
Debug::log(LOG, "LayerSurface %x (namespace %s layer %d) created on monitor %s", layerSurface->layerSurface, layerSurface->layerSurface->_namespace, layerSurface->layer, PMONITOR->szName.c_str());
}
@@ -115,9 +118,14 @@ void Events::listener_mapLayerSurface(void* owner, void* data) {
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
if (layersurface->layerSurface->current.keyboard_interactive)
if (layersurface->layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint)) // don't focus if constrained
g_pCompositor->focusSurface(layersurface->layerSurface->surface);
// mouse enter always, keeb only when needed
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y);
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, layersurface->layerSurface->surface, LOCAL.x, LOCAL.y);
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y);
layersurface->position = Vector2D(layersurface->geometry.x, layersurface->geometry.y);
wlr_box geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height};
@@ -150,14 +158,17 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
if (layersurface->layerSurface->mapped)
layersurface->layerSurface->mapped = false;
if (layersurface->layerSurface->surface == g_pCompositor->m_pLastFocus)
g_pCompositor->m_pLastFocus = nullptr;
const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layersurface->layerSurface->output);
if (!PMONITOR)
return;
// refocus if needed
if (layersurface->layerSurface->surface == g_pCompositor->m_pLastFocus) {
g_pCompositor->m_pLastFocus = nullptr;
g_pInputManager->refocus();
}
wlr_box geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height};
g_pHyprRenderer->damageBox(&geomFixed);
@@ -206,5 +217,8 @@ void Events::listener_commitLayerSurface(void* owner, void* data) {
layersurface->position = Vector2D(layersurface->geometry.x, layersurface->geometry.y);
// update geom if it changed
layersurface->geometry = {layersurface->geometry.x, layersurface->geometry.y, layersurface->layerSurface->surface->current.width, layersurface->layerSurface->surface->current.height};
g_pHyprRenderer->damageSurface(layersurface->layerSurface->surface, layersurface->position.x, layersurface->position.y);
}

View File

@@ -149,10 +149,10 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
g_pCompositor->deactivateAllWLRWorkspaces(PNEWWORKSPACE->m_pWlrHandle);
PNEWWORKSPACE->setActive(true);
//
if (!pMostHzMonitor || monitorRule.refreshRate > pMostHzMonitor->refreshRate)
pMostHzMonitor = PNEWMONITOR;
//
if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet
g_pCompositor->m_pLastMonitor = PNEWMONITOR;
@@ -173,7 +173,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
static auto *const PDEBUGOVERLAY = &g_pConfigManager->getConfigValuePtr("debug:overlay")->intValue;
static auto *const PDAMAGETRACKINGMODE = &g_pConfigManager->getConfigValuePtr("general:damage_tracking_internal")->intValue;
static auto *const PDAMAGEBLINK = &g_pConfigManager->getConfigValuePtr("debug:damage_blink")->intValue;
static auto *const VFRENABLED = &g_pConfigManager->getConfigValuePtr("experimental:vfr")->intValue;
static auto *const PNOVFR = &g_pConfigManager->getConfigValuePtr("misc:no_vfr")->intValue;
static int damageBlinkCleanup = 0; // because double-buffered
@@ -182,22 +182,22 @@ void Events::listener_monitorFrame(void* owner, void* data) {
g_pDebugOverlay->frameData(PMONITOR);
}
// Hack: only check when monitor with top hz refreshes, saves a bit of resources.
// This is for stuff that should be run every frame
if (PMONITOR->ID == pMostHzMonitor->ID || *VFRENABLED) { // unfortunately with VFR we don't have the guarantee mostHz is going to be updated all the time, so we have to ignore that
// checks //
if (PMONITOR->ID == pMostHzMonitor->ID || !*PNOVFR) { // unfortunately with VFR we don't have the guarantee mostHz is going to be updated all the time, so we have to ignore that
g_pCompositor->sanityCheckWorkspaces();
g_pAnimationManager->tick();
g_pCompositor->cleanupFadingOut();
HyprCtl::tickHyprCtl(); // so that we dont get that race condition multithread bullshit
HyprCtl::tickHyprCtl(); // so that we dont get that race condition multithread bullshit
g_pConfigManager->dispatchExecOnce(); // We exec-once when at least one monitor starts refreshing, meaning stuff has init'd
g_pConfigManager->dispatchExecOnce(); // We exec-once when at least one monitor starts refreshing, meaning stuff has init'd
if (g_pConfigManager->m_bWantsMonitorReload)
g_pConfigManager->performMonitorReload();
g_pHyprRenderer->ensureCursorRenderingMode(); // so that the cursor gets hidden/shown if the user requested timeouts
g_pHyprRenderer->ensureCursorRenderingMode(); // so that the cursor gets hidden/shown if the user requested timeouts
}
// //
if (PMONITOR->framesToSkip > 0) {
PMONITOR->framesToSkip -= 1;
@@ -233,7 +233,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
pixman_region32_fini(&damage);
wlr_output_rollback(PMONITOR->output);
if (!*VFRENABLED)
if (*PDAMAGEBLINK || *PNOVFR)
wlr_output_schedule_frame(PMONITOR->output);
return;
@@ -270,7 +270,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
// potentially can save on resources.
g_pHyprOpenGL->begin(PMONITOR, &damage);
g_pHyprOpenGL->clear(CColor(100, 11, 11, 255));
g_pHyprOpenGL->clear(CColor(17, 17, 17, 255));
g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper"
g_pHyprRenderer->renderAllClientsForMonitor(PMONITOR->ID, &now);
@@ -323,7 +323,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
wlr_output_commit(PMONITOR->output);
if (!*VFRENABLED)
if (*PDAMAGEBLINK || *PNOVFR)
wlr_output_schedule_frame(PMONITOR->output);
if (*PDEBUGOVERLAY == 1) {
@@ -391,7 +391,6 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
g_pCompositor->m_vMonitors.erase(std::remove_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](std::unique_ptr<SMonitor>& el) { return el.get() == pMonitor; }));
// update the pMostHzMonitor
if (pMostHzMonitor == pMonitor) {
int mostHz = 0;
SMonitor* pMonitorMostHz = nullptr;

View File

@@ -92,6 +92,9 @@ void Events::listener_newPopupXDG(void* owner, void* data) {
ASSERT(PWINDOW);
if (!PWINDOW->m_bIsMapped)
return;
Debug::log(LOG, "New layer popup created from XDG window %x -> %s", PWINDOW, PWINDOW->m_szTitle.c_str());
const auto WLRPOPUP = (wlr_xdg_popup*)data;

View File

@@ -32,6 +32,9 @@ void addViewCoords(void* pWindow, int* x, int* y) {
void Events::listener_mapWindow(void* owner, void* data) {
CWindow* PWINDOW = (CWindow*)owner;
static auto *const PINACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:inactive_opacity")->floatValue;
static auto *const PACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:active_opacity")->floatValue;
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
const auto PWORKSPACE = PMONITOR->specialWorkspaceOpen ? g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
PWINDOW->m_iMonitorID = PMONITOR->ID;
@@ -122,13 +125,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
requestedWorkspace = WORKSPACERQ;
}
if (requestedWorkspace == "special") {
requestedWorkspace = "";
workspaceSilent = false;
Debug::log(LOG, "windowrule=workspace special is not allowed!");
continue;
}
Debug::log(LOG, "Rule workspace matched by window %x, %s applied.", PWINDOW, r.szValue.c_str());
} else if (r.szRule.find("float") == 0) {
PWINDOW->m_bIsFloating = true;
@@ -152,7 +148,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
try {
std::string alphaPart = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
if (alphaPart.find_first_of(' ') != std::string::npos) {
if (alphaPart.contains(' ')) {
// we have a comma, 2 values
PWINDOW->m_sSpecialRenderData.alpha = std::stof(alphaPart.substr(0, alphaPart.find_first_of(' ')));
PWINDOW->m_sSpecialRenderData.alphaInactive = std::stof(alphaPart.substr(alphaPart.find_first_of(' ') + 1));
@@ -170,13 +166,17 @@ void Events::listener_mapWindow(void* owner, void* data) {
if (requestedWorkspace != "") {
// process requested workspace
if (requestedWorkspace.find_first_of(' ') != std::string::npos) {
if (requestedWorkspace.contains(' ')) {
// check for silent
if (requestedWorkspace.find("silent") != std::string::npos) {
if (requestedWorkspace.contains("silent")) {
workspaceSilent = true;
}
requestedWorkspace = requestedWorkspace.substr(0, requestedWorkspace.find_first_of(' '));
if (requestedWorkspace == "special") {
workspaceSilent = true;
}
}
if (!workspaceSilent) {
@@ -199,8 +199,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(" "));
const auto SIZEYSTR = VALUE.substr(VALUE.find(" ") + 1);
const auto SIZEX = SIZEXSTR.find('%') == std::string::npos ? std::stoi(SIZEXSTR) : std::stoi(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
const auto SIZEY = SIZEYSTR.find('%') == std::string::npos ? std::stoi(SIZEYSTR) : std::stoi(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
const auto SIZEX = !SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stoi(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
const auto SIZEY = !SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stoi(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
Debug::log(LOG, "Rule size, applying to window %x", PWINDOW);
@@ -215,8 +215,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
const auto POSXSTR = VALUE.substr(0, VALUE.find(" "));
const auto POSYSTR = VALUE.substr(VALUE.find(" ") + 1);
const auto POSX = POSXSTR.find('%') == std::string::npos ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
const auto POSY = POSYSTR.find('%') == std::string::npos ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
const auto POSX = !POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
const auto POSY = !POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
Debug::log(LOG, "Rule move, applying to window %x", PWINDOW);
@@ -238,8 +238,11 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv() - Vector2D(10,10);
}
if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus)
if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus && PWINDOW->m_iX11Type != 2) {
g_pCompositor->focusWindow(PWINDOW);
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA);
} else
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PINACTIVEALPHA);
Debug::log(LOG, "Window got assigned a surfaceTreeNode %x", PWINDOW->m_pSurfaceTree);
@@ -253,6 +256,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->hyprListener_activateX11.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_activate, &Events::listener_activateX11, PWINDOW, "XWayland Window Late");
PWINDOW->hyprListener_configureX11.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_configure, &Events::listener_configureX11, PWINDOW, "XWayland Window Late");
PWINDOW->hyprListener_setTitleWindow.initCallback(&PWINDOW->m_uSurface.xwayland->events.set_title, &Events::listener_setTitleWindow, PWINDOW, "XWayland Window Late");
if (PWINDOW->m_iX11Type == 2)
PWINDOW->hyprListener_setGeometryX11U.initCallback(&PWINDOW->m_uSurface.xwayland->events.set_geometry, &Events::listener_unmanagedSetGeometry, PWINDOW, "XWayland Window Late");
}
// do the animation thing
@@ -284,6 +290,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
g_pCompositor->setWindowFullscreen(PWINDOW, true, FULLSCREEN_FULL);
}
// recheck idle inhibitors
g_pInputManager->recheckIdleInhibitorStatus();
PWINDOW->m_pSurfaceTree = SubsurfaceTree::createTreeRoot(g_pXWaylandManager->getWindowSurface(PWINDOW), addViewCoords, PWINDOW, PWINDOW);
Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, PWINDOW->m_vRealSize.goalv().x, PWINDOW->m_vRealSize.goalv().y);
@@ -306,6 +315,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
PWINDOW->hyprListener_activateX11.removeCallback();
PWINDOW->hyprListener_configureX11.removeCallback();
PWINDOW->hyprListener_setTitleWindow.removeCallback();
PWINDOW->hyprListener_setGeometryX11U.removeCallback();
}
if (PWINDOW->m_bIsFullscreen) {
@@ -363,12 +373,15 @@ void Events::listener_unmapWindow(void* owner, void* data) {
// Destroy Foreign Toplevel
wlr_foreign_toplevel_handle_v1_destroy(PWINDOW->m_phForeignToplevel);
PWINDOW->m_phForeignToplevel = nullptr;
// recheck idle inhibitors
g_pInputManager->recheckIdleInhibitorStatus();
}
void Events::listener_commitWindow(void* owner, void* data) {
CWindow* PWINDOW = (CWindow*)owner;
if (!g_pCompositor->windowValidMapped(PWINDOW))
if (!PWINDOW->m_bMappedX11 || PWINDOW->m_bHidden || (PWINDOW->m_bIsX11 && !PWINDOW->m_bMappedX11))
return;
g_pHyprRenderer->damageSurface(g_pXWaylandManager->getWindowSurface(PWINDOW), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y);
@@ -487,6 +500,29 @@ void Events::listener_configureX11(void* owner, void* data) {
g_pHyprRenderer->damageWindow(PWINDOW);
}
void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
CWindow* PWINDOW = (CWindow*)owner;
if (!PWINDOW->m_bMappedX11 || PWINDOW->m_bHidden)
return;
const auto POS = PWINDOW->m_vRealPosition.goalv();
const auto SIZ = PWINDOW->m_vRealSize.goalv();
if (abs(floor(POS.x) - PWINDOW->m_uSurface.xwayland->x) > 2 || abs(floor(POS.y) - PWINDOW->m_uSurface.xwayland->y) > 2 || abs(floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2) {
g_pHyprRenderer->damageWindow(PWINDOW);
PWINDOW->m_vRealPosition.setValueAndWarp(Vector2D(PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y));
if (abs(floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2)
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(PWINDOW->m_uSurface.xwayland->width, PWINDOW->m_uSurface.xwayland->height));
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.vec());
g_pCompositor->moveWindowToTop(PWINDOW);
PWINDOW->updateWindowDecos();
g_pHyprRenderer->damageWindow(PWINDOW);
}
}
void Events::listener_surfaceXWayland(wl_listener* listener, void* data) {
const auto XWSURFACE = (wlr_xwayland_surface*)data;

View File

@@ -128,10 +128,10 @@ public:
case AVARTYPE_COLOR:
return m_cValue != m_cGoal;
default:
return false;
std::unreachable();
}
return false; // unreachable
std::unreachable();
}
void warp() {
@@ -149,7 +149,7 @@ public:
break;
}
default:
break;
std::unreachable();
}
}

View File

@@ -137,7 +137,7 @@ float getPlusMinusKeywordResult(std::string source, float relative) {
if (source.find_first_of("+") == 0) {
try {
if (source.find('.') != std::string::npos)
if (source.contains("."))
result = relative + std::stof(source.substr(1));
else
result = relative + std::stoi(source.substr(1));
@@ -147,7 +147,7 @@ float getPlusMinusKeywordResult(std::string source, float relative) {
}
} else if (source.find_first_of("-") == 0) {
try {
if (source.find('.') != std::string::npos)
if (source.contains("."))
result = relative - std::stof(source.substr(1));
else
result = relative - std::stoi(source.substr(1));
@@ -157,7 +157,7 @@ float getPlusMinusKeywordResult(std::string source, float relative) {
}
} else {
try {
if (source.find('.') != std::string::npos)
if (source.contains("."))
result = stof(source);
else
result = stoi(source);

56
src/helpers/Splashes.hpp Normal file
View File

@@ -0,0 +1,56 @@
#pragma once
#include <array>
#include <string>
inline const std::vector<std::string> SPLASHES = {
"Woo, animations!",
"It's like Hypr, but better.",
"Release 1.0 when?",
"It's not awesome, it's Hyprland!",
"\"I commit too often, people can't catch up lmao\" - Vaxry",
"This text is random.",
"\"There are reasons to not use rust.\" - Boga",
"Read the wiki.",
"\"Hello everyone this is YOUR daily dose of read the wiki\" - Vaxry",
"h",
"\"why no work, bro I haven't hacked your pc to get live feeds yet\" - Vaxry",
"Compile, wait for 20 minutes, notice a new commit, compile again.",
"To rice, or not to rice, that is the question.",
"Now available on Fedora!",
// music reference / quote section
"J'remue le ciel, le jour, la nuit.",
"aezakmi, aezakmi, aezakmi, aezakmi, aezakmi, aezakmi, aezakmi!",
"Wir sind schon sehr lang zusammen...",
"I see a red door and I want it painted black.",
"Take on me, take me on...",
"You spin me right round baby right round",
"Stayin' alive, stayin' alive",
"Say no way, say no way ya, no way!",
"Ground control to Major Tom...",
"Alors on danse",
"And all that I can see, is just a yellow lemon tree.",
"Got a one-way ticket to the blues",
"Is this the real life, is this just fantasy",
"What's in your head, in your head?",
"We're all living in America, America, America.",
"I'm still standing, better than I ever did",
"Here comes the sun, bringing you love and shining on everyone",
"Two trailer park girls go round the outside",
"With the lights out, it's less dangerous",
"Here we go back, this is the moment, tonight is the night",
"Now you're just somebody that I used to know...",
"Black bird, black moon, black sky",
"Some legends are told, some turn to dust or to gold",
"Your brain gets smart, but your head gets dumb.",
"Save your mercy for someone who needs it more",
"You're gonna hear my voice when I shout it out loud",
"Ding ding pch n daa, bam-ba-ba-re-bam baram bom bom baba-bam-bam-bommm",
"Súbeme la radio que esta es mi canción",
"I'm beggin', beggin' you",
//
"Join the discord server!",
"Thanks ThatOneCalculator!",
"The AUR packages always work, except for the times they don't.",
"Funny animation compositor woo"
};

View File

@@ -25,10 +25,14 @@ struct SLayerSurface {
int monitorID = -1;
std::string szNamespace = "";
CAnimatedVariable alpha;
bool fadingOut = false;
bool readyToDelete = false;
bool forceBlur = false;
// For the list lookup
bool operator==(const SLayerSurface& rhs) {
return layerSurface == rhs.layerSurface && monitorID == rhs.monitorID;
@@ -60,6 +64,26 @@ struct SRenderData {
// for custom round values
int rounding = -1; // -1 means not set
// for blurring
bool blur = false;
// for windows that animate poorly
bool squishOversized = false;
};
struct SExtensionFindingData {
Vector2D origin;
Vector2D vec;
wlr_surface** found;
};
struct SStringRuleNames {
std::string layout = "";
std::string model = "";
std::string variant = "";
std::string options = "";
std::string rules = "";
};
struct SKeyboard {
@@ -73,7 +97,7 @@ struct SKeyboard {
std::string name = "";
xkb_rule_names currentRules = {0};
SStringRuleNames currentRules;
int repeatRate = 0;
int repeatDelay = 0;
int numlockOn = -1;
@@ -94,6 +118,8 @@ struct SMouse {
std::string name = "";
bool virt = false;
DYNLISTENER(commitConstraint);
DYNLISTENER(destroyMouse);
@@ -221,3 +247,25 @@ struct STabletPad {
return wlrTabletPadV2 == b.wlrTabletPadV2;
}
};
struct SIdleInhibitor {
wlr_idle_inhibitor_v1* pWlrInhibitor = nullptr;
CWindow* pWindow = nullptr;
DYNLISTENER(Destroy);
bool operator==(const SIdleInhibitor& b) {
return pWlrInhibitor == b.pWlrInhibitor;
}
};
struct SSwipeGesture {
CWorkspace* pWorkspaceBegin = nullptr;
double delta = 0;
float avgSpeed = 0;
int speedPoints = 0;
SMonitor* pMonitor = nullptr;
};

View File

@@ -28,6 +28,7 @@ public:
// for animations
CAnimatedVariable m_vRenderOffset;
CAnimatedVariable m_fAlpha;
bool m_bForceRendering = false;
// "scratchpad"
bool m_bIsSpecialWorkspace = false;

View File

@@ -14,7 +14,7 @@ void CHyprError::createQueued() {
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecSize.x, PMONITOR->vecSize.y);
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
const auto CAIRO = cairo_create(CAIROSURFACE);
@@ -27,12 +27,12 @@ void CHyprError::createQueued() {
const auto LINECOUNT = 1 + std::count(m_szQueued.begin(), m_szQueued.end(), '\n');
cairo_set_source_rgba(CAIRO, m_cQueued.r / 255.f, m_cQueued.g / 255.f, m_cQueued.b / 255.f, m_cQueued.a / 255.f);
cairo_rectangle(CAIRO, 0, 0, PMONITOR->vecSize.x, 10 * LINECOUNT);
cairo_rectangle(CAIRO, 0, 0, PMONITOR->vecPixelSize.x, 10 * LINECOUNT);
// outline
cairo_rectangle(CAIRO, 0, 0, 1, PMONITOR->vecSize.y); // left
cairo_rectangle(CAIRO, PMONITOR->vecSize.x - 1, 0, PMONITOR->vecSize.x, PMONITOR->vecSize.y); // right
cairo_rectangle(CAIRO, 0, PMONITOR->vecSize.y - 1, PMONITOR->vecSize.x, PMONITOR->vecSize.y); // bottom
cairo_rectangle(CAIRO, 0, 0, 1, PMONITOR->vecPixelSize.y); // left
cairo_rectangle(CAIRO, PMONITOR->vecPixelSize.x - 1, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y); // right
cairo_rectangle(CAIRO, 0, PMONITOR->vecPixelSize.y - 1, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y); // bottom
cairo_fill(CAIRO);
@@ -70,7 +70,7 @@ void CHyprError::createQueued() {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecSize.x, PMONITOR->vecSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
// delete cairo
cairo_destroy(CAIRO);
@@ -104,7 +104,7 @@ void CHyprError::draw() {
if (g_pHyprOpenGL->m_RenderData.pMonitor != PMONITOR)
return; // wrong mon
wlr_box windowBox = {0, 0, PMONITOR->vecSize.x, PMONITOR->vecSize.y};
wlr_box windowBox = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
g_pHyprOpenGL->renderTexture(m_tTexture, &windowBox, 255.f, 0);
}

View File

@@ -74,6 +74,7 @@ extern "C" {
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
#include <wlr/types/wlr_virtual_pointer_v1.h>
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
#include <wlr/util/log.h>
#include <wlr/xwayland.h>
#include <wlr/util/region.h>
@@ -91,6 +92,7 @@ extern "C" {
#include <wlr/types/wlr_xdg_foreign_registry.h>
#include <wlr/types/wlr_xdg_foreign_v1.h>
#include <wlr/types/wlr_xdg_foreign_v2.h>
#include <wlr/types/wlr_pointer_gestures_v1.h>
}
#undef class
@@ -118,4 +120,5 @@ extern "C" {
#include "ext-workspace-unstable-v1-protocol.h"
#include <algorithm>
#include <algorithm>
#include <utility>

View File

@@ -387,6 +387,8 @@ void CHyprDwindleLayout::recalculateMonitor(const int& monid) {
if (!PWORKSPACE)
return;
g_pHyprRenderer->damageMonitor(PMONITOR);
if (PMONITOR->specialWorkspaceOpen) {
const auto TOPNODE = getMasterNodeOnWorkspace(SPECIAL_WORKSPACE_ID);
@@ -397,9 +399,26 @@ void CHyprDwindleLayout::recalculateMonitor(const int& monid) {
}
}
// Ignore any recalc events if we have a fullscreen window.
if (PWORKSPACE->m_bHasFullscreenWindow)
// Ignore any recalc events if we have a fullscreen window, but process if fullscreen mode 2
if (PWORKSPACE->m_bHasFullscreenWindow) {
if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL)
return;
// massive hack from the fullscreen func
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
SDwindleNodeData fakeNode;
fakeNode.pWindow = PFULLWINDOW;
fakeNode.position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
fakeNode.size = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight;
fakeNode.workspaceID = PWORKSPACE->m_iID;
PFULLWINDOW->m_vPosition = fakeNode.position;
PFULLWINDOW->m_vSize = fakeNode.size;
applyNodeDataToWindow(&fakeNode);
return;
}
const auto TOPNODE = getMasterNodeOnWorkspace(PMONITOR->activeWorkspace);
@@ -522,6 +541,8 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
pWindow->m_bIsFullscreen = on;
PWORKSPACE->m_bHasFullscreenWindow = !PWORKSPACE->m_bHasFullscreenWindow;
g_pEventManager->postEvent(SHyprIPCEvent("fullscreen", std::to_string((int)on)));
if (!pWindow->m_bIsFullscreen) {
// if it got its fullscreen disabled, set back its node if it had one
const auto PNODE = getNodeFromWindow(pWindow);
@@ -571,6 +592,8 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
// we need to fix XWayland windows by sending them to NARNIA
// because otherwise they'd still be recieving mouse events
g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace);
recalculateMonitor(PMONITOR->ID);
}
void CHyprDwindleLayout::recalculateWindow(CWindow* pWindow) {
@@ -646,6 +669,8 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
PPARENT->recalcSizePosRecursive();
}
g_pInputManager->refocus();
}
std::deque<CWindow*> CHyprDwindleLayout::getGroupMembers(CWindow* pWindow) {

View File

@@ -45,7 +45,7 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
Vector2D middlePoint = Vector2D(desiredGeometry.x, desiredGeometry.y) + Vector2D(desiredGeometry.width, desiredGeometry.height) / 2.f;
// TODO: detect a popup in a more consistent way.
if (!g_pCompositor->isPointOnAnyMonitor(middlePoint) || (desiredGeometry.x == 0 && desiredGeometry.y == 0)) {
if ((desiredGeometry.x == 0 && desiredGeometry.y == 0)) {
// if it's not, fall back to the center placement
pWindow->m_vRealPosition = PMONITOR->vecPosition + Vector2D((PMONITOR->vecSize.x - desiredGeometry.width) / 2.f, (PMONITOR->vecSize.y - desiredGeometry.height) / 2.f);
} else {
@@ -65,10 +65,12 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
pWindow->m_vRealSize.setValue(pWindow->m_vRealSize.goalv());
}
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv());
g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace);
if (pWindow->m_iX11Type != 2) {
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv());
g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace);
g_pCompositor->moveWindowToTop(pWindow);
g_pCompositor->moveWindowToTop(pWindow);
}
}
void IHyprLayout::onBeginDragWindow() {
@@ -210,9 +212,23 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
// fix pseudo leaving artifacts
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
} else {
pWindow->m_vSize = pWindow->m_vRealSize.vec();
pWindow->m_vPosition = pWindow->m_vRealPosition.vec();
onWindowRemovedTiling(pWindow);
g_pCompositor->moveWindowToTop(pWindow);
const auto POS = pWindow->m_vRealPosition.goalv();
const auto SIZ = pWindow->m_vRealSize.goalv();
pWindow->m_vRealPosition.setValueAndWarp(POS + Vector2D(5, 5));
pWindow->m_vRealSize.setValueAndWarp(SIZ - Vector2D(10, 10));
pWindow->m_vRealPosition = POS;
pWindow->m_vRealSize = SIZ;
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
}
}

View File

@@ -12,7 +12,7 @@ bool ignoreSudo = false;
int main(int argc, char** argv) {
if (!getenv("XDG_RUNTIME_DIR"))
RIP("XDG_RUNTIME_DIR not set!");
throw std::runtime_error("XDG_RUNTIME_DIR is not set!");
// parse some args
for (int i = 1; i < argc; ++i) {

View File

@@ -191,7 +191,7 @@ void CAnimationManager::tick() {
// set size and pos if valid, but only if damage policy entire (dont if border for example)
if (g_pCompositor->windowValidMapped(PWINDOW) && av->m_eDamagePolicy == AVARDAMAGE_ENTIRE)
if (g_pCompositor->windowValidMapped(PWINDOW) && av->m_eDamagePolicy == AVARDAMAGE_ENTIRE && PWINDOW->m_iX11Type != 2)
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
// manually schedule a frame
@@ -309,7 +309,7 @@ void CAnimationManager::onWindowPostCreateClose(CWindow* pWindow, bool close) {
if (pWindow->m_sAdditionalConfigData.animationStyle != "") {
// the window has config'd special anim
if (pWindow->m_sAdditionalConfigData.animationStyle.find("slide") == 0) {
if (pWindow->m_sAdditionalConfigData.animationStyle.find(' ') != std::string::npos) {
if (pWindow->m_sAdditionalConfigData.animationStyle.contains(' ')) {
// has a direction
animationSlide(pWindow, pWindow->m_sAdditionalConfigData.animationStyle.substr(pWindow->m_sAdditionalConfigData.animationStyle.find(' ') + 1), close);
} else {

View File

@@ -41,35 +41,48 @@ void CKeybindManager::addKeybind(SKeybind kb) {
void CKeybindManager::removeKeybind(uint32_t mod, const std::string& key) {
for (auto it = m_lKeybinds.begin(); it != m_lKeybinds.end(); ++it) {
if (it->modmask == mod && it->key == key) {
if (isNumber(key) && std::stoi(key) > 9) {
const auto KEYNUM = std::stoi(key);
if (it->modmask == mod && it->keycode == KEYNUM) {
it = m_lKeybinds.erase(it);
if (it == m_lKeybinds.end())
break;
}
}
else if (it->modmask == mod && it->key == key) {
it = m_lKeybinds.erase(it);
if (it == m_lKeybinds.end())
break;
}
}
}
uint32_t CKeybindManager::stringToModMask(std::string mods) {
uint32_t modMask = 0;
if (mods.find("SHIFT") != std::string::npos)
if (mods.contains("SHIFT"))
modMask |= WLR_MODIFIER_SHIFT;
if (mods.find("CAPS") != std::string::npos)
if (mods.contains("CAPS"))
modMask |= WLR_MODIFIER_CAPS;
if (mods.find("CTRL") != std::string::npos || mods.find("CONTROL") != std::string::npos)
if (mods.contains("CTRL") || mods.contains("CONTROL"))
modMask |= WLR_MODIFIER_CTRL;
if (mods.find("ALT") != std::string::npos)
if (mods.contains("ALT"))
modMask |= WLR_MODIFIER_ALT;
if (mods.find("MOD2") != std::string::npos)
if (mods.contains("MOD2"))
modMask |= WLR_MODIFIER_MOD2;
if (mods.find("MOD3") != std::string::npos)
if (mods.contains("MOD3"))
modMask |= WLR_MODIFIER_MOD3;
if (mods.find("SUPER") != std::string::npos || mods.find("WIN") != std::string::npos || mods.find("LOGO") != std::string::npos || mods.find("MOD4") != std::string::npos)
if (mods.contains("SUPER") || mods.contains("WIN") || mods.contains("LOGO") || mods.contains("MOD4"))
modMask |= WLR_MODIFIER_LOGO;
if (mods.find("MOD5") != std::string::npos)
if (mods.contains("MOD5"))
modMask |= WLR_MODIFIER_MOD5;
return modMask;
}
bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t& key) {
bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t& key, const int& keycode) {
bool found = false;
if (handleInternalKeybinds(key))
@@ -82,15 +95,24 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t
if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap)
continue;
// oMg such performance hit!!11!
// this little maneouver is gonna cost us 4µs
const auto KBKEY = xkb_keysym_from_name(k.key.c_str(), XKB_KEYSYM_CASE_INSENSITIVE);
const auto KBKEYUPPER = xkb_keysym_to_upper(KBKEY);
// small TODO: fix 0-9 keys and other modified ones with shift
if (key != KBKEY && key != KBKEYUPPER)
continue;
if (k.keycode != -1) {
if (keycode != k.keycode)
continue;
} else {
if (key == 0)
continue; // this is a keycode check run
// oMg such performance hit!!11!
// this little maneouver is gonna cost us 4µs
const auto KBKEY = xkb_keysym_from_name(k.key.c_str(), XKB_KEYSYM_CASE_INSENSITIVE);
const auto KBKEYUPPER = xkb_keysym_to_upper(KBKEY);
// small TODO: fix 0-9 keys and other modified ones with shift
if (key != KBKEY && key != KBKEYUPPER)
continue;
}
const auto DISPATCHER = m_mDispatchers.find(k.handler);
@@ -99,7 +121,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t
Debug::log(ERR, "Inavlid handler in a keybind! (handler %s does not exist)", k.handler.c_str());
} else {
// call the dispatcher
Debug::log(LOG, "Keybind triggered, calling dispatcher (%d, %d)", modmask, KBKEYUPPER);
Debug::log(LOG, "Keybind triggered, calling dispatcher (%d, %d)", modmask, key);
DISPATCHER->second(k.arg);
}
@@ -231,9 +253,6 @@ void CKeybindManager::toggleActiveFloating(std::string args) {
moveActiveToWorkspace(std::to_string(g_pCompositor->getMonitorFromID(ACTIVEWINDOW->m_iMonitorID)->activeWorkspace));
}
ACTIVEWINDOW->m_vRealPosition.setValue(ACTIVEWINDOW->m_vRealPosition.vec() + Vector2D(5, 5));
ACTIVEWINDOW->m_vSize = ACTIVEWINDOW->m_vRealPosition.vec() - Vector2D(10, 10);
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(ACTIVEWINDOW);
}
}
@@ -253,7 +272,14 @@ void CKeybindManager::changeworkspace(std::string args) {
int workspaceToChangeTo = 0;
std::string workspaceName = "";
workspaceToChangeTo = getWorkspaceIDFromString(args, workspaceName);
if (args.find("[internal]") == 0) {
workspaceToChangeTo = std::stoi(args.substr(10));
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceToChangeTo);
if (PWORKSPACE)
workspaceName = PWORKSPACE->m_szName;
} else {
workspaceToChangeTo = getWorkspaceIDFromString(args, workspaceName);
}
if (workspaceToChangeTo == INT_MAX) {
Debug::log(ERR, "Error in changeworkspace, invalid value");
@@ -277,8 +303,6 @@ void CKeybindManager::changeworkspace(std::string args) {
const auto OLDWORKSPACEID = PMONITOR->activeWorkspace;
// change it
PMONITOR->specialWorkspaceOpen = false;
if (workspaceToChangeTo != SPECIAL_WORKSPACE_ID)
PMONITOR->activeWorkspace = workspaceToChangeTo;
else
@@ -451,7 +475,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
// undo the damage if we are moving to the special workspace
if (WORKSPACEID == SPECIAL_WORKSPACE_ID) {
changeworkspace(std::to_string(OLDWORKSPACE->m_iID));
changeworkspace("[internal]" + std::to_string(OLDWORKSPACE->m_iID));
OLDWORKSPACE->startAnim(true, true, true);
toggleSpecialWorkspace("");
g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID)->startAnim(false, false, true);
@@ -503,8 +527,8 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceToMoveTo);
changeworkspace(std::to_string(OLDWORKSPACEIDONMONITOR));
changeworkspace(std::to_string(OLDWORKSPACEIDRETURN));
changeworkspace("[internal]" + std::to_string(OLDWORKSPACEIDONMONITOR));
changeworkspace("[internal]" + std::to_string(OLDWORKSPACEIDRETURN));
// revert animations
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0,0));
@@ -663,7 +687,7 @@ void CKeybindManager::focusMonitor(std::string arg) {
}
if (monID > -1 && monID < (int)g_pCompositor->m_vMonitors.size()) {
changeworkspace(std::to_string(g_pCompositor->getMonitorFromID(monID)->activeWorkspace));
changeworkspace("[internal]" + std::to_string(g_pCompositor->getMonitorFromID(monID)->activeWorkspace));
} else {
Debug::log(ERR, "Error in focusMonitor: invalid arg 1");
}
@@ -683,7 +707,7 @@ void CKeybindManager::focusMonitor(std::string arg) {
} else {
for (auto& m : g_pCompositor->m_vMonitors) {
if (m->szName == arg) {
changeworkspace(std::to_string(m->activeWorkspace));
changeworkspace("[internal]" + std::to_string(m->activeWorkspace));
return;
}
}
@@ -816,7 +840,7 @@ void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
}
void CKeybindManager::moveWorkspaceToMonitor(std::string args) {
if (args.find_first_of(' ') == std::string::npos)
if (!args.contains(' '))
return;
std::string workspace = args.substr(0, args.find_first_of(' '));
@@ -891,7 +915,12 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
}
} else {
auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID);
if (!PSPECIALWORKSPACE) {
// ??? happens sometimes...?
PSPECIALWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(g_pCompositor->m_pLastMonitor->ID, "special", true)).get();
}
g_pCompositor->m_pLastMonitor->specialWorkspaceOpen = true;
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID);
@@ -918,7 +947,7 @@ void CKeybindManager::forceRendererReload(std::string args) {
}
void CKeybindManager::resizeActive(std::string args) {
if (args.find_first_of(' ') == std::string::npos)
if (!args.contains(' '))
return;
std::string x = args.substr(0, args.find_first_of(' '));
@@ -967,7 +996,7 @@ void CKeybindManager::resizeActive(std::string args) {
}
void CKeybindManager::moveActive(std::string args) {
if (args.find_first_of(' ') == std::string::npos)
if (!args.contains(' '))
return;
std::string x = args.substr(0, args.find_first_of(' '));
@@ -1015,11 +1044,14 @@ void CKeybindManager::moveActive(std::string args) {
g_pLayoutManager->getCurrentLayout()->moveActiveWindow(Vector2D(X, Y));
}
void CKeybindManager::circleNext(std::string) {
void CKeybindManager::circleNext(std::string arg) {
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
return;
g_pCompositor->focusWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow));
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
g_pCompositor->focusWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow));
else
g_pCompositor->focusWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow));
const auto MIDPOINT = g_pCompositor->m_pLastWindow->m_vRealPosition.goalv() + g_pCompositor->m_pLastWindow->m_vRealSize.goalv() / 2.f;
@@ -1051,7 +1083,7 @@ void CKeybindManager::focusWindow(std::string regexp) {
Debug::log(LOG, "Focusing to window name: %s", w->m_szTitle.c_str());
changeworkspace(std::to_string(w->m_iWorkspaceID));
changeworkspace("[internal]" + std::to_string(w->m_iWorkspaceID));
g_pCompositor->focusWindow(w.get());

View File

@@ -7,7 +7,8 @@
#include <functional>
struct SKeybind {
std::string key = 0;
std::string key = "";
int keycode = -1;
uint32_t modmask = 0;
std::string handler = "";
std::string arg = "";
@@ -19,7 +20,7 @@ class CKeybindManager {
public:
CKeybindManager();
bool handleKeybinds(const uint32_t&, const xkb_keysym_t&);
bool handleKeybinds(const uint32_t&, const xkb_keysym_t&, const int&);
void addKeybind(SKeybind);
void removeKeybind(uint32_t, const std::string&);
uint32_t stringToModMask(std::string);

View File

@@ -36,7 +36,9 @@ void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate)
wlr_xdg_toplevel_set_activated(wlr_xdg_surface_from_wlr_surface(pSurface)->toplevel, activate);
else if (wlr_surface_is_xwayland_surface(pSurface)) {
wlr_xwayland_surface_activate(wlr_xwayland_surface_from_wlr_surface(pSurface), activate);
wlr_xwayland_surface_restack(wlr_xwayland_surface_from_wlr_surface(pSurface), NULL, XCB_STACK_MODE_ABOVE);
if (activate)
wlr_xwayland_surface_restack(wlr_xwayland_surface_from_wlr_surface(pSurface), NULL, XCB_STACK_MODE_ABOVE);
}
}
@@ -153,7 +155,7 @@ bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) {
if (pWindow->m_uSurface.xwayland->role) {
try {
std::string winrole = std::string(pWindow->m_uSurface.xwayland->role);
if (winrole.find("pop-up") != std::string::npos || winrole.find("task_dialog") != std::string::npos) {
if (winrole.contains("pop-up") || winrole.contains("task_dialog")) {
return true;
}
} catch (std::exception& e) {
@@ -221,6 +223,4 @@ void CHyprXWaylandManager::setWindowFullscreen(CWindow* pWindow, bool fullscreen
if (pWindow->m_phForeignToplevel)
wlr_foreign_toplevel_handle_v1_set_fullscreen(pWindow->m_phForeignToplevel, fullscreen);
g_pEventManager->postEvent(SHyprIPCEvent("fullscreen", std::to_string((int)fullscreen)));
}

View File

@@ -0,0 +1,54 @@
#include "InputManager.hpp"
#include "../../Compositor.hpp"
void Events::listener_newIdleInhibitor(wl_listener* listener, void* data) {
const auto WLRIDLEINHIBITOR = (wlr_idle_inhibitor_v1*)data;
if (!WLRIDLEINHIBITOR)
return;
g_pInputManager->newIdleInhibitor(WLRIDLEINHIBITOR);
}
void CInputManager::newIdleInhibitor(wlr_idle_inhibitor_v1* pInhibitor) {
const auto PINHIBIT = &m_lIdleInhibitors.emplace_back();
Debug::log(LOG, "New idle inhibitor registered");
PINHIBIT->pWlrInhibitor = pInhibitor;
PINHIBIT->hyprListener_Destroy.initCallback(&pInhibitor->events.destroy, [](void* owner, void* data){
const auto PINH = (SIdleInhibitor*)owner;
g_pInputManager->m_lIdleInhibitors.remove(*PINH);
Debug::log(LOG, "Destroyed an idleinhibitor");
g_pInputManager->recheckIdleInhibitorStatus();
}, PINHIBIT, "IdleInhibitor");
PINHIBIT->pWindow = g_pCompositor->getWindowFromSurface(pInhibitor->surface);
if (PINHIBIT->pWindow)
Debug::log(LOG, "IdleInhibitor got window %x (%s)", PINHIBIT->pWindow, PINHIBIT->pWindow->m_szTitle.c_str());
recheckIdleInhibitorStatus();
}
void CInputManager::recheckIdleInhibitorStatus() {
for (auto& ii : m_lIdleInhibitors) {
if (!ii.pWindow) {
wlr_idle_set_enabled(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat, false);
return;
} else if (g_pHyprRenderer->shouldRenderWindow(ii.pWindow)) {
wlr_idle_set_enabled(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat, false);
return;
}
}
wlr_idle_set_enabled(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat, true);
return;
}

View File

@@ -28,6 +28,8 @@ void CInputManager::onMouseWarp(wlr_pointer_motion_absolute_event* e) {
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
if (!g_pCompositor->m_bReadyToProcess)
return;
@@ -36,6 +38,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
return;
}
if (g_pCompositor->m_sSeat.mouse->virt)
return; // don't refocus on virt
Vector2D mouseCoords = getMouseCoordsInternal();
const auto MOUSECOORDSFLOORED = mouseCoords.floor();
@@ -139,6 +144,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (!pFoundWindow->m_bIsX11) {
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
surfacePos = Vector2D(-1337, -1337);
} else {
foundSurface = g_pXWaylandManager->getWindowSurface(pFoundWindow);
surfacePos = pFoundWindow->m_vRealPosition.vec();
@@ -154,9 +160,18 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
// then windows
if (!foundSurface) {
if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED)
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
else
if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) {
if (PMONITOR->specialWorkspaceOpen) {
pFoundWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords);
if (pFoundWindow && pFoundWindow->m_iWorkspaceID != SPECIAL_WORKSPACE_ID) {
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
}
} else {
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
}
} else
pFoundWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords);
if (pFoundWindow) {
@@ -184,6 +199,12 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
wlr_seat_pointer_clear_focus(g_pCompositor->m_sSeat.seat);
if (refocus) { // if we are forcing a refocus, and we don't find a surface, clear the kb focus too!
g_pCompositor->focusSurface(nullptr);
g_pCompositor->m_pLastWindow = nullptr;
}
return;
}
@@ -201,7 +222,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
}
if (pFoundWindow) {
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
if (*PFOLLOWMOUSE != 1 && !refocus) {
if (pFoundWindow != g_pCompositor->m_pLastWindow && g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && (g_pCompositor->m_pLastWindow->m_bIsFloating != pFoundWindow->m_bIsFloating)) {
// enter if change floating style
@@ -367,8 +387,8 @@ void CInputManager::newKeyboard(wlr_input_device* keyboard) {
Debug::log(ERR, "Keyboard had no name???"); // logic error
}
PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&keyboard->keyboard->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "Keyboard");
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&keyboard->keyboard->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard");
PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "Keyboard");
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard");
PNEWKEYBOARD->hyprListener_keyboardDestroy.initCallback(&keyboard->events.destroy, &Events::listener_keyboardDestroy, PNEWKEYBOARD, "Keyboard");
if (m_pActiveKeyboard)
@@ -377,7 +397,7 @@ void CInputManager::newKeyboard(wlr_input_device* keyboard) {
applyConfigToKeyboard(PNEWKEYBOARD);
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, keyboard->keyboard);
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(keyboard));
Debug::log(LOG, "New keyboard created, pointers Hypr: %x and WLR: %x", PNEWKEYBOARD, keyboard);
}
@@ -392,7 +412,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
ASSERT(pKeyboard);
if (!pKeyboard->keyboard->keyboard)
if (!wlr_keyboard_from_input_device(pKeyboard->keyboard))
return;
const auto REPEATRATE = HASCONFIG ? g_pConfigManager->getDeviceInt(pKeyboard->name, "repeat_rate") : g_pConfigManager->getInt("input:repeat_rate");
@@ -407,7 +427,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
const auto OPTIONS = HASCONFIG ? g_pConfigManager->getDeviceString(pKeyboard->name, "kb_options") : g_pConfigManager->getString("input:kb_options");
try {
if (NUMLOCKON == pKeyboard->numlockOn && REPEATDELAY == pKeyboard->repeatDelay && REPEATRATE == pKeyboard->repeatRate && RULES != "" && RULES == std::string(pKeyboard->currentRules.rules) && MODEL == std::string(pKeyboard->currentRules.model) && LAYOUT == std::string(pKeyboard->currentRules.layout) && VARIANT == std::string(pKeyboard->currentRules.variant) && OPTIONS == std::string(pKeyboard->currentRules.options)) {
if (NUMLOCKON == pKeyboard->numlockOn && REPEATDELAY == pKeyboard->repeatDelay && REPEATRATE == pKeyboard->repeatRate && RULES != "" && RULES == pKeyboard->currentRules.rules && MODEL == pKeyboard->currentRules.model && LAYOUT == pKeyboard->currentRules.layout && VARIANT == pKeyboard->currentRules.variant && OPTIONS == pKeyboard->currentRules.options) {
Debug::log(LOG, "Not applying config to keyboard, it did not change.");
return;
}
@@ -416,7 +436,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
// we can ignore those and just apply
}
wlr_keyboard_set_repeat_info(pKeyboard->keyboard->keyboard, std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
wlr_keyboard_set_repeat_info(wlr_keyboard_from_input_device(pKeyboard->keyboard), std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
pKeyboard->repeatDelay = REPEATDELAY;
pKeyboard->repeatRate = REPEATRATE;
@@ -429,7 +449,11 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
.variant = VARIANT.c_str(),
.options = OPTIONS.c_str()};
pKeyboard->currentRules = rules;
pKeyboard->currentRules.rules = RULES;
pKeyboard->currentRules.model = MODEL;
pKeyboard->currentRules.variant = VARIANT;
pKeyboard->currentRules.options = OPTIONS;
pKeyboard->currentRules.layout = LAYOUT;
const auto CONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
@@ -446,12 +470,16 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
Debug::log(ERR, "Keyboard layout %s with variant %s (rules: %s, model: %s, options: %s) couldn't have been loaded.", rules.layout, rules.variant, rules.rules, rules.model, rules.options);
memset(&rules, 0, sizeof(rules));
pKeyboard->currentRules = rules;
pKeyboard->currentRules.rules = "";
pKeyboard->currentRules.model = "";
pKeyboard->currentRules.variant = "";
pKeyboard->currentRules.options = "";
pKeyboard->currentRules.layout = "";
KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
}
wlr_keyboard_set_keymap(pKeyboard->keyboard->keyboard, KEYMAP);
wlr_keyboard_set_keymap(wlr_keyboard_from_input_device(pKeyboard->keyboard), KEYMAP);
wlr_keyboard_modifiers wlrMods = {0};
@@ -464,7 +492,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
}
if (wlrMods.locked != 0) {
wlr_keyboard_notify_modifiers(pKeyboard->keyboard->keyboard, 0, 0, wlrMods.locked, 0);
wlr_keyboard_notify_modifiers(wlr_keyboard_from_input_device(pKeyboard->keyboard), 0, 0, wlrMods.locked, 0);
}
xkb_keymap_unref(KEYMAP);
@@ -473,11 +501,12 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
Debug::log(LOG, "Set the keyboard layout to %s and variant to %s for keyboard \"%s\"", rules.layout, rules.variant, pKeyboard->keyboard->name);
}
void CInputManager::newMouse(wlr_input_device* mouse) {
void CInputManager::newMouse(wlr_input_device* mouse, bool virt) {
m_lMice.emplace_back();
const auto PMOUSE = &m_lMice.back();
PMOUSE->mouse = mouse;
PMOUSE->virt = virt;
try {
PMOUSE->name = std::string(mouse->name);
} catch(std::exception& e) {
@@ -501,6 +530,11 @@ void CInputManager::newMouse(wlr_input_device* mouse) {
libinput_device_config_middle_emulation_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
}
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "drag_lock") : g_pConfigManager->getInt("input:touchpad:drag_lock")) == 0)
libinput_device_config_tap_set_drag_lock_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
else
libinput_device_config_tap_set_drag_lock_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_DRAG_LOCK_ENABLED);
if (libinput_device_config_tap_get_finger_count(LIBINPUTDEV)) // this is for tapping (like on a laptop)
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "tap-to-click") : g_pConfigManager->getInt("input:touchpad:tap-to-click")) == 1)
libinput_device_config_tap_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_TAP_ENABLED);
@@ -568,29 +602,31 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
const auto KEYCODE = e->keycode + 8; // Because to xkbcommon it's +8 from libinput
const xkb_keysym_t* keysyms;
int syms = xkb_state_key_get_syms(pKeyboard->keyboard->keyboard->xkb_state, KEYCODE, &keysyms);
int syms = xkb_state_key_get_syms(wlr_keyboard_from_input_device(pKeyboard->keyboard)->xkb_state, KEYCODE, &keysyms);
const auto MODS = wlr_keyboard_get_modifiers(pKeyboard->keyboard->keyboard);
const auto MODS = accumulateModsFromAllKBs();
wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat);
bool found = false;
if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
for (int i = 0; i < syms; ++i)
found = g_pKeybindManager->handleKeybinds(MODS, keysyms[i]) || found;
found = g_pKeybindManager->handleKeybinds(MODS, keysyms[i], 0) || found;
found = g_pKeybindManager->handleKeybinds(MODS, 0, KEYCODE) || found;
} else if (e->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
// hee hee
}
if (!found) {
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, pKeyboard->keyboard->keyboard);
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, e->time_msec, e->keycode, e->state);
}
}
void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, pKeyboard->keyboard->keyboard);
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &pKeyboard->keyboard->keyboard->modifiers);
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &wlr_keyboard_from_input_device(pKeyboard->keyboard)->modifiers);
}
void CInputManager::refocus() {
@@ -708,4 +744,15 @@ void CInputManager::updateCapabilities(wlr_input_device* pDev) {
}
wlr_seat_set_capabilities(g_pCompositor->m_sSeat.seat, m_uiCapabilities);
}
}
uint32_t CInputManager::accumulateModsFromAllKBs() {
uint32_t finalMask = 0;
for (auto& kb : m_lKeyboards) {
finalMask |= wlr_keyboard_get_modifiers(wlr_keyboard_from_input_device(kb.keyboard));
}
return finalMask;
}

View File

@@ -21,7 +21,7 @@ public:
void onKeyboardMod(void*, SKeyboard*);
void newKeyboard(wlr_input_device*);
void newMouse(wlr_input_device*);
void newMouse(wlr_input_device*, bool virt = false);
void destroyKeyboard(SKeyboard*);
void destroyMouse(wlr_input_device*);
@@ -56,9 +56,20 @@ public:
std::list<STabletTool> m_lTabletTools;
std::list<STabletPad> m_lTabletPads;
// idle inhibitors
std::list<SIdleInhibitor> m_lIdleInhibitors;
void newTabletTool(wlr_input_device*);
void newTabletPad(wlr_input_device*);
void focusTablet(STablet*, wlr_tablet_tool*, bool motion = false);
void newIdleInhibitor(wlr_idle_inhibitor_v1*);
void recheckIdleInhibitorStatus();
void onSwipeBegin(wlr_pointer_swipe_begin_event*);
void onSwipeEnd(wlr_pointer_swipe_end_event*);
void onSwipeUpdate(wlr_pointer_swipe_update_event*);
SSwipeGesture m_sActiveSwipe;
SKeyboard* m_pActiveKeyboard = nullptr;
@@ -80,6 +91,9 @@ private:
STabletTool* ensureTabletToolPresent(wlr_tablet_tool*);
void applyConfigToKeyboard(SKeyboard*);
// for shared mods
uint32_t accumulateModsFromAllKBs();
};
inline std::unique_ptr<CInputManager> g_pInputManager;

View File

@@ -0,0 +1,152 @@
#include "InputManager.hpp"
#include "../../Compositor.hpp"
void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
static auto *const PSWIPE = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe")->intValue;
if (e->fingers < 3 || *PSWIPE == 0)
return;
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
Debug::log(LOG, "Starting a swipe from %s", PWORKSPACE->m_szName.c_str());
m_sActiveSwipe.pWorkspaceBegin = PWORKSPACE;
m_sActiveSwipe.delta = 0;
m_sActiveSwipe.pMonitor = g_pCompositor->m_pLastMonitor;
m_sActiveSwipe.avgSpeed = 0;
m_sActiveSwipe.speedPoints = 0;
}
void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
if (!m_sActiveSwipe.pWorkspaceBegin)
return; // no valid swipe
static auto *const PSWIPEPERC = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_cancel_ratio")->floatValue;
static auto *const PSWIPEDIST = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_distance")->intValue;
static auto *const PSWIPEFORC = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_min_speed_to_force")->intValue;
// commit
std::string wsname = "";
auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname);
auto workspaceIDRight = getWorkspaceIDFromString("m+1", wsname);
const auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight);
const auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.vec();
if ((abs(m_sActiveSwipe.delta) < *PSWIPEDIST * *PSWIPEPERC && (*PSWIPEFORC == 0 || (*PSWIPEFORC != 0 && m_sActiveSwipe.avgSpeed < *PSWIPEFORC))) || abs(m_sActiveSwipe.delta) < 2) {
// revert
if (m_sActiveSwipe.delta < 0) {
// to left
PWORKSPACEL->m_vRenderOffset = Vector2D({-m_sActiveSwipe.pMonitor->vecSize.x, 0});
} else {
// to right
PWORKSPACER->m_vRenderOffset = Vector2D({m_sActiveSwipe.pMonitor->vecSize.x, 0});
}
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D();
} else if (m_sActiveSwipe.delta < 0) {
// switch to left
const auto RENDEROFFSET = PWORKSPACEL->m_vRenderOffset.vec();
g_pKeybindManager->m_mDispatchers["workspace"]("[internal]" + std::to_string(workspaceIDLeft));
PWORKSPACEL->m_vRenderOffset.setValue(RENDEROFFSET);
PWORKSPACEL->m_fAlpha.setValueAndWarp(255.f);
Debug::log(LOG, "Ended swipe to the left");
} else {
// switch to right
const auto RENDEROFFSET = PWORKSPACER->m_vRenderOffset.vec();
g_pKeybindManager->m_mDispatchers["workspace"]("[internal]" + std::to_string(workspaceIDRight));
PWORKSPACER->m_vRenderOffset.setValue(RENDEROFFSET);
PWORKSPACER->m_fAlpha.setValueAndWarp(255.f);
Debug::log(LOG, "Ended swipe to the right");
}
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValue(RENDEROFFSETMIDDLE);
m_sActiveSwipe.pWorkspaceBegin->m_fAlpha.setValueAndWarp(255.f);
PWORKSPACEL->m_bForceRendering = false;
PWORKSPACER->m_bForceRendering = false;
m_sActiveSwipe.pWorkspaceBegin->m_bForceRendering = false;
m_sActiveSwipe.pWorkspaceBegin = nullptr;
g_pInputManager->refocus();
}
void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
if (!m_sActiveSwipe.pWorkspaceBegin)
return;
static auto *const PSWIPEDIST = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_distance")->intValue;
static auto *const PSWIPEINVR = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_invert")->intValue;
m_sActiveSwipe.delta += *PSWIPEINVR ? -e->dx : e->dx;
m_sActiveSwipe.avgSpeed = (m_sActiveSwipe.avgSpeed * m_sActiveSwipe.speedPoints + abs(e->dx)) / (m_sActiveSwipe.speedPoints + 1);
m_sActiveSwipe.speedPoints++;
std::string wsname = "";
auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname);
auto workspaceIDRight = getWorkspaceIDFromString("m+1", wsname);
if (workspaceIDLeft == INT_MAX || workspaceIDRight == INT_MAX || workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID)
return;
m_sActiveSwipe.delta = std::clamp(m_sActiveSwipe.delta, (double)-*PSWIPEDIST, (double)*PSWIPEDIST);
if (m_sActiveSwipe.delta < 0) {
if (workspaceIDLeft > m_sActiveSwipe.pWorkspaceBegin->m_iID){
m_sActiveSwipe.delta = 0;
return;
}
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
PWORKSPACE->m_bForceRendering = true;
if (workspaceIDLeft != workspaceIDRight) {
const auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight);
PWORKSPACER->m_bForceRendering = false;
}
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x - m_sActiveSwipe.pMonitor->vecSize.x, 0));
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x, 0));
g_pCompositor->updateWorkspaceWindowDecos(workspaceIDLeft);
} else {
if (workspaceIDRight < m_sActiveSwipe.pWorkspaceBegin->m_iID){
m_sActiveSwipe.delta = 0;
return;
}
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDRight);
PWORKSPACE->m_bForceRendering = true;
if (workspaceIDLeft != workspaceIDRight) {
const auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
PWORKSPACEL->m_bForceRendering = false;
}
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x + m_sActiveSwipe.pMonitor->vecSize.x, 0));
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x, 0));
g_pCompositor->updateWorkspaceWindowDecos(workspaceIDRight);
}
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID);
}

View File

@@ -10,7 +10,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
Debug::log(ERR, "Tablet had no name???"); // logic error
}
PNEWTABLET->wlrTablet = pDevice->tablet;
PNEWTABLET->wlrTablet = wlr_tablet_from_input_device(pDevice);
PNEWTABLET->wlrDevice = pDevice;
PNEWTABLET->wlrTabletV2 = wlr_tablet_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pDevice);
PNEWTABLET->wlrTablet->data = PNEWTABLET;
@@ -27,7 +27,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
Debug::log(LOG, "Removed a tablet");
}, PNEWTABLET, "Tablet");
PNEWTABLET->hyprListener_Axis.initCallback(&pDevice->tablet->events.axis, [](void* owner, void* data) {
PNEWTABLET->hyprListener_Axis.initCallback(&wlr_tablet_from_input_device(pDevice)->events.axis, [](void* owner, void* data) {
const auto EVENT = (wlr_tablet_tool_axis_event*)data;
const auto PTAB = (STablet*)owner;
@@ -80,7 +80,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
}, PNEWTABLET, "Tablet");
PNEWTABLET->hyprListener_Tip.initCallback(&pDevice->tablet->events.tip, [](void* owner, void* data) {
PNEWTABLET->hyprListener_Tip.initCallback(&wlr_tablet_from_input_device(pDevice)->events.tip, [](void* owner, void* data) {
const auto EVENT = (wlr_tablet_tool_tip_event*)data;
const auto PTAB = (STablet*)owner;
@@ -98,7 +98,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
}, PNEWTABLET, "Tablet");
PNEWTABLET->hyprListener_Button.initCallback(&pDevice->tablet->events.button, [](void* owner, void* data) {
PNEWTABLET->hyprListener_Button.initCallback(&wlr_tablet_from_input_device(pDevice)->events.button, [](void* owner, void* data) {
const auto EVENT = (wlr_tablet_tool_button_event*)data;
const auto PTOOL = g_pInputManager->ensureTabletToolPresent(EVENT->tool);
@@ -107,7 +107,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
}, PNEWTABLET, "Tablet");
PNEWTABLET->hyprListener_Proximity.initCallback(&pDevice->tablet->events.proximity, [](void* owner, void* data) {
PNEWTABLET->hyprListener_Proximity.initCallback(&wlr_tablet_from_input_device(pDevice)->events.proximity, [](void* owner, void* data) {
const auto EVENT = (wlr_tablet_tool_proximity_event*)data;
const auto PTAB = (STablet*)owner;
@@ -165,7 +165,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
PNEWPAD->wlrTabletPadV2 = wlr_tablet_pad_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pDevice);
PNEWPAD->hyprListener_Button.initCallback(&pDevice->tablet_pad->events.button, [](void* owner, void* data) {
PNEWPAD->hyprListener_Button.initCallback(&wlr_tablet_pad_from_input_device(pDevice)->events.button, [](void* owner, void* data) {
const auto EVENT = (wlr_tablet_pad_button_event*)data;
const auto PPAD = (STabletPad*)owner;
@@ -175,7 +175,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
}, PNEWPAD, "Tablet Pad");
PNEWPAD->hyprListener_Strip.initCallback(&pDevice->tablet_pad->events.strip, [](void* owner, void* data) {
PNEWPAD->hyprListener_Strip.initCallback(&wlr_tablet_pad_from_input_device(pDevice)->events.strip, [](void* owner, void* data) {
const auto EVENT = (wlr_tablet_pad_strip_event*)data;
const auto PPAD = (STabletPad*)owner;
@@ -184,7 +184,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
}, PNEWPAD, "Tablet Pad");
PNEWPAD->hyprListener_Ring.initCallback(&pDevice->tablet_pad->events.strip, [](void* owner, void* data) {
PNEWPAD->hyprListener_Ring.initCallback(&wlr_tablet_pad_from_input_device(pDevice)->events.strip, [](void* owner, void* data) {
const auto EVENT = (wlr_tablet_pad_ring_event*)data;
const auto PPAD = (STabletPad*)owner;
@@ -193,7 +193,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
}, PNEWPAD, "Tablet Pad");
PNEWPAD->hyprListener_Attach.initCallback(&pDevice->tablet_pad->events.strip, [](void* owner, void* data) {
PNEWPAD->hyprListener_Attach.initCallback(&wlr_tablet_pad_from_input_device(pDevice)->events.strip, [](void* owner, void* data) {
const auto TABLET = (wlr_tablet_tool*)data;
const auto PPAD = (STabletPad*)owner;

View File

@@ -717,7 +717,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
const auto BLURVAL = g_pConfigManager->getInt("decoration:blur");
g_pConfigManager->setInt("decoration:blur", 0);
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders);
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL);
g_pConfigManager->setInt("decoration:blur", BLURVAL);
@@ -915,9 +915,28 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
void CHyprOpenGLImpl::renderSplash(cairo_t *const CAIRO, cairo_surface_t *const CAIROSURFACE) {
cairo_select_font_face(CAIRO, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
const auto FONTSIZE = (int)(m_RenderData.pMonitor->vecPixelSize.y / 76);
cairo_set_font_size(CAIRO, FONTSIZE);
cairo_set_source_rgba(CAIRO, 1.f, 1.f, 1.f, 0.32f);
cairo_text_extents_t textExtents;
cairo_text_extents(CAIRO, g_pCompositor->m_szCurrentSplash.c_str(), &textExtents);
cairo_move_to(CAIRO, m_RenderData.pMonitor->vecPixelSize.x / 2.f - textExtents.width / 2.f, m_RenderData.pMonitor->vecPixelSize.y - textExtents.height - 1);
cairo_show_text(CAIRO, g_pCompositor->m_szCurrentSplash.c_str());
cairo_surface_flush(CAIROSURFACE);
}
void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
RASSERT(m_RenderData.pMonitor, "Tried to createBGTex without begin()!");
static auto *const PNOSPLASH = &g_pConfigManager->getConfigValuePtr("misc:disable_splash_rendering")->intValue;
// release the last tex if exists
const auto PTEX = &m_mMonitorBGTextures[pMonitor];
PTEX->destroyTexture();
@@ -926,6 +945,9 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
Debug::log(LOG, "Allocated texture for BGTex");
// TODO: use relative paths to the installation
// or configure the paths at build time
// check if wallpapers exist
if (!std::filesystem::exists("/usr/share/hyprland/wall_8K.png"))
return; // the texture will be empty, oh well. We'll clear with a solid color anyways.
@@ -949,6 +971,9 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
const auto CAIRO = cairo_create(CAIROSURFACE);
if (!*PNOSPLASH)
renderSplash(CAIRO, CAIROSURFACE);
// copy the data to an OpenGL texture we have
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
glBindTexture(GL_TEXTURE_2D, PTEX->m_iTexID);
@@ -969,9 +994,12 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
void CHyprOpenGLImpl::clearWithTex() {
RASSERT(m_RenderData.pMonitor, "Tried to render BGtex without begin()!");
wlr_box box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
static auto *const PRENDERTEX = &g_pConfigManager->getConfigValuePtr("misc:disable_hyprland_logo")->intValue;
renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0);
if (!*PRENDERTEX) {
wlr_box box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0);
}
}
void CHyprOpenGLImpl::destroyMonitorResources(SMonitor* pMonitor) {

View File

@@ -6,6 +6,8 @@
#include <list>
#include <unordered_map>
#include <cairo/cairo.h>
#include "Shaders.hpp"
#include "Shader.hpp"
#include "Texture.hpp"
@@ -121,6 +123,8 @@ private:
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowCustomUV = false);
void renderSplash(cairo_t *const, cairo_surface_t *const);
};
inline std::unique_ptr<CHyprOpenGLImpl> g_pHyprOpenGL;

View File

@@ -16,6 +16,15 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, RDATA->w, RDATA->h};
else // here we clamp to 2, these might be some tiny specks
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, std::clamp(surface->current.width, 2, 1337420), std::clamp(surface->current.height, 2, 1337420)};
// squish all oversized
if (RDATA->squishOversized) {
if (x + windowBox.width > RDATA->w)
windowBox.width = RDATA->w - x;
if (y + windowBox.height > RDATA->h)
windowBox.height = RDATA->h - y;
}
scaleBox(&windowBox, RDATA->output->scale);
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
@@ -23,7 +32,10 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding;
if (RDATA->surface && surface == RDATA->surface) {
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding);
if (RDATA->blur)
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding);
else
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true);
if (RDATA->decorate) {
auto col = g_pHyprOpenGL->m_pCurrentWindow->m_cRealBorderColor.col();
@@ -60,8 +72,8 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) {
return true;
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
// if not, check if it maybe is active on a different monitor. vvv might be animation in progress
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
// if not, check if it maybe is active on a different monitor. vvv might be animation in progress
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && PWORKSPACE->m_bForceRendering) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
return true;
if (pMonitor->specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
@@ -99,7 +111,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
continue;
// found it!
renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL);
renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL, RENDER_PASS_ALL);
pWorkspaceWindow = w.get();
}
@@ -109,7 +121,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || !w->m_bCreatedOverFullscreen || !w->m_bIsMapped)
continue;
renderWindow(w.get(), pMonitor, time, true);
renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
}
// and then special windows
@@ -124,7 +136,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
continue;
// render the bad boy
renderWindow(w.get(), pMonitor, time, true);
renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
}
// and the overlay layers
@@ -146,7 +158,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
g_pHyprError->draw();
}
void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate) {
void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate, eRenderPassMode mode) {
if (pWindow->m_bHidden)
return;
@@ -166,9 +178,11 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
renderdata.h = std::clamp(pWindow->m_vRealSize.vec().y, (double)5, (double)1337420); // otherwise we'll have issues later with invalid boxes
renderdata.dontRound = pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL;
renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (PWORKSPACE->m_fAlpha.fl() / 255.f);
renderdata.alpha = pWindow->m_bIsFullscreen ? g_pConfigManager->getFloat("decoration:fullscreen_opacity") : pWindow == g_pCompositor->m_pLastWindow ? g_pConfigManager->getFloat("decoration:active_opacity") : g_pConfigManager->getFloat("decoration:inactive_opacity");
renderdata.alpha = pWindow->m_fActiveInactiveAlpha.fl();
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true) && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL);
renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding;
renderdata.blur = true; // if it shouldn't, it will be ignored later
renderdata.squishOversized = pWindow->m_vRealPosition.isBeingAnimated();
// apply window special data
if (pWindow->m_sSpecialRenderData.alphaInactive == -1)
@@ -179,35 +193,40 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
g_pHyprOpenGL->m_pCurrentWindow = pWindow;
// render window decorations first, if not fullscreen full
if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations)
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f);
if (!pWindow->m_bIsX11) {
wlr_box geom;
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_MAIN) {
if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations)
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f);
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D((double)geom.x / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)geom.y / (double)pWindow->m_uSurface.xdg->surface->current.height);
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D((double)(geom.width + geom.x) / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)(geom.y + geom.height) / (double)pWindow->m_uSurface.xdg->surface->current.height);
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) {
// No special UV mods needed
if (!pWindow->m_bIsX11) {
wlr_box geom;
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D((double)geom.x / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)geom.y / (double)pWindow->m_uSurface.xdg->surface->current.height);
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D((double)(geom.width + geom.x) / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)(geom.y + geom.height) / (double)pWindow->m_uSurface.xdg->surface->current.height);
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) {
// No special UV mods needed
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
}
} else {
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
}
} else {
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
}
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
if (!pWindow->m_bIsX11) {
renderdata.dontRound = false; // restore dontround
renderdata.pMonitor = pMonitor;
wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata);
if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_POPUP) {
if (!pWindow->m_bIsX11) {
renderdata.dontRound = false; // restore dontround
renderdata.pMonitor = pMonitor;
wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata);
}
}
g_pHyprOpenGL->m_pCurrentWindow = nullptr;
@@ -221,6 +240,11 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, SMonitor* pMonitor, times
SRenderData renderdata = {pMonitor->output, time, pLayer->geometry.x, pLayer->geometry.y};
renderdata.fadeAlpha = pLayer->alpha.fl();
renderdata.blur = pLayer->forceBlur;
renderdata.surface = pLayer->layerSurface->surface;
renderdata.decorate = false;
renderdata.w = pLayer->layerSurface->surface->current.width;
renderdata.h = pLayer->layerSurface->surface->current.height;
wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata);
}
@@ -247,7 +271,25 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
return;
}
// Non-floating
// Non-floating main
for (auto& w : g_pCompositor->m_vWindows) {
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
continue;
if (w->m_bIsFloating)
continue; // floating are in the second pass
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
continue; // special are in the third pass
if (!shouldRenderWindow(w.get(), PMONITOR))
continue;
// render the bad boy
renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_MAIN);
}
// Non-floating popup
for (auto& w : g_pCompositor->m_vWindows) {
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
continue;
@@ -262,7 +304,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
continue;
// render the bad boy
renderWindow(w.get(), PMONITOR, time, true);
renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_POPUP);
}
// floating on top
@@ -280,7 +322,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
continue;
// render the bad boy
renderWindow(w.get(), PMONITOR, time, true);
renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_ALL);
}
// and then special
@@ -295,7 +337,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
continue;
// render the bad boy
renderWindow(w.get(), PMONITOR, time, true);
renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_ALL);
}
// Render surfaces above windows for monitor
@@ -808,4 +850,4 @@ void CHyprRenderer::ensureCursorRenderingMode() {
bool CHyprRenderer::shouldRenderCursor() {
return m_bHasARenderedCursor;
}
}

View File

@@ -17,6 +17,12 @@ enum DAMAGETRACKINGMODES {
DAMAGE_TRACKING_FULL
};
enum eRenderPassMode {
RENDER_PASS_ALL = 0,
RENDER_PASS_MAIN,
RENDER_PASS_POPUP
};
class CHyprRenderer {
public:
@@ -41,7 +47,7 @@ public:
private:
void arrangeLayerArray(SMonitor*, const std::list<SLayerSurface*>&, bool, wlr_box*);
void renderWorkspaceWithFullscreenWindow(SMonitor*, CWorkspace*, timespec*);
void renderWindow(CWindow*, SMonitor*, timespec*, bool);
void renderWindow(CWindow*, SMonitor*, timespec*, bool, eRenderPassMode);
void renderLayer(SLayerSurface*, SMonitor*, timespec*);
void renderDragIcon(SMonitor*, timespec*);