mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-07-27 18:21:54 -07:00
Compare commits
41 Commits
v0.1.1beta
...
v0.2.0beta
Author | SHA1 | Date | |
---|---|---|---|
|
85128ebb7d | ||
|
ad98b96891 | ||
|
2e7586e841 | ||
|
f6ba9909d6 | ||
|
c9041bf5c9 | ||
|
b2474d406a | ||
|
eee9698ec9 | ||
|
1f4c938c67 | ||
|
c44c79abb2 | ||
|
1e096f6fcd | ||
|
b1c11f3d2e | ||
|
da63503d5f | ||
|
7167be9c48 | ||
|
e81790f357 | ||
|
edf57c50ff | ||
|
e2be91582a | ||
|
7522ade58d | ||
|
3d7abfea92 | ||
|
2de65771ea | ||
|
6b60595822 | ||
|
b76b32b458 | ||
|
f5645805d8 | ||
|
15338fcf63 | ||
|
227cbb0464 | ||
|
9842730f57 | ||
|
d0ff0c0990 | ||
|
fdb3f610e5 | ||
|
d2e1899f26 | ||
|
9d3099b21f | ||
|
4cc085ac75 | ||
|
af55d5aa96 | ||
|
632d00c51c | ||
|
f06d4fca27 | ||
|
2cd5059cf1 | ||
|
65610555c4 | ||
|
3f8845a6a7 | ||
|
894ae2d742 | ||
|
08e0567d3a | ||
|
685cf1e00d | ||
|
bdf1c16195 | ||
|
b1b24cb21a |
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -3,6 +3,7 @@ name: Bug report
|
||||
about: Found a bug? Report it here!
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
@@ -13,3 +14,5 @@ labels: bug
|
||||
|
||||
|
||||
Please attach a log (it's in /tmp/hypr/hyprland.log) and, if crashing, a crashdump (coredumpctl, then coredumpctl info <pid>)
|
||||
|
||||
*Please do NOT attach coredumps from any packaged version of Hyprland (AUR, etc.). Compile manually, and THEN attach a coredump of that.*
|
||||
|
1
.github/ISSUE_TEMPLATE/feature_request.md
vendored
1
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -3,6 +3,7 @@ name: Feature request
|
||||
about: Suggest a feature/change/idea
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
@@ -30,6 +30,8 @@ jobs:
|
||||
|
||||
- name: Checkout Hyprland
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Build Hyprland With default settings
|
||||
run: |
|
||||
|
2
.github/workflows/nix-build.yaml
vendored
2
.github/workflows/nix-build.yaml
vendored
@@ -8,6 +8,8 @@ jobs:
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install nix
|
||||
uses: cachix/install-nix-action@v17
|
||||
with:
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@@ -19,3 +19,7 @@ result
|
||||
.ccls-cache
|
||||
|
||||
hyprctl/hyprctl
|
||||
|
||||
gmon.out
|
||||
*.out
|
||||
*.tar.gz
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "wlroots"]
|
||||
path = wlroots
|
||||
url = https://gitlab.freedesktop.org/wlroots/wlroots
|
15
Makefile
15
Makefile
@@ -89,6 +89,7 @@ clear:
|
||||
rm -rf build
|
||||
rm -f *.o *-protocol.h *-protocol.c
|
||||
rm -f ./hyprctl/hyprctl
|
||||
rm -rf ./wlroots/build
|
||||
|
||||
all:
|
||||
make config
|
||||
@@ -113,4 +114,16 @@ uninstall:
|
||||
rm -f ${PREFIX}/bin/hyprctl
|
||||
rm -rf ${PREFIX}/share/hyprland
|
||||
|
||||
config: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o
|
||||
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o
|
||||
|
||||
config:
|
||||
make protocols
|
||||
|
||||
sed -i -E 's/(soversion = 11)([^032]|$$)/soversion = 11032/g' ./wlroots/meson.build
|
||||
|
||||
rm -rf ./wlroots/build
|
||||
|
||||
cd wlroots && meson ./build --prefix=/usr --buildtype=release
|
||||
cd wlroots && ninja -C build/
|
||||
|
||||
cd wlroots && sudo cp ./build/libwlroots.so.11032 /usr/lib/
|
||||
|
32
aur/PKGBUILD
Normal file
32
aur/PKGBUILD
Normal file
@@ -0,0 +1,32 @@
|
||||
# Maintainer: ThatOneCalculator <kainoa@t1c.dev>
|
||||
|
||||
_pkgname="hyprland"
|
||||
pkgname="${_pkgname}"
|
||||
pkgver="0.1.1beta"
|
||||
pkgrel=2
|
||||
pkgdesc="Hyprland is a dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks."
|
||||
arch=(any)
|
||||
url="https://github.com/vaxerski/Hyprland"
|
||||
license=('BSD')
|
||||
depends=(libxcb xcb-proto xcb-util xcb-util-keysyms libxfixes libx11 libxcomposite xorg-xinput libxrender pixman wayland-protocols wlroots-git cairo pango)
|
||||
makedepends=(git cmake ninja gcc gdb)
|
||||
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/vaxerski/hyprland/archive/v${pkgver}.tar.gz")
|
||||
sha256sums=('SKIP')
|
||||
options=(!makeflags !buildflags)
|
||||
|
||||
build() {
|
||||
cd "$srcdir/Hyprland-$pkgver"
|
||||
make all
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/Hyprland-$pkgver"
|
||||
mkdir -p "${pkgdir}/usr/share/wayland-sessions"
|
||||
mkdir -p "${pkgdir}/usr/share/hyprland"
|
||||
install -Dm755 build/Hyprland -t "${pkgdir}/usr/bin"
|
||||
install -Dm755 hyprctl/hyprctl -t "${pkgdir}/usr/bin"
|
||||
install -Dm644 assets/*.png -t "${pkgdir}/usr/share/hyprland"
|
||||
install -Dm644 example/hyprland.desktop -t "${pkgdir}/usr/share/wayland-sessions"
|
||||
install -Dm644 example/hyprland.conf -t "${pkgdir}/usr/share/hyprland"
|
||||
install -Dm644 LICENSE -t "${pkgdir}/usr/share/licenses/${_pkgname}"
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
# Maintainer: Sander van Kasteel <info@sandervankasteel.nl>, ThatOneCalculator <kainoa@t1c.dev>
|
||||
# Maintainer: ThatOneCalculator <kainoa@t1c.dev>, Sander van Kasteel <info@sandervankasteel.nl>
|
||||
|
||||
_pkgname="hyprland"
|
||||
pkgname="${_pkgname}-git"
|
||||
pkgver=r461.96cdf8f
|
||||
pkgrel=5
|
||||
pkgver=r568.g632d00c
|
||||
pkgrel=1
|
||||
pkgdesc="Hyprland is a dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks."
|
||||
arch=(any)
|
||||
url="https://github.com/vaxerski/Hyprland"
|
||||
|
@@ -64,7 +64,7 @@ dwindle {
|
||||
# example binds
|
||||
bind=SUPER,Q,exec,kitty
|
||||
bind=SUPER,C,killactive,
|
||||
bind=SUPER,M,exec,pkill Hyprland
|
||||
bind=SUPER,M,exit,
|
||||
bind=SUPER,E,exec,dolphin
|
||||
bind=SUPER,V,togglefloating,
|
||||
bind=SUPER,R,exec,wofi --show drun -o DP-3
|
||||
|
12
flake.lock
generated
12
flake.lock
generated
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1653407748,
|
||||
"narHash": "sha256-g9puJaILRTb9ttlLQ7IehpV7Wcy0n+vs8LOFu6ylQcM=",
|
||||
"lastModified": 1653581809,
|
||||
"narHash": "sha256-Uvka0V5MTGbeOfWte25+tfRL3moECDh1VwokWSZUdoY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "5ce6597eca7d7b518c03ecda57d45f9404b5e060",
|
||||
"rev": "83658b28fe638a170a19b8933aa008b30640fbd1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -26,11 +26,11 @@
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"host": "gitlab.freedesktop.org",
|
||||
"lastModified": 1653658290,
|
||||
"narHash": "sha256-zZaona39DOZNL93A1KG3zAi8vDttJBirxacq24hWCn4=",
|
||||
"lastModified": 1653733431,
|
||||
"narHash": "sha256-0JwNH2E9XlMVa7ZCsqxazpKwpZ2rW5QQjbk0DdZxa48=",
|
||||
"owner": "wlroots",
|
||||
"repo": "wlroots",
|
||||
"rev": "75d31509db8c28e8379fe9570118ef8c82284581",
|
||||
"rev": "93ee4c7684050807e959bb3b6d57826a72fba8c2",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
@@ -102,6 +102,8 @@ CCompositor::CCompositor() {
|
||||
m_sWLRVKeyboardMgr = wlr_virtual_keyboard_manager_v1_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRVirtPtrMgr = wlr_virtual_pointer_manager_v1_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRToplevelMgr = wlr_foreign_toplevel_manager_v1_create(m_sWLDisplay);
|
||||
}
|
||||
|
||||
CCompositor::~CCompositor() {
|
||||
@@ -144,6 +146,12 @@ void CCompositor::cleanupExit() {
|
||||
if (!m_sWLDisplay)
|
||||
return;
|
||||
|
||||
m_pLastFocus = nullptr;
|
||||
m_pLastWindow = nullptr;
|
||||
|
||||
m_lWorkspaces.clear();
|
||||
m_lWindows.clear();
|
||||
|
||||
if (g_pXWaylandManager->m_sWLRXWayland) {
|
||||
wlr_xwayland_destroy(g_pXWaylandManager->m_sWLRXWayland);
|
||||
g_pXWaylandManager->m_sWLRXWayland = nullptr;
|
||||
@@ -247,6 +255,16 @@ SMonitor* CCompositor::getMonitorFromID(const int& id) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SMonitor* CCompositor::getMonitorFromName(const std::string& name) {
|
||||
for (auto& m : m_lMonitors) {
|
||||
if (m.szName == name) {
|
||||
return &m;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SMonitor* CCompositor::getMonitorFromCursor() {
|
||||
const auto COORDS = Vector2D(m_sWLRCursor->x, m_sWLRCursor->y);
|
||||
|
||||
@@ -436,6 +454,9 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||
wlr_seat_keyboard_notify_clear_focus(m_sSeat.seat);
|
||||
wlr_seat_pointer_clear_focus(m_sSeat.seat);
|
||||
}
|
||||
|
||||
if (PLASTWINDOW->m_phForeignToplevel)
|
||||
wlr_foreign_toplevel_handle_v1_set_activated(PLASTWINDOW->m_phForeignToplevel, false);
|
||||
}
|
||||
|
||||
m_pLastWindow = PLASTWINDOW;
|
||||
@@ -454,6 +475,9 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||
|
||||
// Send an event
|
||||
g_pEventManager->postEvent(SHyprIPCEvent("activewindow", g_pXWaylandManager->getAppIDClass(pWindow) + "," + pWindow->m_szTitle));
|
||||
|
||||
if (pWindow->m_phForeignToplevel)
|
||||
wlr_foreign_toplevel_handle_v1_set_activated(pWindow->m_phForeignToplevel, true);
|
||||
}
|
||||
|
||||
void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
|
||||
@@ -568,7 +592,7 @@ CWorkspace* CCompositor::getWorkspaceByID(const int& id) {
|
||||
|
||||
void CCompositor::sanityCheckWorkspaces() {
|
||||
for (auto it = m_lWorkspaces.begin(); it != m_lWorkspaces.end(); ++it) {
|
||||
if (getWindowsOnWorkspace(it->m_iID) == 0 && !isWorkspaceVisible(it->m_iID)) {
|
||||
if ((getWindowsOnWorkspace(it->m_iID) == 0 && !isWorkspaceVisible(it->m_iID))) {
|
||||
it = m_lWorkspaces.erase(it);
|
||||
}
|
||||
}
|
||||
@@ -598,6 +622,9 @@ void CCompositor::fixXWaylandWindowsOnWorkspace(const int& id) {
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(id);
|
||||
|
||||
if (!PWORKSPACE)
|
||||
return;
|
||||
|
||||
for (auto& w : m_lWindows) {
|
||||
if (w.m_iWorkspaceID == id) {
|
||||
|
||||
@@ -617,6 +644,9 @@ bool CCompositor::doesSeatAcceptInput(wlr_surface* surface) {
|
||||
}
|
||||
|
||||
bool CCompositor::isWindowActive(CWindow* pWindow) {
|
||||
if (!m_pLastWindow && !m_pLastFocus)
|
||||
return false;
|
||||
|
||||
if (!windowValidMapped(pWindow))
|
||||
return false;
|
||||
|
||||
@@ -793,8 +823,8 @@ CWorkspace* CCompositor::getWorkspaceByString(const std::string& str) {
|
||||
}
|
||||
|
||||
try {
|
||||
int id = std::stoi(str);
|
||||
return getWorkspaceByID(id);
|
||||
std::string name = "";
|
||||
return getWorkspaceByID(getWorkspaceIDFromString(str, name));
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Error in getWorkspaceByString, invalid id");
|
||||
}
|
||||
@@ -909,4 +939,86 @@ void CCompositor::updateWindowBorderColor(CWindow* pWindow) {
|
||||
pWindow->m_cRealBorderColor = RENDERDATA.borderColor;
|
||||
else
|
||||
pWindow->m_cRealBorderColor = CColor(pWindow == m_pLastWindow ? *ACTIVECOL : *INACTIVECOL);
|
||||
}
|
||||
|
||||
void CCompositor::moveWindowToWorkspace(CWindow* pWindow, const std::string& work) {
|
||||
m_pLastWindow = pWindow;
|
||||
g_pKeybindManager->moveActiveToWorkspace(work);
|
||||
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
||||
int CCompositor::getNextAvailableMonitorID() {
|
||||
int64_t topID = -1;
|
||||
for (auto& m : m_lMonitors) {
|
||||
if ((int64_t)m.ID > topID)
|
||||
topID = m.ID;
|
||||
}
|
||||
|
||||
return topID + 1;
|
||||
}
|
||||
|
||||
void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, SMonitor* pMonitor) {
|
||||
|
||||
// We trust the workspace and monitor to be correct.
|
||||
|
||||
if (pWorkspace->m_iMonitorID == pMonitor->ID)
|
||||
return;
|
||||
|
||||
Debug::log(LOG, "moveWorkspaceToMonitor: Moving %d to monitor %d", pWorkspace->m_iID, pMonitor->ID);
|
||||
|
||||
const auto POLDMON = getMonitorFromID(pWorkspace->m_iMonitorID);
|
||||
|
||||
const bool SWITCHINGISACTIVE = POLDMON->activeWorkspace == pWorkspace->m_iID;
|
||||
|
||||
// fix old mon
|
||||
int nextWorkspaceOnMonitorID = -1;
|
||||
for (auto& w : m_lWorkspaces) {
|
||||
if (w.m_iMonitorID == POLDMON->ID && w.m_iID != pWorkspace->m_iID) {
|
||||
nextWorkspaceOnMonitorID = w.m_iID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nextWorkspaceOnMonitorID == -1) {
|
||||
nextWorkspaceOnMonitorID = 1;
|
||||
|
||||
while (getWorkspaceByID(nextWorkspaceOnMonitorID))
|
||||
nextWorkspaceOnMonitorID++;
|
||||
|
||||
Debug::log(LOG, "moveWorkspaceToMonitor: Plugging gap with new %d", nextWorkspaceOnMonitorID);
|
||||
}
|
||||
|
||||
Debug::log(LOG, "moveWorkspaceToMonitor: Plugging gap with existing %d", nextWorkspaceOnMonitorID);
|
||||
|
||||
g_pKeybindManager->focusMonitor(std::to_string(POLDMON->ID));
|
||||
g_pKeybindManager->changeworkspace(std::to_string(nextWorkspaceOnMonitorID));
|
||||
|
||||
// move the workspace
|
||||
|
||||
pWorkspace->m_iMonitorID = pMonitor->ID;
|
||||
pWorkspace->moveToMonitor(pMonitor->ID);
|
||||
|
||||
for (auto& w : m_lWindows) {
|
||||
if (w.m_iWorkspaceID == pWorkspace->m_iID)
|
||||
w.m_iMonitorID = pMonitor->ID;
|
||||
}
|
||||
|
||||
if (SWITCHINGISACTIVE) { // if it was active, preserve its' status. If it wasn't, don't.
|
||||
Debug::log(LOG, "moveWorkspaceToMonitor: SWITCHINGISACTIVE, active %d -> %d", pMonitor->activeWorkspace, pWorkspace->m_iID);
|
||||
|
||||
getWorkspaceByID(pMonitor->activeWorkspace)->startAnim(false, false);
|
||||
|
||||
pMonitor->activeWorkspace = pWorkspace->m_iID;
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pMonitor->ID);
|
||||
|
||||
pWorkspace->startAnim(true, true, true);
|
||||
|
||||
wlr_cursor_warp(m_sWLRCursor, m_sSeat.mouse->mouse, pMonitor->vecPosition.x + pMonitor->vecTransformedSize.x / 2, pMonitor->vecPosition.y + pMonitor->vecTransformedSize.y / 2);
|
||||
}
|
||||
|
||||
// finalize
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(POLDMON->ID);
|
||||
|
||||
g_pInputManager->refocus();
|
||||
}
|
@@ -58,6 +58,7 @@ public:
|
||||
wlr_server_decoration_manager* m_sWLRServerDecoMgr;
|
||||
wlr_xdg_decoration_manager_v1* m_sWLRXDGDecoMgr;
|
||||
wlr_virtual_pointer_manager_v1* m_sWLRVirtPtrMgr;
|
||||
wlr_foreign_toplevel_manager_v1* m_sWLRToplevelMgr;
|
||||
// ------------------------------------------------- //
|
||||
|
||||
|
||||
@@ -85,6 +86,7 @@ public:
|
||||
// ------------------------------------------------- //
|
||||
|
||||
SMonitor* getMonitorFromID(const int&);
|
||||
SMonitor* getMonitorFromName(const std::string&);
|
||||
SMonitor* getMonitorFromCursor();
|
||||
SMonitor* getMonitorFromVector(const Vector2D&);
|
||||
void removeWindowFromVectorSafe(CWindow*);
|
||||
@@ -124,6 +126,9 @@ public:
|
||||
SMonitor* getMonitorInDirection(const char&);
|
||||
void updateAllWindowsBorders();
|
||||
void updateWindowBorderColor(CWindow*);
|
||||
void moveWindowToWorkspace(CWindow*, const std::string&);
|
||||
int getNextAvailableMonitorID();
|
||||
void moveWorkspaceToMonitor(CWorkspace*, SMonitor*);
|
||||
|
||||
private:
|
||||
void initAllSignals();
|
||||
|
@@ -13,4 +13,34 @@ CWindow::~CWindow() {
|
||||
g_pCompositor->m_pLastFocus = nullptr;
|
||||
g_pCompositor->m_pLastWindow = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
wlr_box CWindow::getFullWindowBoundingBox() {
|
||||
|
||||
SWindowDecorationExtents maxExtents;
|
||||
|
||||
for (auto& wd : m_dWindowDecorations) {
|
||||
|
||||
const auto EXTENTS = wd->getWindowDecorationExtents();
|
||||
|
||||
if (EXTENTS.topLeft.x > maxExtents.topLeft.x)
|
||||
maxExtents.topLeft.x = EXTENTS.topLeft.x;
|
||||
|
||||
if (EXTENTS.topLeft.y > maxExtents.topLeft.y)
|
||||
maxExtents.topLeft.y = EXTENTS.topLeft.y;
|
||||
|
||||
if (EXTENTS.bottomRight.x > maxExtents.bottomRight.x)
|
||||
maxExtents.bottomRight.x = EXTENTS.bottomRight.x;
|
||||
|
||||
if (EXTENTS.bottomRight.y > maxExtents.bottomRight.y)
|
||||
maxExtents.bottomRight.y = EXTENTS.bottomRight.y;
|
||||
}
|
||||
|
||||
// Add extents to the real base BB and return
|
||||
wlr_box finalBox = {m_vRealPosition.vec().x - maxExtents.topLeft.x,
|
||||
m_vRealPosition.vec().y - maxExtents.topLeft.y,
|
||||
m_vRealSize.vec().x + maxExtents.topLeft.x + maxExtents.bottomRight.x,
|
||||
m_vRealSize.vec().y + maxExtents.topLeft.y + maxExtents.bottomRight.y};
|
||||
|
||||
return finalBox;
|
||||
}
|
@@ -4,6 +4,8 @@
|
||||
#include "events/Events.hpp"
|
||||
#include "helpers/SubsurfaceTree.hpp"
|
||||
#include "helpers/AnimatedVariable.hpp"
|
||||
#include "render/decorations/IHyprWindowDecoration.hpp"
|
||||
#include <deque>
|
||||
|
||||
struct SWindowSpecialRenderData {
|
||||
float alpha = 1.f;
|
||||
@@ -88,6 +90,12 @@ public:
|
||||
// For hidden windows and stuff
|
||||
bool m_bHidden = false;
|
||||
|
||||
// Foreign Toplevel proto
|
||||
wlr_foreign_toplevel_handle_v1* m_phForeignToplevel = nullptr;
|
||||
|
||||
// Window decorations
|
||||
std::deque<std::unique_ptr<IHyprWindowDecoration>> m_dWindowDecorations;
|
||||
|
||||
// Special render data, rules, etc
|
||||
SWindowSpecialRenderData m_sSpecialRenderData;
|
||||
SWindowAdditionalConfigData m_sAdditionalConfigData;
|
||||
@@ -97,4 +105,7 @@ public:
|
||||
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;
|
||||
}
|
||||
|
||||
// methods
|
||||
wlr_box getFullWindowBoundingBox();
|
||||
|
||||
};
|
@@ -186,10 +186,24 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
||||
|
||||
nextItem();
|
||||
|
||||
if (curitem == "disable" || curitem == "disabled" || curitem == "addreserved") {
|
||||
if (curitem == "disable" || curitem == "disabled" || curitem == "addreserved" || curitem == "transform") {
|
||||
if (curitem == "disable" || curitem == "disabled")
|
||||
newrule.disabled = true;
|
||||
else if (curitem == "addreserved") {
|
||||
else if (curitem == "transform") {
|
||||
nextItem();
|
||||
|
||||
wl_output_transform transform = (wl_output_transform)std::stoi(curitem);
|
||||
|
||||
// overwrite if exists
|
||||
for (auto& r : m_dMonitorRules) {
|
||||
if (r.name == newrule.name) {
|
||||
r.transform = transform;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (curitem == "addreserved") {
|
||||
nextItem();
|
||||
|
||||
int top = std::stoi(curitem);
|
||||
|
@@ -30,6 +30,7 @@ struct SMonitorRule {
|
||||
float refreshRate = 60;
|
||||
int defaultWorkspaceID = -1;
|
||||
bool disabled = false;
|
||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
};
|
||||
|
||||
struct SMonitorAdditionalReservedArea {
|
||||
|
@@ -71,7 +71,7 @@ dwindle {
|
||||
# example binds
|
||||
bind=SUPER,Q,exec,kitty
|
||||
bind=SUPER,C,killactive,
|
||||
bind=SUPER,M,exec,pkill Hyprland
|
||||
bind=SUPER,M,exit,
|
||||
bind=SUPER,E,exec,dolphin
|
||||
bind=SUPER,V,togglefloating,
|
||||
bind=SUPER,R,exec,wofi --show drun -o DP-3
|
||||
|
@@ -26,8 +26,8 @@ std::string monitorsRequest() {
|
||||
std::string clientsRequest() {
|
||||
std::string result = "";
|
||||
for (auto& w : g_pCompositor->m_lWindows) {
|
||||
result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i, %i\n\tworkspace: %i (%s)\n\tfloating: %i\n\n",
|
||||
&w, w.m_szTitle.c_str(), (int)w.m_vRealPosition.vec().x, (int)w.m_vRealPosition.vec().y, (int)w.m_vRealSize.vec().x, (int)w.m_vRealSize.vec().y, w.m_iWorkspaceID, (w.m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w.m_iWorkspaceID)->m_szName.c_str()), (int)w.m_bIsFloating);
|
||||
result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i, %i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\n",
|
||||
&w, w.m_szTitle.c_str(), (int)w.m_vRealPosition.vec().x, (int)w.m_vRealPosition.vec().y, (int)w.m_vRealSize.vec().x, (int)w.m_vRealSize.vec().y, w.m_iWorkspaceID, (w.m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w.m_iWorkspaceID)->m_szName.c_str()), (int)w.m_bIsFloating, w.m_iMonitorID);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -47,8 +47,8 @@ std::string activeWindowRequest() {
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
return "Invalid";
|
||||
|
||||
return getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i, %i\n\tworkspace: %i (%s)\n\tfloating: %i\n\n",
|
||||
PWINDOW, PWINDOW->m_szTitle.c_str(), (int)PWINDOW->m_vRealPosition.vec().x, (int)PWINDOW->m_vRealPosition.vec().y, (int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y, PWINDOW->m_iWorkspaceID, (PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName.c_str()), (int)PWINDOW->m_bIsFloating);
|
||||
return getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i, %i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\n",
|
||||
PWINDOW, PWINDOW->m_szTitle.c_str(), (int)PWINDOW->m_vRealPosition.vec().x, (int)PWINDOW->m_vRealPosition.vec().y, (int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y, PWINDOW->m_iWorkspaceID, (PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName.c_str()), (int)PWINDOW->m_bIsFloating, (int)PWINDOW->m_iMonitorID);
|
||||
}
|
||||
|
||||
std::string layersRequest() {
|
||||
|
@@ -64,4 +64,4 @@
|
||||
#endif
|
||||
#ifndef GIT_DIRTY
|
||||
#define GIT_DIRTY "?"
|
||||
#endif
|
||||
#endif
|
@@ -58,7 +58,12 @@ void Events::listener_destroyLayerSurface(void* owner, void* data) {
|
||||
|
||||
Debug::log(LOG, "LayerSurface %x destroyed", layersurface->layerSurface);
|
||||
|
||||
if (!layersurface->fadingOut) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(layersurface->monitorID);
|
||||
|
||||
if (!g_pCompositor->getMonitorFromID(layersurface->monitorID))
|
||||
Debug::log(WARN, "Layersurface destroyed on an invalid monitor (removed?)");
|
||||
|
||||
if (!layersurface->fadingOut && PMONITOR) {
|
||||
Debug::log(LOG, "Removing LayerSurface that wasn't mapped.");
|
||||
layersurface->alpha.setValueAndWarp(0.f);
|
||||
layersurface->fadingOut = true;
|
||||
@@ -70,8 +75,6 @@ void Events::listener_destroyLayerSurface(void* owner, void* data) {
|
||||
layersurface->hyprListener_unmapLayerSurface.removeCallback();
|
||||
layersurface->hyprListener_newPopup.removeCallback();
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(layersurface->monitorID);
|
||||
|
||||
// rearrange to fix the reserved areas
|
||||
if (PMONITOR) {
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
|
||||
@@ -131,6 +134,11 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
|
||||
|
||||
Debug::log(LOG, "LayerSurface %x unmapped", layersurface->layerSurface);
|
||||
|
||||
if (!g_pCompositor->getMonitorFromID(layersurface->monitorID)) {
|
||||
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
// make a snapshot and start fade
|
||||
g_pHyprOpenGL->makeLayerSnapshot(layersurface);
|
||||
layersurface->alpha = 0.f;
|
||||
|
@@ -48,6 +48,16 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||
// new monitor added, let's accomodate for that.
|
||||
const auto OUTPUT = (wlr_output*)data;
|
||||
|
||||
if (!OUTPUT->name) {
|
||||
Debug::log(ERR, "New monitor has no name?? Ignoring");
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_pCompositor->getMonitorFromName(std::string(OUTPUT->name))) {
|
||||
Debug::log(WARN, "Monitor with name %s already exists, not adding as new!", OUTPUT->name);
|
||||
return;
|
||||
}
|
||||
|
||||
// get monitor rule that matches
|
||||
SMonitorRule monitorRule = g_pConfigManager->getMonitorRuleFor(OUTPUT->name);
|
||||
|
||||
@@ -60,7 +70,7 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||
|
||||
SMonitor newMonitor;
|
||||
newMonitor.output = OUTPUT;
|
||||
newMonitor.ID = g_pCompositor->m_lMonitors.size();
|
||||
newMonitor.ID = g_pCompositor->getNextAvailableMonitorID();
|
||||
newMonitor.szName = OUTPUT->name;
|
||||
|
||||
wlr_output_init_render(OUTPUT, g_pCompositor->m_sWLRAllocator, g_pCompositor->m_sWLRRenderer);
|
||||
@@ -100,7 +110,7 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||
wlr_ext_workspace_group_handle_v1_output_enter(PNEWMONITOR->pWLRWorkspaceGroupHandle, PNEWMONITOR->output);
|
||||
|
||||
// Workspace
|
||||
const auto WORKSPACEID = monitorRule.defaultWorkspaceID == -1 ? g_pCompositor->m_lWorkspaces.size() + 1 /* Cuz workspaces doesnt have the new one yet and we start with 1 */ : monitorRule.defaultWorkspaceID;
|
||||
const auto WORKSPACEID = monitorRule.defaultWorkspaceID == -1 && !g_pCompositor->getWorkspaceByID(monitorRule.defaultWorkspaceID) ? g_pCompositor->m_lWorkspaces.size() + 1 /* Cuz workspaces doesnt have the new one yet and we start with 1 */ : monitorRule.defaultWorkspaceID;
|
||||
g_pCompositor->m_lWorkspaces.emplace_back(newMonitor.ID);
|
||||
const auto PNEWWORKSPACE = &g_pCompositor->m_lWorkspaces.back();
|
||||
|
||||
@@ -191,7 +201,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
|
||||
// if we have no tracking or full tracking, invalidate the entire monitor
|
||||
if (DTMODE == DAMAGE_TRACKING_NONE || DTMODE == DAMAGE_TRACKING_MONITOR) {
|
||||
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)PMONITOR->vecPixelSize.x, (int)PMONITOR->vecPixelSize.y);
|
||||
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||
|
||||
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
||||
} else {
|
||||
@@ -246,10 +256,10 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
pixman_region32_init(&frameDamage);
|
||||
|
||||
const auto TRANSFORM = wlr_output_transform_invert(PMONITOR->output->transform);
|
||||
wlr_region_transform(&frameDamage, &PMONITOR->damage->current, TRANSFORM, (int)PMONITOR->vecPixelSize.x, (int)PMONITOR->vecPixelSize.y);
|
||||
wlr_region_transform(&frameDamage, &PMONITOR->damage->current, TRANSFORM, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||
|
||||
if (DTMODE == DAMAGE_TRACKING_NONE || DTMODE == DAMAGE_TRACKING_MONITOR)
|
||||
pixman_region32_union_rect(&frameDamage, &frameDamage, 0, 0, (int)PMONITOR->vecPixelSize.x, (int)PMONITOR->vecPixelSize.y);
|
||||
pixman_region32_union_rect(&frameDamage, &frameDamage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||
|
||||
wlr_output_set_damage(PMONITOR->output, &frameDamage);
|
||||
pixman_region32_fini(&frameDamage);
|
||||
@@ -286,7 +296,56 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
|
||||
if (!pMonitor)
|
||||
return;
|
||||
|
||||
// Cleanup everything. Move windows back, snap cursor, shit.
|
||||
const auto BACKUPMON = &g_pCompositor->m_lMonitors.front();
|
||||
const auto BACKUPWORKSPACE = BACKUPMON->activeWorkspace > 0 ? std::to_string(BACKUPMON->activeWorkspace) : "name:" + g_pCompositor->getWorkspaceByID(BACKUPMON->activeWorkspace)->m_szName;
|
||||
|
||||
if (!BACKUPMON) {
|
||||
Debug::log(CRIT, "No monitors! Unplugged last! Exiting.");
|
||||
g_pCompositor->cleanupExit();
|
||||
return;
|
||||
}
|
||||
|
||||
// snap cursor
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, BACKUPMON->vecPosition.x + BACKUPMON->vecTransformedSize.x / 2.f, BACKUPMON->vecPosition.y + BACKUPMON->vecTransformedSize.y / 2.f);
|
||||
|
||||
// move workspaces
|
||||
std::deque<CWorkspace*> wspToMove;
|
||||
for (auto& w : g_pCompositor->m_lWorkspaces) {
|
||||
if (w.m_iMonitorID == pMonitor->ID) {
|
||||
wspToMove.push_back(&w);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& w : wspToMove) {
|
||||
g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON);
|
||||
w->startAnim(true, true, true);
|
||||
}
|
||||
|
||||
pMonitor->activeWorkspace = -1;
|
||||
|
||||
for (auto it = g_pCompositor->m_lWorkspaces.begin(); it != g_pCompositor->m_lWorkspaces.end(); ++it) {
|
||||
if (it->m_iMonitorID == pMonitor->ID) {
|
||||
it = g_pCompositor->m_lWorkspaces.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Removed monitor %s!", pMonitor->szName.c_str());
|
||||
|
||||
g_pCompositor->m_lMonitors.remove(*pMonitor);
|
||||
|
||||
// TODO: cleanup windows
|
||||
// update the pMostHzMonitor
|
||||
if (pMostHzMonitor == pMonitor) {
|
||||
int mostHz = 0;
|
||||
SMonitor* pMonitorMostHz = nullptr;
|
||||
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
if (m.refreshRate > mostHz) {
|
||||
pMonitorMostHz = &m;
|
||||
mostHz = m.refreshRate;
|
||||
}
|
||||
}
|
||||
|
||||
pMostHzMonitor = pMonitorMostHz;
|
||||
}
|
||||
}
|
||||
|
@@ -35,6 +35,11 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_szTitle = g_pXWaylandManager->getTitle(PWINDOW);
|
||||
PWINDOW->m_fAlpha = 255.f;
|
||||
|
||||
// Foreign Toplevel
|
||||
PWINDOW->m_phForeignToplevel = wlr_foreign_toplevel_handle_v1_create(g_pCompositor->m_sWLRToplevelMgr);
|
||||
// TODO: handle foreign events (requests)
|
||||
wlr_foreign_toplevel_handle_v1_set_app_id(PWINDOW->m_phForeignToplevel, g_pXWaylandManager->getAppIDClass(PWINDOW).c_str());
|
||||
|
||||
// checks if the window wants borders and sets the appriopriate flag
|
||||
g_pXWaylandManager->checkBorders(PWINDOW);
|
||||
|
||||
@@ -62,7 +67,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && !PWINDOW->m_bIsFloating) {
|
||||
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PFULLWINDOW);
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PFULLWINDOW, FULLSCREEN_FULL);
|
||||
g_pXWaylandManager->setWindowFullscreen(PFULLWINDOW, PFULLWINDOW->m_bIsFullscreen);
|
||||
}
|
||||
|
||||
@@ -254,8 +259,14 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
// do the animation thing
|
||||
PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition.vec();
|
||||
PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize.vec();
|
||||
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.vec() + Vector2D(0.01f, 0.01f); // it has to be animated, otherwise onWindowPostCreateClose will ignore it
|
||||
|
||||
if (!PWINDOW->m_bX11DoesntWantBorders) // don't animate out if they weren't animated in.
|
||||
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.vec() + Vector2D(0.01f, 0.01f); // it has to be animated, otherwise onWindowPostCreateClose will ignore it
|
||||
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, true);
|
||||
|
||||
// Destroy Foreign Toplevel
|
||||
wlr_foreign_toplevel_handle_v1_destroy(PWINDOW->m_phForeignToplevel);
|
||||
PWINDOW->m_phForeignToplevel = nullptr;
|
||||
}
|
||||
|
||||
void Events::listener_commitWindow(void* owner, void* data) {
|
||||
@@ -303,6 +314,9 @@ void Events::listener_setTitleWindow(void* owner, void* data) {
|
||||
if (PWINDOW == g_pCompositor->m_pLastWindow) // if it's the active, let's post an event to update others
|
||||
g_pEventManager->postEvent(SHyprIPCEvent("activewindow", g_pXWaylandManager->getAppIDClass(PWINDOW) + "," + PWINDOW->m_szTitle));
|
||||
|
||||
if (PWINDOW->m_phForeignToplevel)
|
||||
wlr_foreign_toplevel_handle_v1_set_title(PWINDOW->m_phForeignToplevel, PWINDOW->m_szTitle.c_str());
|
||||
|
||||
Debug::log(LOG, "Window %x set title to %s", PWINDOW, PWINDOW->m_szTitle.c_str());
|
||||
}
|
||||
|
||||
@@ -313,9 +327,9 @@ void Events::listener_fullscreenWindow(void* owner, void* data) {
|
||||
const auto REQUESTED = &PWINDOW->m_uSurface.xdg->toplevel->requested;
|
||||
|
||||
if (REQUESTED->fullscreen != PWINDOW->m_bIsFullscreen)
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW);
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW, FULLSCREEN_FULL);
|
||||
} else {
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW);
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW, FULLSCREEN_FULL);
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Window %x fullscreen to %i", PWINDOW, PWINDOW->m_bIsFullscreen);
|
||||
|
@@ -7,9 +7,10 @@
|
||||
#include <array>
|
||||
|
||||
struct SMonitor {
|
||||
Vector2D vecPosition = Vector2D(0,0);
|
||||
Vector2D vecSize = Vector2D(0,0);
|
||||
Vector2D vecPixelSize = Vector2D(0,0);
|
||||
Vector2D vecPosition = Vector2D(0,0);
|
||||
Vector2D vecSize = Vector2D(0,0);
|
||||
Vector2D vecPixelSize = Vector2D(0,0);
|
||||
Vector2D vecTransformedSize = Vector2D(0,0);
|
||||
|
||||
bool primary = false;
|
||||
|
||||
@@ -27,6 +28,7 @@ struct SMonitor {
|
||||
float refreshRate = 60;
|
||||
wlr_output_damage* damage = nullptr;
|
||||
bool needsFrameSkip = false;
|
||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
|
||||
// Double-linked list because we need to have constant mem addresses for signals
|
||||
// We have to store pointers and use raw new/delete because they might be moved between them
|
||||
|
@@ -31,6 +31,8 @@ CWorkspace::CWorkspace(int monitorID) {
|
||||
CWorkspace::~CWorkspace() {
|
||||
m_vRenderOffset.unregister();
|
||||
|
||||
Debug::log(LOG, "Destroying workspace ID %d", m_iID);
|
||||
|
||||
if (m_pWlrHandle) {
|
||||
wlr_ext_workspace_handle_v1_set_active(m_pWlrHandle, false);
|
||||
wlr_ext_workspace_handle_v1_destroy(m_pWlrHandle);
|
||||
@@ -38,7 +40,7 @@ CWorkspace::~CWorkspace() {
|
||||
}
|
||||
}
|
||||
|
||||
void CWorkspace::startAnim(bool in, bool left) {
|
||||
void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
||||
const auto ANIMSTYLE = g_pConfigManager->getString("animations:workspaces_style");
|
||||
|
||||
if (ANIMSTYLE == "fade") {
|
||||
@@ -64,10 +66,37 @@ void CWorkspace::startAnim(bool in, bool left) {
|
||||
m_vRenderOffset = Vector2D(left ? -PMONITOR->vecSize.x : PMONITOR->vecSize.x, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (instant) {
|
||||
m_vRenderOffset.warp();
|
||||
m_fAlpha.warp();
|
||||
}
|
||||
}
|
||||
|
||||
void CWorkspace::setActive(bool on) {
|
||||
if (m_pWlrHandle) {
|
||||
wlr_ext_workspace_handle_v1_set_active(m_pWlrHandle, on);
|
||||
}
|
||||
}
|
||||
|
||||
void CWorkspace::moveToMonitor(const int& id) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(id);
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
|
||||
wlr_ext_workspace_handle_v1_set_active(m_pWlrHandle, false);
|
||||
wlr_ext_workspace_handle_v1_destroy(m_pWlrHandle);
|
||||
|
||||
m_pWlrHandle = wlr_ext_workspace_handle_v1_create(PMONITOR->pWLRWorkspaceGroupHandle);
|
||||
|
||||
// set geometry here cuz we can
|
||||
wl_array_init(&m_wlrCoordinateArr);
|
||||
*reinterpret_cast<int*>(wl_array_add(&m_wlrCoordinateArr, sizeof(int))) = (int)PMONITOR->vecPosition.x;
|
||||
*reinterpret_cast<int*>(wl_array_add(&m_wlrCoordinateArr, sizeof(int))) = (int)PMONITOR->vecPosition.y;
|
||||
wlr_ext_workspace_handle_v1_set_coordinates(m_pWlrHandle, &m_wlrCoordinateArr);
|
||||
wlr_ext_workspace_handle_v1_set_hidden(m_pWlrHandle, false);
|
||||
wlr_ext_workspace_handle_v1_set_urgent(m_pWlrHandle, false);
|
||||
|
||||
wlr_ext_workspace_handle_v1_set_name(m_pWlrHandle, m_szName.c_str());
|
||||
}
|
@@ -3,6 +3,11 @@
|
||||
#include "../defines.hpp"
|
||||
#include "AnimatedVariable.hpp"
|
||||
|
||||
enum eFullscreenMode : uint8_t {
|
||||
FULLSCREEN_FULL = 0,
|
||||
FULLSCREEN_MAXIMIZED
|
||||
};
|
||||
|
||||
class CWorkspace {
|
||||
public:
|
||||
CWorkspace(int monitorID);
|
||||
@@ -14,6 +19,7 @@ public:
|
||||
std::string m_szName = "";
|
||||
uint64_t m_iMonitorID = -1;
|
||||
bool m_bHasFullscreenWindow = false;
|
||||
eFullscreenMode m_efFullscreenMode = FULLSCREEN_FULL;
|
||||
|
||||
wlr_ext_workspace_handle_v1* m_pWlrHandle = nullptr;
|
||||
|
||||
@@ -27,6 +33,8 @@ public:
|
||||
bool m_bDefaultFloating = false;
|
||||
bool m_bDefaultPseudo = false;
|
||||
|
||||
void startAnim(bool in, bool left);
|
||||
void startAnim(bool in, bool left, bool instant = false);
|
||||
void setActive(bool on);
|
||||
|
||||
void moveToMonitor(const int&);
|
||||
};
|
@@ -34,55 +34,56 @@
|
||||
#define static
|
||||
|
||||
extern "C" {
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/backend/libinput.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_data_control_v1.h>
|
||||
#include <wlr/types/wlr_data_device.h>
|
||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||
#include <wlr/types/wlr_idle.h>
|
||||
#include <wlr/types/wlr_input_device.h>
|
||||
#include <wlr/types/wlr_keyboard.h>
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
#include <wlr/types/wlr_matrix.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_output_management_v1.h>
|
||||
#include <wlr/types/wlr_pointer.h>
|
||||
#include <wlr/types/wlr_presentation_time.h>
|
||||
#include <wlr/types/wlr_primary_selection.h>
|
||||
#include <wlr/types/wlr_primary_selection_v1.h>
|
||||
#include <wlr/types/wlr_screencopy_v1.h>
|
||||
#include <wlr/types/wlr_seat.h>
|
||||
#include <wlr/types/wlr_server_decoration.h>
|
||||
#include <wlr/types/wlr_viewporter.h>
|
||||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||
#include <wlr/types/wlr_xcursor_manager.h>
|
||||
#include <wlr/types/wlr_xdg_activation_v1.h>
|
||||
#include <wlr/types/wlr_xdg_decoration_v1.h>
|
||||
#include <wlr/types/wlr_xdg_output_v1.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/types/wlr_subcompositor.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_output_damage.h>
|
||||
#include <wlr/types/wlr_input_inhibitor.h>
|
||||
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
|
||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <wlr/xwayland.h>
|
||||
#include <wlr/util/region.h>
|
||||
#include "../wlroots/include/wlr/backend.h"
|
||||
#include "../wlroots/include/wlr/backend/libinput.h"
|
||||
#include "../wlroots/include/wlr/render/allocator.h"
|
||||
#include "../wlroots/include/wlr/render/wlr_renderer.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_compositor.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_cursor.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_data_control_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_data_device.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_export_dmabuf_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_linux_dmabuf_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_gamma_control_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_idle.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_input_device.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_keyboard.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_layer_shell_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_matrix.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_output.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_output_layout.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_output_management_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_pointer.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_presentation_time.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_primary_selection.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_primary_selection_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_screencopy_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_seat.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_server_decoration.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_viewporter.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_virtual_keyboard_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_xcursor_manager.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_xdg_activation_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_xdg_decoration_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_xdg_output_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_xdg_shell.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_subcompositor.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_scene.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_output_damage.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_input_inhibitor.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_virtual_pointer_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_foreign_toplevel_management_v1.h"
|
||||
#include "../wlroots/include/wlr/util/log.h"
|
||||
#include "../wlroots/include/wlr/xwayland.h"
|
||||
#include "../wlroots/include/wlr/util/region.h"
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include <wlr/render/egl.h>
|
||||
#include <wlr/render/gles2.h>
|
||||
#include <wlr/render/wlr_texture.h>
|
||||
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||
#include <wlr/types/wlr_relative_pointer_v1.h>
|
||||
#include "../wlroots/include/wlr/render/egl.h"
|
||||
#include "../wlroots/include/wlr/render/gles2.h"
|
||||
#include "../wlroots/include/wlr/render/wlr_texture.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_pointer_constraints_v1.h"
|
||||
#include "../wlroots/include/wlr/types/wlr_relative_pointer_v1.h"
|
||||
}
|
||||
|
||||
#undef class
|
||||
|
@@ -275,6 +275,10 @@ void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) {
|
||||
|
||||
if (OPENINGON->pGroupParent) {
|
||||
// means we opened on a group
|
||||
|
||||
// add the group deco
|
||||
pWindow->m_dWindowDecorations.emplace_back(std::make_unique<CHyprGroupBarDecoration>(pWindow));
|
||||
|
||||
PNODE->pGroupParent = OPENINGON->pGroupParent;
|
||||
PNODE->pGroupParent->groupMembers.push_back(PNODE);
|
||||
PNODE->pGroupParent->groupMemberActive = PNODE->pGroupParent->groupMembers.size() - 1;
|
||||
@@ -353,7 +357,7 @@ void CHyprDwindleLayout::recalculateMonitor(const int& monid) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
||||
|
||||
// Ignore any recalc events if we have a fullscreen window.
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow)
|
||||
if (!PWORKSPACE || PWORKSPACE->m_bHasFullscreenWindow)
|
||||
return;
|
||||
|
||||
const auto TOPNODE = getMasterNodeOnWorkspace(PMONITOR->activeWorkspace);
|
||||
@@ -616,7 +620,7 @@ void CHyprDwindleLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
||||
g_pCompositor->moveWindowToTop(pWindow);
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow) {
|
||||
void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreenMode fullscreenMode) {
|
||||
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||
return;
|
||||
|
||||
@@ -646,6 +650,8 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow) {
|
||||
} else {
|
||||
// if it now got fullscreen, make it fullscreen
|
||||
|
||||
PWORKSPACE->m_efFullscreenMode = fullscreenMode;
|
||||
|
||||
// save position and size if floating
|
||||
if (pWindow->m_bIsFloating) {
|
||||
pWindow->m_vPosition = pWindow->m_vRealPosition.vec();
|
||||
@@ -653,8 +659,22 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow) {
|
||||
}
|
||||
|
||||
// apply new pos and size being monitors' box
|
||||
pWindow->m_vRealPosition = PMONITOR->vecPosition;
|
||||
pWindow->m_vRealSize = PMONITOR->vecSize;
|
||||
if (fullscreenMode == FULLSCREEN_FULL) {
|
||||
pWindow->m_vRealPosition = PMONITOR->vecPosition;
|
||||
pWindow->m_vRealSize = PMONITOR->vecSize;
|
||||
} else {
|
||||
// This is a massive hack.
|
||||
// We make a fake "only" node and apply
|
||||
// To keep consistent with the settings without C+P code
|
||||
|
||||
SDwindleNodeData fakeNode;
|
||||
fakeNode.pWindow = pWindow;
|
||||
fakeNode.position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
|
||||
fakeNode.size = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight;
|
||||
fakeNode.workspaceID = pWindow->m_iWorkspaceID;
|
||||
|
||||
applyNodeDataToWindow(&fakeNode);
|
||||
}
|
||||
}
|
||||
|
||||
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv());
|
||||
@@ -693,6 +713,10 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
||||
for (auto& node : PGROUPPARENT->groupMembers) {
|
||||
node->pGroupParent = nullptr;
|
||||
node->pWindow->m_cRealBorderColor.setValueAndWarp(INACTIVEBORDERCOL); // no anim here because they pop in
|
||||
|
||||
for (auto& wd : node->pWindow->m_dWindowDecorations) {
|
||||
wd->updateWindow(node->pWindow);
|
||||
}
|
||||
}
|
||||
|
||||
PGROUPPARENT->groupMembers.clear();
|
||||
@@ -725,6 +749,8 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
||||
c->pGroupParent = PPARENT;
|
||||
c->pWindow->m_cRealBorderColor = GROUPINACTIVEBORDERCOL;
|
||||
|
||||
c->pWindow->m_dWindowDecorations.push_back(std::make_unique<CHyprGroupBarDecoration>(c->pWindow));
|
||||
|
||||
if (c->pWindow == g_pCompositor->m_pLastWindow)
|
||||
c->pWindow->m_cRealBorderColor = CColor(g_pConfigManager->getInt("dwindle:col.group_border_active"));
|
||||
}
|
||||
@@ -735,7 +761,32 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow) {
|
||||
std::deque<CWindow*> CHyprDwindleLayout::getGroupMembers(CWindow* pWindow) {
|
||||
|
||||
std::deque<CWindow*> result;
|
||||
|
||||
if (!g_pCompositor->windowExists(pWindow))
|
||||
return result; // reject with empty
|
||||
|
||||
// get the node
|
||||
const auto PNODE = getNodeFromWindow(pWindow);
|
||||
|
||||
if (!PNODE)
|
||||
return result; // reject with empty
|
||||
|
||||
const auto PGROUPPARENT = PNODE->pGroupParent;
|
||||
|
||||
if (!PGROUPPARENT)
|
||||
return result; // reject with empty
|
||||
|
||||
for (auto& node : PGROUPPARENT->groupMembers) {
|
||||
result.push_back(node->pWindow);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow, bool forward) {
|
||||
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||
return; // reject
|
||||
|
||||
@@ -747,13 +798,25 @@ void CHyprDwindleLayout::switchGroupWindow(CWindow* pWindow) {
|
||||
if (!PNODE->pGroupParent)
|
||||
return; // reject
|
||||
|
||||
PNODE->pGroupParent->groupMemberActive++;
|
||||
if (forward)
|
||||
PNODE->pGroupParent->groupMemberActive++;
|
||||
else
|
||||
PNODE->pGroupParent->groupMemberActive--;
|
||||
|
||||
if (PNODE->pGroupParent->groupMemberActive < 0)
|
||||
PNODE->pGroupParent->groupMemberActive = PNODE->pGroupParent->groupMembers.size() - 1;
|
||||
|
||||
if ((long unsigned int)PNODE->pGroupParent->groupMemberActive >= PNODE->pGroupParent->groupMembers.size())
|
||||
PNODE->pGroupParent->groupMemberActive = 0;
|
||||
|
||||
PNODE->pGroupParent->recalcSizePosRecursive();
|
||||
|
||||
for (auto& gm : PNODE->pGroupParent->groupMembers) {
|
||||
for (auto& deco : gm->pWindow->m_dWindowDecorations) {
|
||||
deco->updateWindow(gm->pWindow);
|
||||
}
|
||||
}
|
||||
|
||||
// focus
|
||||
g_pCompositor->focusWindow(PNODE->pGroupParent->groupMembers[PNODE->pGroupParent->groupMemberActive]->pWindow);
|
||||
}
|
||||
@@ -844,13 +907,21 @@ void CHyprDwindleLayout::alterSplitRatioBy(CWindow* pWindow, float ratio) {
|
||||
PNODE->pParent->recalcSizePosRecursive();
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::layoutMessage(SLayoutMessageHeader header, std::string message) {
|
||||
std::any CHyprDwindleLayout::layoutMessage(SLayoutMessageHeader header, std::string message) {
|
||||
if (message == "togglegroup")
|
||||
toggleWindowGroup(header.pWindow);
|
||||
else if (message == "changegroupactive")
|
||||
switchGroupWindow(header.pWindow);
|
||||
else if (message == "changegroupactivef")
|
||||
switchGroupWindow(header.pWindow, true);
|
||||
else if (message == "changegroupactiveb")
|
||||
switchGroupWindow(header.pWindow, false);
|
||||
else if (message == "togglesplit")
|
||||
toggleSplit(header.pWindow);
|
||||
else if (message == "groupinfo") {
|
||||
auto res = getGroupMembers(g_pCompositor->m_pLastWindow);
|
||||
return res;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::toggleSplit(CWindow* pWindow) {
|
||||
@@ -862,4 +933,8 @@ void CHyprDwindleLayout::toggleSplit(CWindow* pWindow) {
|
||||
PNODE->pParent->splitTop = !PNODE->pParent->splitTop;
|
||||
|
||||
PNODE->pParent->recalcSizePosRecursive();
|
||||
}
|
||||
|
||||
std::string CHyprDwindleLayout::getLayoutName() {
|
||||
return "dwindle";
|
||||
}
|
@@ -3,8 +3,10 @@
|
||||
#include "IHyprLayout.hpp"
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include "../render/decorations/CHyprGroupBarDecoration.hpp"
|
||||
|
||||
class CHyprDwindleLayout;
|
||||
enum eFullscreenMode : uint8_t;
|
||||
|
||||
struct SDwindleNodeData {
|
||||
SDwindleNodeData* pParent = nullptr;
|
||||
@@ -49,11 +51,12 @@ public:
|
||||
virtual void onEndDragWindow();
|
||||
virtual void onMouseMove(const Vector2D&);
|
||||
virtual void onWindowCreatedFloating(CWindow*);
|
||||
virtual void fullscreenRequestForWindow(CWindow*);
|
||||
virtual void layoutMessage(SLayoutMessageHeader, std::string);
|
||||
virtual void fullscreenRequestForWindow(CWindow*, eFullscreenMode);
|
||||
virtual std::any layoutMessage(SLayoutMessageHeader, std::string);
|
||||
virtual SWindowRenderLayoutHints requestRenderHints(CWindow*);
|
||||
virtual void switchWindows(CWindow*, CWindow*);
|
||||
virtual void alterSplitRatioBy(CWindow*, float);
|
||||
virtual std::string getLayoutName();
|
||||
|
||||
private:
|
||||
|
||||
@@ -71,8 +74,9 @@ public:
|
||||
SDwindleNodeData* getMasterNodeOnWorkspace(const int&);
|
||||
|
||||
void toggleWindowGroup(CWindow*);
|
||||
void switchGroupWindow(CWindow*);
|
||||
void switchGroupWindow(CWindow*, bool forward);
|
||||
void toggleSplit(CWindow*);
|
||||
std::deque<CWindow*> getGroupMembers(CWindow*);
|
||||
|
||||
friend struct SDwindleNodeData;
|
||||
};
|
@@ -12,6 +12,8 @@ struct SLayoutMessageHeader {
|
||||
CWindow* pWindow = nullptr;
|
||||
};
|
||||
|
||||
enum eFullscreenMode : uint8_t;
|
||||
|
||||
interface IHyprLayout {
|
||||
public:
|
||||
|
||||
@@ -66,17 +68,18 @@ public:
|
||||
virtual void onWindowCreatedFloating(CWindow*) = 0;
|
||||
|
||||
/*
|
||||
Called when a window requests to toggle its' fullscreen state.
|
||||
Called when a window / the user requests to toggle the fullscreen state of a window
|
||||
The layout sets all the fullscreen flags.
|
||||
It can either accept or ignore.
|
||||
*/
|
||||
virtual void fullscreenRequestForWindow(CWindow*) = 0;
|
||||
virtual void fullscreenRequestForWindow(CWindow*, eFullscreenMode) = 0;
|
||||
|
||||
/*
|
||||
Called when a dispatcher requests a custom message
|
||||
The layout is free to ignore.
|
||||
The layout is free to ignore.
|
||||
std::any is the reply. Can be empty.
|
||||
*/
|
||||
virtual void layoutMessage(SLayoutMessageHeader, std::string) = 0;
|
||||
virtual std::any layoutMessage(SLayoutMessageHeader, std::string) = 0;
|
||||
|
||||
/*
|
||||
Required to be handled, but may return just SWindowRenderLayoutHints()
|
||||
@@ -96,4 +99,9 @@ public:
|
||||
on a window
|
||||
*/
|
||||
virtual void alterSplitRatioBy(CWindow*, float) = 0;
|
||||
|
||||
/*
|
||||
Called when something wants the current layout's name
|
||||
*/
|
||||
virtual std::string getLayoutName() = 0;
|
||||
};
|
@@ -140,8 +140,12 @@ void CAnimationManager::tick() {
|
||||
case AVARDAMAGE_ENTIRE: {
|
||||
g_pHyprRenderer->damageBox(&WLRBOXPREV);
|
||||
|
||||
if (PWINDOW)
|
||||
if (PWINDOW) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
for (auto& wd : PWINDOW->m_dWindowDecorations) {
|
||||
wd->updateWindow(PWINDOW);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AVARDAMAGE_BORDER: {
|
||||
|
@@ -221,7 +221,6 @@ void CInputManager::onMouseButton(wlr_pointer_button_event* e) {
|
||||
// notify app if we didnt handle it
|
||||
if (g_pCompositor->doesSeatAcceptInput(g_pCompositor->m_pLastFocus)) {
|
||||
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, e->time_msec, e->button, e->state);
|
||||
Debug::log(LOG, "Seat notified of button %i (state %i) on surface %x", e->button, e->state, g_pCompositor->m_pLastFocus);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -360,8 +359,6 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
|
||||
|
||||
bool found = false;
|
||||
if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
Debug::log(LOG, "Pressed key %i, with the MODMASK being %i", e->keycode, MODS);
|
||||
|
||||
for (int i = 0; i < syms; ++i)
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, keysyms[i]) || found;
|
||||
} else if (e->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
|
||||
|
@@ -20,6 +20,9 @@ CKeybindManager::CKeybindManager() {
|
||||
m_mDispatchers["focusmonitor"] = focusMonitor;
|
||||
m_mDispatchers["movecursortocorner"] = moveCursorToCorner;
|
||||
m_mDispatchers["workspaceopt"] = workspaceOpt;
|
||||
m_mDispatchers["exit"] = exitHyprland;
|
||||
m_mDispatchers["movecurrentworkspacetomonitor"] = moveCurrentWorkspaceToMonitor;
|
||||
m_mDispatchers["moveworkspacetomonitor"] = moveWorkspaceToMonitor;
|
||||
}
|
||||
|
||||
void CKeybindManager::addKeybind(SKeybind kb) {
|
||||
@@ -88,6 +91,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);
|
||||
DISPATCHER->second(k.arg);
|
||||
}
|
||||
|
||||
@@ -230,6 +234,9 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
g_pCompositor->deactivateAllWLRWorkspaces(PWORKSPACETOCHANGETO->m_pWlrHandle);
|
||||
PWORKSPACETOCHANGETO->setActive(true);
|
||||
|
||||
// recalc layout
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PWORKSPACETOCHANGETO->m_iMonitorID);
|
||||
|
||||
Debug::log(LOG, "Changed to workspace %i", workspaceToChangeTo);
|
||||
|
||||
// focus
|
||||
@@ -250,7 +257,8 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
const auto ANIMTOLEFT = workspaceToChangeTo > OLDWORKSPACE;
|
||||
|
||||
// start anim on old workspace
|
||||
g_pCompositor->getWorkspaceByID(OLDWORKSPACE)->startAnim(false, ANIMTOLEFT);
|
||||
if (const auto POLDWORKSPACE = g_pCompositor->getWorkspaceByID(OLDWORKSPACE); POLDWORKSPACE)
|
||||
POLDWORKSPACE->startAnim(false, ANIMTOLEFT);
|
||||
|
||||
g_pCompositor->m_lWorkspaces.emplace_back(PMONITOR->ID);
|
||||
const auto PWORKSPACE = &g_pCompositor->m_lWorkspaces.back();
|
||||
@@ -294,9 +302,9 @@ void CKeybindManager::fullscreenActive(std::string args) {
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
return;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW);
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW, args == "1" ? eFullscreenMode::FULLSCREEN_MAXIMIZED : eFullscreenMode::FULLSCREEN_FULL);
|
||||
|
||||
g_pXWaylandManager->setWindowFullscreen(PWINDOW, PWINDOW->m_bIsFullscreen);
|
||||
g_pXWaylandManager->setWindowFullscreen(PWINDOW, PWINDOW->m_bIsFullscreen && args == "0");
|
||||
|
||||
// make all windows on the same workspace under the fullscreen window
|
||||
for (auto& w : g_pCompositor->m_lWindows) {
|
||||
@@ -316,15 +324,23 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
||||
const auto OLDWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
|
||||
|
||||
// hack
|
||||
std::string unusedName;
|
||||
const auto WORKSPACEID = getWorkspaceIDFromString(args, unusedName);
|
||||
|
||||
g_pKeybindManager->changeworkspace(args);
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByString(args);
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
||||
|
||||
if (PWORKSPACE == OLDWORKSPACE) {
|
||||
Debug::log(LOG, "Not moving to workspace because it didn't change.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PWORKSPACE) {
|
||||
Debug::log(ERR, "Workspace null in moveActiveToWorkspace?");
|
||||
return;
|
||||
}
|
||||
|
||||
OLDWORKSPACE->m_bHasFullscreenWindow = false;
|
||||
|
||||
PWINDOW->m_iWorkspaceID = PWORKSPACE->m_iID;
|
||||
@@ -503,7 +519,10 @@ void CKeybindManager::toggleGroup(std::string args) {
|
||||
void CKeybindManager::changeGroupActive(std::string args) {
|
||||
SLayoutMessageHeader header;
|
||||
header.pWindow = g_pCompositor->m_pLastWindow;
|
||||
g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "changegroupactive");
|
||||
if (args == "b")
|
||||
g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "changegroupactiveb");
|
||||
else
|
||||
g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "changegroupactivef");
|
||||
}
|
||||
|
||||
void CKeybindManager::toggleSplit(std::string args) {
|
||||
@@ -671,4 +690,61 @@ void CKeybindManager::workspaceOpt(std::string args) {
|
||||
|
||||
// recalc mon
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID);
|
||||
}
|
||||
|
||||
void CKeybindManager::exitHyprland(std::string argz) {
|
||||
g_pCompositor->cleanupExit();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
|
||||
if (!isNumber(args) && !isDirection(args)) {
|
||||
Debug::log(ERR, "moveCurrentWorkspaceToMonitor arg not a number or direction!");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PMONITOR = isDirection(args) ? g_pCompositor->getMonitorInDirection(args[0]) : g_pCompositor->getMonitorFromID(std::stoi(args));
|
||||
|
||||
if (!PMONITOR) {
|
||||
Debug::log(ERR, "Ignoring moveCurrentWorkspaceToMonitor: monitor doesnt exist");
|
||||
return;
|
||||
}
|
||||
|
||||
// get the current workspace
|
||||
const auto PCURRENTWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
|
||||
if (!PCURRENTWORKSPACE)
|
||||
return;
|
||||
|
||||
g_pCompositor->moveWorkspaceToMonitor(PCURRENTWORKSPACE, PMONITOR);
|
||||
}
|
||||
|
||||
void CKeybindManager::moveWorkspaceToMonitor(std::string args) {
|
||||
|
||||
std::string workspace = args.substr(0, args.find_first_of(' '));
|
||||
std::string monitor = args.substr(args.find_first_of(' ') + 1);
|
||||
|
||||
if (!isNumber(monitor) && !isDirection(monitor)) {
|
||||
Debug::log(ERR, "moveWorkspaceToMonitor monitor arg not a number or direction!");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PMONITOR = isDirection(monitor) ? g_pCompositor->getMonitorInDirection(monitor[0]) : g_pCompositor->getMonitorFromID(std::stoi(monitor));
|
||||
|
||||
if (!PMONITOR){
|
||||
Debug::log(ERR, "Ignoring moveWorkspaceToMonitor: monitor doesnt exist");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string workspaceName;
|
||||
const int WORKSPACEID = getWorkspaceIDFromString(workspace, workspaceName);
|
||||
|
||||
if (WORKSPACEID == INT_MAX) {
|
||||
Debug::log(ERR, "moveWorkspaceToMonitor invalid workspace!");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
||||
|
||||
g_pCompositor->moveWorkspaceToMonitor(PWORKSPACE, PMONITOR);
|
||||
}
|
@@ -50,6 +50,11 @@ private:
|
||||
static void toggleSplit(std::string);
|
||||
static void moveCursorToCorner(std::string);
|
||||
static void workspaceOpt(std::string);
|
||||
static void exitHyprland(std::string);
|
||||
static void moveCurrentWorkspaceToMonitor(std::string);
|
||||
static void moveWorkspaceToMonitor(std::string);
|
||||
|
||||
friend class CCompositor;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CKeybindManager> g_pKeybindManager;
|
@@ -126,7 +126,7 @@ void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, const Vector2D& size)
|
||||
const auto XDELTA = pWindow->m_uSurface.xdg->surface->current.width - pWindow->m_uSurface.xdg->current.geometry.width;
|
||||
const auto YDELTA = pWindow->m_uSurface.xdg->surface->current.height - pWindow->m_uSurface.xdg->current.geometry.height;
|
||||
|
||||
wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x - XDELTA, size.y - YDELTA * 2);
|
||||
wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x - XDELTA, size.y - YDELTA);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,5 +222,8 @@ void CHyprXWaylandManager::setWindowFullscreen(CWindow* pWindow, bool fullscreen
|
||||
wlr_xdg_toplevel_set_fullscreen(pWindow->m_uSurface.xdg->toplevel, 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)));
|
||||
}
|
@@ -166,13 +166,17 @@ void CHyprOpenGLImpl::end() {
|
||||
// end the render, copy the data to the WLR framebuffer
|
||||
if (!m_bFakeFrame) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_iWLROutputFb);
|
||||
wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y};
|
||||
wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
|
||||
pixman_region32_copy(m_RenderData.pDamage, &m_rOriginalDamageRegion);
|
||||
|
||||
clear(CColor(11, 11, 11, 255));
|
||||
|
||||
m_bEndFrame = true;
|
||||
|
||||
renderTexture(m_mMonitorRenderResources[m_RenderData.pMonitor].primaryFB.m_cTex, &monbox, 255.f, 0);
|
||||
|
||||
m_bEndFrame = false;
|
||||
}
|
||||
|
||||
// reset our data
|
||||
@@ -205,7 +209,15 @@ void CHyprOpenGLImpl::scissor(const wlr_box* pBox) {
|
||||
return;
|
||||
}
|
||||
|
||||
glScissor(pBox->x, pBox->y, pBox->width, pBox->height);
|
||||
wlr_box newBox = *pBox;
|
||||
|
||||
int w, h;
|
||||
wlr_output_transformed_resolution(m_RenderData.pMonitor->output, &w, &h);
|
||||
|
||||
const auto TR = wlr_output_transform_invert(m_RenderData.pMonitor->transform);
|
||||
wlr_box_transform(&newBox, &newBox, TR, w, h);
|
||||
|
||||
glScissor(newBox.x, newBox.y, newBox.width, newBox.height);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
@@ -217,8 +229,9 @@ void CHyprOpenGLImpl::scissor(const pixman_box32* pBox) {
|
||||
return;
|
||||
}
|
||||
|
||||
glScissor(pBox->x1, pBox->y1, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
wlr_box newBox = {pBox->x1, pBox->y1, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1};
|
||||
|
||||
scissor(&newBox);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h) {
|
||||
@@ -231,7 +244,7 @@ void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!");
|
||||
|
||||
float matrix[9];
|
||||
wlr_matrix_project_box(matrix, box, WL_OUTPUT_TRANSFORM_NORMAL, 0, m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here
|
||||
wlr_matrix_project_box(matrix, box, wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0, m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
@@ -296,7 +309,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
||||
|
||||
// get transform
|
||||
const auto TRANSFORM = wlr_output_transform_invert(WL_OUTPUT_TRANSFORM_NORMAL);
|
||||
const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform);
|
||||
float matrix[9];
|
||||
wlr_matrix_project_box(matrix, pBox, TRANSFORM, 0, m_RenderData.pMonitor->output->transform_matrix);
|
||||
|
||||
@@ -534,7 +547,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
||||
pixman_region32_t inverseOpaque;
|
||||
pixman_region32_init(&inverseOpaque);
|
||||
if (a == 255.f) {
|
||||
pixman_box32_t monbox = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y};
|
||||
pixman_box32_t monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
pixman_region32_copy(&inverseOpaque, &pSurface->current.opaque);
|
||||
pixman_region32_translate(&inverseOpaque, pBox->x, pBox->y);
|
||||
pixman_region32_inverse(&inverseOpaque, &inverseOpaque, &monbox);
|
||||
@@ -572,7 +585,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
|
||||
// stencil done. Render everything.
|
||||
wlr_box MONITORBOX = {0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y};
|
||||
wlr_box MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
if (pixman_region32_not_empty(&damage)) {
|
||||
// render our great blurred FB
|
||||
renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, g_pConfigManager->getInt("decoration:blur_ignore_opacity") ? 255.f : a, &damage);
|
||||
@@ -817,10 +830,10 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||
// get the adequate tex
|
||||
std::string texPath = "/usr/share/hyprland/wall_";
|
||||
Vector2D textureSize;
|
||||
if (pMonitor->vecSize.x > 7000) {
|
||||
if (pMonitor->vecTransformedSize.x > 7000) {
|
||||
textureSize = Vector2D(7680, 4320);
|
||||
texPath += "8K.png";
|
||||
} else if (pMonitor->vecSize.x > 3000) {
|
||||
} else if (pMonitor->vecTransformedSize.x > 3000) {
|
||||
textureSize = Vector2D(3840, 2160);
|
||||
texPath += "4K.png";
|
||||
} else {
|
||||
@@ -853,7 +866,7 @@ 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->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y};
|
||||
wlr_box box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
|
||||
renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0);
|
||||
}
|
||||
|
@@ -92,6 +92,7 @@ private:
|
||||
std::string m_szExtensions;
|
||||
|
||||
bool m_bFakeFrame = false;
|
||||
bool m_bEndFrame = false;
|
||||
|
||||
// Shaders
|
||||
SQuad m_shQUAD;
|
||||
|
@@ -32,7 +32,7 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
}
|
||||
|
||||
bool shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) {
|
||||
wlr_box geometry = {pWindow->m_vRealPosition.vec().x, pWindow->m_vRealPosition.vec().y, pWindow->m_vRealSize.vec().x, pWindow->m_vRealSize.vec().y};
|
||||
wlr_box geometry = pWindow->getFullWindowBoundingBox();
|
||||
|
||||
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, &geometry))
|
||||
return false;
|
||||
@@ -57,7 +57,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
|
||||
continue;
|
||||
|
||||
// found it!
|
||||
renderWindow(&w, pMonitor, time, false);
|
||||
renderWindow(&w, pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL);
|
||||
|
||||
pWorkspaceWindow = &w;
|
||||
}
|
||||
@@ -71,6 +71,13 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
|
||||
}
|
||||
|
||||
// and the overlay layers
|
||||
if (pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL) {
|
||||
// on non-full we draw the bar and shit
|
||||
for (auto& ls : pMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
renderLayer(ls, pMonitor, time);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& ls : pMonitor->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) {
|
||||
renderLayer(ls, pMonitor, time);
|
||||
}
|
||||
@@ -98,7 +105,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
||||
renderdata.surface = g_pXWaylandManager->getWindowSurface(pWindow);
|
||||
renderdata.w = std::clamp(pWindow->m_vRealSize.vec().x, (double)5, (double)1337420); // clamp the size to min 5,
|
||||
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;
|
||||
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.decorate = decorate && !pWindow->m_bX11DoesntWantBorders;
|
||||
@@ -109,6 +116,10 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
||||
|
||||
g_pHyprOpenGL->m_pCurrentWindow = pWindow;
|
||||
|
||||
// render window decorations first
|
||||
for (auto& wd : pWindow->m_dWindowDecorations)
|
||||
wd->draw(pMonitor);
|
||||
|
||||
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
|
||||
|
||||
if (pWindow->m_bIsX11) {
|
||||
@@ -548,7 +559,7 @@ void CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
Debug::log(LOG, "Applying monitor rule for %s", pMonitor->szName.c_str());
|
||||
|
||||
// Check if the rule isn't already applied
|
||||
if (!force && DELTALESSTHAN(pMonitor->vecPixelSize.x, pMonitorRule->resolution.x, 1) && DELTALESSTHAN(pMonitor->vecPixelSize.y, pMonitorRule->resolution.y, 1) && DELTALESSTHAN(pMonitor->refreshRate, pMonitorRule->refreshRate, 1) && pMonitor->scale == pMonitorRule->scale && DELTALESSTHAN(pMonitor->vecPosition.x, pMonitorRule->offset.x, 1) && DELTALESSTHAN(pMonitor->vecPosition.y, pMonitorRule->offset.y, 1)) {
|
||||
if (!force && DELTALESSTHAN(pMonitor->vecPixelSize.x, pMonitorRule->resolution.x, 1) && DELTALESSTHAN(pMonitor->vecPixelSize.y, pMonitorRule->resolution.y, 1) && DELTALESSTHAN(pMonitor->refreshRate, pMonitorRule->refreshRate, 1) && pMonitor->scale == pMonitorRule->scale && DELTALESSTHAN(pMonitor->vecPosition.x, pMonitorRule->offset.x, 1) && DELTALESSTHAN(pMonitor->vecPosition.y, pMonitorRule->offset.y, 1) && pMonitor->transform == pMonitorRule->transform) {
|
||||
Debug::log(LOG, "Not applying a new rule to %s because it's already applied!", pMonitor->szName.c_str());
|
||||
return;
|
||||
}
|
||||
@@ -612,8 +623,10 @@ void CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
pMonitor->vecSize = pMonitorRule->resolution;
|
||||
}
|
||||
|
||||
wlr_output_set_transform(pMonitor->output, pMonitorRule->transform);
|
||||
pMonitor->transform = pMonitorRule->transform;
|
||||
|
||||
pMonitor->vecPixelSize = pMonitor->vecSize;
|
||||
pMonitor->vecSize = (pMonitor->vecSize / pMonitor->scale).floor();
|
||||
|
||||
// update renderer
|
||||
g_pHyprOpenGL->destroyMonitorResources(pMonitor);
|
||||
@@ -623,6 +636,11 @@ void CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||
return;
|
||||
}
|
||||
|
||||
int x, y;
|
||||
wlr_output_transformed_resolution(pMonitor->output, &x, &y);
|
||||
pMonitor->vecSize = (Vector2D(x, y) / pMonitor->scale).floor();
|
||||
pMonitor->vecTransformedSize = Vector2D(x,y);
|
||||
|
||||
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, pMonitor->output, (int)pMonitorRule->offset.x, (int)pMonitorRule->offset.y);
|
||||
|
||||
//wlr_output_damage_add_whole(pMonitor->damage);
|
||||
|
95
src/render/decorations/CHyprGroupBarDecoration.cpp
Normal file
95
src/render/decorations/CHyprGroupBarDecoration.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include "CHyprGroupBarDecoration.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
CHyprGroupBarDecoration::CHyprGroupBarDecoration(CWindow* pWindow) {
|
||||
m_pWindow = pWindow;
|
||||
updateWindow(pWindow);
|
||||
}
|
||||
|
||||
CHyprGroupBarDecoration::~CHyprGroupBarDecoration() {
|
||||
|
||||
}
|
||||
|
||||
SWindowDecorationExtents CHyprGroupBarDecoration::getWindowDecorationExtents() {
|
||||
return m_seExtents;
|
||||
}
|
||||
|
||||
eDecorationType CHyprGroupBarDecoration::getDecorationType() {
|
||||
return DECORATION_GROUPBAR;
|
||||
}
|
||||
|
||||
void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
|
||||
damageEntire();
|
||||
|
||||
if (pWindow->m_vRealPosition.vec() != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
|
||||
// we draw 3px above the window's border with 3px
|
||||
const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size");
|
||||
|
||||
m_seExtents.topLeft = Vector2D(0, BORDERSIZE + 3 + 3);
|
||||
m_seExtents.bottomRight = Vector2D();
|
||||
|
||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec();
|
||||
m_vLastWindowSize = pWindow->m_vRealSize.vec();
|
||||
}
|
||||
|
||||
// let's check if the window group is different.
|
||||
|
||||
if (g_pLayoutManager->getCurrentLayout()->getLayoutName() != "dwindle") {
|
||||
// ????
|
||||
for (auto it = pWindow->m_dWindowDecorations.begin(); it != pWindow->m_dWindowDecorations.end(); it++) {
|
||||
if (it->get() == this) {
|
||||
pWindow->m_dWindowDecorations.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get the group info
|
||||
SLayoutMessageHeader header;
|
||||
header.pWindow = g_pCompositor->m_pLastWindow;
|
||||
|
||||
m_dwGroupMembers = std::any_cast<std::deque<CWindow*>>(g_pLayoutManager->getCurrentLayout()->layoutMessage(header, "groupinfo"));
|
||||
|
||||
damageEntire();
|
||||
|
||||
if (m_dwGroupMembers.size() == 0) {
|
||||
// remove
|
||||
for (auto it = pWindow->m_dWindowDecorations.begin(); it != pWindow->m_dWindowDecorations.end(); it++) {
|
||||
if (it->get() == this) {
|
||||
pWindow->m_dWindowDecorations.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprGroupBarDecoration::damageEntire() {
|
||||
wlr_box dm = {m_vLastWindowPos.x - m_seExtents.topLeft.x, m_vLastWindowPos.y - m_seExtents.topLeft.y, m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x, m_seExtents.topLeft.y};
|
||||
g_pHyprRenderer->damageBox(&dm);
|
||||
}
|
||||
|
||||
void CHyprGroupBarDecoration::draw(SMonitor* pMonitor) {
|
||||
// get how many bars we will draw
|
||||
int barsToDraw = m_dwGroupMembers.size();
|
||||
|
||||
if (barsToDraw < 1 || m_pWindow->m_bHidden || !g_pCompositor->windowValidMapped(m_pWindow))
|
||||
return;
|
||||
|
||||
const int PAD = 2; //2px
|
||||
|
||||
const int BARW = (m_vLastWindowSize.x - PAD * (barsToDraw - 1)) / barsToDraw;
|
||||
|
||||
int xoff = 0;
|
||||
|
||||
for (int i = 0; i < barsToDraw; ++i) {
|
||||
wlr_box rect = {m_vLastWindowPos.x + xoff - pMonitor->vecPosition.x, m_vLastWindowPos.y - m_seExtents.topLeft.y - pMonitor->vecPosition.y, BARW, 3};
|
||||
|
||||
if (rect.width <= 0 || rect.height <= 0)
|
||||
break;
|
||||
|
||||
CColor color = m_dwGroupMembers[i] == g_pCompositor->m_pLastWindow ? CColor(g_pConfigManager->getInt("dwindle:col.group_border_active")) : CColor(g_pConfigManager->getInt("dwindle:col.group_border"));
|
||||
g_pHyprOpenGL->renderRect(&rect, color);
|
||||
|
||||
xoff += PAD + BARW;
|
||||
}
|
||||
}
|
30
src/render/decorations/CHyprGroupBarDecoration.hpp
Normal file
30
src/render/decorations/CHyprGroupBarDecoration.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "IHyprWindowDecoration.hpp"
|
||||
#include <deque>
|
||||
|
||||
class CHyprGroupBarDecoration : public IHyprWindowDecoration {
|
||||
public:
|
||||
CHyprGroupBarDecoration(CWindow*);
|
||||
virtual ~CHyprGroupBarDecoration();
|
||||
|
||||
virtual SWindowDecorationExtents getWindowDecorationExtents();
|
||||
|
||||
virtual void draw(SMonitor*);
|
||||
|
||||
virtual eDecorationType getDecorationType();
|
||||
|
||||
virtual void updateWindow(CWindow*);
|
||||
|
||||
virtual void damageEntire();
|
||||
|
||||
private:
|
||||
SWindowDecorationExtents m_seExtents;
|
||||
|
||||
CWindow* m_pWindow = nullptr;
|
||||
|
||||
Vector2D m_vLastWindowPos;
|
||||
Vector2D m_vLastWindowSize;
|
||||
|
||||
std::deque<CWindow*> m_dwGroupMembers;
|
||||
};
|
7
src/render/decorations/IHyprWindowDecoration.cpp
Normal file
7
src/render/decorations/IHyprWindowDecoration.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "IHyprWindowDecoration.hpp"
|
||||
|
||||
#include "../../Window.hpp"
|
||||
|
||||
IHyprWindowDecoration::~IHyprWindowDecoration() {
|
||||
|
||||
}
|
31
src/render/decorations/IHyprWindowDecoration.hpp
Normal file
31
src/render/decorations/IHyprWindowDecoration.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../defines.hpp"
|
||||
|
||||
enum eDecorationType {
|
||||
DECORATION_NONE = -1,
|
||||
DECORATION_GROUPBAR
|
||||
};
|
||||
|
||||
struct SWindowDecorationExtents {
|
||||
Vector2D topLeft;
|
||||
Vector2D bottomRight;
|
||||
};
|
||||
|
||||
class CWindow;
|
||||
struct SMonitor;
|
||||
|
||||
class IHyprWindowDecoration {
|
||||
public:
|
||||
virtual ~IHyprWindowDecoration() = 0;
|
||||
|
||||
virtual SWindowDecorationExtents getWindowDecorationExtents() = 0;
|
||||
|
||||
virtual void draw(SMonitor*) = 0;
|
||||
|
||||
virtual eDecorationType getDecorationType() = 0;
|
||||
|
||||
virtual void updateWindow(CWindow*) = 0;
|
||||
|
||||
virtual void damageEntire() = 0;
|
||||
};
|
1
wlroots
Submodule
1
wlroots
Submodule
Submodule wlroots added at 75d31509db
Reference in New Issue
Block a user