2024-03-03 18:39:20 +00:00
# include "../config/ConfigValue.hpp"
2024-05-03 22:34:10 +01:00
# include "../devices/IKeyboard.hpp"
2024-05-10 18:27:57 +01:00
# include "../managers/SeatManager.hpp"
2024-06-16 14:42:32 +00:00
# include "../protocols/LayerShell.hpp"
2024-05-29 05:37:24 +08:00
# include "../protocols/ShortcutsInhibit.hpp"
2024-07-30 16:33:56 -05:00
# include "../protocols/GlobalShortcuts.hpp"
2024-05-29 05:37:24 +08:00
# include "../render/decorations/CHyprGroupBarDecoration.hpp"
# include "KeybindManager.hpp"
2024-06-25 03:55:54 -07:00
# include "PointerManager.hpp"
2024-06-19 23:19:18 +02:00
# include "Compositor.hpp"
2024-05-29 05:37:24 +08:00
# include "TokenManager.hpp"
2024-07-21 13:09:54 +02:00
# include "eventLoop/EventLoopManager.hpp"
2024-05-29 05:37:24 +08:00
# include "debug/Log.hpp"
2024-06-11 17:17:45 +02:00
# include "helpers/varlist/VarList.hpp"
2022-03-19 17:48:18 +01:00
2024-05-16 10:48:30 +00:00
# include <optional>
2024-06-05 08:42:44 +00:00
# include <iterator>
2024-05-16 10:48:30 +00:00
# include <string>
2024-05-29 05:37:24 +08:00
# include <string_view>
2024-07-21 13:09:54 +02:00
# include <cstring>
2022-06-10 12:06:27 +02:00
2024-06-11 17:17:45 +02:00
# include <hyprutils/string/String.hpp>
using namespace Hyprutils : : String ;
2023-01-29 12:44:38 +00:00
# include <sys/ioctl.h>
2023-08-16 08:51:08 +00:00
# include <fcntl.h>
2024-01-01 18:29:51 +01:00
# include <vector>
2023-01-29 12:44:38 +00:00
# if defined(__linux__)
# include <linux/vt.h>
# elif defined(__NetBSD__) || defined(__OpenBSD__)
# include <dev/wscons/wsdisplay_usl_io.h>
# elif defined(__DragonFly__) || defined(__FreeBSD__)
# include <sys/consio.h>
# endif
2024-09-06 08:54:01 +09:00
static std : : vector < std : : pair < std : : string , std : : string > > getHyprlandLaunchEnv ( PHLWORKSPACE pInitialWorkspace ) {
2024-04-23 01:28:20 +01:00
static auto PINITIALWSTRACKING = CConfigValue < Hyprlang : : INT > ( " misc:initial_workspace_tracking " ) ;
2024-07-25 15:29:39 +02:00
if ( ! * PINITIALWSTRACKING | | g_pConfigManager - > isLaunchingExecOnce )
2024-04-23 01:28:20 +01:00
return { } ;
const auto PMONITOR = g_pCompositor - > m_pLastMonitor ;
if ( ! PMONITOR | | ! PMONITOR - > activeWorkspace )
return { } ;
std : : vector < std : : pair < std : : string , std : : string > > result ;
2024-09-06 08:54:01 +09:00
if ( ! pInitialWorkspace ) {
if ( PMONITOR - > activeSpecialWorkspace )
pInitialWorkspace = PMONITOR - > activeSpecialWorkspace ;
else
pInitialWorkspace = PMONITOR - > activeWorkspace ;
}
result . push_back ( std : : make_pair < > ( " HL_INITIAL_WORKSPACE_TOKEN " ,
g_pTokenManager - > registerNewToken ( SInitialWorkspaceToken { { } , pInitialWorkspace - > getConfigName ( ) } , std : : chrono : : months ( 1337 ) ) ) ) ;
2024-04-23 01:28:20 +01:00
return result ;
}
2022-04-21 15:50:52 +02:00
CKeybindManager : : CKeybindManager ( ) {
// initialize all dispatchers
2024-01-15 23:30:46 +08:00
m_mDispatchers [ " exec " ] = spawn ;
m_mDispatchers [ " execr " ] = spawnRaw ;
m_mDispatchers [ " killactive " ] = killActive ;
m_mDispatchers [ " closewindow " ] = kill ;
m_mDispatchers [ " togglefloating " ] = toggleActiveFloating ;
2024-03-17 11:41:43 -04:00
m_mDispatchers [ " setfloating " ] = setActiveFloating ;
m_mDispatchers [ " settiled " ] = setActiveTiled ;
2024-01-15 23:30:46 +08:00
m_mDispatchers [ " workspace " ] = changeworkspace ;
m_mDispatchers [ " renameworkspace " ] = renameWorkspace ;
m_mDispatchers [ " fullscreen " ] = fullscreenActive ;
2024-07-31 17:55:52 +00:00
m_mDispatchers [ " fullscreenstate " ] = fullscreenStateActive ;
2024-01-15 23:30:46 +08:00
m_mDispatchers [ " movetoworkspace " ] = moveActiveToWorkspace ;
m_mDispatchers [ " movetoworkspacesilent " ] = moveActiveToWorkspaceSilent ;
m_mDispatchers [ " pseudo " ] = toggleActivePseudo ;
m_mDispatchers [ " movefocus " ] = moveFocusTo ;
m_mDispatchers [ " movewindow " ] = moveActiveTo ;
m_mDispatchers [ " swapwindow " ] = swapActive ;
m_mDispatchers [ " centerwindow " ] = centerWindow ;
m_mDispatchers [ " togglegroup " ] = toggleGroup ;
m_mDispatchers [ " changegroupactive " ] = changeGroupActive ;
m_mDispatchers [ " movegroupwindow " ] = moveGroupWindow ;
m_mDispatchers [ " togglesplit " ] = toggleSplit ;
2024-02-14 18:58:28 +01:00
m_mDispatchers [ " swapsplit " ] = swapSplit ;
2024-01-15 23:30:46 +08:00
m_mDispatchers [ " splitratio " ] = alterSplitRatio ;
m_mDispatchers [ " focusmonitor " ] = focusMonitor ;
m_mDispatchers [ " movecursortocorner " ] = moveCursorToCorner ;
m_mDispatchers [ " movecursor " ] = moveCursor ;
m_mDispatchers [ " workspaceopt " ] = workspaceOpt ;
m_mDispatchers [ " exit " ] = exitHyprland ;
m_mDispatchers [ " movecurrentworkspacetomonitor " ] = moveCurrentWorkspaceToMonitor ;
m_mDispatchers [ " focusworkspaceoncurrentmonitor " ] = focusWorkspaceOnCurrentMonitor ;
m_mDispatchers [ " moveworkspacetomonitor " ] = moveWorkspaceToMonitor ;
m_mDispatchers [ " togglespecialworkspace " ] = toggleSpecialWorkspace ;
m_mDispatchers [ " forcerendererreload " ] = forceRendererReload ;
m_mDispatchers [ " resizeactive " ] = resizeActive ;
m_mDispatchers [ " moveactive " ] = moveActive ;
m_mDispatchers [ " cyclenext " ] = circleNext ;
m_mDispatchers [ " focuswindowbyclass " ] = focusWindow ;
m_mDispatchers [ " focuswindow " ] = focusWindow ;
2024-05-29 05:37:24 +08:00
m_mDispatchers [ " tagwindow " ] = tagWindow ;
2024-01-15 23:30:46 +08:00
m_mDispatchers [ " submap " ] = setSubmap ;
m_mDispatchers [ " pass " ] = pass ;
2024-05-24 20:58:26 +02:00
m_mDispatchers [ " sendshortcut " ] = sendshortcut ;
2024-01-15 23:30:46 +08:00
m_mDispatchers [ " layoutmsg " ] = layoutmsg ;
m_mDispatchers [ " dpms " ] = dpms ;
m_mDispatchers [ " movewindowpixel " ] = moveWindow ;
m_mDispatchers [ " resizewindowpixel " ] = resizeWindow ;
m_mDispatchers [ " swapnext " ] = swapnext ;
m_mDispatchers [ " swapactiveworkspaces " ] = swapActiveWorkspaces ;
m_mDispatchers [ " pin " ] = pinActive ;
m_mDispatchers [ " mouse " ] = mouse ;
m_mDispatchers [ " bringactivetotop " ] = bringActiveToTop ;
m_mDispatchers [ " alterzorder " ] = alterZOrder ;
m_mDispatchers [ " focusurgentorlast " ] = focusUrgentOrLast ;
m_mDispatchers [ " focuscurrentorlast " ] = focusCurrentOrLast ;
m_mDispatchers [ " lockgroups " ] = lockGroups ;
m_mDispatchers [ " lockactivegroup " ] = lockActiveGroup ;
m_mDispatchers [ " moveintogroup " ] = moveIntoGroup ;
m_mDispatchers [ " moveoutofgroup " ] = moveOutOfGroup ;
m_mDispatchers [ " movewindoworgroup " ] = moveWindowOrGroup ;
m_mDispatchers [ " setignoregrouplock " ] = setIgnoreGroupLock ;
m_mDispatchers [ " denywindowfromgroup " ] = denyWindowFromGroup ;
2024-06-15 16:20:00 +02:00
m_mDispatchers [ " event " ] = event ;
2024-01-15 23:30:46 +08:00
m_mDispatchers [ " global " ] = global ;
2024-10-28 18:18:58 +00:00
m_mDispatchers [ " setprop " ] = setProp ;
2022-07-26 23:34:03 +02:00
m_tScrollTimer . reset ( ) ;
2023-09-10 16:27:14 +01:00
2024-11-16 07:21:59 +08:00
m_pLongPressTimer = makeShared < CEventLoopTimer > (
std : : nullopt ,
[ this ] ( SP < CEventLoopTimer > self , void * data ) {
if ( ! m_pLastLongPressKeybind | | g_pSeatManager - > keyboard . expired ( ) )
return ;
const auto DISPATCHER = g_pKeybindManager - > m_mDispatchers . find ( m_pLastLongPressKeybind - > handler ) ;
Debug : : log ( LOG , " Long press timeout passed, calling dispatcher. " ) ;
DISPATCHER - > second ( m_pLastLongPressKeybind - > arg ) ;
} ,
nullptr ) ;
2024-11-18 19:48:13 +00:00
m_pRepeatKeyTimer = makeShared < CEventLoopTimer > (
std : : nullopt ,
[ this ] ( SP < CEventLoopTimer > self , void * data ) {
if ( m_vActiveKeybinds . size ( ) = = 0 | | g_pSeatManager - > keyboard . expired ( ) )
return ;
2024-11-18 19:56:26 +00:00
for ( const auto & k : m_vActiveKeybinds ) {
2024-11-18 19:48:13 +00:00
const auto DISPATCHER = g_pKeybindManager - > m_mDispatchers . find ( k - > handler ) ;
Debug : : log ( LOG , " Keybind repeat triggered, calling dispatcher. " ) ;
DISPATCHER - > second ( k - > arg ) ;
}
const auto PACTIVEKEEB = g_pSeatManager - > keyboard . lock ( ) ;
self - > updateTimeout ( std : : chrono : : milliseconds ( 1000 / PACTIVEKEEB - > repeatRate ) ) ;
} ,
nullptr ) ;
2024-11-16 07:21:59 +08:00
g_pEventLoopManager - > addTimer ( m_pLongPressTimer ) ;
2024-11-18 19:48:13 +00:00
g_pEventLoopManager - > addTimer ( m_pRepeatKeyTimer ) ;
2024-11-16 07:21:59 +08:00
2024-04-20 20:16:42 +01:00
static auto P = g_pHookSystem - > hookDynamic ( " configReloaded " , [ this ] ( void * hk , SCallbackInfo & info , std : : any param ) {
2023-09-10 16:27:14 +01:00
// clear cuz realloc'd
2024-11-18 19:48:13 +00:00
m_vActiveKeybinds . clear ( ) ;
2024-11-18 19:56:26 +00:00
m_pLastLongPressKeybind . reset ( ) ;
2023-09-10 16:27:14 +01:00
m_vPressedSpecialBinds . clear ( ) ;
} ) ;
2022-04-21 15:50:52 +02:00
}
2024-05-03 15:42:08 +02:00
CKeybindManager : : ~ CKeybindManager ( ) {
if ( m_pXKBTranslationState )
xkb_state_unref ( m_pXKBTranslationState ) ;
2024-11-16 07:21:59 +08:00
if ( m_pLongPressTimer & & g_pEventLoopManager ) {
g_pEventLoopManager - > removeTimer ( m_pLongPressTimer ) ;
m_pLongPressTimer . reset ( ) ;
}
2024-11-18 19:48:13 +00:00
if ( m_pRepeatKeyTimer & & g_pEventLoopManager ) {
g_pEventLoopManager - > removeTimer ( m_pRepeatKeyTimer ) ;
m_pRepeatKeyTimer . reset ( ) ;
}
2024-05-03 15:42:08 +02:00
}
2022-03-19 17:48:18 +01:00
void CKeybindManager : : addKeybind ( SKeybind kb ) {
2024-11-18 19:56:26 +00:00
m_vKeybinds . emplace_back ( makeShared < SKeybind > ( kb ) ) ;
2022-07-25 14:42:49 +02:00
2024-11-18 19:48:13 +00:00
m_vActiveKeybinds . clear ( ) ;
2024-11-18 19:56:26 +00:00
m_pLastLongPressKeybind . reset ( ) ;
2022-04-21 17:06:43 +02:00
}
2024-03-03 01:17:02 +01:00
void CKeybindManager : : removeKeybind ( uint32_t mod , const SParsedKey & key ) {
2024-11-18 19:56:26 +00:00
std : : erase_if ( m_vKeybinds , [ & mod , & key ] ( const auto & el ) { return el - > modmask = = mod & & el - > key = = key . key & & el - > keycode = = key . keycode & & el - > catchAll = = key . catchAll ; } ) ;
2022-07-25 14:42:49 +02:00
2024-11-18 19:48:13 +00:00
m_vActiveKeybinds . clear ( ) ;
2024-11-18 19:56:26 +00:00
m_pLastLongPressKeybind . reset ( ) ;
2022-03-19 17:48:18 +01:00
}
uint32_t CKeybindManager : : stringToModMask ( std : : string mods ) {
uint32_t modMask = 0 ;
2023-07-14 18:39:53 +02:00
std : : transform ( mods . begin ( ) , mods . end ( ) , mods . begin ( ) , : : toupper ) ;
2022-07-06 16:50:11 +02:00
if ( mods . contains ( " SHIFT " ) )
2024-07-21 13:09:54 +02:00
modMask | = HL_MODIFIER_SHIFT ;
2022-07-06 16:50:11 +02:00
if ( mods . contains ( " CAPS " ) )
2024-07-21 13:09:54 +02:00
modMask | = HL_MODIFIER_CAPS ;
2022-07-06 16:50:11 +02:00
if ( mods . contains ( " CTRL " ) | | mods . contains ( " CONTROL " ) )
2024-07-21 13:09:54 +02:00
modMask | = HL_MODIFIER_CTRL ;
2023-04-06 19:28:09 +01:00
if ( mods . contains ( " ALT " ) | | mods . contains ( " MOD1 " ) )
2024-07-21 13:09:54 +02:00
modMask | = HL_MODIFIER_ALT ;
2022-07-06 16:50:11 +02:00
if ( mods . contains ( " MOD2 " ) )
2024-07-21 13:09:54 +02:00
modMask | = HL_MODIFIER_MOD2 ;
2022-07-06 16:50:11 +02:00
if ( mods . contains ( " MOD3 " ) )
2024-07-21 13:09:54 +02:00
modMask | = HL_MODIFIER_MOD3 ;
if ( mods . contains ( " SUPER " ) | | mods . contains ( " WIN " ) | | mods . contains ( " LOGO " ) | | mods . contains ( " MOD4 " ) | | mods . contains ( " META " ) )
modMask | = HL_MODIFIER_META ;
2022-07-06 16:50:11 +02:00
if ( mods . contains ( " MOD5 " ) )
2024-07-21 13:09:54 +02:00
modMask | = HL_MODIFIER_MOD5 ;
2022-03-19 17:48:18 +01:00
return modMask ;
}
2024-01-01 18:29:51 +01:00
uint32_t CKeybindManager : : keycodeToModifier ( xkb_keycode_t keycode ) {
2024-08-12 19:19:03 +02:00
if ( keycode = = 0 )
return 0 ;
2024-01-01 18:29:51 +01:00
switch ( keycode - 8 ) {
2024-07-21 13:09:54 +02:00
case KEY_LEFTMETA : return HL_MODIFIER_META ;
case KEY_RIGHTMETA : return HL_MODIFIER_META ;
case KEY_LEFTSHIFT : return HL_MODIFIER_SHIFT ;
case KEY_RIGHTSHIFT : return HL_MODIFIER_SHIFT ;
case KEY_LEFTCTRL : return HL_MODIFIER_CTRL ;
case KEY_RIGHTCTRL : return HL_MODIFIER_CTRL ;
case KEY_LEFTALT : return HL_MODIFIER_ALT ;
case KEY_RIGHTALT : return HL_MODIFIER_ALT ;
case KEY_CAPSLOCK : return HL_MODIFIER_CAPS ;
case KEY_NUMLOCK : return HL_MODIFIER_MOD2 ;
2024-01-01 18:29:51 +01:00
default : return 0 ;
}
}
2022-08-21 16:43:18 +02:00
void CKeybindManager : : updateXKBTranslationState ( ) {
if ( m_pXKBTranslationState ) {
xkb_state_unref ( m_pXKBTranslationState ) ;
m_pXKBTranslationState = nullptr ;
}
2024-03-03 18:39:20 +00:00
static auto PFILEPATH = CConfigValue < std : : string > ( " input:kb_file " ) ;
static auto PRULES = CConfigValue < std : : string > ( " input:kb_rules " ) ;
static auto PMODEL = CConfigValue < std : : string > ( " input:kb_model " ) ;
static auto PLAYOUT = CConfigValue < std : : string > ( " input:kb_layout " ) ;
static auto PVARIANT = CConfigValue < std : : string > ( " input:kb_variant " ) ;
static auto POPTIONS = CConfigValue < std : : string > ( " input:kb_options " ) ;
2024-02-18 15:00:34 +00:00
2024-03-03 18:39:20 +00:00
const std : : string FILEPATH = std : : string { * PFILEPATH } = = STRVAL_EMPTY ? " " : * PFILEPATH ;
const std : : string RULES = std : : string { * PRULES } = = STRVAL_EMPTY ? " " : * PRULES ;
const std : : string MODEL = std : : string { * PMODEL } = = STRVAL_EMPTY ? " " : * PMODEL ;
const std : : string LAYOUT = std : : string { * PLAYOUT } = = STRVAL_EMPTY ? " " : * PLAYOUT ;
const std : : string VARIANT = std : : string { * PVARIANT } = = STRVAL_EMPTY ? " " : * PVARIANT ;
const std : : string OPTIONS = std : : string { * POPTIONS } = = STRVAL_EMPTY ? " " : * POPTIONS ;
2024-02-18 15:00:34 +00:00
2024-03-03 18:39:20 +00:00
xkb_rule_names rules = { . rules = RULES . c_str ( ) , . model = MODEL . c_str ( ) , . layout = LAYOUT . c_str ( ) , . variant = VARIANT . c_str ( ) , . options = OPTIONS . c_str ( ) } ;
const auto PCONTEXT = xkb_context_new ( XKB_CONTEXT_NO_FLAGS ) ;
2024-12-07 18:51:18 +01:00
FILE * const KEYMAPFILE = FILEPATH = = " " ? nullptr : fopen ( absolutePath ( FILEPATH , g_pConfigManager - > configCurrentPath ) . c_str ( ) , " r " ) ;
2024-02-18 15:00:34 +00:00
2024-03-03 18:39:20 +00:00
auto PKEYMAP = KEYMAPFILE ? xkb_keymap_new_from_file ( PCONTEXT , KEYMAPFILE , XKB_KEYMAP_FORMAT_TEXT_V1 , XKB_KEYMAP_COMPILE_NO_FLAGS ) :
xkb_keymap_new_from_names ( PCONTEXT , & rules , XKB_KEYMAP_COMPILE_NO_FLAGS ) ;
2023-08-08 07:07:15 -07:00
if ( KEYMAPFILE )
fclose ( KEYMAPFILE ) ;
2022-09-24 21:07:18 +01:00
if ( ! PKEYMAP ) {
2022-12-16 17:17:31 +00:00
g_pHyprError - > queueCreate ( " [Runtime Error] Invalid keyboard layout passed. ( rules: " + RULES + " , model: " + MODEL + " , variant: " + VARIANT + " , options: " + OPTIONS +
" , layout: " + LAYOUT + " ) " ,
2024-12-03 18:58:24 +00:00
CHyprColor ( 1.0 , 50.0 / 255.0 , 50.0 / 255.0 , 1.0 ) ) ;
2022-09-24 21:07:18 +01:00
2023-09-06 12:51:36 +02:00
Debug : : log ( ERR , " [XKBTranslationState] Keyboard layout {} with variant {} (rules: {}, model: {}, options: {}) couldn't have been loaded. " , rules . layout , rules . variant ,
2022-12-16 17:17:31 +00:00
rules . rules , rules . model , rules . options ) ;
2022-09-24 21:07:18 +01:00
memset ( & rules , 0 , sizeof ( rules ) ) ;
PKEYMAP = xkb_keymap_new_from_names ( PCONTEXT , & rules , XKB_KEYMAP_COMPILE_NO_FLAGS ) ;
}
2022-08-21 16:43:18 +02:00
xkb_context_unref ( PCONTEXT ) ;
m_pXKBTranslationState = xkb_state_new ( PKEYMAP ) ;
2024-05-03 15:42:08 +02:00
xkb_keymap_unref ( PKEYMAP ) ;
2022-08-21 16:43:18 +02:00
}
2022-09-20 22:23:02 +01:00
bool CKeybindManager : : ensureMouseBindState ( ) {
2024-07-27 16:46:19 +00:00
if ( ! g_pInputManager - > currentlyDraggedWindow )
2022-09-20 22:23:02 +01:00
return false ;
2022-09-20 10:02:20 +01:00
2024-04-27 12:43:12 +01:00
if ( ! g_pInputManager - > currentlyDraggedWindow . expired ( ) ) {
2024-07-27 16:46:19 +00:00
changeMouseBindMode ( MBIND_INVALID ) ;
2022-09-20 22:23:02 +01:00
return true ;
2022-09-20 10:02:20 +01:00
}
2022-09-20 22:23:02 +01:00
return false ;
2022-09-20 10:02:20 +01:00
}
2024-12-18 19:56:01 -06:00
static void updateRelativeCursorCoords ( ) {
2024-06-07 17:52:15 +00:00
static auto PNOWARPS = CConfigValue < Hyprlang : : INT > ( " cursor:no_warps " ) ;
if ( * PNOWARPS )
return ;
if ( g_pCompositor - > m_pLastWindow )
g_pCompositor - > m_pLastWindow - > m_vRelativeCursorCoordsOnLastWarp = g_pInputManager - > getMouseCoordsInternal ( ) - g_pCompositor - > m_pLastWindow - > m_vPosition ;
}
2024-10-19 23:03:29 +01:00
bool CKeybindManager : : tryMoveFocusToMonitor ( PHLMONITOR monitor ) {
2023-04-10 21:07:49 +02:00
if ( ! monitor )
2023-04-10 15:40:03 +02:00
return false ;
2024-10-19 23:03:29 +01:00
const auto LASTMONITOR = g_pCompositor - > m_pLastMonitor . lock ( ) ;
2024-07-24 15:16:47 -07:00
if ( ! LASTMONITOR )
return false ;
2023-04-10 21:07:49 +02:00
if ( LASTMONITOR = = monitor ) {
Debug : : log ( LOG , " Tried to move to active monitor " ) ;
return false ;
}
2024-07-24 15:16:47 -07:00
static auto PFOLLOWMOUSE = CConfigValue < Hyprlang : : INT > ( " input:follow_mouse " ) ;
static auto PNOWARPS = CConfigValue < Hyprlang : : INT > ( " cursor:no_warps " ) ;
const auto PWORKSPACE = g_pCompositor - > m_pLastMonitor - > activeWorkspace ;
const auto PNEWMAINWORKSPACE = monitor - > activeWorkspace ;
2023-04-10 21:07:49 +02:00
2024-02-28 00:52:45 +00:00
g_pInputManager - > unconstrainMouse ( ) ;
2023-05-29 18:11:37 +02:00
PNEWMAINWORKSPACE - > rememberPrevWorkspace ( PWORKSPACE ) ;
2024-04-02 20:32:39 +01:00
const auto PNEWWORKSPACE = monitor - > activeSpecialWorkspace ? monitor - > activeSpecialWorkspace : PNEWMAINWORKSPACE ;
2023-04-10 15:40:03 +02:00
const auto PNEWWINDOW = PNEWWORKSPACE - > getLastFocusedWindow ( ) ;
if ( PNEWWINDOW ) {
2024-06-07 17:52:15 +00:00
updateRelativeCursorCoords ( ) ;
2023-04-10 15:40:03 +02:00
g_pCompositor - > focusWindow ( PNEWWINDOW ) ;
2024-06-07 17:52:15 +00:00
PNEWWINDOW - > warpCursor ( ) ;
2024-03-12 19:09:20 -07:00
2024-07-24 15:16:47 -07:00
if ( * PNOWARPS = = 0 | | * PFOLLOWMOUSE < 2 ) {
g_pInputManager - > m_pForcedFocus = PNEWWINDOW ;
g_pInputManager - > simulateMouseMovement ( ) ;
g_pInputManager - > m_pForcedFocus . reset ( ) ;
}
2023-04-10 15:40:03 +02:00
} else {
g_pCompositor - > focusWindow ( nullptr ) ;
2023-09-11 09:09:34 +00:00
g_pCompositor - > warpCursorTo ( monitor - > middle ( ) ) ;
2023-04-10 15:40:03 +02:00
}
2024-03-12 19:09:20 -07:00
g_pCompositor - > setActiveMonitor ( monitor ) ;
2023-04-10 15:40:03 +02:00
return true ;
}
2024-04-27 12:43:12 +01:00
void CKeybindManager : : switchToWindow ( PHLWINDOW PWINDOWTOCHANGETO ) {
2024-07-24 15:16:47 -07:00
static auto PFOLLOWMOUSE = CConfigValue < Hyprlang : : INT > ( " input:follow_mouse " ) ;
static auto PNOWARPS = CConfigValue < Hyprlang : : INT > ( " cursor:no_warps " ) ;
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2023-09-10 11:51:27 +00:00
if ( PWINDOWTOCHANGETO = = PLASTWINDOW | | ! PWINDOWTOCHANGETO )
return ;
2024-02-28 00:52:45 +00:00
// remove constraints
g_pInputManager - > unconstrainMouse ( ) ;
2024-07-31 17:55:52 +00:00
if ( PLASTWINDOW & & PLASTWINDOW - > m_pWorkspace = = PWINDOWTOCHANGETO - > m_pWorkspace & & PLASTWINDOW - > isFullscreen ( ) ) {
2024-04-02 20:32:39 +01:00
const auto PWORKSPACE = PLASTWINDOW - > m_pWorkspace ;
2024-07-31 17:55:52 +00:00
const auto MODE = PWORKSPACE - > m_efFullscreenMode ;
2023-09-10 11:51:27 +00:00
if ( ! PWINDOWTOCHANGETO - > m_bPinned )
2024-07-31 17:55:52 +00:00
g_pCompositor - > setWindowFullscreenInternal ( PLASTWINDOW , FSMODE_NONE ) ;
2023-09-10 11:51:27 +00:00
g_pCompositor - > focusWindow ( PWINDOWTOCHANGETO ) ;
if ( ! PWINDOWTOCHANGETO - > m_bPinned )
2024-07-31 17:55:52 +00:00
g_pCompositor - > setWindowFullscreenInternal ( PWINDOWTOCHANGETO , MODE ) ;
2024-11-11 13:55:32 +00:00
// warp the position + size animation, otherwise it looks weird.
PWINDOWTOCHANGETO - > m_vRealPosition . warp ( ) ;
PWINDOWTOCHANGETO - > m_vRealSize . warp ( ) ;
2023-09-10 11:51:27 +00:00
} else {
2024-06-07 17:52:15 +00:00
updateRelativeCursorCoords ( ) ;
2023-09-10 11:51:27 +00:00
g_pCompositor - > focusWindow ( PWINDOWTOCHANGETO ) ;
2024-06-07 17:52:15 +00:00
PWINDOWTOCHANGETO - > warpCursor ( ) ;
2023-09-10 11:51:27 +00:00
2024-07-24 15:16:47 -07:00
// Move mouse focus to the new window if required by current follow_mouse and warp modes
if ( * PNOWARPS = = 0 | | * PFOLLOWMOUSE < 2 ) {
g_pInputManager - > m_pForcedFocus = PWINDOWTOCHANGETO ;
g_pInputManager - > simulateMouseMovement ( ) ;
g_pInputManager - > m_pForcedFocus . reset ( ) ;
}
2023-09-10 11:51:27 +00:00
2024-10-27 18:45:38 +00:00
if ( PLASTWINDOW & & PLASTWINDOW - > m_pMonitor ! = PWINDOWTOCHANGETO - > m_pMonitor ) {
2023-09-10 11:51:27 +00:00
// event
2024-10-27 18:45:38 +00:00
const auto PNEWMON = PWINDOWTOCHANGETO - > m_pMonitor . lock ( ) ;
2023-09-10 11:51:27 +00:00
g_pCompositor - > setActiveMonitor ( PNEWMON ) ;
}
}
} ;
2024-05-03 22:34:10 +01:00
bool CKeybindManager : : onKeyEvent ( std : : any event , SP < IKeyboard > pKeyboard ) {
2023-09-01 22:03:56 +02:00
if ( ! g_pCompositor - > m_bSessionActive | | g_pCompositor - > m_bUnsafeState ) {
2024-01-01 18:29:51 +01:00
m_dPressedKeys . clear ( ) ;
2022-08-29 11:17:42 +02:00
return true ;
}
2022-08-21 16:43:18 +02:00
if ( ! m_pXKBTranslationState ) {
2024-12-07 18:51:18 +01:00
Debug : : log ( ERR , " BUG THIS: m_pXKBTranslationState nullptr! " ) ;
2022-08-21 16:43:18 +02:00
updateXKBTranslationState ( ) ;
if ( ! m_pXKBTranslationState )
return true ;
}
2024-05-03 22:34:10 +01:00
auto e = std : : any_cast < IKeyboard : : SKeyEvent > ( event ) ;
const auto KEYCODE = e . keycode + 8 ; // Because to xkbcommon it's +8 from libinput
2022-07-20 22:45:06 +02:00
2024-10-08 13:15:53 +01:00
const xkb_keysym_t keysym = xkb_state_key_get_one_sym ( pKeyboard - > resolveBindsBySym ? pKeyboard - > xkbSymState : m_pXKBTranslationState , KEYCODE ) ;
2024-07-21 13:09:54 +02:00
const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym ( pKeyboard - > xkbState , KEYCODE ) ;
2022-08-26 19:19:34 +02:00
2024-11-22 03:31:42 +01:00
// handleInternalKeybinds returns true when the key should be suppressed,
// while this function returns true when the key event should be sent
2022-08-26 19:19:34 +02:00
if ( handleInternalKeybinds ( internalKeysym ) )
2024-11-22 03:31:42 +01:00
return false ;
2022-07-20 22:45:06 +02:00
const auto MODS = g_pInputManager - > accumulateModsFromAllKBs ( ) ;
2024-05-03 22:34:10 +01:00
m_uTimeLastMs = e . timeMs ;
2022-12-16 17:17:31 +00:00
m_uLastCode = KEYCODE ;
2022-08-28 17:01:48 +02:00
m_uLastMouseCode = 0 ;
2022-07-20 23:17:26 +02:00
2024-01-01 18:29:51 +01:00
bool mouseBindWasActive = ensureMouseBindState ( ) ;
const auto KEY = SPressedKeyWithMods {
. keysym = keysym ,
. keycode = KEYCODE ,
. modmaskAtPressTime = MODS ,
2024-01-10 18:06:38 +01:00
. sent = true ,
2024-03-09 16:08:07 +00:00
. submapAtPress = m_szCurrentSelectedSubmap ,
2024-01-01 18:29:51 +01:00
} ;
2022-09-20 10:02:20 +01:00
2024-11-18 19:48:13 +00:00
m_vActiveKeybinds . clear ( ) ;
2024-04-21 12:50:31 +01:00
2024-11-18 19:56:26 +00:00
m_pLastLongPressKeybind . reset ( ) ;
2024-11-16 07:21:59 +08:00
2024-01-10 18:06:38 +01:00
bool suppressEvent = false ;
2024-05-03 22:34:10 +01:00
if ( e . state = = WL_KEYBOARD_KEY_STATE_PRESSED ) {
2022-07-25 14:42:49 +02:00
2024-01-01 18:29:51 +01:00
m_dPressedKeys . push_back ( KEY ) ;
2022-07-20 23:17:26 +02:00
2024-08-24 11:45:53 -05:00
suppressEvent = ! handleKeybinds ( MODS , KEY , true ) . passEvent ;
2022-07-24 14:35:58 +02:00
2024-01-10 18:06:38 +01:00
if ( suppressEvent )
2022-07-25 14:24:02 +02:00
shadowKeybinds ( keysym , KEYCODE ) ;
2024-01-10 18:06:38 +01:00
m_dPressedKeys . back ( ) . sent = ! suppressEvent ;
2024-01-01 18:29:51 +01:00
} else { // key release
2022-07-20 22:45:06 +02:00
2024-01-01 18:29:51 +01:00
bool foundInPressedKeys = false ;
for ( auto it = m_dPressedKeys . begin ( ) ; it ! = m_dPressedKeys . end ( ) ; ) {
if ( it - > keycode = = KEYCODE ) {
2024-05-11 17:02:26 -06:00
handleKeybinds ( MODS , * it , false ) ;
2024-01-10 18:06:38 +01:00
foundInPressedKeys = true ;
suppressEvent = ! it - > sent ;
it = m_dPressedKeys . erase ( it ) ;
2024-01-01 18:29:51 +01:00
} else {
+ + it ;
}
}
if ( ! foundInPressedKeys ) {
Debug : : log ( ERR , " BUG THIS: key not found in m_dPressedKeys " ) ;
// fallback with wrong `KEY.modmaskAtPressTime`, this can be buggy
2024-08-24 11:45:53 -05:00
suppressEvent = ! handleKeybinds ( MODS , KEY , false ) . passEvent ;
2024-01-01 18:29:51 +01:00
}
2022-07-20 23:17:26 +02:00
shadowKeybinds ( ) ;
2022-07-20 22:45:06 +02:00
}
2024-01-10 18:06:38 +01:00
return ! suppressEvent & & ! mouseBindWasActive ;
2022-07-20 22:45:06 +02:00
}
2024-05-05 22:18:10 +01:00
bool CKeybindManager : : onAxisEvent ( const IPointer : : SAxisEvent & e ) {
2024-03-03 18:39:20 +00:00
const auto MODS = g_pInputManager - > accumulateModsFromAllKBs ( ) ;
2022-07-21 19:18:03 +03:00
2024-03-03 18:39:20 +00:00
static auto PDELAY = CConfigValue < Hyprlang : : INT > ( " binds:scroll_event_delay " ) ;
2022-07-26 23:34:03 +02:00
2024-03-03 18:39:20 +00:00
if ( m_tScrollTimer . getMillis ( ) < * PDELAY ) {
2022-07-26 23:34:03 +02:00
m_tScrollTimer . reset ( ) ;
return true ; // timer hasn't passed yet!
}
m_tScrollTimer . reset ( ) ;
2024-11-18 19:48:13 +00:00
m_vActiveKeybinds . clear ( ) ;
2024-04-21 12:50:31 +01:00
2022-07-21 19:18:03 +03:00
bool found = false ;
2024-05-05 22:18:10 +01:00
if ( e . source = = WL_POINTER_AXIS_SOURCE_WHEEL & & e . axis = = WL_POINTER_AXIS_VERTICAL_SCROLL ) {
if ( e . delta < 0 )
2024-08-24 11:45:53 -05:00
found = ! handleKeybinds ( MODS , SPressedKeyWithMods { . keyName = " mouse_down " } , true ) . passEvent ;
2023-02-23 13:55:27 +00:00
else
2024-08-24 11:45:53 -05:00
found = ! handleKeybinds ( MODS , SPressedKeyWithMods { . keyName = " mouse_up " } , true ) . passEvent ;
2024-05-05 22:18:10 +01:00
} else if ( e . source = = WL_POINTER_AXIS_SOURCE_WHEEL & & e . axis = = WL_POINTER_AXIS_HORIZONTAL_SCROLL ) {
if ( e . delta < 0 )
2024-08-24 11:45:53 -05:00
found = ! handleKeybinds ( MODS , SPressedKeyWithMods { . keyName = " mouse_left " } , true ) . passEvent ;
2023-02-23 13:55:27 +00:00
else
2024-08-24 11:45:53 -05:00
found = ! handleKeybinds ( MODS , SPressedKeyWithMods { . keyName = " mouse_right " } , true ) . passEvent ;
2022-07-26 14:50:21 +02:00
}
2023-02-23 13:55:27 +00:00
if ( found )
shadowKeybinds ( ) ;
2022-07-26 14:50:21 +02:00
return ! found ;
}
2024-05-05 22:18:10 +01:00
bool CKeybindManager : : onMouseEvent ( const IPointer : : SButtonEvent & e ) {
2022-07-26 14:50:21 +02:00
const auto MODS = g_pInputManager - > accumulateModsFromAllKBs ( ) ;
2024-01-10 18:06:38 +01:00
bool suppressEvent = false ;
2022-07-26 14:50:21 +02:00
2024-05-05 22:18:10 +01:00
m_uLastMouseCode = e . button ;
2022-12-16 17:17:31 +00:00
m_uLastCode = 0 ;
2024-05-05 22:18:10 +01:00
m_uTimeLastMs = e . timeMs ;
2022-08-28 17:01:48 +02:00
2024-01-01 18:29:51 +01:00
bool mouseBindWasActive = ensureMouseBindState ( ) ;
2024-05-05 22:18:10 +01:00
const auto KEY_NAME = " mouse: " + std : : to_string ( e . button ) ;
2024-01-01 18:29:51 +01:00
const auto KEY = SPressedKeyWithMods {
. keyName = KEY_NAME ,
. modmaskAtPressTime = MODS ,
} ;
2022-09-20 22:23:02 +01:00
2024-11-18 19:48:13 +00:00
m_vActiveKeybinds . clear ( ) ;
2024-04-21 12:50:31 +01:00
2024-05-05 22:18:10 +01:00
if ( e . state = = WL_POINTER_BUTTON_STATE_PRESSED ) {
2024-01-01 18:29:51 +01:00
m_dPressedKeys . push_back ( KEY ) ;
2024-08-24 11:45:53 -05:00
suppressEvent = ! handleKeybinds ( MODS , KEY , true ) . passEvent ;
2022-07-26 14:50:21 +02:00
2024-01-10 18:06:38 +01:00
if ( suppressEvent )
2022-07-26 14:50:21 +02:00
shadowKeybinds ( ) ;
2024-01-10 18:06:38 +01:00
m_dPressedKeys . back ( ) . sent = ! suppressEvent ;
2022-07-26 14:50:21 +02:00
} else {
2024-01-01 18:29:51 +01:00
bool foundInPressedKeys = false ;
for ( auto it = m_dPressedKeys . begin ( ) ; it ! = m_dPressedKeys . end ( ) ; ) {
if ( it - > keyName = = KEY_NAME ) {
2024-08-24 11:45:53 -05:00
suppressEvent = ! handleKeybinds ( MODS , * it , false ) . passEvent ;
2024-01-10 18:06:38 +01:00
foundInPressedKeys = true ;
suppressEvent = ! it - > sent ;
it = m_dPressedKeys . erase ( it ) ;
2024-01-01 18:29:51 +01:00
} 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
2024-08-24 11:45:53 -05:00
suppressEvent = ! handleKeybinds ( MODS , KEY , false ) . passEvent ;
2024-01-01 18:29:51 +01:00
}
2022-07-26 14:50:21 +02:00
shadowKeybinds ( ) ;
2022-07-21 19:18:03 +03:00
}
2024-01-10 18:06:38 +01:00
return ! suppressEvent & & ! mouseBindWasActive ;
2022-07-21 19:18:03 +03:00
}
2024-05-05 22:18:10 +01:00
void CKeybindManager : : resizeWithBorder ( const IPointer : : SButtonEvent & e ) {
2024-07-27 16:46:19 +00:00
changeMouseBindMode ( e . state = = WL_POINTER_BUTTON_STATE_PRESSED ? MBIND_RESIZE : MBIND_INVALID ) ;
2023-02-18 23:35:31 +01:00
}
2022-10-04 20:07:21 +01:00
void CKeybindManager : : onSwitchEvent ( const std : : string & switchName ) {
2024-01-01 18:29:51 +01:00
handleKeybinds ( 0 , SPressedKeyWithMods { . keyName = " switch: " + switchName } , true ) ;
2022-10-04 20:07:21 +01:00
}
2023-01-08 23:35:24 +08:00
void CKeybindManager : : onSwitchOnEvent ( const std : : string & switchName ) {
2024-01-01 18:29:51 +01:00
handleKeybinds ( 0 , SPressedKeyWithMods { . keyName = " switch:on: " + switchName } , true ) ;
2023-01-08 23:35:24 +08:00
}
void CKeybindManager : : onSwitchOffEvent ( const std : : string & switchName ) {
2024-01-01 18:29:51 +01:00
handleKeybinds ( 0 , SPressedKeyWithMods { . keyName = " switch:off: " + switchName } , true ) ;
2023-01-08 23:35:24 +08:00
}
2024-05-16 10:48:30 +00:00
eMultiKeyCase CKeybindManager : : mkKeysymSetMatches ( const std : : set < xkb_keysym_t > keybindKeysyms , const std : : set < xkb_keysym_t > pressedKeysyms ) {
// Returns whether two sets of keysyms are equal, partially equal, or not
// matching. (Partially matching means that pressed is a subset of bound)
std : : set < xkb_keysym_t > boundKeysNotPressed ;
std : : set < xkb_keysym_t > pressedKeysNotBound ;
std : : set_difference ( keybindKeysyms . begin ( ) , keybindKeysyms . end ( ) , pressedKeysyms . begin ( ) , pressedKeysyms . end ( ) ,
std : : inserter ( boundKeysNotPressed , boundKeysNotPressed . begin ( ) ) ) ;
std : : set_difference ( pressedKeysyms . begin ( ) , pressedKeysyms . end ( ) , keybindKeysyms . begin ( ) , keybindKeysyms . end ( ) ,
std : : inserter ( pressedKeysNotBound , pressedKeysNotBound . begin ( ) ) ) ;
if ( boundKeysNotPressed . empty ( ) & & pressedKeysNotBound . empty ( ) )
return MK_FULL_MATCH ;
if ( boundKeysNotPressed . size ( ) & & pressedKeysNotBound . empty ( ) )
return MK_PARTIAL_MATCH ;
return MK_NO_MATCH ;
}
2024-11-18 19:56:26 +00:00
eMultiKeyCase CKeybindManager : : mkBindMatches ( const SP < SKeybind > keybind ) {
if ( mkKeysymSetMatches ( keybind - > sMkMods , m_sMkMods ) ! = MK_FULL_MATCH )
2024-05-16 10:48:30 +00:00
return MK_NO_MATCH ;
2024-11-18 19:56:26 +00:00
return mkKeysymSetMatches ( keybind - > sMkKeys , m_sMkKeys ) ;
2024-05-16 10:48:30 +00:00
}
2024-09-24 11:25:05 +01:00
std : : string CKeybindManager : : getCurrentSubmap ( ) {
return m_szCurrentSelectedSubmap ;
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : handleKeybinds ( const uint32_t modmask , const SPressedKeyWithMods & key , bool pressed ) {
static auto PDISABLEINHIBIT = CConfigValue < Hyprlang : : INT > ( " binds:disable_keybind_grabbing " ) ;
bool found = false ;
SDispatchResult res ;
2024-05-16 10:48:30 +00:00
if ( pressed ) {
if ( keycodeToModifier ( key . keycode ) )
m_sMkMods . insert ( key . keysym ) ;
else
m_sMkKeys . insert ( key . keysym ) ;
} else {
if ( keycodeToModifier ( key . keycode ) )
m_sMkMods . erase ( key . keysym ) ;
else
m_sMkKeys . erase ( key . keysym ) ;
}
2022-04-18 17:16:01 +02:00
2024-11-18 19:56:26 +00:00
for ( auto & k : m_vKeybinds ) {
const bool SPECIALDISPATCHER = k - > handler = = " global " | | k - > handler = = " pass " | | k - > handler = = " sendshortcut " | | k - > handler = = " mouse " ;
2023-09-10 16:27:14 +01:00
const bool SPECIALTRIGGERED =
2024-11-18 19:56:26 +00:00
std : : find_if ( m_vPressedSpecialBinds . begin ( ) , m_vPressedSpecialBinds . end ( ) , [ & ] ( const auto & other ) { return other = = k ; } ) ! = m_vPressedSpecialBinds . end ( ) ;
2023-09-10 16:54:14 +01:00
const bool IGNORECONDITIONS =
SPECIALDISPATCHER & & ! pressed & & SPECIALTRIGGERED ; // ignore mods. Pass, global dispatchers should be released immediately once the key is released.
2023-09-10 13:13:10 +01:00
2024-11-18 19:56:26 +00:00
if ( ! k - > dontInhibit & & ! * PDISABLEINHIBIT & & PROTO : : shortcutsInhibit - > isInhibited ( ) )
2024-07-24 12:10:36 +00:00
continue ;
2024-11-18 19:56:26 +00:00
if ( ! k - > locked & & g_pSessionLockManager - > isSessionLocked ( ) )
2024-05-05 13:28:14 -05:00
continue ;
2024-11-18 19:56:26 +00:00
if ( ! IGNORECONDITIONS & & ( ( modmask ! = k - > modmask & & ! k - > ignoreMods ) | | k - > submap ! = m_szCurrentSelectedSubmap | | k - > shadowed ) )
2022-03-19 17:48:18 +01:00
continue ;
2024-11-18 19:56:26 +00:00
if ( k - > multiKey ) {
2024-05-16 10:48:30 +00:00
switch ( mkBindMatches ( k ) ) {
case MK_NO_MATCH : continue ;
case MK_PARTIAL_MATCH : found = true ; continue ;
case MK_FULL_MATCH : found = true ;
}
} else if ( ! key . keyName . empty ( ) ) {
2024-11-18 19:56:26 +00:00
if ( key . keyName ! = k - > key )
2022-07-15 21:54:05 +03:00
continue ;
2024-11-18 19:56:26 +00:00
} else if ( k - > keycode ! = 0 ) {
if ( key . keycode ! = k - > keycode )
2022-07-08 09:27:17 +02:00
continue ;
2024-11-18 19:56:26 +00:00
} else if ( k - > catchAll ) {
2024-05-11 17:02:26 -06:00
if ( found | | key . submapAtPress ! = m_szCurrentSelectedSubmap )
2024-03-03 01:17:02 +01:00
continue ;
2022-07-08 09:27:17 +02:00
} else {
2024-08-07 06:22:19 -05:00
// in this case, we only have the keysym to go off of for this keybind, and it's invalid
// since there might be something like keycode to match with other keybinds, try the next
if ( key . keysym = = XKB_KEY_NoSymbol )
continue ;
2024-06-17 17:53:44 +02:00
2022-07-08 09:27:17 +02:00
// oMg such performance hit!!11!
// this little maneouver is gonna cost us 4µs
2024-11-18 19:56:26 +00:00
const auto KBKEY = xkb_keysym_from_name ( k - > key . c_str ( ) , XKB_KEYSYM_NO_FLAGS ) ;
const auto KBKEYLOWER = xkb_keysym_from_name ( k - > key . c_str ( ) , XKB_KEYSYM_CASE_INSENSITIVE ) ;
2024-02-19 01:02:03 +01:00
2024-08-07 06:22:19 -05:00
if ( KBKEY = = XKB_KEY_NoSymbol & & KBKEYLOWER = = XKB_KEY_NoSymbol ) {
2024-03-13 00:26:42 +09:00
// Keysym failed to resolve from the key name of the currently iterated bind.
2024-02-19 01:02:03 +01:00
// This happens for names such as `switch:off:Lid Switch` as well as some keys
// (such as yen and ro).
//
// We can't let compare a 0-value with currently pressed key below,
// because if this key also have no keysym (i.e. key.keysym == 0) it will incorrectly trigger the
// currently iterated bind. That's confirmed to be happening with yen and ro keys.
continue ;
}
2024-05-07 01:20:06 -05:00
if ( key . keysym ! = KBKEY & & key . keysym ! = KBKEYLOWER )
2022-07-08 09:27:17 +02:00
continue ;
}
2022-04-21 15:50:52 +02:00
2024-11-18 19:56:26 +00:00
if ( pressed & & k - > release & & ! SPECIALDISPATCHER ) {
if ( k - > nonConsuming )
2023-08-25 12:35:24 +02:00
continue ;
2023-09-01 22:14:06 +02:00
found = true ; // suppress the event
continue ;
}
2023-08-25 12:35:24 +02:00
2024-01-01 18:29:51 +01:00
if ( ! pressed ) {
// Require mods to be matching when the key was first pressed.
2024-11-18 19:56:26 +00:00
if ( key . modmaskAtPressTime ! = modmask & & ! k - > ignoreMods ) {
2024-01-01 18:29:51 +01:00
// 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 ;
2024-11-18 19:56:26 +00:00
} else if ( ! k - > release & & ! SPECIALDISPATCHER ) {
if ( k - > nonConsuming )
2024-01-01 18:29:51 +01:00
continue ;
found = true ; // suppress the event
2023-08-25 12:35:24 +02:00
continue ;
2024-01-01 18:29:51 +01:00
}
2022-07-20 22:45:06 +02:00
}
2024-11-18 19:56:26 +00:00
if ( k - > longPress ) {
2024-11-16 07:21:59 +08:00
const auto PACTIVEKEEB = g_pSeatManager - > keyboard . lock ( ) ;
m_pLongPressTimer - > updateTimeout ( std : : chrono : : milliseconds ( PACTIVEKEEB - > repeatDelay ) ) ;
2024-11-18 19:56:26 +00:00
m_pLastLongPressKeybind = k ;
2024-11-16 07:21:59 +08:00
continue ;
}
2024-11-18 19:56:26 +00:00
const auto DISPATCHER = m_mDispatchers . find ( k - > mouse ? " mouse " : k - > handler ) ;
2022-04-21 15:50:52 +02:00
2023-09-10 16:27:14 +01:00
if ( SPECIALTRIGGERED & & ! pressed )
2024-11-18 19:56:26 +00:00
std : : erase_if ( m_vPressedSpecialBinds , [ & ] ( const auto & other ) { return other = = k ; } ) ;
2023-09-10 16:27:14 +01:00
else if ( SPECIALDISPATCHER & & pressed )
2024-12-07 18:51:18 +01:00
m_vPressedSpecialBinds . emplace_back ( k ) ;
2023-09-10 16:27:14 +01:00
2022-04-21 15:50:52 +02:00
// Should never happen, as we check in the ConfigManager, but oh well
if ( DISPATCHER = = m_mDispatchers . end ( ) ) {
2024-11-18 19:56:26 +00:00
Debug : : log ( ERR , " Invalid handler in a keybind! (handler {} does not exist) " , k - > handler ) ;
2022-04-21 15:50:52 +02:00
} else {
// call the dispatcher
2024-01-01 18:29:51 +01:00
Debug : : log ( LOG , " Keybind triggered, calling dispatcher ({}, {}, {}) " , modmask , key . keyName , key . keysym ) ;
2022-08-27 19:29:28 +02:00
m_iPassPressed = ( int ) pressed ;
2024-08-24 11:45:53 -05:00
// if the dispatchers says to pass event then we will
2024-11-18 19:56:26 +00:00
if ( k - > handler = = " mouse " )
res = DISPATCHER - > second ( ( pressed ? " 1 " : " 0 " ) + k - > arg ) ;
2022-09-19 19:04:48 +01:00
else
2024-11-18 19:56:26 +00:00
res = DISPATCHER - > second ( k - > arg ) ;
2022-08-09 19:54:06 +02:00
2022-08-27 19:29:28 +02:00
m_iPassPressed = - 1 ;
2024-11-18 19:56:26 +00:00
if ( k - > handler = = " submap " ) {
2022-08-09 19:54:06 +02:00
found = true ; // don't process keybinds on submap change.
break ;
}
2022-04-14 23:02:10 +02:00
}
2022-03-19 22:03:40 +01:00
2024-11-18 19:56:26 +00:00
if ( k - > repeat ) {
2024-05-10 18:27:57 +01:00
const auto PACTIVEKEEB = g_pSeatManager - > keyboard . lock ( ) ;
2022-07-25 14:42:49 +02:00
2024-12-07 18:51:18 +01:00
m_vActiveKeybinds . emplace_back ( k ) ;
2024-11-18 19:48:13 +00:00
m_pRepeatKeyTimer - > updateTimeout ( std : : chrono : : milliseconds ( PACTIVEKEEB - > repeatDelay ) ) ;
2022-07-25 14:42:49 +02:00
}
2024-11-18 19:56:26 +00:00
if ( ! k - > nonConsuming )
2023-06-14 04:08:56 -07:00
found = true ;
2022-03-19 17:48:18 +01:00
}
2022-03-19 22:03:40 +01:00
2024-08-24 11:45:53 -05:00
// if keybind wasn't found (or dispatcher said to) then pass event
res . passEvent | = ! found ;
if ( ! found & & ! * PDISABLEINHIBIT & & PROTO : : shortcutsInhibit - > isInhibited ( ) ) {
Debug : : log ( LOG , " Keybind handling is disabled due to an inhibitor " ) ;
res . success = false ;
if ( res . error . empty ( ) )
res . error = " Keybind handling is disabled due to an inhibitor " ;
}
return res ;
2022-03-19 17:48:18 +01:00
}
2024-01-01 18:29:51 +01:00
void CKeybindManager : : shadowKeybinds ( const xkb_keysym_t & doesntHave , const uint32_t doesntHaveCode ) {
2022-07-20 23:17:26 +02:00
// shadow disables keybinds after one has been triggered
2024-11-18 19:56:26 +00:00
for ( auto & k : m_vKeybinds ) {
2022-07-20 23:17:26 +02:00
2023-04-09 13:48:20 +01:00
bool shadow = false ;
2024-11-18 19:56:26 +00:00
if ( k - > handler = = " global " | | k - > transparent )
2023-04-09 13:48:20 +01:00
continue ; // can't be shadowed
2022-07-20 23:17:26 +02:00
2024-11-18 19:56:26 +00:00
if ( k - > multiKey & & ( mkBindMatches ( k ) = = MK_FULL_MATCH ) )
2024-05-16 10:48:30 +00:00
shadow = true ;
else {
2024-11-18 19:56:26 +00:00
const auto KBKEY = xkb_keysym_from_name ( k - > key . c_str ( ) , XKB_KEYSYM_CASE_INSENSITIVE ) ;
2024-05-16 10:48:30 +00:00
const auto KBKEYUPPER = xkb_keysym_to_upper ( KBKEY ) ;
2022-07-20 23:17:26 +02:00
2024-08-26 17:25:39 +02:00
for ( auto const & pk : m_dPressedKeys ) {
2024-05-16 10:48:30 +00:00
if ( ( pk . keysym ! = 0 & & ( pk . keysym = = KBKEY | | pk . keysym = = KBKEYUPPER ) ) ) {
shadow = true ;
2022-09-25 20:07:48 +02:00
2024-05-16 10:48:30 +00:00
if ( pk . keysym = = doesntHave & & doesntHave ! = 0 ) {
shadow = false ;
break ;
}
2022-07-25 16:12:06 +02:00
}
2022-07-20 23:17:26 +02:00
2024-11-18 19:56:26 +00:00
if ( pk . keycode ! = 0 & & pk . keycode = = k - > keycode ) {
2024-05-16 10:48:30 +00:00
shadow = true ;
2022-07-24 12:16:26 +02:00
2024-05-16 10:48:30 +00:00
if ( pk . keycode = = doesntHaveCode & & doesntHaveCode ! = 0 ) {
shadow = false ;
break ;
}
2022-07-25 16:12:06 +02:00
}
2022-07-24 12:16:26 +02:00
}
2022-07-20 23:17:26 +02:00
}
2024-11-18 19:56:26 +00:00
k - > shadowed = shadow ;
2022-07-20 23:17:26 +02:00
}
}
2022-06-27 13:42:20 +02:00
bool CKeybindManager : : handleVT ( xkb_keysym_t keysym ) {
2022-03-27 19:32:50 +02:00
// Handles the CTRL+ALT+FX TTY keybinds
2024-12-07 18:51:18 +01:00
if ( keysym < XKB_KEY_XF86Switch_VT_1 | | keysym > XKB_KEY_XF86Switch_VT_12 )
2022-03-27 19:32:50 +02:00
return false ;
2022-10-06 19:31:32 +01:00
// beyond this point, return true to not handle anything else.
// we'll avoid printing shit to active windows.
2024-07-21 13:09:54 +02:00
if ( g_pCompositor - > m_pAqBackend - > hasSession ( ) ) {
2022-10-05 02:42:51 +02:00
const unsigned int TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1 ;
2022-10-04 16:53:09 +01:00
2022-10-05 21:41:27 +01:00
// vtnr is bugged for some reason.
2023-01-29 17:02:55 +00:00
unsigned int ttynum = 0 ;
2023-08-16 08:51:08 +00:00
int fd ;
if ( ( fd = open ( " /dev/tty " , O_RDONLY | O_NOCTTY ) ) > = 0 ) {
2023-03-31 19:39:04 +00:00
# if defined(VT_GETSTATE)
2023-08-16 08:51:08 +00:00
struct vt_stat st ;
if ( ! ioctl ( fd , VT_GETSTATE , & st ) )
ttynum = st . v_active ;
2023-03-31 19:39:04 +00:00
# elif defined(VT_GETACTIVE)
2023-08-16 08:51:08 +00:00
int vt ;
if ( ! ioctl ( fd , VT_GETACTIVE , & vt ) )
ttynum = vt ;
2023-01-29 12:44:38 +00:00
# endif
2023-08-16 08:51:08 +00:00
close ( fd ) ;
}
2022-10-05 21:41:27 +01:00
if ( ttynum = = TTY )
2022-10-06 19:31:32 +01:00
return true ;
2022-10-05 21:41:27 +01:00
2023-09-06 12:51:36 +02:00
Debug : : log ( LOG , " Switching from VT {} to VT {} " , ttynum , TTY ) ;
2022-10-05 21:41:27 +01:00
2024-07-21 13:09:54 +02:00
g_pCompositor - > m_pAqBackend - > session - > switchVT ( TTY ) ;
2022-03-27 19:32:50 +02:00
}
2022-10-06 19:31:32 +01:00
return true ;
2022-03-27 19:32:50 +02:00
}
2022-06-27 13:42:20 +02:00
bool CKeybindManager : : handleInternalKeybinds ( xkb_keysym_t keysym ) {
if ( handleVT ( keysym ) )
return true ;
// handle ESC while in kill mode
if ( g_pInputManager - > getClickMode ( ) = = CLICKMODE_KILL ) {
const auto KBKEY = xkb_keysym_from_name ( " ESCAPE " , XKB_KEYSYM_CASE_INSENSITIVE ) ;
if ( keysym = = KBKEY ) {
g_pInputManager - > setClickMode ( CLICKMODE_DEFAULT ) ;
return true ;
}
}
return false ;
}
2022-03-19 17:48:18 +01:00
// Dispatchers
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : spawn ( std : : string args ) {
2024-09-06 08:54:01 +09:00
const uint64_t PROC = spawnWithRules ( args , nullptr ) ;
return { . success = PROC > 0 , . error = std : : format ( " Failed to start process {} " , args ) } ;
}
uint64_t CKeybindManager : : spawnWithRules ( std : : string args , PHLWORKSPACE pInitialWorkspace ) {
2022-11-10 13:39:23 +00:00
2024-06-11 17:17:45 +02:00
args = trim ( args ) ;
2022-11-10 13:39:23 +00:00
std : : string RULES = " " ;
if ( args [ 0 ] = = ' [ ' ) {
// we have exec rules
RULES = args . substr ( 1 , args . substr ( 1 ) . find_first_of ( ' ] ' ) ) ;
2022-12-16 17:17:31 +00:00
args = args . substr ( args . find_first_of ( ' ] ' ) + 1 ) ;
2022-11-10 13:39:23 +00:00
}
2024-09-06 08:54:01 +09:00
const uint64_t PROC = spawnRawProc ( args , pInitialWorkspace ) ;
2023-02-19 13:59:39 +00:00
if ( ! RULES . empty ( ) ) {
const auto RULESLIST = CVarList ( RULES , 0 , ' ; ' ) ;
2024-08-26 17:25:39 +02:00
for ( auto const & r : RULESLIST ) {
2023-02-19 13:59:39 +00:00
g_pConfigManager - > addExecRule ( { r , ( unsigned long ) PROC } ) ;
}
2023-09-06 12:51:36 +02:00
Debug : : log ( LOG , " Applied {} rule arguments for exec. " , RULESLIST . size ( ) ) ;
2023-02-19 13:59:39 +00:00
}
2024-08-24 11:45:53 -05:00
2024-09-06 08:54:01 +09:00
return PROC ;
2024-08-24 11:45:53 -05:00
}
SDispatchResult CKeybindManager : : spawnRaw ( std : : string args ) {
2024-09-06 08:54:01 +09:00
const uint64_t PROC = spawnRawProc ( args , nullptr ) ;
2024-08-24 11:45:53 -05:00
return { . success = PROC > 0 , . error = std : : format ( " Failed to start process {} " , args ) } ;
2023-02-19 13:59:39 +00:00
}
2024-09-06 08:54:01 +09:00
uint64_t CKeybindManager : : spawnRawProc ( std : : string args , PHLWORKSPACE pInitialWorkspace ) {
2023-09-06 21:45:37 +02:00
Debug : : log ( LOG , " Executing {} " , args ) ;
2022-03-19 17:48:18 +01:00
2024-09-06 08:54:01 +09:00
const auto HLENV = getHyprlandLaunchEnv ( pInitialWorkspace ) ;
2024-04-23 01:28:20 +01:00
int socket [ 2 ] ;
2022-06-17 03:19:36 +08:00
if ( pipe ( socket ) ! = 0 ) {
Debug : : log ( LOG , " Unable to create pipe for fork " ) ;
}
2022-06-16 01:06:51 +08:00
2022-06-17 03:19:36 +08:00
pid_t child , grandchild ;
2022-06-16 01:06:51 +08:00
child = fork ( ) ;
2022-06-17 03:19:36 +08:00
if ( child < 0 ) {
2022-06-16 01:06:51 +08:00
close ( socket [ 0 ] ) ;
close ( socket [ 1 ] ) ;
Debug : : log ( LOG , " Fail to create the first fork " ) ;
2023-02-19 13:59:39 +00:00
return 0 ;
2022-06-16 01:06:51 +08:00
}
2022-06-17 03:19:36 +08:00
if ( child = = 0 ) {
2022-06-16 01:06:51 +08:00
// run in child
2024-06-19 18:36:40 +02:00
g_pCompositor - > restoreNofile ( ) ;
2022-10-06 19:02:03 +01:00
sigset_t set ;
sigemptyset ( & set ) ;
2024-12-07 18:51:18 +01:00
sigprocmask ( SIG_SETMASK , & set , nullptr ) ;
2022-10-06 19:02:03 +01:00
2022-06-16 01:06:51 +08:00
grandchild = fork ( ) ;
2022-06-17 03:19:36 +08:00
if ( grandchild = = 0 ) {
2022-06-16 01:06:51 +08:00
// run in grandchild
2024-08-26 20:24:30 +02:00
for ( auto const & e : HLENV ) {
2024-04-23 01:28:20 +01:00
setenv ( e . first . c_str ( ) , e . second . c_str ( ) , 1 ) ;
}
2024-07-21 13:09:54 +02:00
setenv ( " WAYLAND_DISPLAY " , g_pCompositor - > m_szWLDisplaySocket . c_str ( ) , 1 ) ;
2022-06-16 01:06:51 +08:00
close ( socket [ 0 ] ) ;
close ( socket [ 1 ] ) ;
execl ( " /bin/sh " , " /bin/sh " , " -c " , args . c_str ( ) , nullptr ) ;
// exit grandchild
_exit ( 0 ) ;
}
close ( socket [ 0 ] ) ;
2022-06-17 03:19:36 +08:00
write ( socket [ 1 ] , & grandchild , sizeof ( grandchild ) ) ;
2022-06-16 01:06:51 +08:00
close ( socket [ 1 ] ) ;
// exit child
2022-03-19 17:48:18 +01:00
_exit ( 0 ) ;
}
2022-06-16 01:06:51 +08:00
// run in parent
close ( socket [ 1 ] ) ;
2022-06-17 03:19:36 +08:00
read ( socket [ 0 ] , & grandchild , sizeof ( grandchild ) ) ;
2022-06-16 01:06:51 +08:00
close ( socket [ 0 ] ) ;
2024-03-11 15:31:39 -04:00
// clear child and leave grandchild to init
2024-12-07 18:51:18 +01:00
waitpid ( child , nullptr , 0 ) ;
2024-03-11 15:31:39 -04:00
if ( grandchild < 0 ) {
2022-06-16 01:06:51 +08:00
Debug : : log ( LOG , " Fail to create the second fork " ) ;
2023-02-19 13:59:39 +00:00
return 0 ;
2022-06-16 01:06:51 +08:00
}
2022-11-10 13:39:23 +00:00
2023-09-06 12:51:36 +02:00
Debug : : log ( LOG , " Process Created with pid {} " , grandchild ) ;
2022-11-10 13:39:23 +00:00
2023-02-19 13:59:39 +00:00
return grandchild ;
2022-03-19 17:48:18 +01:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : killActive ( std : : string args ) {
2024-04-27 12:43:12 +01:00
g_pCompositor - > closeWindow ( g_pCompositor - > m_pLastWindow . lock ( ) ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-03-19 21:48:24 +01:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : kill ( std : : string args ) {
2022-08-30 21:35:27 +02:00
const auto PWINDOW = g_pCompositor - > getWindowByRegex ( args ) ;
if ( ! PWINDOW ) {
Debug : : log ( ERR , " kill: no window found " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " kill: no window found " } ;
2022-08-30 21:35:27 +02:00
}
g_pCompositor - > closeWindow ( PWINDOW ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-08-30 21:35:27 +02:00
}
2022-03-19 21:48:24 +01:00
void CKeybindManager : : clearKeybinds ( ) {
2024-11-18 19:56:26 +00:00
m_vKeybinds . clear ( ) ;
2022-03-20 11:14:24 +01:00
}
2024-08-24 11:45:53 -05:00
static SDispatchResult toggleActiveFloatingCore ( std : : string args , std : : optional < bool > floatState ) {
2024-04-27 12:43:12 +01:00
PHLWINDOW PWINDOW = nullptr ;
2022-03-20 11:14:24 +01:00
2024-02-17 23:44:22 +01:00
if ( args ! = " active " & & args . length ( ) > 1 )
2022-08-25 22:34:53 +02:00
PWINDOW = g_pCompositor - > getWindowByRegex ( args ) ;
2023-11-18 17:00:24 +00:00
else
2024-04-27 12:43:12 +01:00
PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2022-08-25 22:34:53 +02:00
if ( ! PWINDOW )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2022-08-25 22:34:53 +02:00
2024-03-17 11:41:43 -04:00
if ( floatState . has_value ( ) & & floatState = = PWINDOW - > m_bIsFloating )
2024-08-24 11:45:53 -05:00
return { } ;
2024-03-17 11:41:43 -04:00
2022-10-14 20:46:32 +01:00
// remove drag status
2024-07-27 16:46:19 +00:00
if ( ! g_pInputManager - > currentlyDraggedWindow . expired ( ) )
g_pKeybindManager - > changeMouseBindMode ( MBIND_INVALID ) ;
2022-06-30 12:09:05 +02:00
2024-04-27 12:43:12 +01:00
if ( PWINDOW - > m_sGroupData . pNextWindow . lock ( ) & & PWINDOW - > m_sGroupData . pNextWindow . lock ( ) ! = PWINDOW ) {
2024-03-17 11:41:43 -04:00
const auto PCURRENT = PWINDOW - > getGroupCurrent ( ) ;
2022-05-31 14:01:00 +02:00
2023-02-19 21:07:32 +00:00
PCURRENT - > m_bIsFloating = ! PCURRENT - > m_bIsFloating ;
g_pLayoutManager - > getCurrentLayout ( ) - > changeWindowFloatingMode ( PCURRENT ) ;
2022-11-15 11:21:26 +01:00
2024-04-27 12:43:12 +01:00
PHLWINDOW curr = PCURRENT - > m_sGroupData . pNextWindow . lock ( ) ;
2023-02-19 21:07:32 +00:00
while ( curr ! = PCURRENT ) {
curr - > m_bIsFloating = PCURRENT - > m_bIsFloating ;
2024-04-27 12:43:12 +01:00
curr = curr - > m_sGroupData . pNextWindow . lock ( ) ;
2023-02-19 21:07:32 +00:00
}
} else {
PWINDOW - > m_bIsFloating = ! PWINDOW - > m_bIsFloating ;
g_pLayoutManager - > getCurrentLayout ( ) - > changeWindowFloatingMode ( PWINDOW ) ;
}
2024-11-22 16:01:02 +00:00
if ( PWINDOW - > m_pWorkspace ) {
PWINDOW - > m_pWorkspace - > updateWindows ( ) ;
PWINDOW - > m_pWorkspace - > updateWindowData ( ) ;
}
2024-10-27 18:45:38 +00:00
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( PWINDOW - > monitorID ( ) ) ;
2024-04-11 01:26:11 +09:00
g_pCompositor - > updateAllWindowsAnimatedDecorationValues ( ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-03-20 15:55:47 +01:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : toggleActiveFloating ( std : : string args ) {
2024-04-04 01:16:47 +01:00
return toggleActiveFloatingCore ( args , std : : nullopt ) ;
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : setActiveFloating ( std : : string args ) {
2024-04-04 01:16:47 +01:00
return toggleActiveFloatingCore ( args , true ) ;
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : setActiveTiled ( std : : string args ) {
2024-04-04 01:16:47 +01:00
return toggleActiveFloatingCore ( args , false ) ;
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : centerWindow ( std : : string args ) {
2024-04-27 12:43:12 +01:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2022-11-07 13:16:30 +01:00
2024-07-31 17:55:52 +00:00
if ( ! PWINDOW | | ! PWINDOW - > m_bIsFloating | | PWINDOW - > isFullscreen ( ) )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " No floating window found " } ;
2022-11-07 13:16:30 +01:00
2024-10-27 18:45:38 +00:00
const auto PMONITOR = PWINDOW - > m_pMonitor . lock ( ) ;
2022-11-07 13:16:30 +01:00
2023-08-11 14:54:16 +00:00
auto RESERVEDOFFSET = Vector2D ( ) ;
if ( args = = " 1 " )
RESERVEDOFFSET = ( PMONITOR - > vecReservedTopLeft - PMONITOR - > vecReservedBottomRight ) / 2.f ;
2024-03-02 01:35:17 +01:00
PWINDOW - > m_vRealPosition = PMONITOR - > middle ( ) - PWINDOW - > m_vRealSize . goal ( ) / 2.f + RESERVEDOFFSET ;
PWINDOW - > m_vPosition = PWINDOW - > m_vRealPosition . goal ( ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-11-07 13:16:30 +01:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : toggleActivePseudo ( std : : string args ) {
2024-06-19 23:19:18 +02:00
PHLWINDOW PWINDOW = nullptr ;
2022-04-02 20:04:32 +02:00
2024-06-19 23:19:18 +02:00
if ( args ! = " active " & & args . length ( ) > 1 )
PWINDOW = g_pCompositor - > getWindowByRegex ( args ) ;
else
PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
if ( ! PWINDOW )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2022-04-02 20:04:32 +02:00
2024-06-19 23:19:18 +02:00
PWINDOW - > m_bIsPseudotiled = ! PWINDOW - > m_bIsPseudotiled ;
2022-04-02 20:04:32 +02:00
2024-07-31 17:55:52 +00:00
if ( ! PWINDOW - > isFullscreen ( ) )
2024-06-19 23:19:18 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateWindow ( PWINDOW ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-04-02 20:04:32 +02:00
}
2024-12-18 19:56:01 -06:00
static SWorkspaceIDName getWorkspaceToChangeFromArgs ( std : : string args , PHLWORKSPACE PCURRENTWORKSPACE ) {
2024-06-23 00:52:42 +03:00
if ( ! args . starts_with ( " previous " ) ) {
return getWorkspaceIDNameFromString ( args ) ;
}
2024-06-27 16:07:56 +03:00
const bool PER_MON = args . contains ( " _per_monitor " ) ;
const SWorkspaceIDName PPREVWS = PCURRENTWORKSPACE - > getPrevWorkspaceIDName ( PER_MON ) ;
2024-06-23 00:52:42 +03:00
// Do nothing if there's no previous workspace, otherwise switch to it.
if ( PPREVWS . id = = - 1 ) {
Debug : : log ( LOG , " No previous workspace to change to " ) ;
return { WORKSPACE_NOT_CHANGED , " " } ;
}
const auto ID = PCURRENTWORKSPACE - > m_iID ;
2024-06-27 16:07:56 +03:00
if ( const auto PWORKSPACETOCHANGETO = g_pCompositor - > getWorkspaceByID ( PPREVWS . id ) ; PWORKSPACETOCHANGETO ) {
2024-10-27 18:45:38 +00:00
if ( PER_MON & & PCURRENTWORKSPACE - > m_pMonitor ! = PWORKSPACETOCHANGETO - > m_pMonitor )
2024-06-27 16:07:56 +03:00
return { WORKSPACE_NOT_CHANGED , " " } ;
2024-06-23 00:52:42 +03:00
return { ID , PWORKSPACETOCHANGETO - > m_szName } ;
2024-06-27 16:07:56 +03:00
}
2024-06-23 00:52:42 +03:00
return { ID , PPREVWS . name . empty ( ) ? std : : to_string ( PPREVWS . id ) : PPREVWS . name } ;
}
2022-04-21 16:38:48 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : changeworkspace ( std : : string args ) {
2023-04-14 15:03:53 +01:00
// Workspace_back_and_forth being enabled means that an attempt to switch to
// the current workspace will instead switch to the previous.
2024-03-03 18:39:20 +00:00
static auto PBACKANDFORTH = CConfigValue < Hyprlang : : INT > ( " binds:workspace_back_and_forth " ) ;
static auto PALLOWWORKSPACECYCLES = CConfigValue < Hyprlang : : INT > ( " binds:allow_workspace_cycles " ) ;
static auto PWORKSPACECENTERON = CConfigValue < Hyprlang : : INT > ( " binds:workspace_center_on " ) ;
2022-08-23 23:34:36 +02:00
2024-10-19 23:03:29 +01:00
const auto PMONITOR = g_pCompositor - > m_pLastMonitor . lock ( ) ;
2023-12-06 17:09:25 -07:00
if ( ! PMONITOR )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Last monitor not found " } ;
2023-12-06 17:09:25 -07:00
2024-04-02 20:32:39 +01:00
const auto PCURRENTWORKSPACE = PMONITOR - > activeWorkspace ;
2024-06-23 00:52:42 +03:00
const bool EXPLICITPREVIOUS = args . contains ( " previous " ) ;
2022-04-14 23:02:10 +02:00
2024-06-23 00:52:42 +03:00
const auto & [ workspaceToChangeTo , workspaceName ] = getWorkspaceToChangeFromArgs ( args , PCURRENTWORKSPACE ) ;
2023-11-12 13:34:42 +00:00
if ( workspaceToChangeTo = = WORKSPACE_INVALID ) {
2022-04-20 16:53:41 +02:00
Debug : : log ( ERR , " Error in changeworkspace, invalid value " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Error in changeworkspace, invalid value " } ;
2022-03-20 15:55:47 +01:00
}
2024-08-24 11:45:53 -05:00
if ( workspaceToChangeTo = = WORKSPACE_NOT_CHANGED )
return { } ;
2024-06-23 00:52:42 +03:00
const auto PREVWS = PCURRENTWORKSPACE - > getPrevWorkspaceIDName ( args . contains ( " _per_monitor " ) ) ;
2023-04-14 17:51:10 +01:00
2024-06-23 00:52:42 +03:00
const bool BISWORKSPACECURRENT = workspaceToChangeTo = = PCURRENTWORKSPACE - > m_iID ;
if ( BISWORKSPACECURRENT & & ( ! ( * PBACKANDFORTH | | EXPLICITPREVIOUS ) | | PREVWS . id = = - 1 ) )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Previous workspace doesn't exist " } ;
2022-03-20 15:55:47 +01:00
2023-09-11 14:14:43 +00:00
g_pInputManager - > unconstrainMouse ( ) ;
g_pInputManager - > m_bEmptyFocusCursorSet = false ;
2024-06-23 00:52:42 +03:00
auto pWorkspaceToChangeTo = g_pCompositor - > getWorkspaceByID ( BISWORKSPACECURRENT ? PREVWS . id : workspaceToChangeTo ) ;
2023-04-14 15:03:53 +01:00
if ( ! pWorkspaceToChangeTo )
2024-06-23 00:52:42 +03:00
pWorkspaceToChangeTo =
g_pCompositor - > createNewWorkspace ( BISWORKSPACECURRENT ? PREVWS . id : workspaceToChangeTo , PMONITOR - > ID , BISWORKSPACECURRENT ? PREVWS . name : workspaceName ) ;
2022-03-20 15:55:47 +01:00
2023-09-11 14:14:43 +00:00
if ( ! BISWORKSPACECURRENT & & pWorkspaceToChangeTo - > m_bIsSpecialWorkspace ) {
2023-04-14 15:03:53 +01:00
PMONITOR - > setSpecialWorkspace ( pWorkspaceToChangeTo ) ;
2023-06-09 12:19:48 +02:00
g_pInputManager - > simulateMouseMovement ( ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-03-13 15:19:25 +00:00
}
2022-08-21 20:21:21 +10:00
2023-04-20 00:46:42 +01:00
g_pInputManager - > releaseAllMouseButtons ( ) ;
2024-10-27 18:45:38 +00:00
const auto PMONITORWORKSPACEOWNER = PMONITOR = = pWorkspaceToChangeTo - > m_pMonitor ? PMONITOR : pWorkspaceToChangeTo - > m_pMonitor . lock ( ) ;
2022-05-12 11:27:31 +02:00
2023-09-11 14:14:43 +00:00
if ( ! PMONITORWORKSPACEOWNER )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Workspace to switch to has no monitor " } ;
2023-09-11 14:14:43 +00:00
2024-06-16 14:42:32 +00:00
updateRelativeCursorCoords ( ) ;
2023-04-14 15:28:22 +01:00
g_pCompositor - > setActiveMonitor ( PMONITORWORKSPACEOWNER ) ;
2024-05-23 05:01:12 -06:00
if ( BISWORKSPACECURRENT ) {
if ( * PALLOWWORKSPACECYCLES )
pWorkspaceToChangeTo - > rememberPrevWorkspace ( PCURRENTWORKSPACE ) ;
else if ( ! EXPLICITPREVIOUS & & ! * PBACKANDFORTH )
pWorkspaceToChangeTo - > rememberPrevWorkspace ( nullptr ) ;
} else
pWorkspaceToChangeTo - > rememberPrevWorkspace ( PCURRENTWORKSPACE ) ;
2023-09-11 14:14:43 +00:00
PMONITORWORKSPACEOWNER - > changeWorkspace ( pWorkspaceToChangeTo , false , true ) ;
2022-05-31 14:01:00 +02:00
2023-09-18 11:33:19 +01:00
if ( PMONITOR ! = PMONITORWORKSPACEOWNER ) {
2023-10-10 18:34:28 +02:00
Vector2D middle = PMONITORWORKSPACEOWNER - > middle ( ) ;
if ( const auto PLAST = pWorkspaceToChangeTo - > getLastFocusedWindow ( ) ; PLAST ) {
2023-09-18 11:33:19 +01:00
g_pCompositor - > focusWindow ( PLAST ) ;
2024-03-03 18:39:20 +00:00
if ( * PWORKSPACECENTERON = = 1 )
2023-10-10 18:34:28 +02:00
middle = PLAST - > middle ( ) ;
}
g_pCompositor - > warpCursorTo ( middle ) ;
2023-09-18 11:33:19 +01:00
}
2023-04-14 16:22:55 +01:00
2024-01-01 12:02:16 +00:00
if ( ! g_pInputManager - > m_bLastFocusOnLS ) {
if ( g_pCompositor - > m_pLastFocus )
g_pInputManager - > sendMotionEventsToFocused ( ) ;
else
g_pInputManager - > simulateMouseMovement ( ) ;
}
2024-06-16 14:42:32 +00:00
const static auto PWARPONWORKSPACECHANGE = CConfigValue < Hyprlang : : INT > ( " cursor:warp_on_change_workspace " ) ;
2024-12-10 23:55:05 +03:00
if ( * PWARPONWORKSPACECHANGE > 0 ) {
2024-06-16 14:42:32 +00:00
auto PLAST = pWorkspaceToChangeTo - > getLastFocusedWindow ( ) ;
auto HLSurface = CWLSurface : : fromResource ( g_pSeatManager - > state . pointerFocus . lock ( ) ) ;
if ( PLAST & & ( ! HLSurface | | HLSurface - > getWindow ( ) ) )
2024-12-10 23:55:05 +03:00
PLAST - > warpCursor ( * PWARPONWORKSPACECHANGE = = 2 ) ;
2024-06-16 14:42:32 +00:00
}
2024-08-24 11:45:53 -05:00
return { } ;
2022-03-21 19:18:33 +01:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : fullscreenActive ( std : : string args ) {
2024-04-27 12:43:12 +01:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2022-03-21 19:18:33 +01:00
2022-10-14 20:46:32 +01:00
if ( ! PWINDOW )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2022-03-21 19:18:33 +01:00
2024-07-31 17:55:52 +00:00
const eFullscreenMode MODE = args = = " 1 " ? FSMODE_MAXIMIZED : FSMODE_FULLSCREEN ;
if ( PWINDOW - > isEffectiveInternalFSMode ( MODE ) )
g_pCompositor - > setWindowFullscreenInternal ( PWINDOW , FSMODE_NONE ) ;
else
g_pCompositor - > setWindowFullscreenInternal ( PWINDOW , MODE ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2024-07-31 17:55:52 +00:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : fullscreenStateActive ( std : : string args ) {
2024-07-31 17:55:52 +00:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
const auto ARGS = CVarList ( args , 2 , ' ' ) ;
if ( ! PWINDOW )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2024-07-31 17:55:52 +00:00
2024-08-12 13:41:26 -04:00
PWINDOW - > m_sWindowData . syncFullscreen = CWindowOverridableVar ( false , PRIORITY_SET_PROP ) ;
2024-07-31 17:55:52 +00:00
int internalMode , clientMode ;
try {
internalMode = std : : stoi ( ARGS [ 0 ] ) ;
} catch ( std : : exception & e ) { internalMode = - 1 ; }
try {
clientMode = std : : stoi ( ARGS [ 1 ] ) ;
} catch ( std : : exception & e ) { clientMode = - 1 ; }
2024-12-07 18:51:18 +01:00
const SFullscreenState STATE = SFullscreenState { . internal = ( internalMode ! = - 1 ? ( eFullscreenMode ) internalMode : PWINDOW - > m_sFullscreenState . internal ) ,
2024-08-01 09:43:32 +00:00
. client = ( clientMode ! = - 1 ? ( eFullscreenMode ) clientMode : PWINDOW - > m_sFullscreenState . client ) } ;
2024-08-15 12:04:24 -04:00
if ( internalMode ! = - 1 & & clientMode ! = - 1 & & PWINDOW - > m_sFullscreenState . internal = = STATE . internal & & PWINDOW - > m_sFullscreenState . client = = STATE . client )
2024-12-07 18:51:18 +01:00
g_pCompositor - > setWindowFullscreenState ( PWINDOW , SFullscreenState { . internal = FSMODE_NONE , . client = FSMODE_NONE } ) ;
2024-08-15 12:04:24 -04:00
else if ( internalMode ! = - 1 & & clientMode = = - 1 & & PWINDOW - > m_sFullscreenState . internal = = STATE . internal )
2024-12-07 18:51:18 +01:00
g_pCompositor - > setWindowFullscreenState ( PWINDOW , SFullscreenState { . internal = FSMODE_NONE , . client = PWINDOW - > m_sFullscreenState . client } ) ;
2024-08-15 12:04:24 -04:00
else if ( internalMode = = - 1 & & clientMode ! = - 1 & & PWINDOW - > m_sFullscreenState . client = = STATE . client )
2024-12-07 18:51:18 +01:00
g_pCompositor - > setWindowFullscreenState ( PWINDOW , SFullscreenState { . internal = PWINDOW - > m_sFullscreenState . internal , . client = FSMODE_NONE } ) ;
2024-08-15 12:04:24 -04:00
else
g_pCompositor - > setWindowFullscreenState ( PWINDOW , STATE ) ;
2024-08-04 19:40:34 +00:00
2024-08-15 12:04:24 -04:00
PWINDOW - > m_sWindowData . syncFullscreen = CWindowOverridableVar ( PWINDOW - > m_sFullscreenState . internal = = PWINDOW - > m_sFullscreenState . client , PRIORITY_SET_PROP ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-03-23 16:51:48 +01:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveActiveToWorkspace ( std : : string args ) {
2022-08-15 16:12:53 +02:00
2024-04-27 12:43:12 +01:00
PHLWINDOW PWINDOW = nullptr ;
2022-08-15 16:12:53 +02:00
if ( args . contains ( ' , ' ) ) {
PWINDOW = g_pCompositor - > getWindowByRegex ( args . substr ( args . find_last_of ( ' , ' ) + 1 ) ) ;
2022-12-16 17:17:31 +00:00
args = args . substr ( 0 , args . find_last_of ( ' , ' ) ) ;
2022-08-15 16:12:53 +02:00
} else {
2024-04-27 12:43:12 +01:00
PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2022-08-15 16:12:53 +02:00
}
2022-03-23 16:51:48 +01:00
2022-10-14 20:46:32 +01:00
if ( ! PWINDOW )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2022-03-23 16:51:48 +01:00
2024-06-23 00:52:42 +03:00
const auto & [ WORKSPACEID , workspaceName ] = getWorkspaceIDNameFromString ( args ) ;
2023-11-12 13:34:42 +00:00
if ( WORKSPACEID = = WORKSPACE_INVALID ) {
2022-12-14 18:42:48 +00:00
Debug : : log ( LOG , " Invalid workspace in moveActiveToWorkspace " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Invalid workspace in moveActiveToWorkspace " } ;
2022-12-14 18:42:48 +00:00
}
2024-04-02 20:32:39 +01:00
if ( WORKSPACEID = = PWINDOW - > workspaceID ( ) ) {
2022-06-03 11:19:17 +02:00
Debug : : log ( LOG , " Not moving to workspace because it didn't change. " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Not moving to workspace because it didn't change. " } ;
2022-06-03 11:19:17 +02:00
}
2024-03-03 18:39:20 +00:00
auto pWorkspace = g_pCompositor - > getWorkspaceByID ( WORKSPACEID ) ;
2024-10-19 23:03:29 +01:00
PHLMONITOR pMonitor = nullptr ;
2024-04-02 20:32:39 +01:00
const auto POLDWS = PWINDOW - > m_pWorkspace ;
2024-03-03 18:39:20 +00:00
static auto PALLOWWORKSPACECYCLES = CConfigValue < Hyprlang : : INT > ( " binds:allow_workspace_cycles " ) ;
2022-11-20 18:50:22 +00:00
2024-06-07 17:52:15 +00:00
updateRelativeCursorCoords ( ) ;
2023-04-15 16:16:33 +01:00
g_pHyprRenderer - > damageWindow ( PWINDOW ) ;
2023-04-14 15:03:53 +01:00
if ( pWorkspace ) {
g_pCompositor - > moveWindowToWorkspaceSafe ( PWINDOW , pWorkspace ) ;
2024-10-27 18:45:38 +00:00
pMonitor = pWorkspace - > m_pMonitor . lock ( ) ;
2023-05-22 19:44:10 +02:00
g_pCompositor - > setActiveMonitor ( pMonitor ) ;
2022-12-06 20:31:44 +00:00
} else {
2024-10-27 18:45:38 +00:00
pWorkspace = g_pCompositor - > createNewWorkspace ( WORKSPACEID , PWINDOW - > monitorID ( ) , workspaceName , false ) ;
pMonitor = pWorkspace - > m_pMonitor . lock ( ) ;
2023-04-14 15:03:53 +01:00
g_pCompositor - > moveWindowToWorkspaceSafe ( PWINDOW , pWorkspace ) ;
2022-05-31 14:01:00 +02:00
}
2022-06-08 15:52:38 +02:00
2024-11-22 16:01:02 +00:00
POLDWS - > m_pLastFocusedWindow = POLDWS - > getFirstWindow ( ) ;
2023-05-22 19:44:10 +02:00
2023-11-15 04:32:02 -08:00
if ( pWorkspace - > m_bIsSpecialWorkspace )
pMonitor - > setSpecialWorkspace ( pWorkspace ) ;
else if ( POLDWS - > m_bIsSpecialWorkspace )
2024-10-27 18:45:38 +00:00
POLDWS - > m_pMonitor . lock ( ) - > setSpecialWorkspace ( nullptr ) ;
2023-11-15 04:32:02 -08:00
2024-05-23 05:01:12 -06:00
if ( * PALLOWWORKSPACECYCLES )
pWorkspace - > rememberPrevWorkspace ( POLDWS ) ;
2023-05-22 19:44:10 +02:00
pMonitor - > changeWorkspace ( pWorkspace ) ;
2023-04-14 15:03:53 +01:00
g_pCompositor - > focusWindow ( PWINDOW ) ;
2024-06-07 17:52:15 +00:00
PWINDOW - > warpCursor ( ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-03-27 19:32:50 +02:00
}
2022-04-09 13:26:55 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveActiveToWorkspaceSilent ( std : : string args ) {
2024-04-27 12:43:12 +01:00
PHLWINDOW PWINDOW = nullptr ;
2022-08-15 16:12:53 +02:00
const auto ORIGINALARGS = args ;
if ( args . contains ( ' , ' ) ) {
PWINDOW = g_pCompositor - > getWindowByRegex ( args . substr ( args . find_last_of ( ' , ' ) + 1 ) ) ;
2022-12-16 17:17:31 +00:00
args = args . substr ( 0 , args . find_last_of ( ' , ' ) ) ;
2022-08-15 16:12:53 +02:00
} else {
2024-04-27 12:43:12 +01:00
PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2022-08-15 16:12:53 +02:00
}
2022-10-14 20:46:32 +01:00
if ( ! PWINDOW )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2022-08-15 16:12:53 +02:00
2024-06-23 00:52:42 +03:00
const auto & [ WORKSPACEID , workspaceName ] = getWorkspaceIDNameFromString ( args ) ;
2023-11-12 13:34:42 +00:00
if ( WORKSPACEID = = WORKSPACE_INVALID ) {
2022-05-18 12:18:58 +02:00
Debug : : log ( ERR , " Error in moveActiveToWorkspaceSilent, invalid value " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Error in moveActiveToWorkspaceSilent, invalid value " } ;
2022-05-18 12:18:58 +02:00
}
2024-04-02 20:32:39 +01:00
if ( WORKSPACEID = = PWINDOW - > workspaceID ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2022-05-18 12:18:58 +02:00
2023-04-15 16:16:33 +01:00
g_pHyprRenderer - > damageWindow ( PWINDOW ) ;
2023-04-14 15:03:53 +01:00
auto pWorkspace = g_pCompositor - > getWorkspaceByID ( WORKSPACEID ) ;
const auto OLDMIDDLE = PWINDOW - > middle ( ) ;
2022-05-18 12:18:58 +02:00
2023-04-14 15:03:53 +01:00
if ( pWorkspace ) {
g_pCompositor - > moveWindowToWorkspaceSafe ( PWINDOW , pWorkspace ) ;
} else {
2024-10-27 18:45:38 +00:00
pWorkspace = g_pCompositor - > createNewWorkspace ( WORKSPACEID , PWINDOW - > monitorID ( ) , workspaceName , false ) ;
2023-04-14 15:03:53 +01:00
g_pCompositor - > moveWindowToWorkspaceSafe ( PWINDOW , pWorkspace ) ;
2022-09-12 21:05:52 +02:00
}
2022-05-18 12:18:58 +02:00
2024-05-05 17:16:00 +01:00
if ( PWINDOW = = g_pCompositor - > m_pLastWindow ) {
2024-02-04 15:40:20 +00:00
if ( const auto PATCOORDS = g_pCompositor - > vectorToWindowUnified ( OLDMIDDLE , RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING , PWINDOW ) ; PATCOORDS )
2024-01-02 13:50:30 +00:00
g_pCompositor - > focusWindow ( PATCOORDS ) ;
else
g_pInputManager - > refocus ( ) ;
}
2024-08-24 11:45:53 -05:00
return { } ;
2022-05-18 12:18:58 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveFocusTo ( std : : string args ) {
2024-05-22 13:51:46 -06:00
static auto PFULLCYCLE = CConfigValue < Hyprlang : : INT > ( " binds:movefocus_cycles_fullscreen " ) ;
static auto PMONITORFALLBACK = CConfigValue < Hyprlang : : INT > ( " binds:window_direction_monitor_fallback " ) ;
2024-12-14 01:58:57 +05:30
static auto PGROUPCYCLE = CConfigValue < Hyprlang : : INT > ( " binds:movefocus_cycles_groupfirst " ) ;
2024-05-22 13:51:46 -06:00
char arg = args [ 0 ] ;
2022-04-09 13:26:55 +02:00
2022-05-05 12:50:25 +02:00
if ( ! isDirection ( args ) ) {
2023-09-06 12:51:36 +02:00
Debug : : log ( ERR , " Cannot move focus in direction {}, unsupported direction. Supported: l,r,u/t,d/b " , arg ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = std : : format ( " Cannot move focus in direction {}, unsupported direction. Supported: l,r,u/t,d/b " , arg ) } ;
2022-04-09 13:26:55 +02:00
}
2024-04-27 12:43:12 +01:00
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2023-04-10 15:40:03 +02:00
if ( ! PLASTWINDOW ) {
2024-05-22 13:51:46 -06:00
if ( * PMONITORFALLBACK )
tryMoveFocusToMonitor ( g_pCompositor - > getMonitorInDirection ( arg ) ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-04-10 15:40:03 +02:00
}
2022-08-08 22:46:11 +02:00
2024-07-31 17:55:52 +00:00
const auto PWINDOWTOCHANGETO = * PFULLCYCLE & & PLASTWINDOW - > isFullscreen ( ) ?
2023-07-18 22:30:10 +00:00
( arg = = ' d ' | | arg = = ' b ' | | arg = = ' r ' ? g_pCompositor - > getNextWindowOnWorkspace ( PLASTWINDOW , true ) : g_pCompositor - > getPrevWindowOnWorkspace ( PLASTWINDOW , true ) ) :
g_pCompositor - > getWindowInDirection ( PLASTWINDOW , arg ) ;
2022-04-09 13:26:55 +02:00
2024-12-14 01:58:57 +05:30
// Prioritize focus change within groups if the window is a part of it.
2024-12-17 21:42:38 +05:30
if ( * PGROUPCYCLE & & PLASTWINDOW - > m_sGroupData . pNextWindow ) {
auto isTheOnlyGroupOnWs = ! PWINDOWTOCHANGETO & & g_pCompositor - > m_vMonitors . size ( ) = = 1 ;
if ( arg = = ' l ' & & ( PLASTWINDOW ! = PLASTWINDOW - > getGroupHead ( ) | | isTheOnlyGroupOnWs ) ) {
PLASTWINDOW - > setGroupCurrent ( PLASTWINDOW - > getGroupPrevious ( ) ) ;
return { } ;
}
2024-12-14 01:58:57 +05:30
2024-12-17 21:42:38 +05:30
else if ( arg = = ' r ' & & ( PLASTWINDOW ! = PLASTWINDOW - > getGroupTail ( ) | | isTheOnlyGroupOnWs ) ) {
PLASTWINDOW - > setGroupCurrent ( PLASTWINDOW - > m_sGroupData . pNextWindow . lock ( ) ) ;
return { } ;
2024-12-14 01:58:57 +05:30
}
}
2023-04-10 15:40:03 +02:00
// Found window in direction, switch to it
2022-04-09 13:33:44 +02:00
if ( PWINDOWTOCHANGETO ) {
2022-04-13 20:45:06 +02:00
switchToWindow ( PWINDOWTOCHANGETO ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-04-13 20:45:06 +02:00
}
2023-04-10 15:40:03 +02:00
2023-09-06 12:51:36 +02:00
Debug : : log ( LOG , " No window found in direction {}, looking for a monitor " , arg ) ;
2023-04-10 15:40:03 +02:00
2024-05-22 13:51:46 -06:00
if ( * PMONITORFALLBACK & & tryMoveFocusToMonitor ( g_pCompositor - > getMonitorInDirection ( arg ) ) )
2024-08-24 11:45:53 -05:00
return { } ;
2023-04-10 15:40:03 +02:00
2024-03-03 18:39:20 +00:00
static auto PNOFALLBACK = CConfigValue < Hyprlang : : INT > ( " general:no_focus_fallback " ) ;
if ( * PNOFALLBACK )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = std : : format ( " Nothing to focus to in direction {} " , arg ) } ;
2023-04-10 15:40:03 +02:00
2023-09-06 12:51:36 +02:00
Debug : : log ( LOG , " No monitor found in direction {}, falling back to next window on current workspace " , arg ) ;
2023-04-10 15:40:03 +02:00
const auto PWINDOWNEXT = g_pCompositor - > getNextWindowOnWorkspace ( PLASTWINDOW , true ) ;
if ( PWINDOWNEXT )
switchToWindow ( PWINDOWNEXT ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-04-12 16:44:18 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : focusUrgentOrLast ( std : : string args ) {
2023-01-21 11:18:55 +01:00
const auto PWINDOWURGENT = g_pCompositor - > getUrgentWindow ( ) ;
2024-04-27 12:43:12 +01:00
const auto PWINDOWPREV = g_pCompositor - > m_pLastWindow . lock ( ) ? ( g_pCompositor - > m_vWindowFocusHistory . size ( ) < 2 ? nullptr : g_pCompositor - > m_vWindowFocusHistory [ 1 ] . lock ( ) ) :
( g_pCompositor - > m_vWindowFocusHistory . empty ( ) ? nullptr : g_pCompositor - > m_vWindowFocusHistory [ 0 ] . lock ( ) ) ;
2023-01-21 11:18:55 +01:00
if ( ! PWINDOWURGENT & & ! PWINDOWPREV )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2023-01-21 11:18:55 +01:00
switchToWindow ( PWINDOWURGENT ? PWINDOWURGENT : PWINDOWPREV ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-01-21 11:18:55 +01:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : focusCurrentOrLast ( std : : string args ) {
2024-04-27 12:43:12 +01:00
const auto PWINDOWPREV = g_pCompositor - > m_pLastWindow . lock ( ) ? ( g_pCompositor - > m_vWindowFocusHistory . size ( ) < 2 ? nullptr : g_pCompositor - > m_vWindowFocusHistory [ 1 ] . lock ( ) ) :
( g_pCompositor - > m_vWindowFocusHistory . empty ( ) ? nullptr : g_pCompositor - > m_vWindowFocusHistory [ 0 ] . lock ( ) ) ;
2023-02-14 06:16:58 +05:30
if ( ! PWINDOWPREV )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2023-02-14 06:16:58 +05:30
switchToWindow ( PWINDOWPREV ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-02-14 06:16:58 +05:30
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : swapActive ( std : : string args ) {
2023-04-10 21:07:49 +02:00
char arg = args [ 0 ] ;
2022-04-20 16:18:58 +02:00
2023-04-10 21:07:49 +02:00
if ( ! isDirection ( args ) ) {
2023-09-06 12:51:36 +02:00
Debug : : log ( ERR , " Cannot move window in direction {}, unsupported direction. Supported: l,r,u/t,d/b " , arg ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = std : : format ( " Cannot move window in direction {}, unsupported direction. Supported: l,r,u/t,d/b " , arg ) } ;
2023-04-10 21:07:49 +02:00
}
2022-05-05 13:02:55 +02:00
2023-09-06 12:51:36 +02:00
Debug : : log ( LOG , " Swapping active window in direction {} " , arg ) ;
2024-04-27 12:43:12 +01:00
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2024-08-24 11:45:53 -05:00
if ( ! PLASTWINDOW )
return { . success = false , . error = " Window to swap with not found " } ;
if ( PLASTWINDOW - > isFullscreen ( ) )
return { . success = false , . error = " Can't swap fullscreen window " } ;
2022-05-05 13:02:55 +02:00
2023-04-10 21:07:49 +02:00
const auto PWINDOWTOCHANGETO = g_pCompositor - > getWindowInDirection ( PLASTWINDOW , arg ) ;
if ( ! PWINDOWTOCHANGETO )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window to swap with not found " } ;
2022-05-05 13:02:55 +02:00
2024-06-07 17:52:15 +00:00
updateRelativeCursorCoords ( ) ;
2023-04-10 21:07:49 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > switchWindows ( PLASTWINDOW , PWINDOWTOCHANGETO ) ;
2024-06-07 17:52:15 +00:00
PLASTWINDOW - > warpCursor ( ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-04-10 21:07:49 +02:00
}
2022-05-05 13:02:55 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveActiveTo ( std : : string args ) {
2024-04-17 13:04:16 +02:00
char arg = args [ 0 ] ;
bool silent = args . ends_with ( " silent " ) ;
if ( silent )
args = args . substr ( 0 , args . length ( ) - 7 ) ;
2022-05-05 13:02:55 +02:00
2023-10-15 20:07:23 +02:00
if ( args . starts_with ( " mon: " ) ) {
2023-04-10 21:07:49 +02:00
const auto PNEWMONITOR = g_pCompositor - > getMonitorFromString ( args . substr ( 4 ) ) ;
if ( ! PNEWMONITOR )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = std : : format ( " Monitor {} not found " , args . substr ( 4 ) ) } ;
2022-05-05 13:02:55 +02:00
2024-04-17 13:04:16 +02:00
if ( silent )
moveActiveToWorkspaceSilent ( PNEWMONITOR - > activeWorkspace - > getConfigName ( ) ) ;
else
moveActiveToWorkspace ( PNEWMONITOR - > activeWorkspace - > getConfigName ( ) ) ;
2024-05-22 13:51:46 -06:00
2024-08-24 11:45:53 -05:00
return { } ;
2022-05-05 13:02:55 +02:00
}
2022-05-05 12:50:25 +02:00
if ( ! isDirection ( args ) ) {
2023-09-06 12:51:36 +02:00
Debug : : log ( ERR , " Cannot move window in direction {}, unsupported direction. Supported: l,r,u/t,d/b " , arg ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = std : : format ( " Cannot move window in direction {}, unsupported direction. Supported: l,r,u/t,d/b " , arg ) } ;
2022-04-20 16:18:58 +02:00
}
2024-04-27 12:43:12 +01:00
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2022-04-20 16:18:58 +02:00
2024-08-24 11:45:53 -05:00
if ( ! PLASTWINDOW )
return { . success = false , . error = " Window to move not found " } ;
if ( PLASTWINDOW - > isFullscreen ( ) )
return { . success = false , . error = " Can't move fullscreen window " } ;
2022-04-20 16:18:58 +02:00
2023-09-11 05:23:57 -04:00
if ( PLASTWINDOW - > m_bIsFloating ) {
2024-07-05 20:46:38 +00:00
std : : optional < float > vPosx , vPosy ;
2024-10-27 18:45:38 +00:00
const auto PMONITOR = PLASTWINDOW - > m_pMonitor . lock ( ) ;
2024-07-05 20:46:38 +00:00
const auto BORDERSIZE = PLASTWINDOW - > getRealBorderSize ( ) ;
2023-09-11 05:23:57 -04:00
switch ( arg ) {
2024-07-05 20:46:38 +00:00
case ' l ' : vPosx = PMONITOR - > vecReservedTopLeft . x + BORDERSIZE + PMONITOR - > vecPosition . x ; break ;
case ' r ' : vPosx = PMONITOR - > vecSize . x - PMONITOR - > vecReservedBottomRight . x - PLASTWINDOW - > m_vRealSize . goal ( ) . x - BORDERSIZE + PMONITOR - > vecPosition . x ; break ;
2023-09-11 05:23:57 -04:00
case ' t ' :
2024-07-05 20:46:38 +00:00
case ' u ' : vPosy = PMONITOR - > vecReservedTopLeft . y + BORDERSIZE + PMONITOR - > vecPosition . y ; break ;
2023-09-11 05:23:57 -04:00
case ' b ' :
2024-07-05 20:46:38 +00:00
case ' d ' : vPosy = PMONITOR - > vecSize . y - PMONITOR - > vecReservedBottomRight . y - PLASTWINDOW - > m_vRealSize . goal ( ) . y - BORDERSIZE + PMONITOR - > vecPosition . y ; break ;
2023-09-11 05:23:57 -04:00
}
2024-07-05 20:46:38 +00:00
PLASTWINDOW - > m_vRealPosition = Vector2D ( vPosx . value_or ( PLASTWINDOW - > m_vRealPosition . goal ( ) . x ) , vPosy . value_or ( PLASTWINDOW - > m_vRealPosition . goal ( ) . y ) ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-09-11 05:23:57 -04:00
}
2023-04-10 21:07:49 +02:00
// If the window to change to is on the same workspace, switch them
2022-04-20 16:18:58 +02:00
const auto PWINDOWTOCHANGETO = g_pCompositor - > getWindowInDirection ( PLASTWINDOW , arg ) ;
2023-09-04 15:34:07 +02:00
if ( PWINDOWTOCHANGETO ) {
2024-06-07 17:52:15 +00:00
updateRelativeCursorCoords ( ) ;
2024-04-17 13:04:16 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > moveWindowTo ( PLASTWINDOW , args , silent ) ;
if ( ! silent )
2024-06-07 17:52:15 +00:00
PLASTWINDOW - > warpCursor ( ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-04-10 21:07:49 +02:00
}
2022-04-20 16:18:58 +02:00
2024-05-22 13:51:46 -06:00
static auto PMONITORFALLBACK = CConfigValue < Hyprlang : : INT > ( " binds:window_direction_monitor_fallback " ) ;
if ( ! * PMONITORFALLBACK )
2024-08-24 11:45:53 -05:00
return { } ;
2024-05-22 13:51:46 -06:00
2023-04-10 21:07:49 +02:00
// Otherwise, we always want to move to the next monitor in that direction
const auto PMONITORTOCHANGETO = g_pCompositor - > getMonitorInDirection ( arg ) ;
if ( ! PMONITORTOCHANGETO )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Nowhere to move active window to " } ;
2023-03-20 01:42:21 +00:00
2024-04-02 20:32:39 +01:00
const auto PWORKSPACE = PMONITORTOCHANGETO - > activeWorkspace ;
2024-04-17 13:04:16 +02:00
if ( silent )
moveActiveToWorkspaceSilent ( PWORKSPACE - > getConfigName ( ) ) ;
else
moveActiveToWorkspace ( PWORKSPACE - > getConfigName ( ) ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-04-20 16:18:58 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : toggleGroup ( std : : string args ) {
2024-04-27 12:43:12 +01:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2023-02-19 21:07:32 +00:00
if ( ! PWINDOW )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2023-02-19 21:07:32 +00:00
2024-07-31 17:55:52 +00:00
if ( PWINDOW - > isFullscreen ( ) )
g_pCompositor - > setWindowFullscreenInternal ( PWINDOW , FSMODE_NONE ) ;
2023-07-03 10:49:56 +00:00
2024-04-27 12:43:12 +01:00
if ( PWINDOW - > m_sGroupData . pNextWindow . expired ( ) )
2023-09-21 23:42:00 +00:00
PWINDOW - > createGroup ( ) ;
else
PWINDOW - > destroyGroup ( ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-04-12 16:44:18 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : changeGroupActive ( std : : string args ) {
2024-04-27 12:43:12 +01:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2023-02-19 21:07:32 +00:00
if ( ! PWINDOW )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2023-02-19 21:07:32 +00:00
2024-04-27 12:43:12 +01:00
if ( PWINDOW - > m_sGroupData . pNextWindow . expired ( ) )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " No next window in group " } ;
2023-02-19 21:07:32 +00:00
2024-04-27 12:43:12 +01:00
if ( PWINDOW - > m_sGroupData . pNextWindow . lock ( ) = = PWINDOW )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Only one window in group " } ;
2023-02-19 21:07:32 +00:00
2023-09-23 12:36:40 +00:00
if ( isNumber ( args , false ) ) {
// index starts from '1'; '0' means last window
const int INDEX = std : : stoi ( args ) ;
if ( INDEX > PWINDOW - > getGroupSize ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2023-09-23 12:36:40 +00:00
if ( INDEX = = 0 )
PWINDOW - > setGroupCurrent ( PWINDOW - > getGroupTail ( ) ) ;
else
PWINDOW - > setGroupCurrent ( PWINDOW - > getGroupWindowByIndex ( INDEX - 1 ) ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-09-23 12:36:40 +00:00
}
2023-02-24 17:24:51 +00:00
if ( args ! = " b " & & args ! = " prev " ) {
2024-04-27 12:43:12 +01:00
PWINDOW - > setGroupCurrent ( PWINDOW - > m_sGroupData . pNextWindow . lock ( ) ) ;
2023-02-24 17:24:51 +00:00
} else {
2023-09-04 13:13:39 +00:00
PWINDOW - > setGroupCurrent ( PWINDOW - > getGroupPrevious ( ) ) ;
2023-02-24 17:24:51 +00:00
}
2024-08-24 11:45:53 -05:00
return { } ;
2022-05-16 17:37:46 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : toggleSplit ( std : : string args ) {
2022-05-16 17:37:46 +02:00
SLayoutMessageHeader header ;
2024-04-27 12:43:12 +01:00
header . pWindow = g_pCompositor - > m_pLastWindow . lock ( ) ;
2023-03-11 17:58:34 +00:00
if ( ! header . pWindow )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2023-03-11 17:58:34 +00:00
2024-04-02 20:32:39 +01:00
const auto PWORKSPACE = header . pWindow - > m_pWorkspace ;
2023-03-11 17:58:34 +00:00
if ( PWORKSPACE - > m_bHasFullscreenWindow )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Can't split windows that already split " } ;
2023-03-11 17:58:34 +00:00
2022-05-16 17:37:46 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > layoutMessage ( header , " togglesplit " ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-04-20 16:53:41 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : swapSplit ( std : : string args ) {
2024-02-14 18:58:28 +01:00
SLayoutMessageHeader header ;
2024-04-27 12:43:12 +01:00
header . pWindow = g_pCompositor - > m_pLastWindow . lock ( ) ;
2024-02-14 18:58:28 +01:00
if ( ! header . pWindow )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2024-02-14 18:58:28 +01:00
2024-04-02 20:32:39 +01:00
const auto PWORKSPACE = header . pWindow - > m_pWorkspace ;
2024-02-14 18:58:28 +01:00
if ( PWORKSPACE - > m_bHasFullscreenWindow )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Can't split windows that already split " } ;
2024-02-14 18:58:28 +01:00
g_pLayoutManager - > getCurrentLayout ( ) - > layoutMessage ( header , " swapsplit " ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2024-02-14 18:58:28 +01:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : alterSplitRatio ( std : : string args ) {
2023-11-12 13:40:02 +00:00
std : : optional < float > splitResult ;
bool exact = false ;
2022-04-20 16:53:41 +02:00
2023-11-12 13:40:02 +00:00
if ( args . starts_with ( " exact " ) ) {
exact = true ;
splitResult = getPlusMinusKeywordResult ( args . substr ( 5 ) , 0 ) ;
} else
splitResult = getPlusMinusKeywordResult ( args , 0 ) ;
2022-04-20 16:53:41 +02:00
2023-11-12 13:40:02 +00:00
if ( ! splitResult . has_value ( ) ) {
2022-04-20 16:53:41 +02:00
Debug : : log ( ERR , " Splitratio invalid in alterSplitRatio! " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Splitratio invalid in alterSplitRatio! " } ;
2022-04-20 16:53:41 +02:00
}
2024-04-27 12:43:12 +01:00
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2022-04-20 16:53:41 +02:00
2022-10-14 20:46:32 +01:00
if ( ! PLASTWINDOW )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2022-04-20 16:53:41 +02:00
2023-11-12 13:40:02 +00:00
g_pLayoutManager - > getCurrentLayout ( ) - > alterSplitRatio ( PLASTWINDOW , splitResult . value ( ) , exact ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-05-05 12:50:25 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : focusMonitor ( std : : string arg ) {
2022-08-25 21:25:28 +02:00
const auto PMONITOR = g_pCompositor - > getMonitorFromString ( arg ) ;
2023-04-10 21:07:49 +02:00
tryMoveFocusToMonitor ( PMONITOR ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-05-18 12:18:58 +02:00
}
2022-05-22 11:52:39 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveCursorToCorner ( std : : string arg ) {
2022-05-22 11:52:39 +02:00
if ( ! isNumber ( arg ) ) {
Debug : : log ( ERR , " moveCursorToCorner, arg has to be a number. " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " moveCursorToCorner, arg has to be a number. " } ;
2022-05-22 11:52:39 +02:00
}
const auto CORNER = std : : stoi ( arg ) ;
if ( CORNER < 0 | | CORNER > 3 ) {
Debug : : log ( ERR , " moveCursorToCorner, corner not 0 - 3. " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " moveCursorToCorner, corner not 0 - 3. " } ;
2022-05-22 11:52:39 +02:00
}
2024-04-27 12:43:12 +01:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2022-05-22 11:52:39 +02:00
2022-10-14 20:46:32 +01:00
if ( ! PWINDOW )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Window not found " } ;
2022-05-22 11:52:39 +02:00
switch ( CORNER ) {
case 0 :
// bottom left
2024-05-05 22:18:10 +01:00
g_pCompositor - > warpCursorTo ( { PWINDOW - > m_vRealPosition . value ( ) . x , PWINDOW - > m_vRealPosition . value ( ) . y + PWINDOW - > m_vRealSize . value ( ) . y } , true ) ;
2022-05-22 11:52:39 +02:00
break ;
case 1 :
// bottom right
2024-05-05 22:18:10 +01:00
g_pCompositor - > warpCursorTo ( { PWINDOW - > m_vRealPosition . value ( ) . x + PWINDOW - > m_vRealSize . value ( ) . x , PWINDOW - > m_vRealPosition . value ( ) . y + PWINDOW - > m_vRealSize . value ( ) . y } ,
true ) ;
2022-05-22 11:52:39 +02:00
break ;
case 2 :
// top right
2024-05-05 22:18:10 +01:00
g_pCompositor - > warpCursorTo ( { PWINDOW - > m_vRealPosition . value ( ) . x + PWINDOW - > m_vRealSize . value ( ) . x , PWINDOW - > m_vRealPosition . value ( ) . y } , true ) ;
2022-05-22 11:52:39 +02:00
break ;
case 3 :
// top left
2024-05-05 22:18:10 +01:00
g_pCompositor - > warpCursorTo ( { PWINDOW - > m_vRealPosition . value ( ) . x , PWINDOW - > m_vRealPosition . value ( ) . y } , true ) ;
2022-05-22 11:52:39 +02:00
break ;
}
2024-08-24 11:45:53 -05:00
return { } ;
2022-05-26 19:05:32 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveCursor ( std : : string args ) {
2023-04-24 04:50:53 +10:00
std : : string x_str , y_str ;
2023-05-02 14:53:15 +01:00
int x , y ;
2023-04-24 04:50:53 +10:00
2023-05-02 14:53:15 +01:00
size_t i = args . find_first_of ( ' ' ) ;
2023-04-24 04:50:53 +10:00
if ( i = = std : : string : : npos ) {
Debug : : log ( ERR , " moveCursor, takes 2 arguments. " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " moveCursor, takes 2 arguments " } ;
2023-04-24 04:50:53 +10:00
}
x_str = args . substr ( 0 , i ) ;
y_str = args . substr ( i + 1 ) ;
if ( ! isNumber ( x_str ) ) {
Debug : : log ( ERR , " moveCursor, x argument has to be a number. " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " moveCursor, x argument has to be a number. " } ;
2023-04-24 04:50:53 +10:00
}
if ( ! isNumber ( y_str ) ) {
Debug : : log ( ERR , " moveCursor, y argument has to be a number. " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " moveCursor, y argument has to be a number. " } ;
2023-04-24 04:50:53 +10:00
}
x = std : : stoi ( x_str ) ;
y = std : : stoi ( y_str ) ;
2024-05-05 22:18:10 +01:00
g_pCompositor - > warpCursorTo ( { x , y } , true ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-04-24 04:50:53 +10:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : workspaceOpt ( std : : string args ) {
2022-09-25 20:07:48 +02:00
2022-05-26 19:05:32 +02:00
// current workspace
2024-04-02 20:32:39 +01:00
const auto PWORKSPACE = g_pCompositor - > m_pLastMonitor - > activeWorkspace ;
2022-05-26 19:05:32 +02:00
if ( ! PWORKSPACE )
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Workspace not found " } ; // ????
2022-05-26 19:05:32 +02:00
if ( args = = " allpseudo " ) {
PWORKSPACE - > m_bDefaultPseudo = ! PWORKSPACE - > m_bDefaultPseudo ;
// apply
2024-08-26 17:25:39 +02:00
for ( auto const & w : g_pCompositor - > m_vWindows ) {
2024-04-02 20:32:39 +01:00
if ( ! w - > m_bIsMapped | | w - > m_pWorkspace ! = PWORKSPACE )
2022-05-26 19:05:32 +02:00
continue ;
2022-06-30 15:44:26 +02:00
w - > m_bIsPseudotiled = PWORKSPACE - > m_bDefaultPseudo ;
2022-05-26 19:05:32 +02:00
}
} else if ( args = = " allfloat " ) {
PWORKSPACE - > m_bDefaultFloating = ! PWORKSPACE - > m_bDefaultFloating ;
// apply
// we make a copy because changeWindowFloatingMode might invalidate the iterator
2024-12-16 15:58:19 +00:00
std : : vector < PHLWINDOW > ptrs ;
2024-08-26 20:24:30 +02:00
for ( auto const & w : g_pCompositor - > m_vWindows )
2024-04-27 12:43:12 +01:00
ptrs . push_back ( w ) ;
2022-05-26 19:05:32 +02:00
2024-08-26 20:24:30 +02:00
for ( auto const & w : ptrs ) {
2024-04-02 20:32:39 +01:00
if ( ! w - > m_bIsMapped | | w - > m_pWorkspace ! = PWORKSPACE | | w - > isHidden ( ) )
2022-05-26 19:05:32 +02:00
continue ;
if ( ! w - > m_bRequestsFloat & & w - > m_bIsFloating ! = PWORKSPACE - > m_bDefaultFloating ) {
2024-03-02 01:35:17 +01:00
const auto SAVEDPOS = w - > m_vRealPosition . value ( ) ;
const auto SAVEDSIZE = w - > m_vRealSize . value ( ) ;
2022-05-26 19:05:32 +02:00
w - > m_bIsFloating = PWORKSPACE - > m_bDefaultFloating ;
g_pLayoutManager - > getCurrentLayout ( ) - > changeWindowFloatingMode ( w ) ;
if ( PWORKSPACE - > m_bDefaultFloating ) {
w - > m_vRealPosition . setValueAndWarp ( SAVEDPOS ) ;
w - > m_vRealSize . setValueAndWarp ( SAVEDSIZE ) ;
g_pXWaylandManager - > setWindowSize ( w , SAVEDSIZE ) ;
2024-03-02 01:35:17 +01:00
w - > m_vRealSize = w - > m_vRealSize . value ( ) + Vector2D ( 4 , 4 ) ;
w - > m_vRealPosition = w - > m_vRealPosition . value ( ) - Vector2D ( 2 , 2 ) ;
2022-05-26 19:05:32 +02:00
}
}
}
} else {
2023-09-06 21:45:37 +02:00
Debug : : log ( ERR , " Invalid arg in workspaceOpt, opt \" {} \" doesn't exist. " , args ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = std : : format ( " Invalid arg in workspaceOpt, opt \" {} \" doesn't exist. " , args ) } ;
2022-05-26 19:05:32 +02:00
}
// recalc mon
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( g_pCompositor - > m_pLastMonitor - > ID ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-05-29 00:00:47 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : renameWorkspace ( std : : string args ) {
2023-01-08 14:19:18 +01:00
try {
const auto FIRSTSPACEPOS = args . find_first_of ( ' ' ) ;
if ( FIRSTSPACEPOS ! = std : : string : : npos ) {
int workspace = std : : stoi ( args . substr ( 0 , FIRSTSPACEPOS ) ) ;
std : : string name = args . substr ( FIRSTSPACEPOS + 1 ) ;
2024-11-22 16:01:02 +00:00
if ( const auto & PWS = g_pCompositor - > getWorkspaceByID ( workspace ) ; PWS )
PWS - > rename ( name ) ;
else
return { . success = false , . error = " No such workspace " } ;
} else if ( const auto & PWS = g_pCompositor - > getWorkspaceByID ( std : : stoi ( args ) ) ; PWS )
PWS - > rename ( " " ) ;
else
return { . success = false , . error = " No such workspace " } ;
2024-08-24 11:45:53 -05:00
} catch ( std : : exception & e ) {
2024-12-07 18:51:18 +01:00
Debug : : log ( ERR , R " (Invalid arg in renameWorkspace, expected numeric id only or a numeric id and string name. " { } " : " { } " ) " , args , e . what ( ) ) ;
return { . success = false , . error = std : : format ( R " (Invalid arg in renameWorkspace, expected numeric id only or a numeric id and string name. " { } " : " { } " ) " , args , e . what ( ) ) } ;
2024-08-24 11:45:53 -05:00
}
return { } ;
2023-01-08 14:19:18 +01:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : exitHyprland ( std : : string argz ) {
2024-09-07 14:54:33 -05:00
g_pConfigManager - > dispatchExecShutdown ( ) ;
if ( g_pCompositor - > m_bFinalRequests )
return { } ; // Exiting deferred until requests complete
2024-07-24 12:07:36 -05:00
g_pCompositor - > stopCompositor ( ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-05-30 20:05:38 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveCurrentWorkspaceToMonitor ( std : : string args ) {
2024-10-19 23:03:29 +01:00
PHLMONITOR PMONITOR = g_pCompositor - > getMonitorFromString ( args ) ;
2022-05-30 20:05:38 +02:00
2024-02-10 00:47:00 +01:00
if ( ! PMONITOR ) {
Debug : : log ( ERR , " Ignoring moveCurrentWorkspaceToMonitor: monitor doesnt exist " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Ignoring moveCurrentWorkspaceToMonitor: monitor doesnt exist " } ;
2024-02-10 00:47:00 +01:00
}
2022-07-29 10:59:31 -04:00
2022-05-30 20:05:38 +02:00
// get the current workspace
2024-04-02 20:32:39 +01:00
const auto PCURRENTWORKSPACE = g_pCompositor - > m_pLastMonitor - > activeWorkspace ;
2024-02-10 00:47:00 +01:00
if ( ! PCURRENTWORKSPACE ) {
Debug : : log ( ERR , " moveCurrentWorkspaceToMonitor invalid workspace! " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " moveCurrentWorkspaceToMonitor invalid workspace! " } ;
2024-02-10 00:47:00 +01:00
}
2022-05-30 20:05:38 +02:00
g_pCompositor - > moveWorkspaceToMonitor ( PCURRENTWORKSPACE , PMONITOR ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-05-30 20:05:38 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveWorkspaceToMonitor ( std : : string args ) {
2022-07-06 16:50:11 +02:00
if ( ! args . contains ( ' ' ) )
2024-08-24 11:45:53 -05:00
return { } ;
2022-05-30 20:05:38 +02:00
std : : string workspace = args . substr ( 0 , args . find_first_of ( ' ' ) ) ;
2022-12-16 17:17:31 +00:00
std : : string monitor = args . substr ( args . find_first_of ( ' ' ) + 1 ) ;
2022-05-30 20:05:38 +02:00
2022-12-16 17:17:31 +00:00
const auto PMONITOR = g_pCompositor - > getMonitorFromString ( monitor ) ;
2022-05-30 20:05:38 +02:00
2022-12-16 17:17:31 +00:00
if ( ! PMONITOR ) {
2022-05-30 20:05:38 +02:00
Debug : : log ( ERR , " Ignoring moveWorkspaceToMonitor: monitor doesnt exist " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Ignoring moveWorkspaceToMonitor: monitor doesnt exist " } ;
2022-05-30 20:05:38 +02:00
}
2024-08-08 21:01:50 +02:00
const auto WORKSPACEID = getWorkspaceIDNameFromString ( workspace ) . id ;
2022-05-30 20:05:38 +02:00
2023-11-12 13:34:42 +00:00
if ( WORKSPACEID = = WORKSPACE_INVALID ) {
2022-05-30 20:05:38 +02:00
Debug : : log ( ERR , " moveWorkspaceToMonitor invalid workspace! " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " moveWorkspaceToMonitor invalid workspace! " } ;
2022-05-30 20:05:38 +02:00
}
const auto PWORKSPACE = g_pCompositor - > getWorkspaceByID ( WORKSPACEID ) ;
2022-05-31 18:47:32 +02:00
if ( ! PWORKSPACE ) {
Debug : : log ( ERR , " moveWorkspaceToMonitor workspace doesn't exist! " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " moveWorkspaceToMonitor workspace doesn't exist! " } ;
2022-05-31 18:47:32 +02:00
}
2022-05-30 20:05:38 +02:00
g_pCompositor - > moveWorkspaceToMonitor ( PWORKSPACE , PMONITOR ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-05-31 14:01:00 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : focusWorkspaceOnCurrentMonitor ( std : : string args ) {
2024-11-16 16:39:58 +00:00
auto [ workspaceID , workspaceName ] = getWorkspaceIDNameFromString ( args ) ;
2024-03-04 18:05:20 +01:00
if ( workspaceID = = WORKSPACE_INVALID ) {
2024-01-15 23:30:46 +08:00
Debug : : log ( ERR , " focusWorkspaceOnCurrentMonitor invalid workspace! " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " focusWorkspaceOnCurrentMonitor invalid workspace! " } ;
2024-01-15 23:30:46 +08:00
}
2024-10-19 23:03:29 +01:00
const auto PCURRMONITOR = g_pCompositor - > m_pLastMonitor . lock ( ) ;
2024-01-15 23:30:46 +08:00
if ( ! PCURRMONITOR ) {
Debug : : log ( ERR , " focusWorkspaceOnCurrentMonitor monitor doesn't exist! " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " focusWorkspaceOnCurrentMonitor monitor doesn't exist! " } ;
2024-01-15 23:30:46 +08:00
}
2024-03-04 18:05:20 +01:00
auto pWorkspace = g_pCompositor - > getWorkspaceByID ( workspaceID ) ;
2024-01-15 23:30:46 +08:00
2024-03-04 18:05:20 +01:00
if ( ! pWorkspace ) {
2024-11-16 16:39:58 +00:00
pWorkspace = g_pCompositor - > createNewWorkspace ( workspaceID , PCURRMONITOR - > ID , workspaceName ) ;
2024-01-15 23:30:46 +08:00
// we can skip the moving, since it's already on the current monitor
2024-03-04 18:05:20 +01:00
changeworkspace ( pWorkspace - > getConfigName ( ) ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2024-01-15 23:30:46 +08:00
}
2024-03-04 18:05:20 +01:00
static auto PBACKANDFORTH = CConfigValue < Hyprlang : : INT > ( " binds:workspace_back_and_forth " ) ;
2024-06-23 00:52:42 +03:00
const auto PREVWS = pWorkspace - > getPrevWorkspaceIDName ( false ) ;
2024-03-04 18:05:20 +01:00
2024-06-23 00:52:42 +03:00
if ( * PBACKANDFORTH & & PCURRMONITOR - > activeWorkspaceID ( ) = = workspaceID & & PREVWS . id ! = - 1 ) {
2024-03-04 18:05:20 +01:00
// Workspace to focus is previous workspace
2024-06-23 00:52:42 +03:00
pWorkspace = g_pCompositor - > getWorkspaceByID ( PREVWS . id ) ;
2024-03-04 18:05:20 +01:00
if ( ! pWorkspace )
2024-06-23 00:52:42 +03:00
pWorkspace = g_pCompositor - > createNewWorkspace ( PREVWS . id , PCURRMONITOR - > ID , PREVWS . name ) ;
2024-03-04 18:05:20 +01:00
workspaceID = pWorkspace - > m_iID ;
}
2024-10-27 18:45:38 +00:00
if ( pWorkspace - > m_pMonitor ! = PCURRMONITOR ) {
const auto POLDMONITOR = pWorkspace - > m_pMonitor . lock ( ) ;
2024-01-15 23:30:46 +08:00
if ( ! POLDMONITOR ) { // wat
Debug : : log ( ERR , " focusWorkspaceOnCurrentMonitor old monitor doesn't exist! " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " focusWorkspaceOnCurrentMonitor old monitor doesn't exist! " } ;
2024-01-15 23:30:46 +08:00
}
2024-04-02 20:32:39 +01:00
if ( POLDMONITOR - > activeWorkspaceID ( ) = = workspaceID ) {
2024-01-15 23:30:46 +08:00
g_pCompositor - > swapActiveWorkspaces ( POLDMONITOR , PCURRMONITOR ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2024-01-15 23:30:46 +08:00
} else {
2024-03-04 18:05:20 +01:00
g_pCompositor - > moveWorkspaceToMonitor ( pWorkspace , PCURRMONITOR , true ) ;
2024-01-15 23:30:46 +08:00
}
}
2024-03-04 18:05:20 +01:00
changeworkspace ( pWorkspace - > getConfigName ( ) ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2024-01-15 23:30:46 +08:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : toggleSpecialWorkspace ( std : : string args ) {
2024-06-23 00:52:42 +03:00
const auto & [ workspaceID , workspaceName ] = getWorkspaceIDNameFromString ( " special: " + args ) ;
2023-11-12 13:34:42 +00:00
if ( workspaceID = = WORKSPACE_INVALID | | ! g_pCompositor - > isWorkspaceSpecial ( workspaceID ) ) {
2022-11-27 22:42:22 +00:00
Debug : : log ( ERR , " Invalid workspace passed to special " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " Invalid workspace passed to special " } ;
2022-11-27 22:42:22 +00:00
}
2022-12-16 17:17:31 +00:00
bool requestedWorkspaceIsAlreadyOpen = false ;
2024-03-30 09:58:18 -07:00
const auto PMONITOR = g_pCompositor - > m_pLastMonitor ;
2024-08-08 21:01:50 +02:00
auto specialOpenOnMonitor = PMONITOR - > activeSpecialWorkspaceID ( ) ;
2022-05-31 14:01:00 +02:00
2024-08-26 20:24:30 +02:00
for ( auto const & m : g_pCompositor - > m_vMonitors ) {
2024-04-02 20:32:39 +01:00
if ( m - > activeSpecialWorkspaceID ( ) = = workspaceID ) {
2022-11-27 22:42:22 +00:00
requestedWorkspaceIsAlreadyOpen = true ;
2022-05-31 14:01:00 +02:00
break ;
}
}
2022-11-27 22:42:22 +00:00
if ( requestedWorkspaceIsAlreadyOpen & & specialOpenOnMonitor = = workspaceID ) {
// already open on this monitor
2023-09-06 12:51:36 +02:00
Debug : : log ( LOG , " Toggling special workspace {} to closed " , workspaceID ) ;
2023-04-14 15:03:53 +01:00
PMONITOR - > setSpecialWorkspace ( nullptr ) ;
2022-05-31 14:01:00 +02:00
} else {
2023-09-06 12:51:36 +02:00
Debug : : log ( LOG , " Toggling special workspace {} to open " , workspaceID ) ;
2022-11-27 22:42:22 +00:00
auto PSPECIALWORKSPACE = g_pCompositor - > getWorkspaceByID ( workspaceID ) ;
2022-07-07 19:01:42 +02:00
2023-08-25 18:05:08 +02:00
if ( ! PSPECIALWORKSPACE )
2022-12-06 20:31:44 +00:00
PSPECIALWORKSPACE = g_pCompositor - > createNewWorkspace ( workspaceID , PMONITOR - > ID , workspaceName ) ;
2022-07-07 19:01:42 +02:00
2023-04-14 15:03:53 +01:00
PMONITOR - > setSpecialWorkspace ( PSPECIALWORKSPACE ) ;
2022-08-31 17:02:44 +02:00
}
2024-08-24 11:45:53 -05:00
return { } ;
2022-06-06 13:48:17 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : forceRendererReload ( std : : string args ) {
2022-06-30 23:55:28 +02:00
bool overAgain = false ;
2024-08-26 20:24:30 +02:00
for ( auto const & m : g_pCompositor - > m_vMonitors ) {
2023-03-16 14:03:40 +00:00
if ( ! m - > output )
continue ;
2024-09-26 11:10:53 +01:00
auto rule = g_pConfigManager - > getMonitorRuleFor ( m ) ;
2024-10-19 23:03:29 +01:00
if ( ! g_pHyprRenderer - > applyMonitorRule ( m , & rule , true ) ) {
2022-06-30 23:55:28 +02:00
overAgain = true ;
break ;
}
2022-06-06 13:48:17 +02:00
}
2022-06-30 23:55:28 +02:00
if ( overAgain )
forceRendererReload ( args ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-06-06 19:32:14 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : resizeActive ( std : : string args ) {
2024-04-27 12:43:12 +01:00
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2024-07-31 17:55:52 +00:00
if ( ! PLASTWINDOW | | PLASTWINDOW - > isFullscreen ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2022-08-09 11:57:09 +03:00
2024-04-27 12:43:12 +01:00
const auto SIZ = g_pCompositor - > parseWindowVectorArgsRelative ( args , PLASTWINDOW - > m_vRealSize . goal ( ) ) ;
2022-06-06 19:32:14 +02:00
2023-05-15 15:16:06 +01:00
if ( SIZ . x < 1 | | SIZ . y < 1 )
2024-08-24 11:45:53 -05:00
return { } ;
2023-05-15 15:16:06 +01:00
2024-04-27 12:43:12 +01:00
g_pLayoutManager - > getCurrentLayout ( ) - > resizeActiveWindow ( SIZ - PLASTWINDOW - > m_vRealSize . goal ( ) ) ;
2022-06-23 10:14:59 +02:00
2024-04-27 12:43:12 +01:00
if ( PLASTWINDOW - > m_vRealSize . goal ( ) . x > 1 & & PLASTWINDOW - > m_vRealSize . goal ( ) . y > 1 )
PLASTWINDOW - > setHidden ( false ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-08-15 15:59:07 +02:00
}
2022-06-23 10:14:59 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveActive ( std : : string args ) {
2024-04-27 12:43:12 +01:00
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2024-07-31 17:55:52 +00:00
if ( ! PLASTWINDOW | | PLASTWINDOW - > isFullscreen ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2022-06-23 10:14:59 +02:00
2024-04-27 12:43:12 +01:00
const auto POS = g_pCompositor - > parseWindowVectorArgsRelative ( args , PLASTWINDOW - > m_vRealPosition . goal ( ) ) ;
2022-06-23 10:14:59 +02:00
2024-04-27 12:43:12 +01:00
g_pLayoutManager - > getCurrentLayout ( ) - > moveActiveWindow ( POS - PLASTWINDOW - > m_vRealPosition . goal ( ) ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-08-15 15:59:07 +02:00
}
2022-06-23 10:14:59 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveWindow ( std : : string args ) {
2022-06-23 10:14:59 +02:00
2022-08-15 15:59:07 +02:00
const auto WINDOWREGEX = args . substr ( args . find_first_of ( ' , ' ) + 1 ) ;
2022-12-16 17:17:31 +00:00
const auto MOVECMD = args . substr ( 0 , args . find_first_of ( ' , ' ) ) ;
2022-08-09 11:57:09 +03:00
2022-08-15 15:59:07 +02:00
const auto PWINDOW = g_pCompositor - > getWindowByRegex ( WINDOWREGEX ) ;
2022-06-23 10:14:59 +02:00
2022-08-15 15:59:07 +02:00
if ( ! PWINDOW ) {
Debug : : log ( ERR , " moveWindow: no window " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " moveWindow: no window " } ;
2022-06-06 19:32:14 +02:00
}
2024-07-31 17:55:52 +00:00
if ( PWINDOW - > isFullscreen ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2022-09-20 19:58:08 +01:00
2024-03-02 01:35:17 +01:00
const auto POS = g_pCompositor - > parseWindowVectorArgsRelative ( MOVECMD , PWINDOW - > m_vRealPosition . goal ( ) ) ;
2022-06-06 19:32:14 +02:00
2024-03-02 01:35:17 +01:00
g_pLayoutManager - > getCurrentLayout ( ) - > moveActiveWindow ( POS - PWINDOW - > m_vRealPosition . goal ( ) , PWINDOW ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-06-10 11:39:06 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : resizeWindow ( std : : string args ) {
2022-06-23 10:14:59 +02:00
2022-08-15 15:59:07 +02:00
const auto WINDOWREGEX = args . substr ( args . find_first_of ( ' , ' ) + 1 ) ;
2022-12-16 17:17:31 +00:00
const auto MOVECMD = args . substr ( 0 , args . find_first_of ( ' , ' ) ) ;
2022-06-23 10:14:59 +02:00
2022-08-15 15:59:07 +02:00
const auto PWINDOW = g_pCompositor - > getWindowByRegex ( WINDOWREGEX ) ;
2022-06-23 10:14:59 +02:00
2022-08-15 15:59:07 +02:00
if ( ! PWINDOW ) {
Debug : : log ( ERR , " resizeWindow: no window " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " resizeWindow: no window " } ;
2022-06-23 10:14:59 +02:00
}
2024-07-31 17:55:52 +00:00
if ( PWINDOW - > isFullscreen ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2022-09-20 19:58:08 +01:00
2024-03-02 01:35:17 +01:00
const auto SIZ = g_pCompositor - > parseWindowVectorArgsRelative ( MOVECMD , PWINDOW - > m_vRealSize . goal ( ) ) ;
2022-06-23 10:14:59 +02:00
2023-05-15 15:16:06 +01:00
if ( SIZ . x < 1 | | SIZ . y < 1 )
2024-08-24 11:45:53 -05:00
return { } ;
2023-05-15 15:16:06 +01:00
2024-03-02 01:35:17 +01:00
g_pLayoutManager - > getCurrentLayout ( ) - > resizeActiveWindow ( SIZ - PWINDOW - > m_vRealSize . goal ( ) , CORNER_NONE , PWINDOW ) ;
2022-06-23 10:14:59 +02:00
2024-03-02 01:35:17 +01:00
if ( PWINDOW - > m_vRealSize . goal ( ) . x > 1 & & PWINDOW - > m_vRealSize . goal ( ) . y > 1 )
2022-10-14 20:46:32 +01:00
PWINDOW - > setHidden ( false ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-06-23 10:14:59 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : circleNext ( std : : string arg ) {
2022-08-11 19:45:37 +02:00
2024-04-27 12:43:12 +01:00
if ( g_pCompositor - > m_pLastWindow . expired ( ) ) {
2022-10-28 21:31:39 +01:00
// if we have a clear focus, find the first window and get the next focusable.
2024-11-22 16:01:02 +00:00
const auto PWS = g_pCompositor - > m_pLastMonitor - > activeWorkspace ;
if ( PWS & & PWS - > getWindows ( ) > 0 ) {
const auto PWINDOW = PWS - > getFirstWindow ( ) ;
2022-10-28 21:31:39 +01:00
switchToWindow ( PWINDOW ) ;
}
2024-08-24 11:45:53 -05:00
return { } ;
2022-10-28 21:31:39 +01:00
}
2023-12-24 15:08:48 +01:00
CVarList args { arg , 0 , ' s ' , true } ;
std : : optional < bool > floatStatus = { } ;
if ( args . contains ( " tile " ) | | args . contains ( " tiled " ) )
floatStatus = false ;
else if ( args . contains ( " float " ) | | args . contains ( " floating " ) )
floatStatus = true ;
if ( args . contains ( " prev " ) | | args . contains ( " p " ) | | args . contains ( " last " ) | | args . contains ( " l " ) )
2024-04-27 12:43:12 +01:00
switchToWindow ( g_pCompositor - > getPrevWindowOnWorkspace ( g_pCompositor - > m_pLastWindow . lock ( ) , true , floatStatus ) ) ;
2022-08-11 19:45:37 +02:00
else
2024-04-27 12:43:12 +01:00
switchToWindow ( g_pCompositor - > getNextWindowOnWorkspace ( g_pCompositor - > m_pLastWindow . lock ( ) , true , floatStatus ) ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-06-10 11:39:06 +02:00
}
2022-06-10 12:06:27 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : focusWindow ( std : : string regexp ) {
2022-07-26 17:30:30 +02:00
const auto PWINDOW = g_pCompositor - > getWindowByRegex ( regexp ) ;
2022-07-17 19:00:12 -04:00
2022-07-26 17:30:30 +02:00
if ( ! PWINDOW )
2024-08-24 11:45:53 -05:00
return { } ;
2022-06-10 12:06:27 +02:00
2023-09-06 21:45:37 +02:00
Debug : : log ( LOG , " Focusing to window name: {} " , PWINDOW - > m_szTitle ) ;
2022-06-10 12:06:27 +02:00
2024-04-02 20:32:39 +01:00
const auto PWORKSPACE = PWINDOW - > m_pWorkspace ;
2024-02-25 17:05:20 -07:00
if ( ! PWORKSPACE ) {
Debug : : log ( ERR , " BUG THIS: null workspace in focusWindow " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " BUG THIS: null workspace in focusWindow " } ;
2024-02-25 17:05:20 -07:00
}
2024-06-07 17:52:15 +00:00
updateRelativeCursorCoords ( ) ;
2024-04-30 16:42:31 +01:00
if ( g_pCompositor - > m_pLastMonitor & & g_pCompositor - > m_pLastMonitor - > activeWorkspace ! = PWINDOW - > m_pWorkspace & &
g_pCompositor - > m_pLastMonitor - > activeSpecialWorkspace ! = PWINDOW - > m_pWorkspace ) {
2023-05-01 15:39:08 +01:00
Debug : : log ( LOG , " Fake executing workspace to move focus " ) ;
changeworkspace ( PWORKSPACE - > getConfigName ( ) ) ;
}
2024-02-25 17:05:20 -07:00
if ( PWORKSPACE - > m_bHasFullscreenWindow ) {
2024-11-22 16:01:02 +00:00
const auto FSWINDOW = PWORKSPACE - > getFullscreenWindow ( ) ;
2024-02-25 17:05:20 -07:00
const auto FSMODE = PWORKSPACE - > m_efFullscreenMode ;
2024-02-26 00:15:59 +00:00
if ( PWINDOW - > m_bIsFloating ) {
// don't make floating implicitly fs
if ( ! PWINDOW - > m_bCreatedOverFullscreen ) {
g_pCompositor - > changeWindowZOrder ( PWINDOW , true ) ;
g_pCompositor - > updateFullscreenFadeOnWorkspace ( PWORKSPACE ) ;
}
2024-02-25 17:05:20 -07:00
2024-02-26 00:15:59 +00:00
g_pCompositor - > focusWindow ( PWINDOW ) ;
} else {
if ( FSWINDOW ! = PWINDOW & & ! PWINDOW - > m_bPinned )
2024-07-31 17:55:52 +00:00
g_pCompositor - > setWindowFullscreenClient ( FSWINDOW , FSMODE_NONE ) ;
2024-02-25 17:05:20 -07:00
2024-02-26 00:15:59 +00:00
g_pCompositor - > focusWindow ( PWINDOW ) ;
if ( FSWINDOW ! = PWINDOW & & ! PWINDOW - > m_bPinned )
2024-07-31 17:55:52 +00:00
g_pCompositor - > setWindowFullscreenClient ( PWINDOW , FSMODE ) ;
2024-11-11 13:55:32 +00:00
// warp the position + size animation, otherwise it looks weird.
PWINDOW - > m_vRealPosition . warp ( ) ;
PWINDOW - > m_vRealSize . warp ( ) ;
2024-02-26 00:15:59 +00:00
}
} else
2024-02-25 17:05:20 -07:00
g_pCompositor - > focusWindow ( PWINDOW ) ;
2022-06-10 12:06:27 +02:00
2024-06-07 17:52:15 +00:00
PWINDOW - > warpCursor ( ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-06-10 12:06:27 +02:00
}
2022-06-22 20:23:20 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : tagWindow ( std : : string args ) {
2024-05-29 05:37:24 +08:00
PHLWINDOW PWINDOW = nullptr ;
CVarList vars { args , 0 , ' s ' , true } ;
if ( vars . size ( ) = = 1 )
PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
else if ( vars . size ( ) = = 2 )
PWINDOW = g_pCompositor - > getWindowByRegex ( vars [ 1 ] ) ;
else
2024-08-24 11:45:53 -05:00
return { } ;
2024-05-29 05:37:24 +08:00
if ( PWINDOW & & PWINDOW - > m_tags . applyTag ( vars [ 0 ] ) ) {
PWINDOW - > updateDynamicRules ( ) ;
g_pCompositor - > updateWindowAnimatedDecorationValues ( PWINDOW - > m_pSelf . lock ( ) ) ;
}
2024-08-24 11:45:53 -05:00
return { } ;
2024-05-29 05:37:24 +08:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : setSubmap ( std : : string submap ) {
2022-06-22 20:23:20 +02:00
if ( submap = = " reset " | | submap = = " " ) {
m_szCurrentSelectedSubmap = " " ;
Debug : : log ( LOG , " Reset active submap to the default one. " ) ;
2022-09-05 13:50:52 +02:00
g_pEventManager - > postEvent ( SHyprIPCEvent { " submap " , " " } ) ;
2023-02-19 20:54:53 +00:00
EMIT_HOOK_EVENT ( " submap " , m_szCurrentSelectedSubmap ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-06-22 20:23:20 +02:00
}
2024-11-18 19:56:26 +00:00
for ( const auto & k : g_pKeybindManager - > m_vKeybinds ) {
if ( k - > submap = = submap ) {
2022-06-22 20:23:20 +02:00
m_szCurrentSelectedSubmap = submap ;
2023-09-06 21:45:37 +02:00
Debug : : log ( LOG , " Changed keybind submap to {} " , submap ) ;
2022-09-05 13:50:52 +02:00
g_pEventManager - > postEvent ( SHyprIPCEvent { " submap " , submap } ) ;
2023-02-19 20:54:53 +00:00
EMIT_HOOK_EVENT ( " submap " , m_szCurrentSelectedSubmap ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-06-22 20:23:20 +02:00
}
}
2023-09-06 21:45:37 +02:00
Debug : : log ( ERR , " Cannot set submap {}, submap doesn't exist (wasn't registered!) " , submap ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = std : : format ( " Cannot set submap {}, submap doesn't exist (wasn't registered!) " , submap ) } ;
2022-06-22 20:23:20 +02:00
}
2022-07-26 17:30:30 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : pass ( std : : string regexp ) {
2022-07-26 17:30:30 +02:00
// find the first window passing the regex
const auto PWINDOW = g_pCompositor - > getWindowByRegex ( regexp ) ;
if ( ! PWINDOW ) {
Debug : : log ( ERR , " pass: window not found " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " pass: window not found " } ;
2022-07-26 17:30:30 +02:00
}
2024-05-10 18:27:57 +01:00
if ( ! g_pSeatManager - > keyboard ) {
2022-07-26 17:30:30 +02:00
Debug : : log ( ERR , " No kb in pass? " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " No kb in pass? " } ;
2022-07-26 17:30:30 +02:00
}
2024-06-25 06:46:49 -05:00
const auto XWTOXW = PWINDOW - > m_bIsX11 & & g_pCompositor - > m_pLastWindow . lock ( ) & & g_pCompositor - > m_pLastWindow - > m_bIsX11 ;
const auto LASTMOUSESURF = g_pSeatManager - > state . pointerFocus . lock ( ) ;
const auto LASTKBSURF = g_pSeatManager - > state . keyboardFocus . lock ( ) ;
2022-08-28 16:43:15 +02:00
2022-07-26 17:30:30 +02:00
// pass all mf shit
2022-08-28 17:01:48 +02:00
if ( ! XWTOXW ) {
if ( g_pKeybindManager - > m_uLastCode ! = 0 )
2024-06-08 10:07:59 +02:00
g_pSeatManager - > setKeyboardFocus ( PWINDOW - > m_pWLSurface - > resource ( ) ) ;
2022-08-28 17:01:48 +02:00
else
2024-06-08 10:07:59 +02:00
g_pSeatManager - > setPointerFocus ( PWINDOW - > m_pWLSurface - > resource ( ) , { 1 , 1 } ) ;
2022-08-28 17:01:48 +02:00
}
2022-09-25 20:07:48 +02:00
2024-05-10 18:27:57 +01:00
g_pSeatManager - > sendKeyboardMods ( g_pInputManager - > accumulateModsFromAllKBs ( ) , 0 , 0 , 0 ) ;
2022-08-08 20:31:48 +02:00
2022-08-28 16:43:15 +02:00
if ( g_pKeybindManager - > m_iPassPressed = = 1 ) {
2022-08-28 17:01:48 +02:00
if ( g_pKeybindManager - > m_uLastCode ! = 0 )
2024-05-10 18:27:57 +01:00
g_pSeatManager - > sendKeyboardKey ( g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastCode - 8 , WL_KEYBOARD_KEY_STATE_PRESSED ) ;
2022-08-28 17:01:48 +02:00
else
2024-05-10 18:27:57 +01:00
g_pSeatManager - > sendPointerButton ( g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastMouseCode , WL_POINTER_BUTTON_STATE_PRESSED ) ;
2022-08-28 16:43:15 +02:00
} else if ( g_pKeybindManager - > m_iPassPressed = = 0 )
2022-08-28 17:01:48 +02:00
if ( g_pKeybindManager - > m_uLastCode ! = 0 )
2024-05-10 18:27:57 +01:00
g_pSeatManager - > sendKeyboardKey ( g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastCode - 8 , WL_KEYBOARD_KEY_STATE_RELEASED ) ;
2022-08-28 17:01:48 +02:00
else
2024-05-10 18:27:57 +01:00
g_pSeatManager - > sendPointerButton ( g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastMouseCode , WL_POINTER_BUTTON_STATE_RELEASED ) ;
2022-08-27 19:29:28 +02:00
else {
// dynamic call of the dispatcher
2022-08-28 17:01:48 +02:00
if ( g_pKeybindManager - > m_uLastCode ! = 0 ) {
2024-05-10 18:27:57 +01:00
g_pSeatManager - > sendKeyboardKey ( g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastCode - 8 , WL_KEYBOARD_KEY_STATE_PRESSED ) ;
g_pSeatManager - > sendKeyboardKey ( g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastCode - 8 , WL_KEYBOARD_KEY_STATE_RELEASED ) ;
2022-08-28 17:01:48 +02:00
} else {
2024-05-10 18:27:57 +01:00
g_pSeatManager - > sendPointerButton ( g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastMouseCode , WL_POINTER_BUTTON_STATE_PRESSED ) ;
g_pSeatManager - > sendPointerButton ( g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastMouseCode , WL_POINTER_BUTTON_STATE_RELEASED ) ;
2022-09-25 20:07:48 +02:00
}
2022-08-27 19:29:28 +02:00
}
2022-07-26 17:30:30 +02:00
2022-08-28 16:43:15 +02:00
if ( XWTOXW )
2024-08-24 11:45:53 -05:00
return { } ;
2022-08-28 16:43:15 +02:00
// Massive hack:
2024-05-10 18:27:57 +01:00
// this will make g_pSeatManager NOT send the leave event to XWayland apps, provided we are not on an XWayland window already.
2022-08-28 16:43:15 +02:00
// please kill me
if ( PWINDOW - > m_bIsX11 ) {
2022-08-28 17:01:48 +02:00
if ( g_pKeybindManager - > m_uLastCode ! = 0 ) {
2024-06-08 10:07:59 +02:00
g_pSeatManager - > state . keyboardFocus . reset ( ) ;
2024-05-10 18:27:57 +01:00
g_pSeatManager - > state . keyboardFocusResource . reset ( ) ;
2022-08-28 17:01:48 +02:00
} else {
2024-06-08 10:07:59 +02:00
g_pSeatManager - > state . pointerFocus . reset ( ) ;
2024-05-10 18:27:57 +01:00
g_pSeatManager - > state . pointerFocusResource . reset ( ) ;
2022-08-28 17:01:48 +02:00
}
2022-08-28 16:43:15 +02:00
}
2024-05-10 18:27:57 +01:00
const auto SL = PWINDOW - > m_vRealPosition . goal ( ) - g_pInputManager - > getMouseCoordsInternal ( ) ;
2022-08-28 17:01:48 +02:00
if ( g_pKeybindManager - > m_uLastCode ! = 0 )
2024-06-25 06:46:49 -05:00
g_pSeatManager - > setKeyboardFocus ( LASTKBSURF ) ;
2022-08-28 17:01:48 +02:00
else
2024-06-25 06:46:49 -05:00
g_pSeatManager - > setPointerFocus ( LASTMOUSESURF , SL ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-07-28 12:00:10 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : sendshortcut ( std : : string args ) {
2024-05-24 20:58:26 +02:00
// args=<NEW_MODKEYS><NEW_KEY>[,WINDOW_RULES]
const auto ARGS = CVarList ( args , 3 ) ;
if ( ARGS . size ( ) ! = 3 ) {
Debug : : log ( ERR , " sendshortcut: invalid args " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " sendshortcut: invalid args " } ;
2024-05-24 20:58:26 +02:00
}
const auto MOD = g_pKeybindManager - > stringToModMask ( ARGS [ 0 ] ) ;
const auto KEY = ARGS [ 1 ] ;
uint32_t keycode = 0 ;
2024-12-07 18:51:18 +01:00
bool isMouse = false ;
2024-05-24 20:58:26 +02:00
// similar to parseKey in ConfigManager
if ( isNumber ( KEY ) & & std : : stoi ( KEY ) > 9 )
keycode = std : : stoi ( KEY ) ;
else if ( KEY . compare ( 0 , 5 , " code: " ) = = 0 & & isNumber ( KEY . substr ( 5 ) ) )
keycode = std : : stoi ( KEY . substr ( 5 ) ) ;
else if ( KEY . compare ( 0 , 6 , " mouse: " ) = = 0 & & isNumber ( KEY . substr ( 6 ) ) ) {
keycode = std : : stoi ( KEY . substr ( 6 ) ) ;
2024-12-07 18:51:18 +01:00
isMouse = true ;
2024-05-24 20:58:26 +02:00
if ( keycode < 272 ) {
Debug : : log ( ERR , " sendshortcut: invalid mouse button " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " sendshortcut: invalid mouse button " } ;
2024-05-24 20:58:26 +02:00
}
} else {
// here, we need to find the keycode from the key name
// this is not possible through xkb's lib, so we need to iterate through all keycodes
// once found, we save it to the cache
const auto KEYSYM = xkb_keysym_from_name ( KEY . c_str ( ) , XKB_KEYSYM_CASE_INSENSITIVE ) ;
keycode = 0 ;
const auto KB = g_pSeatManager - > keyboard ;
if ( ! KB ) {
Debug : : log ( ERR , " sendshortcut: no kb " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " sendshortcut: no kb " } ;
2024-05-24 20:58:26 +02:00
}
const auto KEYPAIRSTRING = std : : format ( " {}{} " , ( uintptr_t ) KB . get ( ) , KEY ) ;
if ( ! g_pKeybindManager - > m_mKeyToCodeCache . contains ( KEYPAIRSTRING ) ) {
2024-07-21 13:09:54 +02:00
xkb_keymap * km = KB - > xkbKeymap ;
xkb_state * ks = KB - > xkbState ;
2024-05-24 20:58:26 +02:00
xkb_keycode_t keycode_min , keycode_max ;
keycode_min = xkb_keymap_min_keycode ( km ) ;
keycode_max = xkb_keymap_max_keycode ( km ) ;
for ( xkb_keycode_t kc = keycode_min ; kc < = keycode_max ; + + kc ) {
xkb_keysym_t sym = xkb_state_key_get_one_sym ( ks , kc ) ;
if ( sym = = KEYSYM ) {
keycode = kc ;
g_pKeybindManager - > m_mKeyToCodeCache [ KEYPAIRSTRING ] = keycode ;
}
}
if ( ! keycode ) {
Debug : : log ( ERR , " sendshortcut: key not found " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " sendshortcut: key not found " } ;
2024-05-24 20:58:26 +02:00
}
} else
keycode = g_pKeybindManager - > m_mKeyToCodeCache [ KEYPAIRSTRING ] ;
}
if ( ! keycode ) {
Debug : : log ( ERR , " sendshortcut: invalid key " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " sendshortcut: invalid key " } ;
2024-05-24 20:58:26 +02:00
}
const std : : string regexp = ARGS [ 2 ] ;
PHLWINDOW PWINDOW = nullptr ;
2024-06-08 10:07:59 +02:00
const auto LASTSURFACE = g_pCompositor - > m_pLastFocus . lock ( ) ;
2024-05-24 20:58:26 +02:00
//if regexp is not empty, send shortcut to current window
//else, dont change focus
if ( regexp ! = " " ) {
PWINDOW = g_pCompositor - > getWindowByRegex ( regexp ) ;
if ( ! PWINDOW ) {
Debug : : log ( ERR , " sendshortcut: window not found " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " sendshortcut: window not found " } ;
2024-05-24 20:58:26 +02:00
}
if ( ! g_pSeatManager - > keyboard ) {
Debug : : log ( ERR , " No kb in sendshortcut? " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " No kb in sendshortcut? " } ;
2024-05-24 20:58:26 +02:00
}
if ( ! isMouse )
2024-06-08 10:07:59 +02:00
g_pSeatManager - > setKeyboardFocus ( PWINDOW - > m_pWLSurface - > resource ( ) ) ;
2024-05-24 20:58:26 +02:00
else
2024-06-08 10:07:59 +02:00
g_pSeatManager - > setPointerFocus ( PWINDOW - > m_pWLSurface - > resource ( ) , { 1 , 1 } ) ;
2024-05-24 20:58:26 +02:00
}
//copied the rest from pass and modified it
// if wl -> xwl, activate destination
if ( PWINDOW & & PWINDOW - > m_bIsX11 & & g_pCompositor - > m_pLastWindow & & ! g_pCompositor - > m_pLastWindow - > m_bIsX11 )
2024-06-08 10:07:59 +02:00
g_pXWaylandManager - > activateSurface ( PWINDOW - > m_pWLSurface - > resource ( ) , true ) ;
2024-05-24 20:58:26 +02:00
// if xwl -> xwl, send to current. Timing issues make this not work.
if ( PWINDOW & & PWINDOW - > m_bIsX11 & & g_pCompositor - > m_pLastWindow & & g_pCompositor - > m_pLastWindow - > m_bIsX11 )
PWINDOW = nullptr ;
g_pSeatManager - > sendKeyboardMods ( MOD , 0 , 0 , 0 ) ;
if ( g_pKeybindManager - > m_iPassPressed = = 1 ) {
if ( ! isMouse )
g_pSeatManager - > sendKeyboardKey ( g_pKeybindManager - > m_uTimeLastMs , keycode - 8 , WL_KEYBOARD_KEY_STATE_PRESSED ) ;
else
g_pSeatManager - > sendPointerButton ( g_pKeybindManager - > m_uTimeLastMs , keycode , WL_POINTER_BUTTON_STATE_PRESSED ) ;
} else if ( g_pKeybindManager - > m_iPassPressed = = 0 ) {
if ( ! isMouse )
g_pSeatManager - > sendKeyboardKey ( g_pKeybindManager - > m_uTimeLastMs , keycode - 8 , WL_KEYBOARD_KEY_STATE_RELEASED ) ;
else
g_pSeatManager - > sendPointerButton ( g_pKeybindManager - > m_uTimeLastMs , keycode , WL_POINTER_BUTTON_STATE_RELEASED ) ;
} else {
// dynamic call of the dispatcher
if ( ! isMouse ) {
g_pSeatManager - > sendKeyboardKey ( g_pKeybindManager - > m_uTimeLastMs , keycode - 8 , WL_KEYBOARD_KEY_STATE_PRESSED ) ;
g_pSeatManager - > sendKeyboardKey ( g_pKeybindManager - > m_uTimeLastMs , keycode - 8 , WL_KEYBOARD_KEY_STATE_RELEASED ) ;
} else {
g_pSeatManager - > sendPointerButton ( g_pKeybindManager - > m_uTimeLastMs , keycode , WL_POINTER_BUTTON_STATE_PRESSED ) ;
g_pSeatManager - > sendPointerButton ( g_pKeybindManager - > m_uTimeLastMs , keycode , WL_POINTER_BUTTON_STATE_RELEASED ) ;
}
}
2024-08-30 15:06:49 +02:00
g_pSeatManager - > sendKeyboardMods ( 0 , 0 , 0 , 0 ) ;
2024-05-24 20:58:26 +02:00
if ( ! PWINDOW )
2024-08-24 11:45:53 -05:00
return { } ;
2024-05-24 20:58:26 +02:00
if ( PWINDOW - > m_bIsX11 ) { //xwayland hack, see pass
if ( ! isMouse ) {
2024-06-08 10:07:59 +02:00
g_pSeatManager - > state . keyboardFocus . reset ( ) ;
2024-05-24 20:58:26 +02:00
g_pSeatManager - > state . keyboardFocusResource . reset ( ) ;
} else {
2024-06-08 10:07:59 +02:00
g_pSeatManager - > state . pointerFocus . reset ( ) ;
2024-05-24 20:58:26 +02:00
g_pSeatManager - > state . pointerFocusResource . reset ( ) ;
}
}
const auto SL = PWINDOW - > m_vRealPosition . goal ( ) - g_pInputManager - > getMouseCoordsInternal ( ) ;
if ( ! isMouse )
g_pSeatManager - > setKeyboardFocus ( LASTSURFACE ) ;
else
g_pSeatManager - > setPointerFocus ( LASTSURFACE , SL ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2024-05-24 20:58:26 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : layoutmsg ( std : : string msg ) {
2024-04-27 12:43:12 +01:00
SLayoutMessageHeader hd = { g_pCompositor - > m_pLastWindow . lock ( ) } ;
2022-07-28 12:00:10 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > layoutMessage ( hd , msg ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-07-28 12:07:41 +02:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : dpms ( std : : string arg ) {
SDispatchResult res ;
bool enable = arg . starts_with ( " on " ) ;
std : : string port = " " ;
2022-10-05 10:31:47 +01:00
2024-09-26 04:08:50 +05:00
bool isToggle = arg . starts_with ( " toggle " ) ;
2023-06-20 21:35:54 +02:00
if ( arg . find_first_of ( ' ' ) ! = std : : string : : npos )
2022-10-05 10:31:47 +01:00
port = arg . substr ( arg . find_first_of ( ' ' ) + 1 ) ;
2022-07-30 23:51:13 +02:00
2024-08-26 20:24:30 +02:00
for ( auto const & m : g_pCompositor - > m_vMonitors ) {
2022-10-05 10:31:47 +01:00
if ( ! port . empty ( ) & & m - > szName ! = port )
continue ;
2024-09-26 04:08:50 +05:00
if ( isToggle )
enable = ! m - > dpmsStatus ;
2024-08-06 14:52:19 +01:00
m - > output - > state - > resetExplicitFences ( ) ;
2024-07-21 13:09:54 +02:00
m - > output - > state - > setEnabled ( enable ) ;
2022-09-25 20:07:48 +02:00
2022-10-05 18:14:11 +01:00
m - > dpmsStatus = enable ;
2024-01-28 01:57:13 +00:00
if ( ! m - > state . commit ( ) ) {
2023-09-06 21:45:37 +02:00
Debug : : log ( ERR , " Couldn't commit output {} " , m - > szName ) ;
2024-08-24 11:45:53 -05:00
res . success = false ;
res . error = " Couldn't commit output {} " ;
2022-07-30 23:51:13 +02:00
}
2022-07-31 12:39:49 +02:00
if ( enable )
2024-10-19 23:03:29 +01:00
g_pHyprRenderer - > damageMonitor ( m ) ;
2024-04-29 01:28:26 +01:00
m - > events . dpmsChanged . emit ( ) ;
2022-07-30 23:51:13 +02:00
}
2022-07-31 15:46:42 +02:00
g_pCompositor - > m_bDPMSStateON = enable ;
2024-06-25 03:55:54 -07:00
g_pPointerManager - > recheckEnteredOutputs ( ) ;
2024-08-24 11:45:53 -05:00
return res ;
2022-07-30 23:51:13 +02:00
}
2022-08-24 21:40:36 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : swapnext ( std : : string arg ) {
2022-08-24 21:40:36 +02:00
2024-04-27 12:43:12 +01:00
PHLWINDOW toSwap = nullptr ;
2022-08-24 21:40:36 +02:00
2024-04-27 12:43:12 +01:00
if ( g_pCompositor - > m_pLastWindow . expired ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2022-08-24 21:40:36 +02:00
2024-04-27 12:43:12 +01:00
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2022-08-24 21:40:36 +02:00
2024-05-05 17:16:00 +01:00
const auto PLASTCYCLED =
validMapped ( g_pCompositor - > m_pLastWindow - > m_pLastCycledWindow ) & & g_pCompositor - > m_pLastWindow - > m_pLastCycledWindow - > m_pWorkspace = = PLASTWINDOW - > m_pWorkspace ?
g_pCompositor - > m_pLastWindow - > m_pLastCycledWindow . lock ( ) :
2022-12-16 17:17:31 +00:00
nullptr ;
2022-08-24 22:01:25 +02:00
2022-08-24 21:40:36 +02:00
if ( arg = = " last " | | arg = = " l " | | arg = = " prev " | | arg = = " p " )
2022-09-29 16:53:31 +01:00
toSwap = g_pCompositor - > getPrevWindowOnWorkspace ( PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW , true ) ;
2022-08-24 21:40:36 +02:00
else
2022-09-29 16:53:31 +01:00
toSwap = g_pCompositor - > getNextWindowOnWorkspace ( PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW , true ) ;
2022-08-24 22:01:25 +02:00
// sometimes we may come back to ourselves.
if ( toSwap = = PLASTWINDOW ) {
if ( arg = = " last " | | arg = = " l " | | arg = = " prev " | | arg = = " p " )
2024-08-26 18:02:44 +02:00
toSwap = g_pCompositor - > getPrevWindowOnWorkspace ( PLASTWINDOW , true ) ;
2022-08-24 22:01:25 +02:00
else
2022-09-29 16:53:31 +01:00
toSwap = g_pCompositor - > getNextWindowOnWorkspace ( PLASTWINDOW , true ) ;
2022-08-24 22:01:25 +02:00
}
2022-08-24 21:40:36 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > switchWindows ( PLASTWINDOW , toSwap ) ;
2022-08-24 22:01:25 +02:00
PLASTWINDOW - > m_pLastCycledWindow = toSwap ;
2022-08-24 21:40:36 +02:00
g_pCompositor - > focusWindow ( PLASTWINDOW ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-08-24 21:40:36 +02:00
}
2022-08-25 21:25:28 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : swapActiveWorkspaces ( std : : string args ) {
2022-08-25 21:25:28 +02:00
const auto MON1 = args . substr ( 0 , args . find_first_of ( ' ' ) ) ;
const auto MON2 = args . substr ( args . find_first_of ( ' ' ) + 1 ) ;
const auto PMON1 = g_pCompositor - > getMonitorFromString ( MON1 ) ;
const auto PMON2 = g_pCompositor - > getMonitorFromString ( MON2 ) ;
2023-05-17 14:31:03 +02:00
if ( ! PMON1 | | ! PMON2 | | PMON1 = = PMON2 )
2024-08-24 11:45:53 -05:00
return { } ;
2022-08-25 21:25:28 +02:00
g_pCompositor - > swapActiveWorkspaces ( PMON1 , PMON2 ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-08-25 21:25:28 +02:00
}
2022-09-10 13:11:02 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : pinActive ( std : : string args ) {
2023-01-08 18:37:24 +01:00
2024-04-27 12:43:12 +01:00
PHLWINDOW PWINDOW = nullptr ;
2023-01-08 18:37:24 +01:00
2024-02-17 23:44:22 +01:00
if ( args ! = " active " & & args . length ( ) > 1 )
2023-01-08 18:37:24 +01:00
PWINDOW = g_pCompositor - > getWindowByRegex ( args ) ;
2023-06-20 21:35:54 +02:00
else
2024-04-27 12:43:12 +01:00
PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2023-01-08 18:37:24 +01:00
if ( ! PWINDOW ) {
Debug : : log ( ERR , " pin: window not found " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " pin: window not found " } ;
2023-01-08 18:37:24 +01:00
}
2022-09-10 13:11:02 +02:00
2024-07-31 17:55:52 +00:00
if ( ! PWINDOW - > m_bIsFloating | | PWINDOW - > isFullscreen ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2023-01-08 18:37:24 +01:00
2024-07-31 16:54:07 +01:00
PWINDOW - > m_bPinned = ! PWINDOW - > m_bPinned ;
2024-10-27 18:45:38 +00:00
const auto PMONITOR = PWINDOW - > m_pMonitor . lock ( ) ;
2024-07-31 16:54:07 +01:00
if ( ! PMONITOR ) {
Debug : : log ( ERR , " pin: monitor not found " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " pin: window not found " } ;
2024-07-31 16:54:07 +01:00
}
PWINDOW - > m_pWorkspace = PMONITOR - > activeWorkspace ;
2022-09-10 13:11:02 +02:00
2023-01-08 18:37:24 +01:00
PWINDOW - > updateDynamicRules ( ) ;
g_pCompositor - > updateWindowAnimatedDecorationValues ( PWINDOW ) ;
2022-11-15 11:21:26 +01:00
2024-04-02 20:32:39 +01:00
const auto PWORKSPACE = PWINDOW - > m_pWorkspace ;
2022-09-10 13:11:02 +02:00
2024-02-04 15:40:20 +00:00
PWORKSPACE - > m_pLastFocusedWindow = g_pCompositor - > vectorToWindowUnified ( g_pInputManager - > getMouseCoordsInternal ( ) , RESERVED_EXTENTS | INPUT_EXTENTS ) ;
2024-03-18 18:11:20 +00:00
2024-04-27 12:43:12 +01:00
g_pEventManager - > postEvent ( SHyprIPCEvent { " pin " , std : : format ( " {:x},{} " , ( uintptr_t ) PWINDOW . get ( ) , ( int ) PWINDOW - > m_bPinned ) } ) ;
2024-03-18 18:11:20 +00:00
EMIT_HOOK_EVENT ( " pin " , PWINDOW ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-09-10 13:11:02 +02:00
}
2022-09-19 19:04:48 +01:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : mouse ( std : : string args ) {
2023-08-08 16:52:20 +00:00
const auto ARGS = CVarList ( args . substr ( 1 ) , 2 , ' ' ) ;
2022-09-19 19:04:48 +01:00
const auto PRESSED = args [ 0 ] = = ' 1 ' ;
2024-07-27 16:46:19 +00:00
if ( ! PRESSED ) {
2024-08-24 11:45:53 -05:00
return changeMouseBindMode ( MBIND_INVALID ) ;
2024-07-27 16:46:19 +00:00
}
2023-08-08 16:52:20 +00:00
if ( ARGS [ 0 ] = = " movewindow " ) {
2024-08-24 11:45:53 -05:00
return changeMouseBindMode ( MBIND_MOVE ) ;
2024-07-27 16:46:19 +00:00
} else {
try {
switch ( std : : stoi ( ARGS [ 1 ] ) ) {
2024-08-24 11:45:53 -05:00
case 1 : return changeMouseBindMode ( MBIND_RESIZE_FORCE_RATIO ) ; break ;
case 2 : return changeMouseBindMode ( MBIND_RESIZE_BLOCK_RATIO ) ; break ;
default : return changeMouseBindMode ( MBIND_RESIZE ) ;
2024-07-27 16:46:19 +00:00
}
2024-08-24 11:45:53 -05:00
} catch ( std : : exception & e ) { return changeMouseBindMode ( MBIND_RESIZE ) ; }
2024-07-27 16:46:19 +00:00
}
}
2022-09-20 10:02:20 +01:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : changeMouseBindMode ( const eMouseBindMode MODE ) {
2024-07-27 16:46:19 +00:00
if ( MODE ! = MBIND_INVALID ) {
if ( ! g_pInputManager - > currentlyDraggedWindow . expired ( ) | | g_pInputManager - > dragMode ! = MBIND_INVALID )
2024-08-24 11:45:53 -05:00
return { } ;
2023-08-30 15:39:22 +00:00
2024-07-27 16:46:19 +00:00
const auto MOUSECOORDS = g_pInputManager - > getMouseCoordsInternal ( ) ;
const PHLWINDOW PWINDOW = g_pCompositor - > vectorToWindowUnified ( MOUSECOORDS , RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING ) ;
2022-09-19 19:04:48 +01:00
2024-07-27 16:46:19 +00:00
if ( ! PWINDOW )
2024-08-24 11:45:53 -05:00
return SDispatchResult { . passEvent = true } ;
2023-10-29 20:14:47 +00:00
2024-07-31 17:55:52 +00:00
if ( ! PWINDOW - > isFullscreen ( ) & & MODE = = MBIND_MOVE )
2024-07-27 16:46:19 +00:00
PWINDOW - > checkInputOnDecos ( INPUT_TYPE_DRAG_START , MOUSECOORDS ) ;
2022-09-20 10:02:20 +01:00
2024-07-27 16:46:19 +00:00
if ( g_pInputManager - > currentlyDraggedWindow . expired ( ) )
g_pInputManager - > currentlyDraggedWindow = PWINDOW ;
g_pInputManager - > dragMode = MODE ;
g_pLayoutManager - > getCurrentLayout ( ) - > onBeginDragWindow ( ) ;
} else {
if ( g_pInputManager - > currentlyDraggedWindow . expired ( ) | | g_pInputManager - > dragMode = = MBIND_INVALID )
2024-08-24 11:45:53 -05:00
return { } ;
2024-07-27 16:46:19 +00:00
g_pLayoutManager - > getCurrentLayout ( ) - > onEndDragWindow ( ) ;
g_pInputManager - > dragMode = MODE ;
2022-09-19 19:04:48 +01:00
}
2024-08-24 11:45:53 -05:00
return { } ;
2022-09-19 19:04:48 +01:00
}
2022-10-14 14:22:20 +01:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : bringActiveToTop ( std : : string args ) {
2024-05-05 17:16:00 +01:00
if ( g_pCompositor - > m_pLastWindow . lock ( ) & & g_pCompositor - > m_pLastWindow - > m_bIsFloating )
2024-04-27 12:43:12 +01:00
g_pCompositor - > changeWindowZOrder ( g_pCompositor - > m_pLastWindow . lock ( ) , true ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-09-21 17:18:26 -04:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : alterZOrder ( std : : string args ) {
2023-09-21 17:18:26 -04:00
const auto WINDOWREGEX = args . substr ( args . find_first_of ( ' , ' ) + 1 ) ;
const auto POSITION = args . substr ( 0 , args . find_first_of ( ' , ' ) ) ;
auto PWINDOW = g_pCompositor - > getWindowByRegex ( WINDOWREGEX ) ;
2024-05-05 17:16:00 +01:00
if ( ! PWINDOW & & g_pCompositor - > m_pLastWindow . lock ( ) & & g_pCompositor - > m_pLastWindow - > m_bIsFloating )
2024-04-27 12:43:12 +01:00
PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2023-09-21 17:18:26 -04:00
if ( ! PWINDOW ) {
Debug : : log ( ERR , " alterZOrder: no window " ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " alterZOrder: no window " } ;
2023-09-21 17:18:26 -04:00
}
if ( POSITION = = " top " )
2024-12-07 18:51:18 +01:00
g_pCompositor - > changeWindowZOrder ( PWINDOW , true ) ;
2023-09-21 17:18:26 -04:00
else if ( POSITION = = " bottom " )
2024-12-07 18:51:18 +01:00
g_pCompositor - > changeWindowZOrder ( PWINDOW , false ) ;
2023-09-21 17:18:26 -04:00
else {
2023-11-30 16:20:08 +01:00
Debug : : log ( ERR , " alterZOrder: bad position: {} " , POSITION ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = " alterZOrder: bad position: {} " } ;
2023-09-21 17:18:26 -04:00
}
g_pInputManager - > simulateMouseMovement ( ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2022-10-14 14:22:20 +01:00
}
2023-01-01 16:54:13 +01:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : lockGroups ( std : : string args ) {
2023-06-20 21:35:54 +02:00
if ( args = = " lock " | | args . empty ( ) | | args = = " lockgroups " )
2023-02-21 12:13:35 +00:00
g_pKeybindManager - > m_bGroupsLocked = true ;
2023-06-20 21:35:54 +02:00
else if ( args = = " toggle " )
2023-03-02 20:50:37 +00:00
g_pKeybindManager - > m_bGroupsLocked = ! g_pKeybindManager - > m_bGroupsLocked ;
2023-06-20 21:35:54 +02:00
else
2023-02-21 12:13:35 +00:00
g_pKeybindManager - > m_bGroupsLocked = false ;
2023-09-15 11:06:59 +00:00
g_pEventManager - > postEvent ( SHyprIPCEvent { " lockgroups " , g_pKeybindManager - > m_bGroupsLocked ? " 1 " : " 0 " } ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-02-21 12:13:35 +00:00
}
2023-02-26 13:52:11 +00:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : lockActiveGroup ( std : : string args ) {
2024-04-27 12:43:12 +01:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2023-06-09 21:44:18 +00:00
2024-04-27 12:43:12 +01:00
if ( ! PWINDOW | | ! PWINDOW - > m_sGroupData . pNextWindow . lock ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2023-06-20 21:35:54 +02:00
2023-06-09 21:44:18 +00:00
const auto PHEAD = PWINDOW - > getGroupHead ( ) ;
2023-06-20 21:35:54 +02:00
if ( args = = " lock " )
2023-06-09 21:44:18 +00:00
PHEAD - > m_sGroupData . locked = true ;
2023-06-20 21:35:54 +02:00
else if ( args = = " toggle " )
2023-06-09 21:44:18 +00:00
PHEAD - > m_sGroupData . locked = ! PHEAD - > m_sGroupData . locked ;
2023-06-20 21:35:54 +02:00
else
2023-06-09 21:44:18 +00:00
PHEAD - > m_sGroupData . locked = false ;
2023-06-13 10:04:54 +00:00
g_pCompositor - > updateWindowAnimatedDecorationValues ( PWINDOW ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-06-09 21:44:18 +00:00
}
2024-04-27 12:43:12 +01:00
void CKeybindManager : : moveWindowIntoGroup ( PHLWINDOW pWindow , PHLWINDOW pWindowInDirection ) {
2023-09-21 23:42:00 +00:00
if ( pWindow - > m_sGroupData . deny )
return ;
2024-06-07 17:52:15 +00:00
updateRelativeCursorCoords ( ) ;
2023-09-10 22:29:10 +00:00
g_pLayoutManager - > getCurrentLayout ( ) - > onWindowRemoved ( pWindow ) ; // This removes groupped property!
2024-10-27 18:45:38 +00:00
if ( pWindow - > m_pMonitor ! = pWindowInDirection - > m_pMonitor ) {
2024-07-24 18:00:25 +00:00
pWindow - > moveToWorkspace ( pWindowInDirection - > m_pWorkspace ) ;
2024-10-27 18:45:38 +00:00
pWindow - > m_pMonitor = pWindowInDirection - > m_pMonitor ;
2024-07-24 18:00:25 +00:00
}
2024-03-03 18:39:20 +00:00
static auto USECURRPOS = CConfigValue < Hyprlang : : INT > ( " group:insert_after_current " ) ;
2024-10-30 10:00:58 +00:00
( * USECURRPOS ? pWindowInDirection : pWindowInDirection - > getGroupTail ( ) ) - > insertWindowToGroup ( pWindow ) ;
2023-09-10 22:29:10 +00:00
pWindowInDirection - > setGroupCurrent ( pWindow ) ;
pWindow - > updateWindowDecos ( ) ;
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateWindow ( pWindow ) ;
g_pCompositor - > focusWindow ( pWindow ) ;
2024-06-07 17:52:15 +00:00
pWindow - > warpCursor ( ) ;
2023-11-11 14:37:17 +00:00
if ( ! pWindow - > getDecorationByType ( DECORATION_GROUPBAR ) )
pWindow - > addWindowDeco ( std : : make_unique < CHyprGroupBarDecoration > ( pWindow ) ) ;
2024-05-07 15:00:55 +04:00
g_pEventManager - > postEvent ( SHyprIPCEvent { " moveintogroup " , std : : format ( " {:x} " , ( uintptr_t ) pWindow . get ( ) ) } ) ;
2023-09-10 22:29:10 +00:00
}
2024-04-27 12:43:12 +01:00
void CKeybindManager : : moveWindowOutOfGroup ( PHLWINDOW pWindow , const std : : string & dir ) {
2024-03-03 18:39:20 +00:00
static auto BFOCUSREMOVEDWINDOW = CConfigValue < Hyprlang : : INT > ( " group:focus_removed_window " ) ;
const auto PWINDOWPREV = pWindow - > getGroupPrevious ( ) ;
eDirection direction ;
2023-09-13 10:13:29 +00:00
switch ( dir [ 0 ] ) {
case ' t ' :
case ' u ' : direction = DIRECTION_UP ; break ;
case ' d ' :
case ' b ' : direction = DIRECTION_DOWN ; break ;
case ' l ' : direction = DIRECTION_LEFT ; break ;
case ' r ' : direction = DIRECTION_RIGHT ; break ;
default : direction = DIRECTION_DEFAULT ;
}
2023-09-10 22:29:10 +00:00
2024-06-07 17:52:15 +00:00
updateRelativeCursorCoords ( ) ;
2024-04-27 12:43:12 +01:00
if ( pWindow - > m_sGroupData . pNextWindow . lock ( ) = = pWindow ) {
2023-09-21 23:42:00 +00:00
pWindow - > destroyGroup ( ) ;
2023-09-13 10:44:02 +00:00
} else {
g_pLayoutManager - > getCurrentLayout ( ) - > onWindowRemoved ( pWindow ) ;
2023-09-10 22:29:10 +00:00
2023-09-13 10:44:02 +00:00
const auto GROUPSLOCKEDPREV = g_pKeybindManager - > m_bGroupsLocked ;
g_pKeybindManager - > m_bGroupsLocked = true ;
2023-09-10 22:29:10 +00:00
2023-09-13 10:44:02 +00:00
g_pLayoutManager - > getCurrentLayout ( ) - > onWindowCreated ( pWindow , direction ) ;
2023-09-10 22:29:10 +00:00
2023-09-13 10:44:02 +00:00
g_pKeybindManager - > m_bGroupsLocked = GROUPSLOCKEDPREV ;
}
2023-09-10 22:29:10 +00:00
2024-03-03 18:39:20 +00:00
if ( * BFOCUSREMOVEDWINDOW ) {
2023-09-10 22:29:10 +00:00
g_pCompositor - > focusWindow ( pWindow ) ;
2024-06-07 17:52:15 +00:00
pWindow - > warpCursor ( ) ;
2023-09-10 22:29:10 +00:00
} else {
g_pCompositor - > focusWindow ( PWINDOWPREV ) ;
2024-06-07 17:52:15 +00:00
PWINDOWPREV - > warpCursor ( ) ;
2023-09-10 22:29:10 +00:00
}
2024-05-07 15:00:55 +04:00
g_pEventManager - > postEvent ( SHyprIPCEvent { " moveoutofgroup " , std : : format ( " {:x} " , ( uintptr_t ) pWindow . get ( ) ) } ) ;
2023-09-10 22:29:10 +00:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveIntoGroup ( std : : string args ) {
2024-03-03 18:39:20 +00:00
char arg = args [ 0 ] ;
2023-07-24 16:25:10 +00:00
2024-03-03 18:39:20 +00:00
static auto PIGNOREGROUPLOCK = CConfigValue < Hyprlang : : INT > ( " binds:ignore_group_lock " ) ;
2023-10-11 10:13:12 +00:00
2024-03-03 18:39:20 +00:00
if ( ! * PIGNOREGROUPLOCK & & g_pKeybindManager - > m_bGroupsLocked )
2024-08-24 11:45:53 -05:00
return { } ;
2023-02-26 13:52:11 +00:00
if ( ! isDirection ( args ) ) {
2023-09-06 12:51:36 +02:00
Debug : : log ( ERR , " Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b " , arg ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = std : : format ( " Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b " , arg ) } ;
2023-02-26 13:52:11 +00:00
}
2024-04-27 12:43:12 +01:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2023-02-26 13:52:11 +00:00
2024-09-18 12:05:17 +02:00
if ( ! PWINDOW | | PWINDOW - > m_sGroupData . deny )
2024-08-24 11:45:53 -05:00
return { } ;
2023-02-26 13:52:11 +00:00
2023-08-30 15:39:22 +00:00
auto PWINDOWINDIR = g_pCompositor - > getWindowInDirection ( PWINDOW , arg ) ;
2023-02-26 13:52:11 +00:00
2024-04-27 12:43:12 +01:00
if ( ! PWINDOWINDIR | | ! PWINDOWINDIR - > m_sGroupData . pNextWindow . lock ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2023-02-26 13:52:11 +00:00
2023-09-10 22:29:10 +00:00
// Do not move window into locked group if binds:ignore_group_lock is false
2024-04-27 12:43:12 +01:00
if ( ! * PIGNOREGROUPLOCK & & ( PWINDOWINDIR - > getGroupHead ( ) - > m_sGroupData . locked | | ( PWINDOW - > m_sGroupData . pNextWindow . lock ( ) & & PWINDOW - > getGroupHead ( ) - > m_sGroupData . locked ) ) )
2024-08-24 11:45:53 -05:00
return { } ;
2023-07-20 17:48:32 +00:00
2023-09-10 22:29:10 +00:00
moveWindowIntoGroup ( PWINDOW , PWINDOWINDIR ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-02-26 13:52:11 +00:00
}
2023-02-26 13:55:35 +00:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveOutOfGroup ( std : : string args ) {
2024-03-03 18:39:20 +00:00
static auto PIGNOREGROUPLOCK = CConfigValue < Hyprlang : : INT > ( " binds:ignore_group_lock " ) ;
2023-10-11 10:13:12 +00:00
2024-03-03 18:39:20 +00:00
if ( ! * PIGNOREGROUPLOCK & & g_pKeybindManager - > m_bGroupsLocked )
2024-08-24 11:45:53 -05:00
return { } ;
2023-10-11 10:13:12 +00:00
2024-04-27 12:43:12 +01:00
PHLWINDOW PWINDOW = nullptr ;
2024-02-17 23:44:22 +01:00
if ( args ! = " active " & & args . length ( ) > 1 )
PWINDOW = g_pCompositor - > getWindowByRegex ( args ) ;
else
2024-04-27 12:43:12 +01:00
PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2023-02-26 13:55:35 +00:00
2024-04-27 12:43:12 +01:00
if ( ! PWINDOW | | ! PWINDOW - > m_sGroupData . pNextWindow . lock ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2023-02-26 13:55:35 +00:00
2023-09-10 22:29:10 +00:00
moveWindowOutOfGroup ( PWINDOW ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-09-10 22:29:10 +00:00
}
2023-02-26 13:55:35 +00:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveWindowOrGroup ( std : : string args ) {
2024-03-03 18:39:20 +00:00
char arg = args [ 0 ] ;
2023-02-26 13:55:35 +00:00
2024-03-03 18:39:20 +00:00
static auto PIGNOREGROUPLOCK = CConfigValue < Hyprlang : : INT > ( " binds:ignore_group_lock " ) ;
2023-02-26 13:55:35 +00:00
2023-09-10 22:29:10 +00:00
if ( ! isDirection ( args ) ) {
2023-11-30 16:20:08 +01:00
Debug : : log ( ERR , " Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b " , arg ) ;
2024-08-24 11:45:53 -05:00
return { . success = false , . error = std : : format ( " Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b " , arg ) } ;
2023-09-10 22:29:10 +00:00
}
2023-02-26 13:55:35 +00:00
2024-04-27 12:43:12 +01:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
2024-07-31 17:55:52 +00:00
if ( ! PWINDOW | | PWINDOW - > isFullscreen ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2023-10-11 10:13:12 +00:00
2024-03-03 18:39:20 +00:00
if ( ! * PIGNOREGROUPLOCK & & g_pKeybindManager - > m_bGroupsLocked ) {
2023-10-11 10:13:12 +00:00
g_pLayoutManager - > getCurrentLayout ( ) - > moveWindowTo ( PWINDOW , args ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-10-11 10:13:12 +00:00
}
2023-09-21 23:42:00 +00:00
const auto PWINDOWINDIR = g_pCompositor - > getWindowInDirection ( PWINDOW , arg ) ;
2023-09-10 22:29:10 +00:00
2024-04-27 12:43:12 +01:00
const bool ISWINDOWGROUP = PWINDOW - > m_sGroupData . pNextWindow . lock ( ) . get ( ) ;
2023-09-21 23:42:00 +00:00
const bool ISWINDOWGROUPLOCKED = ISWINDOWGROUP & & PWINDOW - > getGroupHead ( ) - > m_sGroupData . locked ;
2024-04-27 12:43:12 +01:00
const bool ISWINDOWGROUPSINGLE = ISWINDOWGROUP & & PWINDOW - > m_sGroupData . pNextWindow . lock ( ) = = PWINDOW ;
2023-09-10 22:29:10 +00:00
2024-06-07 17:52:15 +00:00
updateRelativeCursorCoords ( ) ;
2023-09-10 22:29:10 +00:00
// note: PWINDOWINDIR is not null implies !PWINDOW->m_bIsFloating
2024-05-05 17:16:00 +01:00
if ( PWINDOWINDIR & & PWINDOWINDIR - > m_sGroupData . pNextWindow ) { // target is group
2024-03-03 18:39:20 +00:00
if ( ! * PIGNOREGROUPLOCK & & ( PWINDOWINDIR - > getGroupHead ( ) - > m_sGroupData . locked | | ISWINDOWGROUPLOCKED | | PWINDOW - > m_sGroupData . deny ) ) {
2023-09-10 22:29:10 +00:00
g_pLayoutManager - > getCurrentLayout ( ) - > moveWindowTo ( PWINDOW , args ) ;
2024-06-07 17:52:15 +00:00
PWINDOW - > warpCursor ( ) ;
2023-09-10 22:29:10 +00:00
} else
moveWindowIntoGroup ( PWINDOW , PWINDOWINDIR ) ;
2023-09-21 23:42:00 +00:00
} else if ( PWINDOWINDIR ) { // target is regular window
2024-03-03 18:39:20 +00:00
if ( ( ! * PIGNOREGROUPLOCK & & ISWINDOWGROUPLOCKED ) | | ! ISWINDOWGROUP | | ( ISWINDOWGROUPSINGLE & & PWINDOW - > m_eGroupRules & GROUP_SET_ALWAYS ) ) {
2023-09-10 22:29:10 +00:00
g_pLayoutManager - > getCurrentLayout ( ) - > moveWindowTo ( PWINDOW , args ) ;
2024-06-07 17:52:15 +00:00
PWINDOW - > warpCursor ( ) ;
2023-09-10 22:29:10 +00:00
} else
2023-09-13 10:13:29 +00:00
moveWindowOutOfGroup ( PWINDOW , args ) ;
2024-02-26 15:05:24 +01:00
} else if ( ( * PIGNOREGROUPLOCK | | ! ISWINDOWGROUPLOCKED ) & & ISWINDOWGROUP ) { // no target window
2023-09-13 10:13:29 +00:00
moveWindowOutOfGroup ( PWINDOW , args ) ;
2024-02-26 15:05:24 +01:00
} else if ( ! PWINDOWINDIR & & ! ISWINDOWGROUP ) { // no target in dir and not in group
g_pLayoutManager - > getCurrentLayout ( ) - > moveWindowTo ( PWINDOW , args ) ;
2024-06-07 17:52:15 +00:00
PWINDOW - > warpCursor ( ) ;
2024-02-26 15:05:24 +01:00
}
2023-09-21 23:42:00 +00:00
g_pCompositor - > updateWindowAnimatedDecorationValues ( PWINDOW ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-09-10 22:29:10 +00:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : setIgnoreGroupLock ( std : : string args ) {
2024-03-03 18:39:20 +00:00
static auto PIGNOREGROUPLOCK = ( Hyprlang : : INT * const * ) g_pConfigManager - > getConfigValuePtr ( " binds:ignore_group_lock " ) ;
2023-09-10 22:29:10 +00:00
if ( args = = " toggle " )
2024-03-03 18:39:20 +00:00
* * PIGNOREGROUPLOCK = ! * * PIGNOREGROUPLOCK ;
2023-09-10 22:29:10 +00:00
else
2024-03-03 18:39:20 +00:00
* * PIGNOREGROUPLOCK = args = = " on " ;
2023-09-10 22:29:10 +00:00
2024-03-03 18:39:20 +00:00
g_pEventManager - > postEvent ( SHyprIPCEvent { " ignoregrouplock " , std : : to_string ( * * PIGNOREGROUPLOCK ) } ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-02-26 13:55:35 +00:00
}
2023-04-09 13:48:20 +01:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : denyWindowFromGroup ( std : : string args ) {
2024-04-27 12:43:12 +01:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
if ( ! PWINDOW | | ( PWINDOW & & PWINDOW - > m_sGroupData . pNextWindow . lock ( ) ) )
2024-08-24 11:45:53 -05:00
return { } ;
2023-09-21 23:42:00 +00:00
if ( args = = " toggle " )
PWINDOW - > m_sGroupData . deny = ! PWINDOW - > m_sGroupData . deny ;
else
PWINDOW - > m_sGroupData . deny = args = = " on " ;
g_pCompositor - > updateWindowAnimatedDecorationValues ( PWINDOW ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-09-21 23:42:00 +00:00
}
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : global ( std : : string args ) {
2023-04-09 13:48:20 +01:00
const auto APPID = args . substr ( 0 , args . find_first_of ( ' : ' ) ) ;
const auto NAME = args . substr ( args . find_first_of ( ' : ' ) + 1 ) ;
2023-09-02 19:32:05 +02:00
if ( NAME . empty ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2023-04-09 13:48:20 +01:00
2024-07-30 16:33:56 -05:00
if ( ! PROTO : : globalShortcuts - > isTaken ( APPID , NAME ) )
2024-08-24 11:45:53 -05:00
return { } ;
2023-04-09 13:48:20 +01:00
2024-07-30 16:33:56 -05:00
PROTO : : globalShortcuts - > sendGlobalShortcutEvent ( APPID , NAME , g_pKeybindManager - > m_iPassPressed ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-04-10 21:07:49 +02:00
}
2023-07-13 17:55:20 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : moveGroupWindow ( std : : string args ) {
2023-07-13 17:55:20 +02:00
const auto BACK = args = = " b " | | args = = " prev " ;
2024-04-27 12:43:12 +01:00
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
if ( ! PLASTWINDOW | | ! PLASTWINDOW - > m_sGroupData . pNextWindow . lock ( ) )
2024-08-24 11:45:53 -05:00
return { } ;
2023-07-13 17:55:20 +02:00
2024-05-05 17:16:00 +01:00
if ( ( ! BACK & & PLASTWINDOW - > m_sGroupData . pNextWindow - > m_sGroupData . head ) | | ( BACK & & PLASTWINDOW - > m_sGroupData . head ) ) {
std : : swap ( PLASTWINDOW - > m_sGroupData . head , PLASTWINDOW - > m_sGroupData . pNextWindow - > m_sGroupData . head ) ;
std : : swap ( PLASTWINDOW - > m_sGroupData . locked , PLASTWINDOW - > m_sGroupData . pNextWindow - > m_sGroupData . locked ) ;
2023-07-20 17:48:32 +00:00
} else
2024-04-27 12:43:12 +01:00
PLASTWINDOW - > switchWithWindowInGroup ( BACK ? PLASTWINDOW - > getGroupPrevious ( ) : PLASTWINDOW - > m_sGroupData . pNextWindow . lock ( ) ) ;
2023-07-20 17:48:32 +00:00
2024-04-27 12:43:12 +01:00
PLASTWINDOW - > updateWindowDecos ( ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2023-07-13 17:55:20 +02:00
}
2024-06-15 16:20:00 +02:00
2024-08-24 11:45:53 -05:00
SDispatchResult CKeybindManager : : event ( std : : string args ) {
2024-06-15 16:20:00 +02:00
g_pEventManager - > postEvent ( SHyprIPCEvent { " custom " , args } ) ;
2024-08-24 11:45:53 -05:00
return { } ;
2024-06-15 16:20:00 +02:00
}
2024-10-28 18:18:58 +00:00
2024-11-19 01:16:11 +00:00
# include <utility>
# include <type_traits>
2024-10-28 18:18:58 +00:00
SDispatchResult CKeybindManager : : setProp ( std : : string args ) {
CVarList vars ( args , 3 , ' ' ) ;
if ( vars . size ( ) < 3 )
return { . success = false , . error = " Not enough args " } ;
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow . lock ( ) ;
const auto PWINDOW = g_pCompositor - > getWindowByRegex ( vars [ 0 ] ) ;
if ( ! PWINDOW )
return { . success = false , . error = " Window not found " } ;
const auto PROP = vars [ 1 ] ;
const auto VAL = vars [ 2 ] ;
bool noFocus = PWINDOW - > m_sWindowData . noFocus . valueOrDefault ( ) ;
try {
if ( PROP = = " animationstyle " ) {
PWINDOW - > m_sWindowData . animationStyle = CWindowOverridableVar ( VAL , PRIORITY_SET_PROP ) ;
} else if ( PROP = = " maxsize " ) {
PWINDOW - > m_sWindowData . maxSize = CWindowOverridableVar ( configStringToVector2D ( VAL ) , PRIORITY_SET_PROP ) ;
PWINDOW - > clampWindowSize ( std : : nullopt , PWINDOW - > m_sWindowData . maxSize . value ( ) ) ;
PWINDOW - > setHidden ( false ) ;
} else if ( PROP = = " minsize " ) {
PWINDOW - > m_sWindowData . minSize = CWindowOverridableVar ( configStringToVector2D ( VAL ) , PRIORITY_SET_PROP ) ;
PWINDOW - > clampWindowSize ( PWINDOW - > m_sWindowData . minSize . value ( ) , std : : nullopt ) ;
PWINDOW - > setHidden ( false ) ;
} else if ( PROP = = " alpha " ) {
PWINDOW - > m_sWindowData . alpha = CWindowOverridableVar ( SAlphaValue { std : : stof ( VAL ) , PWINDOW - > m_sWindowData . alpha . valueOrDefault ( ) . m_bOverride } , PRIORITY_SET_PROP ) ;
} else if ( PROP = = " alphainactive " ) {
PWINDOW - > m_sWindowData . alphaInactive =
CWindowOverridableVar ( SAlphaValue { std : : stof ( VAL ) , PWINDOW - > m_sWindowData . alphaInactive . valueOrDefault ( ) . m_bOverride } , PRIORITY_SET_PROP ) ;
} else if ( PROP = = " alphafullscreen " ) {
PWINDOW - > m_sWindowData . alphaFullscreen =
CWindowOverridableVar ( SAlphaValue { std : : stof ( VAL ) , PWINDOW - > m_sWindowData . alphaFullscreen . valueOrDefault ( ) . m_bOverride } , PRIORITY_SET_PROP ) ;
} else if ( PROP = = " alphaoverride " ) {
PWINDOW - > m_sWindowData . alpha =
2024-11-20 10:32:50 +00:00
CWindowOverridableVar ( SAlphaValue { PWINDOW - > m_sWindowData . alpha . valueOrDefault ( ) . m_fAlpha , ( bool ) configStringToInt ( VAL ) . value_or ( 0 ) } , PRIORITY_SET_PROP ) ;
2024-10-28 18:18:58 +00:00
} else if ( PROP = = " alphainactiveoverride " ) {
PWINDOW - > m_sWindowData . alphaInactive =
2024-11-20 10:32:50 +00:00
CWindowOverridableVar ( SAlphaValue { PWINDOW - > m_sWindowData . alphaInactive . valueOrDefault ( ) . m_fAlpha , ( bool ) configStringToInt ( VAL ) . value_or ( 0 ) } , PRIORITY_SET_PROP ) ;
2024-10-28 18:18:58 +00:00
} else if ( PROP = = " alphafullscreenoverride " ) {
PWINDOW - > m_sWindowData . alphaFullscreen =
2024-11-20 10:32:50 +00:00
CWindowOverridableVar ( SAlphaValue { PWINDOW - > m_sWindowData . alphaFullscreen . valueOrDefault ( ) . m_fAlpha , ( bool ) configStringToInt ( VAL ) . value_or ( 0 ) } , PRIORITY_SET_PROP ) ;
2024-10-28 18:18:58 +00:00
} else if ( PROP = = " activebordercolor " | | PROP = = " inactivebordercolor " ) {
CGradientValueData colorData = { } ;
if ( vars . size ( ) > 4 ) {
for ( int i = 3 ; i < static_cast < int > ( vars . size ( ) ) ; + + i ) {
const auto TOKEN = vars [ i ] ;
if ( TOKEN . ends_with ( " deg " ) )
colorData . m_fAngle = std : : stoi ( TOKEN . substr ( 0 , TOKEN . size ( ) - 3 ) ) * ( PI / 180.0 ) ;
2024-11-19 01:16:11 +00:00
else
configStringToInt ( TOKEN ) . and_then ( [ & colorData ] ( const auto & e ) {
colorData . m_vColors . push_back ( e ) ;
2024-11-28 14:31:38 +00:00
return std : : invoke_result_t < decltype ( : : configStringToInt ) , const std : : string & > ( 1 ) ;
2024-11-19 01:16:11 +00:00
} ) ;
2024-10-28 18:18:58 +00:00
}
2024-11-19 01:16:11 +00:00
} else if ( VAL ! = " -1 " )
configStringToInt ( VAL ) . and_then ( [ & colorData ] ( const auto & e ) {
colorData . m_vColors . push_back ( e ) ;
2024-11-28 14:31:38 +00:00
return std : : invoke_result_t < decltype ( : : configStringToInt ) , const std : : string & > ( 1 ) ;
2024-11-19 01:16:11 +00:00
} ) ;
2024-10-28 18:18:58 +00:00
2024-12-03 22:58:30 +00:00
colorData . updateColorsOk ( ) ;
2024-10-28 18:18:58 +00:00
if ( PROP = = " activebordercolor " )
PWINDOW - > m_sWindowData . activeBorderColor = CWindowOverridableVar ( colorData , PRIORITY_SET_PROP ) ;
else
PWINDOW - > m_sWindowData . inactiveBorderColor = CWindowOverridableVar ( colorData , PRIORITY_SET_PROP ) ;
} else if ( auto search = g_pConfigManager - > mbWindowProperties . find ( PROP ) ; search ! = g_pConfigManager - > mbWindowProperties . end ( ) ) {
auto pWindowDataElement = search - > second ( PWINDOW ) ;
if ( VAL = = " toggle " )
* pWindowDataElement = CWindowOverridableVar ( ! pWindowDataElement - > valueOrDefault ( ) , PRIORITY_SET_PROP ) ;
else if ( VAL = = " unset " )
pWindowDataElement - > unset ( PRIORITY_SET_PROP ) ;
else
2024-11-20 10:32:50 +00:00
* pWindowDataElement = CWindowOverridableVar ( ( bool ) configStringToInt ( VAL ) . value_or ( 0 ) , PRIORITY_SET_PROP ) ;
2024-10-28 18:18:58 +00:00
} else if ( auto search = g_pConfigManager - > miWindowProperties . find ( PROP ) ; search ! = g_pConfigManager - > miWindowProperties . end ( ) ) {
if ( VAL = = " unset " )
search - > second ( PWINDOW ) - > unset ( PRIORITY_SET_PROP ) ;
2024-11-18 23:53:38 +00:00
else if ( const auto V = configStringToInt ( VAL ) ; V )
* ( search - > second ( PWINDOW ) ) = CWindowOverridableVar ( ( int ) * V , PRIORITY_SET_PROP ) ;
2024-12-06 01:16:58 -05:00
} else if ( auto search = g_pConfigManager - > mfWindowProperties . find ( PROP ) ; search ! = g_pConfigManager - > mfWindowProperties . end ( ) ) {
if ( VAL = = " unset " )
search - > second ( PWINDOW ) - > unset ( PRIORITY_SET_PROP ) ;
else {
const auto V = std : : stof ( VAL ) ;
* ( search - > second ( PWINDOW ) ) = CWindowOverridableVar ( V , PRIORITY_SET_PROP ) ;
}
2024-11-19 01:16:11 +00:00
} else
2024-10-28 18:18:58 +00:00
return { . success = false , . error = " Prop not found " } ;
} catch ( std : : exception & e ) { return { . success = false , . error = std : : format ( " Error parsing prop value: {} " , std : : string ( e . what ( ) ) ) } ; }
g_pCompositor - > updateAllWindowsAnimatedDecorationValues ( ) ;
if ( ! ( PWINDOW - > m_sWindowData . noFocus . valueOrDefault ( ) = = noFocus ) ) {
g_pCompositor - > focusWindow ( nullptr ) ;
g_pCompositor - > focusWindow ( PWINDOW ) ;
g_pCompositor - > focusWindow ( PLASTWINDOW ) ;
}
for ( auto const & m : g_pCompositor - > m_vMonitors )
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( m - > ID ) ;
return { } ;
}