2022-03-19 17:48:18 +01:00
# include "KeybindManager.hpp"
2023-09-20 17:25:03 +02:00
# include "../render/decorations/CHyprGroupBarDecoration.hpp"
2023-10-23 00:11:03 +02:00
# include "debug/Log.hpp"
# include "helpers/VarList.hpp"
2024-03-03 19:39:20 +01:00
# include "../config/ConfigValue.hpp"
2022-03-19 17:48:18 +01:00
2022-06-10 12:06:27 +02:00
# include <regex>
2023-01-29 13:44:38 +01:00
# include <sys/ioctl.h>
2023-08-16 10:51:08 +02:00
# include <fcntl.h>
2024-01-01 18:29:51 +01:00
# include <vector>
2023-01-29 13:44:38 +01: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
2022-04-21 15:50:52 +02:00
CKeybindManager : : CKeybindManager ( ) {
// initialize all dispatchers
2024-01-15 16:30:46 +01:00
m_mDispatchers [ " exec " ] = spawn ;
m_mDispatchers [ " execr " ] = spawnRaw ;
m_mDispatchers [ " killactive " ] = killActive ;
m_mDispatchers [ " closewindow " ] = kill ;
m_mDispatchers [ " togglefloating " ] = toggleActiveFloating ;
2024-03-17 16:41:43 +01:00
m_mDispatchers [ " setfloating " ] = setActiveFloating ;
m_mDispatchers [ " settiled " ] = setActiveTiled ;
2024-01-15 16:30:46 +01:00
m_mDispatchers [ " workspace " ] = changeworkspace ;
m_mDispatchers [ " renameworkspace " ] = renameWorkspace ;
m_mDispatchers [ " fullscreen " ] = fullscreenActive ;
m_mDispatchers [ " fakefullscreen " ] = fakeFullscreenActive ;
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 16:30:46 +01: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-04-11 12:05:31 +02:00
m_mDispatchers [ " toggleswallow " ] = toggleSwallow ;
2024-01-15 16:30:46 +01:00
m_mDispatchers [ " submap " ] = setSubmap ;
m_mDispatchers [ " pass " ] = pass ;
m_mDispatchers [ " layoutmsg " ] = layoutmsg ;
m_mDispatchers [ " toggleopaque " ] = toggleOpaque ;
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 ;
m_mDispatchers [ " global " ] = global ;
2022-07-26 23:34:03 +02:00
m_tScrollTimer . reset ( ) ;
2023-09-10 17:27:14 +02:00
2023-10-21 15:52:43 +02:00
g_pHookSystem - > hookDynamic ( " configReloaded " , [ this ] ( void * hk , SCallbackInfo & info , std : : any param ) {
2023-09-10 17:27:14 +02:00
// clear cuz realloc'd
m_pActiveKeybind = nullptr ;
m_vPressedSpecialBinds . clear ( ) ;
} ) ;
2022-04-21 15:50:52 +02:00
}
2022-03-19 17:48:18 +01:00
void CKeybindManager : : addKeybind ( SKeybind kb ) {
2022-04-21 17:06:43 +02:00
m_lKeybinds . push_back ( kb ) ;
2022-07-25 14:42:49 +02:00
m_pActiveKeybind = nullptr ;
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 ) {
2022-04-21 17:06:43 +02:00
for ( auto it = m_lKeybinds . begin ( ) ; it ! = m_lKeybinds . end ( ) ; + + it ) {
2024-03-03 01:17:02 +01:00
if ( it - > modmask = = mod & & it - > key = = key . key & & it - > keycode = = key . keycode & & it - > catchAll = = key . catchAll ) {
2022-04-21 17:06:43 +02:00
it = m_lKeybinds . erase ( it ) ;
2022-07-08 09:32:09 +02:00
if ( it = = m_lKeybinds . end ( ) )
break ;
2022-04-21 17:06:43 +02:00
}
}
2022-07-25 14:42:49 +02:00
m_pActiveKeybind = nullptr ;
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 " ) )
2022-03-19 17:48:18 +01:00
modMask | = WLR_MODIFIER_SHIFT ;
2022-07-06 16:50:11 +02:00
if ( mods . contains ( " CAPS " ) )
2022-03-19 17:48:18 +01:00
modMask | = WLR_MODIFIER_CAPS ;
2022-07-06 16:50:11 +02:00
if ( mods . contains ( " CTRL " ) | | mods . contains ( " CONTROL " ) )
2022-03-19 17:48:18 +01:00
modMask | = WLR_MODIFIER_CTRL ;
2023-04-06 20:28:09 +02:00
if ( mods . contains ( " ALT " ) | | mods . contains ( " MOD1 " ) )
2022-03-19 17:48:18 +01:00
modMask | = WLR_MODIFIER_ALT ;
2022-07-06 16:50:11 +02:00
if ( mods . contains ( " MOD2 " ) )
2022-03-19 17:48:18 +01:00
modMask | = WLR_MODIFIER_MOD2 ;
2022-07-06 16:50:11 +02:00
if ( mods . contains ( " MOD3 " ) )
2022-03-19 17:48:18 +01:00
modMask | = WLR_MODIFIER_MOD3 ;
2022-07-06 16:50:11 +02:00
if ( mods . contains ( " SUPER " ) | | mods . contains ( " WIN " ) | | mods . contains ( " LOGO " ) | | mods . contains ( " MOD4 " ) )
2022-03-19 17:48:18 +01:00
modMask | = WLR_MODIFIER_LOGO ;
2022-07-06 16:50:11 +02:00
if ( mods . contains ( " MOD5 " ) )
2022-03-19 17:48:18 +01:00
modMask | = WLR_MODIFIER_MOD5 ;
return modMask ;
}
2024-01-01 18:29:51 +01:00
uint32_t CKeybindManager : : keycodeToModifier ( xkb_keycode_t keycode ) {
switch ( keycode - 8 ) {
case KEY_LEFTMETA : return WLR_MODIFIER_LOGO ;
case KEY_RIGHTMETA : return WLR_MODIFIER_LOGO ;
case KEY_LEFTSHIFT : return WLR_MODIFIER_SHIFT ;
case KEY_RIGHTSHIFT : return WLR_MODIFIER_SHIFT ;
case KEY_LEFTCTRL : return WLR_MODIFIER_CTRL ;
case KEY_RIGHTCTRL : return WLR_MODIFIER_CTRL ;
case KEY_LEFTALT : return WLR_MODIFIER_ALT ;
case KEY_RIGHTALT : return WLR_MODIFIER_ALT ;
case KEY_CAPSLOCK : return WLR_MODIFIER_CAPS ;
case KEY_NUMLOCK : return WLR_MODIFIER_MOD2 ;
default : return 0 ;
}
}
2022-08-21 16:43:18 +02:00
void CKeybindManager : : updateXKBTranslationState ( ) {
if ( m_pXKBTranslationState ) {
xkb_keymap_unref ( xkb_state_get_keymap ( m_pXKBTranslationState ) ) ;
xkb_state_unref ( m_pXKBTranslationState ) ;
m_pXKBTranslationState = nullptr ;
}
2024-03-03 19:39:20 +01: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 16:00:34 +01:00
2024-03-03 19:39:20 +01: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 16:00:34 +01:00
2024-03-03 19:39:20 +01: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 ) ;
FILE * const KEYMAPFILE = FILEPATH = = " " ? NULL : fopen ( absolutePath ( FILEPATH , g_pConfigManager - > configCurrentPath ) . c_str ( ) , " r " ) ;
2024-02-18 16:00:34 +01:00
2024-03-03 19:39:20 +01: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 16:07:15 +02:00
if ( KEYMAPFILE )
fclose ( KEYMAPFILE ) ;
2022-09-24 22:07:18 +02:00
if ( ! PKEYMAP ) {
2022-12-16 18:17:31 +01:00
g_pHyprError - > queueCreate ( " [Runtime Error] Invalid keyboard layout passed. ( rules: " + RULES + " , model: " + MODEL + " , variant: " + VARIANT + " , options: " + OPTIONS +
" , layout: " + LAYOUT + " ) " ,
2023-01-05 19:25:45 +01:00
CColor ( 1.0 , 50.0 / 255.0 , 50.0 / 255.0 , 1.0 ) ) ;
2022-09-24 22:07:18 +02: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 18:17:31 +01:00
rules . rules , rules . model , rules . options ) ;
2022-09-24 22:07:18 +02: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 ) ;
}
2022-09-20 23:23:02 +02:00
bool CKeybindManager : : ensureMouseBindState ( ) {
2022-09-20 11:02:20 +02:00
if ( ! m_bIsMouseBindActive )
2022-09-20 23:23:02 +02:00
return false ;
2022-09-20 11:02:20 +02:00
if ( g_pInputManager - > currentlyDraggedWindow ) {
2024-04-10 18:26:11 +02:00
CWindow * lastDraggedWindow = g_pInputManager - > currentlyDraggedWindow ;
2022-09-20 23:23:02 +02:00
m_bIsMouseBindActive = false ;
2022-09-20 11:02:20 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > onEndDragWindow ( ) ;
g_pInputManager - > currentlyDraggedWindow = nullptr ;
2022-12-16 18:17:31 +01:00
g_pInputManager - > dragMode = MBIND_INVALID ;
2022-09-20 23:23:02 +02:00
2024-04-10 18:26:11 +02:00
g_pCompositor - > updateWorkspaceWindows ( lastDraggedWindow - > workspaceID ( ) ) ;
g_pCompositor - > updateWorkspaceSpecialRenderData ( lastDraggedWindow - > workspaceID ( ) ) ;
g_pCompositor - > updateAllWindowsAnimatedDecorationValues ( ) ;
2022-09-20 23:23:02 +02:00
return true ;
2022-09-20 11:02:20 +02:00
}
m_bIsMouseBindActive = false ;
2022-09-20 23:23:02 +02:00
return false ;
2022-09-20 11:02:20 +02:00
}
2023-04-10 21:07:49 +02:00
bool CKeybindManager : : tryMoveFocusToMonitor ( CMonitor * monitor ) {
if ( ! monitor )
2023-04-10 15:40:03 +02:00
return false ;
2023-04-10 21:07:49 +02:00
const auto LASTMONITOR = g_pCompositor - > m_pLastMonitor ;
if ( LASTMONITOR = = monitor ) {
Debug : : log ( LOG , " Tried to move to active monitor " ) ;
return false ;
}
2024-04-02 21:32:39 +02:00
const auto PWORKSPACE = g_pCompositor - > m_pLastMonitor - > activeWorkspace ;
const auto PNEWMAINWORKSPACE = monitor - > activeWorkspace ;
2023-04-10 21:07:49 +02:00
2024-02-28 01:52:45 +01:00
g_pInputManager - > unconstrainMouse ( ) ;
2023-05-29 18:11:37 +02:00
PNEWMAINWORKSPACE - > rememberPrevWorkspace ( PWORKSPACE ) ;
2024-04-02 21:32:39 +02:00
const auto PNEWWORKSPACE = monitor - > activeSpecialWorkspace ? monitor - > activeSpecialWorkspace : PNEWMAINWORKSPACE ;
2023-04-10 15:40:03 +02:00
const auto PNEWWINDOW = PNEWWORKSPACE - > getLastFocusedWindow ( ) ;
if ( PNEWWINDOW ) {
g_pCompositor - > focusWindow ( PNEWWINDOW ) ;
2023-09-11 11:09:34 +02:00
g_pCompositor - > warpCursorTo ( PNEWWINDOW - > middle ( ) ) ;
2024-03-13 03:09:20 +01:00
g_pInputManager - > m_pForcedFocus = PNEWWINDOW ;
g_pInputManager - > simulateMouseMovement ( ) ;
g_pInputManager - > m_pForcedFocus = nullptr ;
2023-04-10 15:40:03 +02:00
} else {
g_pCompositor - > focusWindow ( nullptr ) ;
2023-09-11 11:09:34 +02:00
g_pCompositor - > warpCursorTo ( monitor - > middle ( ) ) ;
2023-04-10 15:40:03 +02:00
}
2024-03-13 03:09:20 +01:00
g_pCompositor - > setActiveMonitor ( monitor ) ;
2023-04-10 15:40:03 +02:00
return true ;
}
2023-09-10 13:51:27 +02:00
void CKeybindManager : : switchToWindow ( CWindow * PWINDOWTOCHANGETO ) {
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow ;
if ( PWINDOWTOCHANGETO = = PLASTWINDOW | | ! PWINDOWTOCHANGETO )
return ;
2024-02-28 01:52:45 +01:00
// remove constraints
g_pInputManager - > unconstrainMouse ( ) ;
2024-04-02 21:32:39 +02:00
if ( PLASTWINDOW & & PLASTWINDOW - > m_pWorkspace = = PWINDOWTOCHANGETO - > m_pWorkspace & & PLASTWINDOW - > m_bIsFullscreen ) {
const auto PWORKSPACE = PLASTWINDOW - > m_pWorkspace ;
2023-09-10 13:51:27 +02:00
const auto FSMODE = PWORKSPACE - > m_efFullscreenMode ;
if ( ! PWINDOWTOCHANGETO - > m_bPinned )
g_pCompositor - > setWindowFullscreen ( PLASTWINDOW , false , FULLSCREEN_FULL ) ;
g_pCompositor - > focusWindow ( PWINDOWTOCHANGETO ) ;
if ( ! PWINDOWTOCHANGETO - > m_bPinned )
g_pCompositor - > setWindowFullscreen ( PWINDOWTOCHANGETO , true , FSMODE ) ;
} else {
g_pCompositor - > focusWindow ( PWINDOWTOCHANGETO ) ;
2023-09-11 11:09:34 +02:00
g_pCompositor - > warpCursorTo ( PWINDOWTOCHANGETO - > middle ( ) ) ;
2023-09-10 13:51:27 +02:00
g_pInputManager - > m_pForcedFocus = PWINDOWTOCHANGETO ;
g_pInputManager - > simulateMouseMovement ( ) ;
g_pInputManager - > m_pForcedFocus = nullptr ;
if ( PLASTWINDOW & & PLASTWINDOW - > m_iMonitorID ! = PWINDOWTOCHANGETO - > m_iMonitorID ) {
// event
const auto PNEWMON = g_pCompositor - > getMonitorFromID ( PWINDOWTOCHANGETO - > m_iMonitorID ) ;
g_pCompositor - > setActiveMonitor ( PNEWMON ) ;
}
}
} ;
2022-07-20 22:45:06 +02:00
bool CKeybindManager : : onKeyEvent ( wlr_keyboard_key_event * e , SKeyboard * 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-11-07 23:22:13 +01:00
if ( pKeyboard - > isVirtual & & g_pInputManager - > shouldIgnoreVirtualKeyboard ( pKeyboard ) )
2022-08-05 16:21:08 +02:00
return true ;
2022-08-21 16:43:18 +02:00
if ( ! m_pXKBTranslationState ) {
Debug : : log ( ERR , " BUG THIS: m_pXKBTranslationState NULL! " ) ;
updateXKBTranslationState ( ) ;
if ( ! m_pXKBTranslationState )
return true ;
}
2022-12-16 18:17:31 +01:00
const auto KEYCODE = e - > keycode + 8 ; // Because to xkbcommon it's +8 from libinput
2022-07-20 22:45:06 +02:00
2024-02-28 00:21:22 +01:00
const xkb_keysym_t keysym = xkb_state_key_get_one_sym ( pKeyboard - > resolveBindsBySym ? pKeyboard - > xkbTranslationState : m_pXKBTranslationState , KEYCODE ) ;
2022-08-26 19:19:34 +02:00
const xkb_keysym_t internalKeysym = xkb_state_key_get_one_sym ( wlr_keyboard_from_input_device ( pKeyboard - > keyboard ) - > xkb_state , KEYCODE ) ;
if ( handleInternalKeybinds ( internalKeysym ) )
return true ;
2022-07-20 22:45:06 +02:00
const auto MODS = g_pInputManager - > accumulateModsFromAllKBs ( ) ;
2022-12-16 18:17:31 +01:00
m_uTimeLastMs = e - > time_msec ;
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 17:08:07 +01:00
. submapAtPress = m_szCurrentSelectedSubmap ,
2024-01-01 18:29:51 +01:00
} ;
2022-09-20 11:02:20 +02:00
2024-01-10 18:06:38 +01:00
bool suppressEvent = false ;
2022-07-20 22:45:06 +02:00
if ( e - > state = = WL_KEYBOARD_KEY_STATE_PRESSED ) {
2022-07-25 14:42:49 +02:00
// clean repeat
if ( m_pActiveKeybindEventSource ) {
wl_event_source_remove ( m_pActiveKeybindEventSource ) ;
m_pActiveKeybindEventSource = nullptr ;
2022-12-16 18:17:31 +01:00
m_pActiveKeybind = nullptr ;
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-01-10 18:06:38 +01:00
suppressEvent = handleKeybinds ( MODS , KEY , true ) ;
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-25 14:42:49 +02:00
// clean repeat
if ( m_pActiveKeybindEventSource ) {
wl_event_source_remove ( m_pActiveKeybindEventSource ) ;
m_pActiveKeybindEventSource = nullptr ;
2022-12-16 18:17:31 +01:00
m_pActiveKeybind = nullptr ;
2022-07-25 14:42:49 +02:00
}
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-03-09 17:08:07 +01:00
if ( it - > submapAtPress = = m_szCurrentSelectedSubmap )
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-01-10 18:06:38 +01:00
suppressEvent = handleKeybinds ( MODS , KEY , false ) ;
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
}
2022-07-21 18:18:03 +02:00
bool CKeybindManager : : onAxisEvent ( wlr_pointer_axis_event * e ) {
2024-03-03 19:39:20 +01:00
const auto MODS = g_pInputManager - > accumulateModsFromAllKBs ( ) ;
2022-07-21 18:18:03 +02:00
2024-03-03 19:39:20 +01:00
static auto PDELAY = CConfigValue < Hyprlang : : INT > ( " binds:scroll_event_delay " ) ;
2022-07-26 23:34:03 +02:00
2024-03-03 19:39:20 +01: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 ( ) ;
2022-07-21 18:18:03 +02:00
bool found = false ;
2024-03-09 17:35:35 +01:00
if ( e - > source = = WL_POINTER_AXIS_SOURCE_WHEEL & & e - > orientation = = WL_POINTER_AXIS_VERTICAL_SCROLL ) {
2023-02-23 14:55:27 +01:00
if ( e - > delta < 0 )
2024-01-01 18:29:51 +01:00
found = handleKeybinds ( MODS , SPressedKeyWithMods { . keyName = " mouse_down " } , true ) ;
2023-02-23 14:55:27 +01:00
else
2024-01-01 18:29:51 +01:00
found = handleKeybinds ( MODS , SPressedKeyWithMods { . keyName = " mouse_up " } , true ) ;
2024-03-09 17:35:35 +01:00
} else if ( e - > source = = WL_POINTER_AXIS_SOURCE_WHEEL & & e - > orientation = = WL_POINTER_AXIS_HORIZONTAL_SCROLL ) {
2023-02-23 14:55:27 +01:00
if ( e - > delta < 0 )
2024-01-01 18:29:51 +01:00
found = handleKeybinds ( MODS , SPressedKeyWithMods { . keyName = " mouse_left " } , true ) ;
2023-02-23 14:55:27 +01:00
else
2024-01-01 18:29:51 +01:00
found = handleKeybinds ( MODS , SPressedKeyWithMods { . keyName = " mouse_right " } , true ) ;
2022-07-26 14:50:21 +02:00
}
2023-02-23 14:55:27 +01:00
if ( found )
shadowKeybinds ( ) ;
2022-07-26 14:50:21 +02:00
return ! found ;
}
bool CKeybindManager : : onMouseEvent ( wlr_pointer_button_event * e ) {
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
2022-08-28 17:01:48 +02:00
m_uLastMouseCode = e - > button ;
2022-12-16 18:17:31 +01:00
m_uLastCode = 0 ;
m_uTimeLastMs = e - > time_msec ;
2022-08-28 17:01:48 +02:00
2024-01-01 18:29:51 +01:00
bool mouseBindWasActive = ensureMouseBindState ( ) ;
const auto KEY_NAME = " mouse: " + std : : to_string ( e - > button ) ;
const auto KEY = SPressedKeyWithMods {
. keyName = KEY_NAME ,
. modmaskAtPressTime = MODS ,
} ;
2022-09-20 23:23:02 +02:00
2024-03-09 17:35:35 +01:00
if ( e - > state = = WL_POINTER_BUTTON_STATE_PRESSED ) {
2024-01-01 18:29:51 +01:00
m_dPressedKeys . push_back ( KEY ) ;
2024-01-10 18:06:38 +01:00
suppressEvent = handleKeybinds ( MODS , KEY , true ) ;
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-01-10 18:06:38 +01:00
suppressEvent = handleKeybinds ( MODS , * it , false ) ;
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-01-10 18:06:38 +01:00
suppressEvent = handleKeybinds ( MODS , KEY , false ) ;
2024-01-01 18:29:51 +01:00
}
2022-07-26 14:50:21 +02:00
shadowKeybinds ( ) ;
2022-07-21 18:18:03 +02:00
}
2024-01-10 18:06:38 +01:00
return ! suppressEvent & & ! mouseBindWasActive ;
2022-07-21 18:18:03 +02:00
}
2023-02-18 23:35:31 +01:00
void CKeybindManager : : resizeWithBorder ( wlr_pointer_button_event * e ) {
2024-03-09 17:35:35 +01:00
if ( e - > state = = WL_POINTER_BUTTON_STATE_PRESSED ) {
2023-02-18 23:35:31 +01:00
mouse ( " 1resizewindow " ) ;
} else {
mouse ( " 0resizewindow " ) ;
}
}
2022-10-04 21:07:21 +02: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 21:07:21 +02:00
}
2023-01-08 16:35:24 +01: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 16:35:24 +01: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 16:35:24 +01:00
}
2022-07-25 14:42:49 +02:00
int repeatKeyHandler ( void * data ) {
SKeybind * * ppActiveKeybind = ( SKeybind * * ) data ;
if ( ! * ppActiveKeybind )
return 0 ;
const auto DISPATCHER = g_pKeybindManager - > m_mDispatchers . find ( ( * ppActiveKeybind ) - > handler ) ;
Debug : : log ( LOG , " Keybind repeat triggered, calling dispatcher. " ) ;
DISPATCHER - > second ( ( * ppActiveKeybind ) - > arg ) ;
wl_event_source_timer_update ( g_pKeybindManager - > m_pActiveKeybindEventSource , 1000 / g_pInputManager - > m_pActiveKeyboard - > repeatRate ) ;
return 0 ;
}
2024-01-01 18:29:51 +01:00
bool CKeybindManager : : handleKeybinds ( const uint32_t modmask , const SPressedKeyWithMods & key , bool pressed ) {
2022-03-19 22:03:40 +01:00
bool found = false ;
2022-03-27 19:32:50 +02:00
2022-06-21 22:47:27 +02:00
if ( g_pCompositor - > m_sSeat . exclusiveClient )
Debug : : log ( LOG , " Keybind handling only locked (inhibitor) " ) ;
2022-04-18 17:16:01 +02:00
2024-03-29 19:57:10 +01:00
static auto PDISABLEINHIBIT = CConfigValue < Hyprlang : : INT > ( " binds:disable_keybind_grabbing " ) ;
if ( ! * PDISABLEINHIBIT & & ! m_lShortcutInhibitors . empty ( ) ) {
2024-02-28 00:14:56 +01:00
for ( auto & i : m_lShortcutInhibitors ) {
if ( i . pWlrInhibitor - > surface = = g_pCompositor - > m_pLastFocus ) {
Debug : : log ( LOG , " Keybind handling is disabled due to an inhibitor for surface {:x} " , ( uintptr_t ) i . pWlrInhibitor - > surface ) ;
return false ;
}
}
}
2022-04-21 17:06:43 +02:00
for ( auto & k : m_lKeybinds ) {
2023-09-10 14:13:10 +02:00
const bool SPECIALDISPATCHER = k . handler = = " global " | | k . handler = = " pass " | | k . handler = = " mouse " ;
2023-09-10 17:27:14 +02:00
const bool SPECIALTRIGGERED =
std : : find_if ( m_vPressedSpecialBinds . begin ( ) , m_vPressedSpecialBinds . end ( ) , [ & ] ( const auto & other ) { return other = = & k ; } ) ! = m_vPressedSpecialBinds . end ( ) ;
2023-09-10 17:54:14 +02:00
const bool IGNORECONDITIONS =
SPECIALDISPATCHER & & ! pressed & & SPECIALTRIGGERED ; // ignore mods. Pass, global dispatchers should be released immediately once the key is released.
2023-09-10 14:13:10 +02:00
2023-10-17 21:09:54 +02:00
if ( ! IGNORECONDITIONS & &
( ( modmask ! = k . modmask & & ! k . ignoreMods ) | | ( g_pCompositor - > m_sSeat . exclusiveClient & & ! k . locked ) | | k . submap ! = m_szCurrentSelectedSubmap | | k . shadowed ) )
2022-03-19 17:48:18 +01:00
continue ;
2024-01-01 18:29:51 +01:00
if ( ! key . keyName . empty ( ) ) {
if ( key . keyName ! = k . key )
2022-07-15 20:54:05 +02:00
continue ;
2024-01-01 18:29:51 +01:00
} else if ( k . keycode ! = 0 ) {
if ( key . keycode ! = k . keycode )
2022-07-08 09:27:17 +02:00
continue ;
2024-03-03 01:17:02 +01:00
} else if ( k . catchAll ) {
if ( found )
continue ;
2022-07-08 09:27:17 +02:00
} else {
// oMg such performance hit!!11!
// this little maneouver is gonna cost us 4µs
2024-02-19 01:02:03 +01:00
const auto KBKEY = xkb_keysym_from_name ( k . key . c_str ( ) , XKB_KEYSYM_CASE_INSENSITIVE ) ;
if ( KBKEY = = 0 ) {
2024-03-12 16:26:42 +01: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 ;
}
2022-07-08 09:27:17 +02:00
const auto KBKEYUPPER = xkb_keysym_to_upper ( KBKEY ) ;
2024-01-01 18:29:51 +01:00
if ( key . keysym ! = KBKEY & & key . keysym ! = KBKEYUPPER )
2022-07-08 09:27:17 +02:00
continue ;
}
2022-04-21 15:50:52 +02:00
2023-09-10 14:13:10 +02:00
if ( pressed & & k . release & & ! SPECIALDISPATCHER ) {
2023-06-14 13:08:56 +02:00
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-02-02 02:09:49 +01: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 ;
} else if ( ! k . release & & ! SPECIALDISPATCHER ) {
if ( k . nonConsuming )
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
}
2022-09-19 20:04:48 +02:00
const auto DISPATCHER = m_mDispatchers . find ( k . mouse ? " mouse " : k . handler ) ;
2022-04-21 15:50:52 +02:00
2023-09-10 17:27:14 +02:00
if ( SPECIALTRIGGERED & & ! pressed )
std : : erase_if ( m_vPressedSpecialBinds , [ & ] ( const auto & other ) { return other = = & k ; } ) ;
else if ( SPECIALDISPATCHER & & pressed )
m_vPressedSpecialBinds . push_back ( & k ) ;
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 ( ) ) {
2023-09-06 21:45:37 +02: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 ;
2022-09-19 20:04:48 +02:00
if ( k . handler = = " mouse " )
DISPATCHER - > second ( ( pressed ? " 1 " : " 0 " ) + k . arg ) ;
else
DISPATCHER - > second ( k . arg ) ;
2022-08-09 19:54:06 +02:00
2022-08-27 19:29:28 +02:00
m_iPassPressed = - 1 ;
2022-08-09 19:54:06 +02:00
if ( k . handler = = " submap " ) {
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
2022-07-25 14:42:49 +02:00
if ( k . repeat ) {
2022-12-16 18:17:31 +01:00
m_pActiveKeybind = & k ;
2022-07-25 14:42:49 +02:00
m_pActiveKeybindEventSource = wl_event_loop_add_timer ( g_pCompositor - > m_sWLEventLoop , repeatKeyHandler , & m_pActiveKeybind ) ;
const auto PACTIVEKEEB = g_pInputManager - > m_pActiveKeyboard ;
wl_event_source_timer_update ( m_pActiveKeybindEventSource , PACTIVEKEEB - > repeatDelay ) ;
}
2023-06-14 13:08:56 +02:00
if ( ! k . nonConsuming )
found = true ;
2022-03-19 17:48:18 +01:00
}
2022-03-19 22:03:40 +01:00
return found ;
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
for ( auto & k : m_lKeybinds ) {
2023-04-09 14:48:20 +02:00
bool shadow = false ;
2023-08-25 12:35:24 +02:00
if ( k . handler = = " global " | | k . transparent )
2023-04-09 14:48:20 +02:00
continue ; // can't be shadowed
2022-07-20 23:17:26 +02:00
2022-12-16 18:17:31 +01:00
const auto KBKEY = xkb_keysym_from_name ( k . key . c_str ( ) , XKB_KEYSYM_CASE_INSENSITIVE ) ;
2022-07-20 23:17:26 +02:00
const auto KBKEYUPPER = xkb_keysym_to_upper ( KBKEY ) ;
2024-01-01 18:29:51 +01:00
for ( auto & pk : m_dPressedKeys ) {
if ( ( pk . keysym ! = 0 & & ( pk . keysym = = KBKEY | | pk . keysym = = KBKEYUPPER ) ) ) {
2022-07-20 23:17:26 +02:00
shadow = true ;
2022-09-25 20:07:48 +02:00
2024-01-01 18:29:51 +01:00
if ( pk . keysym = = doesntHave & & doesntHave ! = 0 ) {
2022-07-25 16:12:06 +02:00
shadow = false ;
break ;
}
2022-07-24 12:16:26 +02:00
}
2022-07-20 23:17:26 +02:00
2024-01-01 18:29:51 +01:00
if ( pk . keycode ! = 0 & & pk . keycode = = k . keycode ) {
2022-07-20 23:17:26 +02:00
shadow = true ;
2022-07-24 12:16:26 +02:00
2024-01-01 18:29:51 +01:00
if ( pk . keycode = = doesntHaveCode & & doesntHaveCode ! = 0 ) {
2022-07-25 16:12:06 +02:00
shadow = false ;
break ;
}
2022-07-24 12:16:26 +02:00
}
2022-07-20 23:17:26 +02:00
}
k . shadowed = shadow ;
}
}
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
if ( ! ( keysym > = XKB_KEY_XF86Switch_VT_1 & & keysym < = XKB_KEY_XF86Switch_VT_12 ) )
return false ;
2022-10-06 20:31:32 +02:00
// beyond this point, return true to not handle anything else.
// we'll avoid printing shit to active windows.
2022-10-05 22:41:27 +02:00
if ( g_pCompositor - > m_sWLRSession ) {
2022-10-05 02:42:51 +02:00
const unsigned int TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1 ;
2022-10-04 17:53:09 +02:00
2022-10-05 22:41:27 +02:00
// vtnr is bugged for some reason.
2023-01-29 18:02:55 +01:00
unsigned int ttynum = 0 ;
2023-08-16 10:51:08 +02:00
int fd ;
if ( ( fd = open ( " /dev/tty " , O_RDONLY | O_NOCTTY ) ) > = 0 ) {
2023-03-31 21:39:04 +02:00
# if defined(VT_GETSTATE)
2023-08-16 10:51:08 +02:00
struct vt_stat st ;
if ( ! ioctl ( fd , VT_GETSTATE , & st ) )
ttynum = st . v_active ;
2023-03-31 21:39:04 +02:00
# elif defined(VT_GETACTIVE)
2023-08-16 10:51:08 +02:00
int vt ;
if ( ! ioctl ( fd , VT_GETACTIVE , & vt ) )
ttynum = vt ;
2023-01-29 13:44:38 +01:00
# endif
2023-08-16 10:51:08 +02:00
close ( fd ) ;
}
2022-10-05 22:41:27 +02:00
if ( ttynum = = TTY )
2022-10-06 20:31:32 +02:00
return true ;
2022-10-05 22:41:27 +02:00
2023-09-06 12:51:36 +02:00
Debug : : log ( LOG , " Switching from VT {} to VT {} " , ttynum , TTY ) ;
2022-10-05 22:41:27 +02:00
if ( ! wlr_session_change_vt ( g_pCompositor - > m_sWLRSession , TTY ) )
2022-10-06 20:31:32 +02:00
return true ; // probably same session
2022-10-04 17:53:09 +02:00
2022-07-13 18:18:23 +02:00
g_pCompositor - > m_bSessionActive = false ;
2022-06-06 13:48:17 +02:00
2022-06-30 15:44:26 +02:00
for ( auto & m : g_pCompositor - > m_vMonitors ) {
m - > noFrameSchedule = true ;
2022-12-16 18:17:31 +01:00
m - > framesToSkip = 1 ;
2022-06-06 13:48:17 +02:00
}
2023-09-06 12:51:36 +02:00
Debug : : log ( LOG , " Switched to VT {}, destroyed all render data, frames to skip for each: 2 " , TTY ) ;
2022-06-27 13:42:20 +02:00
2022-03-27 19:32:50 +02:00
return true ;
}
2022-10-06 20:31:32 +02: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
void CKeybindManager : : spawn ( std : : string args ) {
2022-11-10 14:39:23 +01:00
args = removeBeginEndSpacesTabs ( args ) ;
std : : string RULES = " " ;
if ( args [ 0 ] = = ' [ ' ) {
// we have exec rules
RULES = args . substr ( 1 , args . substr ( 1 ) . find_first_of ( ' ] ' ) ) ;
2022-12-16 18:17:31 +01:00
args = args . substr ( args . find_first_of ( ' ] ' ) + 1 ) ;
2022-11-10 14:39:23 +01:00
}
2023-02-19 14:59:39 +01:00
const uint64_t PROC = spawnRaw ( args ) ;
if ( ! RULES . empty ( ) ) {
const auto RULESLIST = CVarList ( RULES , 0 , ' ; ' ) ;
for ( auto & r : RULESLIST ) {
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 14:59:39 +01:00
}
}
uint64_t CKeybindManager : : spawnRaw ( std : : string args ) {
2023-09-06 21:45:37 +02:00
Debug : : log ( LOG , " Executing {} " , args ) ;
2022-03-19 17:48:18 +01:00
2022-06-15 19:06:51 +02:00
int socket [ 2 ] ;
2022-06-16 21:19:36 +02:00
if ( pipe ( socket ) ! = 0 ) {
Debug : : log ( LOG , " Unable to create pipe for fork " ) ;
}
2022-06-15 19:06:51 +02:00
2022-06-16 21:19:36 +02:00
pid_t child , grandchild ;
2022-06-15 19:06:51 +02:00
child = fork ( ) ;
2022-06-16 21:19:36 +02:00
if ( child < 0 ) {
2022-06-15 19:06:51 +02:00
close ( socket [ 0 ] ) ;
close ( socket [ 1 ] ) ;
Debug : : log ( LOG , " Fail to create the first fork " ) ;
2023-02-19 14:59:39 +01:00
return 0 ;
2022-06-15 19:06:51 +02:00
}
2022-06-16 21:19:36 +02:00
if ( child = = 0 ) {
2022-06-15 19:06:51 +02:00
// run in child
2022-10-06 20:02:03 +02:00
sigset_t set ;
sigemptyset ( & set ) ;
sigprocmask ( SIG_SETMASK , & set , NULL ) ;
2022-06-15 19:06:51 +02:00
grandchild = fork ( ) ;
2022-06-16 21:19:36 +02:00
if ( grandchild = = 0 ) {
2022-06-15 19:06:51 +02:00
// run in grandchild
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-16 21:19:36 +02:00
write ( socket [ 1 ] , & grandchild , sizeof ( grandchild ) ) ;
2022-06-15 19:06:51 +02:00
close ( socket [ 1 ] ) ;
// exit child
2022-03-19 17:48:18 +01:00
_exit ( 0 ) ;
}
2022-06-15 19:06:51 +02:00
// run in parent
close ( socket [ 1 ] ) ;
2022-06-16 21:19:36 +02:00
read ( socket [ 0 ] , & grandchild , sizeof ( grandchild ) ) ;
2022-06-15 19:06:51 +02:00
close ( socket [ 0 ] ) ;
2024-03-11 20:31:39 +01:00
// clear child and leave grandchild to init
2022-06-15 19:06:51 +02:00
waitpid ( child , NULL , 0 ) ;
2024-03-11 20:31:39 +01:00
if ( grandchild < 0 ) {
2022-06-15 19:06:51 +02:00
Debug : : log ( LOG , " Fail to create the second fork " ) ;
2023-02-19 14:59:39 +01:00
return 0 ;
2022-06-15 19:06:51 +02:00
}
2022-11-10 14:39:23 +01:00
2023-09-06 12:51:36 +02:00
Debug : : log ( LOG , " Process Created with pid {} " , grandchild ) ;
2022-11-10 14:39:23 +01:00
2023-02-19 14:59:39 +01:00
return grandchild ;
2022-03-19 17:48:18 +01:00
}
void CKeybindManager : : killActive ( std : : string args ) {
2022-08-06 20:57:38 +02:00
g_pCompositor - > closeWindow ( g_pCompositor - > m_pLastWindow ) ;
2022-03-19 21:48:24 +01:00
}
2022-08-30 21:35:27 +02:00
void CKeybindManager : : kill ( std : : string args ) {
const auto PWINDOW = g_pCompositor - > getWindowByRegex ( args ) ;
if ( ! PWINDOW ) {
Debug : : log ( ERR , " kill: no window found " ) ;
return ;
}
g_pCompositor - > closeWindow ( PWINDOW ) ;
}
2022-03-19 21:48:24 +01:00
void CKeybindManager : : clearKeybinds ( ) {
2022-04-21 17:06:43 +02:00
m_lKeybinds . clear ( ) ;
2022-03-20 11:14:24 +01:00
}
2024-04-04 02:16:47 +02:00
static void toggleActiveFloatingCore ( std : : string args , std : : optional < bool > floatState ) {
2022-08-25 22:34:53 +02:00
CWindow * 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 18:00:24 +01:00
else
2022-08-25 22:34:53 +02:00
PWINDOW = g_pCompositor - > m_pLastWindow ;
if ( ! PWINDOW )
return ;
2024-03-17 16:41:43 +01:00
if ( floatState . has_value ( ) & & floatState = = PWINDOW - > m_bIsFloating )
return ;
2022-10-14 21:46:32 +02:00
// remove drag status
g_pInputManager - > currentlyDraggedWindow = nullptr ;
2022-06-30 12:09:05 +02:00
2023-02-19 22:07:32 +01:00
if ( PWINDOW - > m_sGroupData . pNextWindow & & PWINDOW - > m_sGroupData . pNextWindow ! = PWINDOW ) {
2024-03-17 16:41:43 +01:00
const auto PCURRENT = PWINDOW - > getGroupCurrent ( ) ;
2022-05-31 14:01:00 +02:00
2023-02-19 22:07:32 +01:00
PCURRENT - > m_bIsFloating = ! PCURRENT - > m_bIsFloating ;
g_pLayoutManager - > getCurrentLayout ( ) - > changeWindowFloatingMode ( PCURRENT ) ;
2022-11-15 11:21:26 +01:00
2023-02-19 22:07:32 +01:00
CWindow * curr = PCURRENT - > m_sGroupData . pNextWindow ;
while ( curr ! = PCURRENT ) {
curr - > m_bIsFloating = PCURRENT - > m_bIsFloating ;
2024-04-10 18:26:11 +02:00
curr = curr - > m_sGroupData . pNextWindow ;
2023-02-19 22:07:32 +01:00
}
} else {
PWINDOW - > m_bIsFloating = ! PWINDOW - > m_bIsFloating ;
g_pLayoutManager - > getCurrentLayout ( ) - > changeWindowFloatingMode ( PWINDOW ) ;
}
2024-04-10 18:26:11 +02:00
g_pCompositor - > updateWorkspaceWindows ( PWINDOW - > workspaceID ( ) ) ;
g_pCompositor - > updateWorkspaceSpecialRenderData ( PWINDOW - > workspaceID ( ) ) ;
g_pCompositor - > updateAllWindowsAnimatedDecorationValues ( ) ;
2022-03-20 15:55:47 +01:00
}
2024-04-04 02:16:47 +02:00
void CKeybindManager : : toggleActiveFloating ( std : : string args ) {
return toggleActiveFloatingCore ( args , std : : nullopt ) ;
}
void CKeybindManager : : setActiveFloating ( std : : string args ) {
return toggleActiveFloatingCore ( args , true ) ;
}
void CKeybindManager : : setActiveTiled ( std : : string args ) {
return toggleActiveFloatingCore ( args , false ) ;
}
2022-11-07 13:16:30 +01:00
void CKeybindManager : : centerWindow ( std : : string args ) {
const auto PWINDOW = g_pCompositor - > m_pLastWindow ;
if ( ! PWINDOW | | ! PWINDOW - > m_bIsFloating | | PWINDOW - > m_bIsFullscreen )
return ;
const auto PMONITOR = g_pCompositor - > getMonitorFromID ( PWINDOW - > m_iMonitorID ) ;
2023-08-11 16:54:16 +02: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 ( ) ;
2022-11-07 13:16:30 +01:00
}
2022-04-02 20:04:32 +02:00
void CKeybindManager : : toggleActivePseudo ( std : : string args ) {
const auto ACTIVEWINDOW = g_pCompositor - > m_pLastWindow ;
2022-10-14 21:46:32 +02:00
if ( ! ACTIVEWINDOW )
2022-04-02 20:04:32 +02:00
return ;
ACTIVEWINDOW - > m_bIsPseudotiled = ! ACTIVEWINDOW - > m_bIsPseudotiled ;
2022-09-22 21:57:09 +02:00
if ( ! ACTIVEWINDOW - > m_bIsFullscreen )
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateWindow ( ACTIVEWINDOW ) ;
2022-04-02 20:04:32 +02:00
}
2022-04-21 17:21:55 +02:00
void CKeybindManager : : changeworkspace ( std : : string args ) {
2022-12-16 18:17:31 +01:00
int workspaceToChangeTo = 0 ;
std : : string workspaceName = " " ;
2022-04-21 16:38:48 +02:00
2023-04-14 16:03:53 +02: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 19:39:20 +01: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-03-03 19:39:20 +01:00
const auto PMONITOR = g_pCompositor - > m_pLastMonitor ;
2023-12-07 01:09:25 +01:00
if ( ! PMONITOR )
return ;
2024-04-02 21:32:39 +02:00
const auto PCURRENTWORKSPACE = PMONITOR - > activeWorkspace ;
2023-12-07 11:46:12 +01:00
const bool EXPLICITPREVIOUS = args . starts_with ( " previous " ) ;
2023-04-14 18:51:10 +02:00
2023-10-15 20:07:23 +02:00
if ( args . starts_with ( " previous " ) ) {
2022-08-21 12:21:21 +02:00
// Do nothing if there's no previous workspace, otherwise switch to it.
2023-03-13 16:19:25 +01:00
if ( PCURRENTWORKSPACE - > m_sPrevWorkspace . iID = = - 1 ) {
2022-08-21 12:21:21 +02:00
Debug : : log ( LOG , " No previous workspace to change to " ) ;
return ;
2022-10-13 16:16:39 +02:00
} else {
2023-04-14 16:03:53 +02:00
workspaceToChangeTo = PCURRENTWORKSPACE - > m_iID ;
2022-11-07 13:16:30 +01:00
2023-04-14 16:03:53 +02:00
if ( const auto PWORKSPACETOCHANGETO = g_pCompositor - > getWorkspaceByID ( PCURRENTWORKSPACE - > m_sPrevWorkspace . iID ) ; PWORKSPACETOCHANGETO )
2022-10-13 16:16:39 +02:00
workspaceName = PWORKSPACETOCHANGETO - > m_szName ;
else
2023-04-14 16:03:53 +02:00
workspaceName =
PCURRENTWORKSPACE - > m_sPrevWorkspace . name . empty ( ) ? std : : to_string ( PCURRENTWORKSPACE - > m_sPrevWorkspace . iID ) : PCURRENTWORKSPACE - > m_sPrevWorkspace . name ;
2022-08-21 12:21:21 +02:00
}
2022-07-06 11:02:21 +02:00
} else {
workspaceToChangeTo = getWorkspaceIDFromString ( args , workspaceName ) ;
}
2022-04-14 23:02:10 +02:00
2023-11-12 14:34:42 +01:00
if ( workspaceToChangeTo = = WORKSPACE_INVALID ) {
2022-04-20 16:53:41 +02:00
Debug : : log ( ERR , " Error in changeworkspace, invalid value " ) ;
return ;
2022-03-20 15:55:47 +01:00
}
2023-09-11 16:14:43 +02:00
const bool BISWORKSPACECURRENT = workspaceToChangeTo = = PCURRENTWORKSPACE - > m_iID ;
2023-04-14 18:51:10 +02:00
2024-03-03 19:39:20 +01:00
if ( BISWORKSPACECURRENT & & ( ! ( * PBACKANDFORTH | | EXPLICITPREVIOUS ) | | PCURRENTWORKSPACE - > m_sPrevWorkspace . iID = = - 1 ) )
2022-03-20 15:55:47 +01:00
return ;
2023-09-11 16:14:43 +02:00
g_pInputManager - > unconstrainMouse ( ) ;
g_pInputManager - > m_bEmptyFocusCursorSet = false ;
auto pWorkspaceToChangeTo = g_pCompositor - > getWorkspaceByID ( BISWORKSPACECURRENT ? PCURRENTWORKSPACE - > m_sPrevWorkspace . iID : workspaceToChangeTo ) ;
2023-04-14 16:03:53 +02:00
if ( ! pWorkspaceToChangeTo )
2023-09-11 16:14:43 +02:00
pWorkspaceToChangeTo = g_pCompositor - > createNewWorkspace ( BISWORKSPACECURRENT ? PCURRENTWORKSPACE - > m_sPrevWorkspace . iID : workspaceToChangeTo , PMONITOR - > ID ,
BISWORKSPACECURRENT ? PCURRENTWORKSPACE - > m_sPrevWorkspace . name : workspaceName ) ;
2022-03-20 15:55:47 +01:00
2023-09-11 16:14:43 +02:00
if ( ! BISWORKSPACECURRENT & & pWorkspaceToChangeTo - > m_bIsSpecialWorkspace ) {
2023-04-14 16:03:53 +02:00
PMONITOR - > setSpecialWorkspace ( pWorkspaceToChangeTo ) ;
2023-06-09 12:19:48 +02:00
g_pInputManager - > simulateMouseMovement ( ) ;
2023-04-14 16:03:53 +02:00
return ;
2023-03-13 16:19:25 +01:00
}
2022-08-21 12:21:21 +02:00
2023-04-20 01:46:42 +02:00
g_pInputManager - > releaseAllMouseButtons ( ) ;
2023-04-14 16:03:53 +02:00
const auto PMONITORWORKSPACEOWNER = PMONITOR - > ID = = pWorkspaceToChangeTo - > m_iMonitorID ? PMONITOR : g_pCompositor - > getMonitorFromID ( pWorkspaceToChangeTo - > m_iMonitorID ) ;
2022-05-12 11:27:31 +02:00
2023-09-11 16:14:43 +02:00
if ( ! PMONITORWORKSPACEOWNER )
return ;
2023-04-14 16:28:22 +02:00
g_pCompositor - > setActiveMonitor ( PMONITORWORKSPACEOWNER ) ;
2023-09-11 16:14:43 +02:00
PMONITORWORKSPACEOWNER - > changeWorkspace ( pWorkspaceToChangeTo , false , true ) ;
2022-05-31 14:01:00 +02:00
2023-09-18 12:33:19 +02: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 12:33:19 +02:00
g_pCompositor - > focusWindow ( PLAST ) ;
2024-03-03 19:39:20 +01:00
if ( * PWORKSPACECENTERON = = 1 )
2023-10-10 18:34:28 +02:00
middle = PLAST - > middle ( ) ;
}
g_pCompositor - > warpCursorTo ( middle ) ;
2023-09-18 12:33:19 +02:00
}
2023-04-14 17:22:55 +02:00
2023-09-11 16:14:43 +02:00
if ( BISWORKSPACECURRENT ) {
2024-03-03 19:39:20 +01:00
if ( * PALLOWWORKSPACECYCLES )
2023-09-11 16:14:43 +02:00
pWorkspaceToChangeTo - > rememberPrevWorkspace ( PCURRENTWORKSPACE ) ;
else if ( ! EXPLICITPREVIOUS )
pWorkspaceToChangeTo - > rememberPrevWorkspace ( nullptr ) ;
} else
pWorkspaceToChangeTo - > rememberPrevWorkspace ( PCURRENTWORKSPACE ) ;
2022-09-10 13:11:02 +02:00
2024-01-01 13:02:16 +01:00
if ( ! g_pInputManager - > m_bLastFocusOnLS ) {
if ( g_pCompositor - > m_pLastFocus )
g_pInputManager - > sendMotionEventsToFocused ( ) ;
else
g_pInputManager - > simulateMouseMovement ( ) ;
}
2022-03-21 19:18:33 +01:00
}
void CKeybindManager : : fullscreenActive ( std : : string args ) {
2022-04-02 18:57:09 +02:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow ;
2022-03-21 19:18:33 +01:00
2022-10-14 21:46:32 +02:00
if ( ! PWINDOW )
2022-03-21 19:18:33 +01:00
return ;
2024-02-17 17:21:06 +01:00
PWINDOW - > m_bDontSendFullscreen = false ;
if ( args = = " 2 " )
PWINDOW - > m_bDontSendFullscreen = true ;
2022-06-26 12:12:29 +02:00
g_pCompositor - > setWindowFullscreen ( PWINDOW , ! PWINDOW - > m_bIsFullscreen , args = = " 1 " ? FULLSCREEN_MAXIMIZED : FULLSCREEN_FULL ) ;
2022-03-23 16:51:48 +01:00
}
void CKeybindManager : : moveActiveToWorkspace ( std : : string args ) {
2022-08-15 16:12:53 +02:00
CWindow * PWINDOW = nullptr ;
if ( args . contains ( ' , ' ) ) {
PWINDOW = g_pCompositor - > getWindowByRegex ( args . substr ( args . find_last_of ( ' , ' ) + 1 ) ) ;
2022-12-16 18:17:31 +01:00
args = args . substr ( 0 , args . find_last_of ( ' , ' ) ) ;
2022-08-15 16:12:53 +02:00
} else {
PWINDOW = g_pCompositor - > m_pLastWindow ;
}
2022-03-23 16:51:48 +01:00
2022-10-14 21:46:32 +02:00
if ( ! PWINDOW )
2022-03-23 16:51:48 +01:00
return ;
// hack
2022-11-27 23:42:22 +01:00
std : : string workspaceName ;
2022-12-16 18:17:31 +01:00
const auto WORKSPACEID = getWorkspaceIDFromString ( args , workspaceName ) ;
2022-05-30 15:28:23 +02:00
2023-11-12 14:34:42 +01:00
if ( WORKSPACEID = = WORKSPACE_INVALID ) {
2022-12-14 19:42:48 +01:00
Debug : : log ( LOG , " Invalid workspace in moveActiveToWorkspace " ) ;
return ;
}
2024-04-02 21:32:39 +02: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. " ) ;
return ;
}
2024-03-03 19:39:20 +01:00
auto pWorkspace = g_pCompositor - > getWorkspaceByID ( WORKSPACEID ) ;
CMonitor * pMonitor = nullptr ;
2024-04-02 21:32:39 +02:00
const auto POLDWS = PWINDOW - > m_pWorkspace ;
2024-03-03 19:39:20 +01:00
static auto PALLOWWORKSPACECYCLES = CConfigValue < Hyprlang : : INT > ( " binds:allow_workspace_cycles " ) ;
2022-11-20 19:50:22 +01:00
2023-04-15 17:16:33 +02:00
g_pHyprRenderer - > damageWindow ( PWINDOW ) ;
2023-04-14 16:03:53 +02:00
if ( pWorkspace ) {
g_pCompositor - > moveWindowToWorkspaceSafe ( PWINDOW , pWorkspace ) ;
2023-05-22 19:44:10 +02:00
pMonitor = g_pCompositor - > getMonitorFromID ( pWorkspace - > m_iMonitorID ) ;
g_pCompositor - > setActiveMonitor ( pMonitor ) ;
2022-12-06 21:31:44 +01:00
} else {
2023-05-22 19:44:10 +02:00
pWorkspace = g_pCompositor - > createNewWorkspace ( WORKSPACEID , PWINDOW - > m_iMonitorID , workspaceName ) ;
pMonitor = g_pCompositor - > getMonitorFromID ( pWorkspace - > m_iMonitorID ) ;
2023-04-14 16:03:53 +02:00
g_pCompositor - > moveWindowToWorkspaceSafe ( PWINDOW , pWorkspace ) ;
2022-05-31 14:01:00 +02:00
}
2022-06-08 15:52:38 +02:00
2023-05-22 19:44:10 +02:00
POLDWS - > m_pLastFocusedWindow = g_pCompositor - > getFirstWindowOnWorkspace ( POLDWS - > m_iID ) ;
2023-11-15 13:32:02 +01:00
if ( pWorkspace - > m_bIsSpecialWorkspace )
pMonitor - > setSpecialWorkspace ( pWorkspace ) ;
else if ( POLDWS - > m_bIsSpecialWorkspace )
g_pCompositor - > getMonitorFromID ( POLDWS - > m_iMonitorID ) - > setSpecialWorkspace ( nullptr ) ;
2023-05-22 19:44:10 +02:00
pMonitor - > changeWorkspace ( pWorkspace ) ;
2023-04-14 16:03:53 +02:00
g_pCompositor - > focusWindow ( PWINDOW ) ;
g_pCompositor - > warpCursorTo ( PWINDOW - > middle ( ) ) ;
2023-06-05 09:44:13 +02:00
2024-03-03 19:39:20 +01:00
if ( * PALLOWWORKSPACECYCLES )
2023-09-11 16:14:43 +02:00
pWorkspace - > rememberPrevWorkspace ( POLDWS ) ;
2022-03-27 19:32:50 +02:00
}
2022-04-09 13:26:55 +02:00
2022-05-18 12:18:58 +02:00
void CKeybindManager : : moveActiveToWorkspaceSilent ( std : : string args ) {
2022-12-16 18:17:31 +01:00
CWindow * 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 18:17:31 +01:00
args = args . substr ( 0 , args . find_last_of ( ' , ' ) ) ;
2022-08-15 16:12:53 +02:00
} else {
PWINDOW = g_pCompositor - > m_pLastWindow ;
}
2022-10-14 21:46:32 +02:00
if ( ! PWINDOW )
2022-08-15 16:12:53 +02:00
return ;
2023-04-14 16:03:53 +02:00
std : : string workspaceName = " " ;
2022-05-18 12:18:58 +02:00
2023-04-14 16:03:53 +02:00
const int WORKSPACEID = getWorkspaceIDFromString ( args , workspaceName ) ;
2022-05-18 12:18:58 +02:00
2023-11-12 14:34:42 +01:00
if ( WORKSPACEID = = WORKSPACE_INVALID ) {
2022-05-18 12:18:58 +02:00
Debug : : log ( ERR , " Error in moveActiveToWorkspaceSilent, invalid value " ) ;
return ;
}
2024-04-02 21:32:39 +02:00
if ( WORKSPACEID = = PWINDOW - > workspaceID ( ) )
2022-05-18 12:18:58 +02:00
return ;
2023-04-15 17:16:33 +02:00
g_pHyprRenderer - > damageWindow ( PWINDOW ) ;
2023-04-14 16:03:53 +02:00
auto pWorkspace = g_pCompositor - > getWorkspaceByID ( WORKSPACEID ) ;
const auto OLDMIDDLE = PWINDOW - > middle ( ) ;
2022-05-18 12:18:58 +02:00
2023-04-14 16:03:53 +02:00
if ( pWorkspace ) {
g_pCompositor - > moveWindowToWorkspaceSafe ( PWINDOW , pWorkspace ) ;
} else {
pWorkspace = g_pCompositor - > createNewWorkspace ( WORKSPACEID , PWINDOW - > m_iMonitorID , workspaceName ) ;
g_pCompositor - > moveWindowToWorkspaceSafe ( PWINDOW , pWorkspace ) ;
2022-09-12 21:05:52 +02:00
}
2022-05-18 12:18:58 +02:00
2024-01-02 14:50:30 +01:00
if ( PWINDOW = = g_pCompositor - > m_pLastWindow ) {
2024-02-04 16:40:20 +01:00
if ( const auto PATCOORDS = g_pCompositor - > vectorToWindowUnified ( OLDMIDDLE , RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING , PWINDOW ) ; PATCOORDS )
2024-01-02 14:50:30 +01:00
g_pCompositor - > focusWindow ( PATCOORDS ) ;
else
g_pInputManager - > refocus ( ) ;
}
2022-05-18 12:18:58 +02:00
}
2022-04-09 13:26:55 +02:00
void CKeybindManager : : moveFocusTo ( std : : string args ) {
2024-03-03 19:39:20 +01:00
static auto PFULLCYCLE = CConfigValue < Hyprlang : : INT > ( " binds:movefocus_cycles_fullscreen " ) ;
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 ) ;
2022-04-09 13:26:55 +02:00
return ;
}
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow ;
2023-04-10 15:40:03 +02:00
if ( ! PLASTWINDOW ) {
2023-04-10 21:07:49 +02:00
tryMoveFocusToMonitor ( g_pCompositor - > getMonitorInDirection ( arg ) ) ;
2022-08-08 22:46:11 +02:00
return ;
2023-04-10 15:40:03 +02:00
}
2022-08-08 22:46:11 +02:00
2024-03-03 19:39:20 +01:00
const auto PWINDOWTOCHANGETO = * PFULLCYCLE & & PLASTWINDOW - > m_bIsFullscreen ?
2023-07-19 00:30:10 +02: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
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 ) ;
2023-04-10 15:40:03 +02: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
2023-04-10 21:07:49 +02:00
if ( tryMoveFocusToMonitor ( g_pCompositor - > getMonitorInDirection ( arg ) ) )
2023-04-10 15:40:03 +02:00
return ;
2024-03-03 19:39:20 +01:00
static auto PNOFALLBACK = CConfigValue < Hyprlang : : INT > ( " general:no_focus_fallback " ) ;
if ( * PNOFALLBACK )
2023-04-10 15:40:03 +02:00
return ;
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 ) ;
2022-04-12 16:44:18 +02:00
}
2023-01-21 11:18:55 +01:00
void CKeybindManager : : focusUrgentOrLast ( std : : string args ) {
const auto PWINDOWURGENT = g_pCompositor - > getUrgentWindow ( ) ;
2023-01-29 18:02:55 +01:00
const auto PWINDOWPREV = g_pCompositor - > m_pLastWindow ? ( g_pCompositor - > m_vWindowFocusHistory . size ( ) < 2 ? nullptr : g_pCompositor - > m_vWindowFocusHistory [ 1 ] ) :
( g_pCompositor - > m_vWindowFocusHistory . empty ( ) ? nullptr : g_pCompositor - > m_vWindowFocusHistory [ 0 ] ) ;
2023-01-21 11:18:55 +01:00
if ( ! PWINDOWURGENT & & ! PWINDOWPREV )
return ;
switchToWindow ( PWINDOWURGENT ? PWINDOWURGENT : PWINDOWPREV ) ;
}
2023-02-14 01:46:58 +01:00
void CKeybindManager : : focusCurrentOrLast ( std : : string args ) {
2023-02-19 14:59:39 +01:00
const auto PWINDOWPREV = g_pCompositor - > m_pLastWindow ? ( g_pCompositor - > m_vWindowFocusHistory . size ( ) < 2 ? nullptr : g_pCompositor - > m_vWindowFocusHistory [ 1 ] ) :
( g_pCompositor - > m_vWindowFocusHistory . empty ( ) ? nullptr : g_pCompositor - > m_vWindowFocusHistory [ 0 ] ) ;
2023-02-14 01:46:58 +01:00
if ( ! PWINDOWPREV )
return ;
switchToWindow ( PWINDOWPREV ) ;
}
2023-04-10 21:07:49 +02:00
void CKeybindManager : : swapActive ( std : : string args ) {
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 ) ;
2023-04-10 21:07:49 +02:00
return ;
}
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 ) ;
2023-04-10 21:07:49 +02:00
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow ;
if ( ! PLASTWINDOW | | PLASTWINDOW - > m_bIsFullscreen )
return ;
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 )
return ;
2022-05-05 13:02:55 +02:00
2023-04-10 21:07:49 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > switchWindows ( PLASTWINDOW , PWINDOWTOCHANGETO ) ;
2023-10-10 18:34:28 +02:00
g_pCompositor - > warpCursorTo ( PLASTWINDOW - > middle ( ) ) ;
2023-04-10 21:07:49 +02:00
}
2022-05-05 13:02:55 +02:00
2023-04-10 21:07:49 +02:00
void CKeybindManager : : moveActiveTo ( std : : string args ) {
char arg = args [ 0 ] ;
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 )
return ;
2022-05-05 13:02:55 +02:00
2024-04-02 21:32:39 +02:00
moveActiveToWorkspace ( PNEWMONITOR - > activeWorkspace - > getConfigName ( ) ) ;
2022-05-05 13:02:55 +02:00
return ;
}
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 ) ;
2022-04-20 16:18:58 +02:00
return ;
}
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow ;
2022-10-14 21:46:32 +02:00
if ( ! PLASTWINDOW | | PLASTWINDOW - > m_bIsFullscreen )
2022-04-20 16:18:58 +02:00
return ;
2023-09-11 11:23:57 +02:00
if ( PLASTWINDOW - > m_bIsFloating ) {
2023-10-08 14:49:15 +02:00
Vector2D vPos ;
2023-09-11 11:23:57 +02:00
const auto PMONITOR = g_pCompositor - > getMonitorFromID ( PLASTWINDOW - > m_iMonitorID ) ;
const auto BORDERSIZE = PLASTWINDOW - > getRealBorderSize ( ) ;
switch ( arg ) {
2023-10-08 14:49:15 +02:00
case ' l ' : vPos . x = PMONITOR - > vecReservedTopLeft . x + BORDERSIZE + PMONITOR - > vecPosition . x ; break ;
2024-03-02 01:35:17 +01:00
case ' r ' : vPos . x = PMONITOR - > vecSize . x - PMONITOR - > vecReservedBottomRight . x - PLASTWINDOW - > m_vRealSize . goal ( ) . x - BORDERSIZE + PMONITOR - > vecPosition . x ; break ;
2023-09-11 11:23:57 +02:00
case ' t ' :
2023-10-08 14:49:15 +02:00
case ' u ' : vPos . y = PMONITOR - > vecReservedTopLeft . y + BORDERSIZE + PMONITOR - > vecPosition . y ; break ;
2023-09-11 11:23:57 +02:00
case ' b ' :
2024-03-02 01:35:17 +01:00
case ' d ' : vPos . y = PMONITOR - > vecSize . y - PMONITOR - > vecReservedBottomRight . y - PLASTWINDOW - > m_vRealSize . goal ( ) . y - BORDERSIZE + PMONITOR - > vecPosition . y ; break ;
2023-09-11 11:23:57 +02:00
}
2024-03-02 01:35:17 +01:00
PLASTWINDOW - > m_vRealPosition = Vector2D ( vPos . x ! = 0 ? vPos . x : PLASTWINDOW - > m_vRealPosition . goal ( ) . x , vPos . y ! = 0 ? vPos . y : PLASTWINDOW - > m_vRealPosition . goal ( ) . y ) ;
2023-09-11 11:23:57 +02:00
return ;
}
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 ) {
g_pLayoutManager - > getCurrentLayout ( ) - > moveWindowTo ( PLASTWINDOW , args ) ;
2023-09-11 13:19:21 +02:00
g_pCompositor - > warpCursorTo ( PLASTWINDOW - > middle ( ) ) ;
2022-04-20 16:18:58 +02:00
return ;
2023-04-10 21:07:49 +02:00
}
2022-04-20 16:18:58 +02: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 )
return ;
2023-03-20 02:42:21 +01:00
2024-04-02 21:32:39 +02:00
const auto PWORKSPACE = PMONITORTOCHANGETO - > activeWorkspace ;
2023-04-26 17:58:58 +02:00
2023-05-01 16:39:08 +02:00
moveActiveToWorkspace ( PWORKSPACE - > getConfigName ( ) ) ;
2022-04-20 16:18:58 +02:00
}
2022-04-12 16:44:18 +02:00
void CKeybindManager : : toggleGroup ( std : : string args ) {
2023-02-19 22:07:32 +01:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow ;
if ( ! PWINDOW )
return ;
2023-07-03 12:49:56 +02:00
g_pCompositor - > setWindowFullscreen ( PWINDOW , false , FULLSCREEN_FULL ) ;
2023-09-22 01:42:00 +02:00
if ( ! PWINDOW - > m_sGroupData . pNextWindow )
PWINDOW - > createGroup ( ) ;
else
PWINDOW - > destroyGroup ( ) ;
2022-04-12 16:44:18 +02:00
}
void CKeybindManager : : changeGroupActive ( std : : string args ) {
2023-02-19 22:07:32 +01:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow ;
if ( ! PWINDOW )
return ;
if ( ! PWINDOW - > m_sGroupData . pNextWindow )
return ;
if ( PWINDOW - > m_sGroupData . pNextWindow = = PWINDOW )
return ;
2023-09-23 14:36:40 +02:00
if ( isNumber ( args , false ) ) {
// index starts from '1'; '0' means last window
const int INDEX = std : : stoi ( args ) ;
if ( INDEX > PWINDOW - > getGroupSize ( ) )
return ;
if ( INDEX = = 0 )
PWINDOW - > setGroupCurrent ( PWINDOW - > getGroupTail ( ) ) ;
else
PWINDOW - > setGroupCurrent ( PWINDOW - > getGroupWindowByIndex ( INDEX - 1 ) ) ;
return ;
}
2023-02-24 18:24:51 +01:00
if ( args ! = " b " & & args ! = " prev " ) {
PWINDOW - > setGroupCurrent ( PWINDOW - > m_sGroupData . pNextWindow ) ;
} else {
2023-09-04 15:13:39 +02:00
PWINDOW - > setGroupCurrent ( PWINDOW - > getGroupPrevious ( ) ) ;
2023-02-24 18:24:51 +01:00
}
2022-05-16 17:37:46 +02:00
}
void CKeybindManager : : toggleSplit ( std : : string args ) {
SLayoutMessageHeader header ;
header . pWindow = g_pCompositor - > m_pLastWindow ;
2023-03-11 18:58:34 +01:00
if ( ! header . pWindow )
return ;
2024-04-02 21:32:39 +02:00
const auto PWORKSPACE = header . pWindow - > m_pWorkspace ;
2023-03-11 18:58:34 +01:00
if ( PWORKSPACE - > m_bHasFullscreenWindow )
return ;
2022-05-16 17:37:46 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > layoutMessage ( header , " togglesplit " ) ;
2022-04-20 16:53:41 +02:00
}
2024-02-14 18:58:28 +01:00
void CKeybindManager : : swapSplit ( std : : string args ) {
SLayoutMessageHeader header ;
header . pWindow = g_pCompositor - > m_pLastWindow ;
if ( ! header . pWindow )
return ;
2024-04-02 21:32:39 +02:00
const auto PWORKSPACE = header . pWindow - > m_pWorkspace ;
2024-02-14 18:58:28 +01:00
if ( PWORKSPACE - > m_bHasFullscreenWindow )
return ;
g_pLayoutManager - > getCurrentLayout ( ) - > layoutMessage ( header , " swapsplit " ) ;
}
2022-04-20 16:53:41 +02:00
void CKeybindManager : : alterSplitRatio ( std : : string args ) {
2023-11-12 14:40:02 +01:00
std : : optional < float > splitResult ;
bool exact = false ;
2022-04-20 16:53:41 +02:00
2023-11-12 14:40:02 +01: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 14:40:02 +01:00
if ( ! splitResult . has_value ( ) ) {
2022-04-20 16:53:41 +02:00
Debug : : log ( ERR , " Splitratio invalid in alterSplitRatio! " ) ;
return ;
}
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow ;
2022-10-14 21:46:32 +02:00
if ( ! PLASTWINDOW )
2022-04-20 16:53:41 +02:00
return ;
2023-11-12 14:40:02 +01:00
g_pLayoutManager - > getCurrentLayout ( ) - > alterSplitRatio ( PLASTWINDOW , splitResult . value ( ) , exact ) ;
2022-05-05 12:50:25 +02:00
}
void 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 ) ;
2022-05-18 12:18:58 +02:00
}
2022-05-22 11:52:39 +02:00
void CKeybindManager : : moveCursorToCorner ( std : : string arg ) {
if ( ! isNumber ( arg ) ) {
Debug : : log ( ERR , " moveCursorToCorner, arg has to be a number. " ) ;
return ;
}
const auto CORNER = std : : stoi ( arg ) ;
if ( CORNER < 0 | | CORNER > 3 ) {
Debug : : log ( ERR , " moveCursorToCorner, corner not 0 - 3. " ) ;
return ;
}
const auto PWINDOW = g_pCompositor - > m_pLastWindow ;
2022-10-14 21:46:32 +02:00
if ( ! PWINDOW )
2022-05-22 11:52:39 +02:00
return ;
switch ( CORNER ) {
case 0 :
// bottom left
2024-03-02 01:35:17 +01:00
wlr_cursor_warp ( g_pCompositor - > m_sWLRCursor , g_pCompositor - > m_sSeat . mouse - > mouse , PWINDOW - > m_vRealPosition . value ( ) . x ,
PWINDOW - > m_vRealPosition . value ( ) . y + PWINDOW - > m_vRealSize . value ( ) . y ) ;
2022-05-22 11:52:39 +02:00
break ;
case 1 :
// bottom right
2024-03-02 01:35:17 +01:00
wlr_cursor_warp ( g_pCompositor - > m_sWLRCursor , g_pCompositor - > m_sSeat . mouse - > mouse , PWINDOW - > m_vRealPosition . value ( ) . x + PWINDOW - > m_vRealSize . value ( ) . x ,
PWINDOW - > m_vRealPosition . value ( ) . y + PWINDOW - > m_vRealSize . value ( ) . y ) ;
2022-05-22 11:52:39 +02:00
break ;
case 2 :
// top right
2024-03-02 01:35:17 +01:00
wlr_cursor_warp ( g_pCompositor - > m_sWLRCursor , g_pCompositor - > m_sSeat . mouse - > mouse , PWINDOW - > m_vRealPosition . value ( ) . x + PWINDOW - > m_vRealSize . value ( ) . x ,
PWINDOW - > m_vRealPosition . value ( ) . y ) ;
2022-05-22 11:52:39 +02:00
break ;
case 3 :
// top left
2024-03-02 01:35:17 +01:00
wlr_cursor_warp ( g_pCompositor - > m_sWLRCursor , g_pCompositor - > m_sSeat . mouse - > mouse , PWINDOW - > m_vRealPosition . value ( ) . x , PWINDOW - > m_vRealPosition . value ( ) . y ) ;
2022-05-22 11:52:39 +02:00
break ;
}
2022-05-26 19:05:32 +02:00
}
2023-04-23 20:50:53 +02:00
void CKeybindManager : : moveCursor ( std : : string args ) {
std : : string x_str , y_str ;
2023-05-02 15:53:15 +02:00
int x , y ;
2023-04-23 20:50:53 +02:00
2023-05-02 15:53:15 +02:00
size_t i = args . find_first_of ( ' ' ) ;
2023-04-23 20:50:53 +02:00
if ( i = = std : : string : : npos ) {
Debug : : log ( ERR , " moveCursor, takes 2 arguments. " ) ;
return ;
}
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. " ) ;
return ;
}
if ( ! isNumber ( y_str ) ) {
Debug : : log ( ERR , " moveCursor, y argument has to be a number. " ) ;
return ;
}
x = std : : stoi ( x_str ) ;
y = std : : stoi ( y_str ) ;
wlr_cursor_warp ( g_pCompositor - > m_sWLRCursor , g_pCompositor - > m_sSeat . mouse - > mouse , x , y ) ;
}
2022-05-26 19:05:32 +02:00
void 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 21:32:39 +02:00
const auto PWORKSPACE = g_pCompositor - > m_pLastMonitor - > activeWorkspace ;
2022-05-26 19:05:32 +02:00
if ( ! PWORKSPACE )
return ; // ????
if ( args = = " allpseudo " ) {
PWORKSPACE - > m_bDefaultPseudo = ! PWORKSPACE - > m_bDefaultPseudo ;
// apply
2022-06-30 15:44:26 +02:00
for ( auto & w : g_pCompositor - > m_vWindows ) {
2024-04-02 21:32:39 +02: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
std : : deque < CWindow * > ptrs ;
2022-06-30 15:44:26 +02:00
for ( auto & w : g_pCompositor - > m_vWindows )
ptrs . push_back ( w . get ( ) ) ;
2022-05-26 19:05:32 +02:00
for ( auto & w : ptrs ) {
2024-04-02 21:32:39 +02: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 ) ;
2022-05-26 19:05:32 +02:00
return ;
}
// recalc mon
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( g_pCompositor - > m_pLastMonitor - > ID ) ;
2022-05-29 00:00:47 +02:00
}
2023-01-08 14:19:18 +01:00
void CKeybindManager : : renameWorkspace ( std : : string args ) {
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 ) ;
g_pCompositor - > renameWorkspace ( workspace , name ) ;
} else {
g_pCompositor - > renameWorkspace ( std : : stoi ( args ) , " " ) ;
}
2023-09-06 21:45:37 +02:00
} catch ( std : : exception & e ) { Debug : : log ( ERR , " Invalid arg in renameWorkspace, expected numeric id only or a numeric id and string name. \" {} \" : \" {} \" " , args , e . what ( ) ) ; }
2023-01-08 14:19:18 +01:00
}
2022-05-29 00:00:47 +02:00
void CKeybindManager : : exitHyprland ( std : : string argz ) {
2024-03-25 02:46:59 +01:00
g_pCompositor - > m_bExitTriggered = true ;
2022-05-30 20:05:38 +02:00
}
void CKeybindManager : : moveCurrentWorkspaceToMonitor ( std : : string args ) {
2022-09-02 11:53:12 +02:00
CMonitor * 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 " ) ;
2022-07-29 16:59:31 +02:00
return ;
2024-02-10 00:47:00 +01:00
}
2022-07-29 16:59:31 +02:00
2022-05-30 20:05:38 +02:00
// get the current workspace
2024-04-02 21:32:39 +02:00
const auto PCURRENTWORKSPACE = g_pCompositor - > m_pLastMonitor - > activeWorkspace ;
2022-05-30 20:05:38 +02:00
2024-02-10 00:47:00 +01:00
if ( ! PCURRENTWORKSPACE ) {
Debug : : log ( ERR , " moveCurrentWorkspaceToMonitor invalid workspace! " ) ;
2022-05-30 20:05:38 +02:00
return ;
2024-02-10 00:47:00 +01:00
}
2022-05-30 20:05:38 +02:00
g_pCompositor - > moveWorkspaceToMonitor ( PCURRENTWORKSPACE , PMONITOR ) ;
}
void CKeybindManager : : moveWorkspaceToMonitor ( std : : string args ) {
2022-07-06 16:50:11 +02:00
if ( ! args . contains ( ' ' ) )
2022-06-06 19:32:14 +02:00
return ;
2022-05-30 20:05:38 +02:00
std : : string workspace = args . substr ( 0 , args . find_first_of ( ' ' ) ) ;
2022-12-16 18:17:31 +01:00
std : : string monitor = args . substr ( args . find_first_of ( ' ' ) + 1 ) ;
2022-05-30 20:05:38 +02:00
2022-12-16 18:17:31 +01:00
const auto PMONITOR = g_pCompositor - > getMonitorFromString ( monitor ) ;
2022-05-30 20:05:38 +02:00
2022-12-16 18:17:31 +01:00
if ( ! PMONITOR ) {
2022-05-30 20:05:38 +02:00
Debug : : log ( ERR , " Ignoring moveWorkspaceToMonitor: monitor doesnt exist " ) ;
return ;
}
std : : string workspaceName ;
2022-12-16 18:17:31 +01:00
const int WORKSPACEID = getWorkspaceIDFromString ( workspace , workspaceName ) ;
2022-05-30 20:05:38 +02:00
2023-11-12 14:34:42 +01:00
if ( WORKSPACEID = = WORKSPACE_INVALID ) {
2022-05-30 20:05:38 +02:00
Debug : : log ( ERR , " moveWorkspaceToMonitor invalid workspace! " ) ;
return ;
}
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! " ) ;
return ;
}
2022-05-30 20:05:38 +02:00
g_pCompositor - > moveWorkspaceToMonitor ( PWORKSPACE , PMONITOR ) ;
2022-05-31 14:01:00 +02:00
}
2024-01-15 16:30:46 +01:00
void CKeybindManager : : focusWorkspaceOnCurrentMonitor ( std : : string args ) {
std : : string workspaceName ;
2024-03-04 18:05:20 +01:00
int workspaceID = getWorkspaceIDFromString ( args , workspaceName ) ;
2024-01-15 16:30:46 +01:00
2024-03-04 18:05:20 +01:00
if ( workspaceID = = WORKSPACE_INVALID ) {
2024-01-15 16:30:46 +01:00
Debug : : log ( ERR , " focusWorkspaceOnCurrentMonitor invalid workspace! " ) ;
return ;
}
2024-02-05 23:36:22 +01:00
const auto PCURRMONITOR = g_pCompositor - > m_pLastMonitor ;
2024-01-15 16:30:46 +01:00
if ( ! PCURRMONITOR ) {
Debug : : log ( ERR , " focusWorkspaceOnCurrentMonitor monitor doesn't exist! " ) ;
return ;
}
2024-03-04 18:05:20 +01:00
auto pWorkspace = g_pCompositor - > getWorkspaceByID ( workspaceID ) ;
2024-01-15 16:30:46 +01:00
2024-03-04 18:05:20 +01:00
if ( ! pWorkspace ) {
pWorkspace = g_pCompositor - > createNewWorkspace ( workspaceID , PCURRMONITOR - > ID ) ;
2024-01-15 16:30:46 +01: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-01-15 16:30:46 +01:00
return ;
}
2024-03-04 18:05:20 +01:00
static auto PBACKANDFORTH = CConfigValue < Hyprlang : : INT > ( " binds:workspace_back_and_forth " ) ;
2024-04-02 21:32:39 +02:00
if ( * PBACKANDFORTH & & PCURRMONITOR - > activeWorkspaceID ( ) = = workspaceID & & pWorkspace - > m_sPrevWorkspace . iID ! = - 1 ) {
2024-03-04 18:05:20 +01:00
const int PREVWORKSPACEID = pWorkspace - > m_sPrevWorkspace . iID ;
const auto PREVWORKSPACENAME = pWorkspace - > m_sPrevWorkspace . name ;
// Workspace to focus is previous workspace
pWorkspace = g_pCompositor - > getWorkspaceByID ( PREVWORKSPACEID ) ;
if ( ! pWorkspace )
pWorkspace = g_pCompositor - > createNewWorkspace ( PREVWORKSPACEID , PCURRMONITOR - > ID , PREVWORKSPACENAME ) ;
workspaceID = pWorkspace - > m_iID ;
}
if ( pWorkspace - > m_iMonitorID ! = PCURRMONITOR - > ID ) {
const auto POLDMONITOR = g_pCompositor - > getMonitorFromID ( pWorkspace - > m_iMonitorID ) ;
2024-01-15 16:30:46 +01:00
if ( ! POLDMONITOR ) { // wat
Debug : : log ( ERR , " focusWorkspaceOnCurrentMonitor old monitor doesn't exist! " ) ;
return ;
}
2024-04-02 21:32:39 +02:00
if ( POLDMONITOR - > activeWorkspaceID ( ) = = workspaceID ) {
2024-01-15 16:30:46 +01:00
g_pCompositor - > swapActiveWorkspaces ( POLDMONITOR , PCURRMONITOR ) ;
return ;
} else {
2024-03-04 18:05:20 +01:00
g_pCompositor - > moveWorkspaceToMonitor ( pWorkspace , PCURRMONITOR , true ) ;
2024-01-15 16:30:46 +01:00
}
}
2024-03-04 18:05:20 +01:00
changeworkspace ( pWorkspace - > getConfigName ( ) ) ;
2024-01-15 16:30:46 +01:00
}
2022-05-31 14:01:00 +02:00
void CKeybindManager : : toggleSpecialWorkspace ( std : : string args ) {
2024-03-03 19:39:20 +01:00
std : : string workspaceName = " " ;
int workspaceID = getWorkspaceIDFromString ( " special: " + args , workspaceName ) ;
2022-11-27 23:42:22 +01:00
2023-11-12 14:34:42 +01:00
if ( workspaceID = = WORKSPACE_INVALID | | ! g_pCompositor - > isWorkspaceSpecial ( workspaceID ) ) {
2022-11-27 23:42:22 +01:00
Debug : : log ( ERR , " Invalid workspace passed to special " ) ;
return ;
}
2022-12-16 18:17:31 +01:00
bool requestedWorkspaceIsAlreadyOpen = false ;
2024-03-30 17:58:18 +01:00
const auto PMONITOR = g_pCompositor - > m_pLastMonitor ;
2024-04-02 21:32:39 +02:00
int specialOpenOnMonitor = PMONITOR - > activeSpecialWorkspaceID ( ) ;
2022-05-31 14:01:00 +02:00
2022-06-30 15:44:26 +02:00
for ( auto & m : g_pCompositor - > m_vMonitors ) {
2024-04-02 21:32:39 +02:00
if ( m - > activeSpecialWorkspaceID ( ) = = workspaceID ) {
2022-11-27 23:42:22 +01:00
requestedWorkspaceIsAlreadyOpen = true ;
2022-05-31 14:01:00 +02:00
break ;
}
}
2022-11-27 23:42:22 +01: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 16:03:53 +02: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 23:42:22 +01: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 21:31:44 +01:00
PSPECIALWORKSPACE = g_pCompositor - > createNewWorkspace ( workspaceID , PMONITOR - > ID , workspaceName ) ;
2022-07-07 19:01:42 +02:00
2023-04-14 16:03:53 +02:00
PMONITOR - > setSpecialWorkspace ( PSPECIALWORKSPACE ) ;
2022-08-31 17:02:44 +02:00
}
2022-06-06 13:48:17 +02:00
}
void CKeybindManager : : forceRendererReload ( std : : string args ) {
2022-06-30 23:55:28 +02:00
bool overAgain = false ;
2022-06-30 15:44:26 +02:00
for ( auto & m : g_pCompositor - > m_vMonitors ) {
2023-03-16 15:03:40 +01:00
if ( ! m - > output )
continue ;
2024-02-27 23:11:59 +01:00
auto rule = g_pConfigManager - > getMonitorRuleFor ( * m ) ;
2022-06-30 23:55:28 +02:00
if ( ! g_pHyprRenderer - > applyMonitorRule ( m . get ( ) , & rule , true ) ) {
overAgain = true ;
break ;
}
2022-06-06 13:48:17 +02:00
}
2022-06-30 23:55:28 +02:00
if ( overAgain )
forceRendererReload ( args ) ;
2022-06-06 19:32:14 +02:00
}
void CKeybindManager : : resizeActive ( std : : string args ) {
2022-10-14 21:46:32 +02:00
if ( ! g_pCompositor - > m_pLastWindow | | g_pCompositor - > m_pLastWindow - > m_bIsFullscreen )
2022-08-15 15:59:07 +02:00
return ;
2022-08-09 10:57:09 +02:00
2024-03-02 01:35:17 +01:00
const auto SIZ = g_pCompositor - > parseWindowVectorArgsRelative ( args , g_pCompositor - > m_pLastWindow - > m_vRealSize . goal ( ) ) ;
2022-06-06 19:32:14 +02:00
2023-05-15 16:16:06 +02:00
if ( SIZ . x < 1 | | SIZ . y < 1 )
return ;
2024-03-02 01:35:17 +01:00
g_pLayoutManager - > getCurrentLayout ( ) - > resizeActiveWindow ( SIZ - g_pCompositor - > m_pLastWindow - > m_vRealSize . goal ( ) ) ;
2022-06-23 10:14:59 +02:00
2024-03-02 01:35:17 +01:00
if ( g_pCompositor - > m_pLastWindow - > m_vRealSize . goal ( ) . x > 1 & & g_pCompositor - > m_pLastWindow - > m_vRealSize . goal ( ) . y > 1 )
2022-10-14 21:46:32 +02:00
g_pCompositor - > m_pLastWindow - > setHidden ( false ) ;
2022-08-15 15:59:07 +02:00
}
2022-06-23 10:14:59 +02:00
2022-08-15 15:59:07 +02:00
void CKeybindManager : : moveActive ( std : : string args ) {
2022-12-16 18:17:31 +01:00
if ( ! g_pCompositor - > m_pLastWindow | | g_pCompositor - > m_pLastWindow - > m_bIsFullscreen )
return ;
2022-06-23 10:14:59 +02:00
2024-03-02 01:35:17 +01:00
const auto POS = g_pCompositor - > parseWindowVectorArgsRelative ( args , g_pCompositor - > m_pLastWindow - > m_vRealPosition . goal ( ) ) ;
2022-06-23 10:14:59 +02:00
2024-03-02 01:35:17 +01:00
g_pLayoutManager - > getCurrentLayout ( ) - > moveActiveWindow ( POS - g_pCompositor - > m_pLastWindow - > m_vRealPosition . goal ( ) ) ;
2022-08-15 15:59:07 +02:00
}
2022-06-23 10:14:59 +02:00
2022-08-15 15:59:07 +02:00
void 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 18:17:31 +01:00
const auto MOVECMD = args . substr ( 0 , args . find_first_of ( ' , ' ) ) ;
2022-08-09 10:57:09 +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 , " moveWindow: no window " ) ;
2022-06-06 19:32:14 +02:00
return ;
}
2022-09-20 20:58:08 +02:00
if ( PWINDOW - > m_bIsFullscreen )
return ;
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 ) ;
2022-06-10 11:39:06 +02:00
}
2022-08-15 15:59:07 +02:00
void 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 18:17:31 +01: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 " ) ;
2022-06-23 10:14:59 +02:00
return ;
}
2022-12-16 18:17:31 +01:00
if ( PWINDOW - > m_bIsFullscreen )
return ;
2022-09-20 20:58:08 +02: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 16:16:06 +02:00
if ( SIZ . x < 1 | | SIZ . y < 1 )
return ;
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 21:46:32 +02:00
PWINDOW - > setHidden ( false ) ;
2022-06-23 10:14:59 +02:00
}
2022-07-09 18:39:41 +02:00
void CKeybindManager : : circleNext ( std : : string arg ) {
2022-08-11 19:45:37 +02:00
2022-10-28 22:31:39 +02:00
if ( ! g_pCompositor - > m_pLastWindow ) {
// if we have a clear focus, find the first window and get the next focusable.
2024-04-02 21:32:39 +02:00
if ( g_pCompositor - > getWindowsOnWorkspace ( g_pCompositor - > m_pLastMonitor - > activeWorkspaceID ( ) ) > 0 ) {
const auto PWINDOW = g_pCompositor - > getFirstWindowOnWorkspace ( g_pCompositor - > m_pLastMonitor - > activeWorkspaceID ( ) ) ;
2022-10-28 22:31:39 +02:00
switchToWindow ( PWINDOW ) ;
}
return ;
}
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 " ) )
switchToWindow ( g_pCompositor - > getPrevWindowOnWorkspace ( g_pCompositor - > m_pLastWindow , true , floatStatus ) ) ;
2022-08-11 19:45:37 +02:00
else
2023-12-24 15:08:48 +01:00
switchToWindow ( g_pCompositor - > getNextWindowOnWorkspace ( g_pCompositor - > m_pLastWindow , true , floatStatus ) ) ;
2022-06-10 11:39:06 +02:00
}
2022-06-10 12:06:27 +02:00
2022-07-01 16:24:37 +02:00
void CKeybindManager : : focusWindow ( std : : string regexp ) {
2022-07-26 17:30:30 +02:00
const auto PWINDOW = g_pCompositor - > getWindowByRegex ( regexp ) ;
2022-07-18 01:00:12 +02:00
2022-07-26 17:30:30 +02:00
if ( ! PWINDOW )
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 21:32:39 +02:00
const auto PWORKSPACE = PWINDOW - > m_pWorkspace ;
2024-02-26 01:05:20 +01:00
if ( ! PWORKSPACE ) {
Debug : : log ( ERR , " BUG THIS: null workspace in focusWindow " ) ;
return ;
}
2024-04-02 21:32:39 +02:00
if ( g_pCompositor - > m_pLastMonitor - > activeWorkspace ! = PWINDOW - > m_pWorkspace ) {
2023-05-01 16:39:08 +02:00
Debug : : log ( LOG , " Fake executing workspace to move focus " ) ;
changeworkspace ( PWORKSPACE - > getConfigName ( ) ) ;
}
2024-02-26 01:05:20 +01:00
if ( PWORKSPACE - > m_bHasFullscreenWindow ) {
const auto FSWINDOW = g_pCompositor - > getFullscreenWindowOnWorkspace ( PWORKSPACE - > m_iID ) ;
const auto FSMODE = PWORKSPACE - > m_efFullscreenMode ;
2024-02-26 01:15:59 +01: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-26 01:05:20 +01:00
2024-02-26 01:15:59 +01:00
g_pCompositor - > focusWindow ( PWINDOW ) ;
} else {
if ( FSWINDOW ! = PWINDOW & & ! PWINDOW - > m_bPinned )
g_pCompositor - > setWindowFullscreen ( FSWINDOW , false , FULLSCREEN_FULL ) ;
2024-02-26 01:05:20 +01:00
2024-02-26 01:15:59 +01:00
g_pCompositor - > focusWindow ( PWINDOW ) ;
if ( FSWINDOW ! = PWINDOW & & ! PWINDOW - > m_bPinned )
g_pCompositor - > setWindowFullscreen ( PWINDOW , true , FSMODE ) ;
}
} else
2024-02-26 01:05:20 +01:00
g_pCompositor - > focusWindow ( PWINDOW ) ;
2022-06-10 12:06:27 +02:00
2023-09-11 11:09:34 +02:00
g_pCompositor - > warpCursorTo ( PWINDOW - > middle ( ) ) ;
2022-06-10 12:06:27 +02:00
}
2022-06-22 20:23:20 +02:00
2024-04-11 12:05:31 +02:00
void CKeybindManager : : toggleSwallow ( std : : string args ) {
CWindow * pWindow = g_pCompositor - > m_pLastWindow ;
if ( pWindow - > m_pSwallowed & & g_pCompositor - > windowExists ( pWindow - > m_pSwallowed ) ) {
pWindow - > m_pPreviouslySwallowed = pWindow - > m_pSwallowed ;
pWindow - > m_pSwallowed - > setHidden ( false ) ;
g_pLayoutManager - > getCurrentLayout ( ) - > onWindowCreated ( pWindow - > m_pSwallowed ) ;
pWindow - > m_pSwallowed = nullptr ;
} else if ( pWindow - > m_pPreviouslySwallowed & & g_pCompositor - > windowExists ( pWindow - > m_pPreviouslySwallowed ) ) {
pWindow - > m_pSwallowed = pWindow - > m_pPreviouslySwallowed ;
g_pLayoutManager - > getCurrentLayout ( ) - > onWindowRemoved ( pWindow - > m_pPreviouslySwallowed ) ;
pWindow - > m_pPreviouslySwallowed - > setHidden ( true ) ;
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( pWindow - > m_iMonitorID ) ;
}
}
2022-06-22 20:23:20 +02:00
void CKeybindManager : : setSubmap ( std : : string submap ) {
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 21:54:53 +01:00
EMIT_HOOK_EVENT ( " submap " , m_szCurrentSelectedSubmap ) ;
2022-06-22 20:23:20 +02:00
return ;
}
for ( auto & k : g_pKeybindManager - > m_lKeybinds ) {
if ( k . submap = = submap ) {
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 21:54:53 +01:00
EMIT_HOOK_EVENT ( " submap " , m_szCurrentSelectedSubmap ) ;
2022-06-22 20:23:20 +02:00
return ;
}
}
2023-09-06 21:45:37 +02:00
Debug : : log ( ERR , " 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
void CKeybindManager : : pass ( std : : string regexp ) {
// find the first window passing the regex
const auto PWINDOW = g_pCompositor - > getWindowByRegex ( regexp ) ;
if ( ! PWINDOW ) {
Debug : : log ( ERR , " pass: window not found " ) ;
return ;
}
const auto PLASTSRF = g_pCompositor - > m_pLastFocus ;
const auto KEYBOARD = wlr_seat_get_keyboard ( g_pCompositor - > m_sSeat . seat ) ;
2022-12-16 18:17:31 +01:00
if ( ! KEYBOARD ) {
2022-07-26 17:30:30 +02:00
Debug : : log ( ERR , " No kb in pass? " ) ;
return ;
}
2023-04-10 23:42:05 +02:00
const auto XWTOXW = PWINDOW - > m_bIsX11 & & g_pCompositor - > m_pLastWindow & & g_pCompositor - > m_pLastWindow - > m_bIsX11 ;
const auto SL = Vector2D ( g_pCompositor - > m_sSeat . seat - > pointer_state . sx , g_pCompositor - > m_sSeat . seat - > pointer_state . sy ) ;
uint32_t keycodes [ 32 ] = { 0 } ;
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 )
2023-04-10 23:42:05 +02:00
wlr_seat_keyboard_enter ( g_pCompositor - > m_sSeat . seat , PWINDOW - > m_pWLSurface . wlr ( ) , keycodes , 0 , & KEYBOARD - > modifiers ) ;
2022-08-28 17:01:48 +02:00
else
2023-03-20 16:00:58 +01:00
wlr_seat_pointer_enter ( g_pCompositor - > m_sSeat . seat , PWINDOW - > m_pWLSurface . wlr ( ) , 1 , 1 ) ;
2022-08-28 17:01:48 +02:00
}
2022-09-25 20:07:48 +02:00
2022-08-08 20:31:48 +02:00
wlr_keyboard_modifiers kbmods = { g_pInputManager - > accumulateModsFromAllKBs ( ) , 0 , 0 , 0 } ;
wlr_seat_keyboard_notify_modifiers ( g_pCompositor - > m_sSeat . seat , & kbmods ) ;
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 )
wlr_seat_keyboard_notify_key ( g_pCompositor - > m_sSeat . seat , g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastCode - 8 , WLR_BUTTON_PRESSED ) ;
else
2024-03-09 17:35:35 +01:00
wlr_seat_pointer_notify_button ( g_pCompositor - > m_sSeat . seat , 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 )
wlr_seat_keyboard_notify_key ( g_pCompositor - > m_sSeat . seat , g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastCode - 8 , WLR_BUTTON_RELEASED ) ;
else
2024-03-09 17:35:35 +01:00
wlr_seat_pointer_notify_button ( g_pCompositor - > m_sSeat . seat , 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 ) {
wlr_seat_keyboard_notify_key ( g_pCompositor - > m_sSeat . seat , g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastCode - 8 , WLR_BUTTON_PRESSED ) ;
wlr_seat_keyboard_notify_key ( g_pCompositor - > m_sSeat . seat , g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastCode - 8 , WLR_BUTTON_RELEASED ) ;
} else {
2024-03-09 17:35:35 +01:00
wlr_seat_pointer_notify_button ( g_pCompositor - > m_sSeat . seat , g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastMouseCode , WL_POINTER_BUTTON_STATE_PRESSED ) ;
wlr_seat_pointer_notify_button ( g_pCompositor - > m_sSeat . seat , 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 )
return ;
// Massive hack:
// this will make wlroots NOT send the leave event to XWayland apps, provided we are not on an XWayland window already.
// please kill me
if ( PWINDOW - > m_bIsX11 ) {
2022-08-28 17:01:48 +02:00
if ( g_pKeybindManager - > m_uLastCode ! = 0 ) {
2022-12-16 18:17:31 +01:00
g_pCompositor - > m_sSeat . seat - > keyboard_state . focused_client = nullptr ;
2022-08-28 17:01:48 +02:00
g_pCompositor - > m_sSeat . seat - > keyboard_state . focused_surface = nullptr ;
} else {
2022-12-16 18:17:31 +01:00
g_pCompositor - > m_sSeat . seat - > pointer_state . focused_client = nullptr ;
2022-08-28 17:01:48 +02:00
g_pCompositor - > m_sSeat . seat - > pointer_state . focused_surface = nullptr ;
}
2022-08-28 16:43:15 +02:00
}
2022-08-28 17:01:48 +02:00
if ( g_pKeybindManager - > m_uLastCode ! = 0 )
wlr_seat_keyboard_enter ( g_pCompositor - > m_sSeat . seat , PLASTSRF , KEYBOARD - > keycodes , KEYBOARD - > num_keycodes , & KEYBOARD - > modifiers ) ;
else
2023-03-20 16:00:58 +01:00
wlr_seat_pointer_enter ( g_pCompositor - > m_sSeat . seat , PWINDOW - > m_pWLSurface . wlr ( ) , SL . x , SL . y ) ;
2022-07-28 12:00:10 +02:00
}
void CKeybindManager : : layoutmsg ( std : : string msg ) {
SLayoutMessageHeader hd = { g_pCompositor - > m_pLastWindow } ;
g_pLayoutManager - > getCurrentLayout ( ) - > layoutMessage ( hd , msg ) ;
2022-07-28 12:07:41 +02:00
}
void CKeybindManager : : toggleOpaque ( std : : string unused ) {
const auto PWINDOW = g_pCompositor - > m_pLastWindow ;
2022-10-14 21:46:32 +02:00
if ( ! PWINDOW )
2022-07-28 12:07:41 +02:00
return ;
2023-04-10 21:07:49 +02:00
PWINDOW - > m_sAdditionalConfigData . forceOpaque = ! PWINDOW - > m_sAdditionalConfigData . forceOpaque ;
2023-03-30 00:44:25 +02:00
PWINDOW - > m_sAdditionalConfigData . forceOpaqueOverridden = true ;
2022-07-28 12:07:41 +02:00
g_pHyprRenderer - > damageWindow ( PWINDOW ) ;
2022-07-30 23:51:13 +02:00
}
void CKeybindManager : : dpms ( std : : string arg ) {
2023-10-15 20:07:23 +02:00
bool enable = arg . starts_with ( " on " ) ;
2022-12-16 18:17:31 +01:00
std : : string port = " " ;
2022-10-05 11:31:47 +02:00
2023-10-15 20:07:23 +02:00
if ( arg . starts_with ( " toggle " ) )
2023-07-30 16:46:33 +02:00
enable = ! std : : any_of ( g_pCompositor - > m_vMonitors . begin ( ) , g_pCompositor - > m_vMonitors . end ( ) , [ & ] ( const auto & other ) { return ! other - > dpmsStatus ; } ) ; // enable if any is off
2023-06-20 21:35:54 +02:00
if ( arg . find_first_of ( ' ' ) ! = std : : string : : npos )
2022-10-05 11:31:47 +02:00
port = arg . substr ( arg . find_first_of ( ' ' ) + 1 ) ;
2022-07-30 23:51:13 +02:00
for ( auto & m : g_pCompositor - > m_vMonitors ) {
2022-10-05 11:31:47 +02:00
if ( ! port . empty ( ) & & m - > szName ! = port )
continue ;
2024-01-28 02:57:13 +01:00
wlr_output_state_set_enabled ( m - > state . wlr ( ) , enable ) ;
2022-09-25 20:07:48 +02:00
2022-10-05 19:14:11 +02:00
m - > dpmsStatus = enable ;
2024-01-28 02:57:13 +01:00
if ( ! m - > state . commit ( ) ) {
2023-09-06 21:45:37 +02:00
Debug : : log ( ERR , " Couldn't commit output {} " , m - > szName ) ;
2022-07-30 23:51:13 +02:00
}
2022-07-31 12:39:49 +02:00
if ( enable )
g_pHyprRenderer - > damageMonitor ( m . get ( ) ) ;
2022-07-30 23:51:13 +02:00
}
2022-07-31 15:46:42 +02:00
g_pCompositor - > m_bDPMSStateON = enable ;
2022-07-30 23:51:13 +02:00
}
2022-08-24 21:40:36 +02:00
void CKeybindManager : : swapnext ( std : : string arg ) {
CWindow * toSwap = nullptr ;
2022-10-14 21:46:32 +02:00
if ( ! g_pCompositor - > m_pLastWindow )
2022-08-24 21:40:36 +02:00
return ;
const auto PLASTWINDOW = g_pCompositor - > m_pLastWindow ;
2022-12-16 18:17:31 +01:00
const auto PLASTCYCLED = g_pCompositor - > windowValidMapped ( g_pCompositor - > m_pLastWindow - > m_pLastCycledWindow ) & &
2024-04-02 21:32:39 +02:00
g_pCompositor - > m_pLastWindow - > m_pLastCycledWindow - > m_pWorkspace = = PLASTWINDOW - > m_pWorkspace ?
2022-12-16 18:17:31 +01:00
g_pCompositor - > m_pLastWindow - > m_pLastCycledWindow :
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 17:53:31 +02:00
toSwap = g_pCompositor - > getPrevWindowOnWorkspace ( PLASTCYCLED ? PLASTCYCLED : PLASTWINDOW , true ) ;
2022-08-24 21:40:36 +02:00
else
2022-09-29 17:53:31 +02: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 " )
2022-09-29 17:53:31 +02:00
toSwap = g_pCompositor - > getPrevWindowOnWorkspace ( PLASTWINDOW ) , true ;
2022-08-24 22:01:25 +02:00
else
2022-09-29 17:53:31 +02: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 ) ;
}
2022-08-25 21:25:28 +02:00
void CKeybindManager : : swapActiveWorkspaces ( std : : string args ) {
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 )
2022-08-25 21:25:28 +02:00
return ;
g_pCompositor - > swapActiveWorkspaces ( PMON1 , PMON2 ) ;
}
2022-09-10 13:11:02 +02:00
void CKeybindManager : : pinActive ( std : : string args ) {
2023-01-08 18:37:24 +01:00
CWindow * PWINDOW = nullptr ;
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
2023-01-08 18:37:24 +01:00
PWINDOW = g_pCompositor - > m_pLastWindow ;
if ( ! PWINDOW ) {
Debug : : log ( ERR , " pin: window not found " ) ;
2022-09-10 13:11:02 +02:00
return ;
2023-01-08 18:37:24 +01:00
}
2022-09-10 13:11:02 +02:00
2023-01-08 18:37:24 +01:00
if ( ! PWINDOW - > m_bIsFloating | | PWINDOW - > m_bIsFullscreen )
return ;
2024-04-02 21:32:39 +02:00
PWINDOW - > m_bPinned = ! PWINDOW - > m_bPinned ;
PWINDOW - > m_pWorkspace = g_pCompositor - > getMonitorFromID ( PWINDOW - > m_iMonitorID ) - > 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 21:32:39 +02:00
const auto PWORKSPACE = PWINDOW - > m_pWorkspace ;
2022-09-10 13:11:02 +02:00
2024-02-04 16:40:20 +01:00
PWORKSPACE - > m_pLastFocusedWindow = g_pCompositor - > vectorToWindowUnified ( g_pInputManager - > getMouseCoordsInternal ( ) , RESERVED_EXTENTS | INPUT_EXTENTS ) ;
2024-03-18 19:11:20 +01:00
g_pEventManager - > postEvent ( SHyprIPCEvent { " pin " , std : : format ( " {:x},{} " , ( uintptr_t ) PWINDOW , ( int ) PWINDOW - > m_bPinned ) } ) ;
EMIT_HOOK_EVENT ( " pin " , PWINDOW ) ;
2022-09-10 13:11:02 +02:00
}
2022-09-19 20:04:48 +02:00
void CKeybindManager : : mouse ( std : : string args ) {
2023-08-08 18:52:20 +02:00
const auto ARGS = CVarList ( args . substr ( 1 ) , 2 , ' ' ) ;
2022-09-19 20:04:48 +02:00
const auto PRESSED = args [ 0 ] = = ' 1 ' ;
2023-08-08 18:52:20 +02:00
if ( ARGS [ 0 ] = = " movewindow " ) {
2022-09-19 20:04:48 +02:00
if ( PRESSED ) {
2022-09-20 11:02:20 +02:00
g_pKeybindManager - > m_bIsMouseBindActive = true ;
2023-08-30 17:39:22 +02:00
const auto mouseCoords = g_pInputManager - > getMouseCoordsInternal ( ) ;
2024-02-04 16:40:20 +01:00
CWindow * pWindow = g_pCompositor - > vectorToWindowUnified ( mouseCoords , RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING ) ;
2023-08-30 17:39:22 +02:00
2023-12-28 23:54:41 +01:00
if ( pWindow & & ! pWindow - > m_bIsFullscreen )
pWindow - > checkInputOnDecos ( INPUT_TYPE_DRAG_START , mouseCoords ) ;
2022-09-19 20:04:48 +02:00
2023-10-29 21:14:47 +01:00
if ( ! g_pInputManager - > currentlyDraggedWindow )
g_pInputManager - > currentlyDraggedWindow = pWindow ;
g_pInputManager - > dragMode = MBIND_MOVE ;
2022-09-19 20:04:48 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > onBeginDragWindow ( ) ;
} else {
2022-09-20 11:02:20 +02:00
g_pKeybindManager - > m_bIsMouseBindActive = false ;
2022-09-19 20:04:48 +02:00
if ( g_pInputManager - > currentlyDraggedWindow ) {
g_pLayoutManager - > getCurrentLayout ( ) - > onEndDragWindow ( ) ;
g_pInputManager - > currentlyDraggedWindow = nullptr ;
2022-12-16 18:17:31 +01:00
g_pInputManager - > dragMode = MBIND_INVALID ;
2022-09-19 20:04:48 +02:00
}
}
2023-08-08 18:52:20 +02:00
} else if ( ARGS [ 0 ] = = " resizewindow " ) {
2022-09-19 20:04:48 +02:00
if ( PRESSED ) {
2022-09-20 11:02:20 +02:00
g_pKeybindManager - > m_bIsMouseBindActive = true ;
2024-02-04 16:40:20 +01:00
g_pInputManager - > currentlyDraggedWindow =
g_pCompositor - > vectorToWindowUnified ( g_pInputManager - > getMouseCoordsInternal ( ) , RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING ) ;
2022-09-19 20:04:48 +02:00
2023-08-08 18:52:20 +02:00
try {
switch ( std : : stoi ( ARGS [ 1 ] ) ) {
case 1 : g_pInputManager - > dragMode = MBIND_RESIZE_FORCE_RATIO ; break ;
case 2 : g_pInputManager - > dragMode = MBIND_RESIZE_BLOCK_RATIO ; break ;
default : g_pInputManager - > dragMode = MBIND_RESIZE ;
}
} catch ( std : : exception & e ) { g_pInputManager - > dragMode = MBIND_RESIZE ; }
2022-09-19 20:04:48 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > onBeginDragWindow ( ) ;
} else {
2022-09-20 11:02:20 +02:00
g_pKeybindManager - > m_bIsMouseBindActive = false ;
2022-09-19 20:04:48 +02:00
if ( g_pInputManager - > currentlyDraggedWindow ) {
g_pLayoutManager - > getCurrentLayout ( ) - > onEndDragWindow ( ) ;
g_pInputManager - > currentlyDraggedWindow = nullptr ;
2022-12-16 18:17:31 +01:00
g_pInputManager - > dragMode = MBIND_INVALID ;
2022-09-19 20:04:48 +02:00
}
}
}
}
2022-10-14 15:22:20 +02:00
void CKeybindManager : : bringActiveToTop ( std : : string args ) {
2022-10-14 21:46:32 +02:00
if ( g_pCompositor - > m_pLastWindow & & g_pCompositor - > m_pLastWindow - > m_bIsFloating )
2023-09-21 23:18:26 +02:00
g_pCompositor - > changeWindowZOrder ( g_pCompositor - > m_pLastWindow , true ) ;
}
void CKeybindManager : : alterZOrder ( std : : string args ) {
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 ) ;
if ( ! PWINDOW & & g_pCompositor - > m_pLastWindow & & g_pCompositor - > m_pLastWindow - > m_bIsFloating )
PWINDOW = g_pCompositor - > m_pLastWindow ;
if ( ! PWINDOW ) {
Debug : : log ( ERR , " alterZOrder: no window " ) ;
return ;
}
if ( POSITION = = " top " )
g_pCompositor - > changeWindowZOrder ( PWINDOW , 1 ) ;
else if ( POSITION = = " bottom " )
g_pCompositor - > changeWindowZOrder ( PWINDOW , 0 ) ;
else {
2023-11-30 16:20:08 +01:00
Debug : : log ( ERR , " alterZOrder: bad position: {} " , POSITION ) ;
2023-09-21 23:18:26 +02:00
return ;
}
g_pInputManager - > simulateMouseMovement ( ) ;
2022-10-14 15:22:20 +02:00
}
2023-01-01 16:54:13 +01:00
void CKeybindManager : : fakeFullscreenActive ( std : : string args ) {
if ( g_pCompositor - > m_pLastWindow ) {
// will also set the flag
2023-01-06 13:29:43 +01:00
g_pCompositor - > m_pLastWindow - > m_bFakeFullscreenState = ! g_pCompositor - > m_pLastWindow - > m_bFakeFullscreenState ;
2023-12-11 17:51:10 +01:00
g_pXWaylandManager - > setWindowFullscreen ( g_pCompositor - > m_pLastWindow , g_pCompositor - > m_pLastWindow - > shouldSendFullscreenState ( ) ) ;
2023-01-01 16:54:13 +01:00
}
}
2023-02-21 13:13:35 +01:00
void CKeybindManager : : lockGroups ( std : : string args ) {
2023-06-20 21:35:54 +02:00
if ( args = = " lock " | | args . empty ( ) | | args = = " lockgroups " )
2023-02-21 13:13:35 +01:00
g_pKeybindManager - > m_bGroupsLocked = true ;
2023-06-20 21:35:54 +02:00
else if ( args = = " toggle " )
2023-03-02 21:50:37 +01:00
g_pKeybindManager - > m_bGroupsLocked = ! g_pKeybindManager - > m_bGroupsLocked ;
2023-06-20 21:35:54 +02:00
else
2023-02-21 13:13:35 +01:00
g_pKeybindManager - > m_bGroupsLocked = false ;
2023-09-15 13:06:59 +02:00
g_pEventManager - > postEvent ( SHyprIPCEvent { " lockgroups " , g_pKeybindManager - > m_bGroupsLocked ? " 1 " : " 0 " } ) ;
2023-02-21 13:13:35 +01:00
}
2023-02-26 14:52:11 +01:00
2023-06-09 23:44:18 +02:00
void CKeybindManager : : lockActiveGroup ( std : : string args ) {
const auto PWINDOW = g_pCompositor - > m_pLastWindow ;
if ( ! PWINDOW | | ! PWINDOW - > m_sGroupData . pNextWindow )
return ;
2023-06-20 21:35:54 +02:00
2023-06-09 23:44:18 +02:00
const auto PHEAD = PWINDOW - > getGroupHead ( ) ;
2023-06-20 21:35:54 +02:00
if ( args = = " lock " )
2023-06-09 23:44:18 +02:00
PHEAD - > m_sGroupData . locked = true ;
2023-06-20 21:35:54 +02:00
else if ( args = = " toggle " )
2023-06-09 23:44:18 +02:00
PHEAD - > m_sGroupData . locked = ! PHEAD - > m_sGroupData . locked ;
2023-06-20 21:35:54 +02:00
else
2023-06-09 23:44:18 +02:00
PHEAD - > m_sGroupData . locked = false ;
2023-06-13 12:04:54 +02:00
g_pCompositor - > updateWindowAnimatedDecorationValues ( PWINDOW ) ;
2023-06-09 23:44:18 +02:00
}
2023-09-11 00:29:10 +02:00
void CKeybindManager : : moveWindowIntoGroup ( CWindow * pWindow , CWindow * pWindowInDirection ) {
2023-09-22 01:42:00 +02:00
if ( pWindow - > m_sGroupData . deny )
return ;
2023-09-11 00:29:10 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > onWindowRemoved ( pWindow ) ; // This removes groupped property!
2024-03-03 19:39:20 +01:00
static auto USECURRPOS = CConfigValue < Hyprlang : : INT > ( " group:insert_after_current " ) ;
pWindowInDirection = * USECURRPOS ? pWindowInDirection : pWindowInDirection - > getGroupTail ( ) ;
2023-09-11 00:29:10 +02:00
pWindowInDirection - > insertWindowToGroup ( pWindow ) ;
pWindowInDirection - > setGroupCurrent ( pWindow ) ;
pWindow - > updateWindowDecos ( ) ;
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateWindow ( pWindow ) ;
g_pCompositor - > focusWindow ( pWindow ) ;
g_pCompositor - > warpCursorTo ( pWindow - > middle ( ) ) ;
2023-11-11 15:37:17 +01:00
if ( ! pWindow - > getDecorationByType ( DECORATION_GROUPBAR ) )
pWindow - > addWindowDeco ( std : : make_unique < CHyprGroupBarDecoration > ( pWindow ) ) ;
2023-09-11 00:29:10 +02:00
}
2023-09-13 12:13:29 +02:00
void CKeybindManager : : moveWindowOutOfGroup ( CWindow * pWindow , const std : : string & dir ) {
2024-03-03 19:39:20 +01:00
static auto BFOCUSREMOVEDWINDOW = CConfigValue < Hyprlang : : INT > ( " group:focus_removed_window " ) ;
const auto PWINDOWPREV = pWindow - > getGroupPrevious ( ) ;
eDirection direction ;
2023-09-13 12:13:29 +02: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-11 00:29:10 +02:00
2023-09-13 12:44:02 +02:00
if ( pWindow - > m_sGroupData . pNextWindow = = pWindow ) {
2023-09-22 01:42:00 +02:00
pWindow - > destroyGroup ( ) ;
2023-09-13 12:44:02 +02:00
} else {
g_pLayoutManager - > getCurrentLayout ( ) - > onWindowRemoved ( pWindow ) ;
2023-09-11 00:29:10 +02:00
2023-09-13 12:44:02 +02:00
const auto GROUPSLOCKEDPREV = g_pKeybindManager - > m_bGroupsLocked ;
g_pKeybindManager - > m_bGroupsLocked = true ;
2023-09-11 00:29:10 +02:00
2023-09-13 12:44:02 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > onWindowCreated ( pWindow , direction ) ;
2023-09-11 00:29:10 +02:00
2023-09-13 12:44:02 +02:00
g_pKeybindManager - > m_bGroupsLocked = GROUPSLOCKEDPREV ;
}
2023-09-11 00:29:10 +02:00
2024-03-03 19:39:20 +01:00
if ( * BFOCUSREMOVEDWINDOW ) {
2023-09-11 00:29:10 +02:00
g_pCompositor - > focusWindow ( pWindow ) ;
g_pCompositor - > warpCursorTo ( pWindow - > middle ( ) ) ;
} else {
g_pCompositor - > focusWindow ( PWINDOWPREV ) ;
2023-09-13 16:02:21 +02:00
g_pCompositor - > warpCursorTo ( PWINDOWPREV - > middle ( ) ) ;
2023-09-11 00:29:10 +02:00
}
}
2023-02-26 14:52:11 +01:00
void CKeybindManager : : moveIntoGroup ( std : : string args ) {
2024-03-03 19:39:20 +01:00
char arg = args [ 0 ] ;
2023-07-24 18:25:10 +02:00
2024-03-03 19:39:20 +01:00
static auto PIGNOREGROUPLOCK = CConfigValue < Hyprlang : : INT > ( " binds:ignore_group_lock " ) ;
2023-10-11 12:13:12 +02:00
2024-03-03 19:39:20 +01:00
if ( ! * PIGNOREGROUPLOCK & & g_pKeybindManager - > m_bGroupsLocked )
2023-10-11 12:13:12 +02:00
return ;
2023-02-26 14:52:11 +01: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 ) ;
2023-02-26 14:52:11 +01:00
return ;
}
const auto PWINDOW = g_pCompositor - > m_pLastWindow ;
2023-09-22 01:42:00 +02:00
if ( ! PWINDOW | | PWINDOW - > m_bIsFloating | | PWINDOW - > m_sGroupData . deny )
2023-02-26 14:52:11 +01:00
return ;
2023-08-30 17:39:22 +02:00
auto PWINDOWINDIR = g_pCompositor - > getWindowInDirection ( PWINDOW , arg ) ;
2023-02-26 14:52:11 +01:00
if ( ! PWINDOWINDIR | | ! PWINDOWINDIR - > m_sGroupData . pNextWindow )
return ;
2023-09-11 00:29:10 +02:00
// Do not move window into locked group if binds:ignore_group_lock is false
2024-03-03 19:39:20 +01:00
if ( ! * PIGNOREGROUPLOCK & & ( PWINDOWINDIR - > getGroupHead ( ) - > m_sGroupData . locked | | ( PWINDOW - > m_sGroupData . pNextWindow & & PWINDOW - > getGroupHead ( ) - > m_sGroupData . locked ) ) )
2023-07-20 19:48:32 +02:00
return ;
2023-09-11 00:29:10 +02:00
moveWindowIntoGroup ( PWINDOW , PWINDOWINDIR ) ;
2023-02-26 14:52:11 +01:00
}
2023-02-26 14:55:35 +01:00
void CKeybindManager : : moveOutOfGroup ( std : : string args ) {
2024-03-03 19:39:20 +01:00
static auto PIGNOREGROUPLOCK = CConfigValue < Hyprlang : : INT > ( " binds:ignore_group_lock " ) ;
2023-10-11 12:13:12 +02:00
2024-03-03 19:39:20 +01:00
if ( ! * PIGNOREGROUPLOCK & & g_pKeybindManager - > m_bGroupsLocked )
2023-10-11 12:13:12 +02:00
return ;
2024-02-17 23:44:22 +01:00
CWindow * PWINDOW = nullptr ;
if ( args ! = " active " & & args . length ( ) > 1 )
PWINDOW = g_pCompositor - > getWindowByRegex ( args ) ;
else
PWINDOW = g_pCompositor - > m_pLastWindow ;
2023-02-26 14:55:35 +01:00
if ( ! PWINDOW | | ! PWINDOW - > m_sGroupData . pNextWindow )
return ;
2023-09-11 00:29:10 +02:00
moveWindowOutOfGroup ( PWINDOW ) ;
}
2023-02-26 14:55:35 +01:00
2023-09-11 00:29:10 +02:00
void CKeybindManager : : moveWindowOrGroup ( std : : string args ) {
2024-03-03 19:39:20 +01:00
char arg = args [ 0 ] ;
2023-02-26 14:55:35 +01:00
2024-03-03 19:39:20 +01:00
static auto PIGNOREGROUPLOCK = CConfigValue < Hyprlang : : INT > ( " binds:ignore_group_lock " ) ;
2023-02-26 14:55:35 +01:00
2023-09-11 00:29:10 +02: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 ) ;
2023-09-11 00:29:10 +02:00
return ;
}
2023-02-26 14:55:35 +01:00
2023-09-11 00:29:10 +02:00
const auto PWINDOW = g_pCompositor - > m_pLastWindow ;
if ( ! PWINDOW | | PWINDOW - > m_bIsFullscreen )
return ;
2023-10-11 12:13:12 +02:00
2024-03-03 19:39:20 +01:00
if ( ! * PIGNOREGROUPLOCK & & g_pKeybindManager - > m_bGroupsLocked ) {
2023-10-11 12:13:12 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > moveWindowTo ( PWINDOW , args ) ;
return ;
}
2023-09-22 01:42:00 +02:00
const auto PWINDOWINDIR = g_pCompositor - > getWindowInDirection ( PWINDOW , arg ) ;
2023-09-11 00:29:10 +02:00
2023-09-22 01:42:00 +02:00
const bool ISWINDOWGROUP = PWINDOW - > m_sGroupData . pNextWindow ;
const bool ISWINDOWGROUPLOCKED = ISWINDOWGROUP & & PWINDOW - > getGroupHead ( ) - > m_sGroupData . locked ;
const bool ISWINDOWGROUPSINGLE = ISWINDOWGROUP & & PWINDOW - > m_sGroupData . pNextWindow = = PWINDOW ;
2023-09-11 00:29:10 +02:00
// note: PWINDOWINDIR is not null implies !PWINDOW->m_bIsFloating
2023-09-22 01:42:00 +02:00
if ( PWINDOWINDIR & & PWINDOWINDIR - > m_sGroupData . pNextWindow ) { // target is group
2024-03-03 19:39:20 +01:00
if ( ! * PIGNOREGROUPLOCK & & ( PWINDOWINDIR - > getGroupHead ( ) - > m_sGroupData . locked | | ISWINDOWGROUPLOCKED | | PWINDOW - > m_sGroupData . deny ) ) {
2023-09-11 00:29:10 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > moveWindowTo ( PWINDOW , args ) ;
g_pCompositor - > warpCursorTo ( PWINDOW - > middle ( ) ) ;
} else
moveWindowIntoGroup ( PWINDOW , PWINDOWINDIR ) ;
2023-09-22 01:42:00 +02:00
} else if ( PWINDOWINDIR ) { // target is regular window
2024-03-03 19:39:20 +01:00
if ( ( ! * PIGNOREGROUPLOCK & & ISWINDOWGROUPLOCKED ) | | ! ISWINDOWGROUP | | ( ISWINDOWGROUPSINGLE & & PWINDOW - > m_eGroupRules & GROUP_SET_ALWAYS ) ) {
2023-09-11 00:29:10 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > moveWindowTo ( PWINDOW , args ) ;
g_pCompositor - > warpCursorTo ( PWINDOW - > middle ( ) ) ;
} else
2023-09-13 12:13:29 +02:00
moveWindowOutOfGroup ( PWINDOW , args ) ;
2024-02-26 15:05:24 +01:00
} else if ( ( * PIGNOREGROUPLOCK | | ! ISWINDOWGROUPLOCKED ) & & ISWINDOWGROUP ) { // no target window
2023-09-13 12:13:29 +02: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 ) ;
g_pCompositor - > warpCursorTo ( PWINDOW - > middle ( ) ) ;
}
2023-09-22 01:42:00 +02:00
g_pCompositor - > updateWindowAnimatedDecorationValues ( PWINDOW ) ;
2023-09-11 00:29:10 +02:00
}
void CKeybindManager : : setIgnoreGroupLock ( std : : string args ) {
2024-03-03 19:39:20 +01:00
static auto PIGNOREGROUPLOCK = ( Hyprlang : : INT * const * ) g_pConfigManager - > getConfigValuePtr ( " binds:ignore_group_lock " ) ;
2023-09-11 00:29:10 +02:00
if ( args = = " toggle " )
2024-03-03 19:39:20 +01:00
* * PIGNOREGROUPLOCK = ! * * PIGNOREGROUPLOCK ;
2023-09-11 00:29:10 +02:00
else
2024-03-03 19:39:20 +01:00
* * PIGNOREGROUPLOCK = args = = " on " ;
2023-09-11 00:29:10 +02:00
2024-03-03 19:39:20 +01:00
g_pEventManager - > postEvent ( SHyprIPCEvent { " ignoregrouplock " , std : : to_string ( * * PIGNOREGROUPLOCK ) } ) ;
2023-02-26 14:55:35 +01:00
}
2023-04-09 14:48:20 +02:00
2023-09-22 01:42:00 +02:00
void CKeybindManager : : denyWindowFromGroup ( std : : string args ) {
const auto PWINDOW = g_pCompositor - > m_pLastWindow ;
if ( ! PWINDOW | | ( PWINDOW & & PWINDOW - > m_sGroupData . pNextWindow ) )
return ;
if ( args = = " toggle " )
PWINDOW - > m_sGroupData . deny = ! PWINDOW - > m_sGroupData . deny ;
else
PWINDOW - > m_sGroupData . deny = args = = " on " ;
g_pCompositor - > updateWindowAnimatedDecorationValues ( PWINDOW ) ;
}
2023-04-09 14:48:20 +02:00
void CKeybindManager : : global ( std : : string args ) {
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 ( ) )
2023-04-09 14:48:20 +02:00
return ;
if ( ! g_pProtocolManager - > m_pGlobalShortcutsProtocolManager - > globalShortcutExists ( APPID , NAME ) )
return ;
g_pProtocolManager - > m_pGlobalShortcutsProtocolManager - > sendGlobalShortcutEvent ( APPID , NAME , g_pKeybindManager - > m_iPassPressed ) ;
2023-04-10 21:07:49 +02:00
}
2023-07-13 17:55:20 +02:00
void CKeybindManager : : moveGroupWindow ( std : : string args ) {
const auto BACK = args = = " b " | | args = = " prev " ;
if ( ! g_pCompositor - > m_pLastWindow | | ! g_pCompositor - > m_pLastWindow - > m_sGroupData . pNextWindow )
return ;
2023-07-20 19:48:32 +02:00
if ( ( ! BACK & & g_pCompositor - > m_pLastWindow - > m_sGroupData . pNextWindow - > m_sGroupData . head ) | | ( BACK & & g_pCompositor - > m_pLastWindow - > m_sGroupData . head ) ) {
2023-07-19 00:30:10 +02:00
std : : swap ( g_pCompositor - > m_pLastWindow - > m_sGroupData . head , g_pCompositor - > m_pLastWindow - > m_sGroupData . pNextWindow - > m_sGroupData . head ) ;
2023-07-20 19:48:32 +02:00
std : : swap ( g_pCompositor - > m_pLastWindow - > m_sGroupData . locked , g_pCompositor - > m_pLastWindow - > m_sGroupData . pNextWindow - > m_sGroupData . locked ) ;
} else
2023-07-19 00:30:10 +02:00
g_pCompositor - > m_pLastWindow - > switchWithWindowInGroup ( BACK ? g_pCompositor - > m_pLastWindow - > getGroupPrevious ( ) : g_pCompositor - > m_pLastWindow - > m_sGroupData . pNextWindow ) ;
2023-07-20 19:48:32 +02:00
2023-07-13 20:17:14 +02:00
g_pCompositor - > m_pLastWindow - > updateWindowDecos ( ) ;
2023-07-13 17:55:20 +02:00
}