2024-12-16 19:21:44 +01:00
# include <re2/re2.h>
2022-03-17 15:53:45 +01:00
# include "ConfigManager.hpp"
2025-01-19 15:39:19 +01:00
# include "ConfigWatcher.hpp"
2022-03-19 17:48:18 +01:00
# include "../managers/KeybindManager.hpp"
2024-12-07 18:51:18 +01:00
# include "../Compositor.hpp"
2022-03-17 15:53:45 +01:00
2023-11-26 17:59:49 +00:00
# include "../render/decorations/CHyprGroupBarDecoration.hpp"
2024-02-21 12:07:39 +01:00
# include "config/ConfigDataValues.hpp"
2024-08-06 14:52:19 +01:00
# include "config/ConfigValue.hpp"
2024-06-11 17:17:45 +02:00
# include "helpers/varlist/VarList.hpp"
2024-05-09 21:47:21 +01:00
# include "../protocols/LayerShell.hpp"
2024-09-05 11:26:46 -05:00
# include "../xwayland/XWayland.hpp"
2024-09-26 11:10:53 +01:00
# include "../protocols/OutputManagement.hpp"
2025-01-17 15:21:35 +00:00
# include "../managers/AnimationManager.hpp"
# include "../desktop/LayerSurface.hpp"
# include "defaultConfig.hpp"
2023-11-26 17:59:49 +00:00
2025-01-17 15:21:35 +00:00
# include "../render/Renderer.hpp"
# include "../hyprerror/HyprError.hpp"
# include "../managers/input/InputManager.hpp"
2025-01-24 20:30:12 +00:00
# include "../managers/eventLoop/EventLoopManager.hpp"
2025-01-17 15:21:35 +00:00
# include "../managers/LayoutManager.hpp"
# include "../managers/EventManager.hpp"
# include "../debug/HyprNotificationOverlay.hpp"
# include "../plugins/PluginSystem.hpp"
2025-02-02 22:16:00 +00:00
# include "../managers/HookSystemManager.hpp"
# include "../protocols/types/ContentType.hpp"
2024-06-11 19:49:54 +02:00
# include <cstddef>
2024-05-16 10:48:30 +00:00
# include <cstdint>
2024-07-16 22:23:37 +03:00
# include <hyprutils/path/Path.hpp>
2024-12-07 18:51:18 +01:00
# include <cstring>
2023-10-22 19:11:03 -03:00
# include <string>
2022-03-17 15:53:45 +01:00
# include <sys/stat.h>
# include <sys/types.h>
# include <unistd.h>
2023-09-12 11:54:05 +00:00
# include <glob.h>
2024-06-11 17:17:45 +02:00
# include <xkbcommon/xkbcommon.h>
2022-03-17 15:53:45 +01:00
# include <algorithm>
# include <fstream>
# include <iostream>
2023-05-01 21:24:51 +00:00
# include <sstream>
2024-05-03 17:58:40 +01:00
# include <ranges>
2024-05-29 05:37:24 +08:00
# include <unordered_set>
2024-06-11 17:17:45 +02:00
# include <hyprutils/string/String.hpp>
2024-07-21 13:09:54 +02:00
# include <filesystem>
2025-01-23 21:55:41 +01:00
# include <memory>
2024-06-11 17:17:45 +02:00
using namespace Hyprutils : : String ;
2025-01-07 17:55:14 +00:00
using namespace Hyprutils : : Animation ;
2022-03-17 15:53:45 +01:00
2024-12-07 18:51:18 +01:00
//NOLINTNEXTLINE
2024-08-17 17:33:16 +01:00
extern " C " char * * environ ;
# include "ConfigDescriptions.hpp"
2023-03-05 18:39:46 +00:00
2024-02-18 15:00:34 +00:00
static Hyprlang : : CParseResult configHandleGradientSet ( const char * VALUE , void * * data ) {
std : : string V = VALUE ;
2023-10-10 16:42:45 +00:00
2024-02-18 15:00:34 +00:00
if ( ! * data )
* data = new CGradientValueData ( ) ;
2023-10-10 16:42:45 +00:00
2024-02-18 15:00:34 +00:00
const auto DATA = reinterpret_cast < CGradientValueData * > ( * data ) ;
2022-11-26 17:56:43 +00:00
2024-02-18 15:00:34 +00:00
CVarList varlist ( V , 0 , ' ' ) ;
DATA - > m_vColors . clear ( ) ;
2023-11-26 18:02:23 +00:00
2024-02-18 15:00:34 +00:00
std : : string parseError = " " ;
2024-08-26 20:24:30 +02:00
for ( auto const & var : varlist ) {
2024-02-18 15:00:34 +00:00
if ( var . find ( " deg " ) ! = std : : string : : npos ) {
// last arg
try {
DATA - > m_fAngle = std : : stoi ( var . substr ( 0 , var . find ( " deg " ) ) ) * ( PI / 180.0 ) ; // radians
} catch ( . . . ) {
Debug : : log ( WARN , " Error parsing gradient {} " , V ) ;
parseError = " Error parsing gradient " + V ;
}
break ;
}
if ( DATA - > m_vColors . size ( ) > = 10 ) {
Debug : : log ( WARN , " Error parsing gradient {}: max colors is 10. " , V ) ;
parseError = " Error parsing gradient " + V + " : max colors is 10. " ;
break ;
}
try {
2024-11-24 02:46:24 +00:00
const auto COL = configStringToInt ( var ) ;
if ( ! COL )
throw std : : runtime_error ( std : : format ( " failed to parse {} as a color " , var ) ) ;
2024-12-07 18:51:18 +01:00
DATA - > m_vColors . emplace_back ( COL . value ( ) ) ;
2024-02-18 15:00:34 +00:00
} catch ( std : : exception & e ) {
Debug : : log ( WARN , " Error parsing gradient {} " , V ) ;
parseError = " Error parsing gradient " + V + " : " + e . what ( ) ;
}
}
if ( DATA - > m_vColors . size ( ) = = 0 ) {
Debug : : log ( WARN , " Error parsing gradient {} " , V ) ;
2024-11-24 14:53:36 +00:00
if ( parseError . empty ( ) )
parseError = " Error parsing gradient " + V + " : No colors? " ;
2024-02-18 15:00:34 +00:00
2024-12-07 18:51:18 +01:00
DATA - > m_vColors . emplace_back ( 0 ) ; // transparent
2024-02-18 15:00:34 +00:00
}
2024-12-03 18:58:24 +00:00
DATA - > updateColorsOk ( ) ;
2024-02-18 15:00:34 +00:00
Hyprlang : : CParseResult result ;
if ( ! parseError . empty ( ) )
result . setError ( parseError . c_str ( ) ) ;
return result ;
}
static void configHandleGradientDestroy ( void * * data ) {
if ( * data )
delete reinterpret_cast < CGradientValueData * > ( * data ) ;
}
2024-02-21 12:07:39 +01:00
static Hyprlang : : CParseResult configHandleGapSet ( const char * VALUE , void * * data ) {
std : : string V = VALUE ;
if ( ! * data )
* data = new CCssGapData ( ) ;
const auto DATA = reinterpret_cast < CCssGapData * > ( * data ) ;
CVarList varlist ( V ) ;
Hyprlang : : CParseResult result ;
try {
DATA - > parseGapData ( varlist ) ;
} catch ( . . . ) {
std : : string parseError = " Error parsing gaps " + V ;
result . setError ( parseError . c_str ( ) ) ;
}
return result ;
}
static void configHandleGapDestroy ( void * * data ) {
if ( * data )
delete reinterpret_cast < CCssGapData * > ( * data ) ;
}
2025-01-11 23:58:05 +08:00
static Hyprlang : : CParseResult handleExec ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleExec ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
2024-02-18 15:00:34 +00:00
static Hyprlang : : CParseResult handleRawExec ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleRawExec ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handleExecOnce ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleExecOnce ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
2025-01-11 23:58:05 +08:00
static Hyprlang : : CParseResult handleExecRawOnce ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleExecRawOnce ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
2024-09-07 14:54:33 -05:00
static Hyprlang : : CParseResult handleExecShutdown ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleExecShutdown ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
2024-02-18 15:00:34 +00:00
static Hyprlang : : CParseResult handleMonitor ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleMonitor ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handleBezier ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleBezier ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handleAnimation ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleAnimation ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handleBind ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleBind ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handleUnbind ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleUnbind ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handleWindowRule ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleWindowRule ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handleLayerRule ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleLayerRule ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handleWindowRuleV2 ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleWindowRuleV2 ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handleBlurLS ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleBlurLS ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handleWorkspaceRules ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleWorkspaceRules ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handleSubmap ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleSubmap ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handleSource ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleSource ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handleEnv ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handleEnv ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
static Hyprlang : : CParseResult handlePlugin ( const char * c , const char * v ) {
const std : : string VALUE = v ;
const std : : string COMMAND = c ;
const auto RESULT = g_pConfigManager - > handlePlugin ( COMMAND , VALUE ) ;
Hyprlang : : CParseResult result ;
if ( RESULT . has_value ( ) )
result . setError ( RESULT . value ( ) . c_str ( ) ) ;
return result ;
}
2025-02-25 13:49:07 +00:00
void CConfigManager : : registerConfigVar ( const char * name , const Hyprlang : : INT & val ) {
m_configValueNumber + + ;
m_pConfig - > addConfigValue ( name , val ) ;
}
void CConfigManager : : registerConfigVar ( const char * name , const Hyprlang : : FLOAT & val ) {
m_configValueNumber + + ;
m_pConfig - > addConfigValue ( name , val ) ;
}
void CConfigManager : : registerConfigVar ( const char * name , const Hyprlang : : VEC2 & val ) {
m_configValueNumber + + ;
m_pConfig - > addConfigValue ( name , val ) ;
}
void CConfigManager : : registerConfigVar ( const char * name , const Hyprlang : : STRING & val ) {
m_configValueNumber + + ;
m_pConfig - > addConfigValue ( name , val ) ;
}
void CConfigManager : : registerConfigVar ( const char * name , Hyprlang : : CUSTOMTYPE & & val ) {
m_configValueNumber + + ;
m_pConfig - > addConfigValue ( name , std : : move ( val ) ) ;
}
2024-02-18 15:00:34 +00:00
CConfigManager : : CConfigManager ( ) {
const auto ERR = verifyConfigExists ( ) ;
2022-07-14 23:55:24 +03:00
2025-01-19 15:39:19 +01:00
m_configPaths . emplace_back ( getMainConfigPath ( ) ) ;
2025-01-23 21:55:41 +01:00
m_pConfig = makeUnique < Hyprlang : : CConfig > ( m_configPaths . begin ( ) - > c_str ( ) , Hyprlang : : SConfigOptions { . throwAllErrors = true , . allowMissingConfig = true } ) ;
2024-02-18 15:00:34 +00:00
2025-02-25 13:49:07 +00:00
registerConfigVar ( " general:border_size " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " general:no_border_on_floating " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " general:gaps_in " , Hyprlang : : CConfigCustomValueType { configHandleGapSet , configHandleGapDestroy , " 5 " } ) ;
registerConfigVar ( " general:gaps_out " , Hyprlang : : CConfigCustomValueType { configHandleGapSet , configHandleGapDestroy , " 20 " } ) ;
registerConfigVar ( " general:gaps_workspaces " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " general:no_focus_fallback " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " general:resize_on_border " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " general:extend_border_grab_area " , Hyprlang : : INT { 15 } ) ;
registerConfigVar ( " general:hover_icon_on_border " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " general:layout " , { " dwindle " } ) ;
registerConfigVar ( " general:allow_tearing " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " general:resize_corner " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " general:snap:enabled " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " general:snap:window_gap " , Hyprlang : : INT { 10 } ) ;
registerConfigVar ( " general:snap:monitor_gap " , Hyprlang : : INT { 10 } ) ;
registerConfigVar ( " general:snap:border_overlap " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " general:col.active_border " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0xffffffff " } ) ;
registerConfigVar ( " general:col.inactive_border " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0xff444444 " } ) ;
registerConfigVar ( " general:col.nogroup_border " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0xffffaaff " } ) ;
registerConfigVar ( " general:col.nogroup_border_active " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0xffff00ff " } ) ;
registerConfigVar ( " misc:disable_hyprland_logo " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:disable_splash_rendering " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:col.splash " , Hyprlang : : INT { 0x55ffffff } ) ;
registerConfigVar ( " misc:splash_font_family " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " misc:font_family " , { " Sans " } ) ;
registerConfigVar ( " misc:force_default_wallpaper " , Hyprlang : : INT { - 1 } ) ;
registerConfigVar ( " misc:vfr " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " misc:vrr " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:mouse_move_enables_dpms " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:key_press_enables_dpms " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:always_follow_on_dnd " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " misc:layers_hog_keyboard_focus " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " misc:animate_manual_resizes " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:animate_mouse_windowdragging " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:disable_autoreload " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:enable_swallow " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:swallow_regex " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " misc:swallow_exception_regex " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " misc:focus_on_activate " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:mouse_move_focuses_monitor " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " misc:render_ahead_of_time " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:render_ahead_safezone " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " misc:allow_session_lock_restore " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:close_special_on_empty " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " misc:background_color " , Hyprlang : : INT { 0xff111111 } ) ;
registerConfigVar ( " misc:new_window_takes_over_fullscreen " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:exit_window_retains_fullscreen " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:initial_workspace_tracking " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " misc:middle_click_paste " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " misc:render_unfocused_fps " , Hyprlang : : INT { 15 } ) ;
registerConfigVar ( " misc:disable_xdg_env_checks " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:disable_hyprland_qtutils_check " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " misc:lockdead_screen_delay " , Hyprlang : : INT { 1000 } ) ;
registerConfigVar ( " misc:enable_anr_dialog " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " group:insert_after_current " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " group:focus_removed_window " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " group:merge_groups_on_drag " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " group:merge_groups_on_groupbar " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " group:merge_floated_into_tiled_on_groupbar " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " group:auto_group " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " group:drag_into_group " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " group:group_on_movetoworkspace " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " group:groupbar:enabled " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " group:groupbar:font_family " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " group:groupbar:font_size " , Hyprlang : : INT { 8 } ) ;
registerConfigVar ( " group:groupbar:gradients " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " group:groupbar:height " , Hyprlang : : INT { 14 } ) ;
registerConfigVar ( " group:groupbar:indicator_height " , Hyprlang : : INT { 3 } ) ;
registerConfigVar ( " group:groupbar:priority " , Hyprlang : : INT { 3 } ) ;
registerConfigVar ( " group:groupbar:render_titles " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " group:groupbar:scrolling " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " group:groupbar:text_color " , Hyprlang : : INT { 0xffffffff } ) ;
registerConfigVar ( " group:groupbar:stacked " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " group:groupbar:rounding " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " group:groupbar:gradient_rounding " , Hyprlang : : INT { 2 } ) ;
registerConfigVar ( " group:groupbar:round_only_edges " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " group:groupbar:gradient_round_only_edges " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " debug:log_damage " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " debug:overlay " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " debug:damage_blink " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " debug:pass " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " debug:disable_logs " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " debug:disable_time " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " debug:enable_stdout_logs " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " debug:damage_tracking " , { ( Hyprlang : : INT ) DAMAGE_TRACKING_FULL } ) ;
registerConfigVar ( " debug:manual_crash " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " debug:suppress_errors " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " debug:error_limit " , Hyprlang : : INT { 5 } ) ;
registerConfigVar ( " debug:error_position " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " debug:watchdog_timeout " , Hyprlang : : INT { 5 } ) ;
registerConfigVar ( " debug:disable_scale_checks " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " debug:colored_stdout_logs " , Hyprlang : : INT { 1 } ) ;
2025-02-26 17:56:37 +03:00
registerConfigVar ( " debug:full_cm_proto " , Hyprlang : : INT { 0 } ) ;
2025-02-25 13:49:07 +00:00
registerConfigVar ( " decoration:rounding " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " decoration:rounding_power " , { 2.F } ) ;
registerConfigVar ( " decoration:blur:enabled " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " decoration:blur:size " , Hyprlang : : INT { 8 } ) ;
registerConfigVar ( " decoration:blur:passes " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " decoration:blur:ignore_opacity " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " decoration:blur:new_optimizations " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " decoration:blur:xray " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " decoration:blur:contrast " , { 0.8916F } ) ;
registerConfigVar ( " decoration:blur:brightness " , { 1.0F } ) ;
registerConfigVar ( " decoration:blur:vibrancy " , { 0.1696F } ) ;
registerConfigVar ( " decoration:blur:vibrancy_darkness " , { 0.0F } ) ;
registerConfigVar ( " decoration:blur:noise " , { 0.0117F } ) ;
registerConfigVar ( " decoration:blur:special " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " decoration:blur:popups " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " decoration:blur:popups_ignorealpha " , { 0.2F } ) ;
registerConfigVar ( " decoration:blur:input_methods " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " decoration:blur:input_methods_ignorealpha " , { 0.2F } ) ;
registerConfigVar ( " decoration:active_opacity " , { 1.F } ) ;
registerConfigVar ( " decoration:inactive_opacity " , { 1.F } ) ;
registerConfigVar ( " decoration:fullscreen_opacity " , { 1.F } ) ;
registerConfigVar ( " decoration:shadow:enabled " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " decoration:shadow:range " , Hyprlang : : INT { 4 } ) ;
registerConfigVar ( " decoration:shadow:render_power " , Hyprlang : : INT { 3 } ) ;
registerConfigVar ( " decoration:shadow:ignore_window " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " decoration:shadow:offset " , Hyprlang : : VEC2 { 0 , 0 } ) ;
registerConfigVar ( " decoration:shadow:scale " , { 1.f } ) ;
registerConfigVar ( " decoration:shadow:sharp " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " decoration:shadow:color " , Hyprlang : : INT { 0xee1a1a1a } ) ;
registerConfigVar ( " decoration:shadow:color_inactive " , { ( Hyprlang : : INT ) INT64_MAX } ) ;
registerConfigVar ( " decoration:dim_inactive " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " decoration:dim_strength " , { 0.5f } ) ;
registerConfigVar ( " decoration:dim_special " , { 0.2f } ) ;
registerConfigVar ( " decoration:dim_around " , { 0.4f } ) ;
registerConfigVar ( " decoration:screen_shader " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " dwindle:pseudotile " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " dwindle:force_split " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " dwindle:permanent_direction_override " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " dwindle:preserve_split " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " dwindle:special_scale_factor " , { 1.f } ) ;
registerConfigVar ( " dwindle:split_width_multiplier " , { 1.0f } ) ;
registerConfigVar ( " dwindle:use_active_for_splits " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " dwindle:default_split_ratio " , { 1.f } ) ;
registerConfigVar ( " dwindle:split_bias " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " dwindle:smart_split " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " dwindle:smart_resizing " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " master:special_scale_factor " , { 1.f } ) ;
registerConfigVar ( " master:mfact " , { 0.55f } ) ;
registerConfigVar ( " master:new_status " , { " slave " } ) ;
registerConfigVar ( " master:slave_count_for_center_master " , Hyprlang : : INT { 2 } ) ;
registerConfigVar ( " master:center_master_slaves_on_right " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " master:center_ignores_reserved " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " master:new_on_active " , { " none " } ) ;
registerConfigVar ( " master:new_on_top " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " master:orientation " , { " left " } ) ;
registerConfigVar ( " master:inherit_fullscreen " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " master:allow_small_split " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " master:smart_resizing " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " master:drop_at_cursor " , Hyprlang : : INT { 1 } ) ;
2025-03-06 17:06:05 -05:00
registerConfigVar ( " master:always_keep_position " , Hyprlang : : INT { 0 } ) ;
2025-02-25 13:49:07 +00:00
registerConfigVar ( " animations:enabled " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " animations:first_launch_animation " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " input:follow_mouse " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " input:follow_mouse_threshold " , Hyprlang : : FLOAT { 0 } ) ;
registerConfigVar ( " input:focus_on_close " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:mouse_refocus " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " input:special_fallthrough " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:off_window_axis_events " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " input:sensitivity " , { 0.f } ) ;
registerConfigVar ( " input:accel_profile " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " input:kb_file " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " input:kb_layout " , { " us " } ) ;
registerConfigVar ( " input:kb_variant " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " input:kb_options " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " input:kb_rules " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " input:kb_model " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " input:repeat_rate " , Hyprlang : : INT { 25 } ) ;
registerConfigVar ( " input:repeat_delay " , Hyprlang : : INT { 600 } ) ;
registerConfigVar ( " input:natural_scroll " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:numlock_by_default " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:resolve_binds_by_sym " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:force_no_accel " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:float_switch_override_focus " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " input:left_handed " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:scroll_method " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " input:scroll_button " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:scroll_button_lock " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:scroll_factor " , { 1.f } ) ;
registerConfigVar ( " input:scroll_points " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " input:emulate_discrete_scroll " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " input:touchpad:natural_scroll " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:touchpad:disable_while_typing " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " input:touchpad:clickfinger_behavior " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:touchpad:tap_button_map " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " input:touchpad:middle_button_emulation " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:touchpad:tap-to-click " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " input:touchpad:tap-and-drag " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " input:touchpad:drag_lock " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:touchpad:scroll_factor " , { 1.f } ) ;
2025-03-03 15:56:01 -05:00
registerConfigVar ( " input:touchpad:flip_x " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:touchpad:flip_y " , Hyprlang : : INT { 0 } ) ;
2025-02-25 13:49:07 +00:00
registerConfigVar ( " input:touchdevice:transform " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:touchdevice:output " , { " [[Auto]] " } ) ;
registerConfigVar ( " input:touchdevice:enabled " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " input:tablet:transform " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:tablet:output " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " input:tablet:region_position " , Hyprlang : : VEC2 { 0 , 0 } ) ;
registerConfigVar ( " input:tablet:absolute_region_position " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:tablet:region_size " , Hyprlang : : VEC2 { 0 , 0 } ) ;
registerConfigVar ( " input:tablet:relative_input " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:tablet:left_handed " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " input:tablet:active_area_position " , Hyprlang : : VEC2 { 0 , 0 } ) ;
registerConfigVar ( " input:tablet:active_area_size " , Hyprlang : : VEC2 { 0 , 0 } ) ;
registerConfigVar ( " binds:pass_mouse_when_bound " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " binds:scroll_event_delay " , Hyprlang : : INT { 300 } ) ;
registerConfigVar ( " binds:workspace_back_and_forth " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " binds:allow_workspace_cycles " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " binds:workspace_center_on " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " binds:focus_preferred_method " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " binds:ignore_group_lock " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " binds:movefocus_cycles_fullscreen " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " binds:movefocus_cycles_groupfirst " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " binds:disable_keybind_grabbing " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " binds:window_direction_monitor_fallback " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " binds:allow_pin_fullscreen " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " gestures:workspace_swipe " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " gestures:workspace_swipe_fingers " , Hyprlang : : INT { 3 } ) ;
registerConfigVar ( " gestures:workspace_swipe_min_fingers " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " gestures:workspace_swipe_distance " , Hyprlang : : INT { 300 } ) ;
registerConfigVar ( " gestures:workspace_swipe_invert " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " gestures:workspace_swipe_min_speed_to_force " , Hyprlang : : INT { 30 } ) ;
registerConfigVar ( " gestures:workspace_swipe_cancel_ratio " , { 0.5f } ) ;
registerConfigVar ( " gestures:workspace_swipe_create_new " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " gestures:workspace_swipe_direction_lock " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " gestures:workspace_swipe_direction_lock_threshold " , Hyprlang : : INT { 10 } ) ;
registerConfigVar ( " gestures:workspace_swipe_forever " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " gestures:workspace_swipe_use_r " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " gestures:workspace_swipe_touch " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " gestures:workspace_swipe_touch_invert " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " xwayland:enabled " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " xwayland:use_nearest_neighbor " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " xwayland:force_zero_scaling " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " opengl:nvidia_anti_flicker " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " cursor:no_hardware_cursors " , Hyprlang : : INT { 2 } ) ;
registerConfigVar ( " cursor:no_break_fs_vrr " , Hyprlang : : INT { 2 } ) ;
registerConfigVar ( " cursor:min_refresh_rate " , Hyprlang : : INT { 24 } ) ;
registerConfigVar ( " cursor:hotspot_padding " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " cursor:inactive_timeout " , { 0.f } ) ;
registerConfigVar ( " cursor:no_warps " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " cursor:persistent_warps " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " cursor:warp_on_change_workspace " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " cursor:default_monitor " , { STRVAL_EMPTY } ) ;
registerConfigVar ( " cursor:zoom_factor " , { 1.f } ) ;
registerConfigVar ( " cursor:zoom_rigid " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " cursor:enable_hyprcursor " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " cursor:sync_gsettings_theme " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " cursor:hide_on_key_press " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " cursor:hide_on_touch " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " cursor:use_cpu_buffer " , Hyprlang : : INT { 2 } ) ;
registerConfigVar ( " cursor:warp_back_after_non_mouse_input " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " autogenerated " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " group:col.border_active " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66ffff00 " } ) ;
registerConfigVar ( " group:col.border_inactive " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66777700 " } ) ;
registerConfigVar ( " group:col.border_locked_active " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66ff5500 " } ) ;
registerConfigVar ( " group:col.border_locked_inactive " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66775500 " } ) ;
registerConfigVar ( " group:groupbar:col.active " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66ffff00 " } ) ;
registerConfigVar ( " group:groupbar:col.inactive " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66777700 " } ) ;
registerConfigVar ( " group:groupbar:col.locked_active " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66ff5500 " } ) ;
registerConfigVar ( " group:groupbar:col.locked_inactive " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66775500 " } ) ;
registerConfigVar ( " render:explicit_sync " , Hyprlang : : INT { 2 } ) ;
registerConfigVar ( " render:explicit_sync_kms " , Hyprlang : : INT { 2 } ) ;
registerConfigVar ( " render:direct_scanout " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " render:expand_undersized_textures " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " render:xp_mode " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " render:ctm_animation " , Hyprlang : : INT { 2 } ) ;
registerConfigVar ( " render:allow_early_buffer_release " , Hyprlang : : INT { 1 } ) ;
registerConfigVar ( " ecosystem:no_update_news " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " ecosystem:no_donation_nag " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " experimental:wide_color_gamut " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " experimental:hdr " , Hyprlang : : INT { 0 } ) ;
registerConfigVar ( " experimental:xx_color_management_v4 " , Hyprlang : : INT { 0 } ) ;
2025-01-07 21:32:50 +03:00
2024-02-18 15:00:34 +00:00
// devices
m_pConfig - > addSpecialCategory ( " device " , { " name " } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " sensitivity " , { 0.F } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " accel_profile " , { STRVAL_EMPTY } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " kb_file " , { STRVAL_EMPTY } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " kb_layout " , { " us " } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " kb_variant " , { STRVAL_EMPTY } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " kb_options " , { STRVAL_EMPTY } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " kb_rules " , { STRVAL_EMPTY } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " kb_model " , { STRVAL_EMPTY } ) ;
2024-02-29 21:33:39 +00:00
m_pConfig - > addSpecialConfigValue ( " device " , " repeat_rate " , Hyprlang : : INT { 25 } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " repeat_delay " , Hyprlang : : INT { 600 } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " natural_scroll " , Hyprlang : : INT { 0 } ) ;
2024-02-18 15:00:34 +00:00
m_pConfig - > addSpecialConfigValue ( " device " , " tap_button_map " , { STRVAL_EMPTY } ) ;
2024-02-29 21:33:39 +00:00
m_pConfig - > addSpecialConfigValue ( " device " , " numlock_by_default " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " resolve_binds_by_sym " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " disable_while_typing " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " clickfinger_behavior " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " middle_button_emulation " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " tap-to-click " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " tap-and-drag " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " drag_lock " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " left_handed " , Hyprlang : : INT { 0 } ) ;
2024-02-18 15:00:34 +00:00
m_pConfig - > addSpecialConfigValue ( " device " , " scroll_method " , { STRVAL_EMPTY } ) ;
2024-02-29 21:33:39 +00:00
m_pConfig - > addSpecialConfigValue ( " device " , " scroll_button " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " scroll_button_lock " , Hyprlang : : INT { 0 } ) ;
2024-02-18 15:00:34 +00:00
m_pConfig - > addSpecialConfigValue ( " device " , " scroll_points " , { STRVAL_EMPTY } ) ;
2024-02-29 21:33:39 +00:00
m_pConfig - > addSpecialConfigValue ( " device " , " transform " , Hyprlang : : INT { 0 } ) ;
2024-02-18 15:00:34 +00:00
m_pConfig - > addSpecialConfigValue ( " device " , " output " , { STRVAL_EMPTY } ) ;
2024-03-23 23:31:03 +03:00
m_pConfig - > addSpecialConfigValue ( " device " , " enabled " , Hyprlang : : INT { 1 } ) ; // only for mice, touchpads, and touchdevices
m_pConfig - > addSpecialConfigValue ( " device " , " region_position " , Hyprlang : : VEC2 { 0 , 0 } ) ; // only for tablets
2024-11-11 13:45:33 +00:00
m_pConfig - > addSpecialConfigValue ( " device " , " absolute_region_position " , Hyprlang : : INT { 0 } ) ; // only for tablets
2024-03-23 23:31:03 +03:00
m_pConfig - > addSpecialConfigValue ( " device " , " region_size " , Hyprlang : : VEC2 { 0 , 0 } ) ; // only for tablets
m_pConfig - > addSpecialConfigValue ( " device " , " relative_input " , Hyprlang : : INT { 0 } ) ; // only for tablets
m_pConfig - > addSpecialConfigValue ( " device " , " active_area_position " , Hyprlang : : VEC2 { 0 , 0 } ) ; // only for tablets
m_pConfig - > addSpecialConfigValue ( " device " , " active_area_size " , Hyprlang : : VEC2 { 0 , 0 } ) ; // only for tablets
2025-03-03 15:56:01 -05:00
m_pConfig - > addSpecialConfigValue ( " device " , " flip_x " , Hyprlang : : INT { 0 } ) ; // only for touchpads
m_pConfig - > addSpecialConfigValue ( " device " , " flip_y " , Hyprlang : : INT { 0 } ) ; // only for touchpads
2024-02-18 15:00:34 +00:00
// keywords
2025-01-11 23:58:05 +08:00
m_pConfig - > registerHandler ( & : : handleExec , " exec " , { false } ) ;
m_pConfig - > registerHandler ( & : : handleRawExec , " execr " , { false } ) ;
2024-02-18 15:00:34 +00:00
m_pConfig - > registerHandler ( & : : handleExecOnce , " exec-once " , { false } ) ;
2025-01-11 23:58:05 +08:00
m_pConfig - > registerHandler ( & : : handleExecRawOnce , " execr-once " , { false } ) ;
2024-09-07 14:54:33 -05:00
m_pConfig - > registerHandler ( & : : handleExecShutdown , " exec-shutdown " , { false } ) ;
2024-02-18 15:00:34 +00:00
m_pConfig - > registerHandler ( & : : handleMonitor , " monitor " , { false } ) ;
m_pConfig - > registerHandler ( & : : handleBind , " bind " , { true } ) ;
m_pConfig - > registerHandler ( & : : handleUnbind , " unbind " , { false } ) ;
m_pConfig - > registerHandler ( & : : handleWorkspaceRules , " workspace " , { false } ) ;
m_pConfig - > registerHandler ( & : : handleWindowRule , " windowrule " , { false } ) ;
m_pConfig - > registerHandler ( & : : handleLayerRule , " layerrule " , { false } ) ;
m_pConfig - > registerHandler ( & : : handleWindowRuleV2 , " windowrulev2 " , { false } ) ;
m_pConfig - > registerHandler ( & : : handleBezier , " bezier " , { false } ) ;
m_pConfig - > registerHandler ( & : : handleAnimation , " animation " , { false } ) ;
m_pConfig - > registerHandler ( & : : handleSource , " source " , { false } ) ;
m_pConfig - > registerHandler ( & : : handleSubmap , " submap " , { false } ) ;
m_pConfig - > registerHandler ( & : : handleBlurLS , " blurls " , { false } ) ;
m_pConfig - > registerHandler ( & : : handlePlugin , " plugin " , { false } ) ;
m_pConfig - > registerHandler ( & : : handleEnv , " env " , { true } ) ;
// pluginza
m_pConfig - > addSpecialCategory ( " plugin " , { nullptr , true } ) ;
m_pConfig - > commence ( ) ;
resetHLConfig ( ) ;
2022-07-01 15:57:56 +02:00
2025-02-25 13:49:07 +00:00
if ( CONFIG_OPTIONS . size ( ) ! = m_configValueNumber - 1 /* autogenerated is special */ )
Debug : : log ( LOG , " Warning: config descriptions have {} entries, but there are {} config values. This should fail tests!! " , CONFIG_OPTIONS . size ( ) , m_configValueNumber ) ;
2025-01-24 20:30:12 +00:00
if ( ! g_pCompositor - > m_bOnlyConfigVerification ) {
Debug : : log (
INFO ,
" !!!!HEY YOU, YES YOU!!!!: further logs to stdout / logfile are disabled by default. BEFORE SENDING THIS LOG, ENABLE THEM. Use debug:disable_logs = false to do so: "
" https://wiki.hyprland.org/Configuring/Variables/#debug " ) ;
}
2024-03-23 21:10:54 +00:00
2024-02-18 15:00:34 +00:00
Debug : : disableLogs = reinterpret_cast < int64_t * const * > ( m_pConfig - > getConfigValuePtr ( " debug:disable_logs " ) - > getDataStaticPtr ( ) ) ;
Debug : : disableTime = reinterpret_cast < int64_t * const * > ( m_pConfig - > getConfigValuePtr ( " debug:disable_time " ) - > getDataStaticPtr ( ) ) ;
2023-03-05 14:54:26 +00:00
2025-01-24 20:30:12 +00:00
if ( g_pEventLoopManager & & ERR . has_value ( ) )
g_pEventLoopManager - > doLater ( [ ERR ] { g_pHyprError - > queueCreate ( ERR . value ( ) , CHyprColor { 1.0 , 0.1 , 0.1 , 1.0 } ) ; } ) ;
2023-03-05 14:54:26 +00:00
}
2024-07-16 22:23:37 +03:00
std : : optional < std : : string > CConfigManager : : generateConfig ( std : : string configPath ) {
std : : string parentPath = std : : filesystem : : path ( configPath ) . parent_path ( ) ;
2023-12-04 01:35:24 +00:00
2024-07-16 22:23:37 +03:00
if ( ! std : : filesystem : : is_directory ( parentPath ) ) {
Debug : : log ( WARN , " Creating config home directory " ) ;
try {
std : : filesystem : : create_directories ( parentPath ) ;
2024-07-27 18:15:47 +02:00
} catch ( std : : exception & e ) { throw e ; }
2024-07-16 22:23:37 +03:00
}
2023-12-04 01:35:24 +00:00
2024-07-16 22:23:37 +03:00
Debug : : log ( WARN , " No config file found; attempting to generate. " ) ;
std : : ofstream ofs ;
ofs . open ( configPath , std : : ios : : trunc ) ;
ofs < < AUTOCONFIG ;
ofs . close ( ) ;
2024-07-05 22:58:47 +02:00
2024-07-16 22:23:37 +03:00
if ( ! std : : filesystem : : exists ( configPath ) )
return " Config could not be generated. " ;
2024-07-05 22:58:47 +02:00
2024-07-16 22:23:37 +03:00
return configPath ;
2023-07-07 13:19:35 -04:00
}
std : : string CConfigManager : : getMainConfigPath ( ) {
2025-01-02 18:29:10 +01:00
static std : : string CONFIG_PATH = [ this ] ( ) - > std : : string {
if ( ! g_pCompositor - > explicitConfigPath . empty ( ) )
return g_pCompositor - > explicitConfigPath ;
if ( const auto CFG_ENV = getenv ( " HYPRLAND_CONFIG " ) ; CFG_ENV )
return CFG_ENV ;
const auto PATHS = Hyprutils : : Path : : findConfig ( ISDEBUG ? " hyprlandd " : " hyprland " ) ;
if ( PATHS . first . has_value ( ) ) {
return PATHS . first . value ( ) ;
} else if ( PATHS . second . has_value ( ) ) {
const auto CONFIGPATH = Hyprutils : : Path : : fullConfigPath ( PATHS . second . value ( ) , ISDEBUG ? " hyprlandd " : " hyprland " ) ;
return generateConfig ( CONFIGPATH ) . value ( ) ;
} else
throw std : : runtime_error ( " Neither HOME nor XDG_CONFIG_HOME are set in the environment. Could not find config in XDG_CONFIG_DIRS or /etc/xdg. " ) ;
} ( ) ;
return CONFIG_PATH ;
2024-07-16 22:23:37 +03:00
}
std : : optional < std : : string > CConfigManager : : verifyConfigExists ( ) {
std : : string mainConfigPath = getMainConfigPath ( ) ;
if ( ! std : : filesystem : : exists ( mainConfigPath ) )
return " broken config dir? " ;
return { } ;
2023-07-07 13:19:35 -04:00
}
2024-12-16 19:05:24 +01:00
std : : string CConfigManager : : getConfigString ( ) {
2024-05-25 20:46:07 +00:00
std : : string configString ;
std : : string currFileContent ;
2025-01-19 15:39:19 +01:00
for ( const auto & path : m_configPaths ) {
2024-05-25 20:46:07 +00:00
std : : ifstream configFile ( path ) ;
configString + = ( " \n \n Config File: " + path + " : " ) ;
if ( ! configFile . is_open ( ) ) {
Debug : : log ( LOG , " Config file not readable/found! " ) ;
configString + = " Read Failed \n " ;
continue ;
}
configString + = " Read Succeeded \n " ;
currFileContent . assign ( std : : istreambuf_iterator < char > ( configFile ) , std : : istreambuf_iterator < char > ( ) ) ;
configString . append ( currFileContent ) ;
}
return configString ;
}
2024-03-20 21:55:13 -04:00
std : : string CConfigManager : : getErrors ( ) {
return m_szConfigErrors ;
}
2024-02-18 15:00:34 +00:00
void CConfigManager : : reload ( ) {
2024-02-20 03:24:10 +00:00
EMIT_HOOK_EVENT ( " preConfigReload " , nullptr ) ;
2024-02-18 15:00:34 +00:00
setDefaultAnimationVars ( ) ;
resetHLConfig ( ) ;
2025-01-24 20:30:12 +00:00
configCurrentPath = getMainConfigPath ( ) ;
const auto ERR = m_pConfig - > parse ( ) ;
m_bLastConfigVerificationWasSuccessful = ! ERR . error ;
2024-02-18 15:00:34 +00:00
postConfigReload ( ERR ) ;
2022-06-30 21:26:00 +02:00
}
2025-01-24 20:30:12 +00:00
std : : string CConfigManager : : verify ( ) {
setDefaultAnimationVars ( ) ;
resetHLConfig ( ) ;
configCurrentPath = getMainConfigPath ( ) ;
const auto ERR = m_pConfig - > parse ( ) ;
m_bLastConfigVerificationWasSuccessful = ! ERR . error ;
if ( ERR . error )
return ERR . getError ( ) ;
return " config ok " ;
}
2022-07-28 13:28:43 +02:00
void CConfigManager : : setDefaultAnimationVars ( ) {
2025-01-07 17:55:14 +00:00
m_AnimationTree . createNode ( " __internal_fadeCTM " ) ;
m_AnimationTree . createNode ( " global " ) ;
// global
m_AnimationTree . createNode ( " windows " , " global " ) ;
m_AnimationTree . createNode ( " layers " , " global " ) ;
m_AnimationTree . createNode ( " fade " , " global " ) ;
m_AnimationTree . createNode ( " border " , " global " ) ;
m_AnimationTree . createNode ( " borderangle " , " global " ) ;
m_AnimationTree . createNode ( " workspaces " , " global " ) ;
// layer
m_AnimationTree . createNode ( " layersIn " , " layers " ) ;
m_AnimationTree . createNode ( " layersOut " , " layers " ) ;
// windows
m_AnimationTree . createNode ( " windowsIn " , " windows " ) ;
m_AnimationTree . createNode ( " windowsOut " , " windows " ) ;
m_AnimationTree . createNode ( " windowsMove " , " windows " ) ;
// fade
m_AnimationTree . createNode ( " fadeIn " , " fade " ) ;
m_AnimationTree . createNode ( " fadeOut " , " fade " ) ;
m_AnimationTree . createNode ( " fadeSwitch " , " fade " ) ;
m_AnimationTree . createNode ( " fadeShadow " , " fade " ) ;
m_AnimationTree . createNode ( " fadeDim " , " fade " ) ;
m_AnimationTree . createNode ( " fadeLayers " , " fade " ) ;
m_AnimationTree . createNode ( " fadeLayersIn " , " fadeLayers " ) ;
m_AnimationTree . createNode ( " fadeLayersOut " , " fadeLayers " ) ;
// workspaces
m_AnimationTree . createNode ( " workspacesIn " , " workspaces " ) ;
m_AnimationTree . createNode ( " workspacesOut " , " workspaces " ) ;
m_AnimationTree . createNode ( " specialWorkspace " , " workspaces " ) ;
m_AnimationTree . createNode ( " specialWorkspaceIn " , " specialWorkspace " ) ;
m_AnimationTree . createNode ( " specialWorkspaceOut " , " specialWorkspace " ) ;
// init the root nodes
2025-02-13 11:37:59 +00:00
m_AnimationTree . setConfigForNode ( " global " , 1 , 8.f , " default " ) ;
m_AnimationTree . setConfigForNode ( " __internal_fadeCTM " , 1 , 5.f , " linear " ) ;
m_AnimationTree . setConfigForNode ( " borderangle " , 0 , 1 , " default " ) ;
2022-07-28 13:28:43 +02:00
}
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : resetHLConfig ( ) {
2024-12-16 15:58:19 +00:00
m_vMonitorRules . clear ( ) ;
m_vWindowRules . clear ( ) ;
2024-02-18 15:00:34 +00:00
g_pKeybindManager - > clearKeybinds ( ) ;
g_pAnimationManager - > removeAllBeziers ( ) ;
2025-01-07 17:55:14 +00:00
g_pAnimationManager - > addBezierWithName ( " linear " , Vector2D ( 0.0 , 0.0 ) , Vector2D ( 1.0 , 1.0 ) ) ;
2024-02-18 15:00:34 +00:00
m_mAdditionalReservedAreas . clear ( ) ;
m_dBlurLSNamespaces . clear ( ) ;
2024-12-16 15:58:19 +00:00
m_vWorkspaceRules . clear ( ) ;
2024-02-18 15:00:34 +00:00
setDefaultAnimationVars ( ) ; // reset anims
m_vDeclaredPlugins . clear ( ) ;
2024-12-16 15:58:19 +00:00
m_vLayerRules . clear ( ) ;
2024-02-18 15:00:34 +00:00
m_vFailedPluginConfigValues . clear ( ) ;
2024-09-07 14:54:33 -05:00
finalExecRequests . clear ( ) ;
2024-01-02 21:08:30 +05:30
2024-02-18 15:00:34 +00:00
// paths
2025-01-19 15:39:19 +01:00
m_configPaths . clear ( ) ;
2024-02-18 15:00:34 +00:00
std : : string mainConfigPath = getMainConfigPath ( ) ;
Debug : : log ( LOG , " Using config: {} " , mainConfigPath ) ;
2025-01-19 15:39:19 +01:00
m_configPaths . emplace_back ( mainConfigPath ) ;
2022-05-16 09:38:42 +02:00
2024-02-18 15:00:34 +00:00
const auto RET = verifyConfigExists ( ) ;
2022-03-17 15:53:45 +01:00
2024-02-18 15:00:34 +00:00
return RET ;
}
2022-06-30 21:26:00 +02:00
2025-01-29 10:50:39 +00:00
void CConfigManager : : updateWatcher ( ) {
static const auto PDISABLEAUTORELOAD = CConfigValue < Hyprlang : : INT > ( " misc:disable_autoreload " ) ;
g_pConfigWatcher - > setWatchList ( * PDISABLEAUTORELOAD ? std : : vector < std : : string > { } : m_configPaths ) ;
}
2024-02-18 15:00:34 +00:00
void CConfigManager : : postConfigReload ( const Hyprlang : : CParseResult & result ) {
2024-08-06 14:52:19 +01:00
static const auto PENABLEEXPLICIT = CConfigValue < Hyprlang : : INT > ( " render:explicit_sync " ) ;
static int prevEnabledExplicit = * PENABLEEXPLICIT ;
2025-01-29 10:50:39 +00:00
updateWatcher ( ) ;
2025-01-19 15:39:19 +01:00
2024-08-26 17:25:39 +02:00
for ( auto const & w : g_pCompositor - > m_vWindows ) {
2024-02-18 15:00:34 +00:00
w - > uncacheWindowDecos ( ) ;
}
2022-06-30 21:26:00 +02:00
2024-08-26 17:25:39 +02:00
for ( auto const & m : g_pCompositor - > m_vMonitors )
2024-02-18 15:00:34 +00:00
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( m - > ID ) ;
2022-06-30 21:26:00 +02:00
2024-02-18 15:00:34 +00:00
// Update the keyboard layout to the cfg'd one if this is not the first launch
if ( ! isFirstLaunch ) {
g_pInputManager - > setKeyboardLayout ( ) ;
g_pInputManager - > setPointerConfigs ( ) ;
g_pInputManager - > setTouchDeviceConfigs ( ) ;
g_pInputManager - > setTabletConfigs ( ) ;
2022-06-30 21:26:00 +02:00
2024-02-18 15:00:34 +00:00
g_pHyprOpenGL - > m_bReloadScreenShader = true ;
2022-12-21 15:11:39 +00:00
2025-01-14 17:52:19 +01:00
g_pHyprOpenGL - > ensureBackgroundTexturePresence ( ) ;
}
2024-02-18 15:00:34 +00:00
// parseError will be displayed next frame
2024-03-20 21:55:13 -04:00
if ( result . error )
m_szConfigErrors = result . getError ( ) ;
else
m_szConfigErrors = " " ;
2024-02-18 15:00:34 +00:00
if ( result . error & & ! std : : any_cast < Hyprlang : : INT > ( m_pConfig - > getConfigValue ( " debug:suppress_errors " ) ) )
2024-12-03 18:58:24 +00:00
g_pHyprError - > queueCreate ( result . getError ( ) , CHyprColor ( 1.0 , 50.0 / 255.0 , 50.0 / 255.0 , 1.0 ) ) ;
2024-02-18 15:00:34 +00:00
else if ( std : : any_cast < Hyprlang : : INT > ( m_pConfig - > getConfigValue ( " autogenerated " ) ) = = 1 )
2024-10-08 09:54:25 +01:00
g_pHyprError - > queueCreate (
2025-01-22 11:16:46 +01:00
" Warning: You're using an autogenerated config! Edit the config file to get rid of this message. (config file: " + getMainConfigPath ( ) +
2024-10-08 09:54:25 +01:00
" ) \n SUPER+Q -> kitty (if it doesn't launch, make sure it's installed or choose a different terminal in the config) \n SUPER+M -> exit Hyprland " ,
2024-12-03 18:58:24 +00:00
CHyprColor ( 1.0 , 1.0 , 70.0 / 255.0 , 1.0 ) ) ;
2024-08-12 11:16:00 -05:00
else if ( * PENABLEEXPLICIT ! = prevEnabledExplicit )
2024-12-03 18:58:24 +00:00
g_pHyprError - > queueCreate ( " Warning: You changed the render:explicit_sync option, this requires you to restart Hyprland. " , CHyprColor ( 0.9 , 0.76 , 0.221 , 1.0 ) ) ;
2024-02-18 15:00:34 +00:00
else
g_pHyprError - > destroy ( ) ;
2022-06-30 21:26:00 +02:00
2024-02-18 15:00:34 +00:00
// Set the modes for all monitors as we configured them
// not on first launch because monitors might not exist yet
// and they'll be taken care of in the newMonitor event
// ignore if nomonitorreload is set
if ( ! isFirstLaunch & & ! m_bNoMonitorReload ) {
// check
performMonitorReload ( ) ;
ensureMonitorStatus ( ) ;
ensureVRR ( ) ;
}
2023-02-27 12:32:38 +00:00
2024-09-05 11:26:46 -05:00
# ifndef NO_XWAYLAND
2025-01-20 13:40:51 -05:00
const auto PENABLEXWAYLAND = std : : any_cast < Hyprlang : : INT > ( m_pConfig - > getConfigValue ( " xwayland:enabled " ) ) ;
g_pCompositor - > m_bWantsXwayland = PENABLEXWAYLAND ;
2024-09-05 11:26:46 -05:00
// enable/disable xwayland usage
2025-01-23 21:27:11 +00:00
if ( ! isFirstLaunch & &
g_pXWayland /* XWayland has to be initialized by CCompositor::initManagers for this to make sense, and it doesn't have to be (e.g. very early plugin load) */ ) {
2025-01-20 13:40:51 -05:00
bool prevEnabledXwayland = g_pXWayland - > enabled ( ) ;
2025-01-23 21:55:41 +01:00
if ( g_pCompositor - > m_bWantsXwayland ! = prevEnabledXwayland )
g_pXWayland = makeUnique < CXWayland > ( g_pCompositor - > m_bWantsXwayland ) ;
2024-09-05 11:26:46 -05:00
} else
2025-01-20 13:40:51 -05:00
g_pCompositor - > m_bWantsXwayland = PENABLEXWAYLAND ;
2024-09-05 11:26:46 -05:00
# endif
2024-02-18 15:00:34 +00:00
if ( ! isFirstLaunch & & ! g_pCompositor - > m_bUnsafeState )
refreshGroupBarGradients ( ) ;
2023-02-27 12:32:38 +00:00
2024-02-18 15:00:34 +00:00
// Updates dynamic window and workspace rules
2024-08-26 20:24:30 +02:00
for ( auto const & w : g_pCompositor - > m_vWorkspaces ) {
2024-04-11 01:26:11 +09:00
if ( w - > inert ( ) )
2024-02-18 15:00:34 +00:00
continue ;
2024-11-22 16:01:02 +00:00
w - > updateWindows ( ) ;
w - > updateWindowData ( ) ;
2022-06-30 21:26:00 +02:00
}
2022-04-18 13:25:27 +02:00
2024-02-18 15:00:34 +00:00
// Update window border colors
g_pCompositor - > updateAllWindowsAnimatedDecorationValues ( ) ;
2022-06-30 21:38:06 +02:00
2024-02-18 15:00:34 +00:00
// update layout
g_pLayoutManager - > switchToLayout ( std : : any_cast < Hyprlang : : STRING > ( m_pConfig - > getConfigValue ( " general:layout " ) ) ) ;
2022-09-30 17:03:06 +01:00
2024-02-18 15:00:34 +00:00
// manual crash
if ( std : : any_cast < Hyprlang : : INT > ( m_pConfig - > getConfigValue ( " debug:manual_crash " ) ) & & ! m_bManualCrashInitiated ) {
m_bManualCrashInitiated = true ;
2024-12-03 18:58:24 +00:00
g_pHyprNotificationOverlay - > addNotification ( " Manual crash has been set up. Set debug:manual_crash back to 0 in order to crash the compositor. " , CHyprColor ( 0 ) , 5000 ,
ICON_INFO ) ;
2024-02-18 15:00:34 +00:00
} else if ( m_bManualCrashInitiated & & ! std : : any_cast < Hyprlang : : INT > ( m_pConfig - > getConfigValue ( " debug:manual_crash " ) ) ) {
// cowabunga it is
g_pHyprRenderer - > initiateManualCrash ( ) ;
}
2022-11-26 17:56:43 +00:00
2024-02-18 15:00:34 +00:00
Debug : : disableStdout = ! std : : any_cast < Hyprlang : : INT > ( m_pConfig - > getConfigValue ( " debug:enable_stdout_logs " ) ) ;
if ( Debug : : disableStdout & & isFirstLaunch )
Debug : : log ( LOG , " Disabling stdout logs! Check the log for further logs. " ) ;
2022-12-16 17:17:31 +00:00
2024-04-29 08:07:35 -07:00
Debug : : coloredLogs = reinterpret_cast < int64_t * const * > ( m_pConfig - > getConfigValuePtr ( " debug:colored_stdout_logs " ) - > getDataStaticPtr ( ) ) ;
2024-08-26 20:24:30 +02:00
for ( auto const & m : g_pCompositor - > m_vMonitors ) {
2024-02-18 15:00:34 +00:00
// mark blur dirty
2024-10-19 23:03:29 +01:00
g_pHyprOpenGL - > markBlurDirtyForMonitor ( m ) ;
2022-11-26 17:56:43 +00:00
2024-10-19 23:03:29 +01:00
g_pCompositor - > scheduleFrameForMonitor ( m ) ;
2022-11-26 17:56:43 +00:00
2024-02-18 15:00:34 +00:00
// Force the compositor to fully re-render all monitors
m - > forceFullFrames = 2 ;
2024-04-24 17:29:41 +02:00
// also force mirrors, as the aspect ratio could've changed
2024-08-26 17:25:39 +02:00
for ( auto const & mirror : m - > mirrors )
2024-04-24 17:29:41 +02:00
mirror - > forceFullFrames = 3 ;
2024-02-18 15:00:34 +00:00
}
2022-11-26 17:56:43 +00:00
2024-02-18 15:00:34 +00:00
// Reset no monitor reload
m_bNoMonitorReload = false ;
2022-11-26 17:56:43 +00:00
2024-02-18 15:00:34 +00:00
// update plugins
handlePluginLoads ( ) ;
2022-11-26 17:56:43 +00:00
2025-01-26 14:40:42 +00:00
// update persistent workspaces
if ( ! isFirstLaunch )
ensurePersistentWorkspacesPresent ( ) ;
2024-02-18 15:00:34 +00:00
EMIT_HOOK_EVENT ( " configReloaded " , nullptr ) ;
if ( g_pEventManager )
g_pEventManager - > postEvent ( SHyprIPCEvent { " configreloaded " , " " } ) ;
}
2022-11-26 17:56:43 +00:00
2024-02-18 15:00:34 +00:00
void CConfigManager : : init ( ) {
2022-11-26 17:56:43 +00:00
2025-01-19 15:39:19 +01:00
g_pConfigWatcher - > setOnChange ( [ this ] ( const CConfigWatcher : : SConfigWatchEvent & e ) {
Debug : : log ( LOG , " CConfigManager: file {} modified, reloading " , e . file ) ;
reload ( ) ;
} ) ;
2024-02-18 15:00:34 +00:00
const std : : string CONFIGPATH = getMainConfigPath ( ) ;
reload ( ) ;
2022-11-26 17:56:43 +00:00
2024-02-18 15:00:34 +00:00
isFirstLaunch = false ;
}
2022-12-01 13:36:07 +00:00
2024-02-18 15:00:34 +00:00
std : : string CConfigManager : : parseKeyword ( const std : : string & COMMAND , const std : : string & VALUE ) {
2024-08-12 11:16:00 -05:00
static const auto PENABLEEXPLICIT = CConfigValue < Hyprlang : : INT > ( " render:explicit_sync " ) ;
static int prevEnabledExplicit = * PENABLEEXPLICIT ;
const auto RET = m_pConfig - > parseDynamic ( COMMAND . c_str ( ) , VALUE . c_str ( ) ) ;
2024-02-18 15:00:34 +00:00
// invalidate layouts if they changed
2024-02-24 14:06:28 +00:00
if ( COMMAND = = " monitor " | | COMMAND . contains ( " gaps_ " ) | | COMMAND . starts_with ( " dwindle: " ) | | COMMAND . starts_with ( " master: " ) ) {
2024-08-26 17:25:39 +02:00
for ( auto const & m : g_pCompositor - > m_vMonitors )
2024-02-24 14:06:28 +00:00
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( m - > ID ) ;
2024-02-18 15:00:34 +00:00
}
2022-12-01 13:36:07 +00:00
2024-08-12 11:16:00 -05:00
if ( COMMAND . contains ( " explicit " ) ) {
if ( * PENABLEEXPLICIT ! = prevEnabledExplicit )
2024-12-03 18:58:24 +00:00
g_pHyprError - > queueCreate ( " Warning: You changed the render:explicit_sync option, this requires you to restart Hyprland. " , CHyprColor ( 0.9 , 0.76 , 0.221 , 1.0 ) ) ;
2024-08-12 11:16:00 -05:00
else
g_pHyprError - > destroy ( ) ;
}
2024-02-18 15:00:34 +00:00
// Update window border colors
g_pCompositor - > updateAllWindowsAnimatedDecorationValues ( ) ;
// manual crash
if ( std : : any_cast < Hyprlang : : INT > ( m_pConfig - > getConfigValue ( " debug:manual_crash " ) ) & & ! m_bManualCrashInitiated ) {
m_bManualCrashInitiated = true ;
if ( g_pHyprNotificationOverlay ) {
2024-12-03 18:58:24 +00:00
g_pHyprNotificationOverlay - > addNotification ( " Manual crash has been set up. Set debug:manual_crash back to 0 in order to crash the compositor. " , CHyprColor ( 0 ) , 5000 ,
2024-02-18 15:00:34 +00:00
ICON_INFO ) ;
}
} else if ( m_bManualCrashInitiated & & ! std : : any_cast < Hyprlang : : INT > ( m_pConfig - > getConfigValue ( " debug:manual_crash " ) ) ) {
// cowabunga it is
g_pHyprRenderer - > initiateManualCrash ( ) ;
2022-12-01 13:36:07 +00:00
}
2022-03-17 15:53:45 +01:00
2024-02-18 15:00:34 +00:00
return RET . error ? RET . getError ( ) : " " ;
2022-03-17 15:53:45 +01:00
}
2024-02-18 15:00:34 +00:00
Hyprlang : : CConfigValue * CConfigManager : : getConfigValueSafeDevice ( const std : : string & dev , const std : : string & val , const std : : string & fallback ) {
2023-05-09 15:01:45 +02:00
2024-02-18 15:00:34 +00:00
const auto VAL = m_pConfig - > getSpecialConfigValuePtr ( " device " , val . c_str ( ) , dev . c_str ( ) ) ;
2023-05-09 15:01:45 +02:00
2024-02-18 15:00:34 +00:00
if ( ( ! VAL | | ! VAL - > m_bSetByUser ) & & ! fallback . empty ( ) ) {
return m_pConfig - > getConfigValuePtr ( fallback . c_str ( ) ) ;
2023-05-09 15:01:45 +02:00
}
2024-02-18 15:00:34 +00:00
return VAL ;
2023-05-09 15:01:45 +02:00
}
2024-02-18 15:00:34 +00:00
int CConfigManager : : getDeviceInt ( const std : : string & dev , const std : : string & v , const std : : string & fallback ) {
return std : : any_cast < Hyprlang : : INT > ( getConfigValueSafeDevice ( dev , v , fallback ) - > getValue ( ) ) ;
}
2022-03-17 16:56:33 +01:00
2024-02-18 15:00:34 +00:00
float CConfigManager : : getDeviceFloat ( const std : : string & dev , const std : : string & v , const std : : string & fallback ) {
return std : : any_cast < Hyprlang : : FLOAT > ( getConfigValueSafeDevice ( dev , v , fallback ) - > getValue ( ) ) ;
}
2022-03-17 16:56:33 +01:00
2024-02-18 15:00:34 +00:00
Vector2D CConfigManager : : getDeviceVec ( const std : : string & dev , const std : : string & v , const std : : string & fallback ) {
2024-06-19 16:20:06 +02:00
auto vec = std : : any_cast < Hyprlang : : VEC2 > ( getConfigValueSafeDevice ( dev , v , fallback ) - > getValue ( ) ) ;
return { vec . x , vec . y } ;
2024-02-18 15:00:34 +00:00
}
2023-01-29 16:04:47 +00:00
2024-02-18 15:00:34 +00:00
std : : string CConfigManager : : getDeviceString ( const std : : string & dev , const std : : string & v , const std : : string & fallback ) {
2024-12-07 18:51:18 +01:00
auto VAL = std : : string { std : : any_cast < Hyprlang : : STRING > ( getConfigValueSafeDevice ( dev , v , fallback ) - > getValue ( ) ) } ;
2022-05-29 12:27:45 +02:00
2024-02-18 15:00:34 +00:00
if ( VAL = = STRVAL_EMPTY )
return " " ;
2022-05-29 12:27:45 +02:00
2024-02-18 15:00:34 +00:00
return VAL ;
}
2022-04-27 17:46:07 +02:00
2024-10-26 02:06:13 +01:00
SMonitorRule CConfigManager : : getMonitorRuleFor ( const PHLMONITOR PMONITOR ) {
2024-09-26 11:10:53 +01:00
auto applyWlrOutputConfig = [ PMONITOR ] ( SMonitorRule rule ) - > SMonitorRule {
const auto CONFIG = PROTO : : outputManagement - > getOutputStateFor ( PMONITOR ) ;
if ( ! CONFIG )
return rule ;
Debug : : log ( LOG , " CConfigManager::getMonitorRuleFor: found a wlr_output_manager override for {} " , PMONITOR - > szName ) ;
Debug : : log ( LOG , " > overriding enabled: {} -> {} " , ! rule . disabled , ! CONFIG - > enabled ) ;
rule . disabled = ! CONFIG - > enabled ;
if ( ( CONFIG - > committedProperties & OUTPUT_HEAD_COMMITTED_MODE ) | | ( CONFIG - > committedProperties & OUTPUT_HEAD_COMMITTED_CUSTOM_MODE ) ) {
Debug : : log ( LOG , " > overriding mode: {:.0f}x{:.0f}@{:.2f}Hz -> {:.0f}x{:.0f}@{:.2f}Hz " , rule . resolution . x , rule . resolution . y , rule . refreshRate , CONFIG - > resolution . x ,
CONFIG - > resolution . y , CONFIG - > refresh / 1000.F ) ;
rule . resolution = CONFIG - > resolution ;
rule . refreshRate = CONFIG - > refresh / 1000.F ;
}
if ( CONFIG - > committedProperties & OUTPUT_HEAD_COMMITTED_POSITION ) {
Debug : : log ( LOG , " > overriding offset: {:.0f}, {:.0f} -> {:.0f}, {:.0f} " , rule . offset . x , rule . offset . y , CONFIG - > position . x , CONFIG - > position . y ) ;
rule . offset = CONFIG - > position ;
}
if ( CONFIG - > committedProperties & OUTPUT_HEAD_COMMITTED_TRANSFORM ) {
Debug : : log ( LOG , " > overriding transform: {} -> {} " , ( uint8_t ) rule . transform , ( uint8_t ) CONFIG - > transform ) ;
rule . transform = CONFIG - > transform ;
}
if ( CONFIG - > committedProperties & OUTPUT_HEAD_COMMITTED_SCALE ) {
Debug : : log ( LOG , " > overriding scale: {} -> {} " , ( uint8_t ) rule . scale , ( uint8_t ) CONFIG - > scale ) ;
rule . scale = CONFIG - > scale ;
}
if ( CONFIG - > committedProperties & OUTPUT_HEAD_COMMITTED_ADAPTIVE_SYNC ) {
Debug : : log ( LOG , " > overriding vrr: {} -> {} " , rule . vrr . value_or ( 0 ) , CONFIG - > adaptiveSync ) ;
rule . vrr = ( int ) CONFIG - > adaptiveSync ;
}
return rule ;
} ;
2024-12-16 15:58:19 +00:00
for ( auto const & r : m_vMonitorRules | std : : views : : reverse ) {
2024-09-26 11:10:53 +01:00
if ( PMONITOR - > matchesStaticSelector ( r . name ) ) {
return applyWlrOutputConfig ( r ) ;
2024-02-18 15:00:34 +00:00
}
}
2022-04-27 17:46:07 +02:00
2024-09-26 11:10:53 +01:00
Debug : : log ( WARN , " No rule found for {}, trying to use the first. " , PMONITOR - > szName ) ;
2022-04-27 17:46:07 +02:00
2024-12-16 15:58:19 +00:00
for ( auto const & r : m_vMonitorRules ) {
2024-05-29 05:37:24 +08:00
if ( r . name . empty ( ) ) {
2024-09-26 11:10:53 +01:00
return applyWlrOutputConfig ( r ) ;
2022-04-27 17:46:07 +02:00
}
2024-02-18 15:00:34 +00:00
}
2022-04-17 10:19:46 +02:00
2024-02-18 15:00:34 +00:00
Debug : : log ( WARN , " No rules configured. Using the default hardcoded one. " ) ;
2022-04-17 10:21:54 +02:00
2024-09-26 11:10:53 +01:00
return applyWlrOutputConfig ( SMonitorRule { . autoDir = eAutoDirs : : DIR_AUTO_RIGHT ,
. name = " " ,
. resolution = Vector2D ( 0 , 0 ) ,
. offset = Vector2D ( - INT32_MAX , - INT32_MAX ) ,
. scale = - 1 } ) ; // 0, 0 is preferred and -1, -1 is auto
2024-02-18 15:00:34 +00:00
}
2022-04-17 10:19:46 +02:00
2024-04-05 08:54:30 -07:00
SWorkspaceRule CConfigManager : : getWorkspaceRuleFor ( PHLWORKSPACE pWorkspace ) {
SWorkspaceRule mergedRule { } ;
2024-12-16 15:58:19 +00:00
for ( auto const & rule : m_vWorkspaceRules ) {
2024-04-05 08:54:30 -07:00
if ( ! pWorkspace - > matchesStaticSelector ( rule . workspaceString ) )
continue ;
2024-04-19 18:20:16 -07:00
mergedRule = mergeWorkspaceRules ( mergedRule , rule ) ;
2024-03-30 17:49:53 -07:00
}
2024-04-05 08:54:30 -07:00
return mergedRule ;
2024-02-18 15:00:34 +00:00
}
2022-03-19 21:46:29 +01:00
2024-04-19 18:20:16 -07:00
SWorkspaceRule CConfigManager : : mergeWorkspaceRules ( const SWorkspaceRule & rule1 , const SWorkspaceRule & rule2 ) {
SWorkspaceRule mergedRule = rule1 ;
2024-05-03 18:18:04 -07:00
if ( rule1 . monitor . empty ( ) )
mergedRule . monitor = rule2 . monitor ;
if ( rule1 . workspaceString . empty ( ) )
mergedRule . workspaceString = rule2 . workspaceString ;
if ( rule1 . workspaceName . empty ( ) )
mergedRule . workspaceName = rule2 . workspaceName ;
if ( rule1 . workspaceId = = WORKSPACE_INVALID )
mergedRule . workspaceId = rule2 . workspaceId ;
2024-04-19 18:20:16 -07:00
if ( rule2 . isDefault )
mergedRule . isDefault = true ;
if ( rule2 . isPersistent )
mergedRule . isPersistent = true ;
if ( rule2 . gapsIn . has_value ( ) )
mergedRule . gapsIn = rule2 . gapsIn ;
if ( rule2 . gapsOut . has_value ( ) )
mergedRule . gapsOut = rule2 . gapsOut ;
if ( rule2 . borderSize . has_value ( ) )
mergedRule . borderSize = rule2 . borderSize ;
2024-07-11 14:10:42 +00:00
if ( rule2 . noBorder . has_value ( ) )
mergedRule . noBorder = rule2 . noBorder ;
if ( rule2 . noRounding . has_value ( ) )
mergedRule . noRounding = rule2 . noRounding ;
2024-04-19 18:20:16 -07:00
if ( rule2 . decorate . has_value ( ) )
mergedRule . decorate = rule2 . decorate ;
2024-07-11 14:10:42 +00:00
if ( rule2 . noShadow . has_value ( ) )
mergedRule . noShadow = rule2 . noShadow ;
2024-04-19 18:20:16 -07:00
if ( rule2 . onCreatedEmptyRunCmd . has_value ( ) )
mergedRule . onCreatedEmptyRunCmd = rule2 . onCreatedEmptyRunCmd ;
if ( rule2 . defaultName . has_value ( ) )
mergedRule . defaultName = rule2 . defaultName ;
if ( ! rule2 . layoutopts . empty ( ) ) {
for ( const auto & layoutopt : rule2 . layoutopts ) {
mergedRule . layoutopts [ layoutopt . first ] = layoutopt . second ;
}
}
return mergedRule ;
}
2024-12-16 19:05:24 +01:00
std : : vector < SP < CWindowRule > > CConfigManager : : getMatchingRules ( PHLWINDOW pWindow , bool dynamic , bool shadowExec ) {
2024-04-27 12:43:12 +01:00
if ( ! valid ( pWindow ) )
2024-12-16 19:05:24 +01:00
return std : : vector < SP < CWindowRule > > ( ) ;
2022-03-17 16:56:33 +01:00
2024-05-16 00:55:55 +01:00
// if the window is unmapped, don't process exec rules yet.
shadowExec = shadowExec | | ! pWindow - > m_bIsMapped ;
2024-12-16 19:05:24 +01:00
std : : vector < SP < CWindowRule > > returns ;
2022-08-03 21:06:51 +02:00
2024-12-16 19:05:24 +01:00
Debug : : log ( LOG , " Searching for matching rules for {} (title: {}) " , pWindow - > m_szClass , pWindow - > m_szTitle ) ;
2022-08-03 21:06:51 +02:00
2024-02-18 15:00:34 +00:00
// since some rules will be applied later, we need to store some flags
bool hasFloating = pWindow - > m_bIsFloating ;
2024-07-31 17:55:52 +00:00
bool hasFullscreen = pWindow - > isFullscreen ( ) ;
2022-04-21 22:15:42 +02:00
2024-05-29 05:37:24 +08:00
// local tags for dynamic tag rule match
auto tags = pWindow - > m_tags ;
2024-12-16 15:58:19 +00:00
for ( auto const & rule : m_vWindowRules ) {
2024-02-18 15:00:34 +00:00
// check if we have a matching rule
2024-12-16 19:05:24 +01:00
if ( ! rule - > v2 ) {
2024-02-18 15:00:34 +00:00
try {
2024-12-16 19:05:24 +01:00
if ( rule - > szValue . starts_with ( " tag: " ) & & ! tags . isTagged ( rule - > szValue . substr ( 4 ) ) )
2024-05-29 05:37:24 +08:00
continue ;
2024-12-21 23:07:23 +00:00
if ( rule - > szValue . starts_with ( " title: " ) & & ! rule - > rV1Regex . passes ( pWindow - > m_szTitle ) )
2024-12-16 19:21:44 +01:00
continue ;
2023-05-01 23:28:27 +02:00
2024-12-21 23:07:23 +00:00
if ( ! rule - > rV1Regex . passes ( pWindow - > m_szClass ) )
2024-12-16 19:21:44 +01:00
continue ;
2023-05-01 23:28:27 +02:00
2024-02-18 15:00:34 +00:00
} catch ( . . . ) {
2024-12-16 19:05:24 +01:00
Debug : : log ( ERR , " Regex error at {} " , rule - > szValue ) ;
2024-02-18 15:00:34 +00:00
continue ;
}
2022-09-13 15:25:42 +02:00
} else {
2024-02-18 15:00:34 +00:00
try {
2024-12-16 19:05:24 +01:00
if ( rule - > bX11 ! = - 1 ) {
if ( pWindow - > m_bIsX11 ! = rule - > bX11 )
2024-02-18 15:00:34 +00:00
continue ;
}
2022-07-28 13:28:43 +02:00
2024-12-16 19:05:24 +01:00
if ( rule - > bFloating ! = - 1 ) {
if ( hasFloating ! = rule - > bFloating )
2024-02-18 15:00:34 +00:00
continue ;
}
2022-05-14 15:56:01 +02:00
2024-12-16 19:05:24 +01:00
if ( rule - > bFullscreen ! = - 1 ) {
if ( hasFullscreen ! = rule - > bFullscreen )
2024-02-18 15:00:34 +00:00
continue ;
}
2022-05-14 15:56:01 +02:00
2024-12-16 19:05:24 +01:00
if ( rule - > bPinned ! = - 1 ) {
if ( pWindow - > m_bPinned ! = rule - > bPinned )
2024-02-18 15:00:34 +00:00
continue ;
}
2022-09-25 20:07:48 +02:00
2024-12-16 19:05:24 +01:00
if ( rule - > bFocus ! = - 1 ) {
if ( rule - > bFocus ! = ( g_pCompositor - > m_pLastWindow . lock ( ) = = pWindow ) )
2024-02-18 15:00:34 +00:00
continue ;
}
2022-05-14 15:56:01 +02:00
2024-12-16 19:05:24 +01:00
if ( ! rule - > szFullscreenState . empty ( ) ) {
const auto ARGS = CVarList ( rule - > szFullscreenState , 2 , ' ' ) ;
2024-08-24 04:42:14 +09:00
//
std : : optional < eFullscreenMode > internalMode , clientMode ;
if ( ARGS [ 0 ] = = " * " )
2024-08-24 15:24:55 +02:00
internalMode = std : : nullopt ;
2024-08-24 04:42:14 +09:00
else if ( isNumber ( ARGS [ 0 ] ) )
internalMode = ( eFullscreenMode ) std : : stoi ( ARGS [ 0 ] ) ;
else
throw std : : runtime_error ( " szFullscreenState internal mode not valid " ) ;
if ( ARGS [ 1 ] = = " * " )
2024-08-24 15:24:55 +02:00
clientMode = std : : nullopt ;
2024-08-24 04:42:14 +09:00
else if ( isNumber ( ARGS [ 1 ] ) )
clientMode = ( eFullscreenMode ) std : : stoi ( ARGS [ 1 ] ) ;
else
throw std : : runtime_error ( " szFullscreenState client mode not valid " ) ;
if ( internalMode . has_value ( ) & & pWindow - > m_sFullscreenState . internal ! = internalMode )
continue ;
if ( clientMode . has_value ( ) & & pWindow - > m_sFullscreenState . client ! = clientMode )
continue ;
}
2024-12-16 19:05:24 +01:00
if ( ! rule - > szOnWorkspace . empty ( ) ) {
2024-04-02 20:32:39 +01:00
const auto PWORKSPACE = pWindow - > m_pWorkspace ;
2024-12-16 19:05:24 +01:00
if ( ! PWORKSPACE | | ! PWORKSPACE - > matchesStaticSelector ( rule - > szOnWorkspace ) )
2024-02-18 15:00:34 +00:00
continue ;
}
2022-05-14 15:56:01 +02:00
2025-02-02 22:25:29 +03:00
if ( ! rule - > szContentType . empty ( ) ) {
try {
const auto contentType = NContentType : : fromString ( rule - > szContentType ) ;
if ( pWindow - > getContentType ( ) ! = contentType )
continue ;
} catch ( std : : exception & e ) { Debug : : log ( ERR , " Rule \" content:{} \" failed with: {} " , rule - > szContentType , e . what ( ) ) ; }
}
2024-12-16 19:05:24 +01:00
if ( ! rule - > szWorkspace . empty ( ) ) {
2024-04-02 20:32:39 +01:00
const auto PWORKSPACE = pWindow - > m_pWorkspace ;
2022-07-28 13:28:43 +02:00
2024-02-18 15:00:34 +00:00
if ( ! PWORKSPACE )
continue ;
2022-05-14 15:56:01 +02:00
2024-12-16 19:05:24 +01:00
if ( rule - > szWorkspace . starts_with ( " name: " ) ) {
if ( PWORKSPACE - > m_szName ! = rule - > szWorkspace . substr ( 5 ) )
2024-02-18 15:00:34 +00:00
continue ;
} else {
// number
2024-12-16 19:05:24 +01:00
if ( ! isNumber ( rule - > szWorkspace ) )
2024-02-18 15:00:34 +00:00
throw std : : runtime_error ( " szWorkspace not name: or number " ) ;
2022-08-07 19:28:46 +02:00
2024-12-16 19:05:24 +01:00
const int64_t ID = std : : stoll ( rule - > szWorkspace ) ;
2023-09-06 12:58:01 +02:00
2024-02-18 15:00:34 +00:00
if ( PWORKSPACE - > m_iID ! = ID )
continue ;
}
}
2024-12-16 19:05:24 +01:00
if ( ! rule - > szTag . empty ( ) & & ! tags . isTagged ( rule - > szTag ) )
continue ;
2024-12-21 23:07:23 +00:00
if ( ! rule - > szClass . empty ( ) & & ! rule - > rClass . passes ( pWindow - > m_szClass ) )
2024-12-16 19:21:44 +01:00
continue ;
2024-12-16 19:05:24 +01:00
2024-12-21 23:07:23 +00:00
if ( ! rule - > szTitle . empty ( ) & & ! rule - > rTitle . passes ( pWindow - > m_szTitle ) )
2024-12-16 19:21:44 +01:00
continue ;
2024-12-16 19:05:24 +01:00
2024-12-21 23:07:23 +00:00
if ( ! rule - > szInitialTitle . empty ( ) & & ! rule - > rInitialTitle . passes ( pWindow - > m_szInitialTitle ) )
2024-12-16 19:21:44 +01:00
continue ;
2024-12-16 19:05:24 +01:00
2024-12-21 23:07:23 +00:00
if ( ! rule - > szInitialClass . empty ( ) & & ! rule - > rInitialClass . passes ( pWindow - > m_szInitialClass ) )
2024-12-16 19:21:44 +01:00
continue ;
2024-12-16 19:05:24 +01:00
2024-02-18 15:00:34 +00:00
} catch ( std : : exception & e ) {
2024-12-16 19:05:24 +01:00
Debug : : log ( ERR , " Regex error at {} ({}) " , rule - > szValue , e . what ( ) ) ;
2024-02-18 15:00:34 +00:00
continue ;
2023-09-06 12:58:01 +02:00
}
2022-08-07 19:28:46 +02:00
}
2022-05-14 15:56:01 +02:00
2024-02-18 15:00:34 +00:00
// applies. Read the rule and behave accordingly
2024-12-16 19:05:24 +01:00
Debug : : log ( LOG , " Window rule {} -> {} matched {} " , rule - > szRule , rule - > szValue , pWindow ) ;
2022-08-07 19:28:46 +02:00
2024-12-16 19:05:24 +01:00
returns . emplace_back ( rule ) ;
2022-07-28 13:28:43 +02:00
2024-05-29 05:37:24 +08:00
// apply tag with local tags
2024-12-16 19:05:24 +01:00
if ( rule - > ruleType = = CWindowRule : : RULE_TAG ) {
CVarList vars { rule - > szRule , 0 , ' s ' , true } ;
2024-05-29 05:37:24 +08:00
if ( vars . size ( ) = = 2 & & vars [ 0 ] = = " tag " )
tags . applyTag ( vars [ 1 ] , true ) ;
}
2024-02-18 15:00:34 +00:00
if ( dynamic )
continue ;
2022-08-07 19:28:46 +02:00
2024-12-16 19:05:24 +01:00
if ( rule - > szRule = = " float " )
2024-02-18 15:00:34 +00:00
hasFloating = true ;
2024-12-16 19:05:24 +01:00
else if ( rule - > szRule = = " fullscreen " )
2024-02-18 15:00:34 +00:00
hasFullscreen = true ;
2022-08-07 19:28:46 +02:00
}
2024-02-18 15:00:34 +00:00
std : : vector < uint64_t > PIDs = { ( uint64_t ) pWindow - > getPID ( ) } ;
while ( getPPIDof ( PIDs . back ( ) ) > 10 )
PIDs . push_back ( getPPIDof ( PIDs . back ( ) ) ) ;
2022-07-20 22:33:43 +02:00
2024-02-18 15:00:34 +00:00
bool anyExecFound = false ;
2022-07-20 22:45:06 +02:00
2024-08-26 20:24:30 +02:00
for ( auto const & er : execRequestedRules ) {
2024-02-18 15:00:34 +00:00
if ( std : : ranges : : any_of ( PIDs , [ & ] ( const auto & pid ) { return pid = = er . iPid ; } ) ) {
2024-12-16 19:05:24 +01:00
returns . emplace_back ( makeShared < CWindowRule > ( er . szRule , " " , false , true ) ) ;
2024-02-18 15:00:34 +00:00
anyExecFound = true ;
2022-07-20 22:33:43 +02:00
}
}
2022-03-19 17:48:18 +01:00
2024-03-02 18:53:11 +00:00
if ( anyExecFound & & ! shadowExec ) // remove exec rules to unclog searches in the future, why have the garbage here.
2024-12-16 19:05:24 +01:00
std : : erase_if ( execRequestedRules , [ & ] ( const SExecRequestedRule & other ) { return std : : ranges : : any_of ( PIDs , [ & ] ( const auto & pid ) { return pid = = other . iPid ; } ) ; } ) ;
2022-09-19 19:04:48 +01:00
2024-02-18 15:00:34 +00:00
return returns ;
}
2022-03-19 17:48:18 +01:00
2024-12-16 19:05:24 +01:00
std : : vector < SP < CLayerRule > > CConfigManager : : getMatchingRules ( PHLLS pLS ) {
std : : vector < SP < CLayerRule > > returns ;
2022-09-21 17:41:19 +01:00
2024-02-18 15:00:34 +00:00
if ( ! pLS - > layerSurface | | pLS - > fadingOut )
return returns ;
2022-04-21 15:50:52 +02:00
2024-12-16 15:58:19 +00:00
for ( auto const & lr : m_vLayerRules ) {
2024-12-16 19:05:24 +01:00
if ( lr - > targetNamespace . starts_with ( " address:0x " ) ) {
if ( std : : format ( " address:0x{:x} " , ( uintptr_t ) pLS . get ( ) ) ! = lr - > targetNamespace )
2024-02-18 15:00:34 +00:00
continue ;
2024-12-21 23:07:23 +00:00
} else if ( ! lr - > targetNamespaceRegex . passes ( pLS - > layerSurface - > layerNamespace ) )
2024-12-16 19:21:44 +01:00
continue ;
2022-05-12 12:41:28 +02:00
2024-02-18 15:00:34 +00:00
// hit
2024-12-16 19:05:24 +01:00
returns . emplace_back ( lr ) ;
2022-07-08 09:27:17 +02:00
}
2022-04-21 17:06:43 +02:00
2024-05-09 21:47:21 +01:00
if ( shouldBlurLS ( pLS - > layerSurface - > layerNamespace ) )
2024-12-16 19:05:24 +01:00
returns . emplace_back ( makeShared < CLayerRule > ( pLS - > layerSurface - > layerNamespace , " blur " ) ) ;
2022-09-06 11:57:11 +02:00
2024-02-18 15:00:34 +00:00
return returns ;
2023-01-25 15:34:13 +00:00
}
2024-02-18 15:00:34 +00:00
void CConfigManager : : dispatchExecOnce ( ) {
if ( firstExecDispatched | | isFirstLaunch )
2022-09-06 11:57:11 +02:00
return ;
2024-02-18 15:00:34 +00:00
// update dbus env
2024-07-21 13:09:54 +02:00
if ( g_pCompositor - > m_pAqBackend - > hasSession ( ) )
2024-02-18 15:00:34 +00:00
handleRawExec ( " " ,
# ifdef USES_SYSTEMD
2024-06-23 12:43:17 +05:30
" systemctl --user import-environment DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS && hash "
2024-02-18 15:00:34 +00:00
" dbus-update-activation-environment 2>/dev/null && "
# endif
2024-06-23 12:43:17 +05:30
" dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS " ) ;
2022-11-03 19:52:43 +00:00
2024-02-18 15:00:34 +00:00
firstExecDispatched = true ;
2024-07-25 15:29:39 +02:00
isLaunchingExecOnce = true ;
2023-09-12 11:54:05 +00:00
2024-08-26 17:25:39 +02:00
for ( auto const & c : firstExecRequests ) {
2025-01-11 23:58:05 +08:00
c . withRules ? handleExec ( " " , c . exec ) : handleRawExec ( " " , c . exec ) ;
2024-02-18 15:00:34 +00:00
}
2023-09-12 11:54:05 +00:00
2024-02-18 15:00:34 +00:00
firstExecRequests . clear ( ) ; // free some kb of memory :P
2024-07-25 15:29:39 +02:00
isLaunchingExecOnce = false ;
2022-05-16 10:09:20 +02:00
2024-02-18 15:00:34 +00:00
// set input, fixes some certain issues
g_pInputManager - > setKeyboardLayout ( ) ;
g_pInputManager - > setPointerConfigs ( ) ;
g_pInputManager - > setTouchDeviceConfigs ( ) ;
g_pInputManager - > setTabletConfigs ( ) ;
2023-09-28 21:48:33 +01:00
2024-02-18 15:00:34 +00:00
// check for user's possible errors with their setup and notify them if needed
g_pCompositor - > performUserChecks ( ) ;
}
2023-09-12 11:54:05 +00:00
2024-09-07 14:54:33 -05:00
void CConfigManager : : dispatchExecShutdown ( ) {
if ( finalExecRequests . empty ( ) ) {
g_pCompositor - > m_bFinalRequests = false ;
return ;
}
g_pCompositor - > m_bFinalRequests = true ;
for ( auto const & c : finalExecRequests ) {
handleExecShutdown ( " " , c ) ;
}
finalExecRequests . clear ( ) ;
// Actually exit now
handleExecShutdown ( " " , " hyprctl dispatch exit " ) ;
}
2024-02-18 15:00:34 +00:00
void CConfigManager : : performMonitorReload ( ) {
2023-09-12 11:54:05 +00:00
2024-02-18 15:00:34 +00:00
bool overAgain = false ;
2023-09-12 11:54:05 +00:00
2024-08-26 20:24:30 +02:00
for ( auto const & m : g_pCompositor - > m_vRealMonitors ) {
2024-02-18 15:00:34 +00:00
if ( ! m - > output | | m - > isUnsafeFallback )
continue ;
2022-05-16 10:09:20 +02:00
2024-09-26 11:10:53 +01:00
auto rule = getMonitorRuleFor ( m ) ;
2023-09-28 21:48:33 +01:00
2024-12-28 07:32:04 -06:00
if ( ! m - > applyMonitorRule ( & rule ) ) {
2024-02-18 15:00:34 +00:00
overAgain = true ;
break ;
2022-05-16 10:09:20 +02:00
}
2024-02-18 15:00:34 +00:00
// ensure mirror
m - > setMirror ( rule . mirrorOf ) ;
g_pHyprRenderer - > arrangeLayersForMonitor ( m - > ID ) ;
2022-05-16 10:09:20 +02:00
}
2024-02-18 15:00:34 +00:00
if ( overAgain )
performMonitorReload ( ) ;
m_bWantsMonitorReload = false ;
EMIT_HOOK_EVENT ( " monitorLayoutChanged " , nullptr ) ;
2022-09-12 21:05:52 +02:00
}
2024-02-18 15:00:34 +00:00
void * const * CConfigManager : : getConfigValuePtr ( const std : : string & val ) {
const auto VAL = m_pConfig - > getConfigValuePtr ( val . c_str ( ) ) ;
if ( ! VAL )
return nullptr ;
return VAL - > getDataStaticPtr ( ) ;
}
2023-03-05 13:12:01 +00:00
2024-02-18 15:00:34 +00:00
Hyprlang : : CConfigValue * CConfigManager : : getHyprlangConfigValuePtr ( const std : : string & name , const std : : string & specialCat ) {
if ( ! specialCat . empty ( ) )
return m_pConfig - > getSpecialConfigValuePtr ( specialCat . c_str ( ) , name . c_str ( ) , nullptr ) ;
2023-03-05 13:12:01 +00:00
2024-02-18 15:00:34 +00:00
return m_pConfig - > getConfigValuePtr ( name . c_str ( ) ) ;
}
2023-03-05 13:12:01 +00:00
2024-02-18 15:00:34 +00:00
bool CConfigManager : : deviceConfigExists ( const std : : string & dev ) {
auto copy = dev ;
std : : replace ( copy . begin ( ) , copy . end ( ) , ' ' , ' - ' ) ;
2023-03-05 13:15:12 +00:00
2024-02-18 15:00:34 +00:00
return m_pConfig - > specialCategoryExistsForKey ( " device " , copy . c_str ( ) ) ;
2023-03-05 13:12:01 +00:00
}
2024-02-18 15:00:34 +00:00
bool CConfigManager : : shouldBlurLS ( const std : : string & ns ) {
2024-08-26 17:25:39 +02:00
for ( auto const & bls : m_dBlurLSNamespaces ) {
2024-02-18 15:00:34 +00:00
if ( bls = = ns ) {
return true ;
}
2023-05-01 07:10:53 -07:00
}
2024-02-18 15:00:34 +00:00
return false ;
2023-05-01 07:10:53 -07:00
}
2024-02-18 15:00:34 +00:00
void CConfigManager : : ensureMonitorStatus ( ) {
2024-08-26 20:24:30 +02:00
for ( auto const & rm : g_pCompositor - > m_vRealMonitors ) {
2024-02-18 15:00:34 +00:00
if ( ! rm - > output | | rm - > isUnsafeFallback )
continue ;
2022-04-21 16:56:27 +02:00
2024-09-26 11:10:53 +01:00
auto rule = getMonitorRuleFor ( rm ) ;
2022-11-28 19:05:50 +00:00
2024-02-18 15:00:34 +00:00
if ( rule . disabled = = rm - > m_bEnabled )
2024-12-28 07:32:04 -06:00
rm - > applyMonitorRule ( & rule ) ;
2022-11-28 19:05:50 +00:00
}
2024-02-18 15:00:34 +00:00
}
2024-10-19 23:03:29 +01:00
void CConfigManager : : ensureVRR ( PHLMONITOR pMonitor ) {
2024-03-03 18:39:20 +00:00
static auto PVRR = reinterpret_cast < Hyprlang : : INT * const * > ( getConfigValuePtr ( " misc:vrr " ) ) ;
2022-04-21 16:56:27 +02:00
2024-10-19 23:03:29 +01:00
static auto ensureVRRForDisplay = [ & ] ( PHLMONITOR m ) - > void {
2024-02-18 15:00:34 +00:00
if ( ! m - > output | | m - > createdByUser )
return ;
2022-05-25 17:42:38 +02:00
2024-02-18 15:00:34 +00:00
const auto USEVRR = m - > activeMonitorRule . vrr . has_value ( ) ? m - > activeMonitorRule . vrr . value ( ) : * * PVRR ;
2022-05-26 21:23:13 +02:00
2024-02-18 15:00:34 +00:00
if ( USEVRR = = 0 ) {
if ( m - > vrrActive ) {
2024-08-06 14:52:19 +01:00
m - > output - > state - > resetExplicitFences ( ) ;
2024-07-21 13:09:54 +02:00
m - > output - > state - > setAdaptiveSync ( false ) ;
2022-05-26 21:23:13 +02:00
2024-02-18 15:00:34 +00:00
if ( ! m - > state . commit ( ) )
Debug : : log ( ERR , " Couldn't commit output {} in ensureVRR -> false " , m - > output - > name ) ;
2023-04-07 21:15:11 +02:00
}
2024-02-18 15:00:34 +00:00
m - > vrrActive = false ;
return ;
} else if ( USEVRR = = 1 ) {
if ( ! m - > vrrActive ) {
2024-08-06 14:52:19 +01:00
m - > output - > state - > resetExplicitFences ( ) ;
2024-07-21 13:09:54 +02:00
m - > output - > state - > setAdaptiveSync ( true ) ;
2023-04-04 22:13:31 +01:00
2024-02-18 15:00:34 +00:00
if ( ! m - > state . test ( ) ) {
Debug : : log ( LOG , " Pending output {} does not accept VRR. " , m - > output - > name ) ;
2024-07-21 13:09:54 +02:00
m - > output - > state - > setAdaptiveSync ( false ) ;
2024-02-18 15:00:34 +00:00
}
2022-04-21 16:56:27 +02:00
2024-02-18 15:00:34 +00:00
if ( ! m - > state . commit ( ) )
Debug : : log ( ERR , " Couldn't commit output {} in ensureVRR -> true " , m - > output - > name ) ;
}
m - > vrrActive = true ;
return ;
} else if ( USEVRR = = 2 ) {
2024-04-02 20:32:39 +01:00
const auto PWORKSPACE = m - > activeWorkspace ;
2022-05-16 09:38:42 +02:00
2024-02-18 15:00:34 +00:00
if ( ! PWORKSPACE )
return ; // ???
2023-12-20 13:07:12 +01:00
2024-07-31 17:55:52 +00:00
const auto WORKSPACEFULL = PWORKSPACE - > m_bHasFullscreenWindow & & ( PWORKSPACE - > m_efFullscreenMode & FSMODE_FULLSCREEN ) ;
2022-05-16 09:38:42 +02:00
2024-07-21 13:09:54 +02:00
if ( WORKSPACEFULL ) {
2024-11-01 07:30:26 -05:00
/* fullscreen */
m - > vrrActive = true ;
2024-08-06 14:52:19 +01:00
m - > output - > state - > resetExplicitFences ( ) ;
2024-07-21 13:09:54 +02:00
m - > output - > state - > setAdaptiveSync ( true ) ;
2022-05-16 09:38:42 +02:00
2024-02-18 15:00:34 +00:00
if ( ! m - > state . test ( ) ) {
Debug : : log ( LOG , " Pending output {} does not accept VRR. " , m - > output - > name ) ;
2024-07-21 13:09:54 +02:00
m - > output - > state - > setAdaptiveSync ( false ) ;
2023-03-05 14:54:26 +00:00
}
2024-02-18 15:00:34 +00:00
if ( ! m - > state . commit ( ) )
Debug : : log ( ERR , " Couldn't commit output {} in ensureVRR -> true " , m - > output - > name ) ;
2024-07-21 13:09:54 +02:00
} else if ( ! WORKSPACEFULL ) {
2024-11-01 07:30:26 -05:00
m - > vrrActive = false ;
2024-08-06 14:52:19 +01:00
m - > output - > state - > resetExplicitFences ( ) ;
2024-07-21 13:09:54 +02:00
m - > output - > state - > setAdaptiveSync ( false ) ;
2024-02-18 15:00:34 +00:00
if ( ! m - > state . commit ( ) )
Debug : : log ( ERR , " Couldn't commit output {} in ensureVRR -> false " , m - > output - > name ) ;
2023-03-05 14:54:26 +00:00
}
}
2024-02-18 15:00:34 +00:00
} ;
2023-03-05 14:54:26 +00:00
2024-02-18 15:00:34 +00:00
if ( pMonitor ) {
ensureVRRForDisplay ( pMonitor ) ;
return ;
}
2023-12-20 13:07:12 +01:00
2024-08-26 20:24:30 +02:00
for ( auto const & m : g_pCompositor - > m_vMonitors ) {
2024-10-19 23:03:29 +01:00
ensureVRRForDisplay ( m ) ;
2022-05-16 09:38:42 +02:00
}
}
2025-01-07 17:55:14 +00:00
SP < SAnimationPropertyConfig > CConfigManager : : getAnimationPropertyConfig ( const std : : string & name ) {
return m_AnimationTree . getConfig ( name ) ;
2024-02-18 15:00:34 +00:00
}
2022-03-17 15:53:45 +01:00
2024-02-18 15:00:34 +00:00
void CConfigManager : : addParseError ( const std : : string & err ) {
2024-12-03 18:58:24 +00:00
g_pHyprError - > queueCreate ( err + " \n Hyprland may not work correctly. " , CHyprColor ( 1.0 , 50.0 / 255.0 , 50.0 / 255.0 , 1.0 ) ) ;
2024-02-18 15:00:34 +00:00
}
2024-10-19 23:03:29 +01:00
PHLMONITOR CConfigManager : : getBoundMonitorForWS ( const std : : string & wsname ) {
2024-02-18 15:00:34 +00:00
auto monitor = getBoundMonitorStringForWS ( wsname ) ;
if ( monitor . substr ( 0 , 5 ) = = " desc: " )
return g_pCompositor - > getMonitorFromDesc ( monitor . substr ( 5 ) ) ;
else
return g_pCompositor - > getMonitorFromName ( monitor ) ;
}
std : : string CConfigManager : : getBoundMonitorStringForWS ( const std : : string & wsname ) {
2024-12-16 15:58:19 +00:00
for ( auto const & wr : m_vWorkspaceRules ) {
2024-02-18 15:00:34 +00:00
const auto WSNAME = wr . workspaceName . starts_with ( " name: " ) ? wr . workspaceName . substr ( 5 ) : wr . workspaceName ;
2022-10-25 14:32:25 +01:00
2024-03-19 20:56:20 +00:00
if ( WSNAME = = wsname )
2024-02-18 15:00:34 +00:00
return wr . monitor ;
2022-10-25 14:32:25 +01:00
}
2024-02-18 15:00:34 +00:00
return " " ;
}
2022-03-17 15:53:45 +01:00
2024-12-16 15:58:19 +00:00
const std : : vector < SWorkspaceRule > & CConfigManager : : getAllWorkspaceRules ( ) {
return m_vWorkspaceRules ;
2024-02-18 15:00:34 +00:00
}
2022-03-17 15:53:45 +01:00
2024-02-18 15:00:34 +00:00
void CConfigManager : : addExecRule ( const SExecRequestedRule & rule ) {
execRequestedRules . push_back ( rule ) ;
}
2022-04-19 13:42:26 -03:00
2024-02-18 15:00:34 +00:00
void CConfigManager : : handlePluginLoads ( ) {
2025-01-23 21:55:41 +01:00
if ( ! g_pPluginSystem )
2022-03-17 15:53:45 +01:00
return ;
2024-02-18 15:00:34 +00:00
bool pluginsChanged = false ;
auto failedPlugins = g_pPluginSystem - > updateConfigPlugins ( m_vDeclaredPlugins , pluginsChanged ) ;
2022-08-27 23:12:01 +02:00
2024-02-18 15:00:34 +00:00
if ( ! failedPlugins . empty ( ) ) {
std : : stringstream error ;
error < < " Failed to load the following plugins: " ;
2022-08-27 23:12:01 +02:00
2024-12-07 18:51:18 +01:00
for ( const auto & path : failedPlugins ) {
2024-02-18 15:00:34 +00:00
error < < " \n " < < path ;
}
2022-09-25 20:07:48 +02:00
2024-12-03 18:58:24 +00:00
g_pHyprError - > queueCreate ( error . str ( ) , CHyprColor ( 1.0 , 50.0 / 255.0 , 50.0 / 255.0 , 1.0 ) ) ;
2022-03-17 15:53:45 +01:00
}
2024-02-18 15:00:34 +00:00
if ( pluginsChanged ) {
g_pHyprError - > destroy ( ) ;
2025-01-19 15:39:19 +01:00
reload ( ) ;
2024-02-18 15:00:34 +00:00
}
}
2022-03-17 15:53:45 +01:00
2025-01-07 17:55:14 +00:00
const std : : unordered_map < std : : string , SP < SAnimationPropertyConfig > > & CConfigManager : : getAnimationConfig ( ) {
return m_AnimationTree . getFullConfig ( ) ;
2024-02-18 15:00:34 +00:00
}
2022-03-17 15:53:45 +01:00
2024-02-18 15:00:34 +00:00
void CConfigManager : : addPluginConfigVar ( HANDLE handle , const std : : string & name , const Hyprlang : : CConfigValue & value ) {
if ( ! name . starts_with ( " plugin: " ) )
return ;
2022-09-25 20:07:48 +02:00
2024-02-18 15:00:34 +00:00
std : : string field = name . substr ( 7 ) ;
2022-03-17 16:56:33 +01:00
2024-02-18 15:00:34 +00:00
m_pConfig - > addSpecialConfigValue ( " plugin " , field . c_str ( ) , value ) ;
pluginVariables . push_back ( { handle , field } ) ;
}
2023-07-07 13:19:35 -04:00
2024-02-18 15:00:34 +00:00
void CConfigManager : : addPluginKeyword ( HANDLE handle , const std : : string & name , Hyprlang : : PCONFIGHANDLERFUNC fn , Hyprlang : : SHandlerOptions opts ) {
pluginKeywords . emplace_back ( SPluginKeyword { handle , name , fn } ) ;
m_pConfig - > registerHandler ( fn , name . c_str ( ) , opts ) ;
}
2023-12-04 01:35:24 +00:00
2024-02-18 15:00:34 +00:00
void CConfigManager : : removePluginConfig ( HANDLE handle ) {
2024-08-26 17:25:39 +02:00
for ( auto const & k : pluginKeywords ) {
2024-02-18 15:00:34 +00:00
if ( k . handle ! = handle )
continue ;
2022-05-16 10:09:20 +02:00
2024-02-18 15:00:34 +00:00
m_pConfig - > unregisterHandler ( k . name . c_str ( ) ) ;
2023-07-07 13:19:35 -04:00
}
2022-09-25 20:07:48 +02:00
2024-02-18 15:00:34 +00:00
std : : erase_if ( pluginKeywords , [ & ] ( const auto & other ) { return other . handle = = handle ; } ) ;
2024-08-26 20:24:30 +02:00
for ( auto const & [ h , n ] : pluginVariables ) {
2024-02-18 15:00:34 +00:00
if ( h ! = handle )
continue ;
2022-04-08 22:07:40 +02:00
2024-02-18 15:00:34 +00:00
m_pConfig - > removeSpecialConfigValue ( " plugin " , n . c_str ( ) ) ;
}
std : : erase_if ( pluginVariables , [ handle ] ( const auto & other ) { return other . handle = = handle ; } ) ;
}
2022-04-08 22:07:40 +02:00
2024-02-18 15:00:34 +00:00
std : : string CConfigManager : : getDefaultWorkspaceFor ( const std : : string & name ) {
2024-12-16 15:58:19 +00:00
for ( auto other = m_vWorkspaceRules . begin ( ) ; other ! = m_vWorkspaceRules . end ( ) ; + + other ) {
2024-02-18 15:00:34 +00:00
if ( other - > isDefault ) {
if ( other - > monitor = = name )
return other - > workspaceString ;
if ( other - > monitor . substr ( 0 , 5 ) = = " desc: " ) {
2024-08-26 17:25:39 +02:00
auto const monitor = g_pCompositor - > getMonitorFromDesc ( other - > monitor . substr ( 5 ) ) ;
2024-02-18 15:00:34 +00:00
if ( monitor & & monitor - > szName = = name )
return other - > workspaceString ;
}
2022-04-08 22:07:40 +02:00
}
2022-03-17 15:53:45 +01:00
}
2024-02-18 15:00:34 +00:00
return " " ;
}
2022-03-17 15:53:45 +01:00
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleRawExec ( const std : : string & command , const std : : string & args ) {
if ( isFirstLaunch ) {
2025-01-11 23:58:05 +08:00
firstExecRequests . push_back ( { args , false } ) ;
return { } ;
}
g_pKeybindManager - > spawnRaw ( args ) ;
return { } ;
}
std : : optional < std : : string > CConfigManager : : handleExec ( const std : : string & command , const std : : string & args ) {
if ( isFirstLaunch ) {
firstExecRequests . push_back ( { args , true } ) ;
2024-02-18 15:00:34 +00:00
return { } ;
}
2022-03-17 15:53:45 +01:00
2024-02-18 15:00:34 +00:00
g_pKeybindManager - > spawn ( args ) ;
return { } ;
}
2022-03-17 15:53:45 +01:00
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleExecOnce ( const std : : string & command , const std : : string & args ) {
if ( isFirstLaunch )
2025-01-11 23:58:05 +08:00
firstExecRequests . push_back ( { args , true } ) ;
return { } ;
}
std : : optional < std : : string > CConfigManager : : handleExecRawOnce ( const std : : string & command , const std : : string & args ) {
if ( isFirstLaunch )
firstExecRequests . push_back ( { args , false } ) ;
2022-03-17 15:53:45 +01:00
2024-02-18 15:00:34 +00:00
return { } ;
}
2022-03-17 15:53:45 +01:00
2024-09-07 14:54:33 -05:00
std : : optional < std : : string > CConfigManager : : handleExecShutdown ( const std : : string & command , const std : : string & args ) {
if ( g_pCompositor - > m_bFinalRequests ) {
g_pKeybindManager - > spawn ( args ) ;
return { } ;
}
finalExecRequests . push_back ( args ) ;
return { } ;
}
2024-02-18 15:00:34 +00:00
static bool parseModeLine ( const std : : string & modeline , drmModeModeInfo & mode ) {
auto args = CVarList ( modeline , 0 , ' s ' ) ;
2022-03-19 21:48:24 +01:00
2024-02-18 15:00:34 +00:00
auto keyword = args [ 0 ] ;
std : : transform ( keyword . begin ( ) , keyword . end ( ) , keyword . begin ( ) , : : tolower ) ;
2023-12-30 14:18:53 +00:00
2024-02-18 15:00:34 +00:00
if ( keyword ! = " modeline " )
return false ;
2022-03-20 11:14:24 +01:00
2024-02-18 15:00:34 +00:00
if ( args . size ( ) < 10 ) {
Debug : : log ( ERR , " modeline parse error: expected at least 9 arguments, got {} " , args . size ( ) - 1 ) ;
return false ;
2022-07-19 19:26:53 +02:00
}
2022-03-24 21:05:34 +01:00
2024-02-18 15:00:34 +00:00
int argno = 1 ;
2022-12-01 13:36:07 +00:00
2024-02-18 15:00:34 +00:00
mode . type = DRM_MODE_TYPE_USERDEF ;
mode . clock = std : : stof ( args [ argno + + ] ) * 1000 ;
mode . hdisplay = std : : stoi ( args [ argno + + ] ) ;
mode . hsync_start = std : : stoi ( args [ argno + + ] ) ;
mode . hsync_end = std : : stoi ( args [ argno + + ] ) ;
mode . htotal = std : : stoi ( args [ argno + + ] ) ;
mode . vdisplay = std : : stoi ( args [ argno + + ] ) ;
mode . vsync_start = std : : stoi ( args [ argno + + ] ) ;
mode . vsync_end = std : : stoi ( args [ argno + + ] ) ;
mode . vtotal = std : : stoi ( args [ argno + + ] ) ;
mode . vrefresh = mode . clock * 1000.0 * 1000.0 / mode . htotal / mode . vtotal ;
2022-04-19 19:01:23 +02:00
2024-02-18 15:00:34 +00:00
// clang-format off
static std : : unordered_map < std : : string , uint32_t > flagsmap = {
{ " +hsync " , DRM_MODE_FLAG_PHSYNC } ,
{ " -hsync " , DRM_MODE_FLAG_NHSYNC } ,
{ " +vsync " , DRM_MODE_FLAG_PVSYNC } ,
{ " -vsync " , DRM_MODE_FLAG_NVSYNC } ,
{ " Interlace " , DRM_MODE_FLAG_INTERLACE } ,
} ;
// clang-format on
2022-05-26 21:23:13 +02:00
2024-02-18 15:00:34 +00:00
for ( ; argno < static_cast < int > ( args . size ( ) ) ; argno + + ) {
auto key = args [ argno ] ;
std : : transform ( key . begin ( ) , key . end ( ) , key . begin ( ) , : : tolower ) ;
2023-11-26 17:59:49 +00:00
2024-02-18 15:00:34 +00:00
auto it = flagsmap . find ( key ) ;
2023-07-01 16:30:36 +02:00
2024-02-18 15:00:34 +00:00
if ( it ! = flagsmap . end ( ) )
mode . flags | = it - > second ;
else
2024-11-12 02:53:55 +02:00
Debug : : log ( ERR , " Invalid flag {} in modeline " , key ) ;
2023-06-26 11:03:51 +00:00
}
2023-07-01 16:30:36 +02:00
2024-02-18 15:00:34 +00:00
snprintf ( mode . name , sizeof ( mode . name ) , " %dx%d@%d " , mode . hdisplay , mode . vdisplay , mode . vrefresh / 1000 ) ;
2023-07-01 16:30:36 +02:00
2024-02-18 15:00:34 +00:00
return true ;
}
2022-07-16 15:57:31 +02:00
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleMonitor ( const std : : string & command , const std : : string & args ) {
2023-04-04 14:49:58 +01:00
2024-02-18 15:00:34 +00:00
// get the monitor config
SMonitorRule newrule ;
2023-03-24 19:37:37 +00:00
2024-02-18 15:00:34 +00:00
const auto ARGS = CVarList ( args ) ;
2022-08-01 13:12:50 +02:00
2024-02-18 15:00:34 +00:00
newrule . name = ARGS [ 0 ] ;
2023-08-01 15:47:56 +02:00
2024-02-18 15:00:34 +00:00
if ( ARGS [ 1 ] = = " disable " | | ARGS [ 1 ] = = " disabled " | | ARGS [ 1 ] = = " addreserved " | | ARGS [ 1 ] = = " transform " ) {
if ( ARGS [ 1 ] = = " disable " | | ARGS [ 1 ] = = " disabled " )
newrule . disabled = true ;
else if ( ARGS [ 1 ] = = " transform " ) {
const auto TSF = std : : stoi ( ARGS [ 2 ] ) ;
if ( std : : clamp ( TSF , 0 , 7 ) ! = TSF ) {
2024-11-12 02:53:55 +02:00
Debug : : log ( ERR , " Invalid transform {} in monitor " , TSF ) ;
2024-02-18 15:00:34 +00:00
return " invalid transform " ;
}
2022-09-25 20:07:48 +02:00
2024-02-18 15:00:34 +00:00
const auto TRANSFORM = ( wl_output_transform ) TSF ;
2023-05-01 07:10:53 -07:00
2024-02-18 15:00:34 +00:00
// overwrite if exists
2024-12-16 15:58:19 +00:00
for ( auto & r : m_vMonitorRules ) {
2024-02-18 15:00:34 +00:00
if ( r . name = = newrule . name ) {
r . transform = TRANSFORM ;
return { } ;
}
}
2023-07-10 13:54:06 +02:00
2024-02-18 15:00:34 +00:00
return { } ;
} else if ( ARGS [ 1 ] = = " addreserved " ) {
int top = std : : stoi ( ARGS [ 2 ] ) ;
2022-03-17 15:53:45 +01:00
2024-02-18 15:00:34 +00:00
int bottom = std : : stoi ( ARGS [ 3 ] ) ;
2022-04-08 22:07:40 +02:00
2024-02-18 15:00:34 +00:00
int left = std : : stoi ( ARGS [ 4 ] ) ;
2022-05-16 10:09:20 +02:00
2024-02-18 15:00:34 +00:00
int right = std : : stoi ( ARGS [ 5 ] ) ;
2022-05-16 10:09:20 +02:00
2024-02-18 15:00:34 +00:00
m_mAdditionalReservedAreas [ newrule . name ] = { top , bottom , left , right } ;
return { } ;
} else {
Debug : : log ( ERR , " ConfigManager parseMonitor, curitem bogus??? " ) ;
return " parse error: curitem bogus " ;
2022-05-16 10:09:20 +02:00
}
2022-03-17 15:53:45 +01:00
2024-12-16 15:58:19 +00:00
std : : erase_if ( m_vMonitorRules , [ & ] ( const auto & other ) { return other . name = = newrule . name ; } ) ;
2024-02-18 15:00:34 +00:00
2024-12-16 15:58:19 +00:00
m_vMonitorRules . push_back ( newrule ) ;
2022-05-16 10:09:20 +02:00
2024-02-18 15:00:34 +00:00
return { } ;
2022-03-17 15:53:45 +01:00
}
2024-03-12 15:37:40 +00:00
std : : string error = " " ;
2024-02-18 15:00:34 +00:00
if ( ARGS [ 1 ] . starts_with ( " pref " ) ) {
newrule . resolution = Vector2D ( ) ;
} else if ( ARGS [ 1 ] . starts_with ( " highrr " ) ) {
newrule . resolution = Vector2D ( - 1 , - 1 ) ;
} else if ( ARGS [ 1 ] . starts_with ( " highres " ) ) {
newrule . resolution = Vector2D ( - 1 , - 2 ) ;
} else if ( parseModeLine ( ARGS [ 1 ] , newrule . drmMode ) ) {
newrule . resolution = Vector2D ( newrule . drmMode . hdisplay , newrule . drmMode . vdisplay ) ;
2024-05-29 05:37:24 +08:00
newrule . refreshRate = float ( newrule . drmMode . vrefresh ) / 1000 ;
2024-02-18 15:00:34 +00:00
} else {
2022-03-17 15:53:45 +01:00
2024-03-12 15:37:40 +00:00
if ( ! ARGS [ 1 ] . contains ( " x " ) ) {
error + = " invalid resolution " ;
newrule . resolution = Vector2D ( ) ;
} else {
2025-02-24 00:43:24 +02:00
try {
newrule . resolution . x = stoi ( ARGS [ 1 ] . substr ( 0 , ARGS [ 1 ] . find_first_of ( ' x ' ) ) ) ;
newrule . resolution . y = stoi ( ARGS [ 1 ] . substr ( ARGS [ 1 ] . find_first_of ( ' x ' ) + 1 , ARGS [ 1 ] . find_first_of ( ' @ ' ) ) ) ;
2024-03-12 15:37:40 +00:00
2025-02-24 00:43:24 +02:00
if ( ARGS [ 1 ] . contains ( " @ " ) )
newrule . refreshRate = stof ( ARGS [ 1 ] . substr ( ARGS [ 1 ] . find_first_of ( ' @ ' ) + 1 ) ) ;
} catch ( . . . ) {
error + = " invalid resolution " ;
newrule . resolution = Vector2D ( ) ;
}
2024-03-12 15:37:40 +00:00
}
2024-02-18 15:00:34 +00:00
}
2022-03-17 15:53:45 +01:00
2024-02-18 15:00:34 +00:00
if ( ARGS [ 2 ] . starts_with ( " auto " ) ) {
newrule . offset = Vector2D ( - INT32_MAX , - INT32_MAX ) ;
2024-04-23 00:40:03 +00:00
// If this is the first monitor rule needs to be on the right.
2024-12-16 15:58:19 +00:00
if ( ARGS [ 2 ] = = " auto-right " | | ARGS [ 2 ] = = " auto " | | m_vMonitorRules . empty ( ) )
2024-04-23 00:40:03 +00:00
newrule . autoDir = eAutoDirs : : DIR_AUTO_RIGHT ;
else if ( ARGS [ 2 ] = = " auto-left " )
newrule . autoDir = eAutoDirs : : DIR_AUTO_LEFT ;
else if ( ARGS [ 2 ] = = " auto-up " )
newrule . autoDir = eAutoDirs : : DIR_AUTO_UP ;
else if ( ARGS [ 2 ] = = " auto-down " )
newrule . autoDir = eAutoDirs : : DIR_AUTO_DOWN ;
2024-04-25 14:07:50 -07:00
else {
Debug : : log ( WARN ,
" Invalid auto direction. Valid options are 'auto', "
" 'auto-up', 'auto-down', 'auto-left', and 'auto-right'. " ) ;
error + = " invalid auto direction " ;
}
2024-02-18 15:00:34 +00:00
} else {
2024-03-12 15:37:40 +00:00
if ( ! ARGS [ 2 ] . contains ( " x " ) ) {
error + = " invalid offset " ;
newrule . offset = Vector2D ( - INT32_MAX , - INT32_MAX ) ;
} else {
newrule . offset . x = stoi ( ARGS [ 2 ] . substr ( 0 , ARGS [ 2 ] . find_first_of ( ' x ' ) ) ) ;
newrule . offset . y = stoi ( ARGS [ 2 ] . substr ( ARGS [ 2 ] . find_first_of ( ' x ' ) + 1 ) ) ;
}
2024-02-18 15:00:34 +00:00
}
2022-03-17 15:53:45 +01:00
2024-02-18 15:00:34 +00:00
if ( ARGS [ 3 ] . starts_with ( " auto " ) ) {
newrule . scale = - 1 ;
} else {
2024-03-12 15:37:40 +00:00
if ( ! isNumber ( ARGS [ 3 ] , true ) )
error + = " invalid scale " ;
else {
newrule . scale = stof ( ARGS [ 3 ] ) ;
if ( newrule . scale < 0.25f ) {
error + = " invalid scale " ;
newrule . scale = 1 ;
}
2023-09-06 19:16:46 +02:00
}
2022-06-30 21:38:06 +02:00
}
2024-02-18 15:00:34 +00:00
int argno = 4 ;
2022-06-30 21:26:00 +02:00
2024-02-18 15:00:34 +00:00
while ( ARGS [ argno ] ! = " " ) {
if ( ARGS [ argno ] = = " mirror " ) {
newrule . mirrorOf = ARGS [ argno + 1 ] ;
argno + + ;
} else if ( ARGS [ argno ] = = " bitdepth " ) {
newrule . enable10bit = ARGS [ argno + 1 ] = = " 10 " ;
argno + + ;
} else if ( ARGS [ argno ] = = " transform " ) {
2024-03-12 15:37:40 +00:00
if ( ! isNumber ( ARGS [ argno + 1 ] ) ) {
error = " invalid transform " ;
argno + + ;
continue ;
}
const auto NUM = std : : stoi ( ARGS [ argno + 1 ] ) ;
if ( NUM < 0 | | NUM > 7 ) {
error = " invalid transform " ;
argno + + ;
continue ;
}
2024-02-18 15:00:34 +00:00
newrule . transform = ( wl_output_transform ) std : : stoi ( ARGS [ argno + 1 ] ) ;
argno + + ;
} else if ( ARGS [ argno ] = = " vrr " ) {
2024-03-12 15:37:40 +00:00
if ( ! isNumber ( ARGS [ argno + 1 ] ) ) {
error = " invalid vrr " ;
argno + + ;
continue ;
}
2024-02-18 15:00:34 +00:00
newrule . vrr = std : : stoi ( ARGS [ argno + 1 ] ) ;
argno + + ;
} else if ( ARGS [ argno ] = = " workspace " ) {
2024-06-23 00:52:42 +03:00
const auto & [ id , name ] = getWorkspaceIDNameFromString ( ARGS [ argno + 1 ] ) ;
2022-03-17 15:53:45 +01:00
2024-02-18 15:00:34 +00:00
SWorkspaceRule wsRule ;
wsRule . monitor = newrule . name ;
wsRule . workspaceString = ARGS [ argno + 1 ] ;
2024-06-23 00:52:42 +03:00
wsRule . workspaceId = id ;
2024-02-18 15:00:34 +00:00
wsRule . workspaceName = name ;
2022-03-17 15:53:45 +01:00
2024-12-16 15:58:19 +00:00
m_vWorkspaceRules . emplace_back ( wsRule ) ;
2024-02-18 15:00:34 +00:00
argno + + ;
} else {
2024-11-12 02:53:55 +02:00
Debug : : log ( ERR , " Config error: invalid monitor syntax at \" {} \" " , ARGS [ argno ] ) ;
2024-02-18 15:00:34 +00:00
return " invalid syntax at \" " + ARGS [ argno ] + " \" " ;
}
2023-09-28 02:49:30 +08:00
2024-02-18 15:00:34 +00:00
argno + + ;
}
2022-05-06 14:30:35 +02:00
2024-12-16 15:58:19 +00:00
std : : erase_if ( m_vMonitorRules , [ & ] ( const auto & other ) { return other . name = = newrule . name ; } ) ;
2022-05-06 14:30:35 +02:00
2024-12-16 15:58:19 +00:00
m_vMonitorRules . push_back ( newrule ) ;
2022-03-17 16:56:33 +01:00
2024-02-18 15:00:34 +00:00
if ( error . empty ( ) )
return { } ;
return error ;
2022-06-30 21:26:00 +02:00
}
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleBezier ( const std : : string & command , const std : : string & args ) {
const auto ARGS = CVarList ( args ) ;
2022-06-30 21:26:00 +02:00
2024-02-18 15:00:34 +00:00
std : : string bezierName = ARGS [ 0 ] ;
2023-09-28 02:49:30 +08:00
2024-02-18 15:00:34 +00:00
if ( ARGS [ 1 ] = = " " )
return " too few arguments " ;
float p1x = std : : stof ( ARGS [ 1 ] ) ;
2022-06-30 21:26:00 +02:00
2024-02-18 15:00:34 +00:00
if ( ARGS [ 2 ] = = " " )
return " too few arguments " ;
float p1y = std : : stof ( ARGS [ 2 ] ) ;
2022-06-30 21:26:00 +02:00
2024-02-18 15:00:34 +00:00
if ( ARGS [ 3 ] = = " " )
return " too few arguments " ;
float p2x = std : : stof ( ARGS [ 3 ] ) ;
2022-06-30 21:26:00 +02:00
2024-02-18 15:00:34 +00:00
if ( ARGS [ 4 ] = = " " )
return " too few arguments " ;
float p2y = std : : stof ( ARGS [ 4 ] ) ;
2022-04-10 18:25:45 +02:00
2024-02-18 15:00:34 +00:00
if ( ARGS [ 5 ] ! = " " )
return " too many arguments " ;
2022-04-10 18:25:45 +02:00
2024-02-18 15:00:34 +00:00
g_pAnimationManager - > addBezierWithName ( bezierName , Vector2D ( p1x , p1y ) , Vector2D ( p2x , p2y ) ) ;
2023-09-28 02:49:30 +08:00
2024-02-18 15:00:34 +00:00
return { } ;
2022-04-10 18:25:45 +02:00
}
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleAnimation ( const std : : string & command , const std : : string & args ) {
const auto ARGS = CVarList ( args ) ;
2022-03-19 17:00:52 +01:00
2024-02-18 15:00:34 +00:00
// Master on/off
2022-03-17 16:56:33 +01:00
2024-02-18 15:00:34 +00:00
// anim name
const auto ANIMNAME = ARGS [ 0 ] ;
2022-03-17 16:56:33 +01:00
2025-01-07 17:55:14 +00:00
if ( ! m_AnimationTree . nodeExists ( ANIMNAME ) )
2024-02-18 15:00:34 +00:00
return " no such animation " ;
2022-03-24 18:22:01 +01:00
2024-04-20 11:26:48 +00:00
// This helper casts strings like "1", "true", "off", "yes"... to int.
2024-11-20 10:32:50 +00:00
int64_t enabledInt = configStringToInt ( ARGS [ 1 ] ) . value_or ( 0 ) = = 1 ;
2022-03-24 18:22:01 +01:00
2024-04-20 11:26:48 +00:00
// Checking that the int is 1 or 0 because the helper can return integers out of range.
if ( enabledInt ! = 0 & & enabledInt ! = 1 )
2024-02-18 15:00:34 +00:00
return " invalid animation on/off state " ;
2022-03-24 18:22:01 +01:00
2025-01-09 22:08:16 +01:00
if ( ! enabledInt ) {
m_AnimationTree . setConfigForNode ( ANIMNAME , enabledInt , 1 , " default " ) ;
return { } ;
}
2025-01-20 16:48:04 +00:00
float speed = - 1 ;
2024-04-20 11:26:48 +00:00
2025-01-07 20:27:07 +01:00
// speed
if ( isNumber ( ARGS [ 2 ] , true ) ) {
speed = std : : stof ( ARGS [ 2 ] ) ;
2022-03-24 18:22:01 +01:00
2025-01-07 20:27:07 +01:00
if ( speed < = 0 ) {
speed = 1.f ;
2024-02-18 15:00:34 +00:00
return " invalid speed " ;
}
2025-01-07 20:27:07 +01:00
} else {
speed = 10.f ;
return " invalid speed " ;
}
2022-06-24 16:25:57 +02:00
2025-01-07 20:27:07 +01:00
std : : string bezierName = ARGS [ 3 ] ;
m_AnimationTree . setConfigForNode ( ANIMNAME , enabledInt , speed , ARGS [ 3 ] , ARGS [ 4 ] ) ;
2023-07-02 13:02:48 +02:00
2025-01-07 20:27:07 +01:00
if ( ! g_pAnimationManager - > bezierExists ( bezierName ) ) {
const auto PANIMNODE = m_AnimationTree . getConfig ( ANIMNAME ) ;
PANIMNODE - > internalBezier = " default " ;
return " no such bezier " ;
}
2022-06-24 16:25:57 +02:00
2025-01-07 20:27:07 +01:00
if ( ARGS [ 4 ] ! = " " ) {
auto ERR = g_pAnimationManager - > styleValidInConfigVar ( ANIMNAME , ARGS [ 4 ] ) ;
2022-09-06 11:57:11 +02:00
2025-01-07 20:27:07 +01:00
if ( ERR ! = " " )
return ERR ;
2024-02-18 15:00:34 +00:00
}
2022-09-06 11:57:11 +02:00
2024-02-18 15:00:34 +00:00
return { } ;
}
2022-09-07 11:24:40 +02:00
2024-03-03 01:17:02 +01:00
SParsedKey parseKey ( const std : : string & key ) {
if ( isNumber ( key ) & & std : : stoi ( key ) > 9 )
return { . keycode = std : : stoi ( key ) } ;
else if ( key . starts_with ( " code: " ) & & isNumber ( key . substr ( 5 ) ) )
return { . keycode = std : : stoi ( key . substr ( 5 ) ) } ;
else if ( key = = " catchall " )
return { . catchAll = true } ;
else
return { . key = key } ;
}
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleBind ( const std : : string & command , const std : : string & value ) {
// example:
// bind[fl]=SUPER,G,exec,dmenu_run <args>
2023-12-26 23:47:46 +01:00
2024-02-18 15:00:34 +00:00
// flags
2024-06-11 19:49:54 +02:00
bool locked = false ;
bool release = false ;
bool repeat = false ;
bool mouse = false ;
bool nonConsuming = false ;
bool transparent = false ;
bool ignoreMods = false ;
bool multiKey = false ;
2024-11-16 07:21:59 +08:00
bool longPress = false ;
2024-06-11 19:49:54 +02:00
bool hasDescription = false ;
2024-07-24 12:10:36 +00:00
bool dontInhibit = false ;
2024-06-11 19:49:54 +02:00
const auto BINDARGS = command . substr ( 4 ) ;
2023-12-26 23:47:46 +01:00
2024-08-26 17:25:39 +02:00
for ( auto const & arg : BINDARGS ) {
2024-02-18 15:00:34 +00:00
if ( arg = = ' l ' ) {
locked = true ;
} else if ( arg = = ' r ' ) {
release = true ;
} else if ( arg = = ' e ' ) {
repeat = true ;
} else if ( arg = = ' m ' ) {
mouse = true ;
} else if ( arg = = ' n ' ) {
nonConsuming = true ;
} else if ( arg = = ' t ' ) {
transparent = true ;
} else if ( arg = = ' i ' ) {
ignoreMods = true ;
2024-05-16 10:48:30 +00:00
} else if ( arg = = ' s ' ) {
multiKey = true ;
2024-11-16 07:21:59 +08:00
} else if ( arg = = ' o ' ) {
longPress = true ;
2024-06-11 19:49:54 +02:00
} else if ( arg = = ' d ' ) {
hasDescription = true ;
2024-07-24 12:10:36 +00:00
} else if ( arg = = ' p ' ) {
dontInhibit = true ;
2024-02-18 15:00:34 +00:00
} else {
return " bind: invalid flag " ;
}
}
2023-12-26 23:47:46 +01:00
2024-11-16 07:21:59 +08:00
if ( ( longPress | | release ) & & repeat )
return " flags e is mutually exclusive with r and o " ;
2023-12-26 23:47:46 +01:00
2024-02-18 15:00:34 +00:00
if ( mouse & & ( repeat | | release | | locked ) )
return " flag m is exclusive " ;
2022-09-07 11:24:40 +02:00
2024-06-11 19:49:54 +02:00
const int numbArgs = hasDescription ? 5 : 4 ;
const auto ARGS = CVarList ( value , numbArgs ) ;
2022-11-15 11:21:26 +01:00
2024-06-11 19:49:54 +02:00
const int DESCR_OFFSET = hasDescription ? 1 : 0 ;
2024-02-18 15:00:34 +00:00
if ( ( ARGS . size ( ) < 3 & & ! mouse ) | | ( ARGS . size ( ) < 3 & & mouse ) )
return " bind: too few args " ;
2024-06-11 19:49:54 +02:00
else if ( ( ARGS . size ( ) > ( size_t ) 4 + DESCR_OFFSET & & ! mouse ) | | ( ARGS . size ( ) > ( size_t ) 3 + DESCR_OFFSET & & mouse ) )
2024-02-18 15:00:34 +00:00
return " bind: too many args " ;
2022-11-15 11:21:26 +01:00
2024-05-16 10:48:30 +00:00
std : : set < xkb_keysym_t > KEYSYMS ;
std : : set < xkb_keysym_t > MODS ;
if ( multiKey ) {
2024-12-07 18:51:18 +01:00
for ( const auto & splitKey : CVarList ( ARGS [ 1 ] , 8 , ' & ' ) ) {
2024-05-16 10:48:30 +00:00
KEYSYMS . insert ( xkb_keysym_from_name ( splitKey . c_str ( ) , XKB_KEYSYM_CASE_INSENSITIVE ) ) ;
}
2024-12-07 18:51:18 +01:00
for ( const auto & splitMod : CVarList ( ARGS [ 0 ] , 8 , ' & ' ) ) {
2024-05-16 10:48:30 +00:00
MODS . insert ( xkb_keysym_from_name ( splitMod . c_str ( ) , XKB_KEYSYM_CASE_INSENSITIVE ) ) ;
}
}
2024-02-18 15:00:34 +00:00
const auto MOD = g_pKeybindManager - > stringToModMask ( ARGS [ 0 ] ) ;
const auto MODSTR = ARGS [ 0 ] ;
2023-08-02 13:21:38 +02:00
2024-05-16 10:48:30 +00:00
const auto KEY = multiKey ? " " : ARGS [ 1 ] ;
2023-12-08 16:02:16 +00:00
2024-06-11 19:49:54 +02:00
const auto DESCRIPTION = hasDescription ? ARGS [ 2 ] : " " ;
2023-12-20 23:52:18 +01:00
2024-06-11 19:49:54 +02:00
auto HANDLER = ARGS [ 2 + DESCR_OFFSET ] ;
2023-08-02 13:21:38 +02:00
2024-06-11 19:49:54 +02:00
const auto COMMAND = mouse ? HANDLER : ARGS [ 3 + DESCR_OFFSET ] ;
2023-08-02 13:21:38 +02:00
2024-06-11 23:02:29 +02:00
if ( mouse )
HANDLER = " mouse " ;
2024-02-18 15:00:34 +00:00
// to lower
std : : transform ( HANDLER . begin ( ) , HANDLER . end ( ) , HANDLER . begin ( ) , : : tolower ) ;
2023-08-02 13:21:38 +02:00
2024-02-18 15:00:34 +00:00
const auto DISPATCHER = g_pKeybindManager - > m_mDispatchers . find ( HANDLER ) ;
2023-08-02 13:21:38 +02:00
2024-02-18 15:00:34 +00:00
if ( DISPATCHER = = g_pKeybindManager - > m_mDispatchers . end ( ) ) {
2024-11-12 02:53:55 +02:00
Debug : : log ( ERR , " Invalid dispatcher: {} " , HANDLER ) ;
2024-02-18 15:00:34 +00:00
return " Invalid dispatcher, requested \" " + HANDLER + " \" does not exist " ;
}
2022-03-24 18:22:01 +01:00
2024-02-18 15:00:34 +00:00
if ( MOD = = 0 & & MODSTR ! = " " ) {
2024-11-12 02:53:55 +02:00
Debug : : log ( ERR , " Invalid mod: {} " , MODSTR ) ;
2024-02-18 15:00:34 +00:00
return " Invalid mod, requested mod \" " + MODSTR + " \" is not a valid mod. " ;
}
2022-03-24 18:22:01 +01:00
2024-05-16 10:48:30 +00:00
if ( ( KEY ! = " " ) | | multiKey ) {
2024-03-03 01:17:02 +01:00
SParsedKey parsedKey = parseKey ( KEY ) ;
2024-05-29 05:37:24 +08:00
if ( parsedKey . catchAll & & m_szCurrentSubmap . empty ( ) ) {
2024-03-03 01:17:02 +01:00
Debug : : log ( ERR , " Catchall not allowed outside of submap! " ) ;
return " Invalid catchall, catchall keybinds are only allowed in submaps. " ;
}
2024-11-16 07:21:59 +08:00
g_pKeybindManager - > addKeybind ( SKeybind { parsedKey . key , KEYSYMS , parsedKey . keycode , parsedKey . catchAll , MOD , MODS , HANDLER ,
COMMAND , locked , m_szCurrentSubmap , DESCRIPTION , release , repeat , longPress ,
mouse , nonConsuming , transparent , ignoreMods , multiKey , hasDescription , dontInhibit } ) ;
2024-02-18 15:00:34 +00:00
}
2023-07-02 13:02:48 +02:00
2024-02-18 15:00:34 +00:00
return { } ;
}
2024-02-18 00:13:38 +00:00
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleUnbind ( const std : : string & command , const std : : string & value ) {
const auto ARGS = CVarList ( value ) ;
2022-03-24 18:22:01 +01:00
2024-02-18 15:00:34 +00:00
const auto MOD = g_pKeybindManager - > stringToModMask ( ARGS [ 0 ] ) ;
2023-04-18 11:48:56 +01:00
2024-03-03 01:17:02 +01:00
const auto KEY = parseKey ( ARGS [ 1 ] ) ;
2022-11-10 13:39:23 +00:00
2024-02-18 15:00:34 +00:00
g_pKeybindManager - > removeKeybind ( MOD , KEY ) ;
2022-11-10 13:39:23 +00:00
2024-02-18 15:00:34 +00:00
return { } ;
}
2022-11-10 13:39:23 +00:00
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleWindowRule ( const std : : string & command , const std : : string & value ) {
2024-06-11 17:17:45 +02:00
const auto RULE = trim ( value . substr ( 0 , value . find_first_of ( ' , ' ) ) ) ;
const auto VALUE = trim ( value . substr ( value . find_first_of ( ' , ' ) + 1 ) ) ;
2023-03-18 15:02:00 +00:00
2024-02-18 15:00:34 +00:00
// check rule and value
2024-05-29 05:37:24 +08:00
if ( RULE . empty ( ) | | VALUE . empty ( ) )
2024-02-18 15:00:34 +00:00
return " empty rule? " ;
2023-01-25 15:34:13 +00:00
2024-02-18 15:00:34 +00:00
if ( RULE = = " unset " ) {
2024-12-16 19:05:24 +01:00
std : : erase_if ( m_vWindowRules , [ & ] ( const auto & other ) { return other - > szValue = = VALUE ; } ) ;
2024-02-18 15:00:34 +00:00
return { } ;
}
2023-01-25 15:34:13 +00:00
2024-12-16 19:05:24 +01:00
auto newRule = makeShared < CWindowRule > ( RULE , VALUE , false ) ;
2024-02-18 15:00:34 +00:00
// verify we support a rule
2024-12-16 19:05:24 +01:00
if ( newRule - > ruleType = = CWindowRule : : RULE_INVALID ) {
2024-02-18 15:00:34 +00:00
Debug : : log ( ERR , " Invalid rule found: {} " , RULE ) ;
return " Invalid rule: " + RULE ;
2023-01-25 15:34:13 +00:00
}
2024-12-21 23:07:23 +00:00
newRule - > rV1Regex = { VALUE . starts_with ( " title: " ) ? VALUE . substr ( 6 ) : VALUE } ;
2024-12-21 19:21:45 +00:00
2024-02-18 15:00:34 +00:00
if ( RULE . starts_with ( " size " ) | | RULE . starts_with ( " maxsize " ) | | RULE . starts_with ( " minsize " ) )
2024-12-16 19:05:24 +01:00
m_vWindowRules . insert ( m_vWindowRules . begin ( ) , newRule ) ;
2024-02-18 15:00:34 +00:00
else
2024-12-16 19:05:24 +01:00
m_vWindowRules . emplace_back ( newRule ) ;
2023-03-17 23:36:36 +00:00
2024-02-18 15:00:34 +00:00
return { } ;
2023-01-25 15:34:13 +00:00
}
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleLayerRule ( const std : : string & command , const std : : string & value ) {
2024-06-11 17:17:45 +02:00
const auto RULE = trim ( value . substr ( 0 , value . find_first_of ( ' , ' ) ) ) ;
const auto VALUE = trim ( value . substr ( value . find_first_of ( ' , ' ) + 1 ) ) ;
2022-04-12 20:02:57 +02:00
2024-02-18 15:00:34 +00:00
// check rule and value
2024-05-29 05:37:24 +08:00
if ( RULE . empty ( ) | | VALUE . empty ( ) )
2024-02-18 15:00:34 +00:00
return " empty rule? " ;
2023-03-05 12:52:57 +00:00
2024-02-18 15:00:34 +00:00
if ( RULE = = " unset " ) {
2024-12-16 19:05:24 +01:00
std : : erase_if ( m_vLayerRules , [ & ] ( const auto & other ) { return other - > targetNamespace = = VALUE ; } ) ;
2024-02-18 15:00:34 +00:00
return { } ;
}
2022-04-12 20:02:57 +02:00
2024-12-16 19:05:24 +01:00
auto rule = makeShared < CLayerRule > ( RULE , VALUE ) ;
if ( rule - > ruleType = = CLayerRule : : RULE_INVALID ) {
2024-02-18 15:00:34 +00:00
Debug : : log ( ERR , " Invalid rule found: {} " , RULE ) ;
return " Invalid rule found: " + RULE ;
2022-04-12 20:02:57 +02:00
}
2024-12-21 23:07:23 +00:00
rule - > targetNamespaceRegex = { VALUE } ;
2024-12-21 19:21:45 +00:00
2024-12-16 19:05:24 +01:00
m_vLayerRules . emplace_back ( rule ) ;
2022-07-21 20:30:48 +02:00
2024-08-26 17:25:39 +02:00
for ( auto const & m : g_pCompositor - > m_vMonitors )
for ( auto const & lsl : m - > m_aLayerSurfaceLayers )
for ( auto const & ls : lsl )
2024-02-18 15:00:34 +00:00
ls - > applyRules ( ) ;
2022-07-22 12:37:44 +02:00
2024-02-18 15:00:34 +00:00
return { } ;
2022-04-19 19:01:23 +02:00
}
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleWindowRuleV2 ( const std : : string & command , const std : : string & value ) {
2024-06-11 17:17:45 +02:00
const auto RULE = trim ( value . substr ( 0 , value . find_first_of ( ' , ' ) ) ) ;
2024-02-18 15:00:34 +00:00
const auto VALUE = value . substr ( value . find_first_of ( ' , ' ) + 1 ) ;
2022-06-30 23:55:28 +02:00
2024-12-16 19:05:24 +01:00
auto rule = makeShared < CWindowRule > ( RULE , VALUE , true ) ;
if ( rule - > ruleType = = CWindowRule : : RULE_INVALID & & RULE ! = " unset " ) {
2024-02-18 15:00:34 +00:00
Debug : : log ( ERR , " Invalid rulev2 found: {} " , RULE ) ;
return " Invalid rulev2 found: " + RULE ;
}
2022-06-30 23:55:28 +02:00
2024-02-18 15:00:34 +00:00
// now we estract shit from the value
2024-08-24 04:42:14 +09:00
const auto TAGPOS = VALUE . find ( " tag: " ) ;
const auto TITLEPOS = VALUE . find ( " title: " ) ;
const auto CLASSPOS = VALUE . find ( " class: " ) ;
const auto INITIALTITLEPOS = VALUE . find ( " initialTitle: " ) ;
const auto INITIALCLASSPOS = VALUE . find ( " initialClass: " ) ;
const auto X11POS = VALUE . find ( " xwayland: " ) ;
const auto FLOATPOS = VALUE . find ( " floating: " ) ;
const auto FULLSCREENPOS = VALUE . find ( " fullscreen: " ) ;
const auto PINNEDPOS = VALUE . find ( " pinned: " ) ;
const auto FOCUSPOS = VALUE . find ( " focus: " ) ;
const auto FULLSCREENSTATEPOS = VALUE . find ( " fullscreenstate: " ) ;
const auto ONWORKSPACEPOS = VALUE . find ( " onworkspace: " ) ;
2025-02-02 22:25:29 +03:00
const auto CONTENTTYPEPOS = VALUE . find ( " content: " ) ;
2022-09-13 15:25:42 +02:00
2024-02-18 15:00:34 +00:00
// find workspacepos that isn't onworkspacepos
size_t WORKSPACEPOS = std : : string : : npos ;
size_t currentPos = VALUE . find ( " workspace: " ) ;
while ( currentPos ! = std : : string : : npos ) {
if ( currentPos = = 0 | | VALUE [ currentPos - 1 ] ! = ' n ' ) {
WORKSPACEPOS = currentPos ;
2022-06-30 23:55:28 +02:00
break ;
}
2024-02-18 15:00:34 +00:00
currentPos = VALUE . find ( " workspace: " , currentPos + 1 ) ;
}
2022-09-08 14:11:32 +02:00
2025-02-02 22:25:29 +03:00
const auto checkPos = std : : unordered_set { TAGPOS , TITLEPOS , CLASSPOS , INITIALTITLEPOS , INITIALCLASSPOS , X11POS , FLOATPOS ,
FULLSCREENPOS , PINNEDPOS , FULLSCREENSTATEPOS , WORKSPACEPOS , FOCUSPOS , ONWORKSPACEPOS , CONTENTTYPEPOS } ;
2024-05-29 05:37:24 +08:00
if ( checkPos . size ( ) = = 1 & & checkPos . contains ( std : : string : : npos ) ) {
2024-02-18 15:00:34 +00:00
Debug : : log ( ERR , " Invalid rulev2 syntax: {} " , VALUE ) ;
return " Invalid rulev2 syntax: " + VALUE ;
2022-04-19 19:01:23 +02:00
}
2024-02-18 15:00:34 +00:00
auto extract = [ & ] ( size_t pos ) - > std : : string {
std : : string result ;
result = VALUE . substr ( pos ) ;
2022-06-30 23:55:28 +02:00
2024-02-18 15:00:34 +00:00
size_t min = 999999 ;
2024-05-29 05:37:24 +08:00
if ( TAGPOS > pos & & TAGPOS < min )
min = TAGPOS ;
2024-02-18 15:00:34 +00:00
if ( TITLEPOS > pos & & TITLEPOS < min )
min = TITLEPOS ;
if ( CLASSPOS > pos & & CLASSPOS < min )
min = CLASSPOS ;
if ( INITIALTITLEPOS > pos & & INITIALTITLEPOS < min )
min = INITIALTITLEPOS ;
if ( INITIALCLASSPOS > pos & & INITIALCLASSPOS < min )
min = INITIALCLASSPOS ;
if ( X11POS > pos & & X11POS < min )
min = X11POS ;
if ( FLOATPOS > pos & & FLOATPOS < min )
min = FLOATPOS ;
if ( FULLSCREENPOS > pos & & FULLSCREENPOS < min )
min = FULLSCREENPOS ;
if ( PINNEDPOS > pos & & PINNEDPOS < min )
min = PINNEDPOS ;
2024-08-24 04:42:14 +09:00
if ( FULLSCREENSTATEPOS > pos & & FULLSCREENSTATEPOS < min )
min = FULLSCREENSTATEPOS ;
2024-02-18 15:00:34 +00:00
if ( ONWORKSPACEPOS > pos & & ONWORKSPACEPOS < min )
min = ONWORKSPACEPOS ;
if ( WORKSPACEPOS > pos & & WORKSPACEPOS < min )
min = WORKSPACEPOS ;
if ( FOCUSPOS > pos & & FOCUSPOS < min )
min = FOCUSPOS ;
2025-02-02 22:25:29 +03:00
if ( CONTENTTYPEPOS > pos & & CONTENTTYPEPOS < min )
min = CONTENTTYPEPOS ;
2023-07-18 15:30:28 +02:00
2024-02-18 15:00:34 +00:00
result = result . substr ( 0 , min - pos ) ;
2022-04-23 14:16:02 +02:00
2024-06-11 17:17:45 +02:00
result = trim ( result ) ;
2022-06-30 21:26:00 +02:00
2024-04-08 15:27:08 +01:00
if ( ! result . empty ( ) & & result . back ( ) = = ' , ' )
2024-02-18 15:00:34 +00:00
result . pop_back ( ) ;
2023-09-09 13:25:17 +02:00
2024-02-18 15:00:34 +00:00
return result ;
} ;
2023-09-09 13:25:17 +02:00
2024-05-29 05:37:24 +08:00
if ( TAGPOS ! = std : : string : : npos )
2024-12-16 19:05:24 +01:00
rule - > szTag = extract ( TAGPOS + 4 ) ;
2024-05-29 05:37:24 +08:00
2024-12-21 19:21:45 +00:00
if ( CLASSPOS ! = std : : string : : npos ) {
2024-12-16 19:05:24 +01:00
rule - > szClass = extract ( CLASSPOS + 6 ) ;
2024-12-21 23:07:23 +00:00
rule - > rClass = { rule - > szClass } ;
2024-12-21 19:21:45 +00:00
}
2023-09-09 13:25:17 +02:00
2024-12-21 19:21:45 +00:00
if ( TITLEPOS ! = std : : string : : npos ) {
2024-12-16 19:05:24 +01:00
rule - > szTitle = extract ( TITLEPOS + 6 ) ;
2024-12-21 23:07:23 +00:00
rule - > rTitle = { rule - > szTitle } ;
2024-12-21 19:21:45 +00:00
}
2022-08-11 21:16:38 +02:00
2024-12-21 19:21:45 +00:00
if ( INITIALCLASSPOS ! = std : : string : : npos ) {
2024-12-16 19:05:24 +01:00
rule - > szInitialClass = extract ( INITIALCLASSPOS + 13 ) ;
2024-12-21 23:07:23 +00:00
rule - > rInitialClass = { rule - > szInitialClass } ;
2024-12-21 19:21:45 +00:00
}
2023-02-27 12:32:38 +00:00
2024-12-21 19:21:45 +00:00
if ( INITIALTITLEPOS ! = std : : string : : npos ) {
2024-12-16 19:05:24 +01:00
rule - > szInitialTitle = extract ( INITIALTITLEPOS + 13 ) ;
2024-12-21 23:07:23 +00:00
rule - > rInitialTitle = { rule - > szInitialTitle } ;
2024-12-21 19:21:45 +00:00
}
2023-02-27 12:32:38 +00:00
2024-02-18 15:00:34 +00:00
if ( X11POS ! = std : : string : : npos )
2024-12-16 19:05:24 +01:00
rule - > bX11 = extract ( X11POS + 9 ) = = " 1 " ? 1 : 0 ;
2022-08-11 21:16:38 +02:00
2024-02-18 15:00:34 +00:00
if ( FLOATPOS ! = std : : string : : npos )
2024-12-16 19:05:24 +01:00
rule - > bFloating = extract ( FLOATPOS + 9 ) = = " 1 " ? 1 : 0 ;
2023-09-09 13:25:17 +02:00
2024-02-18 15:00:34 +00:00
if ( FULLSCREENPOS ! = std : : string : : npos )
2024-12-16 19:05:24 +01:00
rule - > bFullscreen = extract ( FULLSCREENPOS + 11 ) = = " 1 " ? 1 : 0 ;
2023-09-09 13:25:17 +02:00
2024-02-18 15:00:34 +00:00
if ( PINNEDPOS ! = std : : string : : npos )
2024-12-16 19:05:24 +01:00
rule - > bPinned = extract ( PINNEDPOS + 7 ) = = " 1 " ? 1 : 0 ;
2022-08-11 21:16:38 +02:00
2024-08-24 04:42:14 +09:00
if ( FULLSCREENSTATEPOS ! = std : : string : : npos )
2024-12-16 19:05:24 +01:00
rule - > szFullscreenState = extract ( FULLSCREENSTATEPOS + 16 ) ;
2024-08-24 04:42:14 +09:00
2024-02-18 15:00:34 +00:00
if ( WORKSPACEPOS ! = std : : string : : npos )
2024-12-16 19:05:24 +01:00
rule - > szWorkspace = extract ( WORKSPACEPOS + 10 ) ;
2022-08-20 18:47:48 +02:00
2024-02-18 15:00:34 +00:00
if ( FOCUSPOS ! = std : : string : : npos )
2024-12-16 19:05:24 +01:00
rule - > bFocus = extract ( FOCUSPOS + 6 ) = = " 1 " ? 1 : 0 ;
2022-06-30 21:26:00 +02:00
2024-02-18 15:00:34 +00:00
if ( ONWORKSPACEPOS ! = std : : string : : npos )
2024-12-16 19:05:24 +01:00
rule - > szOnWorkspace = extract ( ONWORKSPACEPOS + 12 ) ;
2022-07-06 22:12:03 +02:00
2025-02-02 22:25:29 +03:00
if ( CONTENTTYPEPOS ! = std : : string : : npos )
rule - > szContentType = extract ( CONTENTTYPEPOS + 8 ) ;
2024-02-18 15:00:34 +00:00
if ( RULE = = " unset " ) {
2024-12-16 19:05:24 +01:00
std : : erase_if ( m_vWindowRules , [ & ] ( const auto & other ) {
if ( ! other - > v2 )
return other - > szClass = = rule - > szClass & & ! rule - > szClass . empty ( ) ;
else {
if ( ! rule - > szTag . empty ( ) & & rule - > szTag ! = other - > szTag )
2024-05-29 05:37:24 +08:00
return false ;
2024-12-16 19:05:24 +01:00
if ( ! rule - > szClass . empty ( ) & & rule - > szClass ! = other - > szClass )
2024-02-18 15:00:34 +00:00
return false ;
2022-07-27 12:32:00 +02:00
2024-12-16 19:05:24 +01:00
if ( ! rule - > szTitle . empty ( ) & & rule - > szTitle ! = other - > szTitle )
2024-02-18 15:00:34 +00:00
return false ;
2023-03-16 14:03:40 +00:00
2024-12-16 19:05:24 +01:00
if ( ! rule - > szInitialClass . empty ( ) & & rule - > szInitialClass ! = other - > szInitialClass )
2024-02-18 15:00:34 +00:00
return false ;
2022-07-27 12:32:00 +02:00
2024-12-16 19:05:24 +01:00
if ( ! rule - > szInitialTitle . empty ( ) & & rule - > szInitialTitle ! = other - > szInitialTitle )
2024-02-18 15:00:34 +00:00
return false ;
2024-12-16 19:05:24 +01:00
if ( rule - > bX11 ! = - 1 & & rule - > bX11 ! = other - > bX11 )
2024-02-18 15:00:34 +00:00
return false ;
2024-12-16 19:05:24 +01:00
if ( rule - > bFloating ! = - 1 & & rule - > bFloating ! = other - > bFloating )
2024-02-18 15:00:34 +00:00
return false ;
2024-12-16 19:05:24 +01:00
if ( rule - > bFullscreen ! = - 1 & & rule - > bFullscreen ! = other - > bFullscreen )
2024-02-18 15:00:34 +00:00
return false ;
2024-12-16 19:05:24 +01:00
if ( rule - > bPinned ! = - 1 & & rule - > bPinned ! = other - > bPinned )
2024-02-18 15:00:34 +00:00
return false ;
2024-12-16 19:05:24 +01:00
if ( ! rule - > szFullscreenState . empty ( ) & & rule - > szFullscreenState ! = other - > szFullscreenState )
2024-08-24 04:42:14 +09:00
return false ;
2024-12-16 19:05:24 +01:00
if ( ! rule - > szWorkspace . empty ( ) & & rule - > szWorkspace ! = other - > szWorkspace )
2024-02-18 15:00:34 +00:00
return false ;
2024-12-16 19:05:24 +01:00
if ( rule - > bFocus ! = - 1 & & rule - > bFocus ! = other - > bFocus )
2024-02-18 15:00:34 +00:00
return false ;
2024-12-16 19:05:24 +01:00
if ( ! rule - > szOnWorkspace . empty ( ) & & rule - > szOnWorkspace ! = other - > szOnWorkspace )
2024-02-18 15:00:34 +00:00
return false ;
2025-02-02 22:25:29 +03:00
if ( ! rule - > szContentType . empty ( ) & & rule - > szContentType ! = other - > szContentType )
return false ;
2024-02-18 15:00:34 +00:00
return true ;
}
} ) ;
return { } ;
2022-07-27 12:32:00 +02:00
}
2022-07-28 13:28:43 +02:00
2024-02-18 15:00:34 +00:00
if ( RULE . starts_with ( " size " ) | | RULE . starts_with ( " maxsize " ) | | RULE . starts_with ( " minsize " ) )
2024-12-16 15:58:19 +00:00
m_vWindowRules . insert ( m_vWindowRules . begin ( ) , rule ) ;
2024-02-18 15:00:34 +00:00
else
2024-12-16 15:58:19 +00:00
m_vWindowRules . push_back ( rule ) ;
2022-10-28 23:48:48 +01:00
2024-02-18 15:00:34 +00:00
return { } ;
}
2023-03-16 14:03:40 +00:00
2024-02-18 15:00:34 +00:00
void CConfigManager : : updateBlurredLS ( const std : : string & name , const bool forceBlur ) {
const bool BYADDRESS = name . starts_with ( " address: " ) ;
std : : string matchName = name ;
2023-08-11 17:37:52 +02:00
2024-12-16 19:05:24 +01:00
if ( BYADDRESS )
2024-02-18 15:00:34 +00:00
matchName = matchName . substr ( 8 ) ;
2022-10-22 21:45:17 +01:00
2024-08-26 17:25:39 +02:00
for ( auto const & m : g_pCompositor - > m_vMonitors ) {
for ( auto const & lsl : m - > m_aLayerSurfaceLayers ) {
for ( auto const & ls : lsl ) {
2024-02-18 15:00:34 +00:00
if ( BYADDRESS ) {
if ( std : : format ( " 0x{:x} " , ( uintptr_t ) ls . get ( ) ) = = matchName )
ls - > forceBlur = forceBlur ;
} else if ( ls - > szNamespace = = matchName )
ls - > forceBlur = forceBlur ;
2022-10-22 21:45:17 +01:00
}
2024-02-18 15:00:34 +00:00
}
}
}
2022-10-22 21:45:17 +01:00
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleBlurLS ( const std : : string & command , const std : : string & value ) {
if ( value . starts_with ( " remove, " ) ) {
2024-06-11 17:17:45 +02:00
const auto TOREMOVE = trim ( value . substr ( 7 ) ) ;
2024-02-18 15:00:34 +00:00
if ( std : : erase_if ( m_dBlurLSNamespaces , [ & ] ( const auto & other ) { return other = = TOREMOVE ; } ) )
updateBlurredLS ( TOREMOVE , false ) ;
return { } ;
}
2023-02-14 17:08:42 +00:00
2024-02-18 15:00:34 +00:00
m_dBlurLSNamespaces . emplace_back ( value ) ;
updateBlurredLS ( value , true ) ;
2022-10-22 21:45:17 +01:00
2024-02-18 15:00:34 +00:00
return { } ;
}
2022-10-22 21:45:17 +01:00
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleWorkspaceRules ( const std : : string & command , const std : : string & value ) {
// This can either be the monitor or the workspace identifier
2024-06-23 00:52:42 +03:00
const auto FIRST_DELIM = value . find_first_of ( ' , ' ) ;
2022-10-22 21:45:17 +01:00
2024-06-23 00:52:42 +03:00
auto first_ident = trim ( value . substr ( 0 , FIRST_DELIM ) ) ;
const auto & [ id , name ] = getWorkspaceIDNameFromString ( first_ident ) ;
2023-09-04 18:24:18 +02:00
2024-02-18 15:00:34 +00:00
auto rules = value . substr ( FIRST_DELIM + 1 ) ;
SWorkspaceRule wsRule ;
wsRule . workspaceString = first_ident ;
2024-03-19 20:56:20 +00:00
// if (id == WORKSPACE_INVALID) {
// // it could be the monitor. If so, second value MUST be
// // the workspace.
// const auto WORKSPACE_DELIM = value.find_first_of(',', FIRST_DELIM + 1);
// auto wsIdent = removeBeginEndSpacesTabs(value.substr(FIRST_DELIM + 1, (WORKSPACE_DELIM - FIRST_DELIM - 1)));
// id = getWorkspaceIDFromString(wsIdent, name);
// if (id == WORKSPACE_INVALID) {
// Debug::log(ERR, "Invalid workspace identifier found: {}", wsIdent);
// return "Invalid workspace identifier found: " + wsIdent;
// }
// wsRule.monitor = first_ident;
// wsRule.workspaceString = wsIdent;
// wsRule.isDefault = true; // backwards compat
// rules = value.substr(WORKSPACE_DELIM + 1);
// }
2023-02-14 17:08:42 +00:00
2024-04-06 19:53:32 +05:00
const static std : : string ruleOnCreatedEmpty = " on-created-empty: " ;
2024-08-08 21:01:50 +02:00
const static auto ruleOnCreatedEmptyLen = ruleOnCreatedEmpty . length ( ) ;
2022-10-22 21:45:17 +01:00
2024-11-18 23:53:38 +00:00
# define CHECK_OR_THROW(expr) \
\
auto X = expr ; \
if ( ! X ) { \
return " Failed parsing a workspace rule " ; \
}
auto assignRule = [ & ] ( std : : string rule ) - > std : : optional < std : : string > {
2024-02-18 15:00:34 +00:00
size_t delim = std : : string : : npos ;
2024-02-21 12:07:39 +01:00
if ( ( delim = rule . find ( " gapsin: " ) ) ! = std : : string : : npos ) {
CVarList varlist = CVarList ( rule . substr ( delim + 7 ) , 0 , ' ' ) ;
wsRule . gapsIn = CCssGapData ( ) ;
try {
wsRule . gapsIn - > parseGapData ( varlist ) ;
} catch ( . . . ) { return " Error parsing workspace rule gaps: {} " , rule . substr ( delim + 7 ) ; }
} else if ( ( delim = rule . find ( " gapsout: " ) ) ! = std : : string : : npos ) {
CVarList varlist = CVarList ( rule . substr ( delim + 8 ) , 0 , ' ' ) ;
wsRule . gapsOut = CCssGapData ( ) ;
try {
wsRule . gapsOut - > parseGapData ( varlist ) ;
} catch ( . . . ) { return " Error parsing workspace rule gaps: {} " , rule . substr ( delim + 8 ) ; }
} else if ( ( delim = rule . find ( " bordersize: " ) ) ! = std : : string : : npos )
try {
wsRule . borderSize = std : : stoi ( rule . substr ( delim + 11 ) ) ;
} catch ( . . . ) { return " Error parsing workspace rule bordersize: {} " , rule . substr ( delim + 11 ) ; }
2024-11-18 23:53:38 +00:00
else if ( ( delim = rule . find ( " border: " ) ) ! = std : : string : : npos ) {
CHECK_OR_THROW ( configStringToInt ( rule . substr ( delim + 7 ) ) )
wsRule . noBorder = ! * X ;
} else if ( ( delim = rule . find ( " shadow: " ) ) ! = std : : string : : npos ) {
CHECK_OR_THROW ( configStringToInt ( rule . substr ( delim + 7 ) ) )
wsRule . noShadow = ! * X ;
} else if ( ( delim = rule . find ( " rounding: " ) ) ! = std : : string : : npos ) {
CHECK_OR_THROW ( configStringToInt ( rule . substr ( delim + 9 ) ) )
wsRule . noRounding = ! * X ;
} else if ( ( delim = rule . find ( " decorate: " ) ) ! = std : : string : : npos ) {
CHECK_OR_THROW ( configStringToInt ( rule . substr ( delim + 9 ) ) )
wsRule . decorate = * X ;
} else if ( ( delim = rule . find ( " monitor: " ) ) ! = std : : string : : npos )
2024-02-18 15:00:34 +00:00
wsRule . monitor = rule . substr ( delim + 8 ) ;
2024-11-18 23:53:38 +00:00
else if ( ( delim = rule . find ( " default: " ) ) ! = std : : string : : npos ) {
CHECK_OR_THROW ( configStringToInt ( rule . substr ( delim + 8 ) ) )
wsRule . isDefault = * X ;
} else if ( ( delim = rule . find ( " persistent: " ) ) ! = std : : string : : npos ) {
CHECK_OR_THROW ( configStringToInt ( rule . substr ( delim + 11 ) ) )
wsRule . isPersistent = * X ;
} else if ( ( delim = rule . find ( " defaultName: " ) ) ! = std : : string : : npos )
2024-02-27 22:44:42 +00:00
wsRule . defaultName = rule . substr ( delim + 12 ) ;
2024-11-18 23:53:38 +00:00
else if ( ( delim = rule . find ( ruleOnCreatedEmpty ) ) ! = std : : string : : npos ) {
CHECK_OR_THROW ( cleanCmdForWorkspace ( name , rule . substr ( delim + ruleOnCreatedEmptyLen ) ) )
wsRule . onCreatedEmptyRunCmd = * X ;
} else if ( ( delim = rule . find ( " layoutopt: " ) ) ! = std : : string : : npos ) {
2024-02-18 15:00:34 +00:00
std : : string opt = rule . substr ( delim + 10 ) ;
if ( ! opt . contains ( " : " ) ) {
// invalid
Debug : : log ( ERR , " Invalid workspace rule found: {} " , rule ) ;
return " Invalid workspace rule found: " + rule ;
}
2023-09-04 18:24:18 +02:00
2024-12-07 18:51:18 +01:00
std : : string val = opt . substr ( opt . find ( ' : ' ) + 1 ) ;
opt = opt . substr ( 0 , opt . find ( ' : ' ) ) ;
2023-02-14 17:08:42 +00:00
2024-02-18 15:00:34 +00:00
wsRule . layoutopts [ opt ] = val ;
2022-10-22 21:45:17 +01:00
}
2024-02-18 15:00:34 +00:00
return { } ;
2022-10-28 23:48:48 +01:00
} ;
2024-11-18 23:53:38 +00:00
# undef CHECK_OR_THROW
2024-02-18 15:00:34 +00:00
CVarList rulesList { rules , 0 , ' , ' , true } ;
2024-08-26 20:24:30 +02:00
for ( auto const & r : rulesList ) {
2024-02-18 15:00:34 +00:00
const auto R = assignRule ( r ) ;
if ( R . has_value ( ) )
return R ;
2022-10-28 23:48:48 +01:00
}
2024-02-18 15:00:34 +00:00
wsRule . workspaceId = id ;
wsRule . workspaceName = name ;
2022-10-22 21:45:17 +01:00
2024-12-16 15:58:19 +00:00
const auto IT = std : : find_if ( m_vWorkspaceRules . begin ( ) , m_vWorkspaceRules . end ( ) , [ & ] ( const auto & other ) { return other . workspaceString = = wsRule . workspaceString ; } ) ;
2022-08-09 18:13:13 +02:00
2024-12-16 15:58:19 +00:00
if ( IT = = m_vWorkspaceRules . end ( ) )
m_vWorkspaceRules . emplace_back ( wsRule ) ;
2024-02-18 15:00:34 +00:00
else
2024-04-19 18:20:16 -07:00
* IT = mergeWorkspaceRules ( * IT , wsRule ) ;
2022-12-01 13:36:07 +00:00
2024-02-18 15:00:34 +00:00
return { } ;
2022-08-19 21:01:51 +03:00
}
2022-09-12 21:05:52 +02:00
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleSubmap ( const std : : string & command , const std : : string & submap ) {
if ( submap = = " reset " )
m_szCurrentSubmap = " " ;
2023-07-09 21:10:35 +00:00
else
2024-02-18 15:00:34 +00:00
m_szCurrentSubmap = submap ;
2022-12-09 17:17:02 +00:00
2024-02-18 15:00:34 +00:00
return { } ;
2022-12-09 17:17:02 +00:00
}
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleSource ( const std : : string & command , const std : : string & rawpath ) {
if ( rawpath . length ( ) < 2 ) {
Debug : : log ( ERR , " source= path garbage " ) ;
2024-11-12 02:53:55 +02:00
return " source= path " + rawpath + " bogus! " ;
2024-02-18 15:00:34 +00:00
}
2025-01-28 10:20:54 +01:00
std : : unique_ptr < glob_t , void ( * ) ( glob_t * ) > glob_buf { static_cast < glob_t * > ( calloc ( 1 , sizeof ( glob_t ) ) ) , // allocate and zero-initialize
[ ] ( glob_t * g ) {
if ( g ) {
globfree ( g ) ; // free internal resources allocated by glob()
free ( g ) ; // free the memory for the glob_t structure
}
} } ;
2023-05-08 15:37:59 +02:00
2024-02-18 15:00:34 +00:00
if ( auto r = glob ( absolutePath ( rawpath , configCurrentPath ) . c_str ( ) , GLOB_TILDE , nullptr , glob_buf . get ( ) ) ; r ! = 0 ) {
std : : string err = std : : format ( " source= globbing error: {} " , r = = GLOB_NOMATCH ? " found no match " : GLOB_ABORTED ? " read error " : " out of memory " ) ;
Debug : : log ( ERR , " {} " , err ) ;
return err ;
}
2022-11-26 17:56:43 +00:00
2024-03-11 01:39:00 +00:00
std : : string errorsFromParsing ;
2024-02-18 15:00:34 +00:00
for ( size_t i = 0 ; i < glob_buf - > gl_pathc ; i + + ) {
auto value = absolutePath ( glob_buf - > gl_pathv [ i ] , configCurrentPath ) ;
2023-05-01 07:10:53 -07:00
2024-02-18 15:00:34 +00:00
if ( ! std : : filesystem : : is_regular_file ( value ) ) {
if ( std : : filesystem : : exists ( value ) ) {
Debug : : log ( WARN , " source= skipping non-file {} " , value ) ;
continue ;
}
2023-05-01 07:10:53 -07:00
2024-11-12 02:53:55 +02:00
Debug : : log ( ERR , " source= file doesn't exist: {} " , value ) ;
return " source= file " + value + " doesn't exist! " ;
2024-02-18 15:00:34 +00:00
}
2025-01-19 15:39:19 +01:00
m_configPaths . emplace_back ( value ) ;
2023-05-01 07:10:53 -07:00
2024-02-18 15:00:34 +00:00
auto configCurrentPathBackup = configCurrentPath ;
configCurrentPath = value ;
2023-05-01 07:10:53 -07:00
2024-03-11 01:39:00 +00:00
const auto THISRESULT = m_pConfig - > parseFile ( value . c_str ( ) ) ;
2024-02-18 15:00:34 +00:00
configCurrentPath = configCurrentPathBackup ;
2024-03-11 01:39:00 +00:00
if ( THISRESULT . error & & errorsFromParsing . empty ( ) )
errorsFromParsing + = THISRESULT . getError ( ) ;
2023-05-01 07:10:53 -07:00
}
2024-03-11 01:39:00 +00:00
if ( errorsFromParsing . empty ( ) )
return { } ;
return errorsFromParsing ;
2022-11-26 17:56:43 +00:00
}
2023-01-25 15:16:28 +00:00
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handleEnv ( const std : : string & command , const std : : string & value ) {
if ( ! isFirstLaunch )
return { } ;
2023-02-27 12:32:38 +00:00
2024-02-18 15:00:34 +00:00
const auto ARGS = CVarList ( value , 2 ) ;
2023-02-27 12:32:38 +00:00
2024-02-18 15:00:34 +00:00
if ( ARGS [ 0 ] . empty ( ) )
return " env empty " ;
2023-02-27 12:32:38 +00:00
2024-02-18 15:00:34 +00:00
setenv ( ARGS [ 0 ] . c_str ( ) , ARGS [ 1 ] . c_str ( ) , 1 ) ;
2023-07-10 14:13:23 +02:00
2024-02-18 15:00:34 +00:00
if ( command . back ( ) = = ' d ' ) {
// dbus
const auto CMD =
# ifdef USES_SYSTEMD
" systemctl --user import-environment " + ARGS [ 0 ] +
" && hash dbus-update-activation-environment 2>/dev/null && "
# endif
" dbus-update-activation-environment --systemd " +
ARGS [ 0 ] ;
handleRawExec ( " " , CMD ) ;
2023-07-10 14:13:23 +02:00
}
2023-02-27 12:32:38 +00:00
2024-02-18 15:00:34 +00:00
return { } ;
2023-10-29 16:59:50 +00:00
}
2024-02-18 15:00:34 +00:00
std : : optional < std : : string > CConfigManager : : handlePlugin ( const std : : string & command , const std : : string & path ) {
if ( std : : find ( m_vDeclaredPlugins . begin ( ) , m_vDeclaredPlugins . end ( ) , path ) ! = m_vDeclaredPlugins . end ( ) )
return " plugin ' " + path + " ' declared twice " ;
2023-03-18 16:12:43 +00:00
2024-02-18 15:00:34 +00:00
m_vDeclaredPlugins . push_back ( path ) ;
return { } ;
2024-02-21 12:07:39 +01:00
}
2024-08-17 17:33:16 +01:00
const std : : vector < SConfigOptionDescription > & CConfigManager : : getAllDescriptions ( ) {
return CONFIG_OPTIONS ;
}
2025-02-15 00:21:50 +00:00
bool CConfigManager : : shouldUseSoftwareCursors ( PHLMONITOR pMonitor ) {
2024-10-26 02:12:43 +01:00
static auto PNOHW = CConfigValue < Hyprlang : : INT > ( " cursor:no_hardware_cursors " ) ;
switch ( * PNOHW ) {
case 0 : return false ;
case 1 : return true ;
2025-02-15 00:21:50 +00:00
case 2 : return pMonitor - > tearingState . activelyTearing ;
2025-01-08 12:29:24 +01:00
default : break ;
2024-10-26 02:12:43 +01:00
}
return true ;
}
2024-08-17 17:33:16 +01:00
std : : string SConfigOptionDescription : : jsonify ( ) const {
auto parseData = [ this ] ( ) - > std : : string {
return std : : visit (
2025-02-25 13:49:07 +00:00
[ this ] ( auto & & val ) {
const auto PTR = g_pConfigManager - > m_pConfig - > getConfigValuePtr ( value . c_str ( ) ) ;
if ( ! PTR ) {
Debug : : log ( ERR , " invalid SConfigOptionDescription: no config option {} exists " , value ) ;
return std : : string { " " } ;
}
const char * const EXPLICIT = PTR - > m_bSetByUser ? " true " : " false " ;
std : : string currentValue = " undefined " ;
const auto CONFIGVALUE = PTR - > getValue ( ) ;
if ( typeid ( Hyprlang : : INT ) = = std : : type_index ( CONFIGVALUE . type ( ) ) )
currentValue = std : : format ( " {} " , std : : any_cast < Hyprlang : : INT > ( CONFIGVALUE ) ) ;
else if ( typeid ( Hyprlang : : FLOAT ) = = std : : type_index ( CONFIGVALUE . type ( ) ) )
currentValue = std : : format ( " {:.2f} " , std : : any_cast < Hyprlang : : FLOAT > ( CONFIGVALUE ) ) ;
else if ( typeid ( Hyprlang : : STRING ) = = std : : type_index ( CONFIGVALUE . type ( ) ) )
currentValue = std : : any_cast < Hyprlang : : STRING > ( CONFIGVALUE ) ;
else if ( typeid ( Hyprlang : : VEC2 ) = = std : : type_index ( CONFIGVALUE . type ( ) ) ) {
const auto V = std : : any_cast < Hyprlang : : VEC2 > ( CONFIGVALUE ) ;
currentValue = std : : format ( " {}, {} " , V . x , V . y ) ;
} else if ( typeid ( void * ) = = std : : type_index ( CONFIGVALUE . type ( ) ) ) {
const auto DATA = ( ICustomConfigValueData * ) std : : any_cast < void * > ( CONFIGVALUE ) ;
currentValue = DATA - > toString ( ) ;
}
try {
using T = std : : decay_t < decltype ( val ) > ;
if constexpr ( std : : is_same_v < T , SStringData > ) {
return std : : format ( R " #( " value " : " { } " ,
" current " : " {} " ,
" explicit " : { } ) # " ,
val . value , currentValue , EXPLICIT ) ;
} else if constexpr ( std : : is_same_v < T , SRangeData > ) {
return std : : format ( R " #( " value " : {},
2024-08-17 17:33:16 +01:00
" min " : { } ,
2025-02-25 13:49:07 +00:00
" max " : { } ,
" current " : { } ,
" explicit " : { } ) # " ,
val . value , val . min , val . max , currentValue , EXPLICIT ) ;
} else if constexpr ( std : : is_same_v < T , SFloatData > ) {
return std : : format ( R " #( " value " : {},
2024-08-17 17:33:16 +01:00
" min " : { } ,
2025-02-25 13:49:07 +00:00
" max " : { } ,
" current " : { } ,
" explicit " : { } ) # " ,
val . value , val . min , val . max , currentValue , EXPLICIT ) ;
} else if constexpr ( std : : is_same_v < T , SColorData > ) {
return std : : format ( R " #( " value " : {},
" current " : { } ,
" explicit " : { } ) # " ,
val . color . getAsHex ( ) , currentValue , EXPLICIT ) ;
} else if constexpr ( std : : is_same_v < T , SBoolData > ) {
return std : : format ( R " #( " value " : {},
" current " : { } ,
" explicit " : { } ) # " ,
val . value , currentValue , EXPLICIT ) ;
} else if constexpr ( std : : is_same_v < T , SChoiceData > ) {
return std : : format ( R " #( " value " : {},
" firstIndex " : { } ,
" current " : { } ,
" explicit " : { } ) # " ,
val . choices , val . firstIndex , currentValue , EXPLICIT ) ;
} else if constexpr ( std : : is_same_v < T , SVectorData > ) {
return std : : format ( R " #( " x " : {},
2024-08-17 17:33:16 +01:00
" y " : { } ,
" min_x " : { } ,
" min_y " : { } ,
" max_x " : { } ,
2025-02-25 13:49:07 +00:00
" max_y " : { } ,
" current " : " {} " ,
" explicit " : { } ) # " ,
val . vec . x , val . vec . y , val . min . x , val . min . y , val . max . x , val . max . y , currentValue , EXPLICIT ) ;
} else if constexpr ( std : : is_same_v < T , SGradientData > ) {
return std : : format ( R " #( " value " : " { } " ,
" current " : " {} " ,
" explicit " : { } ) # " ,
val . gradient , currentValue , EXPLICIT ) ;
}
} catch ( std : : bad_any_cast & e ) { Debug : : log ( ERR , " Bad any_cast on value {} in descriptions " , value ) ; }
2024-08-17 17:33:16 +01:00
return std : : string { " " } ;
} ,
data ) ;
} ;
std : : string json = std : : format ( R " #({{
" value " : " {} " ,
" description " : " {} " ,
" type " : { } ,
" flags " : { } ,
" data " : { {
{ }
} }
} } ) # " ,
value , description , ( uint16_t ) type , ( uint32_t ) flags , parseData ( ) ) ;
return json ;
}
2025-01-26 14:40:42 +00:00
void CConfigManager : : ensurePersistentWorkspacesPresent ( ) {
g_pCompositor - > ensurePersistentWorkspacesPresent ( m_vWorkspaceRules ) ;
}