mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-24 22:45:59 +01:00
Merge branch 'hyprwm:main' into main
This commit is contained in:
commit
e6543c5ca2
20 changed files with 214 additions and 418 deletions
27
.github/workflows/stale.yml
vendored
Normal file
27
.github/workflows/stale.yml
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
|
||||||
|
#
|
||||||
|
# You can adjust the behavior by modifying this file.
|
||||||
|
# For more information, see:
|
||||||
|
# https://github.com/actions/stale
|
||||||
|
name: Mark stale issues and pull requests
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '7 */4 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v5
|
||||||
|
with:
|
||||||
|
repo-token: ${{ secrets.STALEBOT_PAT }}
|
||||||
|
stale-issue-label: 'stale'
|
||||||
|
stale-pr-label: 'stale'
|
||||||
|
operations-per-run: 40
|
|
@ -57,7 +57,7 @@ ExternalProject_Add(
|
||||||
wlroots
|
wlroots
|
||||||
PREFIX ${CMAKE_SOURCE_DIR}/subprojects/wlroots
|
PREFIX ${CMAKE_SOURCE_DIR}/subprojects/wlroots
|
||||||
SOURCE_DIR ${CMAKE_SOURCE_DIR}/subprojects/wlroots
|
SOURCE_DIR ${CMAKE_SOURCE_DIR}/subprojects/wlroots
|
||||||
PATCH_COMMAND sed -E -i -e "s/(soversion = 13)([^032]|$$)/soversion = 13032/g" meson.build
|
PATCH_COMMAND sed -E -i -e "s/(soversion = .*$)/soversion = 13032/g" meson.build
|
||||||
CONFIGURE_COMMAND meson setup build --buildtype=${BUILDTYPE_LOWER} -Dwerror=false -Dexamples=false -Drenderers=gles2 $<IF:$<BOOL:${WITH_ASAN}>,-Db_sanitize=address,-Db_sanitize=none> && meson setup build --buildtype=${BUILDTYPE_LOWER} -Dwerror=false -Dexamples=false -Drenderers=gles2 $<IF:$<BOOL:${WITH_ASAN}>,-Db_sanitize=address,-Db_sanitize=none> --reconfigure
|
CONFIGURE_COMMAND meson setup build --buildtype=${BUILDTYPE_LOWER} -Dwerror=false -Dexamples=false -Drenderers=gles2 $<IF:$<BOOL:${WITH_ASAN}>,-Db_sanitize=address,-Db_sanitize=none> && meson setup build --buildtype=${BUILDTYPE_LOWER} -Dwerror=false -Dexamples=false -Drenderers=gles2 $<IF:$<BOOL:${WITH_ASAN}>,-Db_sanitize=address,-Db_sanitize=none> --reconfigure
|
||||||
BUILD_COMMAND ninja -C build
|
BUILD_COMMAND ninja -C build
|
||||||
BUILD_ALWAYS true
|
BUILD_ALWAYS true
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
# compile with HYPRLAND_HEADERS=<path_to_hl> make all
|
|
||||||
# make sure that the path above is to the root hl repo directory, NOT src/
|
|
||||||
# and that you have ran `make protocols` in the hl dir.
|
|
||||||
|
|
||||||
all:
|
|
||||||
$(CXX) -shared -fPIC --no-gnu-unique main.cpp customLayout.cpp customDecoration.cpp -o examplePlugin.so -g `pkg-config --cflags pixman-1 libdrm hyprland` -std=c++2b
|
|
||||||
clean:
|
|
||||||
rm ./examplePlugin.so
|
|
|
@ -1,74 +0,0 @@
|
||||||
#include "customDecoration.hpp"
|
|
||||||
#include <hyprland/src/Window.hpp>
|
|
||||||
#include <hyprland/src/Compositor.hpp>
|
|
||||||
#include "globals.hpp"
|
|
||||||
|
|
||||||
CCustomDecoration::CCustomDecoration(CWindow* pWindow) {
|
|
||||||
m_pWindow = pWindow;
|
|
||||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec();
|
|
||||||
m_vLastWindowSize = pWindow->m_vRealSize.vec();
|
|
||||||
}
|
|
||||||
|
|
||||||
CCustomDecoration::~CCustomDecoration() {
|
|
||||||
damageEntire();
|
|
||||||
}
|
|
||||||
|
|
||||||
SWindowDecorationExtents CCustomDecoration::getWindowDecorationExtents() {
|
|
||||||
return m_seExtents;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCustomDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& offset) {
|
|
||||||
if (!g_pCompositor->windowValidMapped(m_pWindow))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m_pWindow->m_sSpecialRenderData.decorate)
|
|
||||||
return;
|
|
||||||
|
|
||||||
static auto* const PCOLOR = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:example:border_color")->intValue;
|
|
||||||
static auto* const PROUNDING = &HyprlandAPI::getConfigValue(PHANDLE, "decoration:rounding")->intValue;
|
|
||||||
static auto* const PBORDERSIZE = &HyprlandAPI::getConfigValue(PHANDLE, "general:border_size")->intValue;
|
|
||||||
|
|
||||||
const auto ROUNDING = !m_pWindow->m_sSpecialRenderData.rounding ?
|
|
||||||
0 :
|
|
||||||
(m_pWindow->m_sAdditionalConfigData.rounding.toUnderlying() == -1 ? *PROUNDING : m_pWindow->m_sAdditionalConfigData.rounding.toUnderlying());
|
|
||||||
|
|
||||||
// draw the border
|
|
||||||
CBox fullBox = {(int)(m_vLastWindowPos.x - *PBORDERSIZE), (int)(m_vLastWindowPos.y - *PBORDERSIZE), (int)(m_vLastWindowSize.x + 2.0 * *PBORDERSIZE),
|
|
||||||
(int)(m_vLastWindowSize.y + 2.0 * *PBORDERSIZE)};
|
|
||||||
|
|
||||||
fullBox.x -= pMonitor->vecPosition.x;
|
|
||||||
fullBox.y -= pMonitor->vecPosition.y;
|
|
||||||
|
|
||||||
m_seExtents = {{m_vLastWindowPos.x - fullBox.x - pMonitor->vecPosition.x + 2, m_vLastWindowPos.y - fullBox.y - pMonitor->vecPosition.y + 2},
|
|
||||||
{fullBox.x + fullBox.width + pMonitor->vecPosition.x - m_vLastWindowPos.x - m_vLastWindowSize.x + 2,
|
|
||||||
fullBox.y + fullBox.height + pMonitor->vecPosition.y - m_vLastWindowPos.y - m_vLastWindowSize.y + 2}};
|
|
||||||
|
|
||||||
fullBox.x += offset.x;
|
|
||||||
fullBox.y += offset.y;
|
|
||||||
|
|
||||||
if (fullBox.width < 1 || fullBox.height < 1)
|
|
||||||
return; // don't draw invisible shadows
|
|
||||||
|
|
||||||
g_pHyprOpenGL->scissor((CBox*)nullptr);
|
|
||||||
|
|
||||||
fullBox.scale(pMonitor->scale);
|
|
||||||
g_pHyprOpenGL->renderBorder(&fullBox, CColor(*PCOLOR), *PROUNDING * pMonitor->scale + *PBORDERSIZE * 2, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
eDecorationType CCustomDecoration::getDecorationType() {
|
|
||||||
return DECORATION_CUSTOM;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCustomDecoration::updateWindow(CWindow* pWindow) {
|
|
||||||
|
|
||||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec();
|
|
||||||
m_vLastWindowSize = pWindow->m_vRealSize.vec();
|
|
||||||
|
|
||||||
damageEntire();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCustomDecoration::damageEntire() {
|
|
||||||
CBox dm = {(int)(m_vLastWindowPos.x - m_seExtents.topLeft.x), (int)(m_vLastWindowPos.y - m_seExtents.topLeft.y),
|
|
||||||
(int)(m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x), (int)m_seExtents.topLeft.y};
|
|
||||||
g_pHyprRenderer->damageBox(&dm);
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define WLR_USE_UNSTABLE
|
|
||||||
|
|
||||||
#include <hyprland/src/render/decorations/IHyprWindowDecoration.hpp>
|
|
||||||
|
|
||||||
class CCustomDecoration : public IHyprWindowDecoration {
|
|
||||||
public:
|
|
||||||
CCustomDecoration(CWindow*);
|
|
||||||
virtual ~CCustomDecoration();
|
|
||||||
|
|
||||||
virtual SWindowDecorationExtents getWindowDecorationExtents();
|
|
||||||
|
|
||||||
virtual void draw(CMonitor*, float a, const Vector2D& offset);
|
|
||||||
|
|
||||||
virtual eDecorationType getDecorationType();
|
|
||||||
|
|
||||||
virtual void updateWindow(CWindow*);
|
|
||||||
|
|
||||||
virtual void damageEntire();
|
|
||||||
|
|
||||||
private:
|
|
||||||
SWindowDecorationExtents m_seExtents;
|
|
||||||
|
|
||||||
CWindow* m_pWindow = nullptr;
|
|
||||||
|
|
||||||
Vector2D m_vLastWindowPos;
|
|
||||||
Vector2D m_vLastWindowSize;
|
|
||||||
};
|
|
|
@ -1,80 +0,0 @@
|
||||||
#include "customLayout.hpp"
|
|
||||||
#include <hyprland/src/Compositor.hpp>
|
|
||||||
#include "globals.hpp"
|
|
||||||
|
|
||||||
void CHyprCustomLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
|
||||||
const auto SIZE = PMONITOR->vecSize;
|
|
||||||
|
|
||||||
// these are used for focus and move calculations, and are *required* to touch for moving focus to work properly.
|
|
||||||
pWindow->m_vPosition = Vector2D{(SIZE.x / 2.0) * (m_vWindowData.size() % 2), (SIZE.y / 2.0) * (int)(m_vWindowData.size() > 1)};
|
|
||||||
pWindow->m_vSize = SIZE / 2.0;
|
|
||||||
|
|
||||||
// this is the actual pos and size of the window (where it's rendered)
|
|
||||||
pWindow->m_vRealPosition = pWindow->m_vPosition + Vector2D{10, 10};
|
|
||||||
pWindow->m_vRealSize = pWindow->m_vSize - Vector2D{20, 20};
|
|
||||||
|
|
||||||
const auto PDATA = &m_vWindowData.emplace_back();
|
|
||||||
PDATA->pWindow = pWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
|
||||||
std::erase_if(m_vWindowData, [&](const auto& other) { return other.pWindow == pWindow; });
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CHyprCustomLayout::isWindowTiled(CWindow* pWindow) {
|
|
||||||
return std::find_if(m_vWindowData.begin(), m_vWindowData.end(), [&](const auto& other) { return other.pWindow == pWindow; }) != m_vWindowData.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::recalculateMonitor(const int& eIdleInhibitMode) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::recalculateWindow(CWindow* pWindow) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::resizeActiveWindow(const Vector2D& delta, CWindow* pWindow) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreenMode mode, bool on) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
std::any CHyprCustomLayout::layoutMessage(SLayoutMessageHeader header, std::string content) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
SWindowRenderLayoutHints CHyprCustomLayout::requestRenderHints(CWindow* pWindow) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::switchWindows(CWindow* pWindowA, CWindow* pWindowB) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::alterSplitRatio(CWindow* pWindow, float delta, bool exact) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string CHyprCustomLayout::getLayoutName() {
|
|
||||||
return "custom";
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::replaceWindowDataWith(CWindow* from, CWindow* to) {
|
|
||||||
; // empty
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::onEnable() {
|
|
||||||
for (auto& w : g_pCompositor->m_vWindows) {
|
|
||||||
if (w->isHidden() || !w->m_bIsMapped || w->m_bFadingOut || w->m_bIsFloating)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
onWindowCreatedTiling(w.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CHyprCustomLayout::onDisable() {
|
|
||||||
m_vWindowData.clear();
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define WLR_USE_UNSTABLE
|
|
||||||
|
|
||||||
#include <hyprland/src/layout/IHyprLayout.hpp>
|
|
||||||
|
|
||||||
struct SWindowData {
|
|
||||||
CWindow* pWindow = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CHyprCustomLayout : public IHyprLayout {
|
|
||||||
public:
|
|
||||||
virtual void onWindowCreatedTiling(CWindow*);
|
|
||||||
virtual void onWindowRemovedTiling(CWindow*);
|
|
||||||
virtual bool isWindowTiled(CWindow*);
|
|
||||||
virtual void recalculateMonitor(const int&);
|
|
||||||
virtual void recalculateWindow(CWindow*);
|
|
||||||
virtual void resizeActiveWindow(const Vector2D&, CWindow* pWindow = nullptr);
|
|
||||||
virtual void fullscreenRequestForWindow(CWindow*, eFullscreenMode, bool);
|
|
||||||
virtual std::any layoutMessage(SLayoutMessageHeader, std::string);
|
|
||||||
virtual SWindowRenderLayoutHints requestRenderHints(CWindow*);
|
|
||||||
virtual void switchWindows(CWindow*, CWindow*);
|
|
||||||
virtual void alterSplitRatio(CWindow*, float, bool);
|
|
||||||
virtual std::string getLayoutName();
|
|
||||||
virtual void replaceWindowDataWith(CWindow* from, CWindow* to);
|
|
||||||
|
|
||||||
virtual void onEnable();
|
|
||||||
virtual void onDisable();
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<SWindowData> m_vWindowData;
|
|
||||||
};
|
|
|
@ -1,5 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <hyprland/src/plugins/PluginAPI.hpp>
|
|
||||||
|
|
||||||
inline HANDLE PHANDLE = nullptr;
|
|
|
@ -1,99 +0,0 @@
|
||||||
#define WLR_USE_UNSTABLE
|
|
||||||
|
|
||||||
#include "globals.hpp"
|
|
||||||
|
|
||||||
#include <hyprland/src/Window.hpp>
|
|
||||||
#include <hyprland/src/Compositor.hpp>
|
|
||||||
#include "customLayout.hpp"
|
|
||||||
#include "customDecoration.hpp"
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
// Methods
|
|
||||||
inline std::unique_ptr<CHyprCustomLayout> g_pCustomLayout;
|
|
||||||
inline CFunctionHook* g_pFocusHook = nullptr;
|
|
||||||
inline CFunctionHook* g_pMotionHook = nullptr;
|
|
||||||
inline CFunctionHook* g_pMouseDownHook = nullptr;
|
|
||||||
typedef void (*origFocusWindow)(void*, CWindow*, wlr_surface*);
|
|
||||||
typedef void (*origMotion)(wlr_seat*, uint32_t, double, double);
|
|
||||||
typedef void (*origMouseDownNormal)(void*, wlr_pointer_button_event*);
|
|
||||||
|
|
||||||
// Do NOT change this function.
|
|
||||||
APICALL EXPORT std::string PLUGIN_API_VERSION() {
|
|
||||||
return HYPRLAND_API_VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onActiveWindowChange(void* self, std::any data) {
|
|
||||||
try {
|
|
||||||
auto* const PWINDOW = std::any_cast<CWindow*>(data);
|
|
||||||
|
|
||||||
HyprlandAPI::addNotification(PHANDLE, "[ExamplePlugin] Active window: " + (PWINDOW ? PWINDOW->m_szTitle : "None"), CColor{0.f, 0.5f, 1.f, 1.f}, 5000);
|
|
||||||
} catch (std::bad_any_cast& e) { HyprlandAPI::addNotification(PHANDLE, "[ExamplePlugin] Active window: None", CColor{0.f, 0.5f, 1.f, 1.f}, 5000); }
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onNewWindow(void* self, std::any data) {
|
|
||||||
auto* const PWINDOW = std::any_cast<CWindow*>(data);
|
|
||||||
|
|
||||||
HyprlandAPI::addWindowDecoration(PHANDLE, PWINDOW, new CCustomDecoration(PWINDOW));
|
|
||||||
}
|
|
||||||
|
|
||||||
void hkFocusWindow(void* thisptr, CWindow* pWindow, wlr_surface* pSurface) {
|
|
||||||
// HyprlandAPI::addNotification(PHANDLE, getFormat("FocusWindow with %lx %lx", pWindow, pSurface), CColor{0.f, 1.f, 1.f, 1.f}, 5000);
|
|
||||||
(*(origFocusWindow)g_pFocusHook->m_pOriginal)(thisptr, pWindow, pSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hkNotifyMotion(wlr_seat* wlr_seat, uint32_t time_msec, double sx, double sy) {
|
|
||||||
// HyprlandAPI::addNotification(PHANDLE, getFormat("NotifyMotion with %lf %lf", sx, sy), CColor{0.f, 1.f, 1.f, 1.f}, 5000);
|
|
||||||
(*(origMotion)g_pMotionHook->m_pOriginal)(wlr_seat, time_msec, sx, sy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hkProcessMouseDownNormal(void* thisptr, wlr_pointer_button_event* e) {
|
|
||||||
// HyprlandAPI::addNotification(PHANDLE, "Mouse down normal!", CColor{0.8f, 0.2f, 0.5f, 1.0f}, 5000);
|
|
||||||
(*(origMouseDownNormal)g_pMouseDownHook->m_pOriginal)(thisptr, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
|
||||||
PHANDLE = handle;
|
|
||||||
|
|
||||||
HyprlandAPI::addNotification(PHANDLE, "Hello World from an example plugin!", CColor{0.f, 1.f, 1.f, 1.f}, 5000);
|
|
||||||
|
|
||||||
HyprlandAPI::registerCallbackDynamic(PHANDLE, "activeWindow", [&](void* self, SCallbackInfo& info, std::any data) { onActiveWindowChange(self, data); });
|
|
||||||
HyprlandAPI::registerCallbackDynamic(PHANDLE, "openWindow", [&](void* self, SCallbackInfo& info, std::any data) { onNewWindow(self, data); });
|
|
||||||
|
|
||||||
g_pCustomLayout = std::make_unique<CHyprCustomLayout>();
|
|
||||||
|
|
||||||
HyprlandAPI::addLayout(PHANDLE, "custom", g_pCustomLayout.get());
|
|
||||||
|
|
||||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:example:border_color", SConfigValue{.intValue = configStringToInt("rgb(44ee44)")});
|
|
||||||
|
|
||||||
HyprlandAPI::addDispatcher(PHANDLE, "example", [](std::string arg) { HyprlandAPI::addNotification(PHANDLE, "Arg passed: " + arg, CColor{0.5f, 0.5f, 0.7f, 1.0f}, 5000); });
|
|
||||||
|
|
||||||
// Hook a public member
|
|
||||||
g_pFocusHook = HyprlandAPI::createFunctionHook(PHANDLE, (void*)&CCompositor::focusWindow, (void*)&hkFocusWindow);
|
|
||||||
// Hook a public non-member
|
|
||||||
g_pMotionHook = HyprlandAPI::createFunctionHook(PHANDLE, (void*)&wlr_seat_pointer_notify_motion, (void*)&hkNotifyMotion);
|
|
||||||
// Hook a private member
|
|
||||||
static const auto METHODS = HyprlandAPI::findFunctionsByName(PHANDLE, "processMouseDownNormal");
|
|
||||||
g_pMouseDownHook = HyprlandAPI::createFunctionHook(PHANDLE, METHODS[0].address, (void*)&hkProcessMouseDownNormal);
|
|
||||||
|
|
||||||
static auto* const PBORDERCOLOR = HyprlandAPI::getConfigValue(PHANDLE, "plugin:example:border_color");
|
|
||||||
|
|
||||||
// fancy notifications
|
|
||||||
HyprlandAPI::addNotificationV2(
|
|
||||||
PHANDLE,
|
|
||||||
{{"text", "Example hint, color " + std::to_string(PBORDERCOLOR->intValue)}, {"time", (uint64_t)10000}, {"color", CColor{PBORDERCOLOR->intValue}}, {"icon", ICON_HINT}});
|
|
||||||
|
|
||||||
// Enable our hooks
|
|
||||||
g_pFocusHook->hook();
|
|
||||||
g_pMotionHook->hook();
|
|
||||||
g_pMouseDownHook->hook();
|
|
||||||
|
|
||||||
HyprlandAPI::reloadConfig();
|
|
||||||
|
|
||||||
return {"ExamplePlugin", "An example plugin", "Vaxry", "1.0"};
|
|
||||||
}
|
|
||||||
|
|
||||||
APICALL EXPORT void PLUGIN_EXIT() {
|
|
||||||
HyprlandAPI::invokeHyprctlCommand("seterror", "disable");
|
|
||||||
}
|
|
|
@ -2284,7 +2284,6 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
|
||||||
|
|
||||||
g_pXWaylandManager->setWindowFullscreen(pWindow, pWindow->shouldSendFullscreenState());
|
g_pXWaylandManager->setWindowFullscreen(pWindow, pWindow->shouldSendFullscreenState());
|
||||||
|
|
||||||
pWindow->updateDynamicRules();
|
|
||||||
updateWindowAnimatedDecorationValues(pWindow);
|
updateWindowAnimatedDecorationValues(pWindow);
|
||||||
|
|
||||||
// make all windows on the same workspace under the fullscreen window
|
// make all windows on the same workspace under the fullscreen window
|
||||||
|
|
|
@ -395,10 +395,20 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
||||||
if (!COMMAND.starts_with("device:") /* devices parsed later */ && !COMMAND.starts_with("plugin:") /* plugins parsed later */) {
|
if (!COMMAND.starts_with("device:") /* devices parsed later */ && !COMMAND.starts_with("plugin:") /* plugins parsed later */) {
|
||||||
if (COMMAND[0] == '$') {
|
if (COMMAND[0] == '$') {
|
||||||
// register a dynamic var
|
// register a dynamic var
|
||||||
|
bool found = false;
|
||||||
|
for (auto& [var, val] : configDynamicVars) {
|
||||||
|
if (var == COMMAND.substr(1)) {
|
||||||
|
Debug::log(LOG, "Registered new value for dynamic var \"{}\" -> {}", COMMAND, VALUE);
|
||||||
|
val = VALUE;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
Debug::log(LOG, "Registered dynamic var \"{}\" -> {}", COMMAND, VALUE);
|
Debug::log(LOG, "Registered dynamic var \"{}\" -> {}", COMMAND, VALUE);
|
||||||
configDynamicVars.emplace_back(std::make_pair<>(COMMAND.substr(1), VALUE));
|
configDynamicVars.emplace_back(std::make_pair<>(COMMAND.substr(1), VALUE));
|
||||||
|
|
||||||
std::sort(configDynamicVars.begin(), configDynamicVars.end(), [&](const auto& a, const auto& b) { return a.first.length() > b.first.length(); });
|
std::sort(configDynamicVars.begin(), configDynamicVars.end(), [&](const auto& a, const auto& b) { return a.first.length() > b.first.length(); });
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field.";
|
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field.";
|
||||||
}
|
}
|
||||||
|
@ -935,7 +945,7 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
|
||||||
g_pKeybindManager->addKeybind(
|
g_pKeybindManager->addKeybind(
|
||||||
SKeybind{"", std::stoi(KEY.substr(5)), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse, nonConsuming, transparent, ignoreMods});
|
SKeybind{"", std::stoi(KEY.substr(5)), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse, nonConsuming, transparent, ignoreMods});
|
||||||
else
|
else
|
||||||
g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse, nonConsuming, transparent, ignoreMods});
|
g_pKeybindManager->addKeybind(SKeybind{KEY, 0, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse, nonConsuming, transparent, ignoreMods});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -780,6 +780,9 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
|
||||||
pWindow->m_bIsFullscreen = on;
|
pWindow->m_bIsFullscreen = on;
|
||||||
PWORKSPACE->m_bHasFullscreenWindow = !PWORKSPACE->m_bHasFullscreenWindow;
|
PWORKSPACE->m_bHasFullscreenWindow = !PWORKSPACE->m_bHasFullscreenWindow;
|
||||||
|
|
||||||
|
pWindow->updateDynamicRules();
|
||||||
|
pWindow->updateWindowDecos();
|
||||||
|
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent{"fullscreen", std::to_string((int)on)});
|
g_pEventManager->postEvent(SHyprIPCEvent{"fullscreen", std::to_string((int)on)});
|
||||||
EMIT_HOOK_EVENT("fullscreen", pWindow);
|
EMIT_HOOK_EVENT("fullscreen", pWindow);
|
||||||
|
|
||||||
|
@ -824,7 +827,7 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
|
||||||
pWindow->m_vPosition = fakeNode.box.pos();
|
pWindow->m_vPosition = fakeNode.box.pos();
|
||||||
pWindow->m_vSize = fakeNode.box.size();
|
pWindow->m_vSize = fakeNode.box.size();
|
||||||
|
|
||||||
applyNodeDataToWindow(&fakeNode);
|
applyNodeDataToWindow(&fakeNode, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -883,6 +883,9 @@ void CHyprMasterLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreen
|
||||||
pWindow->m_bIsFullscreen = on;
|
pWindow->m_bIsFullscreen = on;
|
||||||
PWORKSPACE->m_bHasFullscreenWindow = !PWORKSPACE->m_bHasFullscreenWindow;
|
PWORKSPACE->m_bHasFullscreenWindow = !PWORKSPACE->m_bHasFullscreenWindow;
|
||||||
|
|
||||||
|
pWindow->updateDynamicRules();
|
||||||
|
pWindow->updateWindowDecos();
|
||||||
|
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent{"fullscreen", std::to_string((int)on)});
|
g_pEventManager->postEvent(SHyprIPCEvent{"fullscreen", std::to_string((int)on)});
|
||||||
EMIT_HOOK_EVENT("fullscreen", pWindow);
|
EMIT_HOOK_EVENT("fullscreen", pWindow);
|
||||||
|
|
||||||
|
@ -1328,6 +1331,9 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||||
const auto PWINDOW = header.pWindow;
|
const auto PWINDOW = header.pWindow;
|
||||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||||
|
|
||||||
|
if (!PNODE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
const auto OLDMASTER = PNODE->isMaster ? PNODE : getMasterNodeOnWorkspace(PNODE->workspaceID);
|
const auto OLDMASTER = PNODE->isMaster ? PNODE : getMasterNodeOnWorkspace(PNODE->workspaceID);
|
||||||
const auto OLDMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), *OLDMASTER);
|
const auto OLDMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), *OLDMASTER);
|
||||||
|
|
||||||
|
@ -1350,6 +1356,9 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
|
||||||
const auto PWINDOW = header.pWindow;
|
const auto PWINDOW = header.pWindow;
|
||||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||||
|
|
||||||
|
if (!PNODE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
const auto OLDMASTER = PNODE->isMaster ? PNODE : getMasterNodeOnWorkspace(PNODE->workspaceID);
|
const auto OLDMASTER = PNODE->isMaster ? PNODE : getMasterNodeOnWorkspace(PNODE->workspaceID);
|
||||||
const auto OLDMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), *OLDMASTER);
|
const auto OLDMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), *OLDMASTER);
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <vector>
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
#include <linux/vt.h>
|
#include <linux/vt.h>
|
||||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||||
|
@ -95,7 +96,7 @@ void CKeybindManager::addKeybind(SKeybind kb) {
|
||||||
void CKeybindManager::removeKeybind(uint32_t mod, const std::string& key) {
|
void CKeybindManager::removeKeybind(uint32_t mod, const std::string& key) {
|
||||||
for (auto it = m_lKeybinds.begin(); it != m_lKeybinds.end(); ++it) {
|
for (auto it = m_lKeybinds.begin(); it != m_lKeybinds.end(); ++it) {
|
||||||
if (isNumber(key) && std::stoi(key) > 9) {
|
if (isNumber(key) && std::stoi(key) > 9) {
|
||||||
const auto KEYNUM = std::stoi(key);
|
const uint32_t KEYNUM = std::stoi(key);
|
||||||
|
|
||||||
if (it->modmask == mod && it->keycode == KEYNUM) {
|
if (it->modmask == mod && it->keycode == KEYNUM) {
|
||||||
it = m_lKeybinds.erase(it);
|
it = m_lKeybinds.erase(it);
|
||||||
|
@ -137,6 +138,22 @@ uint32_t CKeybindManager::stringToModMask(std::string mods) {
|
||||||
return modMask;
|
return modMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t CKeybindManager::keycodeToModifier(xkb_keycode_t keycode) {
|
||||||
|
switch (keycode - 8) {
|
||||||
|
case KEY_LEFTMETA: return WLR_MODIFIER_LOGO;
|
||||||
|
case KEY_RIGHTMETA: return WLR_MODIFIER_LOGO;
|
||||||
|
case KEY_LEFTSHIFT: return WLR_MODIFIER_SHIFT;
|
||||||
|
case KEY_RIGHTSHIFT: return WLR_MODIFIER_SHIFT;
|
||||||
|
case KEY_LEFTCTRL: return WLR_MODIFIER_CTRL;
|
||||||
|
case KEY_RIGHTCTRL: return WLR_MODIFIER_CTRL;
|
||||||
|
case KEY_LEFTALT: return WLR_MODIFIER_ALT;
|
||||||
|
case KEY_RIGHTALT: return WLR_MODIFIER_ALT;
|
||||||
|
case KEY_CAPSLOCK: return WLR_MODIFIER_CAPS;
|
||||||
|
case KEY_NUMLOCK: return WLR_MODIFIER_MOD2;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CKeybindManager::updateXKBTranslationState() {
|
void CKeybindManager::updateXKBTranslationState() {
|
||||||
if (m_pXKBTranslationState) {
|
if (m_pXKBTranslationState) {
|
||||||
xkb_keymap_unref(xkb_state_get_keymap(m_pXKBTranslationState));
|
xkb_keymap_unref(xkb_state_get_keymap(m_pXKBTranslationState));
|
||||||
|
@ -261,8 +278,7 @@ void CKeybindManager::switchToWindow(CWindow* PWINDOWTOCHANGETO) {
|
||||||
|
|
||||||
bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) {
|
bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard) {
|
||||||
if (!g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) {
|
if (!g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) {
|
||||||
m_dPressedKeycodes.clear();
|
m_dPressedKeys.clear();
|
||||||
m_dPressedKeysyms.clear();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,6 +309,12 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
||||||
|
|
||||||
bool mouseBindWasActive = ensureMouseBindState();
|
bool mouseBindWasActive = ensureMouseBindState();
|
||||||
|
|
||||||
|
const auto KEY = SPressedKeyWithMods{
|
||||||
|
.keysym = keysym,
|
||||||
|
.keycode = KEYCODE,
|
||||||
|
.modmaskAtPressTime = MODS,
|
||||||
|
};
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||||
// clean repeat
|
// clean repeat
|
||||||
|
@ -302,16 +324,13 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
||||||
m_pActiveKeybind = nullptr;
|
m_pActiveKeybind = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dPressedKeycodes.push_back(KEYCODE);
|
m_dPressedKeys.push_back(KEY);
|
||||||
m_dPressedKeysyms.push_back(keysym);
|
|
||||||
|
|
||||||
found = handleKeybinds(MODS, "", keysym, 0, true, e->time_msec) || found;
|
found = handleKeybinds(MODS, KEY, true);
|
||||||
|
|
||||||
found = handleKeybinds(MODS, "", 0, KEYCODE, true, e->time_msec) || found;
|
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
shadowKeybinds(keysym, KEYCODE);
|
shadowKeybinds(keysym, KEYCODE);
|
||||||
} else if (e->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
|
} else { // key release
|
||||||
// clean repeat
|
// clean repeat
|
||||||
if (m_pActiveKeybindEventSource) {
|
if (m_pActiveKeybindEventSource) {
|
||||||
wl_event_source_remove(m_pActiveKeybindEventSource);
|
wl_event_source_remove(m_pActiveKeybindEventSource);
|
||||||
|
@ -319,12 +338,23 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
|
||||||
m_pActiveKeybind = nullptr;
|
m_pActiveKeybind = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dPressedKeycodes.erase(std::remove(m_dPressedKeycodes.begin(), m_dPressedKeycodes.end(), KEYCODE), m_dPressedKeycodes.end());
|
bool foundInPressedKeys = false;
|
||||||
m_dPressedKeysyms.erase(std::remove(m_dPressedKeysyms.begin(), m_dPressedKeysyms.end(), keysym), m_dPressedKeysyms.end());
|
for (auto it = m_dPressedKeys.begin(); it != m_dPressedKeys.end();) {
|
||||||
|
if (it->keycode == KEYCODE) {
|
||||||
found = handleKeybinds(MODS, "", keysym, 0, false, e->time_msec) || found;
|
if (!foundInPressedKeys) {
|
||||||
|
found = handleKeybinds(MODS, *it, false);
|
||||||
found = handleKeybinds(MODS, "", 0, KEYCODE, false, e->time_msec) || found;
|
foundInPressedKeys = true;
|
||||||
|
}
|
||||||
|
it = m_dPressedKeys.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundInPressedKeys) {
|
||||||
|
Debug::log(ERR, "BUG THIS: key not found in m_dPressedKeys");
|
||||||
|
// fallback with wrong `KEY.modmaskAtPressTime`, this can be buggy
|
||||||
|
found = handleKeybinds(MODS, KEY, false);
|
||||||
|
}
|
||||||
|
|
||||||
shadowKeybinds();
|
shadowKeybinds();
|
||||||
}
|
}
|
||||||
|
@ -347,14 +377,14 @@ bool CKeybindManager::onAxisEvent(wlr_pointer_axis_event* e) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
if (e->source == WLR_AXIS_SOURCE_WHEEL && e->orientation == WLR_AXIS_ORIENTATION_VERTICAL) {
|
if (e->source == WLR_AXIS_SOURCE_WHEEL && e->orientation == WLR_AXIS_ORIENTATION_VERTICAL) {
|
||||||
if (e->delta < 0)
|
if (e->delta < 0)
|
||||||
found = handleKeybinds(MODS, "mouse_down", 0, 0, true, 0);
|
found = handleKeybinds(MODS, SPressedKeyWithMods{.keyName = "mouse_down"}, true);
|
||||||
else
|
else
|
||||||
found = handleKeybinds(MODS, "mouse_up", 0, 0, true, 0);
|
found = handleKeybinds(MODS, SPressedKeyWithMods{.keyName = "mouse_up"}, true);
|
||||||
} else if (e->source == WLR_AXIS_SOURCE_WHEEL && e->orientation == WLR_AXIS_ORIENTATION_HORIZONTAL) {
|
} else if (e->source == WLR_AXIS_SOURCE_WHEEL && e->orientation == WLR_AXIS_ORIENTATION_HORIZONTAL) {
|
||||||
if (e->delta < 0)
|
if (e->delta < 0)
|
||||||
found = handleKeybinds(MODS, "mouse_left", 0, 0, true, 0);
|
found = handleKeybinds(MODS, SPressedKeyWithMods{.keyName = "mouse_left"}, true);
|
||||||
else
|
else
|
||||||
found = handleKeybinds(MODS, "mouse_right", 0, 0, true, 0);
|
found = handleKeybinds(MODS, SPressedKeyWithMods{.keyName = "mouse_right"}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
|
@ -374,13 +404,38 @@ bool CKeybindManager::onMouseEvent(wlr_pointer_button_event* e) {
|
||||||
|
|
||||||
bool mouseBindWasActive = ensureMouseBindState();
|
bool mouseBindWasActive = ensureMouseBindState();
|
||||||
|
|
||||||
|
const auto KEY_NAME = "mouse:" + std::to_string(e->button);
|
||||||
|
|
||||||
|
const auto KEY = SPressedKeyWithMods{
|
||||||
|
.keyName = KEY_NAME,
|
||||||
|
.modmaskAtPressTime = MODS,
|
||||||
|
};
|
||||||
|
|
||||||
if (e->state == WLR_BUTTON_PRESSED) {
|
if (e->state == WLR_BUTTON_PRESSED) {
|
||||||
found = handleKeybinds(MODS, "mouse:" + std::to_string(e->button), 0, 0, true, 0);
|
m_dPressedKeys.push_back(KEY);
|
||||||
|
|
||||||
|
found = handleKeybinds(MODS, KEY, true);
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
shadowKeybinds();
|
shadowKeybinds();
|
||||||
} else {
|
} else {
|
||||||
found = handleKeybinds(MODS, "mouse:" + std::to_string(e->button), 0, 0, false, 0);
|
bool foundInPressedKeys = false;
|
||||||
|
for (auto it = m_dPressedKeys.begin(); it != m_dPressedKeys.end();) {
|
||||||
|
if (it->keyName == KEY_NAME) {
|
||||||
|
if (!foundInPressedKeys) {
|
||||||
|
found = handleKeybinds(MODS, *it, false);
|
||||||
|
foundInPressedKeys = true;
|
||||||
|
}
|
||||||
|
it = m_dPressedKeys.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundInPressedKeys) {
|
||||||
|
Debug::log(ERR, "BUG THIS: key not found in m_dPressedKeys (2)");
|
||||||
|
// fallback with wrong `KEY.modmaskAtPressTime`, this can be buggy
|
||||||
|
found = handleKeybinds(MODS, KEY, false);
|
||||||
|
}
|
||||||
|
|
||||||
shadowKeybinds();
|
shadowKeybinds();
|
||||||
}
|
}
|
||||||
|
@ -397,15 +452,15 @@ void CKeybindManager::resizeWithBorder(wlr_pointer_button_event* e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::onSwitchEvent(const std::string& switchName) {
|
void CKeybindManager::onSwitchEvent(const std::string& switchName) {
|
||||||
handleKeybinds(0, "switch:" + switchName, 0, 0, true, 0);
|
handleKeybinds(0, SPressedKeyWithMods{.keyName = "switch:" + switchName}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::onSwitchOnEvent(const std::string& switchName) {
|
void CKeybindManager::onSwitchOnEvent(const std::string& switchName) {
|
||||||
handleKeybinds(0, "switch:on:" + switchName, 0, 0, true, 0);
|
handleKeybinds(0, SPressedKeyWithMods{.keyName = "switch:on:" + switchName}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::onSwitchOffEvent(const std::string& switchName) {
|
void CKeybindManager::onSwitchOffEvent(const std::string& switchName) {
|
||||||
handleKeybinds(0, "switch:off:" + switchName, 0, 0, true, 0);
|
handleKeybinds(0, SPressedKeyWithMods{.keyName = "switch:off:" + switchName}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int repeatKeyHandler(void* data) {
|
int repeatKeyHandler(void* data) {
|
||||||
|
@ -424,7 +479,7 @@ int repeatKeyHandler(void* data) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string& key, const xkb_keysym_t& keysym, const int& keycode, bool pressed, uint32_t time) {
|
bool CKeybindManager::handleKeybinds(const uint32_t modmask, const SPressedKeyWithMods& key, bool pressed) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
if (g_pCompositor->m_sSeat.exclusiveClient)
|
if (g_pCompositor->m_sSeat.exclusiveClient)
|
||||||
|
@ -441,22 +496,19 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
||||||
((modmask != k.modmask && !k.ignoreMods) || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap || k.shadowed))
|
((modmask != k.modmask && !k.ignoreMods) || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap || k.shadowed))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!key.empty()) {
|
if (!key.keyName.empty()) {
|
||||||
if (key != k.key)
|
if (key.keyName != k.key)
|
||||||
continue;
|
continue;
|
||||||
} else if (k.keycode != -1) {
|
} else if (k.keycode != 0) {
|
||||||
if (keycode != k.keycode)
|
if (key.keycode != k.keycode)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if (keysym == 0)
|
|
||||||
continue; // this is a keycode check run
|
|
||||||
|
|
||||||
// oMg such performance hit!!11!
|
// oMg such performance hit!!11!
|
||||||
// this little maneouver is gonna cost us 4µs
|
// 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 KBKEY = xkb_keysym_from_name(k.key.c_str(), XKB_KEYSYM_CASE_INSENSITIVE);
|
||||||
const auto KBKEYUPPER = xkb_keysym_to_upper(KBKEY);
|
const auto KBKEYUPPER = xkb_keysym_to_upper(KBKEY);
|
||||||
|
|
||||||
if (keysym != KBKEY && keysym != KBKEYUPPER)
|
if (key.keysym != KBKEY && key.keysym != KBKEYUPPER)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,13 +520,25 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pressed && !k.release && !SPECIALDISPATCHER) {
|
if (!pressed) {
|
||||||
|
// Require mods to be matching when the key was first pressed.
|
||||||
|
if (key.modmaskAtPressTime != modmask) {
|
||||||
|
// Handle properly `bindr` where a key is itself a bind mod for example:
|
||||||
|
// "bindr = SUPER, SUPER_L, exec, $launcher".
|
||||||
|
// This needs to be handled separately for the above case, because `key.modmaskAtPressTime` is set
|
||||||
|
// from currently pressed keys as programs see them, but it doesn't yet include the currently
|
||||||
|
// pressed mod key, which is still being handled internally.
|
||||||
|
if (keycodeToModifier(key.keycode) == key.modmaskAtPressTime)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
} else if (!k.release && !SPECIALDISPATCHER) {
|
||||||
if (k.nonConsuming)
|
if (k.nonConsuming)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
found = true; // suppress the event
|
found = true; // suppress the event
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const auto DISPATCHER = m_mDispatchers.find(k.mouse ? "mouse" : k.handler);
|
const auto DISPATCHER = m_mDispatchers.find(k.mouse ? "mouse" : k.handler);
|
||||||
|
|
||||||
|
@ -488,7 +552,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
||||||
Debug::log(ERR, "Invalid handler in a keybind! (handler {} does not exist)", k.handler);
|
Debug::log(ERR, "Invalid handler in a keybind! (handler {} does not exist)", k.handler);
|
||||||
} else {
|
} else {
|
||||||
// call the dispatcher
|
// call the dispatcher
|
||||||
Debug::log(LOG, "Keybind triggered, calling dispatcher ({}, {}, {})", modmask, key, keysym);
|
Debug::log(LOG, "Keybind triggered, calling dispatcher ({}, {}, {})", modmask, key.keyName, key.keysym);
|
||||||
|
|
||||||
m_iPassPressed = (int)pressed;
|
m_iPassPressed = (int)pressed;
|
||||||
|
|
||||||
|
@ -521,7 +585,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const std::string&
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::shadowKeybinds(const xkb_keysym_t& doesntHave, const int& doesntHaveCode) {
|
void CKeybindManager::shadowKeybinds(const xkb_keysym_t& doesntHave, const uint32_t doesntHaveCode) {
|
||||||
// shadow disables keybinds after one has been triggered
|
// shadow disables keybinds after one has been triggered
|
||||||
|
|
||||||
for (auto& k : m_lKeybinds) {
|
for (auto& k : m_lKeybinds) {
|
||||||
|
@ -534,22 +598,20 @@ void CKeybindManager::shadowKeybinds(const xkb_keysym_t& doesntHave, const int&
|
||||||
const auto KBKEY = xkb_keysym_from_name(k.key.c_str(), XKB_KEYSYM_CASE_INSENSITIVE);
|
const auto KBKEY = xkb_keysym_from_name(k.key.c_str(), XKB_KEYSYM_CASE_INSENSITIVE);
|
||||||
const auto KBKEYUPPER = xkb_keysym_to_upper(KBKEY);
|
const auto KBKEYUPPER = xkb_keysym_to_upper(KBKEY);
|
||||||
|
|
||||||
for (auto& pk : m_dPressedKeysyms) {
|
for (auto& pk : m_dPressedKeys) {
|
||||||
if ((pk == KBKEY || pk == KBKEYUPPER)) {
|
if ((pk.keysym != 0 && (pk.keysym == KBKEY || pk.keysym == KBKEYUPPER))) {
|
||||||
shadow = true;
|
shadow = true;
|
||||||
|
|
||||||
if (pk == doesntHave && doesntHave != 0) {
|
if (pk.keysym == doesntHave && doesntHave != 0) {
|
||||||
shadow = false;
|
shadow = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& pk : m_dPressedKeycodes) {
|
if (pk.keycode != 0 && pk.keycode == k.keycode) {
|
||||||
if (pk == k.keycode) {
|
|
||||||
shadow = true;
|
shadow = true;
|
||||||
|
|
||||||
if (pk == doesntHaveCode && doesntHaveCode != 0 && doesntHaveCode != -1) {
|
if (pk.keycode == doesntHaveCode && doesntHaveCode != 0) {
|
||||||
shadow = false;
|
shadow = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1000,10 +1062,12 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
||||||
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
|
g_pCompositor->moveWindowToWorkspaceSafe(PWINDOW, pWorkspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto PATCOORDS = g_pCompositor->vectorToWindowIdeal(OLDMIDDLE); PATCOORDS && PATCOORDS != PWINDOW)
|
if (PWINDOW == g_pCompositor->m_pLastWindow) {
|
||||||
|
if (const auto PATCOORDS = g_pCompositor->vectorToWindowIdeal(OLDMIDDLE, PWINDOW); PATCOORDS)
|
||||||
g_pCompositor->focusWindow(PATCOORDS);
|
g_pCompositor->focusWindow(PATCOORDS);
|
||||||
else
|
else
|
||||||
g_pInputManager->refocus();
|
g_pInputManager->refocus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::moveFocusTo(std::string args) {
|
void CKeybindManager::moveFocusTo(std::string args) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ class CPluginSystem;
|
||||||
|
|
||||||
struct SKeybind {
|
struct SKeybind {
|
||||||
std::string key = "";
|
std::string key = "";
|
||||||
int keycode = -1;
|
uint32_t keycode = 0;
|
||||||
uint32_t modmask = 0;
|
uint32_t modmask = 0;
|
||||||
std::string handler = "";
|
std::string handler = "";
|
||||||
std::string arg = "";
|
std::string arg = "";
|
||||||
|
@ -36,6 +36,13 @@ enum eFocusWindowMode {
|
||||||
MODE_PID
|
MODE_PID
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SPressedKeyWithMods {
|
||||||
|
std::string keyName = "";
|
||||||
|
xkb_keysym_t keysym = 0;
|
||||||
|
uint32_t keycode = 0;
|
||||||
|
uint32_t modmaskAtPressTime = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class CKeybindManager {
|
class CKeybindManager {
|
||||||
public:
|
public:
|
||||||
CKeybindManager();
|
CKeybindManager();
|
||||||
|
@ -51,8 +58,9 @@ class CKeybindManager {
|
||||||
void addKeybind(SKeybind);
|
void addKeybind(SKeybind);
|
||||||
void removeKeybind(uint32_t, const std::string&);
|
void removeKeybind(uint32_t, const std::string&);
|
||||||
uint32_t stringToModMask(std::string);
|
uint32_t stringToModMask(std::string);
|
||||||
|
uint32_t keycodeToModifier(xkb_keycode_t);
|
||||||
void clearKeybinds();
|
void clearKeybinds();
|
||||||
void shadowKeybinds(const xkb_keysym_t& doesntHave = 0, const int& doesntHaveCode = 0);
|
void shadowKeybinds(const xkb_keysym_t& doesntHave = 0, const uint32_t doesntHaveCode = 0);
|
||||||
|
|
||||||
std::unordered_map<std::string, std::function<void(std::string)>> m_mDispatchers;
|
std::unordered_map<std::string, std::function<void(std::string)>> m_mDispatchers;
|
||||||
|
|
||||||
|
@ -63,8 +71,7 @@ class CKeybindManager {
|
||||||
std::list<SKeybind> m_lKeybinds;
|
std::list<SKeybind> m_lKeybinds;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::deque<xkb_keysym_t> m_dPressedKeysyms;
|
std::deque<SPressedKeyWithMods> m_dPressedKeys;
|
||||||
std::deque<int> m_dPressedKeycodes;
|
|
||||||
|
|
||||||
inline static std::string m_szCurrentSelectedSubmap = "";
|
inline static std::string m_szCurrentSelectedSubmap = "";
|
||||||
|
|
||||||
|
@ -81,7 +88,7 @@ class CKeybindManager {
|
||||||
|
|
||||||
CTimer m_tScrollTimer;
|
CTimer m_tScrollTimer;
|
||||||
|
|
||||||
bool handleKeybinds(const uint32_t&, const std::string&, const xkb_keysym_t&, const int&, bool, uint32_t);
|
bool handleKeybinds(const uint32_t, const SPressedKeyWithMods&, bool);
|
||||||
|
|
||||||
bool handleInternalKeybinds(xkb_keysym_t);
|
bool handleInternalKeybinds(xkb_keysym_t);
|
||||||
bool handleVT(xkb_keysym_t);
|
bool handleVT(xkb_keysym_t);
|
||||||
|
|
|
@ -190,9 +190,9 @@ bool CFunctionHook::hook() {
|
||||||
(uint64_t)((uint8_t*)m_pSource + sizeof(ABSOLUTE_JMP_ADDRESS));
|
(uint64_t)((uint8_t*)m_pSource + sizeof(ABSOLUTE_JMP_ADDRESS));
|
||||||
|
|
||||||
// make jump to hk
|
// make jump to hk
|
||||||
const auto PAGESIZE = sysconf(_SC_PAGE_SIZE);
|
const auto PAGESIZE_VAR = sysconf(_SC_PAGE_SIZE);
|
||||||
const uint8_t* PROTSTART = (uint8_t*)m_pSource - ((uint64_t)m_pSource % PAGESIZE);
|
const uint8_t* PROTSTART = (uint8_t*)m_pSource - ((uint64_t)m_pSource % PAGESIZE_VAR);
|
||||||
const size_t PROTLEN = std::ceil((float)(ORIGSIZE + ((uint64_t)m_pSource - (uint64_t)PROTSTART)) / (float)PAGESIZE) * PAGESIZE;
|
const size_t PROTLEN = std::ceil((float)(ORIGSIZE + ((uint64_t)m_pSource - (uint64_t)PROTSTART)) / (float)PAGESIZE_VAR) * PAGESIZE_VAR;
|
||||||
mprotect((uint8_t*)PROTSTART, PROTLEN, PROT_READ | PROT_WRITE | PROT_EXEC);
|
mprotect((uint8_t*)PROTSTART, PROTLEN, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||||
memcpy((uint8_t*)m_pSource, ABSOLUTE_JMP_ADDRESS, sizeof(ABSOLUTE_JMP_ADDRESS));
|
memcpy((uint8_t*)m_pSource, ABSOLUTE_JMP_ADDRESS, sizeof(ABSOLUTE_JMP_ADDRESS));
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,7 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data)
|
||||||
const auto NEARESTNEIGHBORSET = g_pHyprOpenGL->m_RenderData.useNearestNeighbor;
|
const auto NEARESTNEIGHBORSET = g_pHyprOpenGL->m_RenderData.useNearestNeighbor;
|
||||||
if (std::floor(RDATA->pMonitor->scale) != RDATA->pMonitor->scale /* Fractional */ && surface->current.scale == 1 /* fs protocol */ &&
|
if (std::floor(RDATA->pMonitor->scale) != RDATA->pMonitor->scale /* Fractional */ && surface->current.scale == 1 /* fs protocol */ &&
|
||||||
windowBox.size() != Vector2D{surface->current.buffer_width, surface->current.buffer_height} /* misaligned */ &&
|
windowBox.size() != Vector2D{surface->current.buffer_width, surface->current.buffer_height} /* misaligned */ &&
|
||||||
|
DELTALESSTHAN(windowBox.width, surface->current.buffer_width, 3) && DELTALESSTHAN(windowBox.height, surface->current.buffer_height, 3) /* off by one-or-two */ &&
|
||||||
(!RDATA->pWindow || (!RDATA->pWindow->m_vRealSize.isBeingAnimated() && !INTERACTIVERESIZEINPROGRESS)) /* not window or not animated/resizing */)
|
(!RDATA->pWindow || (!RDATA->pWindow->m_vRealSize.isBeingAnimated() && !INTERACTIVERESIZEINPROGRESS)) /* not window or not animated/resizing */)
|
||||||
g_pHyprOpenGL->m_RenderData.useNearestNeighbor = true;
|
g_pHyprOpenGL->m_RenderData.useNearestNeighbor = true;
|
||||||
|
|
||||||
|
|
|
@ -104,5 +104,5 @@ std::string CHyprBorderDecoration::getDisplayName() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CHyprBorderDecoration::doesntWantBorders() {
|
bool CHyprBorderDecoration::doesntWantBorders() {
|
||||||
return !m_pWindow->m_sSpecialRenderData.border || m_pWindow->m_bX11DoesntWantBorders;
|
return !m_pWindow->m_sSpecialRenderData.border || m_pWindow->m_bX11DoesntWantBorders || m_pWindow->getRealBorderSize() == 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,6 +317,9 @@ void refreshGroupBarGradients() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
|
bool CHyprGroupBarDecoration::onBeginWindowDragOnDeco(const Vector2D& pos) {
|
||||||
|
if (m_pWindow == m_pWindow->m_sGroupData.pNextWindow)
|
||||||
|
return false;
|
||||||
|
|
||||||
const float BARRELATIVEX = pos.x - assignedBoxGlobal().x;
|
const float BARRELATIVEX = pos.x - assignedBoxGlobal().x;
|
||||||
const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
|
const int WINDOWINDEX = (BARRELATIVEX) / (m_fBarWidth + BAR_HORIZONTAL_PADDING);
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,10 @@ index 29b103a..0b6e5a4 100644
|
||||||
--- a/meson.build
|
--- a/meson.build
|
||||||
+++ b/meson.build
|
+++ b/meson.build
|
||||||
@@ -15,7 +15,7 @@ project(
|
@@ -15,7 +15,7 @@ project(
|
||||||
# necessary for bugfix releases. Increasing soversion is required because
|
version_major = version.split('.')[0]
|
||||||
# wlroots never guarantees ABI stability -- only API stability is guaranteed
|
version_minor = version.split('.')[1]
|
||||||
# between minor releases.
|
assert(version_major == '0')
|
||||||
-soversion = 13
|
-soversion = version_minor.to_int() - 5
|
||||||
+soversion = 13032
|
+soversion = 13032
|
||||||
|
|
||||||
little_endian = target_machine.endian() == 'little'
|
little_endian = target_machine.endian() == 'little'
|
||||||
|
|
Loading…
Reference in a new issue