2022-03-19 17:48:18 +01:00
# include "KeybindManager.hpp"
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>
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
2022-12-16 18:17:31 +01:00
m_mDispatchers [ " exec " ] = spawn ;
2023-02-19 14:59:39 +01:00
m_mDispatchers [ " execr " ] = spawnRaw ;
2022-12-16 18:17:31 +01:00
m_mDispatchers [ " killactive " ] = killActive ;
m_mDispatchers [ " closewindow " ] = kill ;
m_mDispatchers [ " togglefloating " ] = toggleActiveFloating ;
m_mDispatchers [ " workspace " ] = changeworkspace ;
2023-01-08 14:19:18 +01:00
m_mDispatchers [ " renameworkspace " ] = renameWorkspace ;
2022-12-16 18:17:31 +01:00
m_mDispatchers [ " fullscreen " ] = fullscreenActive ;
2023-01-01 16:54:13 +01:00
m_mDispatchers [ " fakefullscreen " ] = fakeFullscreenActive ;
2022-12-16 18:17:31 +01:00
m_mDispatchers [ " movetoworkspace " ] = moveActiveToWorkspace ;
m_mDispatchers [ " movetoworkspacesilent " ] = moveActiveToWorkspaceSilent ;
m_mDispatchers [ " pseudo " ] = toggleActivePseudo ;
m_mDispatchers [ " movefocus " ] = moveFocusTo ;
m_mDispatchers [ " movewindow " ] = moveActiveTo ;
2023-04-10 21:07:49 +02:00
m_mDispatchers [ " swapwindow " ] = swapActive ;
2022-12-16 18:17:31 +01:00
m_mDispatchers [ " centerwindow " ] = centerWindow ;
m_mDispatchers [ " togglegroup " ] = toggleGroup ;
m_mDispatchers [ " changegroupactive " ] = changeGroupActive ;
2023-07-13 17:55:20 +02:00
m_mDispatchers [ " movegroupwindow " ] = moveGroupWindow ;
2022-12-16 18:17:31 +01:00
m_mDispatchers [ " togglesplit " ] = toggleSplit ;
m_mDispatchers [ " splitratio " ] = alterSplitRatio ;
m_mDispatchers [ " focusmonitor " ] = focusMonitor ;
m_mDispatchers [ " movecursortocorner " ] = moveCursorToCorner ;
2023-04-23 20:50:53 +02:00
m_mDispatchers [ " movecursor " ] = moveCursor ;
2022-12-16 18:17:31 +01:00
m_mDispatchers [ " workspaceopt " ] = workspaceOpt ;
m_mDispatchers [ " exit " ] = exitHyprland ;
2022-05-30 20:05:38 +02:00
m_mDispatchers [ " movecurrentworkspacetomonitor " ] = moveCurrentWorkspaceToMonitor ;
2022-12-16 18:17:31 +01:00
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 ;
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 ;
2023-01-21 11:18:55 +01:00
m_mDispatchers [ " focusurgentorlast " ] = focusUrgentOrLast ;
2023-02-14 01:46:58 +01:00
m_mDispatchers [ " focuscurrentorlast " ] = focusCurrentOrLast ;
2023-02-21 13:13:35 +01:00
m_mDispatchers [ " lockgroups " ] = lockGroups ;
2023-06-09 23:44:18 +02:00
m_mDispatchers [ " lockactivegroup " ] = lockActiveGroup ;
2023-02-26 14:52:11 +01:00
m_mDispatchers [ " moveintogroup " ] = moveIntoGroup ;
2023-02-26 14:55:35 +01:00
m_mDispatchers [ " moveoutofgroup " ] = moveOutOfGroup ;
2023-09-11 00:29:10 +02:00
m_mDispatchers [ " movewindoworgroup " ] = moveWindowOrGroup ;
m_mDispatchers [ " setignoregrouplock " ] = setIgnoreGroupLock ;
2023-04-09 14:48:20 +02:00
m_mDispatchers [ " global " ] = global ;
2022-07-26 23:34:03 +02:00
m_tScrollTimer . reset ( ) ;
2023-09-10 17:27:14 +02:00
g_pHookSystem - > hookDynamic ( " configReloaded " , [ this ] ( void * hk , std : : any param ) {
// 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
}
void CKeybindManager : : removeKeybind ( uint32_t mod , const std : : string & key ) {
for ( auto it = m_lKeybinds . begin ( ) ; it ! = m_lKeybinds . end ( ) ; + + it ) {
2022-07-08 09:32:09 +02:00
if ( isNumber ( key ) & & std : : stoi ( key ) > 9 ) {
const auto KEYNUM = std : : stoi ( key ) ;
if ( it - > modmask = = mod & & it - > keycode = = KEYNUM ) {
it = m_lKeybinds . erase ( it ) ;
if ( it = = m_lKeybinds . end ( ) )
break ;
}
2022-12-16 18:17:31 +01:00
} else if ( it - > modmask = = mod & & it - > key = = key ) {
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 ;
}
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 ;
}
2022-12-16 18:17:31 +01:00
const auto FILEPATH = g_pConfigManager - > getString ( " input:kb_file " ) ;
const auto RULES = g_pConfigManager - > getString ( " input:kb_rules " ) ;
const auto MODEL = g_pConfigManager - > getString ( " input:kb_model " ) ;
const auto LAYOUT = g_pConfigManager - > getString ( " input:kb_layout " ) ;
const auto VARIANT = g_pConfigManager - > getString ( " input:kb_variant " ) ;
const auto OPTIONS = g_pConfigManager - > getString ( " input:kb_options " ) ;
2022-08-21 16:43:18 +02:00
2023-08-25 17:21:55 +02: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 ( ) } ;
2023-08-07 19:34:15 +02:00
const auto PCONTEXT = xkb_context_new ( XKB_CONTEXT_NO_FLAGS ) ;
2023-08-25 17:21:55 +02:00
FILE * const KEYMAPFILE = FILEPATH = = " " ? NULL : fopen ( absolutePath ( FILEPATH , g_pConfigManager - > configCurrentPath ) . c_str ( ) , " r " ) ;
2022-08-21 16:43:18 +02:00
2023-08-25 17:21:55 +02: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 ) {
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
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 ;
}
2023-05-29 18:11:37 +02:00
const auto PWORKSPACE = g_pCompositor - > getWorkspaceByID ( g_pCompositor - > m_pLastMonitor - > activeWorkspace ) ;
const auto PNEWMAINWORKSPACE = g_pCompositor - > getWorkspaceByID ( monitor - > activeWorkspace ) ;
2023-04-10 21:07:49 +02:00
g_pCompositor - > setActiveMonitor ( monitor ) ;
2023-05-29 18:11:37 +02:00
PNEWMAINWORKSPACE - > rememberPrevWorkspace ( PWORKSPACE ) ;
const auto PNEWWORKSPACE = monitor - > specialWorkspaceID ! = 0 ? g_pCompositor - > getWorkspaceByID ( monitor - > specialWorkspaceID ) : 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 ( ) ) ;
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
}
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 ;
if ( PLASTWINDOW & & PLASTWINDOW - > m_iWorkspaceID = = PWINDOWTOCHANGETO - > m_iWorkspaceID & & PLASTWINDOW - > m_bIsFullscreen ) {
const auto PWORKSPACE = g_pCompositor - > getWorkspaceByID ( PLASTWINDOW - > m_iWorkspaceID ) ;
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 ) {
2022-08-29 11:17:42 +02:00
m_dPressedKeycodes . clear ( ) ;
m_dPressedKeysyms . clear ( ) ;
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
2022-12-16 18:17:31 +01:00
const xkb_keysym_t keysym = xkb_state_key_get_one_sym ( 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
2022-09-20 23:23:02 +02:00
bool mouseBindWasActive = ensureMouseBindState ( ) ;
2022-09-20 11:02:20 +02:00
2022-07-20 22:45:06 +02:00
bool found = false ;
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
}
2022-07-20 23:17:26 +02:00
m_dPressedKeycodes . push_back ( KEYCODE ) ;
m_dPressedKeysyms . push_back ( keysym ) ;
2022-10-04 21:07:21 +02:00
found = handleKeybinds ( MODS , " " , keysym , 0 , true , e - > time_msec ) | | found ;
2022-07-20 22:45:06 +02:00
2022-10-04 21:07:21 +02:00
found = handleKeybinds ( MODS , " " , 0 , KEYCODE , true , e - > time_msec ) | | found ;
2022-07-24 14:35:58 +02:00
if ( found )
2022-07-25 14:24:02 +02:00
shadowKeybinds ( keysym , KEYCODE ) ;
2022-07-20 22:45:06 +02:00
} else if ( e - > state = = WL_KEYBOARD_KEY_STATE_RELEASED ) {
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
2022-09-13 20:27:07 +02:00
m_dPressedKeycodes . erase ( std : : remove ( m_dPressedKeycodes . begin ( ) , m_dPressedKeycodes . end ( ) , KEYCODE ) , m_dPressedKeycodes . end ( ) ) ;
m_dPressedKeysyms . erase ( std : : remove ( m_dPressedKeysyms . begin ( ) , m_dPressedKeysyms . end ( ) , keysym ) , m_dPressedKeysyms . end ( ) ) ;
2022-07-20 23:17:26 +02:00
2022-10-04 21:07:21 +02:00
found = handleKeybinds ( MODS , " " , keysym , 0 , false , e - > time_msec ) | | found ;
2022-07-20 23:17:26 +02:00
2022-10-04 21:07:21 +02:00
found = handleKeybinds ( MODS , " " , 0 , KEYCODE , false , e - > time_msec ) | | found ;
2022-07-20 23:17:26 +02:00
shadowKeybinds ( ) ;
2022-07-20 22:45:06 +02:00
}
2022-09-20 23:23:02 +02:00
return ! found & & ! 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 ) {
2022-12-16 18:17:31 +01:00
const auto MODS = g_pInputManager - > accumulateModsFromAllKBs ( ) ;
2022-07-21 18:18:03 +02:00
2022-12-16 18:17:31 +01:00
static auto * const PDELAY = & g_pConfigManager - > getConfigValuePtr ( " binds:scroll_event_delay " ) - > intValue ;
2022-07-26 23:34:03 +02:00
if ( m_tScrollTimer . getMillis ( ) < * PDELAY ) {
m_tScrollTimer . reset ( ) ;
return true ; // timer hasn't passed yet!
}
m_tScrollTimer . reset ( ) ;
2022-07-21 18:18:03 +02:00
bool found = false ;
if ( e - > source = = WLR_AXIS_SOURCE_WHEEL & & e - > orientation = = WLR_AXIS_ORIENTATION_VERTICAL ) {
2023-02-23 14:55:27 +01:00
if ( e - > delta < 0 )
2022-10-04 21:07:21 +02:00
found = handleKeybinds ( MODS , " mouse_down " , 0 , 0 , true , 0 ) ;
2023-02-23 14:55:27 +01:00
else
2022-10-04 21:07:21 +02:00
found = handleKeybinds ( MODS , " mouse_up " , 0 , 0 , true , 0 ) ;
2023-02-23 14:55:27 +01:00
} else if ( e - > source = = WLR_AXIS_SOURCE_WHEEL & & e - > orientation = = WLR_AXIS_ORIENTATION_HORIZONTAL ) {
if ( e - > delta < 0 )
found = handleKeybinds ( MODS , " mouse_left " , 0 , 0 , true , 0 ) ;
else
found = handleKeybinds ( MODS , " mouse_right " , 0 , 0 , true , 0 ) ;
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 ( ) ;
2022-12-16 18:17:31 +01:00
bool found = 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
2022-09-20 23:23:02 +02:00
bool mouseBindWasActive = ensureMouseBindState ( ) ;
2022-07-26 14:50:21 +02:00
if ( e - > state = = WLR_BUTTON_PRESSED ) {
2022-10-04 21:07:21 +02:00
found = handleKeybinds ( MODS , " mouse: " + std : : to_string ( e - > button ) , 0 , 0 , true , 0 ) ;
2022-07-26 14:50:21 +02:00
if ( found )
shadowKeybinds ( ) ;
} else {
2022-10-04 21:07:21 +02:00
found = handleKeybinds ( MODS , " mouse: " + std : : to_string ( e - > button ) , 0 , 0 , false , 0 ) ;
2022-07-26 14:50:21 +02:00
shadowKeybinds ( ) ;
2022-07-21 18:18:03 +02:00
}
2022-09-20 23:23:02 +02:00
return ! found & & ! 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 ) {
if ( e - > state = = WLR_BUTTON_PRESSED ) {
mouse ( " 1resizewindow " ) ;
} else {
mouse ( " 0resizewindow " ) ;
}
}
2022-10-04 21:07:21 +02:00
void CKeybindManager : : onSwitchEvent ( const std : : string & switchName ) {
handleKeybinds ( 0 , " switch: " + switchName , 0 , 0 , true , 0 ) ;
}
2023-01-08 16:35:24 +01:00
void CKeybindManager : : onSwitchOnEvent ( const std : : string & switchName ) {
handleKeybinds ( 0 , " switch:on: " + switchName , 0 , 0 , true , 0 ) ;
}
void CKeybindManager : : onSwitchOffEvent ( const std : : string & switchName ) {
handleKeybinds ( 0 , " switch:off: " + switchName , 0 , 0 , true , 0 ) ;
}
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 ;
}
2022-07-21 18:18:03 +02:00
bool CKeybindManager : : handleKeybinds ( const uint32_t & modmask , const std : : string & key , const xkb_keysym_t & keysym , const int & keycode , bool pressed , uint32_t time ) {
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
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-09-10 17:54:14 +02:00
if ( ! IGNORECONDITIONS & & ( modmask ! = k . modmask | | ( g_pCompositor - > m_sSeat . exclusiveClient & & ! k . locked ) | | k . submap ! = m_szCurrentSelectedSubmap | | k . shadowed ) )
2022-03-19 17:48:18 +01:00
continue ;
2022-07-15 20:54:05 +02:00
if ( ! key . empty ( ) ) {
if ( key ! = k . key )
continue ;
} else if ( k . keycode ! = - 1 ) {
2022-07-08 09:27:17 +02:00
if ( keycode ! = k . keycode )
continue ;
} else {
2022-07-15 20:54:05 +02:00
if ( keysym = = 0 )
2022-12-16 18:17:31 +01:00
continue ; // this is a keycode check run
2022-07-08 09:27:17 +02:00
// oMg such performance hit!!11!
// this little maneouver is gonna cost us 4µs
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-08 09:27:17 +02:00
const auto KBKEYUPPER = xkb_keysym_to_upper ( KBKEY ) ;
2022-07-15 20:54:05 +02:00
if ( keysym ! = KBKEY & & 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
2023-09-10 14:13:10 +02:00
if ( ! pressed & & ! k . release & & ! SPECIALDISPATCHER ) {
2023-09-01 22:14:06 +02:00
if ( k . nonConsuming )
2023-08-25 12:35:24 +02:00
continue ;
2023-06-14 13:08:56 +02:00
2023-09-01 22:14:06 +02:00
found = true ; // suppress the event
2023-08-30 23:23:35 +02:00
continue ;
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
2023-09-06 21:45:37 +02:00
Debug : : log ( LOG , " Keybind triggered, calling dispatcher ({}, {}, {}) " , modmask , 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
}
2022-07-25 14:06:49 +02:00
void CKeybindManager : : shadowKeybinds ( const xkb_keysym_t & doesntHave , const int & 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 ) ;
for ( auto & pk : m_dPressedKeysyms ) {
if ( ( pk = = KBKEY | | pk = = KBKEYUPPER ) ) {
shadow = true ;
2022-09-25 20:07:48 +02:00
2022-07-25 16:12:06 +02:00
if ( pk = = doesntHave & & doesntHave ! = 0 ) {
shadow = false ;
break ;
}
2022-07-24 12:16:26 +02:00
}
2022-07-20 23:17:26 +02:00
}
for ( auto & pk : m_dPressedKeycodes ) {
2022-07-25 14:06:49 +02:00
if ( pk = = k . keycode ) {
2022-07-20 23:17:26 +02:00
shadow = true ;
2022-07-24 12:16:26 +02:00
2022-07-25 16:12:06 +02:00
if ( pk = = doesntHaveCode & & doesntHaveCode ! = 0 & & doesntHaveCode ! = - 1 ) {
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
}
2022-04-20 15:58:02 +02:00
if ( g_pXWaylandManager - > m_sWLRXWayland )
args = " WAYLAND_DISPLAY= " + std : : string ( g_pCompositor - > m_szWLDisplaySocket ) + " DISPLAY= " + std : : string ( g_pXWaylandManager - > m_sWLRXWayland - > display_name ) + " " + args ;
else
args = " WAYLAND_DISPLAY= " + std : : string ( g_pCompositor - > m_szWLDisplaySocket ) + " " + args ;
2022-04-20 16:18:58 +02: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 ] ) ;
// clear child and leave child to init
waitpid ( child , NULL , 0 ) ;
2022-06-16 21:19:36 +02:00
if ( child < 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
}
void CKeybindManager : : toggleActiveFloating ( std : : string args ) {
2022-08-25 22:34:53 +02:00
CWindow * PWINDOW = nullptr ;
2022-03-20 11:14:24 +01:00
2022-08-25 22:34:53 +02:00
if ( args ! = " " & & args ! = " active " & & args . length ( ) > 1 ) {
PWINDOW = g_pCompositor - > getWindowByRegex ( args ) ;
} else {
PWINDOW = g_pCompositor - > m_pLastWindow ;
}
if ( ! PWINDOW )
return ;
2022-10-14 21:46:32 +02:00
// remove drag status
g_pInputManager - > currentlyDraggedWindow = nullptr ;
2022-06-30 12:09:05 +02:00
2022-11-27 23:42:22 +01:00
if ( g_pCompositor - > isWorkspaceSpecial ( PWINDOW - > m_iWorkspaceID ) )
2022-10-14 21:46:32 +02:00
return ;
2022-03-20 13:37:07 +01:00
2023-02-19 22:07:32 +01:00
if ( PWINDOW - > m_sGroupData . pNextWindow & & PWINDOW - > m_sGroupData . pNextWindow ! = PWINDOW ) {
2022-05-31 14:01:00 +02:00
2023-02-19 22:07:32 +01:00
const auto PCURRENT = PWINDOW - > getGroupCurrent ( ) ;
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 ;
curr - > updateDynamicRules ( ) ;
curr = curr - > m_sGroupData . pNextWindow ;
}
} else {
PWINDOW - > m_bIsFloating = ! PWINDOW - > m_bIsFloating ;
PWINDOW - > updateDynamicRules ( ) ;
g_pLayoutManager - > getCurrentLayout ( ) - > changeWindowFloatingMode ( PWINDOW ) ;
}
2022-03-20 15:55:47 +01:00
}
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 ;
2023-09-11 11:09:34 +02:00
PWINDOW - > m_vRealPosition = PMONITOR - > middle ( ) - PWINDOW - > m_vRealSize . goalv ( ) / 2.f + RESERVEDOFFSET ;
2022-12-16 18:17:31 +01:00
PWINDOW - > m_vPosition = PWINDOW - > m_vRealPosition . goalv ( ) ;
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.
static auto * const PBACKANDFORTH = & g_pConfigManager - > getConfigValuePtr ( " binds:workspace_back_and_forth " ) - > intValue ;
static auto * const PALLOWWORKSPACECYCLES = & g_pConfigManager - > getConfigValuePtr ( " binds:allow_workspace_cycles " ) - > intValue ;
2022-08-23 23:34:36 +02:00
2023-04-14 16:03:53 +02:00
const auto PMONITOR = g_pCompositor - > m_pLastMonitor ;
const auto PCURRENTWORKSPACE = g_pCompositor - > getWorkspaceByID ( PMONITOR - > activeWorkspace ) ;
2023-09-11 16:14:43 +02:00
const bool EXPLICITPREVIOUS = args . find ( " previous " ) = = 0 ;
2023-04-14 18:51:10 +02:00
2023-04-14 16:03:53 +02:00
if ( args . find ( " previous " ) = = 0 ) {
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
2022-04-20 16:53:41 +02:00
if ( workspaceToChangeTo = = INT_MAX ) {
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
2023-09-11 16:14:43 +02: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-11 16:14:43 +02:00
if ( PMONITOR ! = PMONITORWORKSPACEOWNER )
2023-09-11 11:09:34 +02:00
g_pCompositor - > warpCursorTo ( PMONITORWORKSPACEOWNER - > middle ( ) ) ;
2023-04-14 17:22:55 +02:00
2023-09-11 16:14:43 +02:00
if ( BISWORKSPACECURRENT ) {
if ( * PALLOWWORKSPACECYCLES )
pWorkspaceToChangeTo - > rememberPrevWorkspace ( PCURRENTWORKSPACE ) ;
else if ( ! EXPLICITPREVIOUS )
pWorkspaceToChangeTo - > rememberPrevWorkspace ( nullptr ) ;
} else
pWorkspaceToChangeTo - > rememberPrevWorkspace ( PCURRENTWORKSPACE ) ;
2022-09-10 13:11:02 +02:00
2023-09-13 12:36:41 +02:00
if ( ! g_pCompositor - > m_pLastFocus )
g_pInputManager - > simulateMouseMovement ( ) ;
else
g_pInputManager - > sendMotionEventsToFocused ( ) ;
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 ;
2022-11-27 23:42:22 +01:00
if ( g_pCompositor - > isWorkspaceSpecial ( PWINDOW - > m_iWorkspaceID ) )
2022-08-29 14:55:11 +02:00
return ;
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
2022-12-14 19:42:48 +01:00
if ( WORKSPACEID = = INT_MAX ) {
Debug : : log ( LOG , " Invalid workspace in moveActiveToWorkspace " ) ;
return ;
}
2022-06-03 11:19:17 +02:00
if ( WORKSPACEID = = PWINDOW - > m_iWorkspaceID ) {
Debug : : log ( LOG , " Not moving to workspace because it didn't change. " ) ;
return ;
}
2023-06-05 09:44:13 +02:00
auto pWorkspace = g_pCompositor - > getWorkspaceByID ( WORKSPACEID ) ;
CMonitor * pMonitor = nullptr ;
const auto POLDWS = g_pCompositor - > getWorkspaceByID ( PWINDOW - > m_iWorkspaceID ) ;
static auto * const PALLOWWORKSPACECYCLES = & g_pConfigManager - > getConfigValuePtr ( " binds:allow_workspace_cycles " ) - > intValue ;
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 ) ;
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
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-04-14 16:03:53 +02:00
if ( WORKSPACEID = = INT_MAX ) {
2022-05-18 12:18:58 +02:00
Debug : : log ( ERR , " Error in moveActiveToWorkspaceSilent, invalid value " ) ;
return ;
}
2023-04-14 16:03:53 +02:00
if ( WORKSPACEID = = PWINDOW - > m_iWorkspaceID )
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
2023-04-14 16:03:53 +02:00
if ( const auto PATCOORDS = g_pCompositor - > vectorToWindowIdeal ( OLDMIDDLE ) ; PATCOORDS & & PATCOORDS ! = PWINDOW )
g_pCompositor - > focusWindow ( PATCOORDS ) ;
2023-04-13 23:20:31 +02:00
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 ) {
char arg = args [ 0 ] ;
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
2022-05-18 14:57:08 +02:00
// remove constraints
2022-08-09 20:36:21 +02:00
g_pInputManager - > unconstrainMouse ( ) ;
2022-05-18 14:57:08 +02:00
2023-07-19 00:30:10 +02:00
const auto PWINDOWTOCHANGETO = PLASTWINDOW - > m_bIsFullscreen ?
( 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 ;
static auto * const PNOFALLBACK = & g_pConfigManager - > getConfigValuePtr ( " general:no_focus_fallback " ) - > intValue ;
if ( * PNOFALLBACK )
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 ;
// remove constraints
g_pInputManager - > unconstrainMouse ( ) ;
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 ;
// remove constraints
g_pInputManager - > unconstrainMouse ( ) ;
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 ) ;
g_pCompositor - > warpCursorTo ( PLASTWINDOW - > m_vRealPosition . vec ( ) + PLASTWINDOW - > m_vRealSize . vec ( ) / 2.0 ) ;
}
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-04-10 21:07:49 +02:00
if ( args . find ( " mon: " ) = = 0 ) {
const auto PNEWMONITOR = g_pCompositor - > getMonitorFromString ( args . substr ( 4 ) ) ;
if ( ! PNEWMONITOR )
return ;
2022-05-05 13:02:55 +02:00
2023-04-10 21:07:49 +02:00
moveActiveToWorkspace ( std : : to_string ( PNEWMONITOR - > activeWorkspace ) ) ;
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 ) {
auto vPos = PLASTWINDOW - > m_vRealPosition . goalv ( ) ;
const auto PMONITOR = g_pCompositor - > getMonitorFromID ( PLASTWINDOW - > m_iMonitorID ) ;
const auto BORDERSIZE = PLASTWINDOW - > getRealBorderSize ( ) ;
switch ( arg ) {
case ' l ' : vPos . x = PMONITOR - > vecReservedTopLeft . x + BORDERSIZE ; break ;
case ' r ' : vPos . x = PMONITOR - > vecSize . x - PMONITOR - > vecReservedBottomRight . x - PLASTWINDOW - > m_vRealSize . goalv ( ) . x - BORDERSIZE ; break ;
case ' t ' :
case ' u ' : vPos . y = PMONITOR - > vecReservedTopLeft . y + BORDERSIZE ; break ;
case ' b ' :
case ' d ' : vPos . y = PMONITOR - > vecSize . y - PMONITOR - > vecReservedBottomRight . y - PLASTWINDOW - > m_vRealSize . goalv ( ) . y - BORDERSIZE ; break ;
}
PLASTWINDOW - > m_vRealPosition = vPos + PMONITOR - > vecPosition ;
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
2023-04-26 17:58:58 +02:00
const auto PWORKSPACE = g_pCompositor - > getWorkspaceByID ( PMONITORTOCHANGETO - > activeWorkspace ) ;
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-02-19 22:07:32 +01:00
if ( ! PWINDOW - > m_sGroupData . pNextWindow ) {
PWINDOW - > m_sGroupData . pNextWindow = PWINDOW ;
PWINDOW - > m_sGroupData . head = true ;
2023-06-09 23:44:18 +02:00
PWINDOW - > m_sGroupData . locked = false ;
2023-02-19 22:07:32 +01:00
PWINDOW - > m_dWindowDecorations . emplace_back ( std : : make_unique < CHyprGroupBarDecoration > ( PWINDOW ) ) ;
PWINDOW - > updateWindowDecos ( ) ;
2023-05-23 14:26:38 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateWindow ( PWINDOW ) ;
2023-02-19 22:07:32 +01:00
} else {
if ( PWINDOW - > m_sGroupData . pNextWindow = = PWINDOW ) {
PWINDOW - > m_sGroupData . pNextWindow = nullptr ;
PWINDOW - > updateWindowDecos ( ) ;
} else {
// enum all windows, remove their group state, readd to layout.
CWindow * curr = PWINDOW ;
std : : vector < CWindow * > members ;
do {
const auto PLASTWIN = curr ;
curr = curr - > m_sGroupData . pNextWindow ;
PLASTWIN - > m_sGroupData . pNextWindow = nullptr ;
curr - > setHidden ( false ) ;
members . push_back ( curr ) ;
} while ( curr ! = PWINDOW ) ;
for ( auto & w : members ) {
if ( w - > m_sGroupData . head )
g_pLayoutManager - > getCurrentLayout ( ) - > onWindowRemoved ( curr ) ;
w - > m_sGroupData . head = false ;
}
2023-08-30 17:39:22 +02:00
const bool GROUPSLOCKEDPREV = g_pKeybindManager - > m_bGroupsLocked ;
2023-07-03 12:49:56 +02:00
g_pKeybindManager - > m_bGroupsLocked = true ;
2023-02-19 22:07:32 +01:00
for ( auto & w : members ) {
g_pLayoutManager - > getCurrentLayout ( ) - > onWindowCreated ( w ) ;
w - > updateWindowDecos ( ) ;
}
2023-08-30 17:39:22 +02:00
g_pKeybindManager - > m_bGroupsLocked = GROUPSLOCKEDPREV ;
2023-02-19 22:07:32 +01:00
}
}
g_pCompositor - > updateAllWindowsAnimatedDecorationValues ( ) ;
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-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 ;
const auto PWORKSPACE = g_pCompositor - > getWorkspaceByID ( header . pWindow - > m_iWorkspaceID ) ;
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
}
void CKeybindManager : : alterSplitRatio ( std : : string args ) {
float splitratio = 0 ;
2022-12-19 15:49:19 +01:00
bool exact = false ;
2022-04-20 16:53:41 +02:00
if ( args = = " + " | | args = = " - " ) {
Debug : : log ( LOG , " alterSplitRatio: using LEGACY +/-, consider switching to the Hyprland syntax. " ) ;
splitratio = ( args = = " + " ? 0.05f : - 0.05f ) ;
}
if ( splitratio = = 0 ) {
2022-12-17 23:37:44 +01:00
if ( args . find ( " exact " ) = = 0 ) {
2022-12-19 15:49:19 +01:00
exact = true ;
2022-12-17 23:37:44 +01:00
splitratio = getPlusMinusKeywordResult ( args . substr ( 5 ) , 0 ) ;
} else {
splitratio = getPlusMinusKeywordResult ( args , 0 ) ;
}
2022-04-20 16:53:41 +02:00
}
if ( splitratio = = INT_MAX ) {
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 ;
2022-12-17 23:37:44 +01:00
g_pLayoutManager - > getCurrentLayout ( ) - > alterSplitRatio ( PLASTWINDOW , splitratio , 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
2022-12-16 18:17:31 +01:00
wlr_cursor_warp ( g_pCompositor - > m_sWLRCursor , g_pCompositor - > m_sSeat . mouse - > mouse , PWINDOW - > m_vRealPosition . vec ( ) . x ,
PWINDOW - > m_vRealPosition . vec ( ) . y + PWINDOW - > m_vRealSize . vec ( ) . y ) ;
2022-05-22 11:52:39 +02:00
break ;
case 1 :
// bottom right
2022-12-16 18:17:31 +01:00
wlr_cursor_warp ( g_pCompositor - > m_sWLRCursor , g_pCompositor - > m_sSeat . mouse - > mouse , PWINDOW - > m_vRealPosition . vec ( ) . x + PWINDOW - > m_vRealSize . vec ( ) . x ,
PWINDOW - > m_vRealPosition . vec ( ) . y + PWINDOW - > m_vRealSize . vec ( ) . y ) ;
2022-05-22 11:52:39 +02:00
break ;
case 2 :
// top right
2022-12-16 18:17:31 +01:00
wlr_cursor_warp ( g_pCompositor - > m_sWLRCursor , g_pCompositor - > m_sSeat . mouse - > mouse , PWINDOW - > m_vRealPosition . vec ( ) . x + PWINDOW - > m_vRealSize . vec ( ) . x ,
PWINDOW - > m_vRealPosition . vec ( ) . y ) ;
2022-05-22 11:52:39 +02:00
break ;
case 3 :
// top left
wlr_cursor_warp ( g_pCompositor - > m_sWLRCursor , g_pCompositor - > m_sSeat . mouse - > mouse , PWINDOW - > m_vRealPosition . vec ( ) . x , PWINDOW - > m_vRealPosition . vec ( ) . y ) ;
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
const auto PWORKSPACE = g_pCompositor - > getWorkspaceByID ( g_pCompositor - > m_pLastMonitor - > activeWorkspace ) ;
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 ) {
if ( ! w - > m_bIsMapped | | w - > m_iWorkspaceID ! = PWORKSPACE - > m_iID )
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 ) {
2023-02-19 23:14:37 +01:00
if ( ! w - > m_bIsMapped | | w - > m_iWorkspaceID ! = PWORKSPACE - > m_iID | | w - > isHidden ( ) )
2022-05-26 19:05:32 +02:00
continue ;
if ( ! w - > m_bRequestsFloat & & w - > m_bIsFloating ! = PWORKSPACE - > m_bDefaultFloating ) {
2022-12-16 18:17:31 +01:00
const auto SAVEDPOS = w - > m_vRealPosition . vec ( ) ;
2022-05-26 19:05:32 +02:00
const auto SAVEDSIZE = w - > m_vRealSize . vec ( ) ;
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 ) ;
2022-12-16 18:17:31 +01:00
w - > m_vRealSize = w - > m_vRealSize . vec ( ) + Vector2D ( 4 , 4 ) ;
w - > m_vRealPosition = w - > m_vRealPosition . vec ( ) - 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 ) {
2022-07-13 18:18:23 +02:00
g_pCompositor - > cleanup ( ) ;
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
2022-07-29 16:59:31 +02:00
if ( ! PMONITOR )
return ;
2022-05-30 20:05:38 +02:00
// get the current workspace
const auto PCURRENTWORKSPACE = g_pCompositor - > getWorkspaceByID ( g_pCompositor - > m_pLastMonitor - > activeWorkspace ) ;
if ( ! PCURRENTWORKSPACE )
return ;
g_pCompositor - > moveWorkspaceToMonitor ( PCURRENTWORKSPACE , PMONITOR ) ;
}
void CKeybindManager : : moveWorkspaceToMonitor ( std : : string args ) {
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
if ( WORKSPACEID = = INT_MAX ) {
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
}
void CKeybindManager : : toggleSpecialWorkspace ( std : : string args ) {
2022-12-16 18:17:31 +01:00
static auto * const PFOLLOWMOUSE = & g_pConfigManager - > getConfigValuePtr ( " input:follow_mouse " ) - > intValue ;
2022-12-06 21:31:44 +01:00
2022-12-16 18:17:31 +01:00
std : : string workspaceName = " " ;
int workspaceID = getWorkspaceIDFromString ( " special: " + args , workspaceName ) ;
2022-11-27 23:42:22 +01:00
if ( workspaceID = = INT_MAX | | ! g_pCompositor - > isWorkspaceSpecial ( workspaceID ) ) {
Debug : : log ( ERR , " Invalid workspace passed to special " ) ;
return ;
}
2022-12-16 18:17:31 +01:00
bool requestedWorkspaceIsAlreadyOpen = false ;
const auto PMONITOR = * PFOLLOWMOUSE = = 1 ? g_pCompositor - > getMonitorFromCursor ( ) : g_pCompositor - > m_pLastMonitor ;
int specialOpenOnMonitor = PMONITOR - > specialWorkspaceID ;
2022-05-31 14:01:00 +02:00
2022-06-30 15:44:26 +02:00
for ( auto & m : g_pCompositor - > m_vMonitors ) {
2022-11-27 23:42:22 +01:00
if ( m - > specialWorkspaceID = = workspaceID ) {
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 ;
2022-10-05 11:22:33 +02:00
auto rule = g_pConfigManager - > getMonitorRuleFor ( m - > szName , m - > output - > description ? m - > output - > description : " " ) ;
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
2022-08-15 15:59:07 +02:00
const auto SIZ = g_pCompositor - > parseWindowVectorArgsRelative ( args , g_pCompositor - > m_pLastWindow - > m_vRealSize . goalv ( ) ) ;
2022-06-06 19:32:14 +02:00
2023-05-15 16:16:06 +02:00
if ( SIZ . x < 1 | | SIZ . y < 1 )
return ;
2022-08-15 15:59:07 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > resizeActiveWindow ( SIZ - g_pCompositor - > m_pLastWindow - > m_vRealSize . goalv ( ) ) ;
2022-06-23 10:14:59 +02:00
2022-08-15 15:59:07 +02:00
if ( g_pCompositor - > m_pLastWindow - > m_vRealSize . goalv ( ) . x > 1 & & g_pCompositor - > m_pLastWindow - > m_vRealSize . goalv ( ) . 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
2022-08-15 15:59:07 +02:00
const auto POS = g_pCompositor - > parseWindowVectorArgsRelative ( args , g_pCompositor - > m_pLastWindow - > m_vRealPosition . goalv ( ) ) ;
2022-06-23 10:14:59 +02:00
2022-08-15 15:59:07 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > moveActiveWindow ( POS - g_pCompositor - > m_pLastWindow - > m_vRealPosition . goalv ( ) ) ;
}
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 ;
2022-08-15 15:59:07 +02:00
const auto POS = g_pCompositor - > parseWindowVectorArgsRelative ( MOVECMD , PWINDOW - > m_vRealPosition . goalv ( ) ) ;
2022-06-06 19:32:14 +02:00
2022-08-15 15:59:07 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > moveActiveWindow ( POS - PWINDOW - > m_vRealPosition . goalv ( ) , 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
2022-12-16 18:17:31 +01:00
const auto SIZ = g_pCompositor - > parseWindowVectorArgsRelative ( MOVECMD , PWINDOW - > m_vRealSize . goalv ( ) ) ;
2022-06-23 10:14:59 +02:00
2023-05-15 16:16:06 +02:00
if ( SIZ . x < 1 | | SIZ . y < 1 )
return ;
2023-07-13 16:52:11 +02:00
g_pLayoutManager - > getCurrentLayout ( ) - > resizeActiveWindow ( SIZ - PWINDOW - > m_vRealSize . goalv ( ) , CORNER_NONE , PWINDOW ) ;
2022-06-23 10:14:59 +02:00
2022-08-15 15:59:07 +02:00
if ( PWINDOW - > m_vRealSize . goalv ( ) . x > 1 & & PWINDOW - > m_vRealSize . goalv ( ) . 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.
if ( g_pCompositor - > getWindowsOnWorkspace ( g_pCompositor - > m_pLastMonitor - > activeWorkspace ) > 0 ) {
2023-02-23 15:27:43 +01:00
const auto PWINDOW = g_pCompositor - > getFirstWindowOnWorkspace ( g_pCompositor - > m_pLastMonitor - > activeWorkspace ) ;
2022-10-28 22:31:39 +02:00
switchToWindow ( PWINDOW ) ;
}
return ;
}
2022-08-11 19:45:37 +02:00
if ( arg = = " last " | | arg = = " l " | | arg = = " prev " | | arg = = " p " )
2022-09-29 17:53:31 +02:00
switchToWindow ( g_pCompositor - > getPrevWindowOnWorkspace ( g_pCompositor - > m_pLastWindow , true ) ) ;
2022-08-11 19:45:37 +02:00
else
2022-09-29 17:53:31 +02:00
switchToWindow ( g_pCompositor - > getNextWindowOnWorkspace ( g_pCompositor - > m_pLastWindow , true ) ) ;
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
2023-05-01 16:39:08 +02:00
if ( g_pCompositor - > m_pLastMonitor - > activeWorkspace ! = PWINDOW - > m_iWorkspaceID ) {
Debug : : log ( LOG , " Fake executing workspace to move focus " ) ;
const auto PWORKSPACE = g_pCompositor - > getWorkspaceByID ( PWINDOW - > m_iWorkspaceID ) ;
if ( ! PWORKSPACE ) {
Debug : : log ( ERR , " BUG THIS: null workspace in focusWindow " ) ;
return ;
}
changeworkspace ( PWORKSPACE - > getConfigName ( ) ) ;
}
2022-07-26 17:30:30 +02: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
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
wlr_seat_pointer_notify_button ( g_pCompositor - > m_sSeat . seat , g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastMouseCode , WLR_BUTTON_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
wlr_seat_pointer_notify_button ( g_pCompositor - > m_sSeat . seat , g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastMouseCode , WLR_BUTTON_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 {
wlr_seat_pointer_notify_button ( g_pCompositor - > m_sSeat . seat , g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastMouseCode , WLR_BUTTON_PRESSED ) ;
wlr_seat_pointer_notify_button ( g_pCompositor - > m_sSeat . seat , g_pKeybindManager - > m_uTimeLastMs , g_pKeybindManager - > m_uLastMouseCode , WLR_BUTTON_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 ) {
2022-12-16 18:17:31 +01:00
bool enable = arg . find ( " on " ) = = 0 ;
std : : string port = " " ;
2022-10-05 11:31:47 +02:00
2023-07-30 16:46:33 +02:00
if ( arg . find ( " toggle " ) = = 0 )
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 ;
2022-07-30 23:51:13 +02:00
wlr_output_enable ( m - > output , enable ) ;
2022-09-25 20:07:48 +02:00
2022-10-05 19:14:11 +02:00
m - > dpmsStatus = enable ;
2022-07-30 23:51:13 +02:00
if ( ! wlr_output_commit ( m - > output ) ) {
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 ) & &
g_pCompositor - > m_pLastWindow - > m_pLastCycledWindow - > m_iWorkspaceID = = PLASTWINDOW - > m_iWorkspaceID ?
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 ;
2023-06-20 21:35:54 +02:00
if ( args ! = " " & & 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 ;
PWINDOW - > m_bPinned = ! PWINDOW - > m_bPinned ;
PWINDOW - > m_iWorkspaceID = 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
2023-01-08 18:37:24 +01:00
const auto PWORKSPACE = g_pCompositor - > getWorkspaceByID ( PWINDOW - > m_iWorkspaceID ) ;
2022-09-10 13:11:02 +02:00
PWORKSPACE - > m_pLastFocusedWindow = g_pCompositor - > vectorToWindowTiled ( g_pInputManager - > getMouseCoordsInternal ( ) ) ;
}
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 ( ) ;
CWindow * pWindow = g_pCompositor - > vectorToWindowIdeal ( mouseCoords ) ;
if ( pWindow & & ! pWindow - > m_bIsFullscreen & & ! pWindow - > hasPopupAt ( mouseCoords ) & & pWindow - > m_sGroupData . pNextWindow ) {
const wlr_box box = pWindow - > getDecorationByType ( DECORATION_GROUPBAR ) - > getWindowDecorationRegion ( ) . getExtents ( ) ;
if ( wlr_box_contains_point ( & box , mouseCoords . x , mouseCoords . y ) ) {
const int SIZE = pWindow - > getGroupSize ( ) ;
pWindow = pWindow - > getGroupWindowByIndex ( ( mouseCoords . x - box . x ) * SIZE / box . width ) ;
// hack
g_pLayoutManager - > getCurrentLayout ( ) - > onWindowRemoved ( pWindow ) ;
if ( ! pWindow - > m_bIsFloating ) {
const bool GROUPSLOCKEDPREV = g_pKeybindManager - > m_bGroupsLocked ;
g_pKeybindManager - > m_bGroupsLocked = true ;
g_pLayoutManager - > getCurrentLayout ( ) - > onWindowCreated ( pWindow ) ;
g_pKeybindManager - > m_bGroupsLocked = GROUPSLOCKEDPREV ;
}
}
}
2022-09-19 20:04:48 +02:00
2023-08-30 17:39:22 +02:00
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 ;
2022-10-04 17:08:49 +02:00
g_pInputManager - > currentlyDraggedWindow = g_pCompositor - > vectorToWindowIdeal ( g_pInputManager - > getMouseCoordsInternal ( ) ) ;
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 )
2022-10-14 15:22:20 +02:00
g_pCompositor - > moveWindowToTop ( g_pCompositor - > m_pLastWindow ) ;
}
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 ;
g_pXWaylandManager - > setWindowFullscreen ( g_pCompositor - > m_pLastWindow ,
g_pCompositor - > m_pLastWindow - > m_bFakeFullscreenState | | g_pCompositor - > m_pLastWindow - > m_bIsFullscreen ) ;
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 ) {
if ( ! pWindow - > m_sGroupData . pNextWindow )
pWindow - > m_dWindowDecorations . emplace_back ( std : : make_unique < CHyprGroupBarDecoration > ( pWindow ) ) ;
g_pLayoutManager - > getCurrentLayout ( ) - > onWindowRemoved ( pWindow ) ; // This removes groupped property!
static const auto * USECURRPOS = & g_pConfigManager - > getConfigValuePtr ( " misc:group_insert_after_current " ) - > intValue ;
pWindowInDirection = * USECURRPOS ? pWindowInDirection : pWindowInDirection - > getGroupTail ( ) ;
pWindowInDirection - > insertWindowToGroup ( pWindow ) ;
pWindowInDirection - > setGroupCurrent ( pWindow ) ;
pWindow - > updateWindowDecos ( ) ;
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateWindow ( pWindow ) ;
g_pCompositor - > focusWindow ( pWindow ) ;
g_pCompositor - > warpCursorTo ( pWindow - > middle ( ) ) ;
}
2023-09-13 12:13:29 +02:00
void CKeybindManager : : moveWindowOutOfGroup ( CWindow * pWindow , const std : : string & dir ) {
2023-09-13 12:33:36 +02:00
static auto * const BFOCUSREMOVEDWINDOW = & g_pConfigManager - > getConfigValuePtr ( " misc:group_focus_removed_window " ) - > intValue ;
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 ) {
pWindow - > m_sGroupData . pNextWindow = nullptr ;
pWindow - > updateWindowDecos ( ) ;
} 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
if ( * BFOCUSREMOVEDWINDOW ) {
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 ) {
2023-07-24 18:25:10 +02:00
char arg = args [ 0 ] ;
2023-09-11 00:29:10 +02:00
static auto * const BIGNOREGROUPLOCK = & g_pConfigManager - > getConfigValuePtr ( " binds:ignore_group_lock " ) - > intValue ;
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 ;
if ( ! PWINDOW | | PWINDOW - > m_bIsFloating )
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
if ( ! * BIGNOREGROUPLOCK & & ( 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 ) {
const auto PWINDOW = g_pCompositor - > m_pLastWindow ;
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 ) {
char arg = args [ 0 ] ;
2023-02-26 14:55:35 +01:00
2023-09-11 00:29:10 +02:00
static auto * const BIGNOREGROUPLOCK = & g_pConfigManager - > getConfigValuePtr ( " binds:ignore_group_lock " ) - > intValue ;
2023-02-26 14:55:35 +01:00
2023-09-11 00:29:10 +02:00
if ( ! isDirection ( args ) ) {
Debug : : log ( ERR , " Cannot move into group in direction %c, unsupported direction. Supported: l,r,u/t,d/b " , arg ) ;
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 ;
const auto ISWINDOWGROUP = PWINDOW - > m_sGroupData . pNextWindow ;
const auto ISWINDOWGROUPLOCKED = ISWINDOWGROUP & & PWINDOW - > getGroupHead ( ) - > m_sGroupData . locked ;
const auto PWINDOWINDIR = g_pCompositor - > getWindowInDirection ( PWINDOW , arg ) ;
const auto ISWINDOWINDIRGROUP = PWINDOWINDIR & & PWINDOWINDIR - > m_sGroupData . pNextWindow ;
const auto ISWINDOWINDIRGROUPLOCKED = ISWINDOWINDIRGROUP & & PWINDOWINDIR - > getGroupHead ( ) - > m_sGroupData . locked ;
// note: PWINDOWINDIR is not null implies !PWINDOW->m_bIsFloating
if ( ISWINDOWINDIRGROUP & & ! ISWINDOWINDIRGROUPLOCKED ) {
if ( ISWINDOWGROUPLOCKED & & ! * BIGNOREGROUPLOCK ) {
g_pLayoutManager - > getCurrentLayout ( ) - > moveWindowTo ( PWINDOW , args ) ;
g_pCompositor - > warpCursorTo ( PWINDOW - > middle ( ) ) ;
} else
moveWindowIntoGroup ( PWINDOW , PWINDOWINDIR ) ;
} else if ( ISWINDOWINDIRGROUPLOCKED ) {
if ( ! * BIGNOREGROUPLOCK ) {
g_pLayoutManager - > getCurrentLayout ( ) - > moveWindowTo ( PWINDOW , args ) ;
g_pCompositor - > warpCursorTo ( PWINDOW - > middle ( ) ) ;
} else
moveWindowIntoGroup ( PWINDOW , PWINDOWINDIR ) ;
} else if ( PWINDOWINDIR ) {
if ( ISWINDOWGROUP & & ( * BIGNOREGROUPLOCK | | ! ISWINDOWGROUPLOCKED ) )
2023-09-13 12:13:29 +02:00
moveWindowOutOfGroup ( PWINDOW , args ) ;
2023-09-11 00:29:10 +02:00
else {
g_pLayoutManager - > getCurrentLayout ( ) - > moveWindowTo ( PWINDOW , args ) ;
g_pCompositor - > warpCursorTo ( PWINDOW - > middle ( ) ) ;
}
} else if ( ISWINDOWGROUP & & ( * BIGNOREGROUPLOCK | | ! ISWINDOWGROUPLOCKED ) ) {
2023-09-13 12:13:29 +02:00
moveWindowOutOfGroup ( PWINDOW , args ) ;
2023-09-11 00:29:10 +02:00
}
}
void CKeybindManager : : setIgnoreGroupLock ( std : : string args ) {
static auto * const BIGNOREGROUPLOCK = & g_pConfigManager - > getConfigValuePtr ( " binds:ignore_group_lock " ) - > intValue ;
if ( args = = " toggle " )
* BIGNOREGROUPLOCK = ! * BIGNOREGROUPLOCK ;
else
* BIGNOREGROUPLOCK = args = = " on " ;
g_pEventManager - > postEvent ( SHyprIPCEvent { " ignoregrouplock " , std : : to_string ( * BIGNOREGROUPLOCK ) } ) ;
2023-02-26 14:55:35 +01:00
}
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
}