2022-03-17 15:53:45 +01:00
# include "ConfigManager.hpp"
2022-03-19 17:48:18 +01:00
# include "../managers/KeybindManager.hpp"
2022-03-17 15:53:45 +01:00
2023-11-26 18:59:49 +01:00
# include "../render/decorations/CHyprGroupBarDecoration.hpp"
2024-02-21 12:07:39 +01:00
# include "config/ConfigDataValues.hpp"
2024-06-11 17:17:45 +02:00
# include "helpers/varlist/VarList.hpp"
2024-05-09 22:47:21 +02:00
# include "../protocols/LayerShell.hpp"
2023-11-26 18:59:49 +01:00
2024-06-11 19:49:54 +02:00
# include <cstddef>
2024-05-16 12:48:30 +02:00
# include <cstdint>
2024-07-16 21:23:37 +02:00
# include <hyprutils/path/Path.hpp>
2022-03-17 15:53:45 +01:00
# include <string.h>
2023-10-23 00:11:03 +02: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 13:54:05 +02: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 23:24:51 +02:00
# include <sstream>
2024-05-03 18:58:40 +02:00
# include <ranges>
2024-05-28 23:37:24 +02: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>
2024-06-11 17:17:45 +02:00
using namespace Hyprutils : : String ;
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
extern " C " char * * environ ;
2023-03-05 19:39:46 +01:00
2024-02-18 16:00:34 +01:00
static Hyprlang : : CParseResult configHandleGradientSet ( const char * VALUE , void * * data ) {
std : : string V = VALUE ;
2023-10-10 18:42:45 +02:00
2024-02-18 16:00:34 +01:00
if ( ! * data )
* data = new CGradientValueData ( ) ;
2023-10-10 18:42:45 +02:00
2024-02-18 16:00:34 +01:00
const auto DATA = reinterpret_cast < CGradientValueData * > ( * data ) ;
2022-11-26 18:56:43 +01:00
2024-02-18 16:00:34 +01:00
CVarList varlist ( V , 0 , ' ' ) ;
DATA - > m_vColors . clear ( ) ;
2023-11-26 19:02:23 +01:00
2024-02-18 16:00:34 +01:00
std : : string parseError = " " ;
for ( auto & var : varlist ) {
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 {
DATA - > m_vColors . push_back ( CColor ( configStringToInt ( var ) ) ) ;
} 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 ) ;
parseError = " Error parsing gradient " + V + " : No colors? " ;
DATA - > m_vColors . push_back ( 0 ) ; // transparent
}
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 ) ;
}
2024-02-18 16:00:34 +01: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 ;
}
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 ;
}
CConfigManager : : CConfigManager ( ) {
const auto ERR = verifyConfigExists ( ) ;
2022-07-14 22:55:24 +02:00
2023-07-07 19:19:35 +02:00
configPaths . emplace_back ( getMainConfigPath ( ) ) ;
2024-02-18 16:00:34 +01:00
m_pConfig = std : : make_unique < Hyprlang : : CConfig > ( configPaths . begin ( ) - > c_str ( ) , Hyprlang : : SConfigOptions { . throwAllErrors = true , . allowMissingConfig = true } ) ;
m_pConfig - > addConfigValue ( " general:sensitivity " , { 1.0f } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " general:apply_sens_to_raw " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " general:border_size " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " general:no_border_on_floating " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " general:border_part_of_window " , Hyprlang : : INT { 1 } ) ;
2024-02-21 12:07:39 +01:00
m_pConfig - > addConfigValue ( " general:gaps_in " , Hyprlang : : CConfigCustomValueType { configHandleGapSet , configHandleGapDestroy , " 5 " } ) ;
m_pConfig - > addConfigValue ( " general:gaps_out " , Hyprlang : : CConfigCustomValueType { configHandleGapSet , configHandleGapDestroy , " 20 " } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " general:gaps_workspaces " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " general:no_focus_fallback " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " general:resize_on_border " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " general:extend_border_grab_area " , Hyprlang : : INT { 15 } ) ;
m_pConfig - > addConfigValue ( " general:hover_icon_on_border " , Hyprlang : : INT { 1 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " general:layout " , { " dwindle " } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " general:allow_tearing " , Hyprlang : : INT { 0 } ) ;
2024-03-13 03:43:22 +01:00
m_pConfig - > addConfigValue ( " general:resize_corner " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " misc:disable_hyprland_logo " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " misc:disable_splash_rendering " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " misc:col.splash " , Hyprlang : : INT { 0x55ffffff } ) ;
2024-05-22 10:09:36 +02:00
m_pConfig - > addConfigValue ( " misc:splash_font_family " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " misc:font_family " , { " Sans " } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " misc:force_default_wallpaper " , Hyprlang : : INT { - 1 } ) ;
m_pConfig - > addConfigValue ( " misc:vfr " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " misc:vrr " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " misc:mouse_move_enables_dpms " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " misc:key_press_enables_dpms " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " misc:always_follow_on_dnd " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " misc:layers_hog_keyboard_focus " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " misc:animate_manual_resizes " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " misc:animate_mouse_windowdragging " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " misc:disable_autoreload " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " misc:enable_swallow " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " misc:swallow_regex " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " misc:swallow_exception_regex " , { STRVAL_EMPTY } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " misc:focus_on_activate " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " misc:no_direct_scanout " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " misc:mouse_move_focuses_monitor " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " misc:render_ahead_of_time " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " misc:render_ahead_safezone " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " misc:allow_session_lock_restore " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " misc:close_special_on_empty " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " misc:background_color " , Hyprlang : : INT { 0xff111111 } ) ;
m_pConfig - > addConfigValue ( " misc:new_window_takes_over_fullscreen " , Hyprlang : : INT { 0 } ) ;
2024-07-15 13:48:04 +02:00
m_pConfig - > addConfigValue ( " misc:exit_window_retains_fullscreen " , Hyprlang : : INT { 0 } ) ;
2024-04-23 02:28:20 +02:00
m_pConfig - > addConfigValue ( " misc:initial_workspace_tracking " , Hyprlang : : INT { 1 } ) ;
2024-05-13 22:47:59 +02:00
m_pConfig - > addConfigValue ( " misc:middle_click_paste " , Hyprlang : : INT { 1 } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " group:insert_after_current " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " group:focus_removed_window " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:enabled " , Hyprlang : : INT { 1 } ) ;
2024-05-22 10:09:36 +02:00
m_pConfig - > addConfigValue ( " group:groupbar:font_family " , { STRVAL_EMPTY } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " group:groupbar:font_size " , Hyprlang : : INT { 8 } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:gradients " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:height " , Hyprlang : : INT { 14 } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:priority " , Hyprlang : : INT { 3 } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:render_titles " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:scrolling " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:text_color " , Hyprlang : : INT { 0xffffffff } ) ;
2024-05-16 12:38:10 +02:00
m_pConfig - > addConfigValue ( " group:groupbar:stacked " , Hyprlang : : INT { 0 } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " debug:int " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " debug:log_damage " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " debug:overlay " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " debug:damage_blink " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " debug:disable_logs " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " debug:disable_time " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " debug:enable_stdout_logs " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " debug:damage_tracking " , { ( Hyprlang : : INT ) DAMAGE_TRACKING_FULL } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " debug:manual_crash " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " debug:suppress_errors " , Hyprlang : : INT { 0 } ) ;
2024-03-21 02:55:13 +01:00
m_pConfig - > addConfigValue ( " debug:error_limit " , Hyprlang : : INT { 5 } ) ;
2024-05-17 20:06:51 +02:00
m_pConfig - > addConfigValue ( " debug:error_position " , Hyprlang : : INT { 0 } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " debug:watchdog_timeout " , Hyprlang : : INT { 5 } ) ;
m_pConfig - > addConfigValue ( " debug:disable_scale_checks " , Hyprlang : : INT { 0 } ) ;
2024-04-29 17:07:35 +02:00
m_pConfig - > addConfigValue ( " debug:colored_stdout_logs " , Hyprlang : : INT { 1 } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " decoration:rounding " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:enabled " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:size " , Hyprlang : : INT { 8 } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:passes " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:ignore_opacity " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:new_optimizations " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:xray " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " decoration:blur:contrast " , { 0.8916F } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:brightness " , { 1.0F } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:vibrancy " , { 0.1696F } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:vibrancy_darkness " , { 0.0F } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:noise " , { 0.0117F } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " decoration:blur:special " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:popups " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " decoration:blur:popups_ignorealpha " , { 0.2F } ) ;
m_pConfig - > addConfigValue ( " decoration:active_opacity " , { 1.F } ) ;
m_pConfig - > addConfigValue ( " decoration:inactive_opacity " , { 1.F } ) ;
m_pConfig - > addConfigValue ( " decoration:fullscreen_opacity " , { 1.F } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " decoration:no_blur_on_oversized " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " decoration:drop_shadow " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " decoration:shadow_range " , Hyprlang : : INT { 4 } ) ;
m_pConfig - > addConfigValue ( " decoration:shadow_render_power " , Hyprlang : : INT { 3 } ) ;
m_pConfig - > addConfigValue ( " decoration:shadow_ignore_window " , Hyprlang : : INT { 1 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " decoration:shadow_offset " , Hyprlang : : VEC2 { 0 , 0 } ) ;
m_pConfig - > addConfigValue ( " decoration:shadow_scale " , { 1.f } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " decoration:col.shadow " , Hyprlang : : INT { 0xee1a1a1a } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " decoration:col.shadow_inactive " , { ( Hyprlang : : INT ) INT_MAX } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " decoration:dim_inactive " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " decoration:dim_strength " , { 0.5f } ) ;
m_pConfig - > addConfigValue ( " decoration:dim_special " , { 0.2f } ) ;
m_pConfig - > addConfigValue ( " decoration:dim_around " , { 0.4f } ) ;
m_pConfig - > addConfigValue ( " decoration:screen_shader " , { STRVAL_EMPTY } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " dwindle:pseudotile " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " dwindle:force_split " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " dwindle:permanent_direction_override " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " dwindle:preserve_split " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " dwindle:special_scale_factor " , { 1.f } ) ;
m_pConfig - > addConfigValue ( " dwindle:split_width_multiplier " , { 1.0f } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " dwindle:no_gaps_when_only " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " dwindle:use_active_for_splits " , Hyprlang : : INT { 1 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " dwindle:default_split_ratio " , { 1.f } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " dwindle:smart_split " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " dwindle:smart_resizing " , Hyprlang : : INT { 1 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " master:special_scale_factor " , { 1.f } ) ;
m_pConfig - > addConfigValue ( " master:mfact " , { 0.55f } ) ;
2024-06-15 21:17:38 +02:00
m_pConfig - > addConfigValue ( " master:new_status " , { " slave " } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " master:always_center_master " , Hyprlang : : INT { 0 } ) ;
2024-06-15 21:17:38 +02:00
m_pConfig - > addConfigValue ( " master:new_on_active " , { " none " } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " master:new_on_top " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " master:no_gaps_when_only " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " master:orientation " , { " left " } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " master:inherit_fullscreen " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " master:allow_small_split " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " master:smart_resizing " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " master:drop_at_cursor " , Hyprlang : : INT { 1 } ) ;
2024-02-18 16:00:34 +01:00
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " animations:enabled " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " animations:first_launch_animation " , Hyprlang : : INT { 1 } ) ;
2024-02-18 16:00:34 +01:00
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " input:follow_mouse " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " input:mouse_refocus " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " input:special_fallthrough " , Hyprlang : : INT { 0 } ) ;
2024-04-09 00:35:21 +02:00
m_pConfig - > addConfigValue ( " input:off_window_axis_events " , Hyprlang : : INT { 1 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " input:sensitivity " , { 0.f } ) ;
m_pConfig - > addConfigValue ( " input:accel_profile " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " input:kb_file " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " input:kb_layout " , { " us " } ) ;
m_pConfig - > addConfigValue ( " input:kb_variant " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " input:kb_options " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " input:kb_rules " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " input:kb_model " , { STRVAL_EMPTY } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " input:repeat_rate " , Hyprlang : : INT { 25 } ) ;
m_pConfig - > addConfigValue ( " input:repeat_delay " , Hyprlang : : INT { 600 } ) ;
m_pConfig - > addConfigValue ( " input:natural_scroll " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " input:numlock_by_default " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " input:resolve_binds_by_sym " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " input:force_no_accel " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " input:float_switch_override_focus " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " input:left_handed " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " input:scroll_method " , { STRVAL_EMPTY } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " input:scroll_button " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " input:scroll_button_lock " , Hyprlang : : INT { 0 } ) ;
2024-03-05 20:18:53 +01:00
m_pConfig - > addConfigValue ( " input:scroll_factor " , { 1.f } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " input:scroll_points " , { STRVAL_EMPTY } ) ;
2024-07-18 21:57:08 +02:00
m_pConfig - > addConfigValue ( " input:emulate_discrete_scroll " , Hyprlang : : INT { 1 } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " input:touchpad:natural_scroll " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:disable_while_typing " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:clickfinger_behavior " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " input:touchpad:tap_button_map " , { STRVAL_EMPTY } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " input:touchpad:middle_button_emulation " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:tap-to-click " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:tap-and-drag " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:drag_lock " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " input:touchpad:scroll_factor " , { 1.f } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " input:touchdevice:transform " , Hyprlang : : INT { 0 } ) ;
2024-02-27 23:11:59 +01:00
m_pConfig - > addConfigValue ( " input:touchdevice:output " , { " [[Auto]] " } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " input:touchdevice:enabled " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " input:tablet:transform " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " input:tablet:output " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " input:tablet:region_position " , Hyprlang : : VEC2 { 0 , 0 } ) ;
m_pConfig - > addConfigValue ( " input:tablet:region_size " , Hyprlang : : VEC2 { 0 , 0 } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " input:tablet:relative_input " , Hyprlang : : INT { 0 } ) ;
2024-03-20 05:00:43 +01:00
m_pConfig - > addConfigValue ( " input:tablet:left_handed " , Hyprlang : : INT { 0 } ) ;
2024-03-23 21:31:03 +01:00
m_pConfig - > addConfigValue ( " input:tablet:active_area_position " , Hyprlang : : VEC2 { 0 , 0 } ) ;
m_pConfig - > addConfigValue ( " input:tablet:active_area_size " , Hyprlang : : VEC2 { 0 , 0 } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " binds:pass_mouse_when_bound " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " binds:scroll_event_delay " , Hyprlang : : INT { 300 } ) ;
m_pConfig - > addConfigValue ( " binds:workspace_back_and_forth " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " binds:allow_workspace_cycles " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " binds:workspace_center_on " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " binds:focus_preferred_method " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " binds:ignore_group_lock " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " binds:movefocus_cycles_fullscreen " , Hyprlang : : INT { 1 } ) ;
2024-03-29 19:57:10 +01:00
m_pConfig - > addConfigValue ( " binds:disable_keybind_grabbing " , Hyprlang : : INT { 0 } ) ;
2024-05-22 21:51:46 +02:00
m_pConfig - > addConfigValue ( " binds:window_direction_monitor_fallback " , Hyprlang : : INT { 1 } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " gestures:workspace_swipe " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_fingers " , Hyprlang : : INT { 3 } ) ;
2024-06-07 19:54:08 +02:00
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_min_fingers " , Hyprlang : : INT { 0 } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_distance " , Hyprlang : : INT { 300 } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_invert " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_min_speed_to_force " , Hyprlang : : INT { 30 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_cancel_ratio " , { 0.5f } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_create_new " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_direction_lock " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_direction_lock_threshold " , Hyprlang : : INT { 10 } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_forever " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_use_r " , Hyprlang : : INT { 0 } ) ;
2024-03-17 16:43:59 +01:00
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_touch " , Hyprlang : : INT { 0 } ) ;
2024-07-21 13:59:09 +02:00
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_touch_invert " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " xwayland:use_nearest_neighbor " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " xwayland:force_zero_scaling " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " opengl:nvidia_anti_flicker " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " opengl:force_introspection " , Hyprlang : : INT { 2 } ) ;
2024-02-18 16:00:34 +01:00
2024-05-05 23:18:10 +02:00
m_pConfig - > addConfigValue ( " cursor:no_hardware_cursors " , Hyprlang : : INT { 0 } ) ;
2024-06-14 13:45:32 +02:00
m_pConfig - > addConfigValue ( " cursor:no_break_fs_vrr " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " cursor:min_refresh_rate " , Hyprlang : : INT { 24 } ) ;
2024-07-02 12:17:48 +02:00
m_pConfig - > addConfigValue ( " cursor:hotspot_padding " , Hyprlang : : INT { 0 } ) ;
2024-05-09 23:23:01 +02:00
m_pConfig - > addConfigValue ( " cursor:inactive_timeout " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " cursor:no_warps " , Hyprlang : : INT { 0 } ) ;
2024-06-07 19:52:15 +02:00
m_pConfig - > addConfigValue ( " cursor:persistent_warps " , Hyprlang : : INT { 0 } ) ;
2024-06-16 16:42:32 +02:00
m_pConfig - > addConfigValue ( " cursor:warp_on_change_workspace " , Hyprlang : : INT { 0 } ) ;
2024-05-09 23:23:01 +02:00
m_pConfig - > addConfigValue ( " cursor:default_monitor " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " cursor:zoom_factor " , { 1.f } ) ;
m_pConfig - > addConfigValue ( " cursor:zoom_rigid " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " cursor:enable_hyprcursor " , Hyprlang : : INT { 1 } ) ;
m_pConfig - > addConfigValue ( " cursor:hide_on_key_press " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addConfigValue ( " cursor:hide_on_touch " , Hyprlang : : INT { 1 } ) ;
2024-07-21 13:09:54 +02:00
m_pConfig - > addConfigValue ( " cursor:allow_dumb_copy " , Hyprlang : : INT { 0 } ) ;
2024-05-05 23:18:10 +02:00
2024-02-29 22:33:39 +01:00
m_pConfig - > addConfigValue ( " autogenerated " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " general:col.active_border " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0xffffffff " } ) ;
m_pConfig - > addConfigValue ( " general:col.inactive_border " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0xff444444 " } ) ;
m_pConfig - > addConfigValue ( " general:col.nogroup_border " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0xffffaaff " } ) ;
m_pConfig - > addConfigValue ( " general:col.nogroup_border_active " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0xffff00ff " } ) ;
m_pConfig - > addConfigValue ( " group:col.border_active " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66ffff00 " } ) ;
m_pConfig - > addConfigValue ( " group:col.border_inactive " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66777700 " } ) ;
m_pConfig - > addConfigValue ( " group:col.border_locked_active " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66ff5500 " } ) ;
m_pConfig - > addConfigValue ( " group:col.border_locked_inactive " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66775500 " } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:col.active " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66ffff00 " } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:col.inactive " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66777700 " } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:col.locked_active " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66ff5500 " } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:col.locked_inactive " , Hyprlang : : CConfigCustomValueType { & configHandleGradientSet , configHandleGradientDestroy , " 0x66775500 " } ) ;
2024-07-21 13:09:54 +02:00
m_pConfig - > addConfigValue ( " experimental:explicit_sync " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01: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 22:33:39 +01: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 16:00:34 +01:00
m_pConfig - > addSpecialConfigValue ( " device " , " tap_button_map " , { STRVAL_EMPTY } ) ;
2024-02-29 22:33:39 +01: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 16:00:34 +01:00
m_pConfig - > addSpecialConfigValue ( " device " , " scroll_method " , { STRVAL_EMPTY } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addSpecialConfigValue ( " device " , " scroll_button " , Hyprlang : : INT { 0 } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " scroll_button_lock " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addSpecialConfigValue ( " device " , " scroll_points " , { STRVAL_EMPTY } ) ;
2024-02-29 22:33:39 +01:00
m_pConfig - > addSpecialConfigValue ( " device " , " transform " , Hyprlang : : INT { 0 } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addSpecialConfigValue ( " device " , " output " , { STRVAL_EMPTY } ) ;
2024-03-23 21:31:03 +01: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
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
2024-02-18 16:00:34 +01:00
// keywords
m_pConfig - > registerHandler ( & : : handleRawExec , " exec " , { false } ) ;
m_pConfig - > registerHandler ( & : : handleExecOnce , " exec-once " , { false } ) ;
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 ( ) ;
setDefaultAnimationVars ( ) ;
resetHLConfig ( ) ;
2022-07-01 15:57:56 +02:00
2024-04-29 17:07:35 +02:00
Debug : : log ( INFO ,
2024-03-23 22:10:54 +01:00
" !!!!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-02-18 16:00:34 +01: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 15:54:26 +01:00
2024-02-18 16:00:34 +01:00
if ( ERR . has_value ( ) )
g_pHyprError - > queueCreate ( ERR . value ( ) , CColor { 1.0 , 0.1 , 0.1 , 1.0 } ) ;
2023-03-05 15:54:26 +01:00
}
2024-07-16 21:23:37 +02:00
std : : optional < std : : string > CConfigManager : : generateConfig ( std : : string configPath ) {
std : : string parentPath = std : : filesystem : : path ( configPath ) . parent_path ( ) ;
2023-12-04 02:35:24 +01:00
2024-07-16 21:23:37 +02:00
if ( ! std : : filesystem : : is_directory ( parentPath ) ) {
Debug : : log ( WARN , " Creating config home directory " ) ;
try {
std : : filesystem : : create_directories ( parentPath ) ;
} catch ( std : : exception e ) { throw e ; }
}
2023-12-04 02:35:24 +01:00
2024-07-16 21:23:37 +02: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 21:23:37 +02:00
if ( ! std : : filesystem : : exists ( configPath ) )
return " Config could not be generated. " ;
2024-07-05 22:58:47 +02:00
2024-07-16 21:23:37 +02:00
return configPath ;
2023-07-07 19:19:35 +02:00
}
std : : string CConfigManager : : getMainConfigPath ( ) {
if ( ! g_pCompositor - > explicitConfigPath . empty ( ) )
return g_pCompositor - > explicitConfigPath ;
2024-07-16 21:23:37 +02:00
static const auto paths = Hyprutils : : Path : : findConfig ( ISDEBUG ? " hyprlandd " : " hyprland " ) ;
if ( paths . first . has_value ( ) ) {
return paths . first . value ( ) ;
} else if ( paths . second . has_value ( ) ) {
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. " ) ;
}
std : : optional < std : : string > CConfigManager : : verifyConfigExists ( ) {
std : : string mainConfigPath = getMainConfigPath ( ) ;
if ( ! std : : filesystem : : exists ( mainConfigPath ) )
return " broken config dir? " ;
return { } ;
2023-07-07 19:19:35 +02:00
}
2024-05-25 22:46:07 +02:00
const std : : string CConfigManager : : getConfigString ( ) {
std : : string configString ;
std : : string currFileContent ;
for ( auto path : configPaths ) {
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-21 02:55:13 +01:00
std : : string CConfigManager : : getErrors ( ) {
return m_szConfigErrors ;
}
2024-02-18 16:00:34 +01:00
void CConfigManager : : reload ( ) {
2024-02-20 04:24:10 +01:00
EMIT_HOOK_EVENT ( " preConfigReload " , nullptr ) ;
2024-02-18 16:00:34 +01:00
setDefaultAnimationVars ( ) ;
resetHLConfig ( ) ;
configCurrentPath = getMainConfigPath ( ) ;
const auto ERR = m_pConfig - > parse ( ) ;
postConfigReload ( ERR ) ;
2022-06-30 21:26:00 +02:00
}
2022-07-28 13:28:43 +02:00
void CConfigManager : : setDefaultAnimationVars ( ) {
if ( isFirstLaunch ) {
INITANIMCFG ( " global " ) ;
INITANIMCFG ( " windows " ) ;
2024-02-28 16:00:34 +01:00
INITANIMCFG ( " layers " ) ;
2022-07-28 13:28:43 +02:00
INITANIMCFG ( " fade " ) ;
INITANIMCFG ( " border " ) ;
2023-02-01 22:06:01 +01:00
INITANIMCFG ( " borderangle " ) ;
2022-07-28 13:28:43 +02:00
INITANIMCFG ( " workspaces " ) ;
// windows
INITANIMCFG ( " windowsIn " ) ;
INITANIMCFG ( " windowsOut " ) ;
INITANIMCFG ( " windowsMove " ) ;
2024-04-04 17:41:09 +02:00
// layers
INITANIMCFG ( " layersIn " ) ;
INITANIMCFG ( " layersOut " ) ;
2022-07-28 13:28:43 +02:00
// fade
INITANIMCFG ( " fadeIn " ) ;
INITANIMCFG ( " fadeOut " ) ;
INITANIMCFG ( " fadeSwitch " ) ;
INITANIMCFG ( " fadeShadow " ) ;
2022-08-30 12:46:17 +02:00
INITANIMCFG ( " fadeDim " ) ;
2022-07-28 13:28:43 +02:00
// border
// workspaces
2022-08-26 11:26:23 +02:00
INITANIMCFG ( " specialWorkspace " ) ;
2022-07-28 13:28:43 +02:00
}
2022-09-25 20:07:48 +02:00
2022-07-28 13:28:43 +02:00
// init the values
2022-12-16 18:17:31 +01:00
animationConfig [ " global " ] = { false , " default " , " " , 8.f , 1 , & animationConfig [ " general " ] , nullptr } ;
2022-07-28 13:28:43 +02:00
CREATEANIMCFG ( " windows " , " global " ) ;
2024-02-28 16:00:34 +01:00
CREATEANIMCFG ( " layers " , " global " ) ;
2022-07-28 13:28:43 +02:00
CREATEANIMCFG ( " fade " , " global " ) ;
CREATEANIMCFG ( " border " , " global " ) ;
2023-02-01 22:06:01 +01:00
CREATEANIMCFG ( " borderangle " , " global " ) ;
2022-07-28 13:28:43 +02:00
CREATEANIMCFG ( " workspaces " , " global " ) ;
2024-04-04 17:41:09 +02:00
CREATEANIMCFG ( " layersIn " , " layers " ) ;
CREATEANIMCFG ( " layersOut " , " layers " ) ;
2022-07-28 13:28:43 +02:00
CREATEANIMCFG ( " windowsIn " , " windows " ) ;
CREATEANIMCFG ( " windowsOut " , " windows " ) ;
CREATEANIMCFG ( " windowsMove " , " windows " ) ;
CREATEANIMCFG ( " fadeIn " , " fade " ) ;
CREATEANIMCFG ( " fadeOut " , " fade " ) ;
CREATEANIMCFG ( " fadeSwitch " , " fade " ) ;
CREATEANIMCFG ( " fadeShadow " , " fade " ) ;
2022-08-30 12:46:17 +02:00
CREATEANIMCFG ( " fadeDim " , " fade " ) ;
2024-02-28 16:00:34 +01:00
CREATEANIMCFG ( " fadeLayers " , " fade " ) ;
2024-04-04 17:41:09 +02:00
CREATEANIMCFG ( " fadeLayersIn " , " fadeLayers " ) ;
CREATEANIMCFG ( " fadeLayersOut " , " fadeLayers " ) ;
2022-08-26 11:26:23 +02:00
CREATEANIMCFG ( " specialWorkspace " , " workspaces " ) ;
2022-07-28 13:28:43 +02:00
}
2024-02-18 16:00:34 +01:00
std : : optional < std : : string > CConfigManager : : resetHLConfig ( ) {
m_dMonitorRules . clear ( ) ;
m_dWindowRules . clear ( ) ;
g_pKeybindManager - > clearKeybinds ( ) ;
g_pAnimationManager - > removeAllBeziers ( ) ;
m_mAdditionalReservedAreas . clear ( ) ;
m_dBlurLSNamespaces . clear ( ) ;
m_dWorkspaceRules . clear ( ) ;
setDefaultAnimationVars ( ) ; // reset anims
m_vDeclaredPlugins . clear ( ) ;
m_dLayerRules . clear ( ) ;
m_vFailedPluginConfigValues . clear ( ) ;
2024-01-02 16:38:30 +01:00
2024-02-18 16:00:34 +01:00
// paths
configPaths . clear ( ) ;
std : : string mainConfigPath = getMainConfigPath ( ) ;
Debug : : log ( LOG , " Using config: {} " , mainConfigPath ) ;
configPaths . push_back ( mainConfigPath ) ;
2022-05-16 09:38:42 +02:00
2024-02-18 16:00:34 +01:00
const auto RET = verifyConfigExists ( ) ;
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
return RET ;
}
2022-06-30 21:26:00 +02:00
2024-02-18 16:00:34 +01:00
void CConfigManager : : postConfigReload ( const Hyprlang : : CParseResult & result ) {
for ( auto & w : g_pCompositor - > m_vWindows ) {
w - > uncacheWindowDecos ( ) ;
}
2022-06-30 21:26:00 +02:00
2024-02-18 16:00:34 +01:00
for ( auto & m : g_pCompositor - > m_vMonitors )
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( m - > ID ) ;
2022-06-30 21:26:00 +02:00
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
if ( ! isFirstLaunch )
g_pHyprOpenGL - > m_bReloadScreenShader = true ;
2022-12-21 16:11:39 +01:00
2024-02-18 16:00:34 +01:00
// parseError will be displayed next frame
2024-03-21 02:55:13 +01:00
if ( result . error )
m_szConfigErrors = result . getError ( ) ;
else
m_szConfigErrors = " " ;
2024-02-18 16:00:34 +01:00
if ( result . error & & ! std : : any_cast < Hyprlang : : INT > ( m_pConfig - > getConfigValue ( " debug:suppress_errors " ) ) )
g_pHyprError - > queueCreate ( result . getError ( ) , CColor ( 1.0 , 50.0 / 255.0 , 50.0 / 255.0 , 1.0 ) ) ;
else if ( std : : any_cast < Hyprlang : : INT > ( m_pConfig - > getConfigValue ( " autogenerated " ) ) = = 1 )
g_pHyprError - > queueCreate ( " Warning: You're using an autogenerated config! (config file: " + getMainConfigPath ( ) + " ) \n SUPER+Q -> kitty \n SUPER+M -> exit Hyprland " ,
CColor ( 1.0 , 1.0 , 70.0 / 255.0 , 1.0 ) ) ;
else
g_pHyprError - > destroy ( ) ;
2022-06-30 21:26:00 +02:00
2024-02-18 16:00:34 +01: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 13:32:38 +01:00
2024-02-18 16:00:34 +01:00
if ( ! isFirstLaunch & & ! g_pCompositor - > m_bUnsafeState )
refreshGroupBarGradients ( ) ;
2023-02-27 13:32:38 +01:00
2024-02-18 16:00:34 +01:00
// Updates dynamic window and workspace rules
2024-04-10 18:26:11 +02:00
for ( auto & w : g_pCompositor - > m_vWorkspaces ) {
if ( w - > inert ( ) )
2024-02-18 16:00:34 +01:00
continue ;
2024-04-10 18:26:11 +02:00
g_pCompositor - > updateWorkspaceWindows ( w - > m_iID ) ;
2024-07-11 16:10:42 +02:00
g_pCompositor - > updateWorkspaceWindowData ( w - > m_iID ) ;
2022-06-30 21:26:00 +02:00
}
2022-04-18 13:25:27 +02:00
2024-02-18 16:00:34 +01:00
// Update window border colors
g_pCompositor - > updateAllWindowsAnimatedDecorationValues ( ) ;
2022-06-30 21:38:06 +02:00
2024-02-18 16:00:34 +01:00
// update layout
g_pLayoutManager - > switchToLayout ( std : : any_cast < Hyprlang : : STRING > ( m_pConfig - > getConfigValue ( " general:layout " ) ) ) ;
2022-09-30 18:03:06 +02:00
2024-02-18 16:00:34 +01:00
// manual crash
if ( std : : any_cast < Hyprlang : : INT > ( m_pConfig - > getConfigValue ( " debug:manual_crash " ) ) & & ! m_bManualCrashInitiated ) {
m_bManualCrashInitiated = true ;
g_pHyprNotificationOverlay - > addNotification ( " Manual crash has been set up. Set debug:manual_crash back to 0 in order to crash the compositor. " , CColor ( 0 ) , 5000 , ICON_INFO ) ;
} else if ( m_bManualCrashInitiated & & ! std : : any_cast < Hyprlang : : INT > ( m_pConfig - > getConfigValue ( " debug:manual_crash " ) ) ) {
// cowabunga it is
g_pHyprRenderer - > initiateManualCrash ( ) ;
}
2022-11-26 18:56:43 +01:00
2024-02-18 16:00:34 +01: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 18:17:31 +01:00
2024-04-29 17:07:35 +02:00
Debug : : coloredLogs = reinterpret_cast < int64_t * const * > ( m_pConfig - > getConfigValuePtr ( " debug:colored_stdout_logs " ) - > getDataStaticPtr ( ) ) ;
2024-02-18 16:00:34 +01:00
for ( auto & m : g_pCompositor - > m_vMonitors ) {
// mark blur dirty
g_pHyprOpenGL - > markBlurDirtyForMonitor ( m . get ( ) ) ;
2022-11-26 18:56:43 +01:00
2024-02-18 16:00:34 +01:00
g_pCompositor - > scheduleFrameForMonitor ( m . get ( ) ) ;
2022-11-26 18:56:43 +01:00
2024-02-18 16:00:34 +01: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
for ( auto & mirror : m - > mirrors )
mirror - > forceFullFrames = 3 ;
2024-02-18 16:00:34 +01:00
}
2022-11-26 18:56:43 +01:00
2024-02-18 16:00:34 +01:00
// Reset no monitor reload
m_bNoMonitorReload = false ;
2022-11-26 18:56:43 +01:00
2024-02-18 16:00:34 +01:00
// update plugins
handlePluginLoads ( ) ;
2022-11-26 18:56:43 +01:00
2024-02-18 16:00:34 +01:00
EMIT_HOOK_EVENT ( " configReloaded " , nullptr ) ;
if ( g_pEventManager )
g_pEventManager - > postEvent ( SHyprIPCEvent { " configreloaded " , " " } ) ;
}
2022-11-26 18:56:43 +01:00
2024-02-18 16:00:34 +01:00
void CConfigManager : : init ( ) {
2022-11-26 18:56:43 +01:00
2024-02-18 16:00:34 +01:00
const std : : string CONFIGPATH = getMainConfigPath ( ) ;
reload ( ) ;
2022-11-26 18:56:43 +01:00
2024-02-18 16:00:34 +01:00
struct stat fileStat ;
int err = stat ( CONFIGPATH . c_str ( ) , & fileStat ) ;
if ( err ! = 0 ) {
Debug : : log ( WARN , " Error at statting config, error {} " , errno ) ;
2022-03-17 15:53:45 +01:00
}
2022-12-01 14:36:07 +01:00
2024-02-18 16:00:34 +01:00
configModifyTimes [ CONFIGPATH ] = fileStat . st_mtime ;
2022-12-01 14:36:07 +01:00
2024-02-18 16:00:34 +01:00
isFirstLaunch = false ;
}
2022-12-01 14:36:07 +01:00
2024-02-18 16:00:34 +01:00
std : : string CConfigManager : : parseKeyword ( const std : : string & COMMAND , const std : : string & VALUE ) {
const auto RET = m_pConfig - > parseDynamic ( COMMAND . c_str ( ) , VALUE . c_str ( ) ) ;
// invalidate layouts if they changed
2024-02-24 15:06:28 +01:00
if ( COMMAND = = " monitor " | | COMMAND . contains ( " gaps_ " ) | | COMMAND . starts_with ( " dwindle: " ) | | COMMAND . starts_with ( " master: " ) ) {
for ( auto & m : g_pCompositor - > m_vMonitors )
g_pLayoutManager - > getCurrentLayout ( ) - > recalculateMonitor ( m - > ID ) ;
2024-02-18 16:00:34 +01:00
}
2022-12-01 14:36:07 +01:00
2024-02-18 16:00:34 +01: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 ) {
g_pHyprNotificationOverlay - > addNotification ( " Manual crash has been set up. Set debug:manual_crash back to 0 in order to crash the compositor. " , CColor ( 0 ) , 5000 ,
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 14:36:07 +01:00
}
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
return RET . error ? RET . getError ( ) : " " ;
2022-03-17 15:53:45 +01:00
}
2024-02-18 16:00:34 +01:00
void CConfigManager : : tick ( ) {
std : : string CONFIGPATH = getMainConfigPath ( ) ;
if ( ! std : : filesystem : : exists ( CONFIGPATH ) ) {
Debug : : log ( ERR , " Config doesn't exist?? " ) ;
return ;
}
2023-05-09 15:01:45 +02:00
2024-02-18 16:00:34 +01:00
bool parse = false ;
2023-05-09 15:01:45 +02:00
2024-02-18 16:00:34 +01:00
for ( auto & cf : configPaths ) {
struct stat fileStat ;
int err = stat ( cf . c_str ( ) , & fileStat ) ;
if ( err ! = 0 ) {
Debug : : log ( WARN , " Error at ticking config at {}, error {}: {} " , cf , err , strerror ( err ) ) ;
continue ;
}
2023-05-09 15:01:45 +02:00
2024-02-18 16:00:34 +01:00
// check if we need to reload cfg
if ( fileStat . st_mtime ! = configModifyTimes [ cf ] | | m_bForceReload ) {
parse = true ;
configModifyTimes [ cf ] = fileStat . st_mtime ;
}
2023-05-09 15:01:45 +02:00
}
2024-02-18 16:00:34 +01:00
if ( parse ) {
m_bForceReload = false ;
2023-05-09 15:01:45 +02:00
2024-02-18 16:00:34 +01:00
reload ( ) ;
}
}
2023-05-09 15:01:45 +02:00
2024-02-18 16:00:34 +01: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 16:00:34 +01: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 16:00:34 +01: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 16:00:34 +01:00
return VAL ;
2023-05-09 15:01:45 +02:00
}
2024-02-18 16:00:34 +01: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 16:00:34 +01: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 16:00:34 +01: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 16:00:34 +01:00
}
2023-01-29 17:04:47 +01:00
2024-02-18 16:00:34 +01:00
std : : string CConfigManager : : getDeviceString ( const std : : string & dev , const std : : string & v , const std : : string & fallback ) {
const 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 16:00:34 +01:00
if ( VAL = = STRVAL_EMPTY )
return " " ;
2022-05-29 12:27:45 +02:00
2024-02-18 16:00:34 +01:00
return VAL ;
}
2022-04-27 17:46:07 +02:00
2024-02-27 23:11:59 +01:00
SMonitorRule CConfigManager : : getMonitorRuleFor ( const CMonitor & PMONITOR ) {
2024-05-03 18:58:40 +02:00
for ( auto & r : m_dMonitorRules | std : : views : : reverse ) {
2024-02-27 23:11:59 +01:00
if ( PMONITOR . matchesStaticSelector ( r . name ) ) {
return r ;
2024-02-18 16:00:34 +01:00
}
}
2022-04-27 17:46:07 +02:00
2024-02-27 23:11:59 +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-02-18 16:00:34 +01:00
for ( auto & r : m_dMonitorRules ) {
2024-05-28 23:37:24 +02:00
if ( r . name . empty ( ) ) {
2024-02-27 23:11:59 +01:00
return r ;
2022-04-27 17:46:07 +02:00
}
2024-02-18 16:00:34 +01:00
}
2022-04-17 10:19:46 +02:00
2024-02-18 16:00:34 +01:00
Debug : : log ( WARN , " No rules configured. Using the default hardcoded one. " ) ;
2022-04-17 10:21:54 +02:00
2024-04-25 23:07:50 +02:00
return 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 16:00:34 +01:00
}
2022-04-17 10:19:46 +02:00
2024-04-05 17:54:30 +02:00
SWorkspaceRule CConfigManager : : getWorkspaceRuleFor ( PHLWORKSPACE pWorkspace ) {
SWorkspaceRule mergedRule { } ;
2024-03-31 01:49:53 +01:00
for ( auto & rule : m_dWorkspaceRules ) {
2024-04-05 17:54:30 +02:00
if ( ! pWorkspace - > matchesStaticSelector ( rule . workspaceString ) )
continue ;
2024-04-20 03:20:16 +02:00
mergedRule = mergeWorkspaceRules ( mergedRule , rule ) ;
2024-03-31 01:49:53 +01:00
}
2024-04-05 17:54:30 +02:00
return mergedRule ;
2024-02-18 16:00:34 +01:00
}
2022-03-19 21:46:29 +01:00
2024-04-20 03:20:16 +02:00
SWorkspaceRule CConfigManager : : mergeWorkspaceRules ( const SWorkspaceRule & rule1 , const SWorkspaceRule & rule2 ) {
SWorkspaceRule mergedRule = rule1 ;
2024-05-04 03:18:04 +02: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-20 03:20:16 +02: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 16:10:42 +02:00
if ( rule2 . noBorder . has_value ( ) )
mergedRule . noBorder = rule2 . noBorder ;
if ( rule2 . noRounding . has_value ( ) )
mergedRule . noRounding = rule2 . noRounding ;
2024-04-20 03:20:16 +02:00
if ( rule2 . decorate . has_value ( ) )
mergedRule . decorate = rule2 . decorate ;
2024-07-11 16:10:42 +02:00
if ( rule2 . noShadow . has_value ( ) )
mergedRule . noShadow = rule2 . noShadow ;
2024-04-20 03:20:16 +02: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-04-27 13:43:12 +02:00
std : : vector < SWindowRule > CConfigManager : : getMatchingRules ( PHLWINDOW pWindow , bool dynamic , bool shadowExec ) {
if ( ! valid ( pWindow ) )
2024-02-18 16:00:34 +01:00
return std : : vector < SWindowRule > ( ) ;
2022-03-17 16:56:33 +01:00
2024-05-16 01:55:55 +02:00
// if the window is unmapped, don't process exec rules yet.
shadowExec = shadowExec | | ! pWindow - > m_bIsMapped ;
2024-02-18 16:00:34 +01:00
std : : vector < SWindowRule > returns ;
2022-08-03 21:06:51 +02:00
2024-05-11 00:28:33 +02:00
std : : string title = pWindow - > m_szTitle ;
std : : string appidclass = pWindow - > m_szClass ;
2022-03-17 16:56:33 +01:00
2024-02-18 16:00:34 +01:00
Debug : : log ( LOG , " Searching for matching rules for {} (title: {}) " , appidclass , title ) ;
2022-08-03 21:06:51 +02:00
2024-02-18 16:00:34 +01:00
// since some rules will be applied later, we need to store some flags
bool hasFloating = pWindow - > m_bIsFloating ;
bool hasFullscreen = pWindow - > m_bIsFullscreen ;
2022-04-21 22:15:42 +02:00
2024-05-28 23:37:24 +02:00
// local tags for dynamic tag rule match
auto tags = pWindow - > m_tags ;
2024-02-18 16:00:34 +01:00
for ( auto & rule : m_dWindowRules ) {
// check if we have a matching rule
if ( ! rule . v2 ) {
try {
2024-05-28 23:37:24 +02:00
if ( rule . szValue . starts_with ( " tag: " ) & & ! tags . isTagged ( rule . szValue . substr ( 4 ) ) )
continue ;
2024-02-18 16:00:34 +01:00
if ( rule . szValue . starts_with ( " title: " ) ) {
std : : regex RULECHECK ( rule . szValue . substr ( 6 ) ) ;
2023-05-01 23:28:27 +02:00
2024-02-18 16:00:34 +01:00
if ( ! std : : regex_search ( title , RULECHECK ) )
continue ;
} else {
std : : regex classCheck ( rule . szValue ) ;
2023-05-01 23:28:27 +02:00
2024-02-18 16:00:34 +01:00
if ( ! std : : regex_search ( appidclass , classCheck ) )
continue ;
}
} catch ( . . . ) {
Debug : : log ( ERR , " Regex error at {} " , rule . szValue ) ;
continue ;
}
2022-09-13 15:25:42 +02:00
} else {
2024-02-18 16:00:34 +01:00
try {
2024-05-28 23:37:24 +02:00
if ( ! rule . szTag . empty ( ) & & ! tags . isTagged ( rule . szTag ) )
continue ;
if ( ! rule . szClass . empty ( ) ) {
2024-02-18 16:00:34 +01:00
std : : regex RULECHECK ( rule . szClass ) ;
2022-10-03 15:29:45 +02:00
2024-02-18 16:00:34 +01:00
if ( ! std : : regex_search ( appidclass , RULECHECK ) )
continue ;
}
2022-04-21 22:15:42 +02:00
2024-05-28 23:37:24 +02:00
if ( ! rule . szTitle . empty ( ) ) {
2024-02-18 16:00:34 +01:00
std : : regex RULECHECK ( rule . szTitle ) ;
2022-04-21 17:33:24 +02:00
2024-02-18 16:00:34 +01:00
if ( ! std : : regex_search ( title , RULECHECK ) )
continue ;
}
2022-03-17 16:56:33 +01:00
2024-05-28 23:37:24 +02:00
if ( ! rule . szInitialTitle . empty ( ) ) {
2024-02-18 16:00:34 +01:00
std : : regex RULECHECK ( rule . szInitialTitle ) ;
2022-04-23 21:47:16 +02:00
2024-02-18 16:00:34 +01:00
if ( ! std : : regex_search ( pWindow - > m_szInitialTitle , RULECHECK ) )
continue ;
}
2022-04-23 21:47:16 +02:00
2024-05-28 23:37:24 +02:00
if ( ! rule . szInitialClass . empty ( ) ) {
2024-02-18 16:00:34 +01:00
std : : regex RULECHECK ( rule . szInitialClass ) ;
2022-10-03 15:29:45 +02:00
2024-02-18 16:00:34 +01:00
if ( ! std : : regex_search ( pWindow - > m_szInitialClass , RULECHECK ) )
continue ;
}
2022-07-28 13:28:43 +02:00
2024-02-18 16:00:34 +01:00
if ( rule . bX11 ! = - 1 ) {
if ( pWindow - > m_bIsX11 ! = rule . bX11 )
continue ;
}
2022-07-28 13:28:43 +02:00
2024-02-18 16:00:34 +01:00
if ( rule . bFloating ! = - 1 ) {
if ( hasFloating ! = rule . bFloating )
continue ;
}
2022-05-14 15:56:01 +02:00
2024-02-18 16:00:34 +01:00
if ( rule . bFullscreen ! = - 1 ) {
if ( hasFullscreen ! = rule . bFullscreen )
continue ;
}
2022-05-14 15:56:01 +02:00
2024-02-18 16:00:34 +01:00
if ( rule . bPinned ! = - 1 ) {
if ( pWindow - > m_bPinned ! = rule . bPinned )
continue ;
}
2022-09-25 20:07:48 +02:00
2024-02-18 16:00:34 +01:00
if ( rule . bFocus ! = - 1 ) {
2024-04-27 13:43:12 +02:00
if ( rule . bFocus ! = ( g_pCompositor - > m_pLastWindow . lock ( ) = = pWindow ) )
2024-02-18 16:00:34 +01:00
continue ;
}
2022-05-14 15:56:01 +02:00
2024-03-19 21:56:20 +01:00
if ( ! rule . szOnWorkspace . empty ( ) ) {
2024-04-02 21:32:39 +02:00
const auto PWORKSPACE = pWindow - > m_pWorkspace ;
2024-03-19 21:56:20 +01:00
if ( ! PWORKSPACE | | ! PWORKSPACE - > matchesStaticSelector ( rule . szOnWorkspace ) )
2024-02-18 16:00:34 +01:00
continue ;
}
2022-05-14 15:56:01 +02:00
2024-02-18 16:00:34 +01:00
if ( ! rule . szWorkspace . empty ( ) ) {
2024-04-02 21:32:39 +02:00
const auto PWORKSPACE = pWindow - > m_pWorkspace ;
2022-07-28 13:28:43 +02:00
2024-02-18 16:00:34 +01:00
if ( ! PWORKSPACE )
continue ;
2022-05-14 15:56:01 +02:00
2024-02-18 16:00:34 +01:00
if ( rule . szWorkspace . starts_with ( " name: " ) ) {
if ( PWORKSPACE - > m_szName ! = rule . szWorkspace . substr ( 5 ) )
continue ;
} else {
// number
if ( ! isNumber ( rule . szWorkspace ) )
throw std : : runtime_error ( " szWorkspace not name: or number " ) ;
2022-08-07 19:28:46 +02:00
2024-02-18 16:00:34 +01:00
const int64_t ID = std : : stoll ( rule . szWorkspace ) ;
2023-09-06 12:58:01 +02:00
2024-02-18 16:00:34 +01:00
if ( PWORKSPACE - > m_iID ! = ID )
continue ;
}
}
} catch ( std : : exception & e ) {
Debug : : log ( ERR , " Regex error at {} ({}) " , rule . szValue , e . what ( ) ) ;
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 16:00:34 +01:00
// applies. Read the rule and behave accordingly
Debug : : log ( LOG , " Window rule {} -> {} matched {} " , rule . szRule , rule . szValue , pWindow ) ;
2022-08-07 19:28:46 +02:00
2024-02-18 16:00:34 +01:00
returns . push_back ( rule ) ;
2022-07-28 13:28:43 +02:00
2024-05-28 23:37:24 +02:00
// apply tag with local tags
if ( rule . szRule . starts_with ( " tag " ) ) {
CVarList vars { rule . szRule , 0 , ' s ' , true } ;
if ( vars . size ( ) = = 2 & & vars [ 0 ] = = " tag " )
tags . applyTag ( vars [ 1 ] , true ) ;
}
2024-02-18 16:00:34 +01:00
if ( dynamic )
continue ;
2022-08-07 19:28:46 +02:00
2024-02-18 16:00:34 +01:00
if ( rule . szRule = = " float " )
hasFloating = true ;
else if ( rule . szRule = = " fullscreen " )
hasFullscreen = true ;
2022-08-07 19:28:46 +02:00
}
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
bool anyExecFound = false ;
2022-07-20 22:45:06 +02:00
2024-02-18 16:00:34 +01:00
for ( auto & er : execRequestedRules ) {
if ( std : : ranges : : any_of ( PIDs , [ & ] ( const auto & pid ) { return pid = = er . iPid ; } ) ) {
returns . push_back ( { er . szRule , " execRule " } ) ;
anyExecFound = true ;
2022-07-20 22:33:43 +02:00
}
}
2022-03-19 17:48:18 +01:00
2024-03-02 19:53:11 +01:00
if ( anyExecFound & & ! shadowExec ) // remove exec rules to unclog searches in the future, why have the garbage here.
2024-02-18 16:00:34 +01:00
execRequestedRules . erase ( std : : remove_if ( execRequestedRules . begin ( ) , execRequestedRules . end ( ) ,
[ & ] ( const SExecRequestedRule & other ) { return std : : ranges : : any_of ( PIDs , [ & ] ( const auto & pid ) { return pid = = other . iPid ; } ) ; } ) ) ;
2022-09-19 20:04:48 +02:00
2024-02-18 16:00:34 +01:00
return returns ;
}
2022-03-19 17:48:18 +01:00
2024-04-30 03:41:27 +02:00
std : : vector < SLayerRule > CConfigManager : : getMatchingRules ( PHLLS pLS ) {
2024-02-18 16:00:34 +01:00
std : : vector < SLayerRule > returns ;
2022-09-21 18:41:19 +02:00
2024-02-18 16:00:34 +01:00
if ( ! pLS - > layerSurface | | pLS - > fadingOut )
return returns ;
2022-04-21 15:50:52 +02:00
2024-02-18 16:00:34 +01:00
for ( auto & lr : m_dLayerRules ) {
if ( lr . targetNamespace . starts_with ( " address:0x " ) ) {
2024-04-30 03:41:27 +02:00
if ( std : : format ( " address:0x{:x} " , ( uintptr_t ) pLS . get ( ) ) ! = lr . targetNamespace )
2024-02-18 16:00:34 +01:00
continue ;
} else {
std : : regex NSCHECK ( lr . targetNamespace ) ;
2022-04-21 15:50:52 +02:00
2024-05-09 22:47:21 +02:00
if ( ! std : : regex_search ( pLS - > layerSurface - > layerNamespace , NSCHECK ) )
2024-02-18 16:00:34 +01:00
continue ;
}
2022-05-12 12:41:28 +02:00
2024-02-18 16:00:34 +01:00
// hit
returns . push_back ( lr ) ;
2022-07-08 09:27:17 +02:00
}
2022-04-21 17:06:43 +02:00
2024-05-09 22:47:21 +02:00
if ( shouldBlurLS ( pLS - > layerSurface - > layerNamespace ) )
returns . push_back ( { pLS - > layerSurface - > layerNamespace , " blur " } ) ;
2022-09-06 11:57:11 +02:00
2024-02-18 16:00:34 +01:00
return returns ;
2023-01-25 16:34:13 +01:00
}
2024-02-18 16:00:34 +01:00
void CConfigManager : : dispatchExecOnce ( ) {
if ( firstExecDispatched | | isFirstLaunch )
2022-09-06 11:57:11 +02:00
return ;
2024-02-18 16:00:34 +01:00
// update dbus env
2024-07-21 13:09:54 +02:00
if ( g_pCompositor - > m_pAqBackend - > hasSession ( ) )
2024-02-18 16:00:34 +01:00
handleRawExec ( " " ,
# ifdef USES_SYSTEMD
2024-06-23 09:13:17 +02:00
" systemctl --user import-environment DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS && hash "
2024-02-18 16:00:34 +01:00
" dbus-update-activation-environment 2>/dev/null && "
# endif
2024-06-23 09:13:17 +02:00
" dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE QT_QPA_PLATFORMTHEME PATH XDG_DATA_DIRS " ) ;
2022-11-03 20:52:43 +01:00
2024-02-18 16:00:34 +01:00
firstExecDispatched = true ;
2023-09-12 13:54:05 +02:00
2024-02-18 16:00:34 +01:00
for ( auto & c : firstExecRequests ) {
handleRawExec ( " " , c ) ;
}
2023-09-12 13:54:05 +02:00
2024-02-18 16:00:34 +01:00
firstExecRequests . clear ( ) ; // free some kb of memory :P
2022-05-16 10:09:20 +02:00
2024-02-18 16:00:34 +01:00
// set input, fixes some certain issues
g_pInputManager - > setKeyboardLayout ( ) ;
g_pInputManager - > setPointerConfigs ( ) ;
g_pInputManager - > setTouchDeviceConfigs ( ) ;
g_pInputManager - > setTabletConfigs ( ) ;
2023-09-28 22:48:33 +02:00
2024-02-18 16:00:34 +01:00
// check for user's possible errors with their setup and notify them if needed
g_pCompositor - > performUserChecks ( ) ;
}
2023-09-12 13:54:05 +02:00
2024-05-03 18:58:40 +02:00
void CConfigManager : : appendMonitorRule ( const SMonitorRule & r ) {
m_dMonitorRules . emplace_back ( r ) ;
}
2024-05-23 21:15:31 +02:00
bool CConfigManager : : replaceMonitorRule ( const SMonitorRule & newrule ) {
// Looks for an existing monitor rule (compared by name).
// If the rule exists, it is replaced with the input rule.
for ( auto & r : m_dMonitorRules ) {
if ( r . name = = newrule . name ) {
r = newrule ;
return true ;
}
}
return false ;
}
2024-02-18 16:00:34 +01:00
void CConfigManager : : performMonitorReload ( ) {
2023-09-12 13:54:05 +02:00
2024-02-18 16:00:34 +01:00
bool overAgain = false ;
2023-09-12 13:54:05 +02:00
2024-02-18 16:00:34 +01:00
for ( auto & m : g_pCompositor - > m_vRealMonitors ) {
if ( ! m - > output | | m - > isUnsafeFallback )
continue ;
2022-05-16 10:09:20 +02:00
2024-02-27 23:11:59 +01:00
auto rule = getMonitorRuleFor ( * m ) ;
2023-09-28 22:48:33 +02:00
2024-02-18 16:00:34 +01:00
if ( ! g_pHyprRenderer - > applyMonitorRule ( m . get ( ) , & rule ) ) {
overAgain = true ;
break ;
2022-05-16 10:09:20 +02:00
}
2024-02-18 16:00:34 +01:00
// ensure mirror
m - > setMirror ( rule . mirrorOf ) ;
g_pHyprRenderer - > arrangeLayersForMonitor ( m - > ID ) ;
2022-05-16 10:09:20 +02:00
}
2024-02-18 16:00:34 +01:00
if ( overAgain )
performMonitorReload ( ) ;
m_bWantsMonitorReload = false ;
EMIT_HOOK_EVENT ( " monitorLayoutChanged " , nullptr ) ;
2022-09-12 21:05:52 +02:00
}
2024-02-18 16:00:34 +01: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 14:12:01 +01:00
2024-02-18 16:00:34 +01: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 14:12:01 +01:00
2024-02-18 16:00:34 +01:00
return m_pConfig - > getConfigValuePtr ( name . c_str ( ) ) ;
}
2023-03-05 14:12:01 +01:00
2024-02-18 16:00:34 +01:00
bool CConfigManager : : deviceConfigExists ( const std : : string & dev ) {
auto copy = dev ;
std : : replace ( copy . begin ( ) , copy . end ( ) , ' ' , ' - ' ) ;
2023-03-05 14:15:12 +01:00
2024-02-18 16:00:34 +01:00
return m_pConfig - > specialCategoryExistsForKey ( " device " , copy . c_str ( ) ) ;
2023-03-05 14:12:01 +01:00
}
2024-02-18 16:00:34 +01:00
bool CConfigManager : : shouldBlurLS ( const std : : string & ns ) {
for ( auto & bls : m_dBlurLSNamespaces ) {
if ( bls = = ns ) {
return true ;
}
2023-05-01 16:10:53 +02:00
}
2024-02-18 16:00:34 +01:00
return false ;
2023-05-01 16:10:53 +02:00
}
2024-02-18 16:00:34 +01:00
void CConfigManager : : ensureMonitorStatus ( ) {
for ( auto & rm : g_pCompositor - > m_vRealMonitors ) {
if ( ! rm - > output | | rm - > isUnsafeFallback )
continue ;
2022-04-21 16:56:27 +02:00
2024-02-27 23:11:59 +01:00
auto rule = getMonitorRuleFor ( * rm ) ;
2022-11-28 20:05:50 +01:00
2024-02-18 16:00:34 +01:00
if ( rule . disabled = = rm - > m_bEnabled )
g_pHyprRenderer - > applyMonitorRule ( rm . get ( ) , & rule ) ;
2022-11-28 20:05:50 +01:00
}
2024-02-18 16:00:34 +01:00
}
void CConfigManager : : ensureVRR ( CMonitor * pMonitor ) {
2024-03-03 19:39:20 +01:00
static auto PVRR = reinterpret_cast < Hyprlang : : INT * const * > ( getConfigValuePtr ( " misc:vrr " ) ) ;
2022-04-21 16:56:27 +02:00
2024-03-03 19:39:20 +01:00
static auto ensureVRRForDisplay = [ & ] ( CMonitor * m ) - > void {
2024-02-18 16:00:34 +01:00
if ( ! m - > output | | m - > createdByUser )
return ;
2022-05-25 17:42:38 +02:00
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
if ( USEVRR = = 0 ) {
if ( m - > vrrActive ) {
2024-07-21 13:09:54 +02:00
m - > output - > state - > setAdaptiveSync ( false ) ;
2022-05-26 21:23:13 +02:00
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
m - > vrrActive = false ;
return ;
} else if ( USEVRR = = 1 ) {
if ( ! m - > vrrActive ) {
2024-07-21 13:09:54 +02:00
m - > output - > state - > setAdaptiveSync ( true ) ;
2023-04-04 23:13:31 +02:00
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
}
2022-04-21 16:56:27 +02:00
2024-02-18 16:00:34 +01: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 ) {
/* fullscreen */
m - > vrrActive = true ;
2022-04-21 16:56:27 +02:00
2024-04-02 21:32:39 +02:00
const auto PWORKSPACE = m - > activeWorkspace ;
2022-05-16 09:38:42 +02:00
2024-02-18 16:00:34 +01:00
if ( ! PWORKSPACE )
return ; // ???
2023-12-20 13:07:12 +01:00
2024-02-18 16:00:34 +01:00
const auto WORKSPACEFULL = PWORKSPACE - > m_bHasFullscreenWindow & & PWORKSPACE - > m_efFullscreenMode = = FULLSCREEN_FULL ;
2022-05-16 09:38:42 +02:00
2024-07-21 13:09:54 +02:00
if ( WORKSPACEFULL ) {
m - > output - > state - > setAdaptiveSync ( true ) ;
2022-05-16 09:38:42 +02:00
2024-02-18 16:00:34 +01: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 15:54:26 +01:00
}
2024-02-18 16:00:34 +01: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 ) {
m - > output - > state - > setAdaptiveSync ( false ) ;
2024-02-18 16:00:34 +01:00
if ( ! m - > state . commit ( ) )
Debug : : log ( ERR , " Couldn't commit output {} in ensureVRR -> false " , m - > output - > name ) ;
2023-03-05 15:54:26 +01:00
}
}
2024-02-18 16:00:34 +01:00
} ;
2023-03-05 15:54:26 +01:00
2024-02-18 16:00:34 +01:00
if ( pMonitor ) {
ensureVRRForDisplay ( pMonitor ) ;
return ;
}
2023-12-20 13:07:12 +01:00
2024-02-18 16:00:34 +01:00
for ( auto & m : g_pCompositor - > m_vMonitors ) {
ensureVRRForDisplay ( m . get ( ) ) ;
2022-05-16 09:38:42 +02:00
}
}
2024-02-18 16:00:34 +01:00
SAnimationPropertyConfig * CConfigManager : : getAnimationPropertyConfig ( const std : : string & name ) {
return & animationConfig [ name ] ;
}
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
void CConfigManager : : addParseError ( const std : : string & err ) {
g_pHyprError - > queueCreate ( err + " \n Hyprland may not work correctly. " , CColor ( 1.0 , 50.0 / 255.0 , 50.0 / 255.0 , 1.0 ) ) ;
}
CMonitor * CConfigManager : : getBoundMonitorForWS ( const std : : string & wsname ) {
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 ) {
for ( auto & wr : m_dWorkspaceRules ) {
const auto WSNAME = wr . workspaceName . starts_with ( " name: " ) ? wr . workspaceName . substr ( 5 ) : wr . workspaceName ;
2022-10-25 15:32:25 +02:00
2024-03-19 21:56:20 +01:00
if ( WSNAME = = wsname )
2024-02-18 16:00:34 +01:00
return wr . monitor ;
2022-10-25 15:32:25 +02:00
}
2024-02-18 16:00:34 +01:00
return " " ;
}
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
const std : : deque < SWorkspaceRule > & CConfigManager : : getAllWorkspaceRules ( ) {
return m_dWorkspaceRules ;
}
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
void CConfigManager : : addExecRule ( const SExecRequestedRule & rule ) {
execRequestedRules . push_back ( rule ) ;
}
2022-04-19 18:42:26 +02:00
2024-02-18 16:00:34 +01:00
void CConfigManager : : handlePluginLoads ( ) {
if ( g_pPluginSystem = = nullptr )
2022-03-17 15:53:45 +01:00
return ;
2024-02-18 16:00:34 +01:00
bool pluginsChanged = false ;
auto failedPlugins = g_pPluginSystem - > updateConfigPlugins ( m_vDeclaredPlugins , pluginsChanged ) ;
2022-08-27 23:12:01 +02:00
2024-02-18 16:00:34 +01:00
if ( ! failedPlugins . empty ( ) ) {
std : : stringstream error ;
error < < " Failed to load the following plugins: " ;
2022-08-27 23:12:01 +02:00
2024-02-18 16:00:34 +01:00
for ( auto path : failedPlugins ) {
error < < " \n " < < path ;
}
2022-09-25 20:07:48 +02:00
2024-02-18 16:00:34 +01:00
g_pHyprError - > queueCreate ( error . str ( ) , CColor ( 1.0 , 50.0 / 255.0 , 50.0 / 255.0 , 1.0 ) ) ;
2022-03-17 15:53:45 +01:00
}
2024-02-18 16:00:34 +01:00
if ( pluginsChanged ) {
g_pHyprError - > destroy ( ) ;
m_bForceReload = true ;
tick ( ) ;
}
}
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
ICustomConfigValueData : : ~ ICustomConfigValueData ( ) {
; // empty
}
2022-05-16 09:38:42 +02:00
2024-02-18 16:00:34 +01:00
std : : unordered_map < std : : string , SAnimationPropertyConfig > CConfigManager : : getAnimationConfig ( ) {
return animationConfig ;
}
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
void onPluginLoadUnload ( const std : : string & name , bool load ) {
2022-04-18 13:25:27 +02:00
//
2022-03-17 15:53:45 +01:00
}
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
std : : string field = name . substr ( 7 ) ;
2022-03-17 16:56:33 +01:00
2024-02-18 16:00:34 +01:00
m_pConfig - > addSpecialConfigValue ( " plugin " , field . c_str ( ) , value ) ;
pluginVariables . push_back ( { handle , field } ) ;
}
2023-07-07 19:19:35 +02:00
2024-02-18 16:00:34 +01: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 02:35:24 +01:00
2024-02-18 16:00:34 +01:00
void CConfigManager : : removePluginConfig ( HANDLE handle ) {
for ( auto & k : pluginKeywords ) {
if ( k . handle ! = handle )
continue ;
2022-05-16 10:09:20 +02:00
2024-02-18 16:00:34 +01:00
m_pConfig - > unregisterHandler ( k . name . c_str ( ) ) ;
2023-07-07 19:19:35 +02:00
}
2022-09-25 20:07:48 +02:00
2024-02-18 16:00:34 +01:00
std : : erase_if ( pluginKeywords , [ & ] ( const auto & other ) { return other . handle = = handle ; } ) ;
for ( auto & [ h , n ] : pluginVariables ) {
if ( h ! = handle )
continue ;
2022-04-08 22:07:40 +02:00
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
std : : string CConfigManager : : getDefaultWorkspaceFor ( const std : : string & name ) {
for ( auto other = m_dWorkspaceRules . begin ( ) ; other ! = m_dWorkspaceRules . end ( ) ; + + other ) {
if ( other - > isDefault ) {
if ( other - > monitor = = name )
return other - > workspaceString ;
if ( other - > monitor . substr ( 0 , 5 ) = = " desc: " ) {
auto monitor = g_pCompositor - > getMonitorFromDesc ( other - > monitor . substr ( 5 ) ) ;
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 16:00:34 +01:00
return " " ;
}
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
std : : optional < std : : string > CConfigManager : : handleRawExec ( const std : : string & command , const std : : string & args ) {
if ( isFirstLaunch ) {
firstExecRequests . push_back ( args ) ;
return { } ;
}
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
g_pKeybindManager - > spawn ( args ) ;
return { } ;
}
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
std : : optional < std : : string > CConfigManager : : handleExecOnce ( const std : : string & command , const std : : string & args ) {
if ( isFirstLaunch )
firstExecRequests . push_back ( args ) ;
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
return { } ;
}
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
auto keyword = args [ 0 ] ;
std : : transform ( keyword . begin ( ) , keyword . end ( ) , keyword . begin ( ) , : : tolower ) ;
2023-12-30 15:18:53 +01:00
2024-02-18 16:00:34 +01:00
if ( keyword ! = " modeline " )
return false ;
2022-03-20 11:14:24 +01:00
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
int argno = 1 ;
2022-12-01 14:36:07 +01:00
2024-02-18 16:00:34 +01: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 16:00:34 +01: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 16:00:34 +01: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 18:59:49 +01:00
2024-02-18 16:00:34 +01:00
auto it = flagsmap . find ( key ) ;
2023-07-01 16:30:36 +02:00
2024-02-18 16:00:34 +01:00
if ( it ! = flagsmap . end ( ) )
mode . flags | = it - > second ;
else
Debug : : log ( ERR , " invalid flag {} in modeline " , it - > first ) ;
2023-06-26 13:03:51 +02:00
}
2023-07-01 16:30:36 +02:00
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
return true ;
}
2022-07-16 15:57:31 +02:00
2024-02-18 16:00:34 +01:00
std : : optional < std : : string > CConfigManager : : handleMonitor ( const std : : string & command , const std : : string & args ) {
2023-04-04 15:49:58 +02:00
2024-02-18 16:00:34 +01:00
// get the monitor config
SMonitorRule newrule ;
2023-03-24 20:37:37 +01:00
2024-02-18 16:00:34 +01:00
const auto ARGS = CVarList ( args ) ;
2022-08-01 13:12:50 +02:00
2024-02-18 16:00:34 +01:00
newrule . name = ARGS [ 0 ] ;
2023-08-01 15:47:56 +02:00
2024-02-18 16:00:34 +01: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 ) {
Debug : : log ( ERR , " invalid transform {} in monitor " , TSF ) ;
return " invalid transform " ;
}
2022-09-25 20:07:48 +02:00
2024-02-18 16:00:34 +01:00
const auto TRANSFORM = ( wl_output_transform ) TSF ;
2023-05-01 16:10:53 +02:00
2024-02-18 16:00:34 +01:00
// overwrite if exists
for ( auto & r : m_dMonitorRules ) {
if ( r . name = = newrule . name ) {
r . transform = TRANSFORM ;
return { } ;
}
}
2023-07-10 13:54:06 +02:00
2024-02-18 16:00:34 +01:00
return { } ;
} else if ( ARGS [ 1 ] = = " addreserved " ) {
int top = std : : stoi ( ARGS [ 2 ] ) ;
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
int bottom = std : : stoi ( ARGS [ 3 ] ) ;
2022-04-08 22:07:40 +02:00
2024-02-18 16:00:34 +01:00
int left = std : : stoi ( ARGS [ 4 ] ) ;
2022-05-16 10:09:20 +02:00
2024-02-18 16:00:34 +01:00
int right = std : : stoi ( ARGS [ 5 ] ) ;
2022-05-16 10:09:20 +02:00
2024-02-18 16:00:34 +01: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-02-18 16:00:34 +01:00
std : : erase_if ( m_dMonitorRules , [ & ] ( const auto & other ) { return other . name = = newrule . name ; } ) ;
m_dMonitorRules . push_back ( newrule ) ;
2022-05-16 10:09:20 +02:00
2024-02-18 16:00:34 +01:00
return { } ;
2022-03-17 15:53:45 +01:00
}
2024-03-12 16:37:40 +01:00
std : : string error = " " ;
2024-02-18 16:00:34 +01: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-28 23:37:24 +02:00
newrule . refreshRate = float ( newrule . drmMode . vrefresh ) / 1000 ;
2024-02-18 16:00:34 +01:00
} else {
2022-03-17 15:53:45 +01:00
2024-03-12 16:37:40 +01:00
if ( ! ARGS [ 1 ] . contains ( " x " ) ) {
error + = " invalid resolution " ;
newrule . resolution = Vector2D ( ) ;
} else {
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 ( ' @ ' ) ) ) ;
if ( ARGS [ 1 ] . contains ( " @ " ) )
newrule . refreshRate = stof ( ARGS [ 1 ] . substr ( ARGS [ 1 ] . find_first_of ( ' @ ' ) + 1 ) ) ;
}
2024-02-18 16:00:34 +01:00
}
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
if ( ARGS [ 2 ] . starts_with ( " auto " ) ) {
newrule . offset = Vector2D ( - INT32_MAX , - INT32_MAX ) ;
2024-04-23 02:40:03 +02:00
// If this is the first monitor rule needs to be on the right.
if ( ARGS [ 2 ] = = " auto-right " | | ARGS [ 2 ] = = " auto " | | m_dMonitorRules . empty ( ) )
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 23:07:50 +02: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 16:00:34 +01:00
} else {
2024-03-12 16:37:40 +01: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 16:00:34 +01:00
}
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
if ( ARGS [ 3 ] . starts_with ( " auto " ) ) {
newrule . scale = - 1 ;
} else {
2024-03-12 16:37:40 +01: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 16:00:34 +01:00
int argno = 4 ;
2022-06-30 21:26:00 +02:00
2024-02-18 16:00:34 +01: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 16:37:40 +01: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 16:00:34 +01:00
newrule . transform = ( wl_output_transform ) std : : stoi ( ARGS [ argno + 1 ] ) ;
argno + + ;
} else if ( ARGS [ argno ] = = " vrr " ) {
2024-03-12 16:37:40 +01:00
if ( ! isNumber ( ARGS [ argno + 1 ] ) ) {
error = " invalid vrr " ;
argno + + ;
continue ;
}
2024-02-18 16:00:34 +01:00
newrule . vrr = std : : stoi ( ARGS [ argno + 1 ] ) ;
argno + + ;
} else if ( ARGS [ argno ] = = " workspace " ) {
2024-06-22 23:52:42 +02:00
const auto & [ id , name ] = getWorkspaceIDNameFromString ( ARGS [ argno + 1 ] ) ;
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
SWorkspaceRule wsRule ;
wsRule . monitor = newrule . name ;
wsRule . workspaceString = ARGS [ argno + 1 ] ;
2024-06-22 23:52:42 +02:00
wsRule . workspaceId = id ;
2024-02-18 16:00:34 +01:00
wsRule . workspaceName = name ;
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
m_dWorkspaceRules . emplace_back ( wsRule ) ;
argno + + ;
} else {
Debug : : log ( ERR , " Config error: invalid monitor syntax " ) ;
return " invalid syntax at \" " + ARGS [ argno ] + " \" " ;
}
2023-09-27 20:49:30 +02:00
2024-02-18 16:00:34 +01:00
argno + + ;
}
2022-05-06 14:30:35 +02:00
2024-02-18 16:00:34 +01:00
std : : erase_if ( m_dMonitorRules , [ & ] ( const auto & other ) { return other . name = = newrule . name ; } ) ;
2022-05-06 14:30:35 +02:00
2024-02-18 16:00:34 +01:00
m_dMonitorRules . push_back ( newrule ) ;
2022-03-17 16:56:33 +01:00
2024-02-18 16:00:34 +01:00
if ( error . empty ( ) )
return { } ;
return error ;
2022-06-30 21:26:00 +02:00
}
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
std : : string bezierName = ARGS [ 0 ] ;
2023-09-27 20:49:30 +02:00
2024-02-18 16:00:34 +01: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 16:00:34 +01: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 16:00:34 +01: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 16:00:34 +01: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 16:00:34 +01:00
if ( ARGS [ 5 ] ! = " " )
return " too many arguments " ;
2022-04-10 18:25:45 +02:00
2024-02-18 16:00:34 +01:00
g_pAnimationManager - > addBezierWithName ( bezierName , Vector2D ( p1x , p1y ) , Vector2D ( p2x , p2y ) ) ;
2023-09-27 20:49:30 +02:00
2024-02-18 16:00:34 +01:00
return { } ;
2022-04-10 18:25:45 +02:00
}
2024-02-18 16:00:34 +01:00
void CConfigManager : : setAnimForChildren ( SAnimationPropertyConfig * const ANIM ) {
for ( auto & [ name , anim ] : animationConfig ) {
if ( anim . pParentAnimation = = ANIM & & ! anim . overridden ) {
// if a child isnt overridden, set the values of the parent
anim . pValues = ANIM - > pValues ;
2022-03-17 16:56:33 +01:00
2024-02-18 16:00:34 +01:00
setAnimForChildren ( & anim ) ;
2022-03-17 16:56:33 +01:00
}
}
2024-02-18 16:00:34 +01:00
} ;
2022-03-17 16:56:33 +01:00
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
// Master on/off
2022-03-17 16:56:33 +01:00
2024-02-18 16:00:34 +01:00
// anim name
const auto ANIMNAME = ARGS [ 0 ] ;
2022-03-17 16:56:33 +01:00
2024-02-18 16:00:34 +01:00
const auto PANIM = animationConfig . find ( ANIMNAME ) ;
2022-03-19 17:00:52 +01:00
2024-02-18 16:00:34 +01:00
if ( PANIM = = animationConfig . end ( ) )
return " no such animation " ;
2022-03-24 18:22:01 +01:00
2024-02-18 16:00:34 +01:00
PANIM - > second . overridden = true ;
PANIM - > second . pValues = & PANIM - > second ;
2023-05-01 23:28:27 +02:00
2024-04-20 13:26:48 +02:00
// This helper casts strings like "1", "true", "off", "yes"... to int.
int64_t enabledInt = configStringToInt ( ARGS [ 1 ] ) = = 1 ;
2022-03-24 18:22:01 +01:00
2024-04-20 13:26:48 +02: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 16:00:34 +01:00
return " invalid animation on/off state " ;
2022-03-24 18:22:01 +01:00
2024-04-20 13:26:48 +02:00
PANIM - > second . internalEnabled = configStringToInt ( ARGS [ 1 ] ) = = 1 ;
2024-02-18 16:00:34 +01:00
if ( PANIM - > second . internalEnabled ) {
// speed
if ( isNumber ( ARGS [ 2 ] , true ) ) {
PANIM - > second . internalSpeed = std : : stof ( ARGS [ 2 ] ) ;
2022-03-24 18:22:01 +01:00
2024-02-18 16:00:34 +01:00
if ( PANIM - > second . internalSpeed < = 0 ) {
PANIM - > second . internalSpeed = 1.f ;
return " invalid speed " ;
}
} else {
PANIM - > second . internalSpeed = 10.f ;
return " invalid speed " ;
}
2022-06-24 16:25:57 +02:00
2024-02-18 16:00:34 +01:00
// curve
PANIM - > second . internalBezier = ARGS [ 3 ] ;
2023-07-02 13:02:48 +02:00
2024-02-18 16:00:34 +01:00
if ( ! g_pAnimationManager - > bezierExists ( ARGS [ 3 ] ) ) {
PANIM - > second . internalBezier = " default " ;
return " no such bezier " ;
}
2022-06-24 16:25:57 +02:00
2024-02-18 16:00:34 +01:00
// style
PANIM - > second . internalStyle = ARGS [ 4 ] ;
2022-03-24 18:22:01 +01:00
2024-02-18 16:00:34 +01:00
if ( ARGS [ 4 ] ! = " " ) {
const auto ERR = g_pAnimationManager - > styleValidInConfigVar ( ANIMNAME , ARGS [ 4 ] ) ;
2022-09-06 11:57:11 +02:00
2024-02-18 16:00:34 +01:00
if ( ERR ! = " " )
return ERR ;
}
}
2022-09-06 11:57:11 +02:00
2024-02-18 16:00:34 +01:00
// now, check for children, recursively
setAnimForChildren ( & PANIM - > second ) ;
2022-09-06 11:57:11 +02:00
2024-02-18 16:00:34 +01: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 16:00:34 +01: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 16:00:34 +01: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 ;
bool hasDescription = false ;
2024-07-24 14:10:36 +02: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-02-18 16:00:34 +01:00
for ( auto & arg : BINDARGS ) {
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 12:48:30 +02:00
} else if ( arg = = ' s ' ) {
multiKey = true ;
2024-06-11 19:49:54 +02:00
} else if ( arg = = ' d ' ) {
hasDescription = true ;
2024-07-24 14:10:36 +02:00
} else if ( arg = = ' p ' ) {
dontInhibit = true ;
2024-02-18 16:00:34 +01:00
} else {
return " bind: invalid flag " ;
}
}
2023-12-26 23:47:46 +01:00
2024-02-18 16:00:34 +01:00
if ( release & & repeat )
return " flags r and e are mutually exclusive " ;
2023-12-26 23:47:46 +01:00
2024-02-18 16:00:34 +01: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 16:00:34 +01: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 16:00:34 +01:00
return " bind: too many args " ;
2022-11-15 11:21:26 +01:00
2024-05-16 12:48:30 +02:00
std : : set < xkb_keysym_t > KEYSYMS ;
std : : set < xkb_keysym_t > MODS ;
if ( multiKey ) {
for ( auto splitKey : CVarList ( ARGS [ 1 ] , 8 , ' & ' ) ) {
KEYSYMS . insert ( xkb_keysym_from_name ( splitKey . c_str ( ) , XKB_KEYSYM_CASE_INSENSITIVE ) ) ;
}
for ( auto splitMod : CVarList ( ARGS [ 0 ] , 8 , ' & ' ) ) {
MODS . insert ( xkb_keysym_from_name ( splitMod . c_str ( ) , XKB_KEYSYM_CASE_INSENSITIVE ) ) ;
}
}
2024-02-18 16:00:34 +01: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 12:48:30 +02:00
const auto KEY = multiKey ? " " : ARGS [ 1 ] ;
2023-12-08 17:02:16 +01: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 16:00:34 +01:00
// to lower
std : : transform ( HANDLER . begin ( ) , HANDLER . end ( ) , HANDLER . begin ( ) , : : tolower ) ;
2023-08-02 13:21:38 +02:00
2024-02-18 16:00:34 +01:00
const auto DISPATCHER = g_pKeybindManager - > m_mDispatchers . find ( HANDLER ) ;
2023-08-02 13:21:38 +02:00
2024-02-18 16:00:34 +01:00
if ( DISPATCHER = = g_pKeybindManager - > m_mDispatchers . end ( ) ) {
Debug : : log ( ERR , " Invalid dispatcher! " ) ;
return " Invalid dispatcher, requested \" " + HANDLER + " \" does not exist " ;
}
2022-03-24 18:22:01 +01:00
2024-02-18 16:00:34 +01:00
if ( MOD = = 0 & & MODSTR ! = " " ) {
Debug : : log ( ERR , " Invalid mod! " ) ;
return " Invalid mod, requested mod \" " + MODSTR + " \" is not a valid mod. " ;
}
2022-03-24 18:22:01 +01:00
2024-05-16 12:48:30 +02:00
if ( ( KEY ! = " " ) | | multiKey ) {
2024-03-03 01:17:02 +01:00
SParsedKey parsedKey = parseKey ( KEY ) ;
2024-05-28 23:37:24 +02: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-07-24 14:10:36 +02:00
g_pKeybindManager - > addKeybind ( SKeybind {
parsedKey . key , KEYSYMS , parsedKey . keycode , parsedKey . catchAll , MOD , MODS , HANDLER , COMMAND , locked , m_szCurrentSubmap , DESCRIPTION , release ,
repeat , mouse , nonConsuming , transparent , ignoreMods , multiKey , hasDescription , dontInhibit } ) ;
2024-02-18 16:00:34 +01:00
}
2023-07-02 13:02:48 +02:00
2024-02-18 16:00:34 +01:00
return { } ;
}
2024-02-18 01:13:38 +01:00
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
const auto MOD = g_pKeybindManager - > stringToModMask ( ARGS [ 0 ] ) ;
2023-04-18 12:48:56 +02:00
2024-03-03 01:17:02 +01:00
const auto KEY = parseKey ( ARGS [ 1 ] ) ;
2022-11-10 14:39:23 +01:00
2024-02-18 16:00:34 +01:00
g_pKeybindManager - > removeKeybind ( MOD , KEY ) ;
2022-11-10 14:39:23 +01:00
2024-02-18 16:00:34 +01:00
return { } ;
}
2022-11-10 14:39:23 +01:00
2024-02-18 16:00:34 +01:00
bool windowRuleValid ( const std : : string & RULE ) {
2024-05-28 23:37:24 +02:00
static const auto rules = std : : unordered_set < std : : string > {
2024-07-11 16:10:42 +02:00
" fakefullscreen " , " float " , " fullscreen " , " maximize " , " noinitialfocus " , " pin " , " stayfocused " , " tile " ,
2024-05-28 23:37:24 +02:00
} ;
static const auto rulesPrefix = std : : vector < std : : string > {
" animation " , " bordercolor " , " bordersize " , " center " , " group " , " idleinhibit " , " maxsize " , " minsize " , " monitor " , " move " ,
" opacity " , " plugin: " , " pseudo " , " rounding " , " size " , " suppressevent " , " tag " , " workspace " , " xray " ,
} ;
2024-07-11 16:10:42 +02:00
const auto VALS = CVarList ( RULE , 2 , ' ' ) ;
return rules . contains ( RULE ) | | std : : any_of ( rulesPrefix . begin ( ) , rulesPrefix . end ( ) , [ & RULE ] ( auto prefix ) { return RULE . starts_with ( prefix ) ; } ) | |
( g_pConfigManager - > mbWindowProperties . find ( VALS [ 0 ] ) ! = g_pConfigManager - > mbWindowProperties . end ( ) ) | |
( g_pConfigManager - > miWindowProperties . find ( VALS [ 0 ] ) ! = g_pConfigManager - > miWindowProperties . end ( ) ) ;
2022-04-12 20:02:57 +02:00
}
2024-02-18 16:00:34 +01:00
bool layerRuleValid ( const std : : string & RULE ) {
2024-05-28 23:37:24 +02:00
static const auto rules = std : : unordered_set < std : : string > { " noanim " , " blur " , " blurpopups " , " dimaround " } ;
static const auto rulesPrefix = std : : vector < std : : string > { " ignorealpha " , " ignorezero " , " xray " , " animation " } ;
return rules . contains ( RULE ) | | std : : any_of ( rulesPrefix . begin ( ) , rulesPrefix . end ( ) , [ & RULE ] ( auto prefix ) { return RULE . starts_with ( prefix ) ; } ) ;
2024-02-18 16:00:34 +01:00
}
2023-01-25 16:34:13 +01:00
2024-02-18 16:00:34 +01: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 16:02:00 +01:00
2024-02-18 16:00:34 +01:00
// check rule and value
2024-05-28 23:37:24 +02:00
if ( RULE . empty ( ) | | VALUE . empty ( ) )
2024-02-18 16:00:34 +01:00
return " empty rule? " ;
2023-01-25 16:34:13 +01:00
2024-02-18 16:00:34 +01:00
if ( RULE = = " unset " ) {
std : : erase_if ( m_dWindowRules , [ & ] ( const SWindowRule & other ) { return other . szValue = = VALUE ; } ) ;
return { } ;
}
2023-01-25 16:34:13 +01:00
2024-02-18 16:00:34 +01:00
// verify we support a rule
if ( ! windowRuleValid ( RULE ) ) {
Debug : : log ( ERR , " Invalid rule found: {} " , RULE ) ;
return " Invalid rule: " + RULE ;
2023-01-25 16:34:13 +01:00
}
2024-02-18 16:00:34 +01:00
if ( RULE . starts_with ( " size " ) | | RULE . starts_with ( " maxsize " ) | | RULE . starts_with ( " minsize " ) )
m_dWindowRules . push_front ( { RULE , VALUE } ) ;
else
m_dWindowRules . push_back ( { RULE , VALUE } ) ;
2023-03-18 00:36:36 +01:00
2024-02-18 16:00:34 +01:00
return { } ;
2023-01-25 16:34:13 +01:00
}
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
// check rule and value
2024-05-28 23:37:24 +02:00
if ( RULE . empty ( ) | | VALUE . empty ( ) )
2024-02-18 16:00:34 +01:00
return " empty rule? " ;
2023-03-05 13:52:57 +01:00
2024-02-18 16:00:34 +01:00
if ( RULE = = " unset " ) {
std : : erase_if ( m_dLayerRules , [ & ] ( const SLayerRule & other ) { return other . targetNamespace = = VALUE ; } ) ;
return { } ;
}
2022-04-12 20:02:57 +02:00
2024-02-18 16:00:34 +01:00
if ( ! layerRuleValid ( RULE ) ) {
Debug : : log ( ERR , " Invalid rule found: {} " , RULE ) ;
return " Invalid rule found: " + RULE ;
2022-04-12 20:02:57 +02:00
}
2024-02-18 16:00:34 +01:00
m_dLayerRules . push_back ( { VALUE , RULE } ) ;
2022-07-21 20:30:48 +02:00
2024-02-18 16:00:34 +01:00
for ( auto & m : g_pCompositor - > m_vMonitors )
for ( auto & lsl : m - > m_aLayerSurfaceLayers )
for ( auto & ls : lsl )
ls - > applyRules ( ) ;
2022-07-22 12:37:44 +02:00
2024-02-18 16:00:34 +01:00
return { } ;
2022-04-19 19:01:23 +02:00
}
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
const auto VALUE = value . substr ( value . find_first_of ( ' , ' ) + 1 ) ;
2022-06-30 23:55:28 +02:00
2024-02-18 16:00:34 +01:00
if ( ! windowRuleValid ( RULE ) & & RULE ! = " unset " ) {
Debug : : log ( ERR , " Invalid rulev2 found: {} " , RULE ) ;
return " Invalid rulev2 found: " + RULE ;
}
2022-06-30 23:55:28 +02:00
2024-02-18 16:00:34 +01:00
// now we estract shit from the value
SWindowRule rule ;
rule . v2 = true ;
rule . szRule = RULE ;
rule . szValue = VALUE ;
2023-03-15 16:11:41 +01:00
2024-05-28 23:37:24 +02:00
const auto TAGPOS = VALUE . find ( " tag: " ) ;
2024-02-18 16:00:34 +01:00
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 ONWORKSPACEPOS = VALUE . find ( " onworkspace: " ) ;
2022-09-13 15:25:42 +02:00
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
currentPos = VALUE . find ( " workspace: " , currentPos + 1 ) ;
}
2022-09-08 14:11:32 +02:00
2024-05-28 23:37:24 +02:00
const auto checkPos = std : : unordered_set {
TAGPOS , TITLEPOS , CLASSPOS , INITIALTITLEPOS , INITIALCLASSPOS , X11POS , FLOATPOS , FULLSCREENPOS , PINNEDPOS , WORKSPACEPOS , FOCUSPOS , ONWORKSPACEPOS ,
} ;
if ( checkPos . size ( ) = = 1 & & checkPos . contains ( std : : string : : npos ) ) {
2024-02-18 16:00:34 +01:00
Debug : : log ( ERR , " Invalid rulev2 syntax: {} " , VALUE ) ;
return " Invalid rulev2 syntax: " + VALUE ;
2022-04-19 19:01:23 +02:00
}
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
size_t min = 999999 ;
2024-05-28 23:37:24 +02:00
if ( TAGPOS > pos & & TAGPOS < min )
min = TAGPOS ;
2024-02-18 16:00:34 +01: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 ;
if ( ONWORKSPACEPOS > pos & & ONWORKSPACEPOS < min )
min = ONWORKSPACEPOS ;
if ( WORKSPACEPOS > pos & & WORKSPACEPOS < min )
min = WORKSPACEPOS ;
if ( FOCUSPOS > pos & & FOCUSPOS < min )
min = FOCUSPOS ;
2023-07-18 15:30:28 +02:00
2024-02-18 16:00:34 +01: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 16:27:08 +02:00
if ( ! result . empty ( ) & & result . back ( ) = = ' , ' )
2024-02-18 16:00:34 +01:00
result . pop_back ( ) ;
2023-09-09 13:25:17 +02:00
2024-02-18 16:00:34 +01:00
return result ;
} ;
2023-09-09 13:25:17 +02:00
2024-05-28 23:37:24 +02:00
if ( TAGPOS ! = std : : string : : npos )
rule . szTag = extract ( TAGPOS + 4 ) ;
2024-02-18 16:00:34 +01:00
if ( CLASSPOS ! = std : : string : : npos )
rule . szClass = extract ( CLASSPOS + 6 ) ;
2023-09-09 13:25:17 +02:00
2024-02-18 16:00:34 +01:00
if ( TITLEPOS ! = std : : string : : npos )
rule . szTitle = extract ( TITLEPOS + 6 ) ;
2022-08-11 21:16:38 +02:00
2024-02-18 16:00:34 +01:00
if ( INITIALCLASSPOS ! = std : : string : : npos )
rule . szInitialClass = extract ( INITIALCLASSPOS + 13 ) ;
2023-02-27 13:32:38 +01:00
2024-02-18 16:00:34 +01:00
if ( INITIALTITLEPOS ! = std : : string : : npos )
rule . szInitialTitle = extract ( INITIALTITLEPOS + 13 ) ;
2023-02-27 13:32:38 +01:00
2024-02-18 16:00:34 +01:00
if ( X11POS ! = std : : string : : npos )
rule . bX11 = extract ( X11POS + 9 ) = = " 1 " ? 1 : 0 ;
2022-08-11 21:16:38 +02:00
2024-02-18 16:00:34 +01:00
if ( FLOATPOS ! = std : : string : : npos )
rule . bFloating = extract ( FLOATPOS + 9 ) = = " 1 " ? 1 : 0 ;
2023-09-09 13:25:17 +02:00
2024-02-18 16:00:34 +01:00
if ( FULLSCREENPOS ! = std : : string : : npos )
rule . bFullscreen = extract ( FULLSCREENPOS + 11 ) = = " 1 " ? 1 : 0 ;
2023-09-09 13:25:17 +02:00
2024-02-18 16:00:34 +01:00
if ( PINNEDPOS ! = std : : string : : npos )
rule . bPinned = extract ( PINNEDPOS + 7 ) = = " 1 " ? 1 : 0 ;
2022-08-11 21:16:38 +02:00
2024-02-18 16:00:34 +01:00
if ( WORKSPACEPOS ! = std : : string : : npos )
rule . szWorkspace = extract ( WORKSPACEPOS + 10 ) ;
2022-08-20 18:47:48 +02:00
2024-02-18 16:00:34 +01:00
if ( FOCUSPOS ! = std : : string : : npos )
rule . bFocus = extract ( FOCUSPOS + 6 ) = = " 1 " ? 1 : 0 ;
2022-06-30 21:26:00 +02:00
2024-02-18 16:00:34 +01:00
if ( ONWORKSPACEPOS ! = std : : string : : npos )
2024-03-19 21:56:20 +01:00
rule . szOnWorkspace = extract ( ONWORKSPACEPOS + 12 ) ;
2022-07-06 22:12:03 +02:00
2024-02-18 16:00:34 +01:00
if ( RULE = = " unset " ) {
std : : erase_if ( m_dWindowRules , [ & ] ( const SWindowRule & other ) {
if ( ! other . v2 ) {
return other . szClass = = rule . szClass & & ! rule . szClass . empty ( ) ;
} else {
2024-05-28 23:37:24 +02:00
if ( ! rule . szTag . empty ( ) & & rule . szTag ! = other . szTag )
return false ;
2024-02-18 16:00:34 +01:00
if ( ! rule . szClass . empty ( ) & & rule . szClass ! = other . szClass )
return false ;
2022-07-27 12:32:00 +02:00
2024-02-18 16:00:34 +01:00
if ( ! rule . szTitle . empty ( ) & & rule . szTitle ! = other . szTitle )
return false ;
2023-03-16 15:03:40 +01:00
2024-02-18 16:00:34 +01:00
if ( ! rule . szInitialClass . empty ( ) & & rule . szInitialClass ! = other . szInitialClass )
return false ;
2022-07-27 12:32:00 +02:00
2024-02-18 16:00:34 +01:00
if ( ! rule . szInitialTitle . empty ( ) & & rule . szInitialTitle ! = other . szInitialTitle )
return false ;
if ( rule . bX11 ! = - 1 & & rule . bX11 ! = other . bX11 )
return false ;
if ( rule . bFloating ! = - 1 & & rule . bFloating ! = other . bFloating )
return false ;
if ( rule . bFullscreen ! = - 1 & & rule . bFullscreen ! = other . bFullscreen )
return false ;
if ( rule . bPinned ! = - 1 & & rule . bPinned ! = other . bPinned )
return false ;
if ( ! rule . szWorkspace . empty ( ) & & rule . szWorkspace ! = other . szWorkspace )
return false ;
if ( rule . bFocus ! = - 1 & & rule . bFocus ! = other . bFocus )
return false ;
2024-03-19 21:56:20 +01:00
if ( ! rule . szOnWorkspace . empty ( ) & & rule . szOnWorkspace ! = other . szOnWorkspace )
2024-02-18 16:00:34 +01:00
return false ;
return true ;
}
} ) ;
return { } ;
2022-07-27 12:32:00 +02:00
}
2022-07-28 13:28:43 +02:00
2024-02-18 16:00:34 +01:00
if ( RULE . starts_with ( " size " ) | | RULE . starts_with ( " maxsize " ) | | RULE . starts_with ( " minsize " ) )
m_dWindowRules . push_front ( rule ) ;
else
m_dWindowRules . push_back ( rule ) ;
2022-10-29 00:48:48 +02:00
2024-02-18 16:00:34 +01:00
return { } ;
}
2023-03-16 15:03:40 +01:00
2024-02-18 16:00:34 +01: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-02-18 16:00:34 +01:00
if ( BYADDRESS ) {
matchName = matchName . substr ( 8 ) ;
}
2022-10-22 22:45:17 +02:00
2024-02-18 16:00:34 +01:00
for ( auto & m : g_pCompositor - > m_vMonitors ) {
for ( auto & lsl : m - > m_aLayerSurfaceLayers ) {
for ( auto & ls : lsl ) {
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 22:45:17 +02:00
}
2024-02-18 16:00:34 +01:00
}
}
}
2022-10-22 22:45:17 +02:00
2024-02-18 16:00:34 +01: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 16:00:34 +01:00
if ( std : : erase_if ( m_dBlurLSNamespaces , [ & ] ( const auto & other ) { return other = = TOREMOVE ; } ) )
updateBlurredLS ( TOREMOVE , false ) ;
return { } ;
}
2023-02-14 18:08:42 +01:00
2024-02-18 16:00:34 +01:00
m_dBlurLSNamespaces . emplace_back ( value ) ;
updateBlurredLS ( value , true ) ;
2022-10-22 22:45:17 +02:00
2024-02-18 16:00:34 +01:00
return { } ;
}
2022-10-22 22:45:17 +02:00
2024-02-18 16:00:34 +01: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-22 23:52:42 +02:00
const auto FIRST_DELIM = value . find_first_of ( ' , ' ) ;
2022-10-22 22:45:17 +02:00
2024-06-22 23:52:42 +02: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 16:00:34 +01:00
auto rules = value . substr ( FIRST_DELIM + 1 ) ;
SWorkspaceRule wsRule ;
wsRule . workspaceString = first_ident ;
2024-03-19 21:56:20 +01: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 18:08:42 +01:00
2024-04-06 16:53:32 +02:00
const static std : : string ruleOnCreatedEmpty = " on-created-empty: " ;
const static int ruleOnCreatedEmptyLen = ruleOnCreatedEmpty . length ( ) ;
2022-10-22 22:45:17 +02:00
2024-02-18 16:00:34 +01:00
auto assignRule = [ & ] ( std : : string rule ) - > std : : optional < std : : string > {
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-02-18 16:00:34 +01:00
else if ( ( delim = rule . find ( " border: " ) ) ! = std : : string : : npos )
2024-07-11 16:10:42 +02:00
wsRule . noBorder = ! configStringToInt ( rule . substr ( delim + 7 ) ) ;
2024-02-18 16:00:34 +01:00
else if ( ( delim = rule . find ( " shadow: " ) ) ! = std : : string : : npos )
2024-07-11 16:10:42 +02:00
wsRule . noShadow = ! configStringToInt ( rule . substr ( delim + 7 ) ) ;
2024-02-18 16:00:34 +01:00
else if ( ( delim = rule . find ( " rounding: " ) ) ! = std : : string : : npos )
2024-07-11 16:10:42 +02:00
wsRule . noRounding = ! configStringToInt ( rule . substr ( delim + 9 ) ) ;
2024-02-18 16:00:34 +01:00
else if ( ( delim = rule . find ( " decorate: " ) ) ! = std : : string : : npos )
wsRule . decorate = configStringToInt ( rule . substr ( delim + 9 ) ) ;
else if ( ( delim = rule . find ( " monitor: " ) ) ! = std : : string : : npos )
wsRule . monitor = rule . substr ( delim + 8 ) ;
else if ( ( delim = rule . find ( " default: " ) ) ! = std : : string : : npos )
wsRule . isDefault = configStringToInt ( rule . substr ( delim + 8 ) ) ;
else if ( ( delim = rule . find ( " persistent: " ) ) ! = std : : string : : npos )
wsRule . isPersistent = configStringToInt ( rule . substr ( delim + 11 ) ) ;
2024-02-27 23:44:42 +01:00
else if ( ( delim = rule . find ( " defaultName: " ) ) ! = std : : string : : npos )
wsRule . defaultName = rule . substr ( delim + 12 ) ;
2024-04-06 16:53:32 +02:00
else if ( ( delim = rule . find ( ruleOnCreatedEmpty ) ) ! = std : : string : : npos )
wsRule . onCreatedEmptyRunCmd = cleanCmdForWorkspace ( name , rule . substr ( delim + ruleOnCreatedEmptyLen ) ) ;
2024-02-18 16:00:34 +01:00
else if ( ( delim = rule . find ( " layoutopt: " ) ) ! = std : : string : : npos ) {
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-02-18 16:00:34 +01:00
std : : string val = opt . substr ( opt . find ( " : " ) + 1 ) ;
opt = opt . substr ( 0 , opt . find ( " : " ) ) ;
2023-02-14 18:08:42 +01:00
2024-02-18 16:00:34 +01:00
wsRule . layoutopts [ opt ] = val ;
2022-10-22 22:45:17 +02:00
}
2024-02-18 16:00:34 +01:00
return { } ;
2022-10-29 00:48:48 +02:00
} ;
2024-02-18 16:00:34 +01:00
CVarList rulesList { rules , 0 , ' , ' , true } ;
for ( auto & r : rulesList ) {
const auto R = assignRule ( r ) ;
if ( R . has_value ( ) )
return R ;
2022-10-29 00:48:48 +02:00
}
2024-02-18 16:00:34 +01:00
wsRule . workspaceId = id ;
wsRule . workspaceName = name ;
2022-10-22 22:45:17 +02:00
2024-02-18 16:00:34 +01:00
const auto IT = std : : find_if ( m_dWorkspaceRules . begin ( ) , m_dWorkspaceRules . end ( ) , [ & ] ( const auto & other ) { return other . workspaceString = = wsRule . workspaceString ; } ) ;
2022-08-09 18:13:13 +02:00
2024-02-18 16:00:34 +01:00
if ( IT = = m_dWorkspaceRules . end ( ) )
m_dWorkspaceRules . emplace_back ( wsRule ) ;
else
2024-04-20 03:20:16 +02:00
* IT = mergeWorkspaceRules ( * IT , wsRule ) ;
2022-12-01 14:36:07 +01:00
2024-02-18 16:00:34 +01:00
return { } ;
2022-08-19 20:01:51 +02:00
}
2022-09-12 21:05:52 +02:00
2024-02-18 16:00:34 +01:00
std : : optional < std : : string > CConfigManager : : handleSubmap ( const std : : string & command , const std : : string & submap ) {
if ( submap = = " reset " )
m_szCurrentSubmap = " " ;
2023-07-09 23:10:35 +02:00
else
2024-02-18 16:00:34 +01:00
m_szCurrentSubmap = submap ;
2022-12-09 18:17:02 +01:00
2024-02-18 16:00:34 +01:00
return { } ;
2022-12-09 18:17:02 +01:00
}
2024-02-18 16:00:34 +01: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 " ) ;
return " source path " + rawpath + " bogus! " ;
}
std : : unique_ptr < glob_t , void ( * ) ( glob_t * ) > glob_buf { new glob_t , [ ] ( glob_t * g ) { globfree ( g ) ; } } ;
memset ( glob_buf . get ( ) , 0 , sizeof ( glob_t ) ) ;
2023-05-08 15:37:59 +02:00
2024-02-18 16:00:34 +01: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 18:56:43 +01:00
2024-03-11 02:39:00 +01:00
std : : string errorsFromParsing ;
2024-02-18 16:00:34 +01:00
for ( size_t i = 0 ; i < glob_buf - > gl_pathc ; i + + ) {
auto value = absolutePath ( glob_buf - > gl_pathv [ i ] , configCurrentPath ) ;
2023-05-01 16:10:53 +02:00
2024-02-18 16:00:34 +01: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 16:10:53 +02:00
2024-02-18 16:00:34 +01:00
Debug : : log ( ERR , " source= file doesnt exist " ) ;
return " source file " + value + " doesn't exist! " ;
}
configPaths . push_back ( value ) ;
2023-05-01 16:10:53 +02:00
2024-02-18 16:00:34 +01:00
struct stat fileStat ;
int err = stat ( value . c_str ( ) , & fileStat ) ;
if ( err ! = 0 ) {
Debug : : log ( WARN , " Error at ticking config at {}, error {}: {} " , value , err , strerror ( err ) ) ;
return { } ;
2023-05-01 16:10:53 +02:00
}
2024-02-18 16:00:34 +01:00
configModifyTimes [ value ] = fileStat . st_mtime ;
auto configCurrentPathBackup = configCurrentPath ;
configCurrentPath = value ;
2023-05-01 16:10:53 +02:00
2024-03-11 02:39:00 +01:00
const auto THISRESULT = m_pConfig - > parseFile ( value . c_str ( ) ) ;
2024-02-18 16:00:34 +01:00
configCurrentPath = configCurrentPathBackup ;
2024-03-11 02:39:00 +01:00
if ( THISRESULT . error & & errorsFromParsing . empty ( ) )
errorsFromParsing + = THISRESULT . getError ( ) ;
2023-05-01 16:10:53 +02:00
}
2024-03-11 02:39:00 +01:00
if ( errorsFromParsing . empty ( ) )
return { } ;
return errorsFromParsing ;
2022-11-26 18:56:43 +01:00
}
2023-01-25 16:16:28 +01:00
2024-02-18 16:00:34 +01:00
std : : optional < std : : string > CConfigManager : : handleEnv ( const std : : string & command , const std : : string & value ) {
if ( ! isFirstLaunch )
return { } ;
2023-02-27 13:32:38 +01:00
2024-02-18 16:00:34 +01:00
const auto ARGS = CVarList ( value , 2 ) ;
2023-02-27 13:32:38 +01:00
2024-02-18 16:00:34 +01:00
if ( ARGS [ 0 ] . empty ( ) )
return " env empty " ;
2023-02-27 13:32:38 +01:00
2024-02-18 16:00:34 +01:00
setenv ( ARGS [ 0 ] . c_str ( ) , ARGS [ 1 ] . c_str ( ) , 1 ) ;
2023-07-10 14:13:23 +02:00
2024-02-18 16:00:34 +01: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 13:32:38 +01:00
2024-02-18 16:00:34 +01:00
return { } ;
2023-10-29 17:59:50 +01:00
}
2024-02-18 16:00:34 +01: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 17:12:43 +01:00
2024-02-18 16:00:34 +01:00
m_vDeclaredPlugins . push_back ( path ) ;
return { } ;
2024-02-21 12:07:39 +01:00
}