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"
# include "helpers/VarList.hpp"
2023-11-26 18:59:49 +01:00
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>
2022-03-17 15:53:45 +01:00
# include <algorithm>
# include <fstream>
# include <iostream>
2023-05-01 23:24:51 +02:00
# include <sstream>
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 } ) ;
m_pConfig - > addConfigValue ( " general:apply_sens_to_raw " , { 0L } ) ;
m_pConfig - > addConfigValue ( " general:border_size " , { 1L } ) ;
m_pConfig - > addConfigValue ( " general:no_border_on_floating " , { 0L } ) ;
m_pConfig - > addConfigValue ( " general:border_part_of_window " , { 1L } ) ;
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-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " general:gaps_workspaces " , { 0L } ) ;
m_pConfig - > addConfigValue ( " general:cursor_inactive_timeout " , { 0L } ) ;
m_pConfig - > addConfigValue ( " general:no_cursor_warps " , { 0L } ) ;
m_pConfig - > addConfigValue ( " general:no_focus_fallback " , { 0L } ) ;
m_pConfig - > addConfigValue ( " general:resize_on_border " , { 0L } ) ;
m_pConfig - > addConfigValue ( " general:extend_border_grab_area " , { 15L } ) ;
m_pConfig - > addConfigValue ( " general:hover_icon_on_border " , { 1L } ) ;
m_pConfig - > addConfigValue ( " general:layout " , { " dwindle " } ) ;
m_pConfig - > addConfigValue ( " general:allow_tearing " , { 0L } ) ;
m_pConfig - > addConfigValue ( " misc:disable_hyprland_logo " , { 0L } ) ;
m_pConfig - > addConfigValue ( " misc:disable_splash_rendering " , { 0L } ) ;
2024-02-22 16:28:58 +01:00
m_pConfig - > addConfigValue ( " misc:col.splash " , { 0x55ffffffL } ) ;
2024-02-21 19:31:29 +01:00
m_pConfig - > addConfigValue ( " misc:splash_font_family " , { " Sans " } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " misc:force_default_wallpaper " , { - 1L } ) ;
m_pConfig - > addConfigValue ( " misc:vfr " , { 1L } ) ;
m_pConfig - > addConfigValue ( " misc:vrr " , { 0L } ) ;
m_pConfig - > addConfigValue ( " misc:mouse_move_enables_dpms " , { 0L } ) ;
m_pConfig - > addConfigValue ( " misc:key_press_enables_dpms " , { 0L } ) ;
m_pConfig - > addConfigValue ( " misc:always_follow_on_dnd " , { 1L } ) ;
m_pConfig - > addConfigValue ( " misc:layers_hog_keyboard_focus " , { 1L } ) ;
m_pConfig - > addConfigValue ( " misc:animate_manual_resizes " , { 0L } ) ;
m_pConfig - > addConfigValue ( " misc:animate_mouse_windowdragging " , { 0L } ) ;
m_pConfig - > addConfigValue ( " misc:disable_autoreload " , { 0L } ) ;
m_pConfig - > addConfigValue ( " misc:enable_swallow " , { 0L } ) ;
m_pConfig - > addConfigValue ( " misc:swallow_regex " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " misc:swallow_exception_regex " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " misc:focus_on_activate " , { 0L } ) ;
m_pConfig - > addConfigValue ( " misc:no_direct_scanout " , { 1L } ) ;
m_pConfig - > addConfigValue ( " misc:hide_cursor_on_touch " , { 1L } ) ;
m_pConfig - > addConfigValue ( " misc:mouse_move_focuses_monitor " , { 1L } ) ;
m_pConfig - > addConfigValue ( " misc:render_ahead_of_time " , { 0L } ) ;
m_pConfig - > addConfigValue ( " misc:render_ahead_safezone " , { 1L } ) ;
m_pConfig - > addConfigValue ( " misc:cursor_zoom_factor " , { 1.f } ) ;
m_pConfig - > addConfigValue ( " misc:cursor_zoom_rigid " , { 0L } ) ;
m_pConfig - > addConfigValue ( " misc:allow_session_lock_restore " , { 0L } ) ;
m_pConfig - > addConfigValue ( " misc:close_special_on_empty " , { 1L } ) ;
m_pConfig - > addConfigValue ( " misc:background_color " , { 0xff111111L } ) ;
m_pConfig - > addConfigValue ( " misc:new_window_takes_over_fullscreen " , { 0L } ) ;
m_pConfig - > addConfigValue ( " group:insert_after_current " , { 1L } ) ;
m_pConfig - > addConfigValue ( " group:focus_removed_window " , { 1L } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:enabled " , { 1L } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:font_family " , { " Sans " } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:font_size " , { 8L } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:gradients " , { 1L } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:height " , { 14L } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:priority " , { 3L } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:render_titles " , { 1L } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:scrolling " , { 1L } ) ;
m_pConfig - > addConfigValue ( " group:groupbar:text_color " , { 0xffffffffL } ) ;
m_pConfig - > addConfigValue ( " debug:int " , { 0L } ) ;
m_pConfig - > addConfigValue ( " debug:log_damage " , { 0L } ) ;
m_pConfig - > addConfigValue ( " debug:overlay " , { 0L } ) ;
m_pConfig - > addConfigValue ( " debug:damage_blink " , { 0L } ) ;
m_pConfig - > addConfigValue ( " debug:disable_logs " , { 1L } ) ;
m_pConfig - > addConfigValue ( " debug:disable_time " , { 1L } ) ;
m_pConfig - > addConfigValue ( " debug:enable_stdout_logs " , { 0L } ) ;
m_pConfig - > addConfigValue ( " debug:damage_tracking " , { ( Hyprlang : : INT ) DAMAGE_TRACKING_FULL } ) ;
m_pConfig - > addConfigValue ( " debug:manual_crash " , { 0L } ) ;
m_pConfig - > addConfigValue ( " debug:suppress_errors " , { 0L } ) ;
m_pConfig - > addConfigValue ( " debug:watchdog_timeout " , { 5L } ) ;
m_pConfig - > addConfigValue ( " debug:disable_scale_checks " , { 0L } ) ;
m_pConfig - > addConfigValue ( " decoration:rounding " , { 0L } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:enabled " , { 1L } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:size " , { 8L } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:passes " , { 1L } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:ignore_opacity " , { 0L } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:new_optimizations " , { 1L } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:xray " , { 0L } ) ;
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 } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:special " , { 0L } ) ;
m_pConfig - > addConfigValue ( " decoration:blur:popups " , { 0L } ) ;
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 } ) ;
m_pConfig - > addConfigValue ( " decoration:no_blur_on_oversized " , { 0L } ) ;
m_pConfig - > addConfigValue ( " decoration:drop_shadow " , { 1L } ) ;
m_pConfig - > addConfigValue ( " decoration:shadow_range " , { 4L } ) ;
m_pConfig - > addConfigValue ( " decoration:shadow_render_power " , { 3L } ) ;
m_pConfig - > addConfigValue ( " decoration:shadow_ignore_window " , { 1L } ) ;
m_pConfig - > addConfigValue ( " decoration:shadow_offset " , Hyprlang : : VEC2 { 0 , 0 } ) ;
m_pConfig - > addConfigValue ( " decoration:shadow_scale " , { 1.f } ) ;
m_pConfig - > addConfigValue ( " decoration:col.shadow " , { 0xee1a1a1aL } ) ;
m_pConfig - > addConfigValue ( " decoration:col.shadow_inactive " , { ( Hyprlang : : INT ) INT_MAX } ) ;
m_pConfig - > addConfigValue ( " decoration:dim_inactive " , { 0L } ) ;
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 } ) ;
m_pConfig - > addConfigValue ( " dwindle:pseudotile " , { 0L } ) ;
m_pConfig - > addConfigValue ( " dwindle:force_split " , { 0L } ) ;
m_pConfig - > addConfigValue ( " dwindle:permanent_direction_override " , { 0L } ) ;
m_pConfig - > addConfigValue ( " dwindle:preserve_split " , { 0L } ) ;
m_pConfig - > addConfigValue ( " dwindle:special_scale_factor " , { 1.f } ) ;
m_pConfig - > addConfigValue ( " dwindle:split_width_multiplier " , { 1.0f } ) ;
m_pConfig - > addConfigValue ( " dwindle:no_gaps_when_only " , { 0L } ) ;
m_pConfig - > addConfigValue ( " dwindle:use_active_for_splits " , { 1L } ) ;
m_pConfig - > addConfigValue ( " dwindle:default_split_ratio " , { 1.f } ) ;
m_pConfig - > addConfigValue ( " dwindle:smart_split " , { 0L } ) ;
m_pConfig - > addConfigValue ( " dwindle:smart_resizing " , { 1L } ) ;
m_pConfig - > addConfigValue ( " master:special_scale_factor " , { 1.f } ) ;
m_pConfig - > addConfigValue ( " master:mfact " , { 0.55f } ) ;
m_pConfig - > addConfigValue ( " master:new_is_master " , { 1L } ) ;
m_pConfig - > addConfigValue ( " master:always_center_master " , { 0L } ) ;
m_pConfig - > addConfigValue ( " master:new_on_top " , { 0L } ) ;
m_pConfig - > addConfigValue ( " master:no_gaps_when_only " , { 0L } ) ;
m_pConfig - > addConfigValue ( " master:orientation " , { " left " } ) ;
m_pConfig - > addConfigValue ( " master:inherit_fullscreen " , { 1L } ) ;
m_pConfig - > addConfigValue ( " master:allow_small_split " , { 0L } ) ;
m_pConfig - > addConfigValue ( " master:smart_resizing " , { 1L } ) ;
m_pConfig - > addConfigValue ( " master:drop_at_cursor " , { 1L } ) ;
m_pConfig - > addConfigValue ( " animations:enabled " , { 1L } ) ;
m_pConfig - > addConfigValue ( " animations:first_launch_animation " , { 1L } ) ;
m_pConfig - > addConfigValue ( " input:follow_mouse " , { 1L } ) ;
m_pConfig - > addConfigValue ( " input:mouse_refocus " , { 1L } ) ;
m_pConfig - > addConfigValue ( " input:special_fallthrough " , { 0L } ) ;
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 } ) ;
m_pConfig - > addConfigValue ( " input:repeat_rate " , { 25L } ) ;
m_pConfig - > addConfigValue ( " input:repeat_delay " , { 600L } ) ;
m_pConfig - > addConfigValue ( " input:natural_scroll " , { 0L } ) ;
m_pConfig - > addConfigValue ( " input:numlock_by_default " , { 0L } ) ;
m_pConfig - > addConfigValue ( " input:force_no_accel " , { 0L } ) ;
m_pConfig - > addConfigValue ( " input:float_switch_override_focus " , { 1L } ) ;
m_pConfig - > addConfigValue ( " input:left_handed " , { 0L } ) ;
m_pConfig - > addConfigValue ( " input:scroll_method " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " input:scroll_button " , { 0L } ) ;
m_pConfig - > addConfigValue ( " input:scroll_button_lock " , { 0L } ) ;
m_pConfig - > addConfigValue ( " input:scroll_points " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:natural_scroll " , { 0L } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:disable_while_typing " , { 1L } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:clickfinger_behavior " , { 0L } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:tap_button_map " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:middle_button_emulation " , { 0L } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:tap-to-click " , { 1L } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:tap-and-drag " , { 1L } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:drag_lock " , { 0L } ) ;
m_pConfig - > addConfigValue ( " input:touchpad:scroll_factor " , { 1.f } ) ;
m_pConfig - > addConfigValue ( " input:touchdevice:transform " , { 0L } ) ;
m_pConfig - > addConfigValue ( " input:touchdevice:output " , { STRVAL_EMPTY } ) ;
m_pConfig - > addConfigValue ( " input:touchdevice:enabled " , { 1L } ) ;
m_pConfig - > addConfigValue ( " input:tablet:transform " , { 0L } ) ;
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 } ) ;
m_pConfig - > addConfigValue ( " input:tablet:relative_input " , { 0L } ) ;
m_pConfig - > addConfigValue ( " binds:pass_mouse_when_bound " , { 0L } ) ;
m_pConfig - > addConfigValue ( " binds:scroll_event_delay " , { 300L } ) ;
m_pConfig - > addConfigValue ( " binds:workspace_back_and_forth " , { 0L } ) ;
m_pConfig - > addConfigValue ( " binds:allow_workspace_cycles " , { 0L } ) ;
m_pConfig - > addConfigValue ( " binds:workspace_center_on " , { 1L } ) ;
m_pConfig - > addConfigValue ( " binds:focus_preferred_method " , { 0L } ) ;
m_pConfig - > addConfigValue ( " binds:ignore_group_lock " , { 0L } ) ;
m_pConfig - > addConfigValue ( " binds:movefocus_cycles_fullscreen " , { 1L } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe " , { 0L } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_fingers " , { 3L } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_distance " , { 300L } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_invert " , { 1L } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_min_speed_to_force " , { 30L } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_cancel_ratio " , { 0.5f } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_create_new " , { 1L } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_direction_lock " , { 1L } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_direction_lock_threshold " , { 10L } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_forever " , { 0L } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_numbered " , { 0L } ) ;
m_pConfig - > addConfigValue ( " gestures:workspace_swipe_use_r " , { 0L } ) ;
m_pConfig - > addConfigValue ( " xwayland:use_nearest_neighbor " , { 1L } ) ;
m_pConfig - > addConfigValue ( " xwayland:force_zero_scaling " , { 0L } ) ;
m_pConfig - > addConfigValue ( " opengl:nvidia_anti_flicker " , { 1L } ) ;
2024-02-23 22:21:24 +01:00
m_pConfig - > addConfigValue ( " opengl:force_introspection " , { 2L } ) ;
2024-02-18 16:00:34 +01:00
m_pConfig - > addConfigValue ( " autogenerated " , { 0L } ) ;
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 " } ) ;
// 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 } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " repeat_rate " , { 25L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " repeat_delay " , { 600L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " natural_scroll " , { 0L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " tap_button_map " , { STRVAL_EMPTY } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " numlock_by_default " , { 0L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " disable_while_typing " , { 1L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " clickfinger_behavior " , { 0L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " middle_button_emulation " , { 0L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " tap-to-click " , { 1L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " tap-and-drag " , { 1L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " drag_lock " , { 0L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " left_handed " , { 0L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " scroll_method " , { STRVAL_EMPTY } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " scroll_button " , { 0L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " scroll_button_lock " , { 0L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " scroll_points " , { STRVAL_EMPTY } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " transform " , { 0L } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " output " , { STRVAL_EMPTY } ) ;
m_pConfig - > addSpecialConfigValue ( " device " , " enabled " , { 1L } ) ; // 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 " , { 0L } ) ; // only for tablets
// 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 ( ) ;
Debug : : log ( LOG , " NOTE: further logs to stdout / logfile are disabled by default. Use debug:disable_logs and debug:enable_stdout_logs to override this. " ) ;
setDefaultAnimationVars ( ) ;
resetHLConfig ( ) ;
2022-07-01 15:57:56 +02:00
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
}
2023-07-07 19:19:35 +02:00
std : : string CConfigManager : : getConfigDir ( ) {
static const char * xdgConfigHome = getenv ( " XDG_CONFIG_HOME " ) ;
2023-12-04 02:35:24 +01:00
if ( xdgConfigHome & & std : : filesystem : : path ( xdgConfigHome ) . is_absolute ( ) )
return xdgConfigHome ;
return getenv ( " HOME " ) + std : : string ( " /.config " ) ;
2023-07-07 19:19:35 +02:00
}
std : : string CConfigManager : : getMainConfigPath ( ) {
if ( ! g_pCompositor - > explicitConfigPath . empty ( ) )
return g_pCompositor - > explicitConfigPath ;
return getConfigDir ( ) + " /hypr/ " + ( ISDEBUG ? " hyprlandd.conf " : " hyprland.conf " ) ;
}
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 " ) ;
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 " ) ;
// 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 " ) ;
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 " ) ;
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 " ) ;
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 : : verifyConfigExists ( ) {
std : : string mainConfigPath = getMainConfigPath ( ) ;
2022-09-25 20:07:48 +02:00
2024-02-18 16:00:34 +01:00
if ( g_pCompositor - > explicitConfigPath . empty ( ) & & ! std : : filesystem : : exists ( mainConfigPath ) ) {
std : : string configPath = std : : filesystem : : path ( mainConfigPath ) . parent_path ( ) ;
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
if ( ! std : : filesystem : : is_directory ( configPath ) ) {
Debug : : log ( WARN , " Creating config home directory " ) ;
try {
std : : filesystem : : create_directories ( configPath ) ;
} catch ( . . . ) { return " Broken config file! (Could not create config directory) " ; }
}
2022-03-19 17:00:52 +01:00
2024-02-18 16:00:34 +01:00
Debug : : log ( WARN , " No config file found; attempting to generate. " ) ;
std : : ofstream ofs ;
ofs . open ( mainConfigPath , std : : ios : : trunc ) ;
ofs < < AUTOCONFIG ;
ofs . close ( ) ;
2022-03-19 17:00:52 +01:00
}
2024-02-18 16:00:34 +01:00
if ( ! std : : filesystem : : exists ( mainConfigPath ) )
return " broken config dir? " ;
2022-03-19 17:00:52 +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 : : 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
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
for ( auto & w : g_pCompositor - > m_vWindows ) {
if ( ! w - > m_bIsMapped )
continue ;
w - > updateDynamicRules ( ) ;
w - > updateSpecialRenderData ( ) ;
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-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 ;
}
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 ) {
return std : : any_cast < Hyprlang : : VEC2 > ( getConfigValueSafeDevice ( dev , v , fallback ) - > getValue ( ) ) ;
}
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-18 16:00:34 +01:00
SMonitorRule CConfigManager : : getMonitorRuleFor ( const std : : string & name , const std : : string & displayName ) {
SMonitorRule * found = nullptr ;
2022-04-27 17:46:07 +02:00
2024-02-18 16:00:34 +01:00
for ( auto & r : m_dMonitorRules ) {
if ( r . name = = name | |
( r . name . starts_with ( " desc: " ) & &
( r . name . substr ( 5 ) = = displayName | | r . name . substr ( 5 ) = = removeBeginEndSpacesTabs ( displayName . substr ( 0 , displayName . find_first_of ( ' ( ' ) ) ) ) ) ) {
found = & r ;
break ;
}
}
2022-04-27 17:46:07 +02:00
2024-02-18 16:00:34 +01:00
if ( found )
return * found ;
2022-04-27 17:46:07 +02:00
2024-02-18 16:00:34 +01:00
Debug : : log ( WARN , " No rule found for {}, trying to use the first. " , name ) ;
2022-04-27 17:46:07 +02:00
2024-02-18 16:00:34 +01:00
for ( auto & r : m_dMonitorRules ) {
if ( r . name = = " " ) {
found = & r ;
break ;
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
if ( found )
return * found ;
2022-04-21 17:33:24 +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-02-18 16:00:34 +01:00
return SMonitorRule { . name = " " , . resolution = Vector2D ( 0 , 0 ) , . offset = Vector2D ( - INT32_MAX , - INT32_MAX ) , . scale = - 1 } ; // 0, 0 is preferred and -1, -1 is auto
}
2022-04-17 10:19:46 +02:00
2024-02-18 16:00:34 +01:00
SWorkspaceRule CConfigManager : : getWorkspaceRuleFor ( CWorkspace * pWorkspace ) {
const auto WORKSPACEIDSTR = std : : to_string ( pWorkspace - > m_iID ) ;
const auto IT = std : : find_if ( m_dWorkspaceRules . begin ( ) , m_dWorkspaceRules . end ( ) , [ & ] ( const auto & other ) {
return other . workspaceName = = pWorkspace - > m_szName /* name matches */
| | ( pWorkspace - > m_bIsSpecialWorkspace & & other . workspaceName . starts_with ( " special: " ) & &
other . workspaceName . substr ( 8 ) = = pWorkspace - > m_szName ) /* special and special:name */
| | ( pWorkspace - > m_iID > 0 & & WORKSPACEIDSTR = = other . workspaceName ) ; /* id matches and workspace is numerical */
} ) ;
if ( IT = = m_dWorkspaceRules . end ( ) )
return SWorkspaceRule { } ;
return * IT ;
}
2022-03-19 21:46:29 +01:00
2024-02-18 16:00:34 +01:00
std : : vector < SWindowRule > CConfigManager : : getMatchingRules ( CWindow * pWindow , bool dynamic ) {
if ( ! g_pCompositor - > windowValidMapped ( pWindow ) )
return std : : vector < SWindowRule > ( ) ;
2022-03-17 16:56:33 +01:00
2024-02-18 16:00:34 +01:00
std : : vector < SWindowRule > returns ;
2022-08-03 21:06:51 +02:00
2024-02-18 16:00:34 +01:00
std : : string title = g_pXWaylandManager - > getTitle ( pWindow ) ;
std : : string appidclass = g_pXWaylandManager - > getAppIDClass ( pWindow ) ;
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-02-18 16:00:34 +01:00
for ( auto & rule : m_dWindowRules ) {
// check if we have a matching rule
if ( ! rule . v2 ) {
try {
if ( rule . szValue . starts_with ( " title: " ) ) {
// we have a title rule.
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 {
if ( rule . szClass ! = " " ) {
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-02-18 16:00:34 +01:00
if ( rule . szTitle ! = " " ) {
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-02-18 16:00:34 +01:00
if ( rule . szInitialTitle ! = " " ) {
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-02-18 16:00:34 +01:00
if ( rule . szInitialClass ! = " " ) {
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 ) {
if ( rule . bFocus ! = ( g_pCompositor - > m_pLastWindow = = pWindow ) )
continue ;
}
2022-05-14 15:56:01 +02:00
2024-02-18 16:00:34 +01:00
if ( rule . iOnWorkspace ! = - 1 ) {
if ( rule . iOnWorkspace ! = g_pCompositor - > getWindowsOnWorkspace ( pWindow - > m_iWorkspaceID ) )
continue ;
}
2022-05-14 15:56:01 +02:00
2024-02-18 16:00:34 +01:00
if ( ! rule . szWorkspace . empty ( ) ) {
const auto PWORKSPACE = g_pCompositor - > getWorkspaceByID ( pWindow - > m_iWorkspaceID ) ;
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-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-02-18 16:00:34 +01:00
if ( anyExecFound ) // remove exec rules to unclog searches in the future, why have the garbage here.
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-02-18 16:00:34 +01:00
std : : vector < SLayerRule > CConfigManager : : getMatchingRules ( SLayerSurface * pLS ) {
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 " ) ) {
if ( std : : format ( " address:0x{:x} " , ( uintptr_t ) pLS ) ! = lr . targetNamespace )
continue ;
} else {
std : : regex NSCHECK ( lr . targetNamespace ) ;
2022-04-21 15:50:52 +02:00
2024-02-18 16:00:34 +01:00
if ( ! pLS - > layerSurface - > _namespace | | ! std : : regex_search ( pLS - > layerSurface - > _namespace , NSCHECK ) )
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-02-18 16:00:34 +01:00
if ( pLS - > layerSurface - > _namespace & & shouldBlurLS ( pLS - > layerSurface - > _namespace ) )
returns . push_back ( { pLS - > layerSurface - > _namespace , " 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
if ( g_pCompositor - > m_sWLRSession )
handleRawExec ( " " ,
# ifdef USES_SYSTEMD
" systemctl --user import-environment DISPLAY WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME && hash "
" dbus-update-activation-environment 2>/dev/null && "
# endif
" dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE QT_QPA_PLATFORMTHEME " ) ;
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-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-18 16:00:34 +01:00
auto rule = getMonitorRuleFor ( m - > szName , m - > szDescription ) ;
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-18 16:00:34 +01:00
auto rule = getMonitorRuleFor ( rm - > szName , rm - > szDescription ) ;
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 ) {
static auto * const PVRR = reinterpret_cast < Hyprlang : : INT * const * > ( getConfigValuePtr ( " misc:vrr " ) ) ;
2022-04-21 16:56:27 +02:00
2024-02-18 16:00:34 +01:00
static auto ensureVRRForDisplay = [ & ] ( CMonitor * m ) - > void {
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 ) {
wlr_output_state_set_adaptive_sync_enabled ( m - > state . wlr ( ) , 0 ) ;
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 ) {
wlr_output_state_set_adaptive_sync_enabled ( m - > state . wlr ( ) , 1 ) ;
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 ) ;
wlr_output_state_set_adaptive_sync_enabled ( m - > state . wlr ( ) , 0 ) ;
}
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-02-18 16:00:34 +01:00
const auto PWORKSPACE = g_pCompositor - > getWorkspaceByID ( 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-02-18 16:00:34 +01:00
if ( WORKSPACEFULL & & m - > output - > adaptive_sync_status = = WLR_OUTPUT_ADAPTIVE_SYNC_DISABLED ) {
wlr_output_state_set_adaptive_sync_enabled ( m - > state . wlr ( ) , 1 ) ;
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 ) ;
wlr_output_state_set_adaptive_sync_enabled ( m - > state . wlr ( ) , 0 ) ;
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 ) ;
} else if ( ! WORKSPACEFULL & & m - > output - > adaptive_sync_status = = WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED ) {
wlr_output_state_set_adaptive_sync_enabled ( m - > state . wlr ( ) , 0 ) ;
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-02-18 16:00:34 +01:00
if ( WSNAME = = wsname ) {
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-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 ) ;
newrule . refreshRate = newrule . drmMode . vrefresh / 1000 ;
} 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 ( ' @ ' ) ) ) ;
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
if ( ARGS [ 1 ] . contains ( " @ " ) )
newrule . refreshRate = stof ( ARGS [ 1 ] . substr ( ARGS [ 1 ] . find_first_of ( ' @ ' ) + 1 ) ) ;
}
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 ) ;
} 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 ) ) ;
}
2022-03-17 15:53:45 +01:00
2024-02-18 16:00:34 +01:00
std : : string error = " " ;
2022-06-30 21:26:00 +02:00
2024-02-18 16:00:34 +01:00
if ( ARGS [ 3 ] . starts_with ( " auto " ) ) {
newrule . scale = - 1 ;
} else {
newrule . scale = stof ( ARGS [ 3 ] ) ;
2022-06-30 21:26:00 +02:00
2024-02-18 16:00:34 +01:00
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 " ) {
newrule . transform = ( wl_output_transform ) std : : stoi ( ARGS [ argno + 1 ] ) ;
argno + + ;
} else if ( ARGS [ argno ] = = " vrr " ) {
newrule . vrr = std : : stoi ( ARGS [ argno + 1 ] ) ;
argno + + ;
} else if ( ARGS [ argno ] = = " workspace " ) {
std : : string name = " " ;
int wsId = getWorkspaceIDFromString ( ARGS [ argno + 1 ] , name ) ;
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 ] ;
wsRule . workspaceName = name ;
wsRule . workspaceId = wsId ;
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-02-18 16:00:34 +01:00
// on/off
PANIM - > second . internalEnabled = ARGS [ 1 ] = = " 1 " ;
2022-03-24 18:22:01 +01:00
2024-02-18 16:00:34 +01:00
if ( ARGS [ 1 ] ! = " 0 " & & ARGS [ 1 ] ! = " 1 " )
return " invalid animation on/off state " ;
2022-03-24 18:22:01 +01:00
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-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
bool locked = false ;
bool release = false ;
bool repeat = false ;
bool mouse = false ;
bool nonConsuming = false ;
bool transparent = false ;
bool ignoreMods = false ;
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 ;
} 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-02-18 16:00:34 +01:00
const auto ARGS = CVarList ( value , 4 ) ;
2022-11-15 11:21:26 +01:00
2024-02-18 16:00:34 +01:00
if ( ( ARGS . size ( ) < 3 & & ! mouse ) | | ( ARGS . size ( ) < 3 & & mouse ) )
return " bind: too few args " ;
else if ( ( ARGS . size ( ) > 4 & & ! mouse ) | | ( ARGS . size ( ) > 3 & & mouse ) )
return " bind: too many args " ;
2022-11-15 11:21:26 +01:00
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-02-18 16:00:34 +01:00
const auto KEY = ARGS [ 1 ] ;
2023-12-08 17:02:16 +01:00
2024-02-18 16:00:34 +01:00
auto HANDLER = ARGS [ 2 ] ;
2023-12-20 23:52:18 +01:00
2024-02-18 16:00:34 +01:00
const auto COMMAND = mouse ? HANDLER : ARGS [ 3 ] ;
2023-08-02 13:21:38 +02:00
2024-02-18 16:00:34 +01:00
if ( mouse )
HANDLER = " mouse " ;
2023-08-02 13:21:38 +02:00
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-02-18 16:00:34 +01:00
if ( KEY ! = " " ) {
if ( isNumber ( KEY ) & & std : : stoi ( KEY ) > 9 )
g_pKeybindManager - > addKeybind (
SKeybind { " " , std : : stoi ( KEY ) , MOD , HANDLER , COMMAND , locked , m_szCurrentSubmap , release , repeat , mouse , nonConsuming , transparent , ignoreMods } ) ;
else if ( KEY . starts_with ( " code: " ) & & isNumber ( KEY . substr ( 5 ) ) )
g_pKeybindManager - > addKeybind (
SKeybind { " " , std : : stoi ( KEY . substr ( 5 ) ) , MOD , HANDLER , COMMAND , locked , m_szCurrentSubmap , release , repeat , mouse , nonConsuming , transparent , ignoreMods } ) ;
else
g_pKeybindManager - > addKeybind ( SKeybind { KEY , 0 , MOD , HANDLER , COMMAND , locked , m_szCurrentSubmap , release , repeat , mouse , nonConsuming , transparent , ignoreMods } ) ;
}
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-02-18 16:00:34 +01:00
const auto KEY = 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 ) {
return RULE = = " float " | | RULE = = " tile " | | RULE . starts_with ( " opacity " ) | | RULE . starts_with ( " move " ) | | RULE . starts_with ( " size " ) | | RULE . starts_with ( " minsize " ) | |
RULE . starts_with ( " maxsize " ) | | RULE . starts_with ( " pseudo " ) | | RULE . starts_with ( " monitor " ) | | RULE . starts_with ( " idleinhibit " ) | | RULE = = " nofocus " | | RULE = = " noblur " | |
RULE = = " noshadow " | | RULE = = " nodim " | | RULE = = " noborder " | | RULE = = " opaque " | | RULE = = " forceinput " | | RULE = = " fullscreen " | | RULE = = " fakefullscreen " | |
RULE = = " nomaxsize " | | RULE = = " pin " | | RULE = = " noanim " | | RULE = = " dimaround " | | RULE = = " windowdance " | | RULE = = " maximize " | | RULE = = " keepaspectratio " | |
RULE . starts_with ( " animation " ) | | RULE . starts_with ( " rounding " ) | | RULE . starts_with ( " workspace " ) | | RULE . starts_with ( " bordercolor " ) | | RULE = = " forcergbx " | |
RULE = = " noinitialfocus " | | RULE = = " stayfocused " | | RULE . starts_with ( " bordersize " ) | | RULE . starts_with ( " xray " ) | | RULE . starts_with ( " center " ) | |
RULE . starts_with ( " group " ) | | RULE = = " immediate " | | RULE = = " nearestneighbor " | | RULE . starts_with ( " suppressevent " ) ;
2022-04-12 20:02:57 +02:00
}
2024-02-18 16:00:34 +01:00
bool layerRuleValid ( const std : : string & RULE ) {
return RULE = = " noanim " | | RULE = = " blur " | | RULE . starts_with ( " ignorealpha " ) | | RULE . starts_with ( " ignorezero " ) | | RULE . starts_with ( " xray " ) ;
}
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 ) {
const auto RULE = removeBeginEndSpacesTabs ( value . substr ( 0 , value . find_first_of ( ' , ' ) ) ) ;
const auto VALUE = removeBeginEndSpacesTabs ( 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
if ( RULE = = " " | | VALUE = = " " )
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 ) {
const auto RULE = removeBeginEndSpacesTabs ( value . substr ( 0 , value . find_first_of ( ' , ' ) ) ) ;
const auto VALUE = removeBeginEndSpacesTabs ( 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
if ( RULE = = " " | | VALUE = = " " )
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 ) {
const auto RULE = removeBeginEndSpacesTabs ( value . substr ( 0 , value . find_first_of ( ' , ' ) ) ) ;
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-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-02-18 16:00:34 +01:00
if ( TITLEPOS = = std : : string : : npos & & CLASSPOS = = std : : string : : npos & & INITIALTITLEPOS = = std : : string : : npos & & INITIALCLASSPOS = = std : : string : : npos & &
X11POS = = std : : string : : npos & & FLOATPOS = = std : : string : : npos & & FULLSCREENPOS = = std : : string : : npos & & PINNEDPOS = = std : : string : : npos & & WORKSPACEPOS = = std : : string : : npos & &
FOCUSPOS = = std : : string : : npos & & ONWORKSPACEPOS = = std : : string : : npos ) {
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 ;
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-02-18 16:00:34 +01:00
result = removeBeginEndSpacesTabs ( result ) ;
2022-06-30 21:26:00 +02:00
2024-02-18 16:00:34 +01:00
if ( result . back ( ) = = ' , ' )
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-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 )
rule . iOnWorkspace = configStringToInt ( 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 {
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 ;
if ( rule . iOnWorkspace ! = - 1 & & rule . iOnWorkspace ! = other . iOnWorkspace )
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, " ) ) {
const auto TOREMOVE = removeBeginEndSpacesTabs ( value . substr ( 7 ) ) ;
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
const auto FIRST_DELIM = value . find_first_of ( ' , ' ) ;
2022-10-22 22:45:17 +02:00
2024-02-18 16:00:34 +01:00
std : : string name = " " ;
auto first_ident = removeBeginEndSpacesTabs ( value . substr ( 0 , FIRST_DELIM ) ) ;
int id = getWorkspaceIDFromString ( first_ident , name ) ;
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 ;
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-02-18 16:00:34 +01:00
const static std : : string ruleOnCreatedEmtpy = " on-created-empty: " ;
const static int ruleOnCreatedEmtpyLen = ruleOnCreatedEmtpy . 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 )
wsRule . border = configStringToInt ( rule . substr ( delim + 7 ) ) ;
else if ( ( delim = rule . find ( " shadow: " ) ) ! = std : : string : : npos )
wsRule . shadow = configStringToInt ( rule . substr ( delim + 7 ) ) ;
else if ( ( delim = rule . find ( " rounding: " ) ) ! = std : : string : : npos )
wsRule . rounding = configStringToInt ( rule . substr ( delim + 9 ) ) ;
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 ) ) ;
else if ( ( delim = rule . find ( ruleOnCreatedEmtpy ) ) ! = std : : string : : npos )
wsRule . onCreatedEmptyRunCmd = cleanCmdForWorkspace ( name , rule . substr ( delim + ruleOnCreatedEmtpyLen ) ) ;
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
* 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-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-02-18 16:00:34 +01:00
m_pConfig - > parseFile ( value . c_str ( ) ) ;
configCurrentPath = configCurrentPathBackup ;
2023-05-01 16:10:53 +02:00
}
2024-02-18 16:00:34 +01:00
return { } ;
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
}