2 Commits

Author SHA1 Message Date
end-4 2433298bdd Create README.md 2024-02-22 15:36:20 +07:00
end-4 8db26e9707 stuff 2024-02-22 15:35:06 +07:00
4511 changed files with 207891 additions and 53398 deletions
-576
View File
@@ -1,576 +0,0 @@
[%General]
author=Vince Liuice, based on KvAdapta by Tsu Jan
comment=An uncomplicated theme inspired by the Materia GTK theme
x11drag=none
alt_mnemonic=true
left_tabs=false
attach_active_tab=false
mirror_doc_tabs=true
group_toolbar_buttons=false
toolbar_item_spacing=0
toolbar_interior_spacing=2
spread_progressbar=true
composite=true
menu_shadow_depth=6
spread_menuitems=false
tooltip_shadow_depth=7
splitter_width=1
scroll_width=9
scroll_arrows=false
scroll_min_extent=60
slider_width=2
slider_handle_width=23
slider_handle_length=22
tickless_slider_handle_size=22
center_toolbar_handle=true
check_size=24
textless_progressbar=false
progressbar_thickness=2
menubar_mouse_tracking=true
toolbutton_style=1
double_click=false
translucent_windows=false
blurring=false
popup_blurring=false
vertical_spin_indicators=false
spin_button_width=24
fill_rubberband=false
merge_menubar_with_toolbar=true
small_icon_size=16
large_icon_size=32
button_icon_size=16
toolbar_icon_size=16
combo_as_lineedit=true
animate_states=true
button_contents_shift=false
combo_menu=true
hide_combo_checkboxes=true
combo_focus_rect=false
groupbox_top_label=true
inline_spin_indicators=true
joined_inactive_tabs=false
layout_spacing=3
layout_margin=3
scrollbar_in_view=true
transient_scrollbar=true
transient_groove=false
submenu_overlap=0
tooltip_delay=0
tree_branch_line=false
no_window_pattern=false
opaque=kaffeine,kmplayer,subtitlecomposer,kdenlive,vlc,smplayer,smplayer2,avidemux,avidemux2_qt4,avidemux3_qt4,avidemux3_qt5,kamoso,QtCreator,VirtualBox,trojita,dragon,digikam
reduce_window_opacity=0
respect_DE=true
scrollable_menu=false
submenu_delay=150
no_inactiveness=false
reduce_menu_opacity=0
click_behavior=2
contrast=1.00
dialog_button_layout=0
intensity=1.00
saturation=1.00
shadowless_popup=false
drag_from_buttons=false
menu_blur_radius=0
tooltip_blur_radius=0
[GeneralColors]
window.color=#F5F5F5
base.color=#ffffff
alt.base.color=#f8f8f8
button.color=#f2f2f2
light.color=#ffffff
mid.light.color=#f0f0f0
dark.color=#c8c8c8
mid.color=#e1e1e1
highlight.color=#3c84f7
inactive.highlight.color=#3c84f7
text.color=#444444
window.text.color=#444444
button.text.color=#444444
disabled.text.color=#44444474
tooltip.text.color=#444444
highlight.text.color=#333333
link.color=#0057AE
link.visited.color=#E040FB
progress.indicator.text.color=#444444
[Hacks]
transparent_ktitle_label=true
transparent_dolphin_view=true
transparent_pcmanfm_sidepane=true
blur_translucent=false
transparent_menutitle=true
respect_darkness=true
kcapacitybar_as_progressbar=true
force_size_grip=true
iconless_pushbutton=false
iconless_menu=false
disabled_icon_opacity=100
lxqtmainmenu_iconsize=16
normal_default_pushbutton=true
single_top_toolbar=true
tint_on_mouseover=0
transparent_pcmanfm_view=true
no_selection_tint=true
transparent_arrow_button=true
middle_click_scroll=false
opaque_colors=false
kinetic_scrolling=false
scroll_jump_workaround=true
centered_forms=false
noninteger_translucency=false
style_vertical_toolbars=false
blur_only_active_window=true
[PanelButtonCommand]
frame=true
frame.element=button
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
interior=true
interior.element=button
indicator.size=8
text.normal.color=#444444
text.focus.color=#444444
text.press.color=#333333
text.toggle.color=white
highlight.text.color=white
text.shadow=0
text.margin=4
text.iconspacing=4
indicator.element=arrow
frame.expansion=0
[PanelButtonTool]
inherits=PanelButtonCommand
text.normal.color=#444444
text.focus.color=#444444
text.press.color=#333333
text.toggle.color=white
text.disabled.color=#44444474
text.bold=false
indicator.element=arrow
indicator.size=8
frame.expansion=0
[ToolbarButton]
frame=true
frame.element=tbutton
interior.element=tbutton
frame.top=14
frame.bottom=14
frame.left=14
frame.right=14
indicator.element=tarrow
text.normal.color=#444444
text.focus.color=#444444
text.press.color=#333333
text.toggle.color=#333333
text.disabled.color=#44444474
text.bold=false
frame.expansion=28
[Dock]
inherits=PanelButtonCommand
interior.element=dock
frame.element=dock
frame.top=1
frame.bottom=1
frame.left=1
frame.right=1
text.normal.color=#444444
[DockTitle]
inherits=PanelButtonCommand
frame=false
interior=false
text.normal.color=#444444
text.focus.color=#444444
text.bold=false
[IndicatorSpinBox]
inherits=PanelButtonCommand
frame=true
interior=true
frame.top=2
frame.bottom=2
frame.left=2
frame.right=2
indicator.element=spin
indicator.size=8
text.normal.color=#444444
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
[RadioButton]
inherits=PanelButtonCommand
frame=false
interior.element=radio
text.normal.color=#444444
text.focus.color=#444444
text.press.color=#333333
text.toggle.color=#333333
min_width=+0.3font
min_height=+0.3font
[CheckBox]
inherits=PanelButtonCommand
frame=false
interior.element=checkbox
text.normal.color=#444444
text.focus.color=#444444
text.press.color=#333333
text.toggle.color=#333333
min_width=+0.3font
min_height=+0.3font
[Focus]
inherits=PanelButtonCommand
frame=true
frame.element=focus
frame.top=2
frame.bottom=2
frame.left=2
frame.right=2
frame.patternsize=14
[GenericFrame]
inherits=PanelButtonCommand
frame=true
interior=false
frame.element=common
interior.element=common
frame.top=1
frame.bottom=1
frame.left=1
frame.right=1
[LineEdit]
inherits=PanelButtonCommand
frame.element=lineedit
interior.element=lineedit
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
[ToolbarLineEdit]
frame.element=lineedit
interior.element=lineedit
[DropDownButton]
inherits=PanelButtonCommand
indicator.element=arrow-down
[IndicatorArrow]
indicator.element=arrow
indicator.size=8
[ToolboxTab]
inherits=PanelButtonCommand
text.normal.color=#444444
text.press.color=#333333
text.focus.color=#444444
[Tab]
inherits=PanelButtonCommand
interior.element=tab
text.margin.left=8
text.margin.right=8
text.margin.top=0
text.margin.bottom=0
frame.element=tab
indicator.element=tab
indicator.size=22
frame.top=8
frame.bottom=8
frame.left=8
frame.right=8
text.normal.color=#444444
text.focus.color=#444444
text.press.color=#333333
text.toggle.color=#333333
frame.expansion=0
text.bold=false
[TabFrame]
inherits=PanelButtonCommand
frame.element=tabframe
interior.element=tabframe
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
[TreeExpander]
inherits=PanelButtonCommand
indicator.size=8
indicator.element=tree
[HeaderSection]
inherits=PanelButtonCommand
interior.element=header
frame.element=header
frame.top=0
frame.bottom=1
frame.left=1
frame.right=1
text.normal.color=#444444
text.focus.color=#444444
text.press.color=#333333
text.toggle.color=#333333
frame.expansion=0
[SizeGrip]
indicator.element=resize-grip
[Toolbar]
inherits=PanelButtonCommand
indicator.element=toolbar
indicator.size=5
text.margin=0
interior.element=menubar
frame.element=menubar
text.normal.color=#444444
text.focus.color=#444444
text.press.color=#333333
text.toggle.color=#333333
frame.left=6
frame.right=6
frame.top=0
frame.bottom=1
frame.expansion=0
[Slider]
inherits=PanelButtonCommand
frame.element=slider
focusFrame=true
interior.element=slider
frame.top=3
frame.bottom=3
frame.left=3
frame.right=3
[SliderCursor]
inherits=PanelButtonCommand
frame=false
interior.element=slidercursor
[Progressbar]
inherits=PanelButtonCommand
frame.element=progress
interior.element=progress
text.margin=0
text.normal.color=#444444
text.focus.color=#444444
text.press.color=#333333
text.toggle.color=#333333
text.bold=false
frame.expansion=8
[ProgressbarContents]
inherits=PanelButtonCommand
frame=true
frame.element=progress-pattern
interior.element=progress-pattern
[ItemView]
inherits=PanelButtonCommand
text.margin=0
frame.element=itemview
interior.element=itemview
frame.top=4
frame.bottom=4
frame.left=4
frame.right=4
text.margin.top=0
text.margin.bottom=0
text.margin.left=8
text.margin.right=8
text.normal.color=#444444
text.focus.color=#444444
text.press.color=#333333
text.toggle.color=#333333
min_width=+0.3font
min_height=+0.3font
frame.expansion=0
[Splitter]
interior.element=splitter
frame=false
indicator.size=0
[Scrollbar]
inherits=PanelButtonCommand
indicator.element=arrow
indicator.size=12
[ScrollbarSlider]
inherits=PanelButtonCommand
frame.element=scrollbarslider
interior=false
frame.left=5
frame.right=5
frame.top=5
frame.bottom=5
indicator.element=grip
indicator.size=12
[ScrollbarGroove]
inherits=PanelButtonCommand
interior=false
frame=false
[Menu]
inherits=PanelButtonCommand
frame.top=10
frame.bottom=10
frame.left=10
frame.right=10
frame.element=menu
interior.element=menu
text.normal.color=#444444
text.shadow=false
frame.expansion=0
text.bold=false
[MenuItem]
inherits=PanelButtonCommand
frame=true
frame.element=menuitem
interior.element=menuitem
indicator.element=menuitem
text.normal.color=#444444
text.focus.color=#333333
text.margin.top=0
text.margin.bottom=0
text.margin.left=6
text.margin.right=6
frame.top=4
frame.bottom=4
frame.left=4
frame.right=4
text.bold=false
frame.expansion=0
[MenuBar]
inherits=PanelButtonCommand
frame.element=menubar
interior.element=menubar
frame.bottom=0
text.normal.color=#444444
text.focus.color=#444444
text.press.color=#333333
text.toggle.color=#333333
frame.expansion=0
text.bold=false
[MenuBarItem]
inherits=PanelButtonCommand
interior=true
interior.element=menubaritem
frame.element=menubaritem
frame.top=2
frame.bottom=2
frame.left=2
frame.right=2
text.margin.left=4
text.margin.right=4
text.margin.top=0
text.margin.bottom=0
text.normal.color=#444444
text.focus.color=#444444
text.press.color=#333333
text.toggle.color=#333333
text.bold=false
min_width=+0.3font
min_height=+0.3font
frame.expansion=0
[TitleBar]
inherits=PanelButtonCommand
frame=false
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
interior.element=titlebar
indicator.size=16
indicator.element=mdi
text.normal.color=#444444
text.focus.color=#444444
text.bold=false
text.italic=true
frame.expansion=0
[ComboBox]
inherits=PanelButtonCommand
frame.element=combo
interior.element=combo
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
text.normal.color=#444444
text.focus.color=#424242
text.press.color=#424242
text.toggle.color=#424242
[GroupBox]
inherits=GenericFrame
frame=false
text.shadow=0
text.margin=0
text.normal.color=#444444
text.focus.color=#333333
text.bold=false
frame.expansion=0
[TabBarFrame]
inherits=GenericFrame
frame=false
interior=false
[ToolTip]
inherits=GenericFrame
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
interior=true
text.shadow=0
text.margin=6
interior.element=tooltip
frame.element=tooltip
text.normal.color=#444444
text.focus.color=#333333
text.press.color=#333333
text.toggle.color=#333333
frame.expansion=6
[StatusBar]
inherits=GenericFrame
frame=false
interior=false
[Window]
interior=true
interior.element=window
frame=true
frame.element=window
frame.bottom=10
frame.top=10
File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 170 KiB

@@ -1,569 +0,0 @@
[%General]
author=Vince Liuice, based on KvAdapta by Tsu Jan
comment=An uncomplicated theme inspired by the Materia GTK theme
x11drag=none
alt_mnemonic=true
left_tabs=false
attach_active_tab=false
mirror_doc_tabs=true
group_toolbar_buttons=false
toolbar_item_spacing=0
toolbar_interior_spacing=2
spread_progressbar=true
composite=true
menu_shadow_depth=6
spread_menuitems=false
tooltip_shadow_depth=7
splitter_width=1
scroll_width=9
scroll_arrows=false
scroll_min_extent=60
slider_width=2
slider_handle_width=23
slider_handle_length=22
tickless_slider_handle_size=22
center_toolbar_handle=true
check_size=24
textless_progressbar=false
progressbar_thickness=2
menubar_mouse_tracking=true
toolbutton_style=1
double_click=false
translucent_windows=false
blurring=false
popup_blurring=false
vertical_spin_indicators=false
spin_button_width=24
fill_rubberband=false
merge_menubar_with_toolbar=true
small_icon_size=16
large_icon_size=32
button_icon_size=16
toolbar_icon_size=16
combo_as_lineedit=true
animate_states=true
button_contents_shift=false
combo_menu=true
hide_combo_checkboxes=true
combo_focus_rect=false
groupbox_top_label=true
inline_spin_indicators=true
joined_inactive_tabs=false
layout_spacing=3
layout_margin=3
scrollbar_in_view=true
transient_scrollbar=true
transient_groove=false
submenu_overlap=0
tooltip_delay=0
tree_branch_line=false
no_window_pattern=false
opaque=kaffeine,kmplayer,subtitlecomposer,kdenlive,vlc,smplayer,smplayer2,avidemux,avidemux2_qt4,avidemux3_qt4,avidemux3_qt5,kamoso,QtCreator,VirtualBox,trojita,dragon,digikam
reduce_window_opacity=0
respect_DE=true
scrollable_menu=false
submenu_delay=150
no_inactiveness=false
reduce_menu_opacity=0
click_behavior=2
contrast=1.00
dialog_button_layout=0
intensity=1.00
saturation=1.00
shadowless_popup=false
drag_from_buttons=false
menu_blur_radius=0
tooltip_blur_radius=0
[GeneralColors]
window.color=#2c2c2c
base.color=#2c2c2c
alt.base.color=#2e2e2e
button.color=#4d4d4d
light.color=#535353
mid.light.color=#474747
dark.color=#282828
mid.color=#323232
highlight.color=#5b9bf8
inactive.highlight.color=#5b9bf8
text.color=#dfdfdf
window.text.color=#dfdfdf
button.text.color=#dfdfdf
disabled.text.color=#696969
tooltip.text.color=#efefef
highlight.text.color=#ffffff
link.color=#0057AE
link.visited.color=#E040FB
progress.indicator.text.color=#dfdfdf
[Hacks]
transparent_ktitle_label=true
transparent_dolphin_view=true
transparent_pcmanfm_sidepane=true
blur_translucent=false
transparent_menutitle=true
respect_darkness=true
kcapacitybar_as_progressbar=true
force_size_grip=true
iconless_pushbutton=false
iconless_menu=false
disabled_icon_opacity=100
lxqtmainmenu_iconsize=16
normal_default_pushbutton=true
single_top_toolbar=true
tint_on_mouseover=0
transparent_pcmanfm_view=true
no_selection_tint=true
transparent_arrow_button=true
middle_click_scroll=false
opaque_colors=false
kinetic_scrolling=false
scroll_jump_workaround=true
centered_forms=false
noninteger_translucency=false
style_vertical_toolbars=false
blur_only_active_window=true
[PanelButtonCommand]
frame=true
frame.element=button
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
interior=true
interior.element=button
indicator.size=8
text.normal.color=#dfdfdf
text.focus.color=white
text.press.color=white
text.toggle.color=#ffffff
text.shadow=0
text.margin=4
text.iconspacing=4
indicator.element=arrow
frame.expansion=0
[PanelButtonTool]
inherits=PanelButtonCommand
text.normal.color=#dfdfdf
text.focus.color=white
text.press.color=white
text.toggle.color=#ffffff
text.bold=false
indicator.element=arrow
indicator.size=8
frame.expansion=0
[ToolbarButton]
frame=true
frame.element=tbutton
interior.element=tbutton
frame.top=16
frame.bottom=16
frame.left=16
frame.right=16
indicator.element=tarrow
text.normal.color=#dfdfdf
text.focus.color=white
text.press.color=white
text.toggle.color=white
text.bold=false
frame.expansion=32
[Dock]
inherits=PanelButtonCommand
interior.element=dock
frame.element=dock
frame.top=1
frame.bottom=1
frame.left=1
frame.right=1
text.normal.color=#dfdfdf
[DockTitle]
inherits=PanelButtonCommand
frame=false
interior=false
text.normal.color=#dfdfdf
text.focus.color=white
text.bold=false
[IndicatorSpinBox]
inherits=PanelButtonCommand
frame=true
interior=true
frame.top=2
frame.bottom=2
frame.left=2
frame.right=2
indicator.element=spin
indicator.size=8
text.normal.color=#dfdfdf
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
[RadioButton]
inherits=PanelButtonCommand
frame=false
interior.element=radio
text.normal.color=#dfdfdf
text.focus.color=white
min_width=+0.3font
min_height=+0.3font
[CheckBox]
inherits=PanelButtonCommand
frame=false
interior.element=checkbox
text.normal.color=#dfdfdf
text.focus.color=white
min_width=+0.3font
min_height=+0.3font
[Focus]
inherits=PanelButtonCommand
frame=true
frame.element=focus
frame.top=2
frame.bottom=2
frame.left=2
frame.right=2
frame.patternsize=14
[GenericFrame]
inherits=PanelButtonCommand
frame=true
interior=false
frame.element=common
interior.element=common
frame.top=1
frame.bottom=1
frame.left=1
frame.right=1
[LineEdit]
inherits=PanelButtonCommand
frame.element=lineedit
interior.element=lineedit
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
[ToolbarLineEdit]
frame.element=lineedit
interior.element=lineedit
[DropDownButton]
inherits=PanelButtonCommand
indicator.element=arrow-down
[IndicatorArrow]
indicator.element=arrow
indicator.size=8
[ToolboxTab]
inherits=PanelButtonCommand
text.normal.color=#dfdfdf
text.press.color=#dfdfdf
text.focus.color=white
[Tab]
inherits=PanelButtonCommand
interior.element=tab
text.margin.left=8
text.margin.right=8
text.margin.top=0
text.margin.bottom=0
frame.element=tab
indicator.element=tab
indicator.size=22
frame.top=8
frame.bottom=8
frame.left=8
frame.right=8
text.normal.color=#dfdfdf
text.focus.color=#dfdfdf
text.press.color=white
text.toggle.color=white
frame.expansion=0
text.bold=false
[TabFrame]
inherits=PanelButtonCommand
frame.element=tabframe
interior.element=tabframe
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
[TreeExpander]
inherits=PanelButtonCommand
indicator.size=8
indicator.element=tree
[HeaderSection]
inherits=PanelButtonCommand
interior.element=header
frame.element=header
frame.top=0
frame.bottom=1
frame.left=1
frame.right=1
text.normal.color=#dfdfdf
text.focus.color=white
text.press.color=white
text.toggle.color=white
frame.expansion=0
[SizeGrip]
indicator.element=resize-grip
[Toolbar]
inherits=PanelButtonCommand
indicator.element=toolbar
indicator.size=5
text.margin=0
interior.element=menubar
frame.element=menubar
text.normal.color=#dfdfdf
text.focus.color=white
text.press.color=#dfdfdf
text.toggle.color=white
frame.left=6
frame.right=6
frame.top=0
frame.bottom=1
frame.expansion=0
[Slider]
inherits=PanelButtonCommand
frame.element=slider
focusFrame=true
interior.element=slider
frame.top=3
frame.bottom=3
frame.left=3
frame.right=3
[SliderCursor]
inherits=PanelButtonCommand
frame=false
interior.element=slidercursor
[Progressbar]
inherits=PanelButtonCommand
frame.element=progress
interior.element=progress
text.margin=0
text.normal.color=#dfdfdf
text.focus.color=#dfdfdf
text.press.color=#dfdfdf
text.toggle.color=#dfdfdf
text.bold=false
frame.expansion=8
[ProgressbarContents]
inherits=PanelButtonCommand
frame=true
frame.element=progress-pattern
interior.element=progress-pattern
[ItemView]
inherits=PanelButtonCommand
text.margin=0
frame.element=itemview
interior.element=itemview
frame.top=4
frame.bottom=4
frame.left=4
frame.right=4
text.margin.top=0
text.margin.bottom=0
text.margin.left=8
text.margin.right=8
text.normal.color=#dfdfdf
text.focus.color=#dfdfdf
text.press.color=#ffffff
text.toggle.color=#ffffff
min_width=+0.3font
min_height=+0.3font
frame.expansion=0
[Splitter]
interior.element=splitter
frame=false
indicator.size=0
[Scrollbar]
inherits=PanelButtonCommand
indicator.element=arrow
indicator.size=12
[ScrollbarSlider]
inherits=PanelButtonCommand
frame.element=scrollbarslider
interior=false
frame.left=5
frame.right=5
frame.top=5
frame.bottom=5
indicator.element=grip
indicator.size=12
[ScrollbarGroove]
inherits=PanelButtonCommand
interior=false
frame=false
[Menu]
inherits=PanelButtonCommand
frame.top=10
frame.bottom=10
frame.left=10
frame.right=10
frame.element=menu
interior.element=menu
text.normal.color=#dfdfdf
text.shadow=false
frame.expansion=0
text.bold=false
[MenuItem]
inherits=PanelButtonCommand
frame=true
frame.element=menuitem
interior.element=menuitem
indicator.element=menuitem
text.normal.color=#dfdfdf
text.focus.color=#ffffff
text.margin.top=0
text.margin.bottom=0
text.margin.left=6
text.margin.right=6
frame.top=4
frame.bottom=4
frame.left=4
frame.right=4
text.bold=false
frame.expansion=0
[MenuBar]
inherits=PanelButtonCommand
frame.element=menubar
interior.element=menubar
frame.bottom=0
text.normal.color=#dfdfdf
text.focus.color=#ffffff
text.press.color=#ffffff
text.toggle.color=#ffffff
frame.expansion=0
text.bold=false
[MenuBarItem]
inherits=PanelButtonCommand
interior=true
interior.element=menubaritem
frame.element=menubaritem
frame.top=2
frame.bottom=2
frame.left=2
frame.right=2
text.margin.left=4
text.margin.right=4
text.margin.top=0
text.margin.bottom=0
text.normal.color=#dfdfdf
text.focus.color=#ffffff
text.press.color=#ffffff
text.toggle.color=#ffffff
text.bold=false
min_width=+0.3font
min_height=+0.3font
frame.expansion=0
[TitleBar]
inherits=PanelButtonCommand
frame=false
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
interior.element=titlebar
indicator.size=16
indicator.element=mdi
text.normal.color=#787878
text.focus.color=#dfdfdf
text.bold=false
text.italic=true
frame.expansion=0
[ComboBox]
inherits=PanelButtonCommand
frame.element=combo
interior.element=combo
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
text.focus.color=white
text.press.color=#dfdfdf
text.toggle.color=white
[GroupBox]
inherits=GenericFrame
frame=false
text.shadow=0
text.margin=0
text.normal.color=#dfdfdf
text.focus.color=white
text.bold=false
frame.expansion=0
[TabBarFrame]
inherits=GenericFrame
frame=false
frame.element=tabBarFrame
interior=false
frame.top=0
frame.bottom=0
frame.left=0
frame.right=0
[ToolTip]
inherits=GenericFrame
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
interior=true
text.shadow=0
text.margin=6
interior.element=tooltip
frame.element=tooltip
frame.expansion=6
[StatusBar]
inherits=GenericFrame
frame=false
interior=false
[Window]
interior=true
interior.element=window
frame=true
frame.element=window
frame.bottom=10
frame.top=10
File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 168 KiB

@@ -1,571 +0,0 @@
[%General]
author=Vince Liuice, based on KvAdapta by Tsu Jan
comment=An uncomplicated theme inspired by the Materia GTK theme
x11drag=none
alt_mnemonic=true
left_tabs=false
attach_active_tab=false
mirror_doc_tabs=true
group_toolbar_buttons=false
toolbar_item_spacing=0
toolbar_interior_spacing=2
spread_progressbar=true
composite=true
menu_shadow_depth=6
spread_menuitems=false
tooltip_shadow_depth=7
splitter_width=1
scroll_width=9
scroll_arrows=false
scroll_min_extent=60
slider_width=2
slider_handle_width=23
slider_handle_length=22
tickless_slider_handle_size=22
center_toolbar_handle=true
check_size=24
textless_progressbar=false
progressbar_thickness=2
menubar_mouse_tracking=true
toolbutton_style=1
double_click=false
translucent_windows=false
blurring=false
popup_blurring=false
vertical_spin_indicators=false
spin_button_width=24
fill_rubberband=false
merge_menubar_with_toolbar=true
small_icon_size=16
large_icon_size=32
button_icon_size=16
toolbar_icon_size=16
combo_as_lineedit=true
animate_states=true
button_contents_shift=false
combo_menu=true
hide_combo_checkboxes=true
combo_focus_rect=false
groupbox_top_label=true
inline_spin_indicators=true
joined_inactive_tabs=false
layout_spacing=3
layout_margin=3
scrollbar_in_view=true
transient_scrollbar=true
transient_groove=false
submenu_overlap=0
tooltip_delay=0
tree_branch_line=false
no_window_pattern=false
opaque=kaffeine,kmplayer,subtitlecomposer,kdenlive,vlc,smplayer,smplayer2,avidemux,avidemux2_qt4,avidemux3_qt4,avidemux3_qt5,kamoso,QtCreator,VirtualBox,VirtualBoxVM,trojita,dragon,digikam,lyx
reduce_window_opacity=0
respect_DE=true
scrollable_menu=false
submenu_delay=150
no_inactiveness=false
reduce_menu_opacity=0
click_behavior=2
contrast=1.00
dialog_button_layout=0
intensity=1.00
saturation=1.00
shadowless_popup=false
drag_from_buttons=false
menu_blur_radius=0
tooltip_blur_radius=0
[GeneralColors]
window.color=#0F1416
base.color=#0F1416
alt.base.color=#0F1416
button.color=#1B2022
light.color=#171C1E
mid.light.color=#1B2022
dark.color=#303638
mid.color=#252B2D
highlight.color=#84D2E7
inactive.highlight.color=#84D2E7
text.color=#DEE3E5
window.text.color=#DEE3E5
button.text.color=#DEE3E5
disabled.text.color=#DEE3E5
tooltip.text.color=#DEE3E5
highlight.text.color=#DEE3E5
link.color=#BFC4EB
link.visited.color=#DDE1FF
progress.indicator.text.color=#DEE3E5
[Hacks]
transparent_ktitle_label=true
transparent_dolphin_view=true
transparent_pcmanfm_sidepane=true
blur_translucent=false
transparent_menutitle=true
respect_darkness=true
kcapacitybar_as_progressbar=true
force_size_grip=true
iconless_pushbutton=false
iconless_menu=false
disabled_icon_opacity=100
lxqtmainmenu_iconsize=16
normal_default_pushbutton=true
single_top_toolbar=true
tint_on_mouseover=0
transparent_pcmanfm_view=true
no_selection_tint=true
transparent_arrow_button=true
middle_click_scroll=false
opaque_colors=false
kinetic_scrolling=false
scroll_jump_workaround=true
centered_forms=false
noninteger_translucency=false
style_vertical_toolbars=false
blur_only_active_window=true
[PanelButtonCommand]
frame=true
frame.element=button
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
interior=true
interior.element=button
indicator.size=8
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.press.color=white
text.toggle.color=#ffffff
text.shadow=0
text.margin=4
text.iconspacing=4
indicator.element=arrow
frame.expansion=0
[PanelButtonTool]
inherits=PanelButtonCommand
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.press.color=white
text.toggle.color=#ffffff
text.bold=false
indicator.element=arrow
indicator.size=8
frame.expansion=0
[ToolbarButton]
frame=true
frame.element=tbutton
interior.element=tbutton
frame.top=16
frame.bottom=16
frame.left=16
frame.right=16
indicator.element=tarrow
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.press.color=white
text.toggle.color=white
text.bold=false
frame.expansion=32
[Dock]
inherits=PanelButtonCommand
interior.element=dock
frame.element=dock
frame.top=1
frame.bottom=1
frame.left=1
frame.right=1
text.normal.color=#DEE3E5
[DockTitle]
inherits=PanelButtonCommand
frame=false
interior=false
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.bold=false
[IndicatorSpinBox]
inherits=PanelButtonCommand
frame=true
interior=true
frame.top=2
frame.bottom=2
frame.left=2
frame.right=2
indicator.element=spin
indicator.size=8
text.normal.color=#DEE3E5
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
[RadioButton]
inherits=PanelButtonCommand
frame=false
interior.element=radio
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
min_width=+0.3font
min_height=+0.3font
[CheckBox]
inherits=PanelButtonCommand
frame=false
interior.element=checkbox
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
min_width=+0.3font
min_height=+0.3font
[Focus]
inherits=PanelButtonCommand
frame=true
frame.element=focus
frame.top=2
frame.bottom=2
frame.left=2
frame.right=2
frame.patternsize=14
[GenericFrame]
inherits=PanelButtonCommand
frame=true
interior=false
frame.element=common
interior.element=common
frame.top=1
frame.bottom=1
frame.left=1
frame.right=1
[LineEdit]
inherits=PanelButtonCommand
frame.element=lineedit
interior.element=lineedit
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
[ToolbarLineEdit]
frame.element=lineedit
interior.element=lineedit
[DropDownButton]
inherits=PanelButtonCommand
indicator.element=arrow-down
[IndicatorArrow]
indicator.element=arrow
indicator.size=8
[ToolboxTab]
inherits=PanelButtonCommand
text.normal.color=#DEE3E5
text.press.color=#dfdfdf
text.focus.color=#DEE3E5
[Tab]
inherits=PanelButtonCommand
interior.element=tab
text.margin.left=8
text.margin.right=8
text.margin.top=0
text.margin.bottom=0
frame.element=tab
indicator.element=tab
indicator.size=22
frame.top=8
frame.bottom=8
frame.left=8
frame.right=8
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.press.color=white
text.toggle.color=white
frame.expansion=0
text.bold=false
[TabFrame]
inherits=PanelButtonCommand
frame.element=tabframe
interior.element=tabframe
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
[TreeExpander]
inherits=PanelButtonCommand
indicator.size=8
indicator.element=tree
[HeaderSection]
inherits=PanelButtonCommand
interior.element=header
frame.element=header
frame.top=0
frame.bottom=1
frame.left=1
frame.right=1
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.press.color=white
text.toggle.color=white
frame.expansion=0
[SizeGrip]
indicator.element=resize-grip
[Toolbar]
inherits=PanelButtonCommand
indicator.element=toolbar
indicator.size=5
text.margin=0
interior.element=menubar
frame.element=menubar
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.press.color=#dfdfdf
text.toggle.color=white
frame.left=6
frame.right=6
frame.top=0
frame.bottom=1
frame.expansion=0
[Slider]
inherits=PanelButtonCommand
frame.element=slider
focusFrame=true
interior.element=slider
frame.top=3
frame.bottom=3
frame.left=3
frame.right=3
[SliderCursor]
inherits=PanelButtonCommand
frame=false
interior.element=slidercursor
[Progressbar]
inherits=PanelButtonCommand
frame.element=progress
interior.element=progress
text.margin=0
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.press.color=#dfdfdf
text.toggle.color=#dfdfdf
text.bold=false
frame.expansion=8
[ProgressbarContents]
inherits=PanelButtonCommand
frame=true
frame.element=progress-pattern
interior.element=progress-pattern
[ItemView]
inherits=PanelButtonCommand
text.margin=0
frame.element=itemview
interior.element=itemview
frame.top=4
frame.bottom=4
frame.left=4
frame.right=4
text.margin.top=0
text.margin.bottom=0
text.margin.left=8
text.margin.right=8
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.press.color=#ffffff
text.toggle.color=#ffffff
min_width=+0.3font
min_height=+0.3font
frame.expansion=0
[Splitter]
interior.element=splitter
frame=false
indicator.size=0
[Scrollbar]
inherits=PanelButtonCommand
indicator.element=arrow
indicator.size=12
[ScrollbarSlider]
inherits=PanelButtonCommand
frame.element=scrollbarslider
interior=false
frame.left=5
frame.right=5
frame.top=5
frame.bottom=5
indicator.element=grip
indicator.size=12
[ScrollbarGroove]
inherits=PanelButtonCommand
interior=false
frame=false
[Menu]
inherits=PanelButtonCommand
frame.top=10
frame.bottom=10
frame.left=10
frame.right=10
frame.element=menu
interior.element=menu
text.normal.color=#DEE3E5
text.shadow=false
frame.expansion=0
text.bold=false
[MenuItem]
inherits=PanelButtonCommand
frame=true
frame.element=menuitem
interior.element=menuitem
indicator.element=menuitem
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.margin.top=0
text.margin.bottom=0
text.margin.left=6
text.margin.right=6
frame.top=4
frame.bottom=4
frame.left=4
frame.right=4
text.bold=false
frame.expansion=0
[MenuBar]
inherits=PanelButtonCommand
frame.element=menubar
interior.element=menubar
frame.bottom=0
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.press.color=#ffffff
text.toggle.color=#ffffff
frame.expansion=0
text.bold=false
[MenuBarItem]
inherits=PanelButtonCommand
interior=true
interior.element=menubaritem
frame.element=menubaritem
frame.top=2
frame.bottom=2
frame.left=2
frame.right=2
text.margin.left=4
text.margin.right=4
text.margin.top=0
text.margin.bottom=0
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.press.color=#ffffff
text.toggle.color=#ffffff
text.bold=false
min_width=+0.3font
min_height=+0.3font
frame.expansion=0
[TitleBar]
inherits=PanelButtonCommand
frame=false
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
interior.element=titlebar
indicator.size=16
indicator.element=mdi
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.bold=false
text.italic=true
frame.expansion=0
[ComboBox]
inherits=PanelButtonCommand
frame.element=combo
interior.element=combo
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
text.margin.top=2
text.margin.bottom=2
text.margin.left=2
text.margin.right=2
text.focus.color=#DEE3E5
text.press.color=#dfdfdf
text.toggle.color=white
[GroupBox]
inherits=GenericFrame
frame=false
text.shadow=0
text.margin=0
text.normal.color=#DEE3E5
text.focus.color=#DEE3E5
text.bold=false
frame.expansion=0
[TabBarFrame]
inherits=GenericFrame
frame=false
frame.element=tabBarFrame
interior=false
frame.top=0
frame.bottom=0
frame.left=0
frame.right=0
[ToolTip]
inherits=GenericFrame
frame.top=6
frame.bottom=6
frame.left=6
frame.right=6
interior=true
text.shadow=0
text.margin=6
interior.element=tooltip
frame.element=tooltip
frame.expansion=6
[StatusBar]
inherits=GenericFrame
frame=false
interior=false
[Window]
interior=true
interior.element=window
frame=true
frame.element=window
frame.bottom=10
frame.top=10
text.disabled.color=#0F1416
File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 168 KiB

-2
View File
@@ -1,2 +0,0 @@
[General]
theme=MaterialAdw
@@ -1 +0,0 @@
openai-symbolic.svg
@@ -1,54 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
version="1.1"
id="svg9"
sodipodi:docname="oxygen.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs9" />
<sodipodi:namedview
id="namedview9"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="7.6782609"
inkscape:cx="-11.916761"
inkscape:cy="11.786523"
inkscape:window-width="1627"
inkscape:window-height="1028"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg9" />
<g
id="g9"
transform="translate(0.7158741,-0.307456)">
<path
d="m 12.821126,8.892686 c 0,2.99523 -2.42813,5.42337 -5.4233602,5.42337 -2.99523,0 -5.42334,-2.42814 -5.42334,-5.42337 0,-2.99523 2.42811,-5.42334 5.42334,-5.42334 2.9952302,0 5.4233602,2.42811 5.4233602,5.42334 z"
fill="white"
id="path7"
style="fill:#000000" />
<path
d="m 16.593826,4.412536 c 0,1.04182 -0.8445,1.88638 -1.8863,1.88638 -1.0419,0 -1.8864,-0.84456 -1.8864,-1.88638 0,-1.041819 0.8445,-1.88638 1.8864,-1.88638 1.0418,0 1.8863,0.844561 1.8863,1.88638 z"
fill="white"
id="path8"
style="fill:#000000" />
<path
d="m 16.593826,15.495056 c 0,1.4325 -1.1612,2.5937 -2.5937,2.5937 -1.4325,0 -2.5938,-1.1612 -2.5938,-2.5937 0,-1.4325 1.1613,-2.5938 2.5938,-2.5938 1.4325,0 2.5937,1.1613 2.5937,2.5938 z"
fill="white"
id="path9"
style="fill:#000000" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 KiB

-113
View File
@@ -1,113 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.0"
width="20"
height="19.999941"
id="svg2424"
sodipodi:docname="archlinux-logo-black-scalable.f931920e6cdb.svg"
viewBox="0 0 166.18749 166.187"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="16.650008"
inkscape:cx="13.093087"
inkscape:cy="16.366359"
inkscape:window-width="1340"
inkscape:window-height="768"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g2424" />
<defs
id="defs2426">
<linearGradient
x1="112.49854"
y1="6.1372099"
x2="112.49853"
y2="129.3468"
id="path1082_2_"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(287,-83)">
<stop
id="stop193"
style="stop-color:#ffffff;stop-opacity:0"
offset="0" />
<stop
id="stop195"
style="stop-color:#ffffff;stop-opacity:0.27450982"
offset="1" />
<midPointStop
offset="0"
style="stop-color:#FFFFFF"
id="midPointStop197" />
<midPointStop
offset="0.5"
style="stop-color:#FFFFFF"
id="midPointStop199" />
<midPointStop
offset="1"
style="stop-color:#000000"
id="midPointStop201" />
</linearGradient>
<linearGradient
x1="541.33502"
y1="104.50665"
x2="606.91248"
y2="303.14029"
id="linearGradient2544"
xlink:href="#path1082_2_"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-0.3937741,0,0,0.393752,357.51969,122.00151)" />
<linearGradient
id="linearGradient3388">
<stop
id="stop3390"
style="stop-color:#000000;stop-opacity:0"
offset="0" />
<stop
id="stop3392"
style="stop-color:#000000;stop-opacity:0.37113401"
offset="1" />
</linearGradient>
<linearGradient
x1="490.72305"
y1="237.72447"
x2="490.72305"
y2="183.9644"
id="linearGradient4416"
xlink:href="#linearGradient3388"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.749107,0,0,0.749107,-35.459862,91.44108)" />
</defs>
<g
transform="translate(-57.527313,-146.42741)"
id="layer1">
<g
transform="matrix(0.8746356,0,0,0.8746356,14.730518,23.408954)"
id="g2424"
style="fill:#000000">
<g
transform="matrix(0.6378586,0,0,0.6378586,36.486487,2.17139)"
id="g2809"
style="fill:#000000;fill-opacity:1" />
<path
d="m 143.91698,140.65081 c -8.45709,20.73453 -13.55799,34.29734 -22.97385,54.41552 5.7731,6.11948 12.85931,13.24593 24.36729,21.29458 -12.37221,-5.09109 -20.81157,-10.20242 -27.11844,-15.50646 -12.0505,25.14523 -30.930177,60.96349 -69.243121,129.80406 30.112687,-17.38458 53.455511,-28.10236 75.209891,-32.19198 -0.93414,-4.01773 -1.46524,-8.36369 -1.42916,-12.89823 l 0.0357,-0.96469 c 0.47781,-19.2924 10.51371,-34.12825 22.40218,-33.12093 11.88848,1.00732 21.12927,17.4729 20.65146,36.76531 -0.0899,3.63022 -0.49934,7.12245 -1.21479,10.36146 21.51819,4.20934 44.61141,14.89968 74.31666,32.04906 -5.85729,-10.78369 -11.08544,-20.5044 -16.07812,-29.7624 -7.86429,-6.09535 -16.06714,-14.02847 -32.79938,-22.61656 11.50078,2.98839 19.73519,6.43619 26.15375,10.29 -50.76203,-94.51003 -54.87267,-107.06846 -72.2801,-147.91874 z"
id="path2518"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.14333" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.1 KiB

@@ -1,318 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="SVGRoot"
width="20"
height="20"
version="1.1"
viewBox="0 0 17.921003 17.921002"
sodipodi:docname="cachyos-symbolic.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview30"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="32"
inkscape:cx="10.671875"
inkscape:cy="11.234375"
inkscape:window-width="1687"
inkscape:window-height="1028"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="SVGRoot" />
<defs
id="defs6">
<linearGradient
id="linearGradient939"
x1="237.19"
x2="237.07001"
y1="296.20001"
y2="304.07999"
gradientTransform="matrix(0.04476,0,0,0.044679,-8.5042241,-4.351186)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient937" />
<linearGradient
id="linearGradient937">
<stop
stop-color="#001313"
offset="0"
id="stop1" />
<stop
stop-color="#001313"
stop-opacity="0"
offset="1"
id="stop2" />
</linearGradient>
<linearGradient
id="linearGradient5185"
x1="994.81"
x2="982.34003"
y1="1533.3"
y2="1556.8"
gradientTransform="matrix(0.084141,0,0,0.083989,-76.242924,-126.39098)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient4353" />
<linearGradient
id="linearGradient4353">
<stop
stop-color="#020202"
offset="0"
id="stop3" />
<stop
stop-color="#020202"
stop-opacity="0"
offset="1"
id="stop4" />
</linearGradient>
<linearGradient
id="linearGradient9102"
x1="1022.5"
x2="1018.6"
y1="1582.4"
y2="1575.6"
gradientTransform="matrix(0.086381,0,0,0.081808,-79.103924,-124.69099)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient4353" />
<linearGradient
id="linearGradient11890"
x1="940.42999"
x2="930.59003"
y1="1612.5"
y2="1594.5"
gradientTransform="matrix(0.084141,0,0,0.083989,-76.242924,-126.39098)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient4353" />
<linearGradient
id="linearGradient11670"
x1="965.59998"
x2="951.65997"
y1="1571.4"
y2="1571.3"
gradientTransform="matrix(0.084141,0,0,0.083989,-76.242924,-126.39098)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient4353" />
<linearGradient
id="linearGradient13770"
x1="946.22998"
x2="961.37"
y1="1655.9"
y2="1655.8"
gradientTransform="matrix(0.084141,0,0,0.083989,-76.242924,-126.39098)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient4353" />
<linearGradient
id="linearGradient2816"
x1="366.14999"
x2="350.92001"
y1="427.32001"
y2="419.64001"
gradientTransform="matrix(0.04476,0,0,0.044679,-10.832924,-4.155886)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient937" />
<linearGradient
id="linearGradient12421"
x1="936.34003"
x2="933.38"
y1="1628.8"
y2="1623"
gradientTransform="matrix(0.084141,0,0,0.083989,-76.242924,-126.39098)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient4353" />
<linearGradient
id="linearGradient13391"
x1="950.33002"
x2="941.96997"
y1="1618.6"
y2="1645.8"
gradientTransform="matrix(0.084141,0,0,0.083989,-76.242924,-126.39098)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient4353" />
<linearGradient
id="linearGradient13599"
x1="1008.2"
x2="1015.7"
y1="1681.3"
y2="1668.4"
gradientTransform="matrix(0.084141,0,0,0.083989,-77.884838,-124.43841)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient4353" />
<linearGradient
id="linearGradient18175"
x1="1148.3"
x2="1145.4"
y1="1585.5"
y2="1630"
gradientTransform="matrix(0.34992,0,0,0.34992,-282.87,-491.67)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient18299" />
<linearGradient
id="linearGradient18299">
<stop
stop-color="#008066"
stop-opacity="0"
offset="0"
id="stop5" />
<stop
stop-color="#0fc"
offset="1"
id="stop6" />
</linearGradient>
<linearGradient
id="linearGradient18632"
x1="1148.3"
x2="1145.4"
y1="1585.5"
y2="1630"
gradientTransform="matrix(0.26565,0,0,0.26565,-211.15,-375.49)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient18299" />
<linearGradient
id="linearGradient18659"
x1="1148.3"
x2="1145.4"
y1="1585.5"
y2="1630"
gradientTransform="matrix(0.13679,0,0,0.13679,-53.624,-195.03)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient18299" />
<linearGradient
id="linearGradient3254"
x1="348.04999"
x2="361.20999"
y1="194.78"
y2="187.24001"
gradientTransform="matrix(0.04476,0,0,0.044679,-10.832924,-4.155886)"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient937" />
</defs>
<circle
cx="87.449997"
cy="87.449997"
r="87.449997"
opacity="0"
stroke-width="0.27971"
id="circle6" />
<path
d="m 4.0610759,2.168314 6.5887001,3.6879 2.1127,-3.6528 z"
fill="#00aa88"
id="path7"
style="fill:#000000" />
<path
d="m 6.1499759,12.423014 -1.9125,3.7456 h 8.5747001 l 2.1664,-3.7456 z"
fill="#00aa88"
id="path8"
style="fill:#7a7a7a;fill-opacity:0.68506807" />
<path
d="m 4.0610759,2.168314 6.5887001,3.6879 H 6.1237759 l -1.8859,3.2605 1.9121,3.306 -1.9125,3.7456 -4.13689997,-7.1525 3.96049997,-6.8475"
fill="#00ccff"
id="path9"
style="fill:#7a7a7a;fill-opacity:0.69262218" />
<path
d="m 6.0909759,5.821714 6.7111001,-3.7832 -2.169,3.5579 z"
fill="url(#linearGradient9102)"
id="path12"
style="fill:url(#linearGradient9102)" />
<path
d="m 6.1236759,5.856214 6.6388001,-3.6528 -2.1127,3.6528 z"
fill="#00aa88"
id="path13"
style="fill:#000000" />
<path
d="m 0.10057593,9.015814 6.02309997,-3.1596 -1.8859,3.2605 z"
fill="#00aa88"
id="path14"
style="fill:#1a1a1a" />
<path
d="m 6.1236759,5.856214 -2.0626,-3.6879 0.17673,6.9484 z"
fill="#00aa88"
id="path16"
style="fill:#1a1a1a" />
<path
d="m 4.2378759,9.116714 -3.1586,1.5811 3.1583,5.4705 z"
fill="#00aa88"
id="path19"
style="fill:#1a1a1a" />
<path
d="m 1.0792259,10.698014 5.0708,1.7248 -1.9121,-3.306 z"
fill="#00aa88"
id="path23"
style="fill:#1a1a1a" />
<g
transform="matrix(0.14699,0,0,0.14672,-0.75949407,-0.14715599)"
id="g26"
style="fill:#1a1a1a">
<circle
cx="117.95"
cy="75.441002"
r="9.6893997"
fill="#00ccff"
id="circle25"
style="fill:#1a1a1a" />
<circle
cx="118.08"
cy="75.341003"
r="9.6893997"
fill="url(#linearGradient18175)"
id="circle26"
style="fill:#1a1a1a" />
</g>
<g
transform="matrix(0.14699,0,0,0.14672,-0.11248407,-0.47061599)"
id="g28"
style="fill:#1a1a1a">
<circle
cx="93.138"
cy="55.044998"
r="7.3558998"
fill="#00ccff"
id="circle27"
style="fill:#1a1a1a" />
<circle
cx="93.238998"
cy="54.969002"
r="7.3558998"
fill="url(#linearGradient18632)"
id="circle28"
style="fill:#1a1a1a" />
</g>
<g
transform="matrix(0.14699,0,0,0.14672,-0.08243407,-0.04714599)"
id="g30"
style="fill:#000000">
<circle
cx="103.06"
cy="26.657"
r="3.7876999"
fill="#00ccff"
id="circle29"
style="fill:#000000" />
<circle
cx="103.11"
cy="26.618"
r="3.7876999"
fill="url(#linearGradient18659)"
id="circle30"
style="fill:#000000" />
</g>
<path
d="m 6.1236759,5.856214 -2.0626,-3.6879 0.52544,-0.0074 1.9387,3.4465 z"
fill="url(#linearGradient3254)"
id="path30"
style="fill:url(#linearGradient3254)" />
<path
d="M 12.808567,16.168211 6.1524738,12.428132 4.2457352,16.165572 Z"
fill="#00ccff"
id="path17"
style="fill:#1a1a1a;fill-opacity:1"
sodipodi:nodetypes="cccc" />
</svg>

Before

Width:  |  Height:  |  Size: 9.0 KiB

@@ -1,10 +0,0 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_26_18)">
<path d="M3 7.06015V4.74436C4.12 4.69624 4.90412 4.62466 5.35237 4.52962C6.06664 4.37804 6.64769 4.07549 7.09553 3.62195C7.40205 3.31158 7.63448 2.89754 7.7928 2.37985C7.8839 2.06947 7.92946 1.8387 7.92946 1.68752H10.9001V19H7.25588V7.06015H3ZM12.4228 5.65444V4.52962L15.0783 1H16.1879V4.64211H17V5.65444H16.1879V7.05594H15.0084V5.65444H12.4228ZM14.9823 2.53985L13.4031 4.64511H15.0102V2.53985H14.9823Z" fill="black"/>
</g>
<defs>
<clipPath id="clip0_26_18">
<rect width="20" height="20" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 660 B

@@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
fill="#000000"
width="20"
height="20"
viewBox="0 0 380.95238 380.95238"
version="1.1"
id="svg1"
sodipodi:docname="crosshair-symbolic.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="35"
inkscape:cx="10.371429"
inkscape:cy="7.9571429"
inkscape:window-width="1430"
inkscape:window-height="1028"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<title
id="title1">ionicons-v5_logos</title>
<metadata
id="metadata1">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:title>ionicons-v5_logos</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<rect
style="fill:#000000;stroke-width:23.0377"
id="rect1"
width="380.95239"
height="57.142857"
x="-3.5527137e-15"
y="161.90475" />
<rect
style="fill:#000000;stroke-width:23.0451;stroke-dasharray:none"
id="rect1-5"
width="57.142857"
height="380.95239"
x="161.90475"
y="0" />
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
width="20"
height="20"
viewBox="-30.5 0 317.00242 317.00243"
version="1.1"
preserveAspectRatio="xMidYMid"
id="svg12"
sodipodi:docname="debian-symbolic.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs12" />
<sodipodi:namedview
id="namedview12"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="17.5"
inkscape:cx="13.742857"
inkscape:cy="12.628571"
inkscape:window-width="1295"
inkscape:window-height="867"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg12" />
<g
fill="#A80030"
id="g12"
style="fill:#1a1a1a"
transform="translate(0.05835351,0.0538775)">
<path
d="m 152.79662,167.42537 c -5.25095,0.0731 0.9935,2.70583 7.84865,3.76069 1.8935,-1.47856 3.61167,-2.97466 5.14283,-4.42984 -4.26913,1.04609 -8.61424,1.06947 -12.99148,0.66915"
id="path1"
style="fill:#1a1a1a" />
<path
d="m 180.9799,160.40073 c 3.12661,-4.31588 5.40581,-9.04086 6.20938,-13.92654 -0.70129,3.4831 -2.59187,6.4899 -4.3714,9.66326 -9.81521,6.18016 -0.92337,-3.67011 -0.006,-7.41328 -10.55448,13.2837 -1.44934,7.96554 -1.83213,11.67656"
id="path2"
style="fill:#1a1a1a" />
<path
d="m 191.38244,133.33075 c 0.63409,-9.45579 -1.86135,-6.46652 -2.69999,-2.85777 0.9789,0.50844 1.75324,6.66522 2.69999,2.85777"
id="path3"
style="fill:#1a1a1a" />
<path
d="m 132.88569,4.0879643 c 2.80225,0.5025946 6.05451,0.8883068 5.59867,1.5574589 3.06524,-0.6720742 3.76069,-1.2915513 -5.59867,-1.5574589"
id="path4"
style="fill:#1a1a1a" />
<path
d="m 138.48436,5.6454232 -1.98116,0.4090887 1.84382,-0.1636355 0.13734,-0.2454532"
id="path5"
style="fill:#1a1a1a" />
<path
d="m 225.86569,136.91612 c 0.31266,8.49151 -2.48375,12.61162 -5.00549,19.90509 l -4.53796,2.26752 c -3.71394,7.21165 0.35941,4.57887 -2.29967,10.31487 -5.79737,5.15452 -17.59373,16.12979 -21.36903,17.13205 -2.75551,-0.0614 1.86719,-3.25225 2.47206,-4.50289 -7.76099,5.32984 -6.22691,8.0006 -18.09633,11.23824 l -0.34772,-0.77142 c -29.27322,13.77168 -69.93663,-13.52038 -69.40189,-50.75913 -0.31266,2.36394 -0.88831,1.77369 -1.537,2.7292 -1.51071,-19.15996 8.848,-38.40465 26.31901,-46.262078 17.08821,-8.459369 37.12187,-4.987959 49.36238,6.419768 -6.72366,-8.807092 -20.1067,-18.14308 -35.96765,-17.269383 -15.53661,0.245453 -30.07094,10.1191 -34.92156,20.837223 -7.9597,5.01133 -8.88307,19.31775 -12.351558,21.93592 -4.666532,34.29623 8.777878,49.11401 31.520278,66.54411 3.57953,2.41362 1.00811,2.77888 1.49318,4.61685 -7.55646,-3.53861 -14.4759,-8.88014 -20.16515,-15.41972 3.01849,4.41816 6.27659,8.71359 10.48728,12.08857 -7.12399,-2.41362 -16.64115,-17.26354 -19.42003,-17.8684 12.28143,21.98851 49.827,38.56245 69.48663,30.33976 -9.09638,0.33604 -20.65313,0.18702 -30.8745,-3.59121 -4.29251,-2.20908 -10.13079,-6.78503 -9.08761,-7.64119 26.83037,10.02267 54.54612,7.59151 77.7619,-11.0191 5.90549,-4.59932 12.3574,-12.4246 14.22168,-12.53272 -2.8081,4.22238 0.47921,2.03083 -1.67727,5.75938 5.88504,-9.49085 -2.5568,-3.86296 6.08374,-16.38984 l 3.19089,4.39478 c -1.18636,-7.87788 9.78306,-17.44471 8.66975,-29.90438 2.5159,-3.81037 2.80811,4.09965 0.13734,12.86584 3.70517,-9.72462 0.97597,-11.28793 1.92856,-19.31191 1.02857,2.69707 2.37856,5.56361 3.07109,8.4097 -2.41362,-9.39735 2.47791,-15.82589 3.68764,-21.28722 -1.1922,-0.52889 -3.72563,4.15517 -4.3042,-6.94574 0.0847,-4.8214 1.34123,-2.52759 1.82629,-3.71394 -0.94675,-0.54351 -3.4305,-4.23991 -4.9412,-11.328836 1.09577,-1.665575 2.9279,4.318806 4.41815,4.564256 -0.95843,-5.636653 -2.6094,-9.935006 -2.67661,-14.259657 -4.35387,-9.0993 -1.53992,1.212656 -5.07269,-3.906796 -4.63439,-14.45544 3.84543,-3.354527 4.41815,-9.923322 7.02464,10.177541 11.03079,25.950835 12.86876,32.484565 -1.40259,-7.965545 -3.67011,-15.68271 -6.4373,-23.148578 2.13311,0.897073 -3.43634,-16.389844 2.77304,-4.941206 -6.63308,-24.40506 -28.38783,-47.208829 -48.40103,-57.909419 2.44869,2.241221 5.54023,5.055166 4.42984,5.496398 -9.95254,-5.925941 -8.20223,-6.387627 -9.62819,-8.891834 -8.10872,-3.299008 -8.64054,0.265908 -14.01129,0.0058 -15.28238,-8.105755 -18.22782,-7.243747 -32.2917,-12.32229 l 0.63993,2.9892691 c -10.12494,-3.3720592 -11.79636,1.279863 -22.73948,0.011688 -0.66623,-0.520127 3.50647,-1.8818077 6.93989,-2.3814803 -9.7889,1.2915513 -9.33014,-1.9285607 -18.90866,0.3564916 2.36103,-1.656809 4.85647,-2.7525822 7.37529,-4.1610159 -7.98308,0.4850622 -19.05769,4.6460781 -15.63888,0.8620082 C 96.316085,8.9298206 73.190888,17.085295 60.214012,29.25276 L 59.804924,26.526476 C 53.858528,33.665073 33.874548,47.845838 32.282025,57.091242 l -1.589602,0.371102 C 27.59796,62.7016 25.596347,68.63923 23.141816,74.030433 19.09476,80.926499 17.21003,76.683665 17.785676,77.764828 9.8259803,93.903375 5.8724309,107.46466 2.4565407,118.58603 4.8906182,122.224 2.514982,140.48688 3.4354314,155.10304 -0.56194899,227.28965 54.098137,297.37822 113.84553,313.5606 c 8.75742,3.13245 21.78105,3.01264 32.85859,3.33407 -13.07039,-3.73732 -14.75934,-1.98116 -27.49076,-6.41977 -9.18404,-4.32465 -11.19734,-9.26293 -17.70185,-14.90836 l 2.57434,4.54965 c -12.757724,-4.51458 -7.419118,-5.58698 -17.798281,-8.8743 l 2.74966,-3.59121 c -4.134717,-0.31266 -10.951887,-6.96912 -12.816162,-10.65384 l -4.523352,0.17825 C 66.26268,270.46895 63.366917,265.63586 63.577306,261.8927 l -1.461031,2.60356 c -1.656809,-2.84317 -19.995669,-25.15019 -10.481436,-19.95768 -1.767847,-1.6159 -4.117185,-2.62986 -6.665222,-7.2584 l 1.937326,-2.21493 c -4.57887,-5.89087 -8.427226,-13.44148 -8.135019,-15.95737 2.442843,3.299 4.137639,3.91556 5.814902,4.47952 -11.562598,-28.68881 -12.211295,-1.58084 -20.968714,-29.20309 l 1.852587,-0.14902 c -1.420122,-2.13895 -2.28213,-4.46199 -3.424657,-6.7412 l 0.80649,-8.03567 c -8.324954,-9.62527 -2.328884,-40.9264 -1.127916,-58.09351 0.832787,-6.9808 6.948662,-14.41161 11.600585,-26.064789 l -2.8344,-0.487985 c 5.417502,-9.449947 30.932945,-37.951737 42.749763,-36.484862 5.724319,-7.191194 -1.136683,-0.0263 -2.255832,-1.837977 12.573631,-13.011941 16.527181,-9.192806 25.012848,-11.533378 9.1519,-5.432112 -7.854502,2.118495 -3.51524,-2.071741 15.82004,-4.041212 11.21195,-9.186962 31.85047,-11.23825 2.17694,1.238955 -5.05224,1.913951 -6.86684,3.521085 13.18142,-6.448991 41.71243,-4.982116 60.24414,3.579525 21.50346,10.04897 45.66306,39.75465 46.61565,67.704172 l 1.08409,0.2922 c -0.54935,11.10968 1.70064,23.95799 -2.19739,35.76019 l 2.65323,-5.58698"
id="path6"
style="fill:#1a1a1a" />
<path
d="m 95.483297,174.6341 -0.736359,3.68179 c 3.450955,4.68699 6.188932,9.76553 10.595392,13.4298 -3.17043,-6.18893 -5.525615,-8.74573 -9.859033,-17.11159"
id="path7"
style="fill:#1a1a1a" />
<path
d="m 103.64169,174.31267 c -1.82629,-2.01915 -2.90745,-4.4503 -4.117181,-6.87269 1.157141,4.25744 3.526931,7.91586 5.733081,11.63565 l -1.6159,-4.76296"
id="path8"
style="fill:#1a1a1a" />
<path
d="m 248.00323,142.93557 -0.77142,1.9344 c -1.41428,10.04605 -4.46784,19.98691 -9.14898,29.20309 5.17205,-9.72462 8.51781,-20.36093 9.9204,-31.13749"
id="path9"
style="fill:#1a1a1a" />
<path
d="M 133.92302,1.5691471 C 137.47332,0.26882968 142.65122,0.85616408 146.41775,0 141.50869,0.4120107 136.623,0.65746388 131.79868,1.279863 l 2.12434,0.2892841"
id="path10"
style="fill:#1a1a1a" />
<path
d="m 9.2824769,67.847351 c 0.8181771,7.573984 -5.6980203,10.513578 1.4434981,5.519774 3.827901,-8.623004 -1.4960952,-2.38148 -1.4434981,-5.519774"
id="path11"
style="fill:#1a1a1a" />
<path
d="M 0.89031567,102.9004 C 2.5354364,97.85108 2.8334867,94.81798 3.46173,91.895919 -1.084998,97.707899 1.3695338,98.946854 0.89031567,102.9004"
id="path12"
style="fill:#1a1a1a" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.3 KiB

@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="Layer_1"
version="1.1"
viewBox="0 0 56.202442 56.202035"
sodipodi:docname="DeepSeek_logo.svg"
width="20.000145"
height="20"
inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview2"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="15.999999"
inkscape:cx="6.5625003"
inkscape:cy="7.1875003"
inkscape:window-width="1181"
inkscape:window-height="1028"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<!-- Generator: Adobe Illustrator 29.2.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 116) -->
<defs
id="defs1">
<style
id="style1">
.st0 {
fill: #4d6bfe;
}
</style>
</defs>
<path
class="st0"
d="m 55.612804,10.892579 c -0.5953,-0.2917 -0.8517,0.2642 -1.1998,0.5466 -0.1191,0.0911 -0.2198,0.2095 -0.3206,0.3188 -0.8701,0.9292 -1.8867,1.5398 -3.2148,1.4668 -1.9417,-0.1094 -3.5995,0.5012 -5.065,1.9863 -0.3114,-1.8313 -1.3463,-2.9248 -2.9217,-3.6262 -0.8242,-0.3645 -1.6577,-0.729 -2.2348,-1.5217 -0.403,-0.5646998 -0.5129,-1.1933998 -0.7144,-1.8129998 -0.1283,-0.3735 -0.2565,-0.7563 -0.687,-0.8201 -0.4671,-0.0728 -0.6503,0.3188 -0.8335,0.647 -0.7327,1.3394 -1.0166,2.8153998 -0.9892,4.3095998 0.0641,3.3621 1.4838,6.0406 4.3047,7.9449 0.3206,0.2187 0.403,0.4372 0.3023,0.7563 -0.1924,0.656 -0.4214,1.2937 -0.6228,1.9497 -0.1283,0.4192 -0.3207,0.5103 -0.7694,0.3279 -1.5479,-0.6467 -2.8852,-1.6035 -4.0667,-2.7605 -2.0058,-1.9407 -3.8193,-4.0818 -6.0815,-5.7583 -0.5312,-0.3918 -1.0625,-0.7561 -1.6121,-1.1025 -2.3081,-2.2412 0.3023,-4.0817998 0.9068,-4.3002998 0.6319,-0.2278 0.2198,-1.0115 -1.8227,-1.0022 -2.0425,0.009 -3.9109,0.6924 -6.2922,1.6034998 -0.348,0.1367 -0.7145,0.2368 -1.09,0.3188 -2.1615,-0.4098998 -4.4055,-0.5011998 -6.7502,-0.2368 -4.4147001,0.4919 -7.9408001,2.5784 -10.5328001,6.1409 -3.11399997,4.2822 -3.84669997,9.1474 -2.94909997,14.2224 0.94339997,5.3481 3.67269997,9.7761 7.86759997,13.2385 4.3506001,3.5896 9.3606001,5.3481 15.0758001,5.011 3.4713,-0.2004 7.3364,-0.665 11.6961,-4.355 1.099,0.5467 2.2531,0.7652 4.1674,0.9292 1.4746,0.1367 2.8943,-0.0728 3.9933,-0.3005 1.7219,-0.3645 1.6029,-1.959 0.9801,-2.2505 -5.0466,-2.3506 -3.9385,-1.394 -4.9459,-2.1685 2.5645,-3.0339 6.4297,-6.1865 7.9409,-16.4001 0.119,-0.8108 0.0183,-1.3211 0,-1.9771 -0.0092,-0.4008 0.0824,-0.5556 0.5404,-0.6013 1.2639,-0.1458 2.4912,-0.4919 3.6178,-1.1115 3.2698,-1.7857 4.5886,-4.7195 4.9,-8.2364 0.0459,-0.5376 -0.0091,-1.0935 -0.577,-1.3757 z m -28.4938,31.6518 c -4.8909,-3.8447 -7.263,-5.1113 -8.2431,-5.0566 -0.9159,0.0547 -0.751,1.1025 -0.5496,1.7859 0.2107,0.6741 0.4855,1.1389 0.8701,1.731 0.2656,0.3918 0.4489,0.9748 -0.2655,1.4123 -1.5754,0.9749 -4.314,-0.3281 -4.4423,-0.3918 -3.1872,-1.877 -5.8525001,-4.3553 -7.7302001,-7.7444 -1.8135,-3.262 -2.8667,-6.7605 -3.0408,-10.4961 -0.0458,-0.9019 0.2198,-1.221 1.1174,-1.3848 1.1815,-0.2187 2.3997,-0.2644 3.5812,-0.0913 4.9918001,0.729 9.2415001,2.9612 12.8043001,6.4963 2.0333,2.0135 3.572,4.419 5.1566,6.7696 1.6852,2.4963 3.4987,4.8745 5.8068,6.8242 0.8151,0.6833 1.4654,1.2026 2.0882,1.5854 -1.8775,0.2095 -5.01,0.2552 -7.1532,-1.4397 z m 2.3447,-15.0788 c 0,-0.4009 0.3206,-0.7197 0.7237,-0.7197 0.0916,0 0.174,0.018 0.2473,0.0453 0.1008,0.0366 0.1924,0.0913 0.2656,0.1731 0.1283,0.1277 0.2015,0.3098 0.2015,0.5012 0,0.4009 -0.3205,0.7197 -0.7234,0.7197 -0.4029,0 -0.7145,-0.3188 -0.7145,-0.7197 z m 7.2815,3.7356 c -0.4671,0.1914 -0.9342,0.3552 -1.383,0.3735 -0.6961,0.0364 -1.4563,-0.2461 -1.8684,-0.5923 -0.6411,-0.5376 -1.0991,-0.8381 -1.2914,-1.7766 -0.0825,-0.4009 -0.0367,-1.0205 0.0367,-1.3757 0.1648,-0.7654 -0.0184,-1.2573 -0.5587,-1.7039 -0.4397,-0.3645 -0.9984,-0.4646 -1.6121,-0.4646 -0.229,0 -0.4395,-0.1003 -0.5953,-0.1823 -0.2565,-0.1275 -0.467,-0.4464 -0.2656,-0.8382 0.0641,-0.1274 0.3756,-0.4373 0.4489,-0.4919 0.8335,-0.4739 1.7952,-0.3189 2.6836,0.0364 0.8244,0.3371 1.4472,0.9567 2.3447,1.8313 0.9159,1.0568 1.0807,1.3486 1.6028,2.1411 0.4123,0.6196 0.7878,1.2573 1.0442,1.9863 0.1557,0.4556 -0.0458,0.8291 -0.5862,1.0569 z"
id="path1"
style="stroke-width:1.0004;stroke-dasharray:none;fill:#000000" />
</svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 12 1 c 1.660156 0 3 1.339844 3 3 v 6 c 0 1.660156 -1.339844 3 -3 3 h -8 c -1.660156 0 -3 -1.339844 -3 -3 v -6 c 0 -1.660156 1.339844 -3 3 -3 z m 0 2 h -8 c -0.554688 0 -1 0.445312 -1 1 v 6 c 0 0.554688 0.445312 1 1 1 h 8 c 0.554688 0 1 -0.445312 1 -1 v -6 c 0 -0.554688 -0.445312 -1 -1 -1 z m -4 11 c -5 0 -5 1 -5 1 c 0 1 1 1 1 1 h 8 c 1 0 1 -1 1 -1 s 0 -1 -5 -1 z m 0 0" fill="#2e3436"/>
</svg>

Before

Width:  |  Height:  |  Size: 538 B

@@ -1,96 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="20mm"
height="20mm"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
sodipodi:docname="EndeavourOS Logo.svg"
version="1.1"
viewBox="0 0 48.231007 48.231007"
id="svg8"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs8" />
<sodipodi:namedview
id="cvfa"
bordercolor="#666666"
borderopacity="1.0"
inkscape:current-layer="g3"
inkscape:cx="52.728754"
inkscape:cy="60.739468"
inkscape:document-rotation="0"
inkscape:document-units="mm"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:window-height="1028"
inkscape:window-maximized="1"
inkscape:window-width="1316"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:zoom="4.930896"
pagecolor="#ffffff"
showgrid="false"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" />
<title
id="title1">EndeavourOS Logo</title>
<metadata
id="metadata1">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>EndeavourOS Logo</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(-66.790568,-123.01834)"
inkscape:groupmode="layer"
inkscape:label="Layer 1"
id="g8">
<g
transform="translate(76.2,-12.7)"
id="g7">
<g
transform="matrix(1.47,0,0,1.47,-519,105)"
id="g6">
<g
transform="matrix(0.963,0,0,0.983,13.5,0.76)"
id="g5">
<g
transform="matrix(0.678,0,0,0.678,452,49.2)"
id="g3">
<g
id="g9"
transform="translate(6.8384014e-4,3.6851185)">
<path
d="m -127,-42.3 c 4.57,6.45 23.8,31.4 10.7,36.6 -6.12,2.81 -34,-1.65 -33.6,-0.921 -2,3.28 -3.59,5.92 -3.59,5.92 0,0 21.5,0.967 38.1,-1.27 23.7,-3.18 -4.88,-33.5 -11.6,-40.3 z"
style="fill:#333333;fill-opacity:0.7;stroke-width:0.585"
inkscape:connector-curvature="0"
id="path1" />
<path
d="m -127,-42.3 c -1.52,0.209 -29.4,34.5 -29.4,34.5 0,0 2.01,0.57 6.58,1.23 1.48,-1.15 22.3,-36.2 22.9,-35.7 -0.0107,-0.0141 -0.028,-0.0193 -0.0522,-0.016 z"
style="fill:#333333;fill-opacity:0.7;stroke-width:0.585"
inkscape:connector-curvature="0"
id="path2" />
<path
d="m -127,-42.3 c -0.96,-0.156 -22.9,35.7 -22.9,35.7 0,0 19.9,2.1 28.1,1.96 23.1,-0.39 0.176,-30.6 -5.16,-37.7 -0.007,-0.007 -0.0151,-0.0108 -0.0248,-0.0124 z"
style="fill:#1a1a1a;stroke-width:0.585"
inkscape:connector-curvature="0"
id="path3" />
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 448.00288 448.00288"
version="1.1"
id="svg1"
sodipodi:docname="Fa-Team-Fontawesome-Brands-FontAwesome-Brands-Fedora.svg"
width="19.999744"
height="19.999744"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="13.671875"
inkscape:cx="19.2"
inkscape:cy="17.664"
inkscape:window-width="1313"
inkscape:window-height="908"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<!--! Font Awesome Free 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. -->
<path
d="M 0.0413,223.8 C 0.1219,100.2 100.3,0 224,0 347.7,0 448,100.3 448,224 448,347.7 347.8,447.9 224.1,448 H 50.93 C 22.84,448 0.0832,425.3 0.0416,397.2 H 0 V 223.8 Z M 342.6,160.7 c 0,-39.7 -35.6,-68.5 -73.2,-68.5 -34.9,0 -65.8,26.3 -70.1,59.9 -0.2,3.8 -0.4,5 -0.4,8.5 -0.1,21.1 0,42.8 -0.8,64.4 0.9,26.1 1,52.1 0,76.6 0,27.1 -19.4,45.5 -44.7,45.5 -25.3,0 -45.8,-20.2 -45.8,-45.5 0.5,-27.7 22.6,-45.3 48.5,-46.1 h 0.2 l 26.3,-0.2 V 218 l -26.3,0.2 c -47.1,-0.4 -84.58,36.5 -85.94,83.4 0,45.6 37.54,82.9 83.04,82.9 43,0 78.7,-33.6 82.6,-75.6 l 0.2,-53.5 32.6,-0.3 c 25.3,0.2 25,-37.8 -0.2,-37.3 l -32.4,0.3 c 0,-6.4 0.1,-12.8 0.1,-19.2 0.1,-12.7 0.1,-25.4 -0.1,-38.2 0.1,-16.5 15.8,-31.2 33.2,-31.2 17.5,0 35.9,8.7 35.9,31.2 0,3.2 -0.1,5.1 -0.3,6.3 -1.9,10.5 5.2,20.4 15.7,21.9 10.6,1.5 20.2,-6.1 21.2,-16.6 0.6,-4.2 0.7,-7.9 0.7,-11.6 z"
id="path1" />
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
role="img"
viewBox="0 0 24.000009 24.000009"
version="1.1"
id="svg1"
sodipodi:docname="flatpak_logo_icon_248537.svg"
width="20"
height="20"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="18.229167"
inkscape:cx="11.190857"
inkscape:cy="11.766857"
inkscape:window-width="1164"
inkscape:window-height="648"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<title
id="title1">Flatpak</title>
<path
d="m 12.000004,7.3336774e-5 c -0.556,0 -1.110999,0.143999993226 -1.609999,0.431999993226 L 2.7870046,4.8220733 a 3.217,3.217 0 0 0 -1.61,2.788 v 8.7799997 c 0,1.151 0.612,2.212 1.61,2.788 l 7.6030004,4.39 a 3.217,3.217 0 0 0 3.219999,0 l 7.603,-4.39 a 3.217,3.217 0 0 0 1.61,-2.788 V 7.6100733 a 3.217,3.217 0 0 0 -1.61,-2.788 l -7.603,-4.38999997 a 3.218,3.218 0 0 0 -1.61,-0.431999993226 z m 0,2.357999963226 c 0.15,0 0.299,0.039 0.431,0.115 l 7.604,4.39 c 0.132,0.077 0.24,0.187 0.315,0.316 l -8.35,4.8209997 v 9.642 a 0.863,0.863 0 0 1 -0.431,-0.116 l -7.6039994,-4.39 a 0.866,0.866 0 0 1 -0.431,-0.746 V 7.6100733 c 0,-0.153 0.041,-0.302 0.116,-0.43 l 8.3499994,4.8199997 z"
id="path1" />
<metadata
id="metadata1">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:title>Flatpak</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="98"
height="96"
version="1.1"
id="svg1"
sodipodi:docname="github-symbolic.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="2.4081633"
inkscape:cx="32.597458"
inkscape:cy="46.716102"
inkscape:window-width="1339"
inkscape:window-height="1028"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"
fill="#fff"
id="path1"
style="fill:#000000" />
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

@@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
fill="#000000"
width="20"
height="20"
viewBox="0 0 380.95238 380.95238"
version="1.1"
id="svg1"
sodipodi:docname="google-gemini-symbolic.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="17.5"
inkscape:cx="10.828571"
inkscape:cy="16.971429"
inkscape:window-width="1351"
inkscape:window-height="981"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<title
id="title1">ionicons-v5_logos</title>
<path
d="m 190.47617,352.20814 v 0 0 C 177.81956,268.68717 112.26524,203.13276 28.744252,190.4762 v 0 0 C 112.26524,177.81957 177.81956,112.26522 190.47617,28.744235 v 0 0 c 12.65659,83.520985 78.2109,149.075335 161.73196,161.731965 v 0 0 c -83.52106,12.65656 -149.07537,78.21097 -161.73196,161.73194 z"
fill="#076eff"
id="path19"
style="fill:#000000;stroke-width:4.44566" />
<metadata
id="metadata1">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:title>ionicons-v5_logos</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 16 KiB

@@ -1,54 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 20.999999 20.999999"
version="1.1"
id="svg4"
sodipodi:docname="Microsoft_icon.svg"
width="20"
height="20"
inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs4" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="19.142857"
inkscape:cx="10.970149"
inkscape:cy="12.746269"
inkscape:window-width="1197"
inkscape:window-height="1028"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
fill="#f35325"
d="M 0,0 H 10 V 10 H 0 Z"
id="path1"
style="fill:#000000" />
<path
fill="#81bc06"
d="M 11,0 H 21 V 10 H 11 Z"
id="path2"
style="fill:#000000" />
<path
fill="#05a6f0"
d="M 0,11 H 10 V 21 H 0 Z"
id="path3"
style="fill:#000000" />
<path
fill="#ffba08"
d="M 11,11 H 21 V 21 H 11 Z"
id="path4"
style="fill:#000000" />
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

@@ -1,77 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="20"
width="19.999744"
version="1.1"
id="svg8"
sodipodi:docname="nixos-symbolic.svg"
viewBox="0 0 512.00001 512.00656"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview8"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="27.34375"
inkscape:cx="8.832"
inkscape:cy="15.817143"
inkscape:window-width="1075"
inkscape:window-height="1028"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg8" />
<g
fill-rule="evenodd"
transform="matrix(1.2756532,0,0,-1.2756532,9.0810546e-6,478.03773)"
id="g8"
style="fill:#000000">
<path
d="m 122.453,169.761 97.758,-169.34 -44.926,-0.422 -26.101,45.496 -26.286,-45.25 -22.32,0.008 -11.433,19.75 37.449,64.394 -26.582,46.258 z"
fill="#5277c3"
id="path1"
style="fill:#000000" />
<path
d="M 157.738,239.515 59.961,70.183 37.133,108.882 63.484,154.229 11.152,154.366 0,173.702 l 11.391,19.777 74.488,-0.234 26.769,46.152 z"
fill="#7ebae4"
id="path2"
style="fill:#000000" />
<path
d="M 165.238,104.155 360.77,104.143 338.672,65.026 286.223,65.171 312.27,19.784 301.102,0.456 278.277,0.429 241.238,65.058 187.883,65.167 Z"
fill="#7ebae4"
id="path3"
style="fill:#000000" />
<path
d="m 279.043,178.35 -97.758,169.34 44.926,0.422 26.101,-45.496 26.286,45.254 22.32,-0.008 11.434,-19.754 -37.45,-64.39 26.582,-46.262 z"
fill="#7ebae4"
id="path4"
style="fill:#000000" />
<g
fill="#5277c3"
id="g7"
style="fill:#000000">
<path
d="m 122.453,169.761 97.758,-169.34 -44.926,-0.422 -26.101,45.496 -26.286,-45.25 -22.32,0.008 -11.433,19.75 37.449,64.394 -26.582,46.258 z"
id="path5"
style="fill:#000000" />
<path
d="m 236,244.386 -195.535,0.011 22.101,39.118 52.45,-0.149 -26.047,45.391 11.168,19.328 22.82,0.023 37.043,-64.625 53.352,-0.109 z"
id="path6"
style="fill:#000000" />
<path
d="m 243.625,108.636 97.777,169.328 22.825,-38.696 -26.348,-45.351 52.332,-0.137 11.152,-19.336 -11.39,-19.777 -74.489,0.238 -26.769,-46.152 z"
id="path7"
style="fill:#000000" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

@@ -1,60 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="20"
height="20.000149"
viewBox="0 0 853.78869 853.79504"
fill="none"
version="1.1"
id="svg5"
sodipodi:docname="ollama-symbolic.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs5" />
<sodipodi:namedview
id="namedview5"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
showguides="false"
inkscape:zoom="23.606557"
inkscape:cx="13.004861"
inkscape:cy="9.8065973"
inkscape:window-width="1374"
inkscape:window-height="848"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg5" />
<g
id="g5"
transform="translate(103.8943,1.5259608e-5)">
<path
d="M 140.629,0.23994313 C 132.66,1.5272641 123.097,5.6956941 116.354,10.845014 c -20.413,15.5091 -36.2287,48.4278 -42.9105,89.437996 -2.5133,15.509 -4.2297,37.026 -4.2297,53.455 0,19.371 2.2681,44.136 5.5171,61.239 0.7356,3.801 1.1034,7.173 0.7969,7.418 -0.2452,0.245 -3.249,2.697 -6.6206,5.394 -11.5245,9.195 -24.7043,23.356 -33.7768,36.291 -17.4095,24.704 -28.6888898,52.78 -33.4090698,83.185 -1.83902799,12.015 -2.32943599,36.29 -0.85821199,48.305 3.24895199,27.708 11.58588179,51.125 25.86898179,72.581 l 4.6589,6.927 -1.3486,2.268 c -9.563,16.061 -17.716,39.294 -21.5166498,61.607 -3.00375,17.655 -3.37156,22.375 -3.37156,46.037 0,23.847 0.30651,28.567 3.12635,45.057 3.3715598,19.739 10.2372598,40.642 17.8998598,54.558 2.5134,4.536 8.6435,13.976 9.3791,14.467 0.2452,0.122 -0.4904,2.39 -1.6551,5.026 -8.8274,19.31 -16.3674,44.995 -19.4938,66.635 -2.2068,14.834 -2.5133,19.616 -2.5133,35.248 0,19.922 1.1034,29.608 5.2719,45.485 l 0.613,2.329 H 44.019 70.3172 l -1.7165,-3.249 c -10.605,-19.616 -11.5858,-56.029 -2.452,-92.38 4.1685,-16.797 8.8887,-29.118 17.716,-46.099 l 5.2719,-10.298 v -6.314 c 0,-5.885 -0.1226,-6.559 -2.0229,-10.421 -1.4713,-2.943 -3.4329,-5.456 -6.9271,-8.889 -5.9462,-5.762 -10.2372,-11.831 -13.6701,-19.31 -15.08,-32.735 -18.0225,-81.346 -7.4174,-122.786 4.4137,-17.287 11.7085,-32.673 19.3711,-41.071 5.2106,-5.763 7.9078,-12.199 7.9078,-18.881 0,-6.927 -2.452,-12.628 -7.9691,-18.574 -15.8157,-16.919 -25.5625,-37.517 -29.0567,-61.485 -4.9654,-34.145 4.0459,-71.355 24.5204,-100.84 20.0455,-28.935 48.1824,-47.509 79.6304,-52.474 7.049,-1.165 20.229,-0.981 27.585,0.368 8.031,1.41 13.057,0.98 18.207,-1.472 6.375,-3.003 9.563,-6.743 13.302,-15.325 3.31,-7.662 5.885,-11.831 12.812,-20.474 8.337,-10.36 16.367,-17.41 29.24,-25.931 14.713,-9.624 31.448,-16.612 48.122,-19.984 6.068,-1.226 8.888,-1.41 20.229,-1.41 11.341,0 14.161,0.184 20.229,1.41 24.459,4.966 48.735,17.594 68.106,35.493 4.168,3.862 14.16,16.245 17.348,21.395 1.226,2.022 3.372,6.314 4.72,9.501 3.739,8.582 6.927,12.322 13.302,15.325 4.966,2.391 10.176,2.882 17.9,1.594 12.199,-2.084 21.578,-1.9 33.532,0.552 40.704,8.214 76.136,41.746 91.829,86.68 13.67,39.416 9.808,80.672 -10.544,112.18 -3.433,5.334 -6.866,9.625 -11.831,14.897 -10.728,11.463 -10.728,25.685 -0.061,37.455 17.532,19.187 28.505,66.389 25.194,108.012 -2.206,27.463 -9.256,52.045 -18.942,65.96 -1.716,2.452 -5.271,6.62 -7.969,9.195 -3.494,3.433 -5.455,5.946 -6.927,8.889 -1.9,3.862 -2.023,4.536 -2.023,10.421 v 6.314 l 5.272,10.298 c 8.828,16.981 13.548,29.302 17.716,46.099 9.012,35.861 8.215,71.538 -2.084,91.829 -0.858,1.716 -1.594,3.31 -1.594,3.494 0,0.184 11.709,0.306 26.053,0.306 h 25.992 l 0.674,-2.636 c 0.368,-1.409 0.981,-3.555 1.287,-4.781 0.675,-2.697 2.023,-10.666 3.127,-18.329 1.042,-7.724 1.042,-36.168 0,-44.75 -3.923,-31.141 -10.483,-55.845 -21.21,-79.201 -1.165,-2.636 -1.901,-4.904 -1.656,-5.026 0.307,-0.184 2.023,-2.636 3.862,-5.395 13.364,-20.229 21.578,-45.669 25.747,-79.262 1.103,-9.257 1.103,-49.041 0,-57.93 -2.943,-22.926 -6.498,-38.497 -12.383,-54.251 -2.452,-6.559 -8.95,-20.413 -11.708,-24.888 l -1.349,-2.268 4.659,-6.927 c 14.283,-21.456 22.62,-44.873 25.869,-72.581 1.471,-12.015 0.981,-36.29 -0.858,-48.305 -4.782,-30.467 -16,-58.42 -33.409,-83.185 -9.073,-12.935 -22.253,-27.096 -33.777,-36.291 -3.372,-2.697 -6.376,-5.149 -6.621,-5.394 -0.306,-0.245 0.062,-3.617 0.797,-7.418 7.418,-38.681 7.172,-86.924 -0.613,-124.624596 -6.743,-32.8573 -19.003,-58.9716 -34.819,-74.0516 C 523.209,4.2857941 510.336,-0.86349287 494.888,0.11732413 459.456,2.2015541 430.89,42.966714 419.61,107.21001 c -1.839,10.36 -3.432,22.498 -3.432,25.808 0,1.287 -0.246,2.329 -0.552,2.329 -0.307,0 -2.697,-1.226 -5.272,-2.758 -27.34,-16.184 -57.746,-24.827 -87.354,-24.827 -29.608,0 -60.014,8.643 -87.354,24.827 -2.575,1.532 -4.965,2.758 -5.272,2.758 -0.306,0 -0.552,-1.042 -0.552,-2.329 0,-3.433 -1.655,-15.938 -3.432,-25.808 C 216.152,49.525914 192.674,11.335414 161.472,1.7111341 157.181,0.42381313 144.982,-0.43436787 140.629,0.23994313 Z M 151.051,50.139014 c 8.827,6.9883 18.635,26.9724 24.275,49.3473 1.042,4.045696 2.145,8.704696 2.452,10.420696 0.245,1.656 0.919,5.395 1.471,8.276 2.391,12.996 3.494,27.034 3.617,44.137 l 0.061,16.858 -4.23,6.252 -4.229,6.314 h -9.87 c -11.524,0 -22.988,1.472 -33.961,4.414 -3.923,0.981 -7.724,1.962 -8.459,2.146 -1.165,0.245 -1.349,-0.123 -2.023,-5.15 -3.617,-27.279 -3.433,-57.5 0.552,-82.634 4.413,-28.014096 14.712,-53.392696 24.765,-60.871396 2.391,-1.7778 2.82,-1.7165 5.579,0.4904 z m 349.538,-0.4292 c 6.069,4.475 12.751,16.3674 17.716,31.57 9.992,30.405196 12.812,72.151196 7.54,111.874196 -0.674,5.027 -0.858,5.395 -2.023,5.15 -0.735,-0.184 -4.536,-1.165 -8.459,-2.146 -10.973,-2.942 -22.437,-4.414 -33.961,-4.414 h -9.87 l -4.229,-6.314 -4.23,-6.252 0.061,-16.858 c 0.123,-23.785 2.33,-42.359 7.601,-63.017596 5.579,-22.191 15.448,-42.1751 24.214,-49.1634 2.759,-2.2069 3.188,-2.2682 5.64,-0.4292 z"
fill="#000000"
id="path1" />
<path
d="m 313.498,358.23701 c -13.303,1.288 -16.919,1.778 -23.295,3.066 -10.36,2.145 -24.214,6.927 -33.838,11.647 -33.47,16.367 -56.519,43.646 -63.569,75.216 -1.41,6.253 -1.594,8.337 -1.594,18.881 0,10.421 0.184,12.689 1.533,18.635 9.379,41.256 47.385,71.723 96.549,77.301 10.666,1.165 56.765,1.165 67.431,0 39.478,-4.475 73.439,-25.869 88.703,-55.907 4.045,-8.03 6.007,-13.241 7.846,-21.394 1.349,-5.946 1.533,-8.214 1.533,-18.635 0,-10.544 -0.184,-12.628 -1.594,-18.881 -10.238,-45.853 -54.742,-81.959 -109.3,-88.825 -7.111,-0.858 -25.746,-1.594 -30.405,-1.104 z m 22.926,33.348 c 18.207,1.962 36.536,8.46 51.248,18.268 7.908,5.272 19.065,16.306 23.846,23.54 5.885,8.949 9.256,18.083 10.789,29.179 0.674,5.088 0.307,8.95 -1.533,17.164 -2.881,12.26 -11.831,25.072 -23.907,34.022 -5.64,4.107 -17.348,10.054 -24.52,12.383 -13.609,4.352 -22.498,5.149 -54.252,4.904 -20.719,-0.184 -24.398,-0.368 -30.344,-1.471 -20.29,-3.801 -36.351,-11.893 -47.998,-24.214 -9.441,-9.931 -13.732,-19.003 -16.061,-33.654 -1.042,-6.805 0.919,-18.084 4.904,-27.586 4.843,-11.586 17.348,-25.991 29.731,-34.267 14.344,-9.563 33.225,-16.367 50.573,-18.206 6.682,-0.736 20.842,-0.736 27.524,-0.062 z"
fill="#000000"
id="path2" />
<path
d="m 299.584,436.33601 c -4.659,2.513 -7.908,8.888 -6.927,13.608 1.103,5.088 5.578,10.238 12.566,14.468 3.74,2.268 3.985,2.574 4.169,4.842 0.122,1.349 -0.368,5.211 -1.042,8.644 -0.736,3.371 -1.288,6.927 -1.288,7.908 0.062,2.636 2.514,6.927 5.088,9.011 2.269,1.839 2.698,1.9 9.073,2.084 5.824,0.184 7.05,0.061 9.379,-1.042 6.008,-2.943 7.54,-8.337 5.333,-18.697 -1.839,-8.643 -1.471,-9.992 3.127,-12.628 4.842,-2.82 9.992,-7.785 11.524,-11.157 2.943,-6.436 0.245,-13.731 -6.253,-17.103 -1.593,-0.797 -3.555,-1.164 -6.436,-1.164 -4.475,0 -7.356,1.042 -12.628,4.413 l -3.004,1.901 -1.9,-1.165 c -7.785,-4.598 -9.195,-5.149 -13.916,-5.088 -3.371,0 -5.21,0.306 -6.865,1.165 z"
fill="#000000"
id="path3" />
<path
d="m 150.744,365.16501 c -10.85,3.433 -18.942,11.402 -23.11,22.743 -2.023,5.395 -3.004,13.916 -2.146,18.513 2.023,10.973 11.034,20.965 21.272,23.724 12.873,3.371 22.497,1.164 31.018,-7.295 4.965,-4.843 7.663,-9.073 10.36,-15.939 1.961,-4.842 2.084,-5.7 2.084,-12.566 l 0.061,-7.356 -2.574,-5.272 c -4.108,-8.337 -11.525,-14.529 -20.107,-16.797 -4.843,-1.226 -12.628,-1.164 -16.858,0.245 z"
fill="#000000"
id="path4" />
<path
d="m 478.153,364.98201 c -8.398,2.268 -15.877,8.52 -19.862,16.735 l -2.574,5.272 0.061,7.356 c 0,6.866 0.123,7.724 2.084,12.566 2.698,6.866 5.395,11.096 10.36,15.939 8.521,8.459 18.145,10.666 31.019,7.295 7.417,-1.962 14.834,-8.215 18.39,-15.51 3.065,-6.191 3.8,-10.666 2.82,-17.716 -2.268,-16.122 -11.709,-27.83 -25.747,-31.937 -4.107,-1.226 -12.076,-1.226 -16.551,0 z"
fill="#000000"
id="path5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.8 KiB

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 322.58065 322.58064"
version="1.1"
id="svg1"
sodipodi:docname="openai-symbolic.svg"
width="20"
height="20"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="30.935922"
inkscape:cx="9.0348044"
inkscape:cy="14.917933"
inkscape:window-width="1183"
inkscape:window-height="1028"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 298.66868,131.77215 c 7.30439,-21.92321 4.7891,-45.939129 -6.89187,-65.880296 C 274.21007,35.30601 238.89549,19.570397 204.40593,26.975391 189.0627,9.6903649 167.01876,-0.13936259 143.90833,0.0014933 108.65412,-0.07899576 77.374064,22.618921 66.528162,56.162739 43.880552,60.800921 24.33177,74.977058 12.892261,95.069141 -4.8052718,125.57449 -0.77075743,164.02814 22.872905,190.18709 c -7.304382,21.92321 -4.789099,45.93913 6.891877,65.8803 17.566738,30.58585 52.881316,46.32146 87.370878,38.91646 15.33316,17.28503 37.38717,27.11476 60.49759,26.96384 35.27433,0.0905 66.56446,-22.62749 77.41036,-56.20149 22.64761,-4.63818 42.19639,-18.81432 53.6359,-38.9064 17.67741,-30.50536 13.63284,-68.92883 -10.00077,-95.08777 z M 177.65337,300.90986 c -14.11577,0.0201 -27.78885,-4.91989 -38.62469,-13.96485 0.493,-0.26159 1.34819,-0.73446 1.90156,-1.07654 l 64.10954,-37.02497 c 3.27993,-1.86131 5.29215,-5.35253 5.27203,-9.12545 v -90.37916 l 27.09463,15.64506 c 0.29178,0.14086 0.48294,0.42257 0.52318,0.74453 v 74.84477 c -0.0402,33.28222 -26.99402,60.26618 -60.27625,60.33661 z M 48.025738,245.54345 c -7.072976,-12.21422 -9.618443,-26.53121 -7.19371,-40.42564 0.472874,0.28171 1.307948,0.79483 1.901554,1.13691 l 64.109538,37.02497 c 3.24974,1.90155 7.2742,1.90155 10.534,0 l 78.26556,-45.19461 v 31.29012 c 0.0201,0.32196 -0.1308,0.63386 -0.38232,0.83508 l -64.80376,37.41735 c -28.86539,16.62099 -65.72938,6.74096 -82.4208,-22.08418 z M 31.153218,105.60314 c 7.042793,-12.234331 18.160346,-21.591185 31.400797,-26.450712 0,0.553362 -0.03018,1.529292 -0.03018,2.213449 v 74.059993 c -0.02012,3.76287 1.992105,7.25408 5.261973,9.11539 l 78.265542,45.18455 -27.09463,15.64506 c -0.27165,0.1811 -0.61373,0.21129 -0.91556,0.0805 L 53.227344,188.00382 C 24.42232,171.32247 14.542287,134.46853 31.143157,105.6132 Z m 222.612632,51.80478 -78.26556,-45.19461 27.09463,-15.634999 c 0.27165,-0.181101 0.61373,-0.211284 0.91557,-0.08049 l 64.81382,37.417349 c 28.85533,16.6713 38.74542,53.5856 22.07412,82.44093 -7.05285,12.21421 -18.16034,21.57107 -31.39073,26.44066 V 166.5233 c 0.0302,-3.76286 -1.97199,-7.24401 -5.23179,-9.11538 z m 26.96383,-40.58661 c -0.47287,-0.29178 -1.30794,-0.79483 -1.90155,-1.13691 L 214.71859,78.659433 c -3.24975,-1.901555 -7.2742,-1.901555 -10.53401,0 L 125.91903,123.85404 V 92.563919 c -0.0201,-0.321957 0.13079,-0.633852 0.38232,-0.835074 l 64.80376,-37.387171 c 28.86539,-16.651176 65.76963,-6.74096 82.41074,22.134493 7.03273,12.194093 9.5782,26.470833 7.19371,40.345143 z M 111.18953,172.59017 84.08484,156.94511 c -0.291773,-0.14086 -0.482934,-0.42257 -0.523179,-0.74453 V 81.355816 c 0.02012,-33.322473 27.054379,-60.326555 60.376859,-60.306432 14.09564,0 27.73854,4.950077 38.57438,13.964853 -0.493,0.261589 -1.33813,0.734462 -1.90155,1.076541 l -64.10954,37.02497 c -3.27993,1.86131 -5.29216,5.342462 -5.27204,9.115387 l -0.0402,90.338915 z m 14.71943,-31.73282 34.86183,-20.13232 34.86183,20.12226 v 40.2546 l -34.86183,20.12226 -34.86183,-20.12226 z"
id="path1"
style="stroke-width:1.00611" />
</svg>

Before

Width:  |  Height:  |  Size: 4.0 KiB

@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
width="20.000015"
height="20"
id="svg1"
sodipodi:docname="openrouter-symbolic.svg"
viewBox="0 0 47.999998 47.999962"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:zoom="19.666667"
inkscape:cx="6.7118644"
inkscape:cy="10.805085"
inkscape:window-width="1908"
inkscape:window-height="1028"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<path
d="m 32.999999,2.9999808 c 3.980422,0.5880984 6.862472,1.8203168 10.3125,3.875 0.883008,0.5130469 1.766016,1.0260937 2.675781,1.5546875 0.663867,0.5182031 1.327735,1.0364062 2.011719,1.5703125 0,0.9900002 0,1.9800002 0,3.0000002 -2.311036,1.335928 -4.623718,2.668844 -6.9375,4 -0.659355,0.381562 -1.318711,0.763125 -1.998047,1.15625 -4.951172,2.84375 -4.951172,2.84375 -6.064453,2.84375 0,-1.65 0,-3.3 0,-5 -6.609294,1.004133 -10.792298,2.789518 -16,7 3.696448,3.823912 6.292078,6.155833 11.6875,6.625 0.808242,0.07477 1.616484,0.149531 2.449219,0.226562 0.614883,0.04898 1.229765,0.09797 1.863281,0.148438 0,-0.99 0,-1.98 0,-3 4.062255,0.578231 6.847624,1.891177 10.3125,4.0625 0.883008,0.547852 1.766016,1.095703 2.675781,1.660156 0.663867,0.421524 1.327735,0.843047 2.011719,1.277344 -1.156668,3.470003 -1.857267,3.847015 -4.875,5.6875 -0.698672,0.436992 -1.397344,0.873984 -2.117188,1.324219 -2.007812,0.988281 -2.007812,0.988281 -5.007812,0.988281 0,0.66 0,1.32 0,2 -0.99,0.33 -1.98,0.66 -3,1 0,-1.32 0,-2.64 0,-4 C 32.359335,40.962601 31.718671,40.925211 31.058593,40.8867 22.287404,40.220037 16.393127,37.373973 9.2226552,32.429668 6.2608222,30.524517 3.2830902,29.257335 -8.4473381e-7,27.999981 c 0,-3.3 0,-6.6 0,-10 C 1.6232682,17.32911 3.2486752,16.663411 4.8749992,15.999981 c 0.904922,-0.37125 1.809844,-0.7425 2.742188,-1.125 2.382812,-0.875 2.382812,-0.875 4.3828118,-0.875 0,-0.66 0,-1.32 0,-2 0.99,0 1.98,0 3,0 0,-0.66 0,-1.32 0,-2.0000002 6.284532,-3.3279791 10.886587,-4.4516452 18,-4 0,-0.99 0,-1.98 0,-3 z"
fill="#93a2b8"
id="path1"
style="fill:#000000" />
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg
fill="#000000"
height="20.000002"
width="20"
version="1.1"
id="Capa_1"
viewBox="0 0 493.42511 493.42516"
xml:space="preserve"
sodipodi:docname="ubuntu-logo-svgrepo-com.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs9" /><sodipodi:namedview
id="namedview9"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="12.374369"
inkscape:cx="24.76894"
inkscape:cy="15.515943"
inkscape:window-width="1415"
inkscape:window-height="753"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="Capa_1" />
<g
id="ubuntu"
transform="translate(5.5573583e-4,0.00107926)">
<g
id="g2">
<g
id="g1">
<path
d="m 168.839,241.198 c 0,-38.117 17.894,-72.05 45.685,-93.896 L 171.988,79.22 c -35.648,25.603 -62.472,62.66 -75.127,105.796 19.811,12.751 32.949,35.031 32.949,60.353 0,24.424 -12.143,45.957 -30.783,58.918 13.606,40.86 40.12,75.838 74.706,100.113 l 39.559,-70.358 c -27.105,-21.838 -44.453,-55.318 -44.453,-92.844 z"
id="path1" />
</g>
</g>
<g
id="g3">
<path
d="m 109.704,245.368 c 0,28.484 -23.132,51.592 -51.609,51.592 -28.491,0 -51.606,-23.107 -51.606,-51.592 0,-28.47 23.115,-51.577 51.606,-51.577 28.477,0 51.609,23.107 51.609,51.577 z"
id="path2" />
</g>
<g
id="g5">
<g
id="g4">
<path
d="m 399.494,370.126 c 12.002,0 23.301,2.936 33.23,8.149 30.924,-32.591 50.906,-75.595 54.211,-123.228 l -80.148,-1.551 c -6.171,60.111 -56.954,106.941 -118.677,106.941 -17.084,0 -33.388,-3.594 -48.101,-10.093 l -39.841,69.704 c 26.56,13.069 56.376,20.411 87.941,20.411 13.622,0 26.981,-1.379 39.854,-4.006 2.746,-37.072 33.717,-66.327 71.531,-66.327 z"
id="path3" />
</g>
</g>
<g
id="g6">
<path
d="m 451.071,441.847 c 0,28.478 -23.084,51.576 -51.577,51.576 -28.493,0 -51.594,-23.098 -51.594,-51.576 0,-28.5 23.101,-51.592 51.594,-51.592 28.493,0 51.577,23.092 51.577,51.592 z"
id="path5" />
</g>
<g
id="g8">
<g
id="g7">
<path
d="m 438.211,110.152 c -11.677,8.269 -25.968,13.163 -41.399,13.163 -39.637,0 -71.73,-32.102 -71.73,-71.715 0,-2.104 0.094,-4.139 0.25,-6.181 -12.05,-2.307 -24.503,-3.491 -37.222,-3.491 -31.859,0 -61.988,7.498 -88.689,20.777 l 39.607,69.75 c 14.979,-6.748 31.593,-10.544 49.082,-10.544 61.177,0 111.601,46.074 118.491,105.414 l 80.147,-2.447 C 483.209,181.12 465.487,141.372 438.211,110.152 Z"
id="path6" />
</g>
</g>
<g
id="g9">
<path
d="m 448.374,51.601 c 0,28.492 -23.038,51.592 -51.561,51.592 -28.491,0 -51.592,-23.1 -51.592,-51.592 C 345.22,23.107 368.321,0 396.812,0 c 28.523,0 51.562,23.107 51.562,51.601 z"
id="path8" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

@@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
@@ -1,95 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<style-scheme id="custom-light" _name="Custom" version="1.0">
<author>end_4</author>
<_description>Catppuccin port but very random</_description>
<style name="bracket-match" background="#FDC2A6" foreground="#653D28" bold="true"/>
<style name="bracket-mismatch" background="#E3E6EB" underline="true"/>
<style name="c:preprocessor" foreground="#DF8E1D"/>
<style name="css:at-rules" foreground="#8839EF"/>
<style name="css:color" foreground="#DF8E1D"/>
<style name="css:keyword" foreground="#256BF5"/>
<style name="current-line" background="#F9DCD8"/>
<style name="cursor" foreground="#DC8A78"/>
<style name="def:base-n-integer" foreground="#DF8E1D"/>
<style name="def:boolean" foreground="#DF8E1D"/>
<style name="def:builtin" foreground="#DF8E1D"/>
<style name="def:character" foreground="#DF8E1D"/>
<style name="def:comment" foreground="#9DA1B1"/>
<style name="def:complex" foreground="#DF8E1D"/>
<style name="def:decimal" foreground="#DF8E1D"/>
<style name="def:doc-comment" foreground="#9DA1B1"/>
<style name="def:doc-comment-element" foreground="#9DA1B1"/>
<style name="def:error" foreground="#D53055" background="#EAEDF2"/>
<style name="def:floating-point" foreground="#DF8E1D"/>
<style name="def:function" foreground="#256BF5"/>
<style name="def:identifier" foreground="#000000"/>
<style name="def:keyword" foreground="#8839EF"/>
<style name="def:note" foreground="#9DA1B1"/>
<style name="def:number" foreground="#FE640B"/>
<style name="def:operator" foreground="#8839EF"/>
<style name="def:preprocessor" foreground="#256BF5"/>
<style name="def:reserved" foreground="#8839EF"/>
<style name="def:shebang" foreground="#9DA1B1"/>
<style name="def:special-char" foreground="#256BF5"/>
<style name="def:special-constant" foreground="#DF8E1D"/>
<style name="def:statement" foreground="#8839EF"/>
<style name="def:string" foreground="#4AA537"/>
<style name="def:type" foreground="#256BF5" italic="true"/>
<style name="diff:added-line" foreground="#282D32" background="#ACF2BD"/>
<style name="diff:changed-line" foreground="#282D32" background="#F1F2C3"/>
<style name="diff:location" foreground="#9DA1B1"/>
<style name="diff:removed-line" foreground="#282D32" background="#FFEEF0"/>
<style name="draw-spaces" foreground="#3b3a32"/>
<style name="html:dtd" foreground="#4AA537"/>
<style name="html:tag" foreground="#8839EF"/>
<style name="js:function" foreground="#256BF5"/>
<style name="line-numbers" foreground="#9699AA" background="#EAEDF2"/>
<style name="perl:builtin" foreground="#256BF5"/>
<style name="perl:include-statement" foreground="#8839EF"/>
<style name="perl:special-variable" foreground="#DF8E1D"/>
<style name="perl:variable" foreground="#000000"/>
<style name="php:string" foreground="#4AA537"/>
<style name="python:builtin-constant" foreground="#8839EF"/>
<style name="python:builtin-function" foreground="#256BF5"/>
<style name="python:module-handler" foreground="#8839EF"/>
<style name="python:special-variable" foreground="#8839EF"/>
<style name="ruby:attribute-definition" foreground="#8839EF"/>
<style name="ruby:builtin" foreground="#000000"/>
<style name="ruby:class-variable" foreground="#000000"/>
<style name="ruby:constant" foreground="#000000"/>
<style name="ruby:global-variable" foreground="#256BF5"/>
<style name="ruby:instance-variable" foreground="#000000"/>
<style name="ruby:module-handler" foreground="#8839EF"/>
<style name="ruby:predefined-variable" foreground="#DF8E1D"/>
<style name="ruby:regex" foreground="#f6aa11"/>
<style name="ruby:special-variable" foreground="#8839EF"/>
<style name="ruby:symbol" foreground="#DF8E1D"/>
<style name="rubyonrails:attribute-definition" foreground="#8839EF"/>
<style name="rubyonrails:block-parameter" foreground="#fd971f" italic="true"/>
<style name="rubyonrails:builtin" foreground="#000000"/>
<style name="rubyonrails:class-inherit" foreground="#256BF5" underline="true" italic="true"/>
<style name="rubyonrails:class-name" foreground="#256BF5"/>
<style name="rubyonrails:class-variable" foreground="#000000"/>
<style name="rubyonrails:complex-interpolation" foreground="#DF8E1D"/>
<style name="rubyonrails:constant" foreground="#000000"/>
<style name="rubyonrails:global-variable" foreground="#256BF5"/>
<style name="rubyonrails:instance-variable" foreground="#000000"/>
<style name="rubyonrails:module-handler" foreground="#8839EF"/>
<style name="rubyonrails:module-name" foreground="#256BF5"/>
<style name="rubyonrails:predefined-variable" foreground="#DF8E1D"/>
<style name="rubyonrails:rails" foreground="#000000"/>
<style name="rubyonrails:regex" foreground="#f6aa11"/>
<style name="rubyonrails:simple-interpolation" foreground="#DF8E1D"/>
<style name="rubyonrails:special-variable" foreground="#8839EF"/>
<style name="rubyonrails:symbol" foreground="#DF8E1D"/>
<style name="search-match" background="#E3E6EB" bold="true" underline="true"/>
<style name="selection" foreground="#f8f8f2" background="#444444"/>
<style name="text" foreground="#f8f8f2" background="#222222"/>
<style name="xml:attribute-name" foreground="#256BF5"/>
<style name="xml:element-name" foreground="#8839EF"/>
<style name="xml:entity" foreground="#c8cecc"/>
<style name="xml:namespace" foreground="#8839EF"/>
<style name="xml:tag" foreground="#8839EF"/>
</style-scheme>
@@ -1,121 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2014 Leo Iannacone <info@leoiannacone.com>
This file was generated from a textmate theme named Monokai Extended
with tm2gtksw2 tool. (Alexandre da Silva)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
-->
<!-- MODIFIED -->
<style-scheme id="custom" _name="Custom" version="1.0">
<author>Leo Iannacone</author>
<_description>Based on SublimeText Monokai Extended - Generated with tm2gtksw2</_description>
<style name="bracket-match" background="#FDC2A6" foreground="#653D28" bold="true"/>
<style name="bracket-mismatch" background="#333333" underline="true"/>
<style name="c:preprocessor" foreground="#be84ff"/>
<style name="css:at-rules" foreground="#f92672"/>
<style name="css:color" foreground="#be84ff"/>
<style name="css:keyword" foreground="#66d9ef"/>
<style name="current-line" background="#F9DCD8"/>
<style name="cursor" foreground="#f8f8f0"/>
<style name="def:base-n-integer" foreground="#be84ff"/>
<style name="def:boolean" foreground="#be84ff"/>
<style name="def:builtin" foreground="#be84ff"/>
<style name="def:character" foreground="#be84ff"/>
<style name="def:comment" foreground="#75715e"/>
<style name="def:complex" foreground="#be84ff"/>
<style name="def:decimal" foreground="#be84ff"/>
<style name="def:doc-comment" foreground="#75715e"/>
<style name="def:doc-comment-element" foreground="#75715e"/>
<style name="def:error" foreground="#f8f8f0" background="#f92672"/>
<style name="def:floating-point" foreground="#be84ff"/>
<style name="def:function" foreground="#a6e22e"/>
<style name="def:identifier" foreground="#ffffff"/>
<style name="def:keyword" foreground="#f92672"/>
<style name="def:note" foreground="#75715e"/>
<style name="def:number" foreground="#be84ff"/>
<style name="def:operator" foreground="#f92672"/>
<style name="def:preprocessor" foreground="#66d9ef"/>
<style name="def:reserved" foreground="#f92672"/>
<style name="def:shebang" foreground="#75715e"/>
<style name="def:special-char" foreground="#66d9ef"/>
<style name="def:special-constant" foreground="#be84ff"/>
<style name="def:statement" foreground="#f92672"/>
<style name="def:string" foreground="#e6db74"/>
<style name="def:type" foreground="#66d9ef" italic="true"/>
<style name="diff:added-line" foreground="#a6e22e"/>
<style name="diff:changed-line" foreground="#e6db74"/>
<style name="diff:location" foreground="#75715e"/>
<style name="diff:removed-line" foreground="#f92672"/>
<style name="draw-spaces" foreground="#3b3a32"/>
<style name="html:dtd" foreground="#e6db74"/>
<style name="html:tag" foreground="#f92672"/>
<style name="js:function" foreground="#66d9ef"/>
<style name="line-numbers" foreground="#bebeba" background="#333333"/>
<style name="perl:builtin" foreground="#a6e22e"/>
<style name="perl:include-statement" foreground="#f92672"/>
<style name="perl:special-variable" foreground="#be84ff"/>
<style name="perl:variable" foreground="#ffffff"/>
<style name="php:string" foreground="#e6db74"/>
<style name="python:builtin-constant" foreground="#f92672"/>
<style name="python:builtin-function" foreground="#a6e22e"/>
<style name="python:module-handler" foreground="#f92672"/>
<style name="python:special-variable" foreground="#f92672"/>
<style name="ruby:attribute-definition" foreground="#f92672"/>
<style name="ruby:builtin" foreground="#ffffff"/>
<style name="ruby:class-variable" foreground="#ffffff"/>
<style name="ruby:constant" foreground="#ffffff"/>
<style name="ruby:global-variable" foreground="#a6e22e"/>
<style name="ruby:instance-variable" foreground="#ffffff"/>
<style name="ruby:module-handler" foreground="#f92672"/>
<style name="ruby:predefined-variable" foreground="#be84ff"/>
<style name="ruby:regex" foreground="#f6aa11"/>
<style name="ruby:special-variable" foreground="#f92672"/>
<style name="ruby:symbol" foreground="#be84ff"/>
<style name="rubyonrails:attribute-definition" foreground="#f92672"/>
<style name="rubyonrails:block-parameter" foreground="#fd971f" italic="true"/>
<style name="rubyonrails:builtin" foreground="#ffffff"/>
<style name="rubyonrails:class-inherit" foreground="#a6e22e" underline="true" italic="true"/>
<style name="rubyonrails:class-name" foreground="#66d9ef"/>
<style name="rubyonrails:class-variable" foreground="#ffffff"/>
<style name="rubyonrails:complex-interpolation" foreground="#be84ff"/>
<style name="rubyonrails:constant" foreground="#ffffff"/>
<style name="rubyonrails:global-variable" foreground="#a6e22e"/>
<style name="rubyonrails:instance-variable" foreground="#ffffff"/>
<style name="rubyonrails:module-handler" foreground="#f92672"/>
<style name="rubyonrails:module-name" foreground="#66d9ef"/>
<style name="rubyonrails:predefined-variable" foreground="#be84ff"/>
<style name="rubyonrails:rails" foreground="#ffffff"/>
<style name="rubyonrails:regex" foreground="#f6aa11"/>
<style name="rubyonrails:simple-interpolation" foreground="#be84ff"/>
<style name="rubyonrails:special-variable" foreground="#f92672"/>
<style name="rubyonrails:symbol" foreground="#be84ff"/>
<style name="search-match" background="#333333" bold="true" underline="true"/>
<style name="selection" foreground="#f8f8f2" background="#444444"/>
<style name="text" foreground="#f8f8f2" background="#222222"/>
<style name="xml:attribute-name" foreground="#a6e22e"/>
<style name="xml:element-name" foreground="#f92672"/>
<style name="xml:entity" foreground="#c8cecc"/>
<style name="xml:namespace" foreground="#f92672"/>
<style name="xml:tag" foreground="#f92672"/>
</style-scheme>
-81
View File
@@ -1,81 +0,0 @@
"use strict";
// Import
import Gdk from 'gi://Gdk';
import GLib from 'gi://GLib';
import App from 'resource:///com/github/Aylur/ags/app.js'
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
// Stuff
import userOptions from './modules/.configuration/user_options.js';
import { firstRunWelcome, startBatteryWarningService } from './services/messages.js';
import { startAutoDarkModeService } from './services/darkmode.js';
// Widgets
import { Bar, BarCornerTopleft, BarCornerTopright } from './modules/bar/main.js';
import Cheatsheet from './modules/cheatsheet/main.js';
// import DesktopBackground from './modules/desktopbackground/main.js';
import Dock from './modules/dock/main.js';
import Corner from './modules/screencorners/main.js';
import Crosshair from './modules/crosshair/main.js';
import Indicator from './modules/indicators/main.js';
import Osk from './modules/onscreenkeyboard/main.js';
import Overview from './modules/overview/main.js';
import Session from './modules/session/main.js';
import SideLeft from './modules/sideleft/main.js';
import SideRight from './modules/sideright/main.js';
import { COMPILED_STYLE_DIR } from './init.js';
const range = (length, start = 1) => Array.from({ length }, (_, i) => i + start);
function forMonitors(widget) {
const n = Gdk.Display.get_default()?.get_n_monitors() || 1;
return range(n, 0).map(widget).flat(1);
}
function forMonitorsAsync(widget) {
const n = Gdk.Display.get_default()?.get_n_monitors() || 1;
return range(n, 0).forEach((n) => widget(n).catch(print))
}
// Start stuff
handleStyles(true);
startAutoDarkModeService().catch(print);
firstRunWelcome().catch(print);
startBatteryWarningService().catch(print)
const Windows = () => [
// forMonitors(DesktopBackground),
forMonitors(Crosshair),
Overview(),
forMonitors(Indicator),
forMonitors(Cheatsheet),
SideLeft(),
SideRight(),
forMonitors(Osk),
forMonitors(Session),
...(userOptions.dock.enabled ? [forMonitors(Dock)] : []),
...(userOptions.appearance.fakeScreenRounding !== 0 ? [
forMonitors((id) => Corner(id, 'top left', true)),
forMonitors((id) => Corner(id, 'top right', true)),
forMonitors((id) => Corner(id, 'bottom left', true)),
forMonitors((id) => Corner(id, 'bottom right', true)),
] : []),
...(userOptions.appearance.barRoundCorners ? [
forMonitors(BarCornerTopleft),
forMonitors(BarCornerTopright),
] : []),
];
const CLOSE_ANIM_TIME = 210; // Longer than actual anim time to make sure widgets animate fully
const closeWindowDelays = {}; // For animations
for (let i = 0; i < (Gdk.Display.get_default()?.get_n_monitors() || 1); i++) {
closeWindowDelays[`osk${i}`] = CLOSE_ANIM_TIME;
}
App.config({
css: `${COMPILED_STYLE_DIR}/style.css`,
stackTraceOnError: true,
closeWindowDelay: closeWindowDelays,
windows: Windows().flat(1),
});
// Stuff that don't need to be toggled. And they're async so ugh...
forMonitorsAsync(Bar);
// Bar().catch(print); // Use this to debug the bar. Single monitor only.
-24
View File
@@ -1,24 +0,0 @@
// Want only the overview from my config? this is what you're looking for!
// Remember to install: `dart-sass`, `ags`, `material-symbols`, and `xorg-xrandr`
// To launch this, run the following
// ags -c ~/.config/ags/config_overviewOnly.js
// To toggle the overview, run:
// ags -t overview
// You might wanna add that as a keybind (in hyprland.conf)
// bind = Super, Tab, exec, ags -t overview
// Import
import App from 'resource:///com/github/Aylur/ags/app.js'
// Widgets
import Overview from './modules/overview/main.js';
import { COMPILED_STYLE_DIR } from './init.js';
handleStyles(true);
App.config({
css: `${COMPILED_STYLE_DIR}/style.css`,
stackTraceOnError: true,
windows: [
Overview(),
],
});
-55
View File
@@ -1,55 +0,0 @@
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
import configOptions from "../modules/.configuration/user_options.js";
const { langCode, Extra_logs } = configOptions.i18n
const translations = {};
let currentLanguage = langCode || getLanguageCode();
function getLanguageCode() {
let langEnv = GLib.getenv('LANG') || GLib.getenv('LANGUAGE') || 'Default.';
let langCode = langEnv.split('.')[0];
return langCode;
}
// Load language file
function loadLanguage(lang) {
if (!translations[lang]) {
try {
let filePath = `~/.config/ags/i18n/locales/${lang}.json`;
filePath = filePath.replace(/^~/, GLib.get_home_dir());
let file = Gio.File.new_for_path(filePath);
let [success, contents] = file.load_contents(null);
if (success) {
let decoder = new TextDecoder('utf-8');
let jsonString = decoder.decode(contents);
translations[lang] = JSON.parse(jsonString);
}
} catch (error) {
if (Extra_logs || lang === "Default")
console.warn(`Failed to load language file, language code: ${lang}:\n`, error);
return;
}
}
currentLanguage = currentLanguage || lang;
}
// Initialize default language
function init() {
try {
loadLanguage(currentLanguage);
if (Extra_logs)
console.log(getString("Initialization complete!") || "Initialization complete!");
loadLanguage("Default");
} catch (error) {
console.error('Failed to initialize default language:', error);
}
}
// Get translation, if no corresponding value, return the key
function getString(key) {
if (key && !translations[currentLanguage]?.[key] && Extra_logs)
console.warn(`${translations[currentLanguage]["Not found"] || "Not found"}:::${key}`);
return translations[currentLanguage]?.[key] || translations['Default']?.[key] || key;
}
export { getString, init };
-250
View File
@@ -1,250 +0,0 @@
{
"No media": "No media",
"Powered by Google": "Powered by Google",
"Not affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\nbut will be read by human reviewers to improve the model.": "Not affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\nbut will be read by human reviewers to improve the model.",
"Precise": "Precise",
"Balanced": "Balanced",
"Creative": "Creative",
"Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1",
"Enhancements": "Enhancements",
"Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points",
"Safety": "Safety",
"When turned off, tells the API (not the model) \nto not block harmful/explicit content": "When turned off, tells the API (not the model) \nto not block harmful/explicit content",
"History": "History",
"Saves chat history\nMessages in previous chats won't show automatically, but they are there": "Saves chat history\nMessages in previous chats won't show automatically, but they are there",
"Key stored in:": "Key stored in:",
"To update this key, type": "To update this key, type",
"Updated API Key at": "Updated API Key at",
"Currently using": "Currently using",
"Select ChatGPT-compatible API provider": "Select ChatGPT-compatible API provider",
"Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.",
"Official Ollama API.\nPricing: Free.": "Official Ollama API.\nPricing: Free.",
"A unified interface for LLMs": "A unified interface for LLMs",
"An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key",
"An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key",
"Provider shown above": "Provider shown above",
"Chat with models compatible with OpenAI's Chat Completions API.\nNot affiliated, endorsed, or sponsored by any of the providers.": "Chat with models compatible with OpenAI's Chat Completions API.\nNot affiliated, endorsed, or sponsored by any of the providers.",
"The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1",
"An API key is required\nYou can grab one <u>here</u>, then enter it below": "An API key is required\nYou can grab one <u>here</u>, then enter it below",
"Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points",
"Powered by waifu.im + other APIs": "Powered by waifu.im + other APIs",
"Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.",
"Tags →": "Tags →",
"Invalid command.": "Invalid command.",
"Anime booru": "Anime booru",
"Powered by yande.re and konachan": "Powered by yande.re and konachan",
"An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.",
"Lewds": "Lewds",
"Shows naughty stuff when enabled": "Shows naughty stuff when enabled",
"Saves images in folders by their tags": "Saves images in folders by their tags",
"Message Gemini...": "Message Gemini...",
"Enter Google AI API Key...": "Enter Google AI API Key...",
"Message the model...": "Message the model...",
"Enter API Key...": "Enter API Key...",
"Enter tags": "Enter tags",
"Enter tags and/or page number": "Enter tags and/or page number",
"No tag in mind? Type a page number": "No tag in mind? Type a page number",
"Quick scripts": "Quick scripts",
"Change screen resolution": "Change screen resolution",
"Update packages": "Update packages",
"Trim system generations to 5": "Trim system generations to 5",
"Trim home manager generations to 5": "Trim home manager generations to 5",
"Remove orphan packages": "Remove orphan packages",
"Uninstall unused flatpak packages": "Uninstall unused flatpak packages",
"<span strikethrough=\"true\">Inaccurate</span> Color picker": "<span strikethrough=\"true\">Inaccurate</span> Color picker",
"Result": "Result",
"Type to search": "Type to search",
"illogical-impulse": "illogical-impulse",
"RAM Usage": "RAM Usage",
"Swap Usage": "Swap Usage",
"CPU Usage": "CPU Usage",
"Uptime:": "Uptime:",
"Screen snip": "Screen snip",
"Color picker": "Color picker",
"Toggle on-screen keyboard": "Toggle on-screen keyboard",
"Night Light": "Night Light",
"Color inversion": "Color inversion",
"Keep system awake": "Keep system awake",
"Cloudflare WARP": "Cloudflare WARP",
"Session": "Session",
"Bluetooth | Right-click to configure": "Bluetooth | Right-click to configure",
"Wifi | Right-click to configure": "Wifi | Right-click to configure",
"Right-click to configure": "Right-click to configure",
"Unknown": "Unknown",
"Reload Environment config": "Reload Environment config",
"Open Settings": "Open Settings",
"Notifications": "Notifications",
"Audio controls": "Audio controls",
"Bluetooth": "Bluetooth",
"Wifi networks": "Wifi networks",
"Quick config": "Quick config",
"Silence": "Silence",
"Clear": "Clear",
"No notifications": "No notifications",
"notifications": "notifications",
"Close": "Close",
"Now": "Now",
"Yesterday": "Yesterday",
"No audio source": "No audio source",
"Remove device": "Remove device",
"Connected": "Connected",
"Paired": "Paired",
"More": "More",
"Selected": "Selected",
"Connecting to": "Connecting to",
"Current network": "Current network",
"Authentication": "Authentication",
"Authentication failed": "Authentication failed",
"Enter network password": "Enter network password",
"Properties": "Properties",
"Forget": "Forget",
"Effects": "Effects",
"Transparency": "Transparency",
"[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this",
"Blur": "Blur",
"[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.",
"X-ray": "X-ray",
"[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ",
"Size": "Size",
"[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread",
"Passes": "Passes",
"[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.",
"Animations": "Animations",
"[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\nEnable animations",
"Choreography delay": "Choreography delay",
"In milliseconds, the delay between animations of a series": "In milliseconds, the delay between animations of a series",
"Developer": "Developer",
"Show FPS": "Show FPS",
"[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\nShow FPS overlay on top-left corner",
"Log to stdout": "Log to stdout",
"[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console",
"Damage tracking": "Damage tracking",
"[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work",
"Damage blink": "Damage blink",
"[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [Epilepsy warning!]\nShow screen damage flashes",
"Not all changes are saved": "Not all changes are saved",
"Mo": "Mo",
"Tu": "Tu",
"We": "We",
"Th": "Th",
"Fr": "Fr",
"Sa": "Sa",
"Su": "Su",
"Calendar": "Calendar",
"To Do": "To Do",
"Unfinished": "Unfinished",
"Done": "Done",
"Finished tasks will go here": "Finished tasks will go here",
"Nothing here!": "Nothing here!",
"+ New task": "+ New task",
"Add a task...": "Add a task...",
"Collapse calendar": "Collapse calendar",
"Expand calendar": "Expand calendar",
"To do tasks": "To do tasks",
"Color scheme": "Color scheme",
"Options": "Options",
"Dark Mode": "Dark Mode",
"Ya should go to sleep!": "Ya should go to sleep!",
"Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)",
"Scheme styles": "Scheme styles",
"Vibrant": "Vibrant",
"Vibrant+": "Vibrant+",
"Expressive": "Expressive",
"Monochrome": "Monochrome",
"Rainbow": "Rainbow",
"Fidelity": "Fidelity",
"Fruit Salad": "Fruit Salad",
"Tonal Spot": "Tonal Spot",
"Content": "Content",
"Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "Use arrow keys to navigate.\nEnter to select, Esc to cancel.",
"Lock": "Lock",
"Logout": "Logout",
"Sleep": "Sleep",
"Hibernate": "Hibernate",
"Shutdown": "Shutdown",
"Reboot": "Reboot",
"Cancel": "Cancel",
"Cheat sheet": "Cheat sheet",
"Keybinds": "Keybinds",
"Periodic table": "Periodic table",
"Essentials for beginners": "Essentials for beginners",
"Make shell elements transparent": "Make shell elements transparent",
"Actions": "Actions",
"Window management": "Window management",
"Window arrangement": "Window arrangement",
"Workspace management": "Workspace management",
"Workspace navigation": "Workspace navigation",
"Widgets": "Widgets",
"Media": "Media",
"Apps": "Apps",
"Neutral": "Neutral",
"Launch foot (terminal)": "Launch foot (terminal)",
"Open app launcher": "Open app launcher",
"Change wallpaper": "Change wallpaper",
"Clipboard history >> clipboard": "Clipboard history >> clipboard",
"Pick emoji >> clipboard": "Pick emoji >> clipboard",
"Screen snip >> edit": "Screen snip >> edit",
"Screen snip to text >> clipboard": "Screen snip to text >> clipboard",
"Pick color (Hex) >> clipboard": "Pick color (Hex) >> clipboard",
"Screenshot >> clipboard": "Screenshot >> clipboard",
"Screenshot >> clipboard & file": "Screenshot >> clipboard & file",
"Record region (no sound)": "Record region (no sound)",
"Record screen (with sound)": "Record screen (with sound)",
"Suspend system": "Suspend system",
"Move focus in direction": "Move focus in direction",
"Move window": "Move window",
"Resize window": "Resize window",
"Close window": "Close window",
"Pick and kill a window": "Pick and kill a window",
"Window: move in direction": "Window: move in direction",
"Window: split ratio +/- 0.1": "Window: split ratio +/- 0.1",
"Float/unfloat window": "Float/unfloat window",
"Toggle fake fullscreen": "Toggle fake fullscreen",
"Toggle fullscreen": "Toggle fullscreen",
"Toggle maximization": "Toggle maximization",
"Focus workspace # (1, 2, 3, 4, ...)": "Focus workspace # (1, 2, 3, 4, ...)",
"Workspace: focus left/right": "Workspace: focus left/right",
"Workspace: toggle special": "Workspace: toggle special",
"Window: move to workspace # (1, 2, 3, 4, ...)": "Window: move to workspace # (1, 2, 3, 4, ...)",
"Window: move to workspace left/right": "Window: move to workspace left/right",
"Window: move to workspace special": "Window: move to workspace special",
"Window: pin (show on all workspaces)": "Window: pin (show on all workspaces)",
"Restart widgets": "Restart widgets",
"Cycle bar mode (normal, focus)": "Cycle bar mode (normal, focus)",
"Toggle overview/launcher": "Toggle overview/launcher",
"Show cheatsheet": "Show cheatsheet",
"Toggle left sidebar": "Toggle left sidebar",
"Toggle right sidebar": "Toggle right sidebar",
"Toggle music controls": "Toggle music controls",
"View color scheme and options": "View color scheme and options",
"Toggle power menu": "Toggle power menu",
"Toggle crosshair": "Toggle crosshair",
"Next track": "Next track",
"Previous track": "Previous track",
"Play/pause media": "Play/pause media",
"Launch Zed (editor)": "Launch Zed (editor)",
"Launch VSCode (editor)": "Launch VSCode (editor)",
"Launch Nautilus (file manager)": "Launch Nautilus (file manager)",
"Launch Firefox (browser)": "Launch Firefox (browser)",
"Launch GNOME Text Editor": "Launch GNOME Text Editor",
"Launch WPS Office": "Launch WPS Office",
"Launch GNOME Settings": "Launch GNOME Settings",
"Launch pavucontrol (volume mixer)": "Launch pavucontrol (volume mixer)",
"Launch EasyEffects (equalizer & other audio effects)": "Launch EasyEffects (equalizer & other audio effects)",
"Launch GNOME System monitor": "Launch GNOME System monitor",
"Toggle fallback launcher: anyrun": "Toggle fallback launcher: anyrun",
"Toggle fallback launcher: fuzzel": "Toggle fallback launcher: fuzzel",
"Initialization complete!": "Initialization complete!",
"Not found": "Not found:",
"Calling API": "Calling API",
"Downloading image": "Downloading image",
"Finished!": "Finished!",
"Error": "Error",
"Not found!": "Not found!",
"Go to file url": "Go to file url",
"Save image": "Save image",
"Hoard": "Hoard",
"Open externally": "Open externally",
"You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “Im not sure.”. \nThanks!": "You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “Im not sure.”. \nThanks!",
"Feels like": "Feels like"
}
-238
View File
@@ -1,238 +0,0 @@
{
"No media": "بدون رسانه",
"Powered by Google": "قدرت گرفته از گوگل",
"Not affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\nbut will be read by human reviewers to improve the model.": "بدون وابستگی تأیید شده یا حمایت شده توسط گوگل.\n\nحریم خصوصی: پیام‌های گفتگو به حساب شما مرتبط نیستند،\nاما توسط بازبینی‌کنندگان انسانی برای بهبود مدل خوانده خواهند شد.",
"Precise": "دقیق",
"Balanced": "متعادل",
"Creative": "خلاق",
"Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "مقدار دما در Gemini.\n دقیق = 0\n متعادل = 0.5\n خلاق = 1",
"Enhancements": "بهبودها",
"Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "به Gemini می‌گوید:\n- این یک دستیار نوار کناری لینوکس است\n- مختصر باشید و از فهرست کردن کمک بگیرید",
"Safety": "ایمنی",
"When turned off, tells the API (not the model) \nto not block harmful/explicit content": "زمانی که خاموش باشد، به API (نه مدل) می‌گوید که \nمحتوای مضر/صریح را مسدود نکند",
"History": "پیشینه",
"Saves chat history\nMessages in previous chats won't show automatically, but they are there": "پیشینه گفتگو را نگه‌داری می‌کند\nپیام‌های گفتگو‌های پیشین به‌طور خودکار نمایش داده نمی‌شوند، اما وجود دارند",
"Key stored in:": "کلید نگه‌داری شده در:",
"To update this key, type": "برای به‌روزرسانی این کلید، بنویسید",
"Updated API Key at": "کلید API به‌روزرسانی شده در",
"Currently using": "هم‌اینک بکار گرفته میشود",
"Select ChatGPT-compatible API provider": "انتخاب ارائه‌دهنده API سازگار با ChatGPT",
"Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "API رسمی OpenAI.\nقیمت‌گذاری: رایگان برای اولین 5 دلار یا 3 ماه، هر کدام که کمتر باشد.",
"Official Ollama API.\nPricing: Free.": "API رسمی Ollama.\nقیمت‌گذاری: رایگان.",
"A unified interface for LLMs": "یک رابط یکپارچه برای LLMها",
"An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "API از Tornado Softwares\nقیمت‌گذاری: رایگان: 100 در روز\nنیاز به پیوستن به دیسکورد آنها برای دریافت کلید دارد",
"An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "API از @zukixa در گیت‌هاب.\nتوجه: کلیدها قفل IP هستند بنابراین گاهی اوقات باگ دارند\nقیمت‌گذاری: رایگان: 10 در دقیقه، 800 در روز.\nنیاز به پیوستن به دیسکورد آنها برای دریافت کلید دارد",
"Provider shown above": "ارائه‌دهنده در بالا نشان داده شده است",
"The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "مقدار دما در مدل.\n دقیق = 0\n متعادل = 0.5\n خلاق = 1",
"An API key is required\nYou can grab one <u>here</u>, then enter it below": "یک کلید API مورد نیاز است\nشما می‌توانید یکی را <u>اینجا</u> بگیرید، سپس آن را پایین وارد کنید",
"Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "به مدل می‌گوید:\n- این یک دستیار نوار کناری لینوکس است\n- گزافه‌گو نباشید و نقاط فهرست بکار ببرید",
"Powered by waifu.im + other APIs": "قدرت گرفته از waifu.im + سایر APIها",
"Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "برچسب‌ها را برای یک تصویر تصادفی بنویسید.\nمحتوای NSFW بازگردانده نخواهد شد مگر اینکه\nشما به‌طور صریح چنین برچسبی را درخواست کنید.\n\nتوجه: بدون وابستگی ارائه‌دهندگان\nو مسئول هیچ‌یک از محتوای آنها نیست.",
"Tags →": "برچسب‌ها →",
"Invalid command.": "دستور نامعتبر.",
"Anime booru": "انیمه بورو",
"Powered by yande.re and konachan": "قدرت گرفته از yande.re و konachan",
"An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "یک تصویر بورو. ممکن است محتوای NSFW داشته باشد.\nمواظب باشید.\n\nتوجه: بدون وابستگی به ارائه‌دهنده\nو مسئول هیچ‌یک از محتوای آن نیست.",
"Lewds": "محتوای نامناسب",
"Shows naughty stuff when enabled": "محتوای نامناسب را زمانی که فعال باشد نشان می‌دهد",
"Saves images in folders by their tags": "تصاویر را در پوشه‌ها بر اساس برچسب‌هایشان نگه‌داری می‌کند",
"Message Gemini...": "پیام به Gemini...",
"Enter Google AI API Key...": "کلید API گوگل AI را وارد کنید...",
"Message the model...": "پیام به مدل...",
"Enter API Key...": "کلید API را وارد کنید...",
"Enter tags": "برچسب‌ها را وارد کنید",
"Quick scripts": "اسکریپت‌های سریع",
"Change screen resolution": "تغییر وضوح صفحه",
"Update packages": "به‌روزرسانی بسته‌ها",
"Trim system generations to 5": "تعداد نسل‌های سامانه را به 5 کاهش دهید",
"Trim home manager generations to 5": "تعداد نسل‌های مدیر خانه را به 5 کاهش دهید",
"Remove orphan packages": "بسته‌های ناکارآمد را پاک کنید",
"Uninstall unused flatpak packages": "بسته‌های فلت‌پک بکار گرفته نشده را پاک کنید",
"<span strikethrough=\"true\">Inaccurate</span> Color picker": "<span strikethrough=\"true\">نادرست</span> انتخاب‌گر رنگ",
"Result": "نتیجه",
"Type to search": "برای جستجو بنویسید",
"illogical-impulse": "illogical-impulse",
"RAM Usage": "کارکرد RAM",
"Swap Usage": "کارکرد Swap",
"CPU Usage": "کارکرد CPU",
"Uptime:": "در حال کار:",
"Screen snip": "برش صفحه",
"Color picker": "انتخاب‌گر رنگ",
"Toggle on-screen keyboard": "کیبورد روی صفحه را فعال/غیرفعال کنید",
"Night Light": "نور شب",
"Color inversion": "وارونگی رنگ",
"Keep system awake": "سامانه را بیدار نگه‌دارید",
"Cloudflare WARP": "Cloudflare WARP",
"Session": "نشست",
"Bluetooth | Right-click to configure": "بلوتوث | برای پیکربندی راست کلیک کنید ",
"Wifi | Right-click to configure": "وای‌فای | برای پیکربندی راست کلیک کنید ",
"Right-click to configure": "برای پیکربندی راست کلیک کنید",
"Unknown": "ناشناخته",
"Reload Environment config": "پیکربندی محیط را دوباره بارگذاری کنید",
"Open Settings": "تنظیمات را باز کنید",
"Notifications": "آگاه‌سازها",
"Audio controls": "کنترل‌های صدا",
"Bluetooth": "بلوتوث",
"Wifi networks": "شبکه‌های وای‌فای",
"Quick config": "پیکربندی زنده",
"Silence": "سکوت",
"Clear": "پاک کردن",
"No notifications": "بدون آگاه‌ساز",
"notifications": "آگاه‌سازها",
"Close": "بستن",
"Now": "اینک",
"Yesterday": "دیروز",
"No audio source": "هیچ منبع صوتی",
"Remove device": "پاک‌کردن دستگاه",
"Connected": "متصل",
"Paired": "جفت شده",
"More": "بیشتر",
"Selected": "انتخاب شده",
"Current network": "شبکه کنونی",
"Authentication": "احراز هویت",
"Effects": "جلوه‌ها",
"Transparency": "شفافیت",
"[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\nعناصر شل را شفاف کنید\nهمچنین اگر این را فعال کنید، تاری نیز توصیه می‌شود",
"Blur": "تاری",
"[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\nفعال کردن تاری بر روی عناصر شفاف\nبر عملکرد/مصرف برق تأثیر نمی‌گذارد مگر اینکه پنجره‌های شفاف داشته باشید.",
"X-ray": "اشعه ایکس",
"[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\nهمه چیز را پشت یک پنجره/لایه به جز پس‌زمینه بر روی سطح تاری آن رندر نکنید\nتوصیه می‌شود برای بهبود عملکرد (اگر از شفافیت/تاری سوءاستفاده نکنید)",
"Size": "اندازه",
"[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\nشعاع تاری را تنظیم کنید. به طور کلی بر عملکرد تأثیر نمی‌گذارد\nبیشتر = پخش رنگ بیشتر",
"Passes": "عبور",
"[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland] تعداد عبورهای الگوریتم تاری را تنظیم کنید\nعبورهای بیشتر = پخش بیشتر و مصرف برق بیشتر\n4 توصیه می‌شود\n2- عجیب به نظر می‌رسد و 6+ بی‌مزه خواهد بود.",
"Animations": "پویانمایی‌ها",
"[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\nفعال کردن پویانمایی‌ها",
"Choreography delay": "درنگ در پویایی",
"In milliseconds, the delay between animations of a series": "به میلی‌ثانیه، درنگ بین پویانمایی‌های یک سری",
"Developer": "توسعه‌دهنده",
"Show FPS": "نمایش FPS",
"[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\nنمایش پوشش FPS در گوشه بالا سمت چپ",
"Log to stdout": "ثبت در stdout",
"[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\nپیام‌های LOG، ERR، WARN و دیگر را به کنسول چاپ کنید",
"Damage tracking": "ردیابی آسیب",
"[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\nفعال کردن ردیابی آسیب\nبه طور کلی، آن را روشن بگذارید.\nفقط زمانی که یک سایه‌زن(شیدر) کار نمی‌کند، خاموش کنید",
"Damage blink": "چشمک آسیب",
"[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [هشدار صرع!]\nنمایش چشمک‌های آسیب صفحه",
"Not all changes are saved": "همه تغییرات نگه‌داری نشده‌اند",
"Mo": "دو",
"Tu": "سه",
"We": "چهار",
"Th": "پنج",
"Fr": "جمعه",
"Sa": "شنبه",
"Su": "یک",
"Calendar": "تقویم",
"To Do": "کارها",
"Unfinished": "مانده",
"Done": "پایان یافته",
"Finished tasks will go here": "کارهای پایان یافته اینجا خواهند بود",
"Nothing here!": "هیچ چیز اینجا نیست!",
"+ New task": "+ کار جدید",
"Add a task...": "افزودن یک کار...",
"Color scheme": "طرح رنگ",
"Options": "گزینه‌ها",
"Dark Mode": "حالت تاریک",
"Ya should go to sleep!": "پاشو برو بخواب!",
"Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "برنامه‌های GTK را با بکارگیری رنگ تأکید پوسته گذاری کنید\n(معایب: تغییر حالت تاریک/روشن نیاز به باز راه‌اندازی دارد)",
"Scheme styles": "سبک‌های طرح",
"Vibrant": "زنده",
"Vibrant+": "زنده+",
"Expressive": "بیانگر",
"Monochrome": "تک‌رنگ",
"Rainbow": "رنگین کمان",
"Fidelity": "وفاداری",
"Fruit Salad": "سالاد میوه",
"Tonal Spot": "نقطه تنال",
"Content": "محتوا",
"Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "برای ناوبری کلیدهای جهت‌دار را بکار ببرید.\nبرای انتخاب Enter و برای رد کردن Esc را بزنید.",
"Lock": "قفل",
"Logout": "خروج",
"Sleep": "خواب",
"Hibernate": "خواب زمستانی",
"Shutdown": "خاموش",
"Reboot": "باز راه‌اندازی",
"Cancel": "رد کردن",
"Cheat sheet": "برگه تقلب",
"Keybinds": "کلیدهای میانبر",
"Periodic table": "جدول تناوبی",
"Essentials for beginners": "اساس برای مبتدیان",
"Make shell elements transparent": "عناصر شل را شفاف کنید",
"Actions": "کنش",
"Window management": "مدیریت پنجره",
"Window arrangement": "چیدمان پنجره",
"Workspace management": "مدیریت فضای کاری",
"Workspace navigation": "ناوبری فضای کاری",
"Widgets": "ابزارک‌ها",
"Media": "رسانه",
"Apps": "برنامه‌ها",
"Neutral": "خنثی",
"Launch foot (terminal)": "اجرای foot (ترمینال)",
"Open app launcher": "باز کردن راه‌انداز برنامه",
"Change wallpaper": "تغییر پس‌زمینه",
"Clipboard history >> clipboard": "پیشینه کلیپ بورد >> کلیپ بورد",
"Pick emoji >> clipboard": "انتخاب ایموجی >> کلیپ بورد",
"Screen snip >> edit": "برش صفحه >> ویرایش",
"Screen snip to text >> clipboard": "برش صفحه به متن >> کلیپ بورد",
"Pick color (Hex) >> clipboard": "انتخاب رنگ (Hex) >> کلیپ بورد",
"Screenshot >> clipboard": "عکس صفحه >> کلیپ بورد",
"Screenshot >> clipboard & file": "عکس صفحه >> کلیپ بورد و فایل",
"Record region (no sound)": "ضبط منطقه (بدون صدا)",
"Record screen (with sound)": "ضبط صفحه (با صدا)",
"Suspend system": "تعلیق سامانه",
"Move focus in direction": "جابه‌جایی تمرکز در جهت",
"Move window": "جابه‌جایی پنجره",
"Resize window": "تغییر اندازه پنجره",
"Close window": "بستن پنجره",
"Pick and kill a window": "انتخاب و بستن یک پنجره",
"Window: move in direction": "پنجره: جابه‌جایی در جهت",
"Window: split ratio +/- 0.1": "پنجره: نسبت تقسیم +/- 0.1",
"Float/unfloat window": "پنجره را شناور/نا شناور کنید",
"Toggle fake fullscreen": "تغییر حالت تمام صفحه ساختگی",
"Toggle fullscreen": "تغییر حالت تمام صفحه",
"Toggle maximization": "تغییر حالت بزرگ‌نمایی",
"Focus workspace # (1, 2, 3, 4, ...)": "تمرکز بر فضای کاری # (1، 2، 3، 4، ...)",
"Workspace: focus left/right": "فضای کاری: تمرکز به چپ/راست",
"Workspace: toggle special": "فضای کاری: تغییر حالت خاص",
"Window: move to workspace # (1, 2, 3, 4, ...)": "پنجره: رفتن به فضای کاری # (1، 2، 3، 4، ...)",
"Window: move to workspace left/right": "پنجره: رفتن به فضای کاری چپ/راست",
"Window: move to workspace special": "پنجره: رفتن به فضای کاری خاص",
"Window: pin (show on all workspaces)": "پنجره: سنجاق (نمایش در همه فضاهای کاری)",
"Restart widgets": "باز راه‌اندازی ابزارک‌ها",
"Cycle bar mode (normal, focus)": "چرخش حالت نوار (عادی، تمرکز)",
"Toggle overview/launcher": "تغییر حالت نمای کلی/راه‌انداز",
"Show cheatsheet": "نمایش برگه تقلب",
"Toggle left sidebar": "تغییر حالت نوار کناری چپ",
"Toggle right sidebar": "تغییر حالت نوار کناری راست",
"Toggle music controls": "تغییر حالت کنترل‌های موسیقی",
"View color scheme and options": "مشاهده طرح رنگ و گزینه‌ها",
"Toggle power menu": "تغییر حالت فهرست قدرت",
"Toggle crosshair": "تغییر حالت نشانه‌گذاری",
"Next track": "ترانه پسین",
"Previous track": "ترانه پیشین",
"Play/pause media": "پخش/مکث رسانه",
"Launch Zed (editor)": "اجرای Zed (ویرایشگر)",
"Launch VSCode (editor)": "اجرای VSCode (ویرایشگر)",
"Launch Nautilus (file manager)": "اجرای Nautilus (مدیر فایل)",
"Launch Firefox (browser)": "اجرای Firefox (مرورگر)",
"Launch GNOME Text Editor": "اجرای ویرایشگر متن GNOME",
"Launch WPS Office": "اجرای WPS Office",
"Launch GNOME Settings": "اجرای تنظیمات GNOME",
"Launch pavucontrol (volume mixer)": "اجرای pavucontrol (میکسر صدا)",
"Launch EasyEffects (equalizer & other audio effects)": "اجرای EasyEffects (اکولایزر و سایر جلوه‌های صوتی)",
"Launch GNOME System monitor": "اجرای مانیتور سامانه GNOME",
"Toggle fallback launcher: anyrun": "بکارگیری راه‌انداز پشتیبان: anyrun",
"Toggle fallback launcher: fuzzel": "بکارگیری راه‌انداز پشتیبان: fuzzel",
"Initialization complete!": "راه‌اندازی کامل شد!",
"Not found": "یافت نشد:",
"Calling API": "در حال تماس با API",
"Downloading image": "در حال دریافت تصویر",
"Finished!": "پایان یافت!",
"Error": "خطا",
"Not found!": "یافت نشد!",
"Go to file url": "رفتن به URL فایل",
"Save image": "نگه‌داری تصویر",
"Hoard": "نگه‌داری",
"Open externally": "باز کردن در",
"You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “Im not sure.”. \nThanks!": "You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “Im not sure.”. \nIf user talks to you in Persian and you can also respond in Persian, definitely respond in Persian. Thanks!"
}
-240
View File
@@ -1,240 +0,0 @@
{
"No media": "Aucun média",
"Powered by Google": "Fourni par Google",
"Not affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\nbut will be read by human reviewers to improve the model.": "Non affilié, approuvé ou sponsorisé par Google.\n\nConfidentialité : Les messages de chat ne sont pas liés à votre compte,\nmais seront lus par des examinateurs humains pour améliorer le modèle.",
"Precise": "Précis",
"Balanced": "Équilibré",
"Creative": "Créatif",
"Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Température de Gemini.\n Précis = 0\n Équilibré = 0.5\n Créatif = 1",
"Enhancements": "Améliorations",
"Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Indique à Gemini :\n- C'est un assistant de panneau latéral pour Linux\n- Sois concis et utilise des puces",
"Safety": "Sécurité",
"When turned off, tells the API (not the model) \nto not block harmful/explicit content": "Quand désactivé, indique à l'API (et non au modèle)\nde ne pas bloquer le contenu nuisible/explicite",
"History": "Historique",
"Saves chat history\nMessages in previous chats won't show automatically, but they are there": "Sauvegarde l'historique des discussions\nLes messages des conversations précédentes ne s'affichent pas automatiquement, mais ils existent",
"Key stored in:": "Clé stockée dans :",
"To update this key, type": "Pour mettre à jour cette clé, tapez",
"Updated API Key at": "Clé API mise à jour le",
"Currently using": "Actuellement utilisé",
"Select ChatGPT-compatible API provider": "Sélectionnez un fournisseur d'API compatible ChatGPT",
"Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "API officielle d'OpenAI.\nTarification : Gratuit pour les premiers 5 $ ou 3 mois, selon le moindre des deux.",
"Official Ollama API.\nPricing: Free.": "API officielle d'Ollama.\nTarification : Gratuit.",
"A unified interface for LLMs": "Une interface unifiée pour les LLM",
"An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "Une API de Tornado Softwares\nTarification : Gratuit : 100 par jour\nNécessite de rejoindre leur Discord pour obtenir une clé",
"An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "Une API de @zukixa sur GitHub.\nNote : Les clés sont verrouillées par IP, ce qui peut provoquer des bugs\nTarification : Gratuit : 10/min, 800/jour.\nNécessite de rejoindre leur Discord pour obtenir une clé",
"Provider shown above": "Fournisseur indiqué ci-dessus",
"The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "La valeur de température du modèle.\n Précis = 0\n Équilibré = 0.5\n Créatif = 1",
"An API key is required\nYou can grab one <u>here</u>, then enter it below": "Une clé API est requise\nVous pouvez en obtenir une <u>ici</u>, puis la saisir ci-dessous",
"Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Indique au modèle :\n- C'est un assistant de barre latérale pour Linux\n- Sois concis et utilise des puces",
"Powered by waifu.im + other APIs": "Propulsé par waifu.im + d'autres API",
"Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "Tapez des tags pour une image aléatoire.\nLe contenu NSFW ne sera pas affiché à moins que\nvous ne demandiez explicitement un tel tag.\n\nAvertissement : Pas affilié aux fournisseurs\net pas responsable de leur contenu.",
"Tags →": "Tags →",
"Invalid command.": "Commande invalide.",
"Anime booru": "Booru d'anime",
"Powered by yande.re and konachan": "Propulsé par yande.re et konachan",
"An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "Un booru d'images. Peut contenir du contenu NSFW.\nFais attention.\n\nAvertissement : Pas affilié au fournisseur\net pas responsable de son contenu.",
"Lewds": "Contenu osé",
"Shows naughty stuff when enabled": "Affiche du contenu osé lorsqu'il est activé",
"Saves images in folders by their tags": "Enregistre les images dans des dossiers selon leurs tags",
"Message Gemini...": "Envoyer un message à Gemini...",
"Enter Google AI API Key...": "Saisissez la clé API de Google AI...",
"Message the model...": "Envoyer un message au modèle...",
"Enter API Key...": "Saisissez la clé API...",
"Enter tags": "Saisissez les tags",
"Quick scripts": "Scripts rapides",
"Change screen resolution": "Changer la résolution de l'écran",
"Update packages": "Mettre à jour les paquets",
"Trim system generations to 5": "Limiter les générations système à 5",
"Trim home manager generations to 5": "Limiter les générations de home-manager à 5",
"Remove orphan packages": "Supprimer les paquets orphelins",
"Uninstall unused flatpak packages": "Désinstaller les paquets Flatpak inutilisés",
"<span strikethrough=\"true\">Inaccurate</span> Color picker": "<span strikethrough=\"true\">Inexact</span> Sélecteur de couleur",
"Result": "Résultat",
"Type to search": "Tapez pour rechercher",
"illogical-impulse": "illogical-impulse",
"RAM Usage": "Utilisation de la RAM",
"Swap Usage": "Utilisation du swap",
"CPU Usage": "Utilisation du CPU",
"Uptime:": "Temps de fonctionnement :",
"Screen snip": "Capture d'écran",
"Color picker": "Sélecteur de couleur",
"Toggle on-screen keyboard": "Activer/désactiver le clavier virtuel",
"Night Light": "Lumière nocturne",
"Color inversion": "Inversion des couleurs",
"Keep system awake": "Empêcher la mise en veille du système",
"Cloudflare WARP": "Cloudflare WARP",
"Session": "Session",
"Bluetooth | Right-click to configure": "Bluetooth | Clic droit pour configurer",
"Wifi | Right-click to configure": "Wifi | Clic droit pour configurer",
"Right-click to configure": "Clic droit pour configurer",
"Unknown": "Inconnu",
"Reload Environment config": "Recharger la configuration de l'environnement",
"Open Settings": "Ouvrir les paramètres",
"Notifications": "Notifications",
"Audio controls": "Contrôles audio",
"Bluetooth": "Bluetooth",
"Wifi networks": "Réseaux Wifi",
"Quick config": "Configuration",
"Silence": "Silence",
"Clear": "Effacer",
"No notifications": "Aucune notification",
"notifications": "notifications",
"Close": "Fermer",
"Now": "Maintenant",
"Yesterday": "Hier",
"No audio source": "Aucune source audio",
"Remove device": "Retirer l'appareil",
"Connected": "Connecté",
"Paired": "Appairé",
"More": "Plus",
"Selected": "Sélectionné",
"Current network": "Réseau actuel",
"Authentication": "Authentification",
"Effects": "Effets",
"Transparency": "Transparence",
"[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\nRendre les éléments de l'interface transparents\nLe flou est également recommandé si vous l'activez.\nChoisissez un fond d'écran avant d'activer cette option.",
"Blur": "Flou",
"[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\nActiver le flou sur les éléments transparents\nN'affecte pas les performances ou la consommation d'énergie, sauf en cas de fenêtres transparentes.",
"X-ray": "Rayon X",
"[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\nNe pas afficher ce qui se trouve derrière une fenêtre ou une couche (sauf le fond d'écran) sur sa surface floue\nRecommandé pour améliorer les performances (si vous n'abusez pas de la transparence/flou) ",
"Size": "Taille",
"[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\nAjustez le rayon du flou. En général, cela n'affecte pas les performances\nPlus le rayon est grand, plus la diffusion des couleurs est importante",
"Passes": "Passes",
"[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland] Ajustez le nombre d'exécutions de l'algorithme de flou\nPlus il y a de passes, plus la diffusion et la consommation d'énergie augmentent\n4 est recommandé\n2 ou moins paraîtraient étranges et 6 ou plus sembleraient médiocres.",
"Animations": "Animations",
"[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\nActiver les animations",
"Choreography delay": "Délai de chorégraphie",
"In milliseconds, the delay between animations of a series": "En millisecondes, le délai entre les animations d'une série",
"Developer": "Développeur",
"Show FPS": "Afficher les FPS",
"[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\nAfficher une superposition FPS en haut à gauche",
"Log to stdout": "Journaliser vers stdout",
"[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\nAfficher les messages LOG, ERR, WARN, etc. dans la console",
"Damage tracking": "Suivi des dégâts",
"[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\nActiver le suivi des dégâts\nEn général, laissez-le activé.\nDésactivez-le uniquement si un shader ne fonctionne pas",
"Damage blink": "Clignotement des dégâts",
"[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [Avertissement épilepsie !]\nAfficher des flashs lors des modifications de l'écran",
"Not all changes are saved": "Tous les changements ne sont pas enregistrés",
"Mo": "Lu",
"Tu": "Ma",
"We": "Me",
"Th": "Je",
"Fr": "Ve",
"Sa": "Sa",
"Su": "Di",
"Calendar": "Calendrier",
"To Do": "À faire",
"Unfinished": "Non terminé",
"Done": "Terminé",
"Finished tasks will go here": "Les tâches terminées apparaîtront ici",
"Nothing here!": "Rien ici !",
"+ New task": "+ Nouvelle tâche",
"Add a task...": "Ajouter une tâche...",
"Color scheme": "Schéma de couleurs",
"Options": "Options",
"Dark Mode": "Mode sombre",
"Ya should go to sleep!": "Tu devrais aller dormir !",
"Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "Thématiser les applications GTK avec la couleur d'accent\n(inconvénient : le changement de mode sombre/clair nécessite un redémarrage)",
"Scheme styles": "Styles de schéma",
"Vibrant": "Vibrant",
"Vibrant+": "Vibrant+",
"Expressive": "Expressif",
"Monochrome": "Monochrome",
"Rainbow": "Arc-en-ciel",
"Fidelity": "Fidélité",
"Fruit Salad": "Salade de fruits",
"Tonal Spot": "Tonal Spot",
"Content": "Contenu",
"Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "Utilise les flèches pour naviguer.\nEntrée pour sélectionner, Échap pour annuler.",
"Lock": "Verrouiller",
"Logout": "Se déconnecter",
"Sleep": "Mettre en veille",
"Hibernate": "Hibernation",
"Shutdown": "Éteindre",
"Reboot": "Redémarrer",
"Cancel": "Annuler",
"Cheat sheet": "Aide-mémoire",
"Keybinds": "Raccourcis clavier",
"Periodic table": "Tableau périodique",
"Essentials for beginners": "Notions essentielles pour débutants",
"Make shell elements transparent": "Rendre les éléments de l'interface transparents",
"Actions": "Actions",
"Window management": "Gestion des fenêtres",
"Window arrangement": "Disposition des fenêtres",
"Workspace management": "Gestion des espaces de travail",
"Workspace navigation": "Navigation entre espaces de travail",
"Widgets": "Widgets",
"Media": "Médias",
"Apps": "Applications",
"Neutral": "Neutre",
"Launch foot (terminal)": "Lancer foot (terminal)",
"Open app launcher": "Ouvrir le lanceur d'applications",
"Change wallpaper": "Changer le fond d'écran",
"Clipboard history >> clipboard": "Historique du presse-papiers >> presse-papiers",
"Pick emoji >> clipboard": "Choisir un emoji >> presse-papiers",
"Screen snip >> edit": "Capture d'écran >> éditer",
"Screen snip to text >> clipboard": "Capture d'écran en texte >> presse-papiers",
"Pick color (Hex) >> clipboard": "Choisir une couleur (Hex) >> presse-papiers",
"Screenshot >> clipboard": "Capture d'écran >> presse-papiers",
"Screenshot >> clipboard & file": "Capture d'écran >> presse-papiers & fichier",
"Record region (no sound)": "Enregistrer une région (sans son)",
"Record screen (with sound)": "Enregistrer l'écran (avec son)",
"Suspend system": "Suspendre le système",
"Move focus in direction": "Déplacer le focus dans la direction",
"Move window": "Déplacer la fenêtre",
"Resize window": "Redimensionner la fenêtre",
"Close window": "Fermer la fenêtre",
"Pick and kill a window": "Sélectionner et fermer une fenêtre",
"Window: move in direction": "Fenêtre : déplacer dans la direction",
"Window: split ratio +/- 0.1": "Fenêtre : ajuster le ratio de partage +/- 0.1",
"Float/unfloat window": "Basculer la fenêtre en mode flottant/non flottant",
"Toggle fake fullscreen": "Basculer en faux plein écran",
"Toggle fullscreen": "Basculer le plein écran",
"Toggle maximization": "Basculer la maximisation",
"Focus workspace # (1, 2, 3, 4, ...)": "Sélectionner l'espace de travail n° (1, 2, 3, 4, ...)",
"Workspace: focus left/right": "Espace de travail : se déplacer à gauche/droite",
"Workspace: toggle special": "Espace de travail : basculer spécial",
"Window: move to workspace # (1, 2, 3, 4, ...)": "Fenêtre : déplacer vers l'espace de travail n° (1, 2, 3, 4, ...)",
"Window: move to workspace left/right": "Fenêtre : déplacer vers l'espace de travail à gauche/droite",
"Window: move to workspace special": "Fenêtre : déplacer vers l'espace de travail spécial",
"Window: pin (show on all workspaces)": "Fenêtre : épingler (afficher sur tous les espaces de travail)",
"Restart widgets": "Redémarrer les widgets",
"Cycle bar mode (normal, focus)": "Cycler le mode de la barre (normal, focus)",
"Toggle overview/launcher": "Basculer l'aperçu/le lanceur",
"Show cheatsheet": "Afficher l'aide-mémoire",
"Toggle left sidebar": "Basculer la barre latérale gauche",
"Toggle right sidebar": "Basculer la barre latérale droite",
"Toggle music controls": "Basculer les contrôles de musique",
"View color scheme and options": "Voir le schéma de couleurs et les options",
"Toggle power menu": "Basculer le menu d'alimentation",
"Toggle crosshair": "Basculer le viseur",
"Next track": "Piste suivante",
"Previous track": "Piste précédente",
"Play/pause media": "Lire/metre en pause le média",
"Launch Zed (editor)": "Lancer Zed (éditeur)",
"Launch VSCode (editor)": "Lancer VSCode (éditeur)",
"Launch Nautilus (file manager)": "Lancer Nautilus (gestionnaire de fichiers)",
"Launch Firefox (browser)": "Lancer Firefox (navigateur)",
"Launch GNOME Text Editor": "Lancer GNOME Text Editor",
"Launch WPS Office": "Lancer WPS Office",
"Launch GNOME Settings": "Lancer les paramètres GNOME",
"Launch pavucontrol (volume mixer)": "Lancer pavucontrol (contrôleur de volume)",
"Launch EasyEffects (equalizer & other audio effects)": "Lancer EasyEffects (égaliseur et autres effets audio)",
"Launch GNOME System monitor": "Lancer le moniteur système GNOME",
"Toggle fallback launcher: anyrun": "Basculer le lanceur de secours : anyrun",
"Toggle fallback launcher: fuzzel": "Basculer le lanceur de secours : fuzzel",
"Initialization complete!": "Initialisation terminée !",
"Not found": "Non trouvé :",
"Calling API": "Appel de l'API",
"Downloading image": "Téléchargement de l'image",
"Finished!": "Terminé !",
"Error": "Erreur",
"Not found!": "Non trouvé !",
"Go to file url": "Aller à l'URL du fichier",
"Save image": "Enregistrer l'image",
"Hoard": "Accumuler",
"Open externally": "Ouvrir avec une application externe",
"You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “I'm not sure.”. \nThanks!": "Tu es un assistant dans un panneau latéral d'un bureau Linux sous Wayland. Veilles à toujours adopter un ton décontracté lorsque tu réponds, sauf indication contraire ou lors de suggestions d'écriture. Voici les étapes à suivre pour répondre aux requêtes de l'utilisateur :\n1. S'il s'agit d'une question liée à l'écriture ou à la grammaire, ou d'une phrase entre guillemets, signales les erreurs et corriges-les si nécessaire en utilisant des soulignements, et rends l'écriture plus naturelle lorsque cela est approprié sans apporter de modifications trop importantes. Si on te fournit une phrase entre guillemets mais grammaticalement correcte, expliques brièvement des concepts peu communs.\n2. S'il s'agit d'une question concernant des tâches système, fournis une commande bash dans un bloc de code avec une brève explication.\n3. Sinon, lorsqu'on te demande de résumer des informations ou d'expliquer des concepts, utilises des puces et des titres. Pour les expressions mathématiques, tu *dois* utiliser LaTeX dans un bloc de code avec la langue définie sur \"latex\".\nNote : Utilises un langage décontracté, sois bref, tout en garantissant l'exactitude des informations de ta réponse. Si tu n'es pas sûr ou si tu ne disposes pas d'assez d'informations pour fournir une réponse convaincante, dis simplement \"Je ne sais pas\" ou \"Je ne suis pas sûr\".\nMerci !",
"Feels like": "Ressenti"
}
-238
View File
@@ -1,238 +0,0 @@
{
"No media": "Nessun media",
"Powered by Google": "Offerto da Google",
"Not affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\nbut will be read by human reviewers to improve the model.": "Non affiliato, approvato o sponsorizzato da Google.\n\nPrivacy: I messaggi della chat non sono collegati al tuo account,\n ma saranno letti da revisori umani per migliorare il modello.",
"Precise": "Preciso",
"Balanced": "Bilanciato",
"Creative": "Creativo",
"Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Valore di temperatura di Gemini.\n Preciso = 0\n Bilanciato = 0.5\n Creativo = 1",
"Enhancements": "Miglioramenti",
"Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Dice a Gemini:\n- È un assistente laterale per Linux\n- Sii breve e usa punti elenco",
"Safety": "Sicurezza",
"When turned off, tells the API (not the model) \nto not block harmful/explicit content": "Quando disattivato, dice all'API (non al modello) \n di non bloccare contenuti dannosi/espliciti",
"History": "Cronologia",
"Saves chat history\nMessages in previous chats won't show automatically, but they are there": "Salva la cronologia della chat\nI messaggi nelle chat precedenti non verranno mostrati automaticamente, ma sono lì",
"Key stored in:": "Chiave memorizzata in:",
"To update this key, type": "Per aggiornare questa chiave, digita",
"Updated API Key at": "Chiave API aggiornata alle",
"Currently using": "Attualmente in uso",
"Select ChatGPT-compatible API provider": "Seleziona un provider API compatibile con ChatGPT",
"Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "API ufficiale di OpenAI.\nPrezzi: Gratuito per i primi $5 o 3 mesi, a seconda di quale sia inferiore.",
"Official Ollama API.\nPricing: Free.": "API ufficiale di Ollama.\nPrezzi: Gratuito.",
"A unified interface for LLMs": "Un'interfaccia unificata per LLM",
"An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "Un'API di Tornado Softwares\nPrezzi: Gratuito: 100/giorno\nRichiede di unirsi al loro Discord per una chiave",
"An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "Un'API di @zukixa su GitHub.\nNota: Le chiavi sono bloccate per IP, quindi a volte è instabile\nPrezzi: Gratuito: 10/min, 800/giorno.\nRichiede di unirsi al loro Discord per una chiave",
"Provider shown above": "Provider mostrato sopra",
"The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Valore di temperatura del modello.\n Preciso = 0\n Bilanciato = 0.5\n Creativo = 1",
"An API key is required\nYou can grab one <u>here</u>, then enter it below": "È necessaria una chiave API\nPuoi ottenerne una <u>qui</u>, quindi inserirla qui sotto",
"Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Dice al modello:\n- È un assistente laterale per Linux\n- Sii breve e usa punti elenco",
"Powered by waifu.im + other APIs": "Offerto da waifu.im + altre API",
"Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "Digita i tag per un'immagine casuale.\nIl contenuto NSFW non verrà restituito a meno che\nnon richiedi esplicitamente un tale tag.\n\nDisclaimer: Non affiliato ai provider\nné responsabile per alcun loro contenuto.",
"Tags →": "Tag →",
"Invalid command.": "Comando non valido.",
"Anime booru": "Anime booru",
"Powered by yande.re and konachan": "Offerto da yande.re e konachan",
"An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "Un booru di immagini. Potrebbe contenere contenuti NSFW.\nFai attenzione.\n\nDisclaimer: Non affiliato al provider\nné responsabile per alcun suo contenuto.",
"Lewds": "Contenuti osé",
"Shows naughty stuff when enabled": "Mostra contenuti osé quando abilitato",
"Saves images in folders by their tags": "Salva le immagini in cartelle in base ai loro tag",
"Message Gemini...": "Messaggia Gemini...",
"Enter Google AI API Key...": "Inserisci la chiave API di Google AI...",
"Message the model...": "Messaggia il modello...",
"Enter API Key...": "Inserisci la chiave API...",
"Enter tags": "Inserisci i tag",
"Quick scripts": "Script rapidi",
"Change screen resolution": "Cambia risoluzione dello schermo",
"Update packages": "Aggiorna i pacchetti",
"Trim system generations to 5": "Riduci le generazioni del sistema a 5",
"Trim home manager generations to 5": "Riduci le generazioni del gestore di casa a 5",
"Remove orphan packages": "Rimuovi i pacchetti orfani",
"Uninstall unused flatpak packages": "Disinstalla i pacchetti flatpak non utilizzati",
"<span strikethrough=\"true\">Inaccurate</span> Color picker": "<span strikethrough=\"true\">Impreciso</span> Selettore di colore",
"Result": "Risultato",
"Type to search": "Digita per cercare",
"illogical-impulse": "impulso illogico",
"RAM Usage": "Utilizzo della RAM",
"Swap Usage": "Utilizzo dello Swap",
"CPU Usage": "Utilizzo della CPU",
"Uptime:": "Tempo di attività:",
"Screen snip": "Ritaglio dello schermo",
"Color picker": "Selettore di colore",
"Toggle on-screen keyboard": "Attiva/disattiva tastiera su schermo",
"Night Light": "Luce notturna",
"Color inversion": "Inversione di colore",
"Keep system awake": "Mantieni il sistema sveglio",
"Cloudflare WARP": "Cloudflare WARP",
"Session": "Sessione",
"Bluetooth | Right-click to configure": "Bluetooth | Clic destro per configurare",
"Wifi | Right-click to configure": "Wifi | Clic destro per configurare",
"Right-click to configure": "Clic destro per configurare",
"Unknown": "Sconosciuto",
"Reload Environment config": "Ricarica la configurazione dell'ambiente",
"Open Settings": "Apri Impostazioni",
"Notifications": "Notifiche",
"Audio controls": "Controlli audio",
"Bluetooth": "Bluetooth",
"Wifi networks": "Reti Wifi",
"Quick config": "Configurazione",
"Silence": "Silenzio",
"Clear": "Cancella",
"No notifications": "Nessuna notifica",
"notifications": "notifiche",
"Close": "Chiudi",
"Now": "Ora",
"Yesterday": "Ieri",
"No audio source": "Nessuna sorgente audio",
"Remove device": "Rimuovi dispositivo",
"Connected": "Connesso",
"Paired": "Abbinato",
"More": "Altro",
"Selected": "Selezionato",
"Current network": "Rete corrente",
"Authentication": "Autenticazione",
"Effects": "Effetti",
"Transparency": "Trasparenza",
"[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\nRendi trasparenti gli elementi della shell\nSi consiglia anche il blur se abiliti questa opzione",
"Blur": "Blur",
"[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\nAbilita il blur sugli elementi trasparenti\nNon influisce sulle prestazioni/consumo energetico a meno che non si abbiano finestre trasparenti.",
"X-ray": "Raggi X",
"[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\nRendi tutto dietro una finestra/livello, tranne lo sfondo, non renderizzato sulla sua superficie sfocata\nConsigliato per migliorare le prestazioni (se non abusi di trasparenza/blur) ",
"Size": "Dimensione",
"[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\nRegola il raggio del blur. Generalmente non influisce sulle prestazioni\nPiù alto = più diffusione del colore",
"Passes": "Passaggi",
"[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland] Regola il numero di esecuzioni dell'algoritmo di blur\nPiù passaggi = più diffusione e consumo energetico\nSi consigliano 4\n2- sembrerebbe strano e 6+ sembrerebbe scadente.",
"Animations": "Animazioni",
"[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\nAbilita le animazioni",
"Choreography delay": "Ritardo della coreografia",
"In milliseconds, the delay between animations of a series": "In millisecondi, il ritardo tra le animazioni di una serie",
"Developer": "Sviluppatore",
"Show FPS": "Mostra FPS",
"[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\nMostra l'overlay degli FPS nell'angolo in alto a sinistra",
"Log to stdout": "Log su stdout",
"[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\nStampa i messaggi LOG, ERR, WARN, ecc. sulla console",
"Damage tracking": "Tracciamento dei danni",
"[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\nAbilita il tracciamento dei danni\nGeneralmente, lascialo acceso.\nDisattivalo solo quando uno shader non funziona",
"Damage blink": "Lampeggio dei danni",
"[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [Avviso epilessia!]\nMostra i lampeggi dei danni dello schermo",
"Not all changes are saved": "Non tutte le modifiche sono state salvate",
"Mo": "Lu",
"Tu": "Ma",
"We": "Me",
"Th": "Gi",
"Fr": "Ve",
"Sa": "Sa",
"Su": "Do",
"Calendar": "Calendario",
"To Do": "Da fare",
"Unfinished": "Incompleto",
"Done": "Fatto",
"Finished tasks will go here": "Le attività completate andranno qui",
"Nothing here!": "Niente qui!",
"+ New task": "+ Nuova attività",
"Add a task...": "Aggiungi un'attività...",
"Color scheme": "Schema di colori",
"Options": "Opzioni",
"Dark Mode": "Modalità scura",
"Ya should go to sleep!": "Dovresti andare a dormire!",
"Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "Tema le app GTK usando il colore di accento\n(svantaggio: il passaggio tra modalità scura/chiara richiede un riavvio)",
"Scheme styles": "Stili dello schema",
"Vibrant": "Vivace",
"Vibrant+": "Vivace+",
"Expressive": "Espressivo",
"Monochrome": "Monocromatico",
"Rainbow": "Arcobaleno",
"Fidelity": "Fedeltà",
"Fruit Salad": "Macedonia di frutta",
"Tonal Spot": "Punto tonale",
"Content": "Contenuto",
"Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "Usa i tasti freccia per navigare.\nInvio per selezionare, Esc per annullare.",
"Lock": "Blocca",
"Logout": "Esci",
"Sleep": "Sospendi",
"Hibernate": "Iberna",
"Shutdown": "Spegni",
"Reboot": "Riavvia",
"Cancel": "Annulla",
"Cheat sheet": "Foglio di riferimento",
"Keybinds": "Scorciatoie da tastiera",
"Periodic table": "Tavola periodica",
"Essentials for beginners": "Essenziali per principianti",
"Make shell elements transparent": "Rendi trasparenti gli elementi della shell",
"Actions": "Azioni",
"Window management": "Gestione delle finestre",
"Window arrangement": "Disposizione delle finestre",
"Workspace management": "Gestione degli spazi di lavoro",
"Workspace navigation": "Navigazione degli spazi di lavoro",
"Widgets": "Widget",
"Media": "Media",
"Apps": "App",
"Neutral": "Neutro",
"Launch foot (terminal)": "Avvia foot (terminale)",
"Open app launcher": "Apri il launcher delle app",
"Change wallpaper": "Cambia lo sfondo",
"Clipboard history >> clipboard": "Cronologia degli appunti >> appunti",
"Pick emoji >> clipboard": "Scegli emoji >> appunti",
"Screen snip >> edit": "Ritaglio dello schermo >> modifica",
"Screen snip to text >> clipboard": "Ritaglio dello schermo in testo >> appunti",
"Pick color (Hex) >> clipboard": "Scegli colore (Hex) >> appunti",
"Screenshot >> clipboard": "Screenshot >> appunti",
"Screenshot >> clipboard & file": "Screenshot >> appunti e file",
"Record region (no sound)": "Registra regione (senza audio)",
"Record screen (with sound)": "Registra schermo (con audio)",
"Suspend system": "Sospendi il sistema",
"Move focus in direction": "Sposta il focus nella direzione",
"Move window": "Sposta la finestra",
"Resize window": "Ridimensiona la finestra",
"Close window": "Chiudi la finestra",
"Pick and kill a window": "Scegli e chiudi una finestra",
"Window: move in direction": "Finestra: sposta nella direzione",
"Window: split ratio +/- 0.1": "Finestra: rapporto di divisione +/- 0.1",
"Float/unfloat window": "Finestra libera/agganciata",
"Toggle fake fullscreen": "Attiva/disattiva falso fullscreen",
"Toggle fullscreen": "Attiva/disattiva fullscreen",
"Toggle maximization": "Attiva/disattiva massimizzazione",
"Focus workspace # (1, 2, 3, 4, ...)": "Focalizza spazio di lavoro # (1, 2, 3, 4, ...)",
"Workspace: focus left/right": "Spazio di lavoro: focalizza sinistra/destra",
"Workspace: toggle special": "Spazio di lavoro: attiva/disattiva speciale",
"Window: move to workspace # (1, 2, 3, 4, ...)": "Finestra: sposta in spazio di lavoro # (1, 2, 3, 4, ...)",
"Window: move to workspace left/right": "Finestra: sposta in spazio di lavoro sinistra/destra",
"Window: move to workspace special": "Finestra: sposta in spazio di lavoro speciale",
"Window: pin (show on all workspaces)": "Finestra: fissa (mostra su tutti gli spazi di lavoro)",
"Restart widgets": "Riavvia widget",
"Cycle bar mode (normal, focus)": "Cicla modalità barra (normale, focus)",
"Toggle overview/launcher": "Attiva/disattiva panoramica/lanciatore",
"Show cheatsheet": "Mostra cheatsheet",
"Toggle left sidebar": "Attiva/disattiva barra laterale sinistra",
"Toggle right sidebar": "Attiva/disattiva barra laterale destra",
"Toggle music controls": "Attiva/disattiva controlli musicali",
"View color scheme and options": "Visualizza schema colori e opzioni",
"Toggle power menu": "Attiva/disattiva menu di spegnimento",
"Toggle crosshair": "Attiva/disattiva mirino",
"Next track": "Traccia successiva",
"Previous track": "Traccia precedente",
"Play/pause media": "Riproduci/pausa media",
"Launch Zed (editor)": "Avvia Zed (editor)",
"Launch VSCode (editor)": "Avvia VSCode (editor)",
"Launch Nautilus (file manager)": "Avvia Nautilus (gestore file)",
"Launch Firefox (browser)": "Avvia Firefox (browser)",
"Launch GNOME Text Editor": "Avvia GNOME Text Editor",
"Launch WPS Office": "Avvia WPS Office",
"Launch GNOME Settings": "Avvia Impostazioni GNOME",
"Launch pavucontrol (volume mixer)": "Avvia pavucontrol (mixer volume)",
"Launch EasyEffects (equalizer & other audio effects)": "Avvia EasyEffects (equalizzatore & altri effetti audio)",
"Launch GNOME System monitor": "Avvia monitor di sistema GNOME",
"Toggle fallback launcher: anyrun": "Attiva/disattiva lanciatore di riserva: anyrun",
"Toggle fallback launcher: fuzzel": "Attiva/disattiva lanciatore di riserva: fuzzel",
"Initialization complete!": "Inizializzazione completata!",
"Not found": "Non trovato",
"Calling API": "Chiamata API",
"Downloading image": "Scaricamento immagine",
"Finished!": "Completato!",
"Error": "Errore",
"Not found!": "Non trovato!",
"Go to file url": "Vai all'url del file",
"Save image": "Salva immagine",
"Hoard": "Accumula",
"Open externally": "Apri esternamente",
"You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “Im not sure.”. \nThanks!": "Sei un assistente nella barra laterale di un desktop Wayland Linux. Usa sempre un tono informale quando rispondi alle domande, a meno che non venga richiesto diversamente o quando fai suggerimenti di scrittura. Ecco i passaggi che devi seguire per rispondere alle domande dell'utente:\n1. Se si tratta di una domanda sulla scrittura o sulla grammatica o di una frase tra virgolette, segnala gli errori e correggi quando necessario utilizzando sottolineature, e rendi la scrittura più naturale dove appropriato senza fare modifiche troppo importanti. Se ti viene data una frase tra virgolette ma è grammaticalmente corretta, spiega brevemente concetti che sono poco comuni.\n2. Se è una domanda su attività di sistema, fornisci un comando bash in un blocco di codice con una breve spiegazione.\n3. Altrimenti, quando ti viene chiesto di riassumere informazioni o spiegare concetti, usa punti elenco e titoli. Per espressioni matematiche, *devi* usare LaTeX all'interno di un blocco di codice con il linguaggio impostato su \"latex\". \nNota: usa un linguaggio informale, sii breve, assicurandoti della correttezza fattuale della tua risposta. Se non sei sicuro o non hai abbastanza informazioni per fornire una risposta sicura, semplicemente dici “Non lo so” o “Non sono sicuro”. \nGrazie!"
}
-239
View File
@@ -1,239 +0,0 @@
{
"No media": "无媒体活动",
"Powered by Google": "由 Google 提供技术支持",
"Not affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\nbut will be read by human reviewers to improve the model.": "不隶属于、不受 Google 赞助或支持。\n\n隐私:聊天信息不会与你的账户关联,\n但会被人类审阅者阅读,用于改进模型。",
"Precise": "精确",
"Balanced": "平衡",
"Creative": "创意",
"Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Gemini 的 temperature 值\n 精确 = 0\n 平衡 = 0.5\n 创意 = 1",
"Enhancements": "增强功能",
"Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "告诉 Gemini\n- 它是一个 Linux 侧边栏助手\n- 保持简洁并使用项目符号",
"Safety": "安全",
"When turned off, tells the API (not the model) \nto not block harmful/explicit content": "当关闭时,告诉 API(而不是模型)\n不要屏蔽有害/显露的内容",
"History": "历史",
"Saves chat history\nMessages in previous chats won't show automatically, but they are there": "保存聊天历史\n以前聊天中的消息不会自动显示,但它们仍然存在",
"Key stored in:": "密钥值储存在:",
"To update this key, type": "要更新此密钥,请输入",
"Updated API Key at": "更新了 API 密钥于",
"Currently using": "当前使用",
"Select ChatGPT-compatible API provider": "选择与 ChatGPT 兼容的 API 提供商",
"Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "官方 OpenAI API。\n定价:前 $5 或前 3 个月免费,取较小者。",
"Official Ollama API.\nPricing: Free.": "官方 Ollama API。\n定价:免费。",
"A unified interface for LLMs": "LLM 的统一接口",
"An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "来自 Tornado Softwares 的 API\n定价:免费:每天 100 次请求\n需要加入他们的 Discord 以获取密钥",
"An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "来自 GitHub 上的 @zukixa 的 API。\n注意:密钥与 IP 绑定,所以有时会出错。\n定价:免费:每分钟 10 次,每天 800 次。\n需要加入他们的 Discord 才能获得密钥。",
"Provider shown above": "上述显示的提供商",
"The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "模型的 temperature 值。\n 精确 = 0\n 平衡 = 0.5\n 创意 = 1",
"An API key is required\nYou can grab one <u>here</u>, then enter it below": "需要 API 密钥\n您可以在<u>这里</u>获取一个,然后在下面输入",
"Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "告诉模型:\n- 它是一个 Linux 侧边栏助手\n- 保持简洁并使用项目符号",
"Powered by waifu.im + other APIs": "由 waifu.im + 其他 API 提供支持",
"Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "输入标签以获取随机图片。\n除非您明确请求,否则不会返回 NSFW 内容。\n\n免责声明:与提供商无关联\n我也不对他们的任何内容负责。",
"Tags →": "标签 →",
"Invalid command.": "无效命令。",
"Anime booru": "动漫图库",
"Powered by yande.re and konachan": "由 yande.re 和 konachan 提供支持",
"An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "一个图片图库。可能包含 NSFW 内容。\n小心。\n\n免责声明:与提供商无关联\n也不对它的任何内容负责。",
"Lewds": "不雅内容",
"Shows naughty stuff when enabled": "启用时显示不雅内容",
"Saves images in folders by their tags": "按标签将图片保存到文件夹中",
"Message Gemini...": "向 Gemini 发送消息...",
"Enter Google AI API Key...": "输入 Google AI API 密钥...",
"Message the model...": "向模型发送消息...",
"Enter API Key...": "输入 API 密钥...",
"Enter tags": "输入标签",
"Quick scripts": "快速脚本",
"Change screen resolution": "更改屏幕分辨率",
"Update packages": "更新软件包",
"Trim system generations to 5": "将系统代数修剪为 5",
"Trim home manager generations to 5": "将 home manager 代数修剪为 5",
"Remove orphan packages": "移除孤立软件包",
"Uninstall unused flatpak packages": "卸载未使用的 Flatpak 软件包",
"<span strikethrough=\"true\">Inaccurate</span> Color picker": "<span strikethrough=\"true\">不准确</span> 颜色选择器",
"Result": "结果",
"Type to search": "输入以搜索",
"illogical-impulse": "illogical-impulse",
"RAM Usage": "RAM 使用情况",
"Swap Usage": "Swap 使用情况",
"CPU Usage": "CPU 使用情况",
"Uptime:": "运行时间:",
"Screen snip": "屏幕截图",
"Color picker": "颜色选择器",
"Toggle on-screen keyboard": "切换屏幕键盘",
"Night Light": "夜灯",
"Color inversion": "颜色反转",
"Keep system awake": "保持系统唤醒",
"Cloudflare WARP": "Cloudflare WARP",
"Session": "会话",
"Bluetooth | Right-click to configure": "蓝牙 | 右键单击以配置",
"Wifi | Right-click to configure": "Wi-Fi | 右键单击以配置",
"Right-click to configure": "右键单击以配置",
"Unknown": "未知",
"Reload Environment config": "重新加载环境配置",
"Open Settings": "打开设置",
"Notifications": "通知",
"Audio controls": "音频控制",
"Bluetooth": "蓝牙",
"Wifi networks": "Wi-Fi 网络",
"Quick config": "实时配置",
"Silence": "静音",
"Clear": "清除",
"No notifications": "无通知",
"notifications": "条通知",
"Close": "关闭",
"Now": "现在",
"Yesterday": "昨天",
"No audio source": "没有音频源",
"Remove device": "移除设备",
"Connected": "已连接",
"Paired": "已配对",
"More": "更多",
"Selected": "已选中",
"Current network": "当前网络",
"Authentication": "身份验证",
"Effects": "效果",
"Transparency": "透明度",
"[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\n使外壳元素透明\n如果启用此功能,也建议使用模糊效果",
"Blur": "模糊",
"[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\n在透明元素上启用模糊效果\n除非您有透明窗口,否则不会影响性能/功耗。",
"X-ray": "X-ray",
"[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\n使窗口/图层后面的所有内容(除了壁纸)在其模糊表面上不渲染\n建议提高性能(如果您不滥用透明度/模糊)",
"Size": "大小",
"[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\n调整模糊半径。通常不会影响性能\n数值越高 = 颜色扩散越大",
"Passes": "次数",
"[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland]\n调整模糊算法的运行次数\n次数越多 = 扩散越大,功耗越高\n建议使用 4 次\n2 次看起来很奇怪,6 次以上看起来很糟糕。",
"Animations": "动画",
"[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\n启用动画",
"Choreography delay": "间隔",
"In milliseconds, the delay between animations of a series": "以毫秒为单位,一系列动画之间的延迟",
"Developer": "开发者选项",
"Show FPS": "显示 FPS",
"[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\n在左上角显示 FPS 叠加层",
"Log to stdout": "输出日志",
"[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\n将 LOG、ERR、WARN 等消息打印到控制台",
"Damage tracking": "Damage tracking",
"[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\n启用 Damage tracking \n通常情况下,保持启用状态\n仅当着色器无法正常工作时才禁用",
"Damage blink": "显示视图更新",
"[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [癫痫警告!]\n屏幕视图更新时闪烁",
"Not all changes are saved": "并非所有更改都已保存",
"Mo": "一",
"Tu": "二",
"We": "三",
"Th": "四",
"Fr": "五",
"Sa": "六",
"Su": "日",
"Calendar": "日历",
"To Do": "待办",
"Unfinished": "未完成",
"Done": "已完成",
"Finished tasks will go here": "已完成的任务将显示在此处",
"Nothing here!": "这里什么也没有!",
"+ New task": "+ 新任务",
"Add a task...": "添加任务...",
"Color scheme": "配色方案",
"Options": "选项",
"Dark Mode": "深色模式",
"Ya should go to sleep!": "你应该去睡觉!",
"Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "使用强调色对 GTK 应用程序进行主题化\n(缺点:深色/浅色模式切换需要重启)",
"Scheme styles": "样式方案",
"Vibrant": "鲜艳",
"Vibrant+": "鲜艳+",
"Expressive": "表现力",
"Monochrome": "黑白",
"Rainbow": "彩虹",
"Fidelity": "保真度",
"Fruit Salad": "水果沙拉",
"Tonal Spot": "色调点",
"Content": "内容",
"Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "使用箭头键导航。\n回车键选择,Esc 键取消。",
"Lock": "锁屏",
"Logout": "注销",
"Sleep": "睡眠",
"Hibernate": "休眠",
"Shutdown": "关机",
"Reboot": "重启",
"Cancel": "取消",
"Cheat sheet": "备忘单",
"Keybinds": "按键绑定",
"Periodic table": "元素周期表",
"Essentials for beginners": "初学者必备",
"Make shell elements transparent": "使外壳元素透明",
"Actions": "操作",
"Window management": "窗口管理",
"Window arrangement": "窗口排列",
"Workspace management": "工作区管理",
"Workspace navigation": "工作区导航",
"Widgets": "小部件",
"Media": "媒体",
"Apps": "应用程序",
"Neutral": "中性",
"Launch foot (terminal)": "启动终端(foot",
"Open app launcher": "打开应用程序启动器",
"Change wallpaper": "更改壁纸",
"Clipboard history >> clipboard": "剪贴板历史 >> 剪贴板",
"Pick emoji >> clipboard": "选择表情符号 >> 剪贴板",
"Screen snip >> edit": "屏幕截图 >> 编辑",
"Screen snip to text >> clipboard": "屏幕截图转文字 >> 剪贴板",
"Pick color (Hex) >> clipboard": "选择颜色(十六进制)>> 剪贴板",
"Screenshot >> clipboard": "屏幕截图 >> 剪贴板",
"Screenshot >> clipboard & file": "屏幕截图 >> 剪贴板和文件",
"Record region (no sound)": "录制区域(无声音)",
"Record screen (with sound)": "录制屏幕(带声音)",
"Suspend system": "挂起系统",
"Move focus in direction": "在方向上移动焦点",
"Move window": "移动窗口",
"Resize window": "调整窗口大小",
"Close window": "关闭窗口",
"Pick and kill a window": "选择并关闭一个窗口",
"Window: move in direction": "窗口:在方向上移动",
"Window: split ratio +/- 0.1": "窗口:分割比例 +/- 0.1",
"Float/unfloat window": "浮动/取消浮动窗口",
"Toggle fake fullscreen": "切换伪全屏",
"Toggle fullscreen": "切换全屏",
"Toggle maximization": "切换最大化",
"Focus workspace # (1, 2, 3, 4, ...)": "聚焦工作区 #1, 2, 3, 4, ...",
"Workspace: focus left/right": "工作区:聚焦左右",
"Workspace: toggle special": "工作区:切换特殊工作区",
"Window: move to workspace # (1, 2, 3, 4, ...)": "窗口:移动到工作区 #1, 2, 3, 4, ...",
"Window: move to workspace left/right": "窗口:移动到左右工作区",
"Window: move to workspace special": "窗口:移动到特殊工作区",
"Window: pin (show on all workspaces)": "窗口:固定(在所有工作区显示)",
"Restart widgets": "重启小部件",
"Cycle bar mode (normal, focus)": "循环栏模式(正常,聚焦)",
"Toggle overview/launcher": "切换概览/启动器",
"Show cheatsheet": "显示快捷键表",
"Toggle left sidebar": "切换左侧边栏",
"Toggle right sidebar": "切换右侧边栏",
"Toggle music controls": "切换音乐控制",
"View color scheme and options": "查看配色方案和选项",
"Toggle power menu": "切换电源菜单",
"Toggle crosshair": "切换准星",
"Next track": "下一曲目",
"Previous track": "上一曲目",
"Play/pause media": "播放/暂停媒体",
"Launch Zed (editor)": "启动 Zed(编辑器)",
"Launch VSCode (editor)": "启动 VSCode(编辑器)",
"Launch Nautilus (file manager)": "启动 Nautilus(文件管理器)",
"Launch Firefox (browser)": "启动 Firefox(浏览器)",
"Launch GNOME Text Editor": "启动 GNOME 文本编辑器",
"Launch WPS Office": "启动 WPS 办公软件",
"Launch GNOME Settings": "启动 GNOME 设置",
"Launch pavucontrol (volume mixer)": "启动 pavucontrol(音量混合器)",
"Launch EasyEffects (equalizer & other audio effects)": "启动 EasyEffects(均衡器和其他音频效果)",
"Launch GNOME System monitor": "启动 GNOME 系统监视器",
"Toggle fallback launcher: anyrun": "切换备用启动器:anyrun",
"Toggle fallback launcher: fuzzel": "切换备用启动器:fuzzel",
"Initialization complete!": "初始化完成!",
"Not found": "未找到",
"Calling API": "调用 API",
"Downloading image": "正在下载图片",
"Finished!": "完成!",
"Error": "错误",
"Not found!": "未找到!",
"Go to file url": "前往文件链接",
"Save image": "保存图片",
"Hoard": "保存",
"Open externally": "在外部打开",
"You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or dont have enough information to provide a confident answer, simply say “I dont know” or “Im not sure.”. \nThanks!": "你是 Wayland Linux 桌面侧边栏上的助手。除非有其他要求或提供建议,否则请始终保持轻松的语气回答问题。这是你回答用户查询的步骤:\n1. 如果是写作或语法相关的问题,或者引号中的句子,请指出错误并在必要时进行更正,使用下划线,并在适当的地方使写作更自然,不要进行太大更改。如果你给出的句子在引号中但语法正确,请简要解释不常见概念。\n2. 如果是关于系统任务的问题,请给出bash命令,并在代码块中简要说明。\n3. 否则,在总结信息或解释概念时,你应该使用项目符号和标题。对于数学表达式,你必须在代码块中使用 LaTeX,并将语言设置为\"latex\"。\n注意:使用轻松的语言,简洁,同时确保回答的事实正确性。如果你不确定或没有足够的信息来提供自信的答案,只需说“我不知道”或“我不确定”。\n谢谢!",
"Feels like": "体感温度"
}
-53
View File
@@ -1,53 +0,0 @@
const { Gio, GLib } = imports.gi;
import GtkSource from "gi://GtkSource?version=3.0";
import App from 'resource:///com/github/Aylur/ags/app.js'
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
import { darkMode } from './modules/.miscutils/system.js';
const CUSTOM_SOURCEVIEW_SCHEME_PATH = `${App.configDir}/assets/themes/sourceviewtheme${darkMode.value ? '' : '-light'}.xml`;
export const COMPILED_STYLE_DIR = `${GLib.get_user_cache_dir()}/ags/user/generated`
function loadSourceViewColorScheme(filePath) {
// Read the XML file content
const file = Gio.File.new_for_path(filePath);
const [success, contents] = file.load_contents(null);
if (!success) {
logError('Failed to load the XML file.');
return;
}
// Parse the XML content and set the Style Scheme
const schemeManager = GtkSource.StyleSchemeManager.get_default();
schemeManager.append_search_path(file.get_parent().get_path());
}
globalThis['handleStyles'] = (resetMusic) => {
// Reset
Utils.exec(`mkdir -p "${GLib.get_user_state_dir()}/ags/scss"`);
if (resetMusic) {
Utils.exec(`bash -c 'echo "" > ${GLib.get_user_state_dir()}/ags/scss/_musicwal.scss'`); // reset music styles
Utils.exec(`bash -c 'echo "" > ${GLib.get_user_state_dir()}/ags/scss/_musicmaterial.scss'`); // reset music styles
}
// Generate overrides
let lightdark = darkMode.value ? "dark" : "light";
Utils.writeFileSync(
`
@mixin symbolic-icon {
-gtk-icon-theme: '${userOptions.icons.symbolicIconTheme[lightdark]}';
}
`,
`${GLib.get_user_state_dir()}/ags/scss/_lib_mixins_overrides.scss`)
// Compile and apply
async function applyStyle() {
Utils.exec(`mkdir -p ${COMPILED_STYLE_DIR}`);
Utils.exec(`sass -I "${GLib.get_user_state_dir()}/ags/scss" -I "${App.configDir}/scss/fallback" "${App.configDir}/scss/main.scss" "${COMPILED_STYLE_DIR}/style.css"`);
App.resetCss();
App.applyCss(`${COMPILED_STYLE_DIR}/style.css`);
console.log('[LOG] Styles loaded')
}
applyStyle().then(() => {
loadSourceViewColorScheme(CUSTOM_SOURCEVIEW_SCHEME_PATH);
}).catch(print);
}
@@ -1,33 +0,0 @@
const { Gdk } = imports.gi;
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
export let monitors;
// Mixes with Gdk monitor size cuz it reports monitor size scaled
async function updateStuff() {
monitors = JSON.parse(exec('hyprctl monitors -j'))
const display = Gdk.Display.get_default();
monitors.forEach((monitor, i) => {
const gdkMonitor = display.get_monitor(i);
monitor.realWidth = monitor.width;
monitor.realHeight = monitor.height;
if (userOptions.monitors.scaleMethod.toLowerCase == "gdk") {
monitor.width = gdkMonitor.get_geometry().width;
monitor.height = gdkMonitor.get_geometry().height;
}
else { // == "division"
if (monitor.transform % 2 == 1) { // Vertical monitors (or horizontal monitor that's vertical by default...)
monitor.width = Math.floor(monitor.realHeight / monitor.scale);
monitor.height = Math.floor(monitor.realWidth / monitor.scale);
}
else {
monitor.width = Math.ceil(monitor.realWidth / monitor.scale);
monitor.height = Math.ceil(monitor.realHeight / monitor.scale);
}
}
});
}
updateStuff().catch(print);
-14
View File
@@ -1,14 +0,0 @@
export const quotes = [
{
quote: 'Nvidia, fuck you',
author: 'Linus Torvalds',
},
{
quote: 'reproducible system? cock and vagina?',
author: 'vaxry',
},
{
quote: "haha pointers hee hee i love pointe-\\\nProcess Vaxry exited with signal SIGSEGV",
author: 'vaxry',
}
];
@@ -1,94 +0,0 @@
export const WWO_CODE = {
"113": "Sunny",
"116": "PartlyCloudy",
"119": "Cloudy",
"122": "VeryCloudy",
"143": "Fog",
"176": "LightShowers",
"179": "LightSleetShowers",
"182": "LightSleet",
"185": "LightSleet",
"200": "ThunderyShowers",
"227": "LightSnow",
"230": "HeavySnow",
"248": "Fog",
"260": "Fog",
"263": "LightShowers",
"266": "LightRain",
"281": "LightSleet",
"284": "LightSleet",
"293": "LightRain",
"296": "LightRain",
"299": "HeavyShowers",
"302": "HeavyRain",
"305": "HeavyShowers",
"308": "HeavyRain",
"311": "LightSleet",
"314": "LightSleet",
"317": "LightSleet",
"320": "LightSnow",
"323": "LightSnowShowers",
"326": "LightSnowShowers",
"329": "HeavySnow",
"332": "HeavySnow",
"335": "HeavySnowShowers",
"338": "HeavySnow",
"350": "LightSleet",
"353": "LightShowers",
"356": "HeavyShowers",
"359": "HeavyRain",
"362": "LightSleetShowers",
"365": "LightSleetShowers",
"368": "LightSnowShowers",
"371": "HeavySnowShowers",
"374": "LightSleetShowers",
"377": "LightSleet",
"386": "ThunderyShowers",
"389": "ThunderyHeavyRain",
"392": "ThunderySnowShowers",
"395": "HeavySnowShowers",
}
export const WEATHER_SYMBOL = {
"Unknown": "air",
"Cloudy": "cloud",
"Fog": "foggy",
"HeavyRain": "rainy",
"HeavyShowers": "rainy",
"HeavySnow": "snowing",
"HeavySnowShowers": "snowing",
"LightRain": "rainy",
"LightShowers": "rainy",
"LightSleet": "rainy",
"LightSleetShowers": "rainy",
"LightSnow": "cloudy_snowing",
"LightSnowShowers": "cloudy_snowing",
"PartlyCloudy": "partly_cloudy_day",
"Sunny": "clear_day",
"ThunderyHeavyRain": "thunderstorm",
"ThunderyShowers": "thunderstorm",
"ThunderySnowShowers": "thunderstorm",
"VeryCloudy": "cloud",
}
export const NIGHT_WEATHER_SYMBOL = {
"Unknown": "air",
"Cloudy": "cloud",
"Fog": "foggy",
"HeavyRain": "rainy",
"HeavyShowers": "rainy",
"HeavySnow": "snowing",
"HeavySnowShowers": "snowing",
"LightRain": "rainy",
"LightShowers": "rainy",
"LightSleet": "rainy",
"LightSleetShowers": "rainy",
"LightSnow": "cloudy_snowing",
"LightSnowShowers": "cloudy_snowing",
"PartlyCloudy": "partly_cloudy_night",
"Sunny": "clear_night",
"ThunderyHeavyRain": "thunderstorm",
"ThunderyShowers": "thunderstorm",
"ThunderySnowShowers": "thunderstorm",
"VeryCloudy": "cloud",
}
@@ -1,106 +0,0 @@
const { Gtk } = imports.gi;
const Lang = imports.lang;
import Widget from 'resource:///com/github/Aylur/ags/widget.js'
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
// -- Styling --
// min-height for diameter
// min-width for trough stroke
// padding for space between trough and progress
// margin for space between widget and parent
// background-color for trough color
// color for progress color
// -- Usage --
// font size for progress value (0-100px) (hacky i know, but i want animations)
export const AnimatedCircProg = ({
initFrom = 0,
initTo = 0,
initAnimTime = 2900,
initAnimPoints = 1,
extraSetup = () => { },
...rest
}) => Widget.DrawingArea({
...rest,
css: `${initFrom != initTo ? 'font-size: ' + initFrom + 'px; transition: ' + initAnimTime + 'ms linear;' : ''}`,
setup: (area) => {
const styleContext = area.get_style_context();
const width = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const height = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const padding = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
const marginLeft = styleContext.get_margin(Gtk.StateFlags.NORMAL).left;
const marginRight = styleContext.get_margin(Gtk.StateFlags.NORMAL).right;
const marginTop = styleContext.get_margin(Gtk.StateFlags.NORMAL).top;
const marginBottom = styleContext.get_margin(Gtk.StateFlags.NORMAL).bottom;
area.set_size_request(width + marginLeft + marginRight, height + marginTop + marginBottom);
area.connect('draw', Lang.bind(area, (area, cr) => {
const styleContext = area.get_style_context();
const width = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const height = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const padding = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
const marginLeft = styleContext.get_margin(Gtk.StateFlags.NORMAL).left;
const marginRight = styleContext.get_margin(Gtk.StateFlags.NORMAL).right;
const marginTop = styleContext.get_margin(Gtk.StateFlags.NORMAL).top;
const marginBottom = styleContext.get_margin(Gtk.StateFlags.NORMAL).bottom;
area.set_size_request(width + marginLeft + marginRight, height + marginTop + marginBottom);
const progressValue = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 100.0;
const bg_stroke = styleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const fg_stroke = bg_stroke - padding;
const radius = Math.min(width, height) / 2.0 - Math.max(bg_stroke, fg_stroke) / 2.0;
const center_x = width / 2.0 + marginLeft;
const center_y = height / 2.0 + marginTop;
const start_angle = -Math.PI / 2.0;
const end_angle = start_angle + (2 * Math.PI * progressValue);
const start_x = center_x + Math.cos(start_angle) * radius;
const start_y = center_y + Math.sin(start_angle) * radius;
const end_x = center_x + Math.cos(end_angle) * radius;
const end_y = center_y + Math.sin(end_angle) * radius;
// Draw background
const background_color = styleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
cr.setSourceRGBA(background_color.red, background_color.green, background_color.blue, background_color.alpha);
cr.arc(center_x, center_y, radius, 0, 2 * Math.PI);
cr.setLineWidth(bg_stroke);
cr.stroke();
if (progressValue == 0) return;
// Draw progress
const color = styleContext.get_property('color', Gtk.StateFlags.NORMAL);
cr.setSourceRGBA(color.red, color.green, color.blue, color.alpha);
cr.arc(center_x, center_y, radius, start_angle, end_angle);
cr.setLineWidth(fg_stroke);
cr.stroke();
// Draw rounded ends for progress arcs
cr.setLineWidth(0);
cr.arc(start_x, start_y, fg_stroke / 2, 0, 0 - 0.01);
cr.fill();
cr.arc(end_x, end_y, fg_stroke / 2, 0, 0 - 0.01);
cr.fill();
}));
// Init animation
if (initFrom != initTo) {
area.css = `font-size: ${initFrom}px; transition: ${initAnimTime}ms linear;`;
Utils.timeout(20, () => {
area.css = `font-size: ${initTo}px;`;
}, area)
const transitionDistance = initTo - initFrom;
const oneStep = initAnimTime / initAnimPoints;
area.css = `
font-size: ${initFrom}px;
transition: ${oneStep}ms linear;
`;
for (let i = 0; i < initAnimPoints; i++) {
Utils.timeout(Math.max(10, i * oneStep), () => {
if(!area) return;
area.css = `${initFrom != initTo ? 'font-size: ' + (initFrom + (transitionDistance / initAnimPoints * (i + 1))) + 'px;' : ''}`;
});
}
}
else area.css = 'font-size: 0px;';
extraSetup(area);
},
})
@@ -1,71 +0,0 @@
const { Gtk } = imports.gi;
const Lang = imports.lang;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
// min-height/min-width for height/width
// background-color/color for background/indicator color
// padding for pad of indicator
// font-size for selected index (0-based)
export const NavigationIndicator = ({count, vertical, ...props}) => Widget.DrawingArea({
...props,
setup: (area) => {
const styleContext = area.get_style_context();
const width = Math.max(styleContext.get_property('min-width', Gtk.StateFlags.NORMAL), area.get_allocated_width());
const height = Math.max(styleContext.get_property('min-height', Gtk.StateFlags.NORMAL), area.get_allocated_height());
area.set_size_request(width, height);
area.connect('draw', Lang.bind(area, (area, cr) => {
const styleContext = area.get_style_context();
const width = Math.max(styleContext.get_property('min-width', Gtk.StateFlags.NORMAL), area.get_allocated_width());
const height = Math.max(styleContext.get_property('min-height', Gtk.StateFlags.NORMAL), area.get_allocated_height());
// console.log('allocated width/height:', area.get_allocated_width(), '/', area.get_allocated_height())
area.set_size_request(width, height);
const paddingLeft = styleContext.get_padding(Gtk.StateFlags.NORMAL).left;
const paddingRight = styleContext.get_padding(Gtk.StateFlags.NORMAL).right;
const paddingTop = styleContext.get_padding(Gtk.StateFlags.NORMAL).top;
const paddingBottom = styleContext.get_padding(Gtk.StateFlags.NORMAL).bottom;
const selectedCell = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
let cellWidth = width;
let cellHeight = height;
if (vertical) cellHeight /= count;
else cellWidth /= count;
const indicatorWidth = cellWidth - paddingLeft - paddingRight;
const indicatorHeight = cellHeight - paddingTop - paddingBottom;
const background_color = styleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const color = styleContext.get_property('color', Gtk.StateFlags.NORMAL);
cr.setLineWidth(2);
// Background
cr.setSourceRGBA(background_color.red, background_color.green, background_color.blue, background_color.alpha);
cr.rectangle(0, 0, width, height);
cr.fill();
// The indicator line
cr.setSourceRGBA(color.red, color.green, color.blue, color.alpha);
if (vertical) {
cr.rectangle(paddingLeft, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth, indicatorHeight - indicatorWidth);
cr.stroke();
cr.rectangle(paddingLeft, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth, indicatorHeight - indicatorWidth);
cr.fill();
cr.arc(paddingLeft + indicatorWidth / 2, paddingTop + cellHeight * selectedCell + indicatorWidth / 2, indicatorWidth / 2, Math.PI, 2 * Math.PI);
cr.fill();
cr.arc(paddingLeft + indicatorWidth / 2, paddingTop + cellHeight * selectedCell + indicatorHeight - indicatorWidth / 2, indicatorWidth / 2, 0, Math.PI);
cr.fill();
}
else {
cr.rectangle(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop, indicatorWidth - indicatorHeight, indicatorHeight);
cr.stroke();
cr.rectangle(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop, indicatorWidth - indicatorHeight, indicatorHeight);
cr.fill();
cr.arc(paddingLeft + cellWidth * selectedCell + indicatorHeight / 2, paddingTop + indicatorHeight / 2, indicatorHeight / 2, 0.5 * Math.PI, 1.5 * Math.PI);
cr.fill();
cr.arc(paddingLeft + cellWidth * selectedCell + indicatorWidth - indicatorHeight / 2, paddingTop + indicatorHeight / 2, indicatorHeight / 2, -0.5 * Math.PI, 0.5 * Math.PI);
cr.fill();
}
}))
},
})
@@ -1,50 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Gtk } = imports.gi;
const Lang = imports.lang;
export const RoundedCorner = (place, props) => Widget.DrawingArea({
...props,
hpack: place.includes('left') ? 'start' : 'end',
vpack: place.includes('top') ? 'start' : 'end',
setup: (widget) => Utils.timeout(1, () => {
const c = widget.get_style_context().get_property('background-color', Gtk.StateFlags.NORMAL);
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
widget.set_size_request(r, r);
widget.connect('draw', Lang.bind(widget, (widget, cr) => {
const c = widget.get_style_context().get_property('background-color', Gtk.StateFlags.NORMAL);
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
// const borderColor = widget.get_style_context().get_property('color', Gtk.StateFlags.NORMAL);
// const borderWidth = widget.get_style_context().get_border(Gtk.StateFlags.NORMAL).left; // ur going to write border-width: something anyway
widget.set_size_request(r, r);
switch (place) {
case 'topleft':
cr.arc(r, r, r, Math.PI, 3 * Math.PI / 2);
cr.lineTo(0, 0);
break;
case 'topright':
cr.arc(0, r, r, 3 * Math.PI / 2, 2 * Math.PI);
cr.lineTo(r, 0);
break;
case 'bottomleft':
cr.arc(r, 0, r, Math.PI / 2, Math.PI);
cr.lineTo(0, r);
break;
case 'bottomright':
cr.arc(0, 0, r, 0, Math.PI / 2);
cr.lineTo(r, r);
break;
}
cr.closePath();
cr.setSourceRGBA(c.red, c.green, c.blue, c.alpha);
cr.fill();
// cr.setLineWidth(borderWidth);
// cr.setSourceRGBA(borderColor.red, borderColor.green, borderColor.blue, borderColor.alpha);
// cr.stroke();
}));
}),
});
@@ -1,49 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Gtk } = imports.gi;
const Lang = imports.lang;
export const AnimatedSlider = ({
className,
value,
...rest
}) => {
return Widget.DrawingArea({
className: `${className}`,
setup: (self) => {
self.connect('draw', Lang.bind(self, (self, cr) => {
const styleContext = self.get_style_context();
const allocatedWidth = self.get_allocated_width();
const allocatedHeight = self.get_allocated_height();
console.log(allocatedHeight, allocatedWidth)
const minWidth = styleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const minHeight = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
const radius = styleContext.get_property('border-radius', Gtk.StateFlags.NORMAL);
const bg = styleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const fg = styleContext.get_property('color', Gtk.StateFlags.NORMAL);
const value = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 100;
self.set_size_request(-1, minHeight);
const width = allocatedHeight;
const height = minHeight;
cr.arc(radius, radius, radius, -1 * Math.PI, -0.5 * Math.PI); // Top-left
cr.arc(width - radius, radius, radius, -0.5 * Math.PI, 0); // Top-right
cr.arc(width - radius, height - radius, radius, 0, 0.5 * Math.PI); // Bottom-left
cr.arc(radius, height - radius, radius, 0.5 * Math.PI, 1 * Math.PI); // Bottom-right
cr.setSourceRGBA(bg.red, bg.green, bg.blue, bg.alpha);
cr.closePath();
cr.fill();
// const valueWidth = width * value;
// cr.arc(radius, radius, radius, -1 * Math.PI, -0.5 * Math.PI); // Top-left
// cr.arc(valueWidth - radius, radius, radius, -0.5 * Math.PI, 0); // Top-right
// cr.arc(valueWidth - radius, height - radius, radius, 0, 0.5 * Math.PI); // Bottom-left
// cr.arc(radius, height - radius, radius, 0.5 * Math.PI, 1 * Math.PI); // Bottom-right
// cr.setSourceRGBA(fg.red, fg.green, fg.blue, fg.alpha);
// cr.closePath();
// cr.fill();
}));
},
...rest,
})
}
@@ -1,23 +0,0 @@
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import { monitors } from '../.commondata/hyprlanddata.js';
const { Box, EventBox } = Widget;
export const clickCloseRegion = ({ name, multimonitor = true, monitor = 0, expand = true, fillMonitor = '' }) => {
return EventBox({
child: Box({
expand: expand,
css: `
min-width: ${fillMonitor.includes('h') ? monitors[monitor].width : 0}px;
min-height: ${fillMonitor.includes('v') ? monitors[monitor].height : 0}px;
`,
}),
setup: (self) => self.on('button-press-event', (self, event) => { // Any mouse button
if (multimonitor) closeWindowOnAllMonitors(name);
else App.closeWindow(name);
}),
})
}
export default clickCloseRegion;
@@ -1,298 +0,0 @@
const { Gtk } = imports.gi;
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import { MaterialIcon } from './materialicon.js';
import { setupCursorHover, setupCursorHoverHResize } from '../.widgetutils/cursorhover.js';
const { Box, Button, EventBox, Label, Revealer, SpinButton } = Widget;
// Basically M3 Switch
// https://m3.material.io/components/switch/overview
// onReset must be async
export const ConfigToggle = ({
icon, name, desc = '', initValue,
expandWidget = true, resetButton = false,
onChange = () => { }, extraSetup = () => { },
onReset = () => { }, fetchValue = () => { },
...rest
}) => {
const enabled = Variable(initValue);
const toggleIcon = Label({
className: `icon-material txt-bold ${enabled.value ? '' : 'txt-poof'}`,
label: `${enabled.value ? 'check' : ''}`,
setup: (self) => self.hook(enabled, (self) => {
self.toggleClassName('switch-fg-toggling-false', false);
if (!enabled.value) {
self.label = '';
self.toggleClassName('txt-poof', true);
}
else Utils.timeout(1, () => {
toggleIcon.label = 'check';
toggleIcon.toggleClassName('txt-poof', false);
})
}),
})
const toggleButtonIndicator = Box({
className: `switch-fg ${enabled.value ? 'switch-fg-true' : ''}`,
vpack: 'center',
hpack: 'start',
homogeneous: true,
children: [toggleIcon,],
setup: (self) => self.hook(enabled, (self) => {
self.toggleClassName('switch-fg-true', enabled.value);
}),
});
const toggleButton = Box({
hpack: 'end',
vpack: 'center',
className: `switch-bg ${enabled.value ? 'switch-bg-true' : ''}`,
homogeneous: true,
children: [toggleButtonIndicator],
setup: (self) => self.hook(enabled, (self) => {
self.toggleClassName('switch-bg-true', enabled.value);
}),
});
const widgetContent = Box({
tooltipText: desc,
className: 'txt spacing-h-5',
children: [
...(icon !== undefined ? [MaterialIcon(icon, 'norm', {vpack: 'center'})] : []),
...(name !== undefined ? [Label({
vpack: 'center',
className: 'txt txt-small',
label: name,
})] : []),
...(expandWidget ? [Box({ hexpand: true })] : []),
toggleButton,
]
});
const interactionWrapper = Button({
attribute: {
enabled: enabled,
toggle: (newValue) => {
enabled.value = !enabled.value;
onChange(interactionWrapper, enabled.value);
}
},
child: widgetContent,
onClicked: (self) => self.attribute.toggle(self),
onHoverLost: () => { // mouse away
toggleIcon.toggleClassName('switch-fg-toggling-false', false);
if (enabled.value) toggleIcon.toggleClassName('txt-poof', false);
},
setup: (self) => {
setupCursorHover(self);
self.connect('pressed', () => { // mouse down
toggleIcon.toggleClassName('txt-poof', true);
toggleIcon.toggleClassName('switch-fg-true', false);
if (!enabled.value) toggleIcon.toggleClassName('switch-fg-toggling-false', true);
});
extraSetup(self)
},
...rest,
});
const wholeThing = Box({
attribute: {
'enabled': enabled,
},
className: 'configtoggle-box spacing-h-5',
children: [
interactionWrapper,
...(resetButton ? [Button({
className: 'configtoggle-reset',
onClicked: (self) => {
onReset(self).then(() => {
enabled.value = fetchValue();
}).catch(print);
},
child: MaterialIcon('settings_backup_restore', 'small'),
setup: setupCursorHover,
})] : []),
]
});
wholeThing.enabled = enabled;
return wholeThing;
}
export const ConfigSegmentedSelection = ({
icon, name, desc = '',
options = [{ name: 'Option 1', value: 0 }, { name: 'Option 2', value: 1 }],
initIndex = 0,
onChange,
...rest
}) => {
let lastSelected = initIndex;
let value = options[initIndex].value;
const widget = Box({
tooltipText: desc,
className: 'segment-container',
// homogeneous: true,
children: options.map((option, id) => {
const selectedIcon = Revealer({
revealChild: id == initIndex,
transition: 'slide_right',
transitionDuration: userOptions.animations.durationSmall,
child: MaterialIcon('check', 'norm')
});
return Button({
setup: setupCursorHover,
className: `segment-btn ${id == initIndex ? 'segment-btn-enabled' : ''}`,
child: Box({
hpack: 'center',
className: 'spacing-h-5',
children: [
selectedIcon,
Label({
label: option.name,
})
]
}),
onClicked: (self) => {
value = option.value;
const kids = widget.get_children();
kids[lastSelected].toggleClassName('segment-btn-enabled', false);
kids[lastSelected].get_children()[0].get_children()[0].revealChild = false;
lastSelected = id;
self.toggleClassName('segment-btn-enabled', true);
selectedIcon.revealChild = true;
onChange(option.value, option.name);
}
})
}),
...rest,
});
return widget;
}
export const ConfigMulipleSelection = ({
icon, name, desc = '',
optionsArr = [
[{ name: 'Option 1', value: 0 }, { name: 'Option 2', value: 1 }],
[{ name: 'Option 3', value: 0 }, { name: 'Option 4', value: 1 }],
],
initIndex = [0, 0],
onChange,
...rest
}) => {
let lastSelected = initIndex;
const widget = Box({
tooltipText: desc,
className: 'multipleselection-container spacing-v-3',
vertical: true,
children: optionsArr.map((options, grp) => Box({
className: 'spacing-h-5',
hpack: 'center',
children: options.map((option, id) => Button({
setup: setupCursorHover,
className: `multipleselection-btn ${id == initIndex[1] && grp == initIndex[0] ? 'multipleselection-btn-enabled' : ''}`,
label: option.name,
onClicked: (self) => {
const kidsg = widget.get_children();
const kids = kidsg.flatMap(widget => widget.get_children());
kids.forEach(kid => {
kid.toggleClassName('multipleselection-btn-enabled', false);
});
lastSelected = id;
self.toggleClassName('multipleselection-btn-enabled', true);
onChange(option.value, option.name);
}
})),
})),
...rest,
});
return widget;
}
export const ConfigGap = ({ vertical = true, size = 5, ...rest }) => Box({
className: `gap-${vertical ? 'v' : 'h'}-${size}`,
...rest,
})
// Gtk SpinButton with value scrubbing gesture
// scrubRatio is the ratio of changed value to drag distance in pixels
// onReset must be async
export const ConfigSpinButton = ({
icon, name, desc = '', initValue,
minValue = 0, maxValue = 100, step = 1,
expandWidget = true, resetButton = false,
scrubRatio = 1 / 20, roundValue = true,
onChange = () => { }, extraSetup = () => { },
onReset = () => { }, fetchValue = () => { },
...rest
}) => {
let resetLock = false;
const value = Variable(initValue);
const spinButton = SpinButton({
className: 'spinbutton',
range: [minValue, maxValue],
increments: [step, step],
onValueChanged: ({ value: newValue }) => {
if (resetLock) return;
value.value = newValue;
onChange(spinButton, newValue);
},
// This funny line means: set value of the spinbutton to the value of the
// Variable object called value that tracks the value of the widget
value: value.value,
});
const widgetContent = Box({
tooltipText: desc,
className: 'txt spacing-h-5 configtoggle-box',
children: [
...(icon !== undefined ? [MaterialIcon(icon, 'norm')] : []),
...(name !== undefined ? [Label({
className: 'txt txt-small',
label: name,
})] : []),
...(expandWidget ? [Box({ hexpand: true })] : []),
spinButton,
...(resetButton ? [Button({
className: 'spinbutton-reset',
onClicked: (self) => {
onReset(self).then(() => {
resetLock = true;
const newValue = fetchValue();
spinButton.value = newValue;
value.value = newValue;
resetLock = false;
}).catch(print);
},
child: MaterialIcon('settings_backup_restore', 'small'),
setup: setupCursorHover,
})] : []),
],
setup: (self) => {
extraSetup(self);
},
...rest,
});
const interactionWrapper = EventBox({
child: widgetContent,
setup: setupCursorHoverHResize,
})
const gesture = Gtk.GestureDrag.new(interactionWrapper);
let gestureValueOnDragBegin;
const wholeThing = Box({
children: [interactionWrapper],
setup: (self) => self
.hook(gesture, (self) => {
gestureValueOnDragBegin = value.value;
}, 'drag-begin')
.hook(gesture, (self) => {
var offset_x = gesture.get_offset()[1];
var offset_y = gesture.get_offset()[2];
let newValue = gestureValueOnDragBegin + (offset_x * scrubRatio);
if (roundValue) newValue = Math.round(newValue);
if (newValue !== spinButton.value) {
spinButton.value = newValue;
}
}, 'drag-update')
.hook(gesture, (self) => {
}, 'drag-end')
});
wholeThing.enabled = value;
return wholeThing;
}
@@ -1,154 +0,0 @@
const { GLib } = imports.gi;
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
import { getNestedProperty, updateNestedProperty } from "../.miscutils/objects.js";
import { ConfigSpinButton, ConfigToggle } from "./configwidgets.js";
const AGS_CONFIG_FILE = `${App.configDir}/user_options.jsonc`;
const HYPRLAND_CONFIG_FILE = `${GLib.get_user_config_dir()}/hypr/custom/general.conf`;
export const AgsToggle = ({
icon, name, desc = null,
option, resetButton = true, save = true,
extraOnChange = () => { }, extraOnReset = () => { },
...rest
}) => ConfigToggle({
icon: icon,
name: name,
desc: `${desc}\n\n${option}\nEdit in ${AGS_CONFIG_FILE}`,
resetButton: resetButton,
initValue: getNestedProperty(userOptions, option),
fetchValue: () => getNestedProperty(userOptions, option),
onChange: (self, newValue) => {
updateNestedProperty(userOptions, option, newValue);
if (save) execAsync(['bash', '-c', `${App.configDir}/scripts/ags/agsconfigurator.py \
--key ${option} \
--value ${newValue} \
--file ${AGS_CONFIG_FILE}`
]).catch(print);
extraOnChange(self, newValue);
},
onReset: async (self) => {
updateNestedProperty(userOptions, option,
getNestedProperty(userOptionsDefaults, option));
if (save) exec(`bash -c '${App.configDir}/scripts/ags/agsconfigurator.py \
--key ${option} \
--reset \
--file ${AGS_CONFIG_FILE}'`);
extraOnReset(self);
},
...rest
});
export const AgsSpinButton = ({
icon, name, desc = null,
option, resetButton = true,
save = true, extraOnChange = () => { }, extraOnReset = () => { },
...rest
}) => ConfigSpinButton({
icon: icon,
name: name,
desc: `${desc}\n\n${option}\nEdit in ${AGS_CONFIG_FILE}`,
resetButton: resetButton,
initValue: getNestedProperty(userOptions, option),
fetchValue: () => getNestedProperty(userOptions, option),
step: 10, minValue: 0, maxValue: 1000,
onChange: (self, newValue) => {
updateNestedProperty(userOptions, option, newValue);
if (save) execAsync(['bash', '-c', `${App.configDir}/scripts/ags/agsconfigurator.py \
--key ${option} \
--value ${newValue} \
--file ${AGS_CONFIG_FILE}`
]).catch(print);
extraOnChange(self, newValue);
},
onReset: async () => {
updateNestedProperty(userOptions, option,
getNestedProperty(userOptionsDefaults, option));
if (save) exec(`bash -c '${App.configDir}/scripts/ags/agsconfigurator.py \
--key ${option} \
--reset \
--file ${AGS_CONFIG_FILE}'`);
extraOnReset(self);
},
...rest,
});
export const HyprlandToggle = ({
icon, name, desc = null,
option, resetButton = true,
enableValue = 1, disableValue = 0,
extraOnChange = () => { }, extraOnReset = () => { }, save = true
}) => ConfigToggle({
icon: icon,
name: name,
desc: `${desc}\n\n${option}\nEdit in ${HYPRLAND_CONFIG_FILE}`,
resetButton: resetButton,
initValue: JSON.parse(exec(`hyprctl getoption -j ${option}`))["int"] != 0,
fetchValue: () => JSON.parse(exec(`hyprctl getoption -j ${option}`))["int"] != 0,
onChange: (self, newValue) => {
if (save)
execAsync(['bash', '-c', `${App.configDir}/scripts/hyprland/hyprconfigurator.py \
--key ${option} \
--value ${newValue ? enableValue : disableValue} \
--file ${HYPRLAND_CONFIG_FILE}`
]).catch(print);
else
execAsync(['hyprctl', 'keyword', option, `${newValue ? enableValue : disableValue}`]).catch(print);
extraOnChange(self, newValue);
},
onReset: async (self) => {
if (save)
exec(`bash -c '${App.configDir}/scripts/hyprland/hyprconfigurator.py \
--key ${option} \
--reset \
--file "${HYPRLAND_CONFIG_FILE}"'`);
else
exec('hyprctl reload');
extraOnReset(self);
},
});
export const HyprlandSpinButton = ({
icon, name, desc = null,
option, resetButton = true, save = true,
extraOnChange = () => { }, extraOnReset = () => { },
...rest
}) => ConfigSpinButton({
icon: icon,
name: name,
desc: `${desc}\n\n${option}\nEdit in ${HYPRLAND_CONFIG_FILE}`,
resetButton: resetButton,
initValue: Number(JSON.parse(exec(`hyprctl getoption -j ${option}`))["int"]),
fetchValue: () => Number(JSON.parse(exec(`hyprctl getoption -j ${option}`))["int"]),
onChange: (self, newValue) => {
if (save)
execAsync(['bash', '-c', `${App.configDir}/scripts/hyprland/hyprconfigurator.py \
--key ${option} \
--value ${newValue} \
--file ${HYPRLAND_CONFIG_FILE}`
]).catch(print);
else
execAsync(['hyprctl', 'keyword', option, `${newValue}`]).catch(print);
extraOnChange(self, newValue);
},
onReset: async (self) => {
if (save)
exec(`bash -c '${App.configDir}/scripts/hyprland/hyprconfigurator.py \
--key ${option} \
--reset \
--file "${HYPRLAND_CONFIG_FILE}"'`);
else
exec('hyprctl reload');
extraOnReset(self);
},
...rest,
});
@@ -1,7 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
export const MaterialIcon = (icon, size, props = {}) => Widget.Label({
className: `icon-material txt-${size}`,
label: icon,
...props,
})
@@ -1,505 +0,0 @@
// This file is for the actual widget for each single notification
const { GLib, Gdk, Gtk } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js'
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
const { Box, EventBox, Icon, Overlay, Label, Button, Revealer } = Widget;
import { MaterialIcon } from './materialicon.js';
import { setupCursorHover } from "../.widgetutils/cursorhover.js";
import { AnimatedCircProg } from "./cairo_circularprogress.js";
function guessMessageType(summary) {
const keywordsToTypes = {
'reboot': 'restart_alt',
'recording': 'screen_record',
'battery': 'power',
'power': 'power',
'screenshot': 'screenshot_monitor',
'welcome': 'waving_hand',
'time': 'scheduleb',
'installed': 'download',
'update': 'update',
'ai response': 'neurology',
'startswith:file': 'folder_copy', // Declarative startsWith check
};
const lowerSummary = summary.toLowerCase();
for (const [keyword, type] of Object.entries(keywordsToTypes)) {
if (keyword.startsWith('startswith:')) {
const startsWithKeyword = keyword.replace('startswith:', '');
if (lowerSummary.startsWith(startsWithKeyword)) {
return type;
}
} else if (lowerSummary.includes(keyword)) {
return type;
}
}
return 'chat';
}
function processNotificationBody(body, appEntry) {
// Only process Chrome/Chromium notifications
if (appEntry?.toLowerCase().includes('chrome')) {
// Remove the first line
return body.split('\n\n').slice(1).join('\n\n');
}
return body;
}
const getFriendlyNotifTimeString = (timeObject) => {
const messageTime = GLib.DateTime.new_from_unix_local(timeObject);
const oneMinuteAgo = GLib.DateTime.new_now_local().add_seconds(-60);
if (messageTime.compare(oneMinuteAgo) > 0)
return getString('Now');
else if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year())
return messageTime.format(userOptions.time.format);
else if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year() - 1)
return getString('Yesterday');
else
return messageTime.format(userOptions.time.dateFormat);
}
const NotificationIcon = (notifObject) => {
if (notifObject.hints?.image_path?.deepUnpack) {
const imagePath = notifObject.hints.image_path.deepUnpack();
return Box({
valign: Gtk.Align.CENTER,
hexpand: false,
className: 'notif-icon',
css: `
background-image: url("${imagePath}");
background-size: auto 100%;
background-repeat: no-repeat;
background-position: center;
`,
});
}
if (notifObject.image) {
return Box({
valign: Gtk.Align.CENTER,
hexpand: false,
className: 'notif-icon',
css: `
background-image: url("${notifObject.image}");
background-size: auto 100%;
background-repeat: no-repeat;
background-position: center;
`,
});
}
let icon = 'NO_ICON';
if (Utils.lookUpIcon(notifObject.appIcon))
icon = notifObject.appIcon;
if (Utils.lookUpIcon(notifObject.appEntry))
icon = notifObject.appEntry;
return Box({
vpack: 'center',
hexpand: false,
className: `notif-icon notif-icon-material-${notifObject.urgency}`,
homogeneous: true,
children: [
(icon != 'NO_ICON' ?
Icon({
vpack: 'center',
icon: icon,
})
:
MaterialIcon(`${notifObject.urgency == 'critical' ? 'release_alert' : guessMessageType(notifObject.summary.toLowerCase())}`, 'hugerass', {
hexpand: true,
})
)
],
});
};
export default ({
notifObject,
isPopup = false,
props = {},
} = {}) => {
const popupTimeout = notifObject.timeout || (notifObject.urgency == 'critical' ? 8000 : 3000);
const command = (isPopup ?
() => notifObject.dismiss() :
() => notifObject.close()
)
const destroyWithAnims = () => {
widget.sensitive = false;
notificationBox.setCss(middleClickClose);
Utils.timeout(userOptions.animations.durationSmall, () => {
if (wholeThing) wholeThing.revealChild = false;
}, wholeThing);
Utils.timeout(userOptions.animations.durationSmall * 2, () => {
command();
if (wholeThing) {
wholeThing.destroy();
wholeThing = null;
}
}, wholeThing);
}
const widget = EventBox({
onHover: (self) => {
self.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
if (!wholeThing.attribute.hovered)
wholeThing.attribute.hovered = true;
},
onHoverLost: (self) => {
self.window.set_cursor(null);
if (wholeThing.attribute.hovered)
wholeThing.attribute.hovered = false;
if (isPopup) {
command();
}
},
onMiddleClick: (self) => {
destroyWithAnims();
},
onSecondaryClick: (self) => {
expanded = !expanded;
notifTextPreview.revealChild = !expanded;
notifTextExpanded.revealChild = expanded;
notifExpandButton.child.label = `expand_${expanded ? 'less' : 'more'}`;
},
setup: (self) => {
self.on("button-press-event", () => {
wholeThing.attribute.held = true;
notificationContent.toggleClassName(`${isPopup ? 'popup-' : ''}notif-clicked-${notifObject.urgency}`, true);
Utils.timeout(800, () => {
if (wholeThing?.attribute.held) {
Utils.execAsync(['wl-copy', `${notifObject.body}`]).catch(print);
notifTextSummary.label = notifObject.summary + " (copied)";
Utils.timeout(3000, () => notifTextSummary.label = notifObject.summary)
}
})
}).on("button-release-event", () => {
wholeThing.attribute.held = false;
notificationContent.toggleClassName(`${isPopup ? 'popup-' : ''}notif-clicked-${notifObject.urgency}`, false);
})
}
});
let wholeThing = Revealer({
attribute: {
'close': undefined,
'destroyWithAnims': destroyWithAnims,
'dragging': false,
'held': false,
'hovered': false,
'id': notifObject.id,
},
revealChild: false,
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
child: Box({ // Box to make sure css-based spacing works
homogeneous: true,
}),
});
const display = Gdk.Display.get_default();
const notifTextPreview = Revealer({
transition: 'slide_down',
transitionDuration: userOptions.animations.durationSmall,
revealChild: true,
child: Label({
xalign: 0,
className: `txt-smallie notif-body-${notifObject.urgency}`,
useMarkup: true,
xalign: 0,
justify: Gtk.Justification.LEFT,
maxWidthChars: 1,
truncate: 'end',
label: processNotificationBody(notifObject.body, notifObject.appEntry).split("\n")[0]
}),
});
const notifTextExpanded = Revealer({
transition: 'slide_up',
transitionDuration: userOptions.animations.durationSmall,
revealChild: false,
child: Box({
vertical: true,
className: 'spacing-v-10',
children: [
Label({
xalign: 0,
className: `txt-smallie notif-body-${notifObject.urgency}`,
useMarkup: true,
xalign: 0,
justify: Gtk.Justification.LEFT,
maxWidthChars: 1,
wrap: true,
label: processNotificationBody(notifObject.body, notifObject.appEntry)
}),
Box({
className: 'notif-actions spacing-h-5',
children: [
Button({
hexpand: true,
className: `notif-action notif-action-${notifObject.urgency}`,
onClicked: () => destroyWithAnims(),
setup: setupCursorHover,
child: Label({
label: getString('Close'),
}),
}),
...notifObject.actions.map(action => Widget.Button({
hexpand: true,
className: `notif-action notif-action-${notifObject.urgency}`,
onClicked: () => notifObject.invoke(action.id),
setup: setupCursorHover,
child: Label({
label: action.label,
}),
}))
],
})
]
}),
});
const notifIcon = Box({
vpack: 'start',
homogeneous: true,
children: [
Overlay({
child: NotificationIcon(notifObject),
overlays: isPopup ? [AnimatedCircProg({
className: `notif-circprog-${notifObject.urgency}`,
vpack: 'center', hpack: 'center',
initFrom: (isPopup ? 100 : 0),
initTo: 0,
initAnimTime: popupTimeout,
})] : [],
}),
]
});
const notifTextSummary = Label({
xalign: 0,
className: 'txt-small txt-semibold titlefont',
justify: Gtk.Justification.LEFT,
hexpand: true,
maxWidthChars: 1,
truncate: 'end',
ellipsize: 3,
useMarkup: notifObject.summary.startsWith('<'),
label: notifObject.summary,
});
const initTimeString = getFriendlyNotifTimeString(notifObject.time);
const notifTextBody = Label({
vpack: 'center',
justification: 'right',
className: 'txt-smaller txt-semibold',
label: initTimeString,
setup: initTimeString == 'Now' ? (self) => {
let id = Utils.timeout(60000, () => {
self.label = getFriendlyNotifTimeString(notifObject.time);
id = null;
});
self.connect('destroy', () => { if (id) GLib.source_remove(id) });
} : () => { },
});
const notifText = Box({
valign: Gtk.Align.CENTER,
vertical: true,
hexpand: true,
children: [
Box({
children: [
notifTextSummary,
notifTextBody,
]
}),
notifTextPreview,
notifTextExpanded,
]
});
const notifExpandButton = Button({
vpack: 'start',
className: 'notif-expand-btn',
onClicked: (self) => {
if (notifTextPreview.revealChild) { // Expanding...
notifTextPreview.revealChild = false;
notifTextExpanded.revealChild = true;
self.child.label = 'expand_less';
expanded = true;
}
else {
notifTextPreview.revealChild = true;
notifTextExpanded.revealChild = false;
self.child.label = 'expand_more';
expanded = false;
}
},
child: MaterialIcon('expand_more', 'norm', {
vpack: 'center',
}),
setup: setupCursorHover,
});
const notificationContent = Box({
...props,
className: `${isPopup ? 'popup-' : ''}notif-${notifObject.urgency} spacing-h-10`,
children: [
notifIcon,
Box({
className: 'spacing-h-5',
children: [
notifText,
notifExpandButton,
]
})
]
})
// Gesture stuff
const gesture = Gtk.GestureDrag.new(widget);
var initDirX = 0;
var initDirVertical = -1; // -1: unset, 0: horizontal, 1: vertical
var expanded = false;
// in px
const startMargin = 0;
const MOVE_THRESHOLD = 10;
const DRAG_CONFIRM_THRESHOLD = 100;
// in rem
const maxOffset = 10.227;
const endMargin = 20.455;
const disappearHeight = 6.818;
const leftAnim1 = `transition: ${userOptions.animations.durationSmall}ms cubic-bezier(0.05, 0.7, 0.1, 1);
margin-left: -${Number(maxOffset + endMargin)}rem;
margin-right: ${Number(maxOffset + endMargin)}rem;
opacity: 0;`;
const rightAnim1 = `transition: ${userOptions.animations.durationSmall}ms cubic-bezier(0.05, 0.7, 0.1, 1);
margin-left: ${Number(maxOffset + endMargin)}rem;
margin-right: -${Number(maxOffset + endMargin)}rem;
opacity: 0;`;
const middleClickClose = `transition: ${userOptions.animations.durationSmall}ms cubic-bezier(0.85, 0, 0.15, 1);
margin-left: ${Number(maxOffset + endMargin)}rem;
margin-right: -${Number(maxOffset + endMargin)}rem;
opacity: 0;`;
const notificationBox = Box({
attribute: {
'leftAnim1': leftAnim1,
'rightAnim1': rightAnim1,
'middleClickClose': middleClickClose,
'ready': false,
},
homogeneous: true,
children: [notificationContent],
setup: (self) => self
.hook(gesture, self => {
var offset_x = gesture.get_offset()[1];
var offset_y = gesture.get_offset()[2];
// Which dir?
if (initDirVertical == -1) {
if (Math.abs(offset_y) > MOVE_THRESHOLD)
initDirVertical = 1;
if (initDirX == 0 && Math.abs(offset_x) > MOVE_THRESHOLD) {
initDirVertical = 0;
initDirX = (offset_x > 0 ? 1 : -1);
}
}
// Horizontal drag
if (initDirVertical == 0 && offset_x > MOVE_THRESHOLD) {
if (initDirX < 0)
self.setCss(`margin-left: 0px; margin-right: 0px;`);
else
self.setCss(`
margin-left: ${Number(offset_x + startMargin - MOVE_THRESHOLD)}px;
margin-right: -${Number(offset_x + startMargin - MOVE_THRESHOLD)}px;
`);
}
else if (initDirVertical == 0 && offset_x < -MOVE_THRESHOLD) {
if (initDirX > 0)
self.setCss(`margin-left: 0px; margin-right: 0px;`);
else {
offset_x = Math.abs(offset_x);
self.setCss(`
margin-right: ${Number(offset_x + startMargin - MOVE_THRESHOLD)}px;
margin-left: -${Number(offset_x + startMargin - MOVE_THRESHOLD)}px;
`);
}
}
// Update dragging
wholeThing.attribute.dragging = Math.abs(offset_x) > MOVE_THRESHOLD;
if (Math.abs(offset_x) > MOVE_THRESHOLD ||
Math.abs(offset_y) > MOVE_THRESHOLD) wholeThing.attribute.held = false;
widget.window?.set_cursor(Gdk.Cursor.new_from_name(display, 'grabbing'));
// Vertical drag
if (initDirVertical == 1 && offset_y > MOVE_THRESHOLD && !expanded) {
notifTextPreview.revealChild = false;
notifTextExpanded.revealChild = true;
expanded = true;
notifExpandButton.child.label = 'expand_less';
}
else if (initDirVertical == 1 && offset_y < -MOVE_THRESHOLD && expanded) {
notifTextPreview.revealChild = true;
notifTextExpanded.revealChild = false;
expanded = false;
notifExpandButton.child.label = 'expand_more';
}
}, 'drag-update')
.hook(gesture, self => {
if (!self.attribute.ready) {
wholeThing.revealChild = true;
self.attribute.ready = true;
return;
}
const offset_h = gesture.get_offset()[1];
if (Math.abs(offset_h) > DRAG_CONFIRM_THRESHOLD && offset_h * initDirX > 0) {
if (offset_h > 0) {
self.setCss(rightAnim1);
widget.sensitive = false;
}
else {
self.setCss(leftAnim1);
widget.sensitive = false;
}
Utils.timeout(userOptions.animations.durationSmall, () => {
if (wholeThing) wholeThing.revealChild = false;
}, wholeThing);
Utils.timeout(userOptions.animations.durationSmall * 2, () => {
command();
if (wholeThing) {
wholeThing.destroy();
wholeThing = null;
}
}, wholeThing);
}
else {
self.setCss(`transition: ${userOptions.animations.durationSmall}ms cubic-bezier(0.05, 0.7, 0.1, 1), opacity ${userOptions.animations.durationSmall}ms cubic-bezier(0.05, 0.7, 0.1, 1);
margin-left: ${startMargin}px;
margin-right: ${startMargin}px;
margin-bottom: unset; margin-top: unset;
opacity: 1;`);
if (widget.window)
widget.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab'));
wholeThing.attribute.dragging = false;
}
initDirX = 0;
initDirVertical = -1;
}, 'drag-end')
,
})
widget.add(notificationBox);
wholeThing.child.children = [widget];
if (isPopup) Utils.timeout(popupTimeout, () => {
if (wholeThing && !wholeThing.attribute.hovered) {
wholeThing.revealChild = false;
Utils.timeout(userOptions.animations.durationSmall, () => {
if (wholeThing) {
wholeThing.destroy();
wholeThing = null;
}
command();
}, wholeThing);
}
})
return wholeThing;
}
@@ -1,316 +0,0 @@
import App from 'resource:///com/github/Aylur/ags/app.js';
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import { MaterialIcon } from './materialicon.js';
import Bluetooth from 'resource:///com/github/Aylur/ags/service/bluetooth.js';
import Network from 'resource:///com/github/Aylur/ags/service/network.js';
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
import { languages } from './statusicons_languages.js';
// A guessing func to try to support langs not listed in data/languages.js
function isLanguageMatch(abbreviation, word) {
const lowerAbbreviation = abbreviation.toLowerCase();
const lowerWord = word.toLowerCase();
let j = 0;
for (let i = 0; i < lowerWord.length; i++) {
if (lowerWord[i] === lowerAbbreviation[j]) {
j++;
}
if (j === lowerAbbreviation.length) {
return true;
}
}
return false;
}
export const MicMuteIndicator = () => Widget.Revealer({
transition: 'slide_left',
transitionDuration: userOptions.animations.durationSmall,
revealChild: false,
setup: (self) => self.hook(Audio, (self) => {
self.revealChild = Audio.microphone?.stream?.isMuted;
}),
child: MaterialIcon('mic_off', 'norm'),
});
export const NotificationIndicator = (notifCenterName = 'sideright') => {
const widget = Widget.Revealer({
transition: 'slide_left',
transitionDuration: userOptions.animations.durationSmall,
revealChild: false,
setup: (self) => self
.hook(Notifications, (self, id) => {
if (!id || Notifications.dnd) return;
if (!Notifications.getNotification(id)) return;
self.revealChild = true;
}, 'notified')
.hook(App, (self, currentName, visible) => {
if (visible && currentName === notifCenterName) {
self.revealChild = false;
}
})
,
child: Widget.Box({
children: [
MaterialIcon('notifications', 'norm'),
Widget.Label({
className: 'txt-small titlefont',
attribute: {
unreadCount: 0,
update: (self) => self.label = `${self.attribute.unreadCount}`,
},
setup: (self) => self
.hook(Notifications, (self, id) => {
if (!id || Notifications.dnd) return;
if (!Notifications.getNotification(id)) return;
self.attribute.unreadCount++;
self.attribute.update(self);
}, 'notified')
.hook(App, (self, currentName, visible) => {
if (visible && currentName === notifCenterName) {
self.attribute.unreadCount = 0;
self.attribute.update(self);
}
})
,
})
]
})
});
return widget;
}
export const BluetoothIndicator = () => Widget.Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationSmall,
children: {
'disabled': Widget.Label({ className: 'txt-norm icon-material', label: 'bluetooth_disabled' }),
'enabled': Widget.Label({ className: 'txt-norm icon-material', label: 'bluetooth' }),
'connected': Widget.Label({ className: 'txt-norm icon-material', label: 'bluetooth_connected' }),
},
setup: (self) =>
self.hook(Bluetooth, (stack) => {
if (!Bluetooth.enabled) {
stack.shown = 'disabled';
} else if (Bluetooth.connected_devices.length === 0) {
stack.shown = 'enabled';
} else if (Bluetooth.connected_devices.length > 0) {
stack.shown = 'connected';
}
}),
});
const BluetoothDevices = () => Widget.Box({
className: 'spacing-h-5',
setup: self => self.hook(Bluetooth, self => {
self.children = Bluetooth.connected_devices.map((device) => {
return Widget.Box({
className: 'bar-bluetooth-device spacing-h-5',
vpack: 'center',
tooltipText: device.name,
children: [
Widget.Icon(`${device.iconName}-symbolic`),
...(device.batteryPercentage ? [Widget.Label({
className: 'txt-smallie',
label: `${device.batteryPercentage}`,
setup: (self) => {
self.hook(device, (self) => {
self.label = `${device.batteryPercentage}`;
}, 'notify::batteryPercentage')
}
})] : []),
]
});
});
self.visible = Bluetooth.connected_devices.length > 0;
}, 'notify::connected-devices'),
})
const NetworkWiredIndicator = () => Widget.Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationSmall,
children: {
'fallback': SimpleNetworkIndicator(),
'unknown': Widget.Label({ className: 'txt-norm icon-material', label: 'wifi_off' }),
'disconnected': Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_off' }),
'connected': Widget.Label({ className: 'txt-norm icon-material', label: 'lan' }),
'connecting': Widget.Label({ className: 'txt-norm icon-material', label: 'settings_ethernet' }),
},
setup: (self) => self.hook(Network, stack => {
if (!Network.wired)
return;
const { internet } = Network.wired;
if (['connecting', 'connected'].includes(internet))
stack.shown = internet;
else if (Network.connectivity !== 'full')
stack.shown = 'disconnected';
else
stack.shown = 'fallback';
}),
});
const SimpleNetworkIndicator = () => Widget.Icon({
setup: (self) => self.hook(Network, self => {
const icon = Network[Network.primary || 'wifi']?.iconName;
self.icon = icon || '';
self.visible = icon;
}),
});
const NetworkWifiIndicator = () => Widget.Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationSmall,
children: {
'disabled': Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_off' }),
'disconnected': Widget.Label({
className: 'txt-norm icon-material',
label: 'signal_wifi_statusbar_not_connected',
}),
'connecting': Widget.Label({ className: 'txt-norm icon-material', label: 'settings_ethernet' }),
'0': Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_0_bar' }),
'1': Widget.Label({ className: 'txt-norm icon-material', label: 'network_wifi_1_bar' }),
'2': Widget.Label({ className: 'txt-norm icon-material', label: 'network_wifi_2_bar' }),
'3': Widget.Label({ className: 'txt-norm icon-material', label: 'network_wifi_3_bar' }),
'4': Widget.Label({ className: 'txt-norm icon-material', label: 'signal_wifi_4_bar' }),
},
setup: (self) => self.hook(Network, (stack) => {
if (!Network.wifi) {
return;
}
if (!Network.wifi.enabled) {
stack.shown = 'disabled';
} else if (Network.wifi.internet == 'connected') {
stack.shown = String(Math.ceil(Network.wifi.strength / 25));
} else if (['disconnected', 'connecting'].includes(Network.wifi.internet)) {
stack.shown = Network.wifi.internet;
}
}),
});
export const NetworkIndicator = () => Widget.Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationSmall,
children: {
'fallback': SimpleNetworkIndicator(),
'wifi': NetworkWifiIndicator(),
'wired': NetworkWiredIndicator(),
},
setup: (self) => self.hook(Network, stack => {
if (!Network.primary) {
stack.shown = 'wifi';
return;
}
const primary = Network.primary || 'fallback';
if (['wifi', 'wired'].includes(primary))
stack.shown = primary;
else
stack.shown = 'fallback';
}),
});
const HyprlandXkbKeyboardLayout = async ({ useFlag } = {}) => {
try {
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
var languageStackArray = [];
const updateCurrentKeyboards = () => {
var initLangs = [];
JSON.parse(Utils.exec('hyprctl -j devices')).keyboards
.forEach(keyboard => {
initLangs.push(...keyboard.layout.split(',').map(lang => lang.trim()));
});
initLangs = [...new Set(initLangs)];
languageStackArray = Array.from({ length: initLangs.length }, (_, i) => {
const lang = languages.find(lang => lang.layout == initLangs[i]);
// if (!lang) return [
// initLangs[i],
// Widget.Label({ label: initLangs[i] })
// ];
// return [
// lang.layout,
// Widget.Label({ label: (useFlag ? lang.flag : lang.layout) })
// ];
// Object
if (!lang) return {
[initLangs[i]]: Widget.Label({ label: initLangs[i] })
};
return {
[lang.layout]: Widget.Label({ label: (useFlag ? lang.flag : lang.layout) })
};
});
};
updateCurrentKeyboards();
const widgetRevealer = Widget.Revealer({
transition: 'slide_left',
transitionDuration: userOptions.animations.durationSmall,
revealChild: languageStackArray.length > 1,
});
const widgetKids = {
...languageStackArray.reduce((obj, lang) => {
return { ...obj, ...lang };
}, {}),
'undef': Widget.Label({ label: '?' }),
}
const widgetContent = Widget.Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationSmall,
children: widgetKids,
setup: (self) => self.hook(Hyprland, (stack, kbName, layoutName) => {
if (!kbName) {
return;
}
var lang = languages.find(lang => layoutName.includes(lang.name));
if (lang) {
widgetContent.shown = lang.layout;
}
else { // Attempt to support langs not listed
lang = languageStackArray.find(lang => isLanguageMatch(lang[0], layoutName));
if (!lang) stack.shown = 'undef';
else stack.shown = lang[0];
}
}, 'keyboard-layout'),
});
widgetRevealer.child = widgetContent;
return widgetRevealer;
} catch {
return null;
}
}
const OptionalKeyboardLayout = async () => {
try {
return await HyprlandXkbKeyboardLayout({ useFlag: userOptions.appearance.keyboardUseFlag });
} catch {
return null;
}
};
const createKeyboardLayoutInstances = async () => {
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
const monitorsCount = Hyprland.monitors.length
const instances = await Promise.all(
Array.from({ length: monitorsCount }, () => OptionalKeyboardLayout())
);
return instances;
};
const optionalKeyboardLayoutInstances = await createKeyboardLayoutInstances()
export const StatusIcons = (props = {}, monitor = 0) => Widget.Box({
...props,
child: Widget.Box({
className: 'spacing-h-15',
children: [
MicMuteIndicator(),
optionalKeyboardLayoutInstances[monitor],
NotificationIndicator(),
NetworkIndicator(),
Widget.Box({
className: 'spacing-h-5',
children: [BluetoothIndicator(), BluetoothDevices()]
})
]
})
});
@@ -1,62 +0,0 @@
// For keyboard layout in statusicons.js
// This list is not exhaustive. It just includes known/possible languages of users of my dotfiles
// Add your language here if you use multi-lang xkb input. Else, ignore
// Note that something like "French (Canada)" should go before "French"
// and "English (US)" should go before "English"
export const languages = [
{
layout: 'us',
name: 'English (US)',
flag: '🇺🇸'
},
{
layout: 'ru',
name: 'Russian',
flag: '🇷🇺',
},
{
layout: 'pl',
name: 'Polish',
flag: '🇷🇵🇵🇱',
},
{
layout: 'ro',
name: 'Romanian',
flag: '🇷🇴',
},
{
layout: 'ca',
name: 'French (Canada)',
flag: '🇫🇷',
},
{
layout: 'fr',
name: 'French',
flag: '🇫🇷',
},
{
layout: 'tr',
name: 'Turkish',
flag: '🇹🇷',
},
{
layout: 'jp',
name: 'Japanese',
flag: '🇯🇵',
},
{
layout: 'cn',
name: 'Chinese',
flag: '🇨🇳',
},
{
layout: 'vn',
name: 'Vietnamese',
flag: '🇻🇳',
},
{
layout: 'undef',
name: 'Undefined',
flag: '🧐',
},
]
@@ -1,299 +0,0 @@
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Box, Button, EventBox, Label, Overlay, Stack } = Widget;
import { MaterialIcon } from './materialicon.js';
import { NavigationIndicator } from './cairo_navigationindicator.js';
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
import { DoubleRevealer } from '../.widgethacks/advancedrevealers.js';
export const TabContainer = ({
icons, names, children, initIndex = 0,
className = '', setup = () => { },
onChange = () => { },
extraTabStripWidgets = [],
...rest
}) => {
const shownIndex = Variable(initIndex);
let previousShownIndex = 0;
const count = Math.min(icons.length, names.length, children.length);
const tabs = Box({
homogeneous: true,
children: Array.from({ length: count }, (_, i) => Button({ // Tab button
className: 'tab-btn',
onClicked: () => shownIndex.value = i,
setup: setupCursorHover,
child: Box({
hpack: 'center',
vpack: 'center',
className: 'spacing-h-5 txt-small',
children: [
MaterialIcon(icons[i], 'norm'),
Label({
label: names[i],
})
]
})
})),
setup: (self) => self.hook(shownIndex, (self) => {
self.children[previousShownIndex].toggleClassName('tab-btn-active', false);
self.children[shownIndex.value].toggleClassName('tab-btn-active', true);
previousShownIndex = shownIndex.value;
}),
});
const tabIndicatorLine = Box({
vertical: true,
homogeneous: true,
setup: (self) => self.hook(shownIndex, (self) => {
self.children[0].css = `font-size: ${shownIndex.value}px;`;
}),
children: [NavigationIndicator({
className: 'tab-indicator',
count: count,
css: `font-size: ${shownIndex.value}px;`,
})],
});
const tabSection = Box({
homogeneous: true,
children: [EventBox({
onScrollUp: () => mainBox.prevTab(),
onScrollDown: () => mainBox.nextTab(),
child: Box({
className: 'spacing-h-5',
children: [
Box({
vertical: true,
hexpand: true,
children: [
tabs,
tabIndicatorLine
]
}),
...extraTabStripWidgets,
]
})
})]
});
shownIndex.setValue(initIndex)
const contentStack = Stack({
transition: 'slide_left_right',
children: children.reduce((acc, currentValue, index) => {
acc[index] = currentValue;
return acc;
}, {}),
setup: (self) => self.hook(shownIndex, (self) => {
self.shown = `${shownIndex.value}`;
}),
});
const mainBox = Box({
attribute: {
children: children,
shown: shownIndex,
names: names,
},
vertical: true,
className: `spacing-v-5 ${className}`,
setup: (self) => {
self.pack_start(tabSection, false, false, 0);
self.pack_end(contentStack, true, true, 0);
setup(self);
self.hook(shownIndex, (self) => onChange(self, shownIndex.value));
},
...rest,
});
mainBox.nextTab = () => shownIndex.value = Math.min(shownIndex.value + 1, count - 1);
mainBox.prevTab = () => shownIndex.value = Math.max(shownIndex.value - 1, 0);
mainBox.cycleTab = () => shownIndex.value = (shownIndex.value + 1) % count;
return mainBox;
}
export const IconTabContainer = ({
iconWidgets, names, children, className = '',
initIndex = 0,
setup = () => { }, onChange = () => { },
tabsHpack = 'center', tabSwitcherClassName = '',
...rest
}) => {
const shownIndex = Variable(initIndex);
let previousShownIndex = 0;
const count = Math.min(iconWidgets.length, names.length, children.length);
const tabs = Box({
hpack: tabsHpack,
className: `spacing-h-5 ${tabSwitcherClassName}`,
children: iconWidgets.map((icon, i) => Button({
className: 'tab-icon',
tooltipText: names[i],
child: icon,
setup: setupCursorHover,
onClicked: () => shownIndex.value = i,
})),
setup: (self) => self.hook(shownIndex, (self) => {
self.children[previousShownIndex].toggleClassName('tab-icon-active', false);
self.children[shownIndex.value].toggleClassName('tab-icon-active', true);
previousShownIndex = shownIndex.value;
}),
});
const tabSection = Box({
homogeneous: true,
children: [EventBox({
onScrollUp: () => mainBox.prevTab(),
onScrollDown: () => mainBox.nextTab(),
child: Box({
vertical: true,
hexpand: true,
children: [
tabs,
]
})
})]
});
const contentStack = Stack({
transition: 'slide_left_right',
children: children.reduce((acc, currentValue, index) => {
acc[index] = currentValue;
return acc;
}, {}),
setup: (self) => self.hook(shownIndex, (self) => {
self.shown = `${shownIndex.value}`;
}),
});
const mainBox = Box({
attribute: {
children: children,
shown: shownIndex,
names: names,
},
vertical: true,
className: `spacing-v-5 ${className}`,
setup: (self) => {
self.pack_start(tabSection, false, false, 0);
self.pack_end(contentStack, true, true, 0);
setup(self);
self.hook(shownIndex, (self) => onChange(self, shownIndex.value));
},
...rest,
});
mainBox.nextTab = () => shownIndex.value = Math.min(shownIndex.value + 1, count - 1);
mainBox.prevTab = () => shownIndex.value = Math.max(shownIndex.value - 1, 0);
mainBox.cycleTab = () => shownIndex.value = (shownIndex.value + 1) % count;
mainBox.shown = shownIndex;
return mainBox;
}
export const ExpandingIconTabContainer = ({
icons, names, children, className = '',
setup = () => { }, onChange = () => { },
tabsHpack = 'center', tabSwitcherClassName = '',
transitionDuration = userOptions.animations.durationLarge,
...rest
}) => {
const shownIndex = Variable(0);
let previousShownIndex = 0;
const count = Math.min(icons.length, names.length, children.length);
const tabs = Box({
hpack: tabsHpack,
className: `spacing-h-5 ${tabSwitcherClassName}`,
children: icons.map((icon, i) => {
const tabIcon = MaterialIcon(icon, 'norm', { hexpand: true });
const tabName = DoubleRevealer({
transition1: 'slide_right',
transition2: 'crossfade',
duration1: 0,
duration2: 0,
// duration1: userOptions.animations.durationSmall,
// duration2: userOptions.animations.durationSmall,
child: Label({
className: 'margin-left-5 txt-small',
label: names[i],
}),
revealChild: i === shownIndex.value,
})
const button = Button({
className: 'tab-icon-expandable',
tooltipText: names[i],
child: Box({
homogeneous: true,
children: [Box({
hpack: 'center',
children: [
tabIcon,
tabName,
]
})],
}),
setup: setupCursorHover,
onClicked: () => shownIndex.value = i,
});
button.toggleFocus = (value) => {
tabIcon.hexpand = !value;
button.toggleClassName('tab-icon-expandable-active', value);
tabName.toggleRevealChild(value);
}
return button;
}),
setup: (self) => self.hook(shownIndex, (self) => {
self.children[previousShownIndex].toggleFocus(false);
self.children[shownIndex.value].toggleFocus(true);
previousShownIndex = shownIndex.value;
}),
});
const tabSection = Box({
homogeneous: true,
children: [EventBox({
onScrollUp: () => mainBox.prevTab(),
onScrollDown: () => mainBox.nextTab(),
child: Box({
vertical: true,
hexpand: true,
children: [
tabs,
]
})
})]
});
const contentStack = Stack({
transition: 'slide_left_right',
transitionDuration: transitionDuration,
children: children.reduce((acc, currentValue, index) => {
acc[index] = currentValue;
return acc;
}, {}),
setup: (self) => self.hook(shownIndex, (self) => {
self.shown = `${shownIndex.value}`;
}),
});
const mainBox = Box({
attribute: {
children: children,
shown: shownIndex,
names: names,
},
vertical: true,
className: `spacing-v-5 ${className}`,
setup: (self) => {
self.pack_start(tabSection, false, false, 0);
self.pack_end(contentStack, true, true, 0);
setup(self);
self.hook(shownIndex, (self) => onChange(self, shownIndex.value));
},
...rest,
});
mainBox.nextTab = () => shownIndex.value = Math.min(shownIndex.value + 1, count - 1);
mainBox.prevTab = () => shownIndex.value = Math.max(shownIndex.value - 1, 0);
mainBox.cycleTab = () => shownIndex.value = (shownIndex.value + 1) % count;
mainBox.focusName = (name) => {
const focusIndex = names.indexOf(name);
if (focusIndex !== -1) {
shownIndex.value = focusIndex;
}
}
mainBox.shown = shownIndex;
return mainBox;
}
@@ -1,290 +0,0 @@
// This file is parsed with a custom JSONC parser.
// Don't expect every JSONC feature in... say, vscode, to work.
{
// General stuff
"ai": {
"defaultGPTProvider": "ollama_llama_3_2",
"defaultTemperature": 0.5,
"enhancements": true,
"charsEachUpdate": 50, // Lower = smoother update rate, but more update lag
"keep_alive": -1, // For ollama. -1 means forever
"useHistory": false,
"safety": true,
"writingCursor": " ...", // Warning: Using weird characters can mess up Markdown rendering
"proxyUrl": null, // Can be "socks5://127.0.0.1:9050" or "http://127.0.0.1:8080" for example. Leave it blank if you don't need it.
"extraGptModels": {
// Below is an example. Copy to user_options.jsonc and edit it
// The base url is conveniently ollama's btw
// "model_id": {
// "name": "User-added model",
// "logo_name": "ollama-symbolic",
// "description": "A model added by the user",
// "base_url": "http://localhost:11434/v1/chat/completions",
// "key_get_url": "",
// "requires_key": false,
// "key_file": "api_key_file.txt",
// "model": "model-name"
// },
}
},
"animations": {
"choreographyDelay": 35,
"durationSmall": 110,
"durationLarge": 180
},
"appearance": {
"autoDarkMode": { // Turns on dark mode in certain hours. Time in 24h format
"enabled": false,
"from": "18:10",
"to": "6:10"
},
"borderless": false, // Uhm experimental...
"keyboardUseFlag": false, // Use flag emoji instead of abbreviation letters
"layerSmoke": false,
"layerSmokeStrength": 0.2,
"barRoundCorners": 1, // 0: No, 1: Yes
"fakeScreenRounding": 2 // 0: None | 1: Always | 2: When not fullscreen
},
"apps": {
"bluetooth": "blueberry",
"imageViewer": "loupe",
"network": "XDG_CURRENT_DESKTOP=\"gnome\" gnome-control-center wifi",
"settings": "XDG_CURRENT_DESKTOP=\"gnome\" gnome-control-center",
"taskManager": "gnome-usage",
"terminal": "foot" // This is only for shell actions
},
"bar": {
// Whether to show Swap and CPU usage when there's media. RAM is always shown.
"alwaysShowFullResources": false,
// Array of bar modes for each monitor. Hit Ctrl+Alt+Slash to cycle.
// Modes: "normal", "focus" (workspace indicator only), "nothing"
// Example for four monitors: ["normal", "focus", "normal", "nothing"]
"modes": [
"normal"
]
},
"battery": {
"low": 20,
"critical": 10,
"warnLevels": [
20,
15,
5
],
"warnTitles": [
"Low battery",
"Very low battery",
"Critical Battery"
],
"warnMessages": [
"Plug in the charger",
"You there?",
"PLUG THE CHARGER ALREADY"
],
"suspendThreshold": 3
},
"brightness": {
// Object of controller names for each monitor, either "brightnessctl" or "ddcutil" or "auto"
// "default" one will be used if unspecified
// Examples
// "eDP-1": "brightnessctl",
// "DP-1": "ddcutil",
"controllers": {
"default": "auto"
}
},
"cheatsheet": {
"keybinds": {
"configPath": "" // Path to hyprland keybind config file. Leave empty for default (~/.config/hypr/hyprland/keybinds.conf)
}
},
"gaming": {
"crosshair": {
"size": 20,
"color": "rgba(113,227,32,0.9)"
}
},
"i18n": {
"langCode": "", //Customize the locale, such as zh_CN,Optional value references "~/.config/ags/i18n/locales/"
"extraLogs": false
},
"monitors": {
"scaleMethod": "division" // Either "division" [default] or "gdk"
},
"music": {
"preferredPlayer": "plasma-browser-integration"
},
"onScreenKeyboard": {
"layout": "qwerty_full" // See modules/onscreenkeyboard/onscreenkeyboard.js for available layouts
},
"overview": {
"scale": 0.18, // Relative to screen size
"numOfRows": 2,
"numOfCols": 5,
"wsNumScale": 0.09,
"wsNumMarginScale": 0.07
},
"sidebar": {
"image": {
"columns": 2,
"batchCount": 20,
"allowNsfw": false
},
"pages": {
"order": [
"apis",
"tools"
],
"defaultPage": "apis",
"apis": {
"order": [
"gemini",
"gpt",
"waifu",
"booru"
],
"defaultPage": "gemini"
}
},
"quickToggles": {
"order": [
"wifi",
"bluetooth",
"nightlight",
"gamemode",
"idleinhibitor",
"cloudflarewarp"
]
},
"calendar": {
"expandByDefault": true
}
},
"search": {
"enableFeatures": {
"actions": true,
"commands": true,
"mathResults": true,
"directorySearch": true,
"aiSearch": true,
"webSearch": true
},
"engineBaseUrl": "https://www.google.com/search?q=",
"excludedSites": [
"quora.com"
]
},
"time": {
// See https://docs.gtk.org/glib/method.DateTime.format.html
// Here's the 12h format: "%I:%M%P"
// For seconds, add "%S" and set interval to 1000
"format": "%H:%M",
"interval": 5000,
"dateFormatLong": "%A, %d/%m", // On bar
"dateInterval": 5000,
"dateFormat": "%d/%m", // On notif time
"calendarDateFormat": "%d %B %Y"
},
"weather": {
"city": "",
"preferredUnit": "C" // Either C or F
},
"workspaces": {
"shown": 10
},
"dock": {
"enabled": false,
"hiddenThickness": 5,
"pinnedApps": [
"firefox",
"org.gnome.Nautilus"
],
"layer": "top",
"monitorExclusivity": true, // Dock will move to other monitor along with focus if enabled
"searchPinnedAppIcons": false, // Try to search for the correct icon if the app class isn't an icon name
"trigger": [
"client-added",
"client-removed"
], // client_added, client_move, workspace_active, client_active
// Automatically hide dock after `interval` ms since trigger
"autoHide": [
{
"trigger": "client-added",
"interval": 500
},
{
"trigger": "client-removed",
"interval": 500
}
]
},
// Longer stuff
"icons": {
// Find the window's icon by its class with levenshteinDistance
// The file names are processed at startup, so if there
// are too many files in the search path it'll affect performance
// Example: ["/usr/share/icons/Tela-nord/scalable/apps"]
"searchPaths": [
""
],
"symbolicIconTheme": {
"dark": "Adwaita",
"light": "Adwaita"
},
"substitutions": {
"code-url-handler": "visual-studio-code",
"Code": "visual-studio-code",
"GitHub Desktop": "github-desktop",
"Minecraft* 1.20.1": "minecraft",
"gnome-tweaks": "org.gnome.tweaks",
"pavucontrol-qt": "pavucontrol",
"wps": "wps-office2019-kprometheus",
"wpsoffice": "wps-office2019-kprometheus",
"footclient": "foot",
"zen": "zen-browser",
"": "image-missing"
},
"regexSubstitutions": [
{
"regex": "/^steam_app_(\\d+)$/",
"replace": "steam_icon_$1"
}
]
},
"keybinds": {
// Format: "Modifier_1+...+Modifier_n+key". The key is CaSe SeNsItIvE!
// Modifiers: Shift Ctrl Alt Hyper Meta
// See https://docs.gtk.org/gdk3/index.html#constants for keys (listed as KEY_key)
// You can assign multiple keybinds for the same action. Just split them with a comma
// Example: "Ctrl+Page_Down, ctrl+Tab"
"overview": {
"altMoveLeft": "Ctrl+B",
"altMoveRight": "Ctrl+F",
"deleteToEnd": "Ctrl+K"
},
"sidebar": {
"apis": {
"nextTab": "Page_Down",
"prevTab": "Page_Up"
},
"options": { // Right sidebar
"nextTab": "Page_Down",
"prevTab": "Page_Up"
},
"expand": "Ctrl+E",
"pin": "Ctrl+P",
"cycleTab": "Ctrl+Tab",
"nextTab": "Ctrl+Page_Down",
"prevTab": "Ctrl+Page_Up"
},
"cheatsheet": {
"keybinds": {
"nextTab": "Page_Down",
"prevTab": "Page_Up"
},
"nextTab": "Ctrl+Page_Down",
"prevTab": "Ctrl+Page_Up",
"cycleTab": "Ctrl+Tab"
}
}
}
@@ -1,36 +0,0 @@
import App from 'resource:///com/github/Aylur/ags/app.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
import { parseJSONC } from '../.miscutils/jsonc.js';
function overrideConfigRecursive(userOverrides, configOptions = {}) {
for (const [key, value] of Object.entries(userOverrides)) {
if (typeof value === 'object'
&& !(value instanceof Array)
&& configOptions[key]) {
overrideConfigRecursive(value, configOptions[key]);
}
else {
configOptions[key] = value;
}
}
}
// Load default options from ~/.config/ags/modules/.configuration/default_options.jsonc
const defaultConfigFile = `${App.configDir}/modules/.configuration/default_options.jsonc`;
const defaultConfigFileContents = Utils.readFile(defaultConfigFile);
const defaultConfigOptions = parseJSONC(defaultConfigFileContents);
// Clone the default config to avoid modifying the original
let configOptions = JSON.parse(JSON.stringify(defaultConfigOptions));
// Load user overrides
const userOverrideFile = `${App.configDir}/user_options.jsonc`;
const userOverrideContents = Utils.readFile(userOverrideFile);
const userOverrides = parseJSONC(userOverrideContents);
// Override defaults with user's options
overrideConfigRecursive(userOverrides, configOptions);
globalThis['userOptionsDefaults'] = defaultConfigOptions;
globalThis['userOptions'] = configOptions;
export default configOptions;
-14
View File
@@ -1,14 +0,0 @@
const { Gio, GLib, Gtk } = imports.gi;
export function fileExists(filePath) {
let file = Gio.File.new_for_path(filePath);
return file.query_exists(null);
}
export function expandTilde(path) {
if (path.startsWith('~')) {
return GLib.get_home_dir() + path.slice(1);
} else {
return path;
}
}
-28
View File
@@ -1,28 +0,0 @@
const { Gtk } = imports.gi;
export function iconExists(iconName) {
let iconTheme = Gtk.IconTheme.get_default();
return iconTheme.has_icon(iconName);
}
export function substitute(str) {
// Normal substitutions
if (userOptions.icons.substitutions[str])
return userOptions.icons.substitutions[str];
// Regex substitutions
for (let i = 0; i < userOptions.icons.regexSubstitutions.length; i++) {
const substitution = userOptions.icons.regexSubstitutions[i];
const replacedName = str.replace(
substitution.regex,
substitution.replace,
);
if (replacedName != str) return replacedName;
}
// Guess: convert to kebab case
if (!iconExists(str)) str = str.toLowerCase().replace(/\s+/g, "-");
// Original string
return str;
}
-58
View File
@@ -1,58 +0,0 @@
export function parseJSONC(jsoncString) {
let result = "";
let inString = false;
let inSingleQuote = false;
let inMultiLineComment = false;
let inSingleLineComment = false;
for (let i = 0; i < jsoncString.length; i++) {
let char = jsoncString[i];
let nextChar = jsoncString[i + 1];
// Handle string start/end
if (!inSingleLineComment && !inMultiLineComment) {
if (char === '"' && !inSingleQuote) {
inString = !inString;
} else if (char === "'" && !inString) {
inSingleQuote = !inSingleQuote;
}
}
// Handle single-line comments //
if (!inString && !inSingleQuote && !inMultiLineComment && char === '/' && nextChar === '/') {
inSingleLineComment = true;
i++; // Skip next '/'
continue;
}
// Handle multi-line comments /*
if (!inString && !inSingleQuote && !inSingleLineComment && char === '/' && nextChar === '*') {
inMultiLineComment = true;
i++; // Skip next '*'
continue;
}
// End single-line comment at newline
if (inSingleLineComment && (char === '\n' || char === '\r')) {
inSingleLineComment = false;
}
// End multi-line comment */
if (inMultiLineComment && char === '*' && nextChar === '/') {
inMultiLineComment = false;
i++; // Skip next '/'
continue;
}
// Only append characters if not inside a comment
if (!inSingleLineComment && !inMultiLineComment) {
result += char;
}
}
// Remove trailing commas from objects and arrays
result = result.replace(/,\s*([\]}])/g, '$1');
// Parse as JSON
return JSON.parse(result);
}
@@ -1,16 +0,0 @@
export function clamp(x, min, max) {
return Math.min(Math.max(x, min), max);
}
export function truncateToPrecision(value, precision) {
const factor = Math.pow(10, precision);
const result = Math.round(value * factor) / factor;
return result;
}
export function distance(x1, y1, x2, y2) {
const distanceX = Math.abs(x1 - x2);
const distanceY = Math.abs(y1 - y2);
return Math.sqrt(distanceX * distanceX + distanceY * distanceY)
}
@@ -1,98 +0,0 @@
// Converts from Markdown to Pango. This does not support code blocks.
// For illogical-impulse, code blocks are treated separately, in their own GtkSourceView widgets.
// Partly inherited from https://github.com/ubunatic/md2pango
const monospaceFonts = 'JetBrains Mono NF, JetBrains Mono Nerd Font, JetBrains Mono NL, SpaceMono NF, SpaceMono Nerd Font, monospace';
const codeBlockRegex = /^\s*```([a-zA-Z0-9]+)?\n?/;
const replacements = {
'indents': [
{ name: 'BULLET', re: /^(\s*)([\*\-]\s)(.*)(\s*)$/, sub: ' $1- $3' },
{ name: 'NUMBERING', re: /^(\s*[0-9]+\.\s)(.*)(\s*)$/, sub: ' $1 $2' },
],
'escapes': [
{ name: 'COMMENT', re: /<!--[\s\S]*?-->/, sub: '' },
{ name: 'AMPERSTAND', re: /&/g, sub: '&amp;' },
{ name: 'LESSTHAN', re: /</g, sub: '&lt;' },
{ name: 'GREATERTHAN', re: />/g, sub: '&gt;' },
],
'sections': [
{ name: 'H1', re: /^(#\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="170%">$2</span>' },
{ name: 'H2', re: /^(##\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="150%">$2</span>' },
{ name: 'H3', re: /^(###\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="125%">$2</span>' },
{ name: 'H4', re: /^(####\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="100%">$2</span>' },
{ name: 'H5', re: /^(#####\s+)(.*)(\s*)$/, sub: '<span font_weight="bold" size="90%">$2</span>' },
],
'styles': [
{ name: 'BOLD', re: /(\*\*)(\S[\s\S]*?\S)(\*\*)/g, sub: "<b>$2</b>" },
{ name: 'UND', re: /(__)(\S[\s\S]*?\S)(__)/g, sub: "<u>$2</u>" },
{ name: 'EMPH', re: /\*(\S.*?\S)\*/g, sub: "<i>$1</i>" },
// { name: 'EMPH', re: /_(\S.*?\S)_/g, sub: "<i>$1</i>" },
{ name: 'HEXCOLOR', re: /#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/g, sub: '<span bgcolor="#$1" fgcolor="#000000" font_family="' + monospaceFonts + '">#$1</span>' },
{ name: 'INLCODE', re: /(`)([^`]*)(`)/g, sub: '<span font_weight="bold" font_family="' + monospaceFonts + '">$2</span>' },
// { name: 'UND', re: /(__|\*\*)(\S[\s\S]*?\S)(__|\*\*)/g, sub: "<u>$2</u>" },
],
'forceLatex': [
{ name: 'LATEX_INLINE_SQUARE', re: /\\\[(.*?)\\\]/g, sub: '\n```latex\n$1\n```' },
{ name: 'LATEX_INLINE_ROUND', re: /\\\((.*?)\\\)/g, sub: '\n```latex\n$1\n```' },
{ name: 'LATEX_INLINE_DOLLAR', re: /\$(.*?)\$/g, sub: '\n```latex\n$1\n```' }
]
}
const replaceCategory = (text, replaces) => {
for (const type of replaces) {
text = text.replace(type.re, type.sub);
}
return text;
}
// Main function
export function replaceInlineLatexWithCodeBlocks(text) {
return text.replace(/\\\[(.*?)\\\]|\\\((.*?)\\\)|\$\$(.*?)\$\$|(?:^|[^\w])\$(.*?[^\\])\$(?!\w)/gs, (match, square, round, double, single) => {
const latex = square || round || double || single;
return `\n\`\`\`latex\n${latex}\n\`\`\`\n`;
});
}
export default (text) => {
let lines = text.split('\n')
let output = [];
let inCode = false;
// Replace
for (const line of lines) {
let result = line;
if (codeBlockRegex.test(line)) inCode = !inCode;
if (inCode) continue;
result = replaceCategory(result, replacements.indents);
result = replaceCategory(result, replacements.escapes);
result = replaceCategory(result, replacements.sections);
result = replaceCategory(result, replacements.styles);
output.push(result)
}
// Remove trailing whitespaces
output = output.map(line => line.replace(/ +$/, ''))
return output.join('\n');
}
export const markdownTest = `## Inline formatting
- **Bold** *Italics* __Underline__
- \`Monospace text\` 🤓
- Colors
- Nvidia green #7ABB08
- Soundcloud orange #FF5500
## Code block
\`\`\`cpp
#include <bits/stdc++.h>
const std::string GREETING = "UwU";
int main(int argc, char* argv[]) {
std::cout << GREETING;
}
\`\`\`
## LaTeX
- Inline LaTeX: \\[ \\frac{d}{dx} \\left( \\frac{x-438}{x^2+23x-7} \\right) = \\frac{-x^2 + 869}{(x^2+23x-7)^2} \\]
- Block LaTeX:
\`\`\`latex
\\frac{d}{dx} \\left( \\frac{x-438}{x^2+23x-7} \\right) = \\frac{-x^2 + 869}{(x^2+23x-7)^2} \\\\\\\\ cos(2x) = 2cos^2(x) - 1 = 1 - 2sin^2(x) = cos^2(x) - sin^2(x)
\`\`\`
`;
-33
View File
@@ -1,33 +0,0 @@
export function getNestedProperty(obj, path) {
return path.split('.').reduce((current, key) => {
return (current && typeof current === 'object' && current.hasOwnProperty(key)) ? current[key] : undefined;
}, obj);
}
export function updateNestedProperty(obj, path, newValue) {
const pathArray = path.split('.');
const lastKeyIndex = pathArray.length - 1;
let current = obj;
for (let i = 0; i < lastKeyIndex; i++) {
const key = pathArray[i];
if (!current || typeof current !== 'object') {
return false; // Previous part of path is not an object
}
if (!current.hasOwnProperty(key)) {
current[key] = {}; // Create the missing object
}
current = current[key];
}
const lastKey = pathArray[lastKeyIndex];
if (!current || typeof current !== 'object') {
return false; // Parent is not an object
}
current[lastKey] = newValue;
return true;
}
-61
View File
@@ -1,61 +0,0 @@
const { GLib } = imports.gi;
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
export const distroID = exec(`bash -c 'cat /etc/os-release | grep "^ID=" | cut -d "=" -f 2 | sed "s/\\"//g"'`).trim();
export const isDebianDistro = (distroID == 'linuxmint' || distroID == 'ubuntu' || distroID == 'debian' || distroID == 'zorin' || distroID == 'popos' || distroID == 'raspbian' || distroID == 'kali');
export const isArchDistro = (distroID == 'arch' || distroID == 'endeavouros' || distroID == 'cachyos');
export const hasFlatpak = !!exec(`bash -c 'command -v flatpak'`);
const LIGHTDARK_FILE_LOCATION = `${GLib.get_user_state_dir()}/ags/user/colormode.txt`;
export const darkMode = Variable(!(Utils.readFile(LIGHTDARK_FILE_LOCATION).split('\n')[0].trim() == 'light'));
darkMode.connect('changed', ({ value }) => {
let lightdark = value ? "dark" : "light";
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_state_dir()}/ags/user && sed -i "1s/.*/${lightdark}/" ${GLib.get_user_state_dir()}/ags/user/colormode.txt`])
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`]))
.then(execAsync(['bash', '-c', `command -v darkman && darkman set ${lightdark}`])) // Optional darkman integration
.catch(print);
});
globalThis['darkMode'] = darkMode;
export const hasPlasmaIntegration = !!Utils.exec('bash -c "command -v plasma-browser-integration-host"');
export const getDistroIcon = () => {
// Arches
if(distroID == 'arch') return 'arch-symbolic';
if(distroID == 'endeavouros') return 'endeavouros-symbolic';
if(distroID == 'cachyos') return 'cachyos-symbolic';
// Funny flake
if(distroID == 'nixos') return 'nixos-symbolic';
// Cool thing
if(distroID == 'fedora') return 'fedora-symbolic';
// Debians
if(distroID == 'linuxmint') return 'ubuntu-symbolic';
if(distroID == 'ubuntu') return 'ubuntu-symbolic';
if(distroID == 'debian') return 'debian-symbolic';
if(distroID == 'zorin') return 'ubuntu-symbolic';
if(distroID == 'popos') return 'ubuntu-symbolic';
if(distroID == 'raspbian') return 'debian-symbolic';
if(distroID == 'kali') return 'debian-symbolic';
return 'linux-symbolic';
}
export const getDistroName = () => {
// Arches
if(distroID == 'arch') return 'Arch Linux';
if(distroID == 'endeavouros') return 'EndeavourOS';
if(distroID == 'cachyos') return 'CachyOS';
// Funny flake
if(distroID == 'nixos') return 'NixOS';
// Cool thing
if(distroID == 'fedora') return 'Fedora';
// Debians
if(distroID == 'linuxmint') return 'Linux Mint';
if(distroID == 'ubuntu') return 'Ubuntu';
if(distroID == 'debian') return 'Debian';
if(distroID == 'zorin') return 'Zorin';
if(distroID == 'popos') return 'Pop!_OS';
if(distroID == 'raspbian') return 'Raspbian';
if(distroID == 'kali') return 'Kali Linux';
return 'Linux';
}
@@ -1,86 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Revealer, Scrollable } = Widget;
export const MarginRevealer = ({
transition = 'slide_down',
child,
revealChild,
showClass = 'element-show', // These are for animation curve, they don't really hide
hideClass = 'element-hide', // Don't put margins in these classes!
extraSetup = () => { },
...rest
}) => {
const widget = Scrollable({
...rest,
attribute: {
'revealChild': true, // It'll be set to false after init if it's supposed to hide
'transition': transition,
'show': () => {
if (widget.attribute.revealChild) return;
widget.hscroll = 'never';
widget.vscroll = 'never';
child.toggleClassName(hideClass, false);
child.toggleClassName(showClass, true);
widget.attribute.revealChild = true;
child.css = 'margin: 0px;';
},
'hide': () => {
if (!widget.attribute.revealChild) return;
child.toggleClassName(hideClass, true);
child.toggleClassName(showClass, false);
widget.attribute.revealChild = false;
if (widget.attribute.transition == 'slide_left')
child.css = `margin-right: -${child.get_allocated_width()}px;`;
else if (widget.attribute.transition == 'slide_right')
child.css = `margin-left: -${child.get_allocated_width()}px;`;
else if (widget.attribute.transition == 'slide_up')
child.css = `margin-bottom: -${child.get_allocated_height()}px;`;
else if (widget.attribute.transition == 'slide_down')
child.css = `margin-top: -${child.get_allocated_height()}px;`;
},
'toggle': () => {
if (widget.attribute.revealChild) widget.attribute.hide();
else widget.attribute.show();
},
},
child: child,
hscroll: `${revealChild ? 'never' : 'always'}`,
vscroll: `${revealChild ? 'never' : 'always'}`,
setup: (self) => {
extraSetup(self);
}
});
child.toggleClassName(`${revealChild ? showClass : hideClass}`, true);
return widget;
}
// TODO: Allow reveal update. Currently this just helps at declaration
export const DoubleRevealer = ({
transition1 = 'slide_right',
transition2 = 'slide_left',
duration1 = 150,
duration2 = 150,
child,
revealChild,
...rest
}) => {
const r2 = Revealer({
transition: transition2,
transitionDuration: duration2,
revealChild: revealChild,
child: child,
});
const r1 = Revealer({
transition: transition1,
transitionDuration: duration1,
revealChild: revealChild,
child: r2,
...rest,
})
r1.toggleRevealChild = (value) => {
r1.revealChild = value;
r2.revealChild = value;
}
return r1;
}
@@ -1,36 +0,0 @@
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Box, Window } = Widget;
export default ({
name,
child,
showClassName = "",
hideClassName = "",
...props
}) => {
return Window({
name,
visible: false,
layer: 'top',
...props,
child: Box({
setup: (self) => {
self.keybind("Escape", () => closeEverything());
if (showClassName != "" && hideClassName !== "") {
self.hook(App, (self, currentName, visible) => {
if (currentName === name) {
self.toggleClassName(hideClassName, !visible);
}
});
if (showClassName !== "" && hideClassName !== "")
self.className = `${showClassName} ${hideClassName}`;
}
},
child: child,
}),
});
}
@@ -1,4 +0,0 @@
import Cairo from 'gi://cairo?version=1.0';
export const dummyRegion = new Cairo.Region();
export const enableClickthrough = (self) => self.input_shape_combine_region(dummyRegion);
@@ -1,36 +0,0 @@
// Cursor names reference: https://docs.gtk.org/gdk4/ctor.Cursor.new_from_name.html
const { Gdk } = imports.gi;
export function setupCursorHover(button, cursorName = 'pointer') { // Hand pointing cursor on hover
const display = Gdk.Display.get_default();
button.connect('enter-notify-event', () => {
const cursor = Gdk.Cursor.new_from_name(display, cursorName);
button.get_window().set_cursor(cursor);
});
button.connect('leave-notify-event', () => {
const cursor = Gdk.Cursor.new_from_name(display, 'default');
button.get_window().set_cursor(cursor);
});
}
export function setupCursorHoverAim(button) { // Crosshair cursor on hover
setupCursorHover(button, 'crosshair');
}
export function setupCursorHoverGrab(button) { // Hand ready to grab on hover
setupCursorHover(button, 'grab');
}
export function setupCursorHoverInfo(button) { // "?" mark cursor on hover
setupCursorHover(button, 'help');
}
export function setupCursorHoverHResize(button) { // Resize left right
setupCursorHover(button, 'ew-resize');
}
export function setupCursorHoverVResize(button) { // Resize up down
setupCursorHover(button, 'ns-resize');
}
@@ -1,34 +0,0 @@
const { Gdk } = imports.gi;
const MODS = {
'shift': Gdk.ModifierType.SHIFT_MASK,
'ctrl': Gdk.ModifierType.CONTROL_MASK,
'alt': Gdk.ModifierType.ALT_MASK,
'hyper': Gdk.ModifierType.HYPER_MASK,
'meta': Gdk.ModifierType.META_MASK
}
const checkSingleKeybind = (event, keybind) => {
const pressedModMask = event.get_state()[1];
const pressedKey = event.get_keyval()[1];
const keys = keybind.split('+');
for (let i = 0; i < keys.length; i++) {
if (keys[i].toLowerCase() in MODS) {
if (!(pressedModMask & MODS[keys[i].toLowerCase()])) {
return false;
}
} else if (pressedKey !== Gdk[`KEY_${keys[i]}`] && pressedKey !== Gdk[`KEY_${keys[i].toLowerCase()}`]) {
return false;
}
}
return true;
}
export const checkKeybind = (event, keybind) => {
const keybinds = keybind.replace(' ', '').split(',');
for (let i = 0; i < keybinds.length; i++) {
if (checkSingleKeybind(event, keybinds[i])) {
return true;
}
}
}
@@ -1,213 +0,0 @@
const { GLib, Gdk, Gtk } = imports.gi;
const Lang = imports.lang;
const Cairo = imports.cairo;
const Pango = imports.gi.Pango;
const PangoCairo = imports.gi.PangoCairo;
import App from 'resource:///com/github/Aylur/ags/app.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Box, DrawingArea, EventBox } = Widget;
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
const dummyWs = Box({ className: 'bar-ws-focus' }); // Not shown. Only for getting size props
const dummyActiveWs = Box({ className: 'bar-ws-focus bar-ws-focus-active' }); // Not shown. Only for getting size props
const dummyOccupiedWs = Box({ className: 'bar-ws-focus bar-ws-focus-occupied' }); // Not shown. Only for getting size props
const WS_TAKEN_WIDTH_MULTIPLIER = 1.4;
const floor = Math.floor;
const ceil = Math.ceil;
// Font size = workspace id
const WorkspaceContents = (count = 10) => {
return DrawingArea({
className: 'menu-decel',
attribute: {
lastImmediateActiveWs: 0,
immediateActiveWs: 0,
initialized: false,
workspaceMask: 0,
workspaceGroup: 0,
updateMask: (self) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
// if (self.attribute.initialized) return; // We only need this to run once
const workspaces = Hyprland.workspaces;
let workspaceMask = 0;
for (let i = 0; i < workspaces.length; i++) {
const ws = workspaces[i];
if (ws.id <= offset || ws.id > offset + count) continue; // Out of range, ignore
if (workspaces[i].windows > 0)
workspaceMask |= (1 << (ws.id - offset));
}
// console.log('Mask:', workspaceMask.toString(2));
self.attribute.workspaceMask = workspaceMask;
// self.attribute.initialized = true;
self.queue_draw();
},
toggleMask: (self, occupied, name) => {
if (occupied) self.attribute.workspaceMask |= (1 << parseInt(name));
else self.attribute.workspaceMask &= ~(1 << parseInt(name));
self.queue_draw();
},
},
setup: (area) => area
.hook(Hyprland.active.workspace, (self) => {
const newActiveWs = (Hyprland.active.workspace.id - 1) % count + 1;
self.setCss(`font-size: ${newActiveWs}px;`);
self.attribute.lastImmediateActiveWs = self.attribute.immediateActiveWs;
self.attribute.immediateActiveWs = newActiveWs;
const previousGroup = self.attribute.workspaceGroup;
const currentGroup = Math.floor((Hyprland.active.workspace.id - 1) / count);
if (currentGroup !== previousGroup) {
self.attribute.updateMask(self);
self.attribute.workspaceGroup = currentGroup;
}
})
.hook(Hyprland, (self) => self.attribute.updateMask(self), 'notify::workspaces')
.on('draw', Lang.bind(area, (area, cr) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
const allocation = area.get_allocation();
const { width, height } = allocation;
const workspaceStyleContext = dummyWs.get_style_context();
const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const workspaceRadius = workspaceDiameter / 2;
const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context();
const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const activeWorkspaceStyleContext = dummyActiveWs.get_style_context();
const activeWorkspaceWidth = activeWorkspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
// const activeWorkspaceWidth = 100;
const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const widgetStyleContext = area.get_style_context();
const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
const lastImmediateActiveWs = area.attribute.lastImmediateActiveWs;
const immediateActiveWs = area.attribute.immediateActiveWs;
// Draw
area.set_size_request(workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * (count - 1) + activeWorkspaceWidth, -1);
for (let i = 1; i <= count; i++) {
if (i == immediateActiveWs) continue;
let colors = {};
if (area.attribute.workspaceMask & (1 << i)) colors = occupiedbg;
else colors = wsbg;
// if ((i == immediateActiveWs + 1 && immediateActiveWs < activeWs) ||
// (i == immediateActiveWs + 1 && immediateActiveWs < activeWs)) {
// const widthPercentage = (i == immediateActiveWs - 1) ?
// 1 - (immediateActiveWs - activeWs) :
// activeWs - immediateActiveWs;
// cr.setSourceRGBA(colors.red * widthPercentage + activebg.red * (1 - widthPercentage),
// colors.green * widthPercentage + activebg.green * (1 - widthPercentage),
// colors.blue * widthPercentage + activebg.blue * (1 - widthPercentage),
// colors.alpha);
// }
// else
cr.setSourceRGBA(colors.red, colors.green, colors.blue, colors.alpha)
const centerX = (i <= activeWs) ?
(-workspaceRadius + (workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * i))
: -workspaceRadius + workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * (count - 1) + activeWorkspaceWidth - ((count - i) * workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER);
cr.arc(centerX, height / 2, workspaceRadius, 0, 2 * Math.PI);
cr.fill();
// What if shrinking
if (i == floor(activeWs) && immediateActiveWs > activeWs) { // To right
const widthPercentage = 1 - (ceil(activeWs) - activeWs);
const leftX = centerX;
const wsWidth = (activeWorkspaceWidth - (workspaceDiameter * 1.5)) * (1 - widthPercentage);
cr.rectangle(leftX, height / 2 - workspaceRadius, wsWidth, workspaceDiameter);
cr.fill();
cr.arc(leftX + wsWidth, height / 2, workspaceRadius, 0, Math.PI * 2);
cr.fill();
}
else if (i == ceil(activeWs) && immediateActiveWs < activeWs) { // To left
const widthPercentage = activeWs - floor(activeWs);
const rightX = centerX;
const wsWidth = (activeWorkspaceWidth - (workspaceDiameter * 1.5)) * widthPercentage;
const leftX = rightX - wsWidth;
cr.rectangle(leftX, height / 2 - workspaceRadius, wsWidth, workspaceDiameter);
cr.fill();
cr.arc(leftX, height / 2, workspaceRadius, 0, Math.PI * 2);
cr.fill();
}
}
let widthPercentage, leftX, rightX, activeWsWidth;
cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha);
if (immediateActiveWs > activeWs) { // To right
const immediateActiveWs = ceil(activeWs);
widthPercentage = immediateActiveWs - activeWs;
rightX = -workspaceRadius + workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * (count - 1) + activeWorkspaceWidth - ((count - immediateActiveWs) * workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER);
activeWsWidth = (activeWorkspaceWidth - (workspaceDiameter * 1.5)) * (1 - widthPercentage);
leftX = rightX - activeWsWidth;
cr.arc(leftX, height / 2, workspaceRadius, 0, Math.PI * 2); // Should be 0.5 * Math.PI, 1.5 * Math.PI in theory but it leaves a weird 1px gap
cr.fill();
cr.rectangle(leftX, height / 2 - workspaceRadius, activeWsWidth, workspaceDiameter);
cr.fill();
cr.arc(leftX + activeWsWidth, height / 2, workspaceRadius, 0, Math.PI * 2);
cr.fill();
}
else { // To left
const immediateActiveWs = floor(activeWs);
widthPercentage = 1 - (activeWs - immediateActiveWs);
leftX = -workspaceRadius + (workspaceDiameter * WS_TAKEN_WIDTH_MULTIPLIER * immediateActiveWs);
activeWsWidth = (activeWorkspaceWidth - (workspaceDiameter * 1.5)) * widthPercentage
cr.arc(leftX, height / 2, workspaceRadius, 0, Math.PI * 2); // Should be 0.5 * Math.PI, 1.5 * Math.PI in theory but it leaves a weird 1px gap
cr.fill();
cr.rectangle(leftX, height / 2 - workspaceRadius, activeWsWidth, workspaceDiameter);
cr.fill();
cr.arc(leftX + activeWsWidth, height / 2, workspaceRadius, 0, Math.PI * 2);
cr.fill();
}
}))
,
})
}
export default () => EventBox({
onScrollUp: () => Hyprland.messageAsync(`dispatch workspace r-1`).catch(print),
onScrollDown: () => Hyprland.messageAsync(`dispatch workspace r+1`).catch(print),
onMiddleClick: () => toggleWindowOnAllMonitors('osk'),
onSecondaryClick: () => App.toggleWindow('overview'),
attribute: {
clicked: false,
ws_group: 0,
},
child: Box({
homogeneous: true,
// className: 'bar-group-margin',
children: [Box({
// className: `bar-group${userOptions.appearance.borderless ? '-borderless' : ''} bar-group-standalone bar-group-pad`,
css: 'min-width: 2px;',
children: [WorkspaceContents(userOptions.workspaces.shown)],
})]
}),
setup: (self) => {
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
self.on('motion-notify-event', (self, event) => {
if (!self.attribute.clicked) return;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
.catch(print);
})
self.on('button-press-event', (self, event) => {
if (!(event.get_button()[1] === 1)) return; // We're only interested in left-click here
self.attribute.clicked = true;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
// const wsId = Math.ceil(cursorX * NUM_OF_WORKSPACES_PER_GROUP / widgetWidth) + self.attribute.ws_group * NUM_OF_WORKSPACES_PER_GROUP;
// Hyprland.messageAsync(`dispatch workspace ${wsId}`).catch(print);
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
.catch(print);
})
self.on('button-release-event', (self) => self.attribute.clicked = false);
}
})
@@ -1,183 +0,0 @@
const { GLib, Gdk, Gtk } = imports.gi;
const Lang = imports.lang;
const Cairo = imports.cairo;
const Pango = imports.gi.Pango;
const PangoCairo = imports.gi.PangoCairo;
import Widget from "resource:///com/github/Aylur/ags/widget.js";
import Sway from "../../../services/sway.js";
import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
const { execAsync, exec } = Utils;
const { Box, DrawingArea, EventBox } = Widget;
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props
const dummyActiveWs = Box({ className: 'bar-ws bar-ws-active' }); // Not shown. Only for getting size props
const dummyOccupiedWs = Box({ className: 'bar-ws bar-ws-occupied' }); // Not shown. Only for getting size props
const switchToWorkspace = (arg) => Utils.execAsync(`swaymsg workspace ${arg}`).catch(print);
const switchToRelativeWorkspace = (self, num) =>
execAsync([`${App.configDir}/scripts/sway/swayToRelativeWs.sh`, `${num}`]).catch(print);
const WorkspaceContents = (count = 10) => {
return DrawingArea({
css: `transition: 90ms cubic-bezier(0.1, 1, 0, 1);`,
attribute: {
initialized: false,
workspaceMask: 0,
updateMask: (self) => {
if (self.attribute.initialized) return; // We only need this to run once
const workspaces = Sway.workspaces;
let workspaceMask = 0;
// console.log('----------------')
for (let i = 0; i < workspaces.length; i++) {
const ws = workspaces[i];
// console.log(ws.name, ',', ws.num);
if (!Number(ws.name)) return;
const id = Number(ws.name);
if (id <= 0) continue; // Ignore scratchpads
if (id > count) return; // Not rendered
if (workspaces[i].windows > 0) {
workspaceMask |= (1 << id);
}
}
self.attribute.workspaceMask = workspaceMask;
self.attribute.initialized = true;
},
toggleMask: (self, occupied, name) => {
if (occupied) self.attribute.workspaceMask |= (1 << parseInt(name));
else self.attribute.workspaceMask &= ~(1 << parseInt(name));
},
},
setup: (area) => area
.hook(Sway.active.workspace, (area) => {
area.setCss(`font-size: ${Sway.active.workspace.name}px;`)
})
.hook(Sway, (self) => self.attribute.updateMask(self), 'notify::workspaces')
// .hook(Hyprland, (self, name) => self.attribute.toggleMask(self, true, name), 'workspace-added')
// .hook(Hyprland, (self, name) => self.attribute.toggleMask(self, false, name), 'workspace-removed')
.on('draw', Lang.bind(area, (area, cr) => {
const allocation = area.get_allocation();
const { width, height } = allocation;
const workspaceStyleContext = dummyWs.get_style_context();
const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const workspaceRadius = workspaceDiameter / 2;
const workspaceFontSize = workspaceStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 4 * 3;
const workspaceFontFamily = workspaceStyleContext.get_property('font-family', Gtk.StateFlags.NORMAL);
const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const wsfg = workspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context();
const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const occupiedfg = occupiedWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
const activeWorkspaceStyleContext = dummyActiveWs.get_style_context();
const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const activefg = activeWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
area.set_size_request(workspaceDiameter * count, -1);
const widgetStyleContext = area.get_style_context();
const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
const activeWsCenterX = -(workspaceDiameter / 2) + (workspaceDiameter * activeWs);
const activeWsCenterY = height / 2;
// Font
const layout = PangoCairo.create_layout(cr);
const fontDesc = Pango.font_description_from_string(`${workspaceFontFamily[0]} ${workspaceFontSize}`);
layout.set_font_description(fontDesc);
cr.setAntialias(Cairo.Antialias.BEST);
// Get kinda min radius for number indicators
layout.set_text("0".repeat(count.toString().length), -1);
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
const indicatorRadius = Math.max(layoutWidth, layoutHeight) / 2 * 1.2; // a bit smaller than sqrt(2)*radius
const indicatorGap = workspaceRadius - indicatorRadius;
// Draw workspace numbers
for (let i = 1; i <= count; i++) {
if (area.attribute.workspaceMask & (1 << i)) {
// Draw bg highlight
cr.setSourceRGBA(occupiedbg.red, occupiedbg.green, occupiedbg.blue, occupiedbg.alpha);
const wsCenterX = -(workspaceRadius) + (workspaceDiameter * i);
const wsCenterY = height / 2;
if (!(area.attribute.workspaceMask & (1 << (i - 1)))) { // Left
cr.arc(wsCenterX, wsCenterY, workspaceRadius, 0.5 * Math.PI, 1.5 * Math.PI);
cr.fill();
}
else {
cr.rectangle(wsCenterX - workspaceRadius, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
if (!(area.attribute.workspaceMask & (1 << (i + 1)))) { // Right
cr.arc(wsCenterX, wsCenterY, workspaceRadius, -0.5 * Math.PI, 0.5 * Math.PI);
cr.fill();
}
else {
cr.rectangle(wsCenterX, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
// Set color for text
cr.setSourceRGBA(occupiedfg.red, occupiedfg.green, occupiedfg.blue, occupiedfg.alpha);
}
else
cr.setSourceRGBA(wsfg.red, wsfg.green, wsfg.blue, wsfg.alpha);
layout.set_text(`${i}`, -1);
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
const x = -workspaceRadius + (workspaceDiameter * i) - (layoutWidth / 2);
const y = (height - layoutHeight) / 2;
cr.moveTo(x, y);
// cr.showText(text);
PangoCairo.show_layout(cr, layout);
cr.stroke();
}
// Draw active ws
// base
cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha);
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius, 0, 2 * Math.PI);
cr.fill();
// inner decor
cr.setSourceRGBA(activefg.red, activefg.green, activefg.blue, activefg.alpha);
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius * 0.2, 0, 2 * Math.PI);
cr.fill();
}))
,
})
}
export default () => EventBox({
onScrollUp: (self) => switchToRelativeWorkspace(self, -1),
onScrollDown: (self) => switchToRelativeWorkspace(self, +1),
onMiddleClick: () => toggleWindowOnAllMonitors('osk'),
onSecondaryClick: () => App.toggleWindow('overview'),
attribute: { clicked: false },
child: Box({
homogeneous: true,
className: 'bar-group-margin',
children: [Box({
className: `bar-group${userOptions.appearance.borderless ? '-borderless' : ''} bar-group-standalone bar-group-pad`,
css: 'min-width: 2px;',
children: [
WorkspaceContents(10),
]
})]
}),
setup: (self) => {
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
self.on('motion-notify-event', (self, event) => {
if (!self.attribute.clicked) return;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
switchToWorkspace(wsId);
})
self.on('button-press-event', (self, event) => {
if (!(event.get_button()[1] === 1)) return; // We're only interested in left-click here
self.attribute.clicked = true;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
switchToWorkspace(wsId);
})
self.on('button-release-event', (self) => self.attribute.clicked = false);
}
});
-129
View File
@@ -1,129 +0,0 @@
const { Gtk } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Battery from 'resource:///com/github/Aylur/ags/service/battery.js';
import WindowTitle from "./normal/spaceleft.js";
import Indicators from "./normal/spaceright.js";
import Music from "./normal/music.js";
import System from "./normal/system.js";
import { enableClickthrough } from "../.widgetutils/clickthrough.js";
import { RoundedCorner } from "../.commonwidgets/cairo_roundedcorner.js";
import { currentShellMode } from '../../variables.js';
const NormalOptionalWorkspaces = async () => {
try {
return (await import('./normal/workspaces_hyprland.js')).default();
} catch {
try {
return (await import('./normal/workspaces_sway.js')).default();
} catch {
return null;
}
}
};
const FocusOptionalWorkspaces = async () => {
try {
return (await import('./focus/workspaces_hyprland.js')).default();
} catch {
try {
return (await import('./focus/workspaces_sway.js')).default();
} catch {
return null;
}
}
};
export const Bar = async (monitor = 0) => {
const SideModule = (children) => Widget.Box({
className: 'bar-sidemodule',
children: children,
});
const normalBarContent = Widget.CenterBox({
className: 'bar-bg',
setup: (self) => {
const styleContext = self.get_style_context();
const minHeight = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
// execAsync(['bash', '-c', `hyprctl keyword monitor ,addreserved,${minHeight},0,0,0`]).catch(print);
},
startWidget: (await WindowTitle(monitor)),
centerWidget: Widget.Box({
className: 'spacing-h-4',
children: [
SideModule([Music()]),
Widget.Box({
homogeneous: true,
children: [await NormalOptionalWorkspaces()],
}),
SideModule([System()]),
]
}),
endWidget: Indicators(monitor),
});
const focusedBarContent = Widget.CenterBox({
className: 'bar-bg-focus',
startWidget: Widget.Box({}),
centerWidget: Widget.Box({
className: 'spacing-h-4',
children: [
SideModule([]),
Widget.Box({
homogeneous: true,
children: [await FocusOptionalWorkspaces()],
}),
SideModule([]),
]
}),
endWidget: Widget.Box({}),
setup: (self) => {
self.hook(Battery, (self) => {
if (!Battery.available) return;
self.toggleClassName('bar-bg-focus-batterylow', Battery.percent <= userOptions.battery.low);
})
}
});
const nothingContent = Widget.Box({
className: 'bar-bg-nothing',
})
return Widget.Window({
monitor,
name: `bar${monitor}`,
anchor: ['top', 'left', 'right'],
exclusivity: 'exclusive',
visible: true,
child: Widget.Stack({
homogeneous: false,
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationLarge,
children: {
'normal': normalBarContent,
'focus': focusedBarContent,
'nothing': nothingContent,
},
setup: (self) => self.hook(currentShellMode, (self) => {
self.shown = currentShellMode.value[monitor];
})
}),
});
}
export const BarCornerTopleft = (monitor = 0) => Widget.Window({
monitor,
name: `barcornertl${monitor}`,
layer: 'top',
anchor: ['top', 'left'],
exclusivity: 'normal',
visible: true,
child: RoundedCorner('topleft', { className: 'corner', }),
setup: enableClickthrough,
});
export const BarCornerTopright = (monitor = 0) => Widget.Window({
monitor,
name: `barcornertr${monitor}`,
layer: 'top',
anchor: ['top', 'right'],
exclusivity: 'normal',
visible: true,
child: RoundedCorner('topright', { className: 'corner', }),
setup: enableClickthrough,
});
-241
View File
@@ -1,241 +0,0 @@
const { GLib } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js';
const { Box, Button, EventBox, Label, Overlay, Revealer, Scrollable } = Widget;
const { execAsync, exec } = Utils;
import { AnimatedCircProg } from "../../.commonwidgets/cairo_circularprogress.js";
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { showMusicControls } from '../../../variables.js';
const CUSTOM_MODULE_CONTENT_INTERVAL_FILE = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-interval.txt`;
const CUSTOM_MODULE_CONTENT_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-poll.sh`;
const CUSTOM_MODULE_LEFTCLICK_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-leftclick.sh`;
const CUSTOM_MODULE_RIGHTCLICK_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-rightclick.sh`;
const CUSTOM_MODULE_MIDDLECLICK_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-middleclick.sh`;
const CUSTOM_MODULE_SCROLLUP_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-scrollup.sh`;
const CUSTOM_MODULE_SCROLLDOWN_SCRIPT = `${GLib.get_user_cache_dir()}/ags/user/scripts/custom-module-scrolldown.sh`;
function trimTrackTitle(title) {
if (!title) return '';
const cleanPatterns = [
/【[^】]*】/, // Touhou n weeb stuff
" [FREE DOWNLOAD]", // F-777
];
cleanPatterns.forEach((expr) => title = title.replace(expr, ''));
return title;
}
function adjustVolume(direction) {
const step = 0.1; // We use a larger step because this is player instance volume, not global
const mpris = Mpris.getPlayer('');
mpris.volume += (direction === 'up') ? step : -step
}
const BarGroup = ({ child }) => Box({
className: 'bar-group-margin bar-sides',
children: [
Box({
className: `bar-group${userOptions.appearance.borderless ? '-borderless' : ''} bar-group-standalone bar-group-pad-system`,
children: [child],
}),
]
});
const BarResource = (name, icon, command, circprogClassName = `bar-batt-circprog ${userOptions.appearance.borderless ? 'bar-batt-circprog-borderless' : ''}`, textClassName = 'txt-onSurfaceVariant', iconClassName = 'bar-batt') => {
const resourceCircProg = AnimatedCircProg({
className: `${circprogClassName}`,
vpack: 'center',
hpack: 'center',
});
const resourceProgress = Box({
homogeneous: true,
children: [Overlay({
child: Box({
vpack: 'center',
className: `${iconClassName}`,
homogeneous: true,
children: [
MaterialIcon(icon, 'small'),
],
}),
overlays: [resourceCircProg]
})]
});
const resourceLabel = Label({
className: `txt-smallie ${textClassName}`,
});
const widget = Button({
onClicked: () => Utils.execAsync(['bash', '-c', `${userOptions.apps.taskManager}`]).catch(print),
child: Box({
className: `spacing-h-4 ${textClassName}`,
children: [
resourceProgress,
resourceLabel,
],
setup: (self) => self.poll(5000, () => execAsync(['bash', '-c', command])
.then((output) => {
resourceCircProg.css = `font-size: ${Number(output)}px;`;
resourceLabel.label = `${Math.round(Number(output))}%`;
widget.tooltipText = `${name}: ${Math.round(Number(output))}%`;
}).catch(print))
,
})
});
return widget;
}
const TrackProgress = () => {
const _updateProgress = (circprog) => {
const mpris = Mpris.getPlayer('');
if (!mpris)
circprog.css = `font-size: ${userOptions.appearance.borderless ? 100 : 0}px;`
else // Set circular progress value
circprog.css = `font-size: ${Math.max(mpris.position / mpris.length * 100, 0)}px;`
}
return AnimatedCircProg({
className: `bar-music-circprog ${userOptions.appearance.borderless ? 'bar-music-circprog-borderless' : ''}`,
vpack: 'center', hpack: 'center',
extraSetup: (self) => self
.hook(Mpris, _updateProgress)
.poll(3000, _updateProgress)
,
})
}
const switchToRelativeWorkspace = async (self, num) => {
try {
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
Hyprland.messageAsync(`dispatch workspace ${num > 0 ? '+' : ''}${num}`).catch(print);
} catch {
execAsync([`${App.configDir}/scripts/sway/swayToRelativeWs.sh`, `${num}`]).catch(print);
}
}
export default () => {
// TODO: use cairo to make button bounce smaller on click, if that's possible
const playingState = Box({ // Wrap a box cuz overlay can't have margins itself
homogeneous: true,
children: [Overlay({
child: Box({
vpack: 'center',
className: 'bar-music-playstate',
homogeneous: true,
children: [Label({
vpack: 'center',
className: 'bar-music-playstate-txt',
justification: 'center',
setup: (self) => self.hook(Mpris, label => {
const mpris = Mpris.getPlayer('');
label.label = `${mpris !== null && mpris.playBackStatus == 'Playing' ? 'pause' : 'play_arrow'}`;
}),
})],
setup: (self) => self.hook(Mpris, label => {
const mpris = Mpris.getPlayer('');
if (!mpris) return;
label.toggleClassName('bar-music-playstate-playing', mpris !== null && mpris.playBackStatus == 'Playing');
label.toggleClassName('bar-music-playstate', mpris !== null || mpris.playBackStatus == 'Paused');
}),
}),
overlays: [
TrackProgress(),
]
})]
});
const trackTitle = Label({
hexpand: true,
className: 'txt-smallie bar-music-txt',
truncate: 'end',
maxWidthChars: 1, // Doesn't matter, just needs to be non negative
setup: (self) => self.hook(Mpris, label => {
const mpris = Mpris.getPlayer('');
if (mpris)
label.label = `${trimTrackTitle(mpris.trackTitle)}${mpris.trackArtists.join(', ')}`;
else
label.label = getString('No media');
}),
})
const musicStuff = Box({
className: 'spacing-h-10',
hexpand: true,
children: [
playingState,
trackTitle,
]
})
const SystemResourcesOrCustomModule = () => {
// Check if $XDG_CACHE_HOME/ags/user/scripts/custom-module-poll.sh exists
if (GLib.file_test(CUSTOM_MODULE_CONTENT_SCRIPT, GLib.FileTest.EXISTS)) {
const interval = Number(Utils.readFile(CUSTOM_MODULE_CONTENT_INTERVAL_FILE)) || 5000;
return BarGroup({
child: Button({
child: Label({
className: 'txt-smallie txt-onSurfaceVariant',
useMarkup: true,
setup: (self) => Utils.timeout(1, () => {
self.label = exec(CUSTOM_MODULE_CONTENT_SCRIPT);
self.poll(interval, (self) => {
const content = exec(CUSTOM_MODULE_CONTENT_SCRIPT);
self.label = content;
})
})
}),
onPrimaryClickRelease: () => execAsync(CUSTOM_MODULE_LEFTCLICK_SCRIPT).catch(print),
onSecondaryClickRelease: () => execAsync(CUSTOM_MODULE_RIGHTCLICK_SCRIPT).catch(print),
onMiddleClickRelease: () => execAsync(CUSTOM_MODULE_MIDDLECLICK_SCRIPT).catch(print),
onScrollUp: () => execAsync(CUSTOM_MODULE_SCROLLUP_SCRIPT).catch(print),
onScrollDown: () => execAsync(CUSTOM_MODULE_SCROLLDOWN_SCRIPT).catch(print),
})
});
} else return BarGroup({
child: Box({
children: [
BarResource(getString('RAM Usage'), 'memory', `LANG=C free | awk '/^Mem/ {printf("%.2f\\n", ($3/$2) * 100)}'`,
`bar-ram-circprog ${userOptions.appearance.borderless ? 'bar-ram-circprog-borderless' : ''}`, 'bar-ram-txt', 'bar-ram-icon'),
Revealer({
revealChild: true,
transition: 'slide_left',
transitionDuration: userOptions.animations.durationLarge,
child: Box({
className: 'spacing-h-10 margin-left-10',
children: [
BarResource(getString('Swap Usage'), 'swap_horiz', `LANG=C free | awk '/^Swap/ {if ($2 > 0) printf("%.2f\\n", ($3/$2) * 100); else print "0";}'`,
`bar-swap-circprog ${userOptions.appearance.borderless ? 'bar-swap-circprog-borderless' : ''}`, 'bar-swap-txt', 'bar-swap-icon'),
BarResource(getString('CPU Usage'), 'settings_motion_mode', `LANG=C top -bn1 | grep Cpu | sed 's/\\,/\\./g' | awk '{print $2}'`,
`bar-cpu-circprog ${userOptions.appearance.borderless ? 'bar-cpu-circprog-borderless' : ''}`, 'bar-cpu-txt', 'bar-cpu-icon'),
]
}),
setup: (self) => self.hook(Mpris, label => {
const mpris = Mpris.getPlayer('');
self.revealChild = (!mpris || mpris.playBackStatus !== 'Playing' || userOptions.bar.alwaysShowFullResources);
}),
})
],
})
});
}
return EventBox({
onScrollUp: () => adjustVolume('up'),
onScrollDown: () => adjustVolume('down'),
child: Box({
className: 'spacing-h-4',
children: [
SystemResourcesOrCustomModule(),
EventBox({
child: BarGroup({ child: musicStuff }),
onPrimaryClick: () => showMusicControls.setValue(!showMusicControls.value),
onSecondaryClick: () => execAsync(['bash', '-c', 'playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` &']).catch(print),
onMiddleClick: () => execAsync('playerctl play-pause').catch(print),
setup: (self) => self.on('button-press-event', (self, event) => {
if (event.get_button()[1] === 8) // Side button
execAsync('playerctl previous').catch(print)
}),
})
]
})
});
}
@@ -1,96 +0,0 @@
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Brightness from '../../../services/brightness.js';
import Indicator from '../../../services/indicator.js';
import { distance } from '../../.miscutils/mathfuncs.js';
const OSD_DISMISS_DISTANCE = 10;
const WindowTitle = async () => {
try {
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
return Widget.Scrollable({
hexpand: true, vexpand: true,
hscroll: 'automatic', vscroll: 'never',
child: Widget.Box({
vertical: true,
children: [
Widget.Label({
xalign: 0,
truncate: 'end',
maxWidthChars: 1, // Doesn't matter, just needs to be non negative
className: 'txt-smaller bar-wintitle-topdesc txt',
setup: (self) => self.hook(Hyprland.active.client, label => { // Hyprland.active.client
label.label = Hyprland.active.client.class.length === 0 ? 'Desktop' : Hyprland.active.client.class;
}),
}),
Widget.Label({
xalign: 0,
truncate: 'end',
maxWidthChars: 1, // Doesn't matter, just needs to be non negative
className: 'txt-smallie bar-wintitle-txt',
setup: (self) => {
self.hook(Hyprland.active.client, label => { // Hyprland.active.client
label.label = Hyprland.active.client.title.length === 0 ? `Workspace ${Hyprland.active.workspace.id}` : Hyprland.active.client.title;
});
self.hook(Hyprland.active.workspace, label => { // Hyprland.active.client
label.label = Hyprland.active.client.title.length === 0 ? `Workspace ${Hyprland.active.workspace.id}` : Hyprland.active.client.title;
});
}
})
]
})
});
} catch {
return null;
}
}
export default async (monitor = 0) => {
const optionalWindowTitleInstance = await WindowTitle();
let scrollCursorX, scrollCursorY;
return Widget.EventBox({
onScrollUp: (self, event) => {
let _;
[_, scrollCursorX, scrollCursorY] = event.get_coords();
Indicator.popup(1); // Since the brightness and speaker are both on the same window
Brightness[monitor].screen_value += 0.05;
},
onScrollDown: (self, event) => {
let _;
[_, scrollCursorX, scrollCursorY] = event.get_coords();
Indicator.popup(1); // Since the brightness and speaker are both on the same window
Brightness[monitor].screen_value -= 0.05;
},
onPrimaryClick: () => {
App.toggleWindow('sideleft');
},
setup: (self) => self.on('motion-notify-event', (self, event) => {
const [_, cursorX, cursorY] = event.get_coords();
if (distance(cursorX, cursorY, scrollCursorX, scrollCursorY) >= OSD_DISMISS_DISTANCE)
Indicator.popup(-1);
}),
child: Widget.Box({
homogeneous: false,
children: [
Widget.Box({ className: 'bar-corner-spacing' }),
Widget.Overlay({
overlays: [
Widget.Box({ hexpand: true }),
Widget.Box({
className: 'bar-sidemodule', hexpand: true,
children: [Widget.Box({
vertical: true,
className: 'bar-space-button',
children: [
optionalWindowTitleInstance,
]
})]
}),
]
})
]
})
});
}
@@ -1,106 +0,0 @@
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
import SystemTray from 'resource:///com/github/Aylur/ags/service/systemtray.js';
const { execAsync } = Utils;
import Indicator from '../../../services/indicator.js';
import { StatusIcons } from '../../.commonwidgets/statusicons.js';
import { Tray } from "./tray.js";
import { distance } from '../../.miscutils/mathfuncs.js';
const OSD_DISMISS_DISTANCE = 10;
const SeparatorDot = () => Widget.Revealer({
transition: 'slide_left',
revealChild: false,
attribute: {
'count': SystemTray.items.length,
'update': (self, diff) => {
self.attribute.count += diff;
self.revealChild = (self.attribute.count > 0);
}
},
child: Widget.Box({
vpack: 'center',
className: 'separator-circle',
}),
setup: (self) => self
.hook(SystemTray, (self) => self.attribute.update(self, 1), 'added')
.hook(SystemTray, (self) => self.attribute.update(self, -1), 'removed')
,
});
export default (monitor = 0) => {
const barTray = Tray();
const barStatusIcons = StatusIcons({
className: 'bar-statusicons',
setup: (self) => self.hook(App, (self, currentName, visible) => {
if (currentName === 'sideright') {
self.toggleClassName('bar-statusicons-active', visible);
}
}),
}, monitor);
const SpaceRightInteractions = (child) => Widget.EventBox({
onHover: () => { barStatusIcons.toggleClassName('bar-statusicons-hover', true) },
onHoverLost: () => { barStatusIcons.toggleClassName('bar-statusicons-hover', false) },
onPrimaryClick: () => App.toggleWindow('sideright'),
onSecondaryClick: () => execAsync(['bash', '-c', 'playerctl next || playerctl position `bc <<< "100 * $(playerctl metadata mpris:length) / 1000000 / 100"` &']).catch(print),
onMiddleClick: () => execAsync('playerctl play-pause').catch(print),
setup: (self) => self.on('button-press-event', (self, event) => {
if (event.get_button()[1] === 8)
execAsync('playerctl previous').catch(print)
}).on('motion-notify-event', (self, event) => {
Indicator.popup(-1);
}),
child: child,
});
const emptyArea = SpaceRightInteractions(Widget.Box({ hexpand: true, }));
const indicatorArea = SpaceRightInteractions(Widget.Box({
children: [
SeparatorDot(),
barStatusIcons
],
}));
const actualContent = Widget.Box({
hexpand: true,
className: 'spacing-h-5 bar-spaceright',
children: [
emptyArea,
barTray,
indicatorArea
],
});
let scrollCursorX, scrollCursorY;
return Widget.EventBox({
onScrollUp: (self, event) => {
if (!Audio.speaker) return;
let _;
[_, scrollCursorX, scrollCursorY] = event.get_coords();
if (Audio.speaker.volume <= 0.09) Audio.speaker.volume += 0.01;
else Audio.speaker.volume += 0.03;
Indicator.popup(1);
},
onScrollDown: (self, event) => {
if (!Audio.speaker) return;
let _;
[_, scrollCursorX, scrollCursorY] = event.get_coords();
if (Audio.speaker.volume <= 0.09) Audio.speaker.volume -= 0.01;
else Audio.speaker.volume -= 0.03;
Indicator.popup(1);
},
setup: (self) => self.on('motion-notify-event', (self, event) => {
const [_, cursorX, cursorY] = event.get_coords();
if (distance(cursorX, cursorY, scrollCursorX, scrollCursorY) >= OSD_DISMISS_DISTANCE)
Indicator.popup(-1);
}),
child: Widget.Box({
children: [
actualContent,
SpaceRightInteractions(Widget.Box({ className: 'bar-corner-spacing' })),
]
})
});
}
-238
View File
@@ -1,238 +0,0 @@
// This is for the right pills of the bar.
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { Box, Label, Button, Overlay, Revealer, Scrollable, Stack, EventBox } = Widget;
const { exec, execAsync } = Utils;
const { GLib } = imports.gi;
import Battery from 'resource:///com/github/Aylur/ags/service/battery.js';
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
import { AnimatedCircProg } from "../../.commonwidgets/cairo_circularprogress.js";
import { WWO_CODE, WEATHER_SYMBOL, NIGHT_WEATHER_SYMBOL } from '../../.commondata/weather.js';
import { setupCursorHover } from '../../.widgetutils/cursorhover.js';
const WEATHER_CACHE_FOLDER = `${GLib.get_user_cache_dir()}/ags/weather`;
Utils.exec(`mkdir -p ${WEATHER_CACHE_FOLDER}`);
const BarBatteryProgress = () => {
const _updateProgress = (circprog) => { // Set circular progress value
circprog.css = `font-size: ${Math.abs(Battery.percent)}px;`
circprog.toggleClassName('bar-batt-circprog-low', Battery.percent <= userOptions.battery.low);
circprog.toggleClassName('bar-batt-circprog-full', Battery.charged);
}
return AnimatedCircProg({
className: `bar-batt-circprog ${userOptions.appearance.borderless ? 'bar-batt-circprog-borderless' : ''}`,
vpack: 'center', hpack: 'center',
extraSetup: (self) => self
.hook(Battery, _updateProgress)
,
})
}
const time = Variable('', {
poll: [
userOptions.time.interval,
() => GLib.DateTime.new_now_local().format(userOptions.time.format),
],
})
const date = Variable('', {
poll: [
userOptions.time.dateInterval,
() => GLib.DateTime.new_now_local().format(userOptions.time.dateFormatLong),
],
})
const BarClock = () => Widget.Box({
vpack: 'center',
className: 'spacing-h-4 bar-clock-box',
children: [
Widget.Label({
className: 'bar-time',
label: time.bind(),
}),
Widget.Label({
className: 'txt-norm txt-onLayer1',
label: '•',
}),
Widget.Label({
className: 'txt-smallie bar-date',
label: date.bind(),
}),
],
});
const UtilButton = ({ name, icon, onClicked }) => Button({
vpack: 'center',
tooltipText: name,
onClicked: onClicked,
className: `bar-util-btn ${userOptions.appearance.borderless ? 'bar-util-btn-borderless' : ''} icon-material txt-norm`,
label: `${icon}`,
setup: setupCursorHover
})
const Utilities = () => Box({
hpack: 'center',
className: 'spacing-h-4',
children: [
UtilButton({
name: getString('Screen snip'), icon: 'screenshot_region', onClicked: () => {
Utils.execAsync(`${App.configDir}/scripts/grimblast.sh copy area`)
.catch(print)
}
}),
UtilButton({
name: getString('Color picker'), icon: 'colorize', onClicked: () => {
Utils.execAsync(['hyprpicker', '-a']).catch(print)
}
}),
UtilButton({
name: getString('Toggle on-screen keyboard'), icon: 'keyboard', onClicked: () => {
toggleWindowOnAllMonitors('osk');
}
}),
]
})
const BarBattery = () => Box({
className: 'spacing-h-4 bar-batt-txt',
children: [
Revealer({
transitionDuration: userOptions.animations.durationSmall,
revealChild: false,
transition: 'slide_right',
child: MaterialIcon('bolt', 'norm', { tooltipText: "Charging" }),
setup: (self) => self.hook(Battery, revealer => {
self.revealChild = Battery.charging;
}),
}),
Label({
className: 'txt-smallie',
setup: (self) => self.hook(Battery, label => {
label.label = `${Number.parseFloat(Battery.percent.toFixed(1))}%`;
}),
}),
Overlay({
child: Widget.Box({
vpack: 'center',
className: 'bar-batt',
homogeneous: true,
children: [
MaterialIcon('battery_full', 'small'),
],
setup: (self) => self.hook(Battery, box => {
box.toggleClassName('bar-batt-low', Battery.percent <= userOptions.battery.low);
box.toggleClassName('bar-batt-full', Battery.charged);
}),
}),
overlays: [
BarBatteryProgress(),
]
}),
]
});
const BarGroup = ({ child }) => Widget.Box({
className: 'bar-group-margin bar-sides',
children: [
Widget.Box({
className: `bar-group${userOptions.appearance.borderless ? '-borderless' : ''} bar-group-standalone bar-group-pad-system`,
children: [child],
}),
]
});
const BatteryModule = () => Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationLarge,
children: {
'laptop': Box({
className: 'spacing-h-4', children: [
BarGroup({ child: Utilities() }),
BarGroup({ child: BarBattery() }),
]
}),
'desktop': BarGroup({
child: Box({
hexpand: true,
hpack: 'center',
className: 'spacing-h-4 txt-onSurfaceVariant',
children: [
MaterialIcon('device_thermostat', 'small'),
Label({
label: 'Weather',
})
],
setup: (self) => self.poll(900000, async (self) => {
const WEATHER_CACHE_PATH = WEATHER_CACHE_FOLDER + '/wttr.in.txt';
const updateWeatherForCity = (city) => execAsync(`curl https://wttr.in/${city.replace(/ /g, '%20')}?format=j1`)
.then(output => {
const weather = JSON.parse(output);
Utils.writeFile(JSON.stringify(weather), WEATHER_CACHE_PATH)
.catch(print);
const weatherCode = weather.current_condition[0].weatherCode;
const weatherDesc = weather.current_condition[0].weatherDesc[0].value;
const temperature = weather.current_condition[0][`temp_${userOptions.weather.preferredUnit}`];
const feelsLike = weather.current_condition[0][`FeelsLike${userOptions.weather.preferredUnit}`];
const weatherSymbol = WEATHER_SYMBOL[WWO_CODE[weatherCode]];
self.children[0].label = weatherSymbol;
self.children[1].label = `${temperature}°${userOptions.weather.preferredUnit}${getString('Feels like')} ${feelsLike}°${userOptions.weather.preferredUnit}`;
self.tooltipText = weatherDesc;
}).catch((err) => {
try { // Read from cache
const weather = JSON.parse(
Utils.readFile(WEATHER_CACHE_PATH)
);
const weatherCode = weather.current_condition[0].weatherCode;
const weatherDesc = weather.current_condition[0].weatherDesc[0].value;
const temperature = weather.current_condition[0][`temp_${userOptions.weather.preferredUnit}`];
const feelsLike = weather.current_condition[0][`FeelsLike${userOptions.weather.preferredUnit}`];
const weatherSymbol = WEATHER_SYMBOL[WWO_CODE[weatherCode]];
self.children[0].label = weatherSymbol;
self.children[1].label = `${temperature}°${userOptions.weather.preferredUnit}${getString('Feels like')} ${feelsLike}°${userOptions.weather.preferredUnit}`;
self.tooltipText = weatherDesc;
} catch (err) {
print(err);
}
});
if (userOptions.weather.city != '' && userOptions.weather.city != null) {
updateWeatherForCity(userOptions.weather.city.replace(/ /g, '%20'));
}
else {
Utils.execAsync('curl ipinfo.io')
.then(output => {
return JSON.parse(output)['city'].toLowerCase();
})
.then(updateWeatherForCity)
.catch(print)
}
}),
})
}),
},
setup: (stack) => Utils.timeout(10, () => {
if (!Battery.available) stack.shown = 'desktop';
else stack.shown = 'laptop';
})
})
const switchToRelativeWorkspace = async (self, num) => {
try {
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
Hyprland.messageAsync(`dispatch workspace r${num > 0 ? '+' : ''}${num}`).catch(print);
} catch {
execAsync([`${App.configDir}/scripts/sway/swayToRelativeWs.sh`, `${num}`]).catch(print);
}
}
export default () => Widget.EventBox({
onScrollUp: (self) => switchToRelativeWorkspace(self, -1),
onScrollDown: (self) => switchToRelativeWorkspace(self, +1),
onPrimaryClick: () => App.toggleWindow('sideright'),
child: Widget.Box({
className: 'spacing-h-4',
children: [
BarGroup({ child: BarClock() }),
BatteryModule(),
]
})
});
-36
View File
@@ -1,36 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import SystemTray from 'resource:///com/github/Aylur/ags/service/systemtray.js';
const { Box, Icon, Button, Revealer } = Widget;
const { Gravity } = imports.gi.Gdk;
const SysTrayItem = (item) => item.id !== null ? Button({
className: 'bar-systray-item',
child: Icon({ hpack: 'center' }).bind('icon', item, 'icon'),
setup: (self) => self
.hook(item, (self) => self.tooltipMarkup = item['tooltip-markup'])
,
onPrimaryClick: (_, event) => item.activate(event),
onSecondaryClick: (btn, event) => item.menu.popup_at_widget(btn, Gravity.SOUTH, Gravity.NORTH, null),
}) : null;
export const Tray = (props = {}) => {
const trayContent = Box({
className: 'margin-right-5 spacing-h-15',
setup: (self) => self
.hook(SystemTray, (self) => {
self.children = SystemTray.items.map(SysTrayItem);
self.show_all();
})
,
});
const trayRevealer = Widget.Revealer({
revealChild: true,
transition: 'slide_left',
transitionDuration: userOptions.animations.durationLarge,
child: trayContent,
});
return Box({
...props,
children: [trayRevealer],
});
}
@@ -1,224 +0,0 @@
const { GLib, Gdk, Gtk } = imports.gi;
const Lang = imports.lang;
const Cairo = imports.cairo;
const Pango = imports.gi.Pango;
const PangoCairo = imports.gi.PangoCairo;
import App from 'resource:///com/github/Aylur/ags/app.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
const { Box, DrawingArea, EventBox } = Widget;
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props
const dummyActiveWs = Box({ className: 'bar-ws bar-ws-active' }); // Not shown. Only for getting size props
const dummyOccupiedWs = Box({ className: 'bar-ws bar-ws-occupied' }); // Not shown. Only for getting size props
const mix = (value1, value2, perc) => {
return value1 * perc + value2 * (1 - perc);
}
const getFontWeightName = (weight) => {
switch (weight) {
case Pango.Weight.ULTRA_LIGHT:
return 'UltraLight';
case Pango.Weight.LIGHT:
return 'Light';
case Pango.Weight.NORMAL:
return 'Normal';
case Pango.Weight.BOLD:
return 'Bold';
case Pango.Weight.ULTRA_BOLD:
return 'UltraBold';
case Pango.Weight.HEAVY:
return 'Heavy';
default:
return 'Normal';
}
}
// Font size = workspace id
const WorkspaceContents = (count = 10) => {
return DrawingArea({
className: 'bar-ws-container',
attribute: {
initialized: false,
workspaceMask: 0,
workspaceGroup: 0,
updateMask: (self) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
// if (self.attribute.initialized) return; // We only need this to run once
const workspaces = Hyprland.workspaces;
let workspaceMask = 0;
for (let i = 0; i < workspaces.length; i++) {
const ws = workspaces[i];
if (ws.id <= offset || ws.id > offset + count) continue; // Out of range, ignore
if (workspaces[i].windows > 0)
workspaceMask |= (1 << (ws.id - offset));
}
// console.log('Mask:', workspaceMask.toString(2));
self.attribute.workspaceMask = workspaceMask;
// self.attribute.initialized = true;
self.queue_draw();
},
toggleMask: (self, occupied, name) => {
if (occupied) self.attribute.workspaceMask |= (1 << parseInt(name));
else self.attribute.workspaceMask &= ~(1 << parseInt(name));
self.queue_draw();
},
},
setup: (area) => area
.hook(Hyprland.active.workspace, (self) => {
self.setCss(`font-size: ${(Hyprland.active.workspace.id - 1) % count + 1}px;`);
const previousGroup = self.attribute.workspaceGroup;
const currentGroup = Math.floor((Hyprland.active.workspace.id - 1) / count);
if (currentGroup !== previousGroup) {
self.attribute.updateMask(self);
self.attribute.workspaceGroup = currentGroup;
}
})
.hook(Hyprland, (self) => self.attribute.updateMask(self), 'notify::workspaces')
.on('draw', Lang.bind(area, (area, cr) => {
const offset = Math.floor((Hyprland.active.workspace.id - 1) / count) * userOptions.workspaces.shown;
const allocation = area.get_allocation();
const { width, height } = allocation;
const workspaceStyleContext = dummyWs.get_style_context();
const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const workspaceRadius = workspaceDiameter / 2;
const workspaceFontSize = workspaceStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 4 * 3;
const workspaceFontFamily = workspaceStyleContext.get_property('font-family', Gtk.StateFlags.NORMAL);
const workspaceFontWeight = workspaceStyleContext.get_property('font-weight', Gtk.StateFlags.NORMAL);
const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const wsfg = workspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context();
const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const occupiedfg = occupiedWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
const activeWorkspaceStyleContext = dummyActiveWs.get_style_context();
const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const activefg = activeWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
area.set_size_request(workspaceDiameter * count, -1);
const widgetStyleContext = area.get_style_context();
const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
const activeWsCenterX = -(workspaceDiameter / 2) + (workspaceDiameter * activeWs);
const activeWsCenterY = height / 2;
// Font
const layout = PangoCairo.create_layout(cr);
const fontDesc = Pango.font_description_from_string(`${workspaceFontFamily[0]} ${getFontWeightName(workspaceFontWeight)} ${workspaceFontSize}`);
layout.set_font_description(fontDesc);
cr.setAntialias(Cairo.Antialias.BEST);
// Get kinda min radius for number indicators
layout.set_text("0".repeat(count.toString().length), -1);
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
const indicatorRadius = Math.max(layoutWidth, layoutHeight) / 2 * 1.15; // smaller than sqrt(2)*radius
const indicatorGap = workspaceRadius - indicatorRadius;
for (let i = 1; i <= count; i++) {
if (area.attribute.workspaceMask & (1 << i)) {
// Draw bg highlight
cr.setSourceRGBA(occupiedbg.red, occupiedbg.green, occupiedbg.blue, occupiedbg.alpha);
const wsCenterX = -(workspaceRadius) + (workspaceDiameter * i);
const wsCenterY = height / 2;
if (!(area.attribute.workspaceMask & (1 << (i - 1)))) { // Left
cr.arc(wsCenterX, wsCenterY, workspaceRadius, 0.5 * Math.PI, 1.5 * Math.PI);
cr.fill();
}
else {
cr.rectangle(wsCenterX - workspaceRadius, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
if (!(area.attribute.workspaceMask & (1 << (i + 1)))) { // Right
cr.arc(wsCenterX, wsCenterY, workspaceRadius, -0.5 * Math.PI, 0.5 * Math.PI);
cr.fill();
}
else {
cr.rectangle(wsCenterX, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
}
}
// Draw active ws
cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha);
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius, 0, 2 * Math.PI);
cr.fill();
// Draw workspace numbers
for (let i = 1; i <= count; i++) {
const inactivecolors = area.attribute.workspaceMask & (1 << i) ? occupiedfg : wsfg;
if (i == activeWs) {
cr.setSourceRGBA(activefg.red, activefg.green, activefg.blue, activefg.alpha);
}
// Moving to
else if ((i == Math.floor(activeWs) && Hyprland.active.workspace.id < activeWs) || (i == Math.ceil(activeWs) && Hyprland.active.workspace.id > activeWs)) {
cr.setSourceRGBA(mix(activefg.red, inactivecolors.red, 1 - Math.abs(activeWs - i)), mix(activefg.green, inactivecolors.green, 1 - Math.abs(activeWs - i)), mix(activefg.blue, inactivecolors.blue, 1 - Math.abs(activeWs - i)), activefg.alpha);
}
// Moving from
else if ((i == Math.floor(activeWs) && Hyprland.active.workspace.id > activeWs) || (i == Math.ceil(activeWs) && Hyprland.active.workspace.id < activeWs)) {
cr.setSourceRGBA(mix(activefg.red, inactivecolors.red, 1 - Math.abs(activeWs - i)), mix(activefg.green, inactivecolors.green, 1 - Math.abs(activeWs - i)), mix(activefg.blue, inactivecolors.blue, 1 - Math.abs(activeWs - i)), activefg.alpha);
}
// Inactive
else
cr.setSourceRGBA(inactivecolors.red, inactivecolors.green, inactivecolors.blue, inactivecolors.alpha);
layout.set_text(`${i + offset}`, -1);
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
const x = -workspaceRadius + (workspaceDiameter * i) - (layoutWidth / 2);
const y = (height - layoutHeight) / 2;
cr.moveTo(x, y);
PangoCairo.show_layout(cr, layout);
cr.stroke();
}
}))
,
})
}
export default () => EventBox({
onScrollUp: () => Hyprland.messageAsync(`dispatch workspace r-1`).catch(print),
onScrollDown: () => Hyprland.messageAsync(`dispatch workspace r+1`).catch(print),
onMiddleClick: () => toggleWindowOnAllMonitors('osk'),
onSecondaryClick: () => App.toggleWindow('overview'),
attribute: {
clicked: false,
ws_group: 0,
},
child: Box({
homogeneous: true,
className: 'bar-group-margin',
children: [Box({
className: `bar-group${userOptions.appearance.borderless ? '-borderless' : ''} bar-group-standalone bar-group-pad`,
css: 'min-width: 2px;',
children: [WorkspaceContents(userOptions.workspaces.shown)],
})]
}),
setup: (self) => {
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
self.on('motion-notify-event', (self, event) => {
if (!self.attribute.clicked) return;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
.catch(print);
})
self.on('button-press-event', (self, event) => {
if (event.get_button()[1] === 1) {
self.attribute.clicked = true;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
Utils.execAsync([`${App.configDir}/scripts/hyprland/workspace_action.sh`, 'workspace', `${wsId}`])
.catch(print);
}
else if (event.get_button()[1] === 8) {
Hyprland.messageAsync(`dispatch togglespecialworkspace`).catch(print);
}
})
self.on('button-release-event', (self) => self.attribute.clicked = false);
}
})
@@ -1,183 +0,0 @@
const { GLib, Gdk, Gtk } = imports.gi;
const Lang = imports.lang;
const Cairo = imports.cairo;
const Pango = imports.gi.Pango;
const PangoCairo = imports.gi.PangoCairo;
import Widget from "resource:///com/github/Aylur/ags/widget.js";
import Sway from "../../../services/sway.js";
import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
const { execAsync, exec } = Utils;
const { Box, DrawingArea, EventBox } = Widget;
const dummyWs = Box({ className: 'bar-ws' }); // Not shown. Only for getting size props
const dummyActiveWs = Box({ className: 'bar-ws bar-ws-active' }); // Not shown. Only for getting size props
const dummyOccupiedWs = Box({ className: 'bar-ws bar-ws-occupied' }); // Not shown. Only for getting size props
const switchToWorkspace = (arg) => Utils.execAsync(`swaymsg workspace ${arg}`).catch(print);
const switchToRelativeWorkspace = (self, num) =>
execAsync([`${App.configDir}/scripts/sway/swayToRelativeWs.sh`, `${num}`]).catch(print);
const WorkspaceContents = (count = 10) => {
return DrawingArea({
css: `transition: 90ms cubic-bezier(0.1, 1, 0, 1);`,
attribute: {
initialized: false,
workspaceMask: 0,
updateMask: (self) => {
if (self.attribute.initialized) return; // We only need this to run once
const workspaces = Sway.workspaces;
let workspaceMask = 0;
// console.log('----------------')
for (let i = 0; i < workspaces.length; i++) {
const ws = workspaces[i];
// console.log(ws.name, ',', ws.num);
if (!Number(ws.name)) return;
const id = Number(ws.name);
if (id <= 0) continue; // Ignore scratchpads
if (id > count) return; // Not rendered
if (workspaces[i].windows > 0) {
workspaceMask |= (1 << id);
}
}
self.attribute.workspaceMask = workspaceMask;
self.attribute.initialized = true;
},
toggleMask: (self, occupied, name) => {
if (occupied) self.attribute.workspaceMask |= (1 << parseInt(name));
else self.attribute.workspaceMask &= ~(1 << parseInt(name));
},
},
setup: (area) => area
.hook(Sway.active.workspace, (area) => {
area.setCss(`font-size: ${Sway.active.workspace.name}px;`)
})
.hook(Sway, (self) => self.attribute.updateMask(self), 'notify::workspaces')
// .hook(Hyprland, (self, name) => self.attribute.toggleMask(self, true, name), 'workspace-added')
// .hook(Hyprland, (self, name) => self.attribute.toggleMask(self, false, name), 'workspace-removed')
.on('draw', Lang.bind(area, (area, cr) => {
const allocation = area.get_allocation();
const { width, height } = allocation;
const workspaceStyleContext = dummyWs.get_style_context();
const workspaceDiameter = workspaceStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
const workspaceRadius = workspaceDiameter / 2;
const workspaceFontSize = workspaceStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL) / 4 * 3;
const workspaceFontFamily = workspaceStyleContext.get_property('font-family', Gtk.StateFlags.NORMAL);
const wsbg = workspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const wsfg = workspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
const occupiedWorkspaceStyleContext = dummyOccupiedWs.get_style_context();
const occupiedbg = occupiedWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const occupiedfg = occupiedWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
const activeWorkspaceStyleContext = dummyActiveWs.get_style_context();
const activebg = activeWorkspaceStyleContext.get_property('background-color', Gtk.StateFlags.NORMAL);
const activefg = activeWorkspaceStyleContext.get_property('color', Gtk.StateFlags.NORMAL);
area.set_size_request(workspaceDiameter * count, -1);
const widgetStyleContext = area.get_style_context();
const activeWs = widgetStyleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
const activeWsCenterX = -(workspaceDiameter / 2) + (workspaceDiameter * activeWs);
const activeWsCenterY = height / 2;
// Font
const layout = PangoCairo.create_layout(cr);
const fontDesc = Pango.font_description_from_string(`${workspaceFontFamily[0]} ${workspaceFontSize}`);
layout.set_font_description(fontDesc);
cr.setAntialias(Cairo.Antialias.BEST);
// Get kinda min radius for number indicators
layout.set_text("0".repeat(count.toString().length), -1);
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
const indicatorRadius = Math.max(layoutWidth, layoutHeight) / 2 * 1.2; // a bit smaller than sqrt(2)*radius
const indicatorGap = workspaceRadius - indicatorRadius;
// Draw workspace numbers
for (let i = 1; i <= count; i++) {
if (area.attribute.workspaceMask & (1 << i)) {
// Draw bg highlight
cr.setSourceRGBA(occupiedbg.red, occupiedbg.green, occupiedbg.blue, occupiedbg.alpha);
const wsCenterX = -(workspaceRadius) + (workspaceDiameter * i);
const wsCenterY = height / 2;
if (!(area.attribute.workspaceMask & (1 << (i - 1)))) { // Left
cr.arc(wsCenterX, wsCenterY, workspaceRadius, 0.5 * Math.PI, 1.5 * Math.PI);
cr.fill();
}
else {
cr.rectangle(wsCenterX - workspaceRadius, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
if (!(area.attribute.workspaceMask & (1 << (i + 1)))) { // Right
cr.arc(wsCenterX, wsCenterY, workspaceRadius, -0.5 * Math.PI, 0.5 * Math.PI);
cr.fill();
}
else {
cr.rectangle(wsCenterX, wsCenterY - workspaceRadius, workspaceRadius, workspaceRadius * 2)
cr.fill();
}
// Set color for text
cr.setSourceRGBA(occupiedfg.red, occupiedfg.green, occupiedfg.blue, occupiedfg.alpha);
}
else
cr.setSourceRGBA(wsfg.red, wsfg.green, wsfg.blue, wsfg.alpha);
layout.set_text(`${i}`, -1);
const [layoutWidth, layoutHeight] = layout.get_pixel_size();
const x = -workspaceRadius + (workspaceDiameter * i) - (layoutWidth / 2);
const y = (height - layoutHeight) / 2;
cr.moveTo(x, y);
// cr.showText(text);
PangoCairo.show_layout(cr, layout);
cr.stroke();
}
// Draw active ws
// base
cr.setSourceRGBA(activebg.red, activebg.green, activebg.blue, activebg.alpha);
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius, 0, 2 * Math.PI);
cr.fill();
// inner decor
cr.setSourceRGBA(activefg.red, activefg.green, activefg.blue, activefg.alpha);
cr.arc(activeWsCenterX, activeWsCenterY, indicatorRadius * 0.2, 0, 2 * Math.PI);
cr.fill();
}))
,
})
}
export default () => EventBox({
onScrollUp: (self) => switchToRelativeWorkspace(self, -1),
onScrollDown: (self) => switchToRelativeWorkspace(self, +1),
onMiddleClick: () => toggleWindowOnAllMonitors('osk'),
onSecondaryClick: () => App.toggleWindow('overview'),
attribute: { clicked: false },
child: Box({
homogeneous: true,
className: 'bar-group-margin',
children: [Box({
className: `bar-group${userOptions.appearance.borderless ? '-borderless' : ''} bar-group-standalone bar-group-pad`,
css: 'min-width: 2px;',
children: [
WorkspaceContents(10),
]
})]
}),
setup: (self) => {
self.add_events(Gdk.EventMask.POINTER_MOTION_MASK);
self.on('motion-notify-event', (self, event) => {
if (!self.attribute.clicked) return;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
switchToWorkspace(wsId);
})
self.on('button-press-event', (self, event) => {
if (!(event.get_button()[1] === 1)) return; // We're only interested in left-click here
self.attribute.clicked = true;
const [_, cursorX, cursorY] = event.get_coords();
const widgetWidth = self.get_allocation().width;
const wsId = Math.ceil(cursorX * userOptions.workspaces.shown / widgetWidth);
switchToWorkspace(wsId);
})
self.on('button-release-event', (self) => self.attribute.clicked = false);
}
});
@@ -1,122 +0,0 @@
export const keybindList = [[
{
"icon": "pin_drop",
"name": "Workspaces: navigation",
"binds": [
{ "keys": ["󰖳", "+", "#"], "action": "Go to workspace #" },
{ "keys": ["󰖳", "+", "S"], "action": "Toggle special workspace" },
{ "keys": ["󰖳", "+", "(Scroll ↑↓)"], "action": "Go to workspace -1/+1" },
{ "keys": ["Ctrl", "󰖳", "+", "←"], "action": "Go to workspace on the left" },
{ "keys": ["Ctrl", "󰖳", "+", "→"], "action": "Go to workspace on the right" },
{ "keys": ["󰖳", "+", "PageUp"], "action": "Go to workspace on the left" },
{ "keys": ["󰖳", "+", "PageDown"], "action": "Go to workspace on the right" }
],
"id": 1
},
{
"icon": "overview_key",
"name": "Workspaces: management",
"binds": [
{ "keys": ["󰖳", "Alt", "+", "#"], "action": "Move window to workspace #" },
{ "keys": ["󰖳", "Alt", "+", "S"], "action": "Move window to special workspace" },
{ "keys": ["󰖳", "Alt", "+", "PageUp"], "action": "Move window to workspace on the left" },
{ "keys": ["󰖳", "Alt", "+", "PageDown"], "action": "Move window to workspace on the right" }
],
"id": 2
},
{
"icon": "move_group",
"name": "Windows",
"binds": [
{ "keys": ["󰖳", "+", "←↑→↓"], "action": "Focus window in direction" },
{ "keys": ["󰖳", "Shift", "+", "←↑→↓"], "action": "Swap window in direction" },
{ "keys": ["󰖳", "+", ";"], "action": "Split ratio -" },
{ "keys": ["󰖳", "+", "'"], "action": "Split ratio +" },
{ "keys": ["󰖳", "+", "Lmb"], "action": "Move window" },
{ "keys": ["󰖳", "+", "Rmb"], "action": "Resize window" },
{ "keys": ["󰖳", "Alt", "+", "Space"], "action": "Float window" },
{ "keys": ["󰖳", "+", "F"], "action": "Fullscreen" },
{ "keys": ["󰖳", "Alt", "+", "F"], "action": "Fake fullscreen" }
],
"id": 3
}
],
[
{
"icon": "widgets",
"name": "Widgets (AGS)",
"binds": [
{ "keys": ["󰖳", "OR", "󰖳", "+", "Tab"], "action": "Toggle overview/launcher" },
{ "keys": ["Ctrl", "󰖳", "+", "R"], "action": "Restart AGS" },
{ "keys": ["󰖳", "+", "/"], "action": "Toggle this cheatsheet" },
{ "keys": ["󰖳", "+", "N"], "action": "Toggle system sidebar" },
{ "keys": ["󰖳", "+", "B", "OR", "󰖳", "+", "O"], "action": "Toggle utilities sidebar" },
{ "keys": ["󰖳", "+", "K"], "action": "Toggle virtual keyboard" },
{ "keys": ["Ctrl", "Alt", "+", "Del"], "action": "Power/Session menu" },
{ "keys": ["Esc"], "action": "Exit a window" },
{ "keys": ["rightCtrl"], "action": "Dismiss/close sidebar" },
{ "keys": ["Ctrl", "󰖳", "+", "T"], "action": "Change wallpaper+colorscheme" },
// { "keys": ["󰖳", "+", "B"], "action": "Toggle left sidebar" },
// { "keys": ["󰖳", "+", "N"], "action": "Toggle right sidebar" },
// { "keys": ["󰖳", "+", "G"], "action": "Toggle volume mixer" },
// { "keys": ["󰖳", "+", "M"], "action": "Toggle useless audio visualizer" },
// { "keys": ["(right)Ctrl"], "action": "Dismiss notification & close menus" }
],
"id": 4
},
{
"icon": "construction",
"name": "Utilities",
"binds": [
{ "keys": ["PrtSc"], "action": "Screenshot >> clipboard" },
{ "keys": ["Ctrl", "PrtSc"], "action": "Screenshot >> file + clipboard" },
{ "keys": ["󰖳", "Shift", "+", "S"], "action": "Screen snip >> clipboard" },
{ "keys": ["󰖳", "Shift", "+", "T"], "action": "Image to text >> clipboard" },
{ "keys": ["󰖳", "Shift", "+", "C"], "action": "Color picker" },
{ "keys": ["󰖳", "Alt", "+", "R"], "action": "Record region" },
{ "keys": ["Ctrl", "Alt", "+", "R"], "action": "Record region with sound" },
{ "keys": ["󰖳", "Shift", "Alt", "+", "R"], "action": "Record screen with sound" }
],
"id": 5
},
],
[
{
"icon": "apps",
"name": "Apps",
"binds": [
{ "keys": ["󰖳", "+", "T"], "action": "Launch terminal: foot" },
{ "keys": ["󰖳", "+", "W"], "action": "Launch browser: Firefox" },
{ "keys": ["󰖳", "+", "C"], "action": "Launch editor: vscode" },
{ "keys": ["󰖳", "+", "X"], "action": "Launch editor: GNOME Text Editor" },
{ "keys": ["󰖳", "+", "I"], "action": "Launch settings: GNOME Control center" }
],
"id": 6
},
{
"icon": "keyboard",
"name": "Typing",
"binds": [
{ "keys": ["󰖳", "+", "V"], "action": "Clipboard history >> clipboard" },
{ "keys": ["󰖳", "+", "."], "action": "Emoji picker >> clipboard" },
],
"id": 7
},
{
"icon": "terminal",
"name": "Launcher actions",
"binds": [
{ "keys": [">raw"], "action": "Toggle mouse acceleration" },
{ "keys": [">img"], "action": "Select wallpaper and generate colorscheme" },
{ "keys": [">light"], "action": "Switch to light theme" },
{ "keys": [">dark"], "action": "Switch to dark theme" },
{ "keys": [">badapple"], "action": "Apply black n' white colorscheme" },
{ "keys": [">color"], "action": "Pick acccent color" },
{ "keys": [">todo"], "action": "Type something after that to add a To-do item" },
],
"id": 8
}
]];
@@ -1,195 +0,0 @@
export const periodicTable = [
[
{ name: 'Hydrogen', symbol: 'H', number: 1, weight: 1.01, type: 'nonmetal' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: 'Helium', symbol: 'He', number: 2, weight: 4.00, type: 'noblegas' },
],
[
{ name: 'Lithium', symbol: 'Li', number: 3, weight: 6.94, type: 'metal' },
{ name: 'Beryllium', symbol: 'Be', number: 4, weight: 9.01, type: 'metal' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: 'Boron', symbol: 'B', number: 5, weight: 10.81, type: 'nonmetal' },
{ name: 'Carbon', symbol: 'C', number: 6, weight: 12.01, type: 'nonmetal' },
{ name: 'Nitrogen', symbol: 'N', number: 7, weight: 14.01, type: 'nonmetal' },
{ name: 'Oxygen', symbol: 'O', number: 8, weight: 16, type: 'nonmetal' },
{ name: 'Fluorine', symbol: 'F', number: 9, weight: 19, type: 'nonmetal' },
{ name: 'Neon', symbol: 'Ne', number: 10, weight: 20.18, type: 'noblegas' },
],
[
{ name: 'Sodium', symbol: 'Na', number: 11, weight: 22.99, type: 'metal' },
{ name: 'Magnesium', symbol: 'Mg', number: 12, weight: 24.31, type: 'metal' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: 'Aluminum', symbol: 'Al', number: 13, weight: 26.98, type: 'metal' },
{ name: 'Silicon', symbol: 'Si', number: 14, weight: 28.09, type: 'nonmetal' },
{ name: 'Phosphorus', symbol: 'P', number: 15, weight: 30.97, type: 'nonmetal' },
{ name: 'Sulfur', symbol: 'S', number: 16, weight: 32.07, type: 'nonmetal' },
{ name: 'Chlorine', symbol: 'Cl', number: 17, weight: 35.45, type: 'nonmetal' },
{ name: 'Argon', symbol: 'Ar', number: 18, weight: 39.95, type: 'noblegas' },
],
[
{ name: 'Kalium', symbol: 'K', number: 19, weight: 39.098, type: 'metal' },
{ name: 'Calcium', symbol: 'Ca', number: 20, weight: 40.078, type: 'metal' },
{ name: 'Scandium', symbol: 'Sc', number: 21, weight: 44.956, type: 'metal' },
{ name: 'Titanium', symbol: 'Ti', number: 22, weight: 47.87, type: 'metal' },
{ name: 'Vanadium', symbol: 'V', number: 23, weight: 50.94, type: 'metal' },
{ name: 'Chromium', symbol: 'Cr', number: 24, weight: 52, type: 'metal'/*, icon: 'chromium-browser'*/ },
{ name: 'Manganese', symbol: 'Mn', number: 25, weight: 54.94, type: 'metal' },
{ name: 'Iron', symbol: 'Fe', number: 26, weight: 55.85, type: 'metal' },
{ name: 'Cobalt', symbol: 'Co', number: 27, weight: 58.93, type: 'metal' },
{ name: 'Nickel', symbol: 'Ni', number: 28, weight: 58.69, type: 'metal' },
{ name: 'Copper', symbol: 'Cu', number: 29, weight: 63.55, type: 'metal' },
{ name: 'Zinc', symbol: 'Zn', number: 30, weight: 65.38, type: 'metal' },
{ name: 'Gallium', symbol: 'Ga', number: 31, weight: 69.72, type: 'metal' },
{ name: 'Germanium', symbol: 'Ge', number: 32, weight: 72.63, type: 'metal' },
{ name: 'Arsenic', symbol: 'As', number: 33, weight: 74.92, type: 'nonmetal' },
{ name: 'Selenium', symbol: 'Se', number: 34, weight: 78.96, type: 'nonmetal' },
{ name: 'Bromine', symbol: 'Br', number: 35, weight: 79.904, type: 'nonmetal' },
{ name: 'Krypton', symbol: 'Kr', number: 36, weight: 83.8, type: 'noblegas' },
],
[
{ name: 'Rubidium', symbol: 'Rb', number: 37, weight: 85.47, type: 'metal' },
{ name: 'Strontium', symbol: 'Sr', number: 38, weight: 87.62, type: 'metal' },
{ name: 'Yttrium', symbol: 'Y', number: 39, weight: 88.91, type: 'metal' },
{ name: 'Zirconium', symbol: 'Zr', number: 40, weight: 91.22, type: 'metal' },
{ name: 'Niobium', symbol: 'Nb', number: 41, weight: 92.91, type: 'metal' },
{ name: 'Molybdenum', symbol: 'Mo', number: 42, weight: 95.94, type: 'metal' },
{ name: 'Technetium', symbol: 'Tc', number: 43, weight: 98, type: 'metal' },
{ name: 'Ruthenium', symbol: 'Ru', number: 44, weight: 101.07, type: 'metal' },
{ name: 'Rhodium', symbol: 'Rh', number: 45, weight: 102.91, type: 'metal' },
{ name: 'Palladium', symbol: 'Pd', number: 46, weight: 106.42, type: 'metal' },
{ name: 'Silver', symbol: 'Ag', number: 47, weight: 107.87, type: 'metal' },
{ name: 'Cadmium', symbol: 'Cd', number: 48, weight: 112.41, type: 'metal' },
{ name: 'Indium', symbol: 'In', number: 49, weight: 114.82, type: 'metal' },
{ name: 'Tin', symbol: 'Sn', number: 50, weight: 118.71, type: 'metal' },
{ name: 'Antimony', symbol: 'Sb', number: 51, weight: 121.76, type: 'metal' },
{ name: 'Tellurium', symbol: 'Te', number: 52, weight: 127.6, type: 'nonmetal' },
{ name: 'Iodine', symbol: 'I', number: 53, weight: 126.9, type: 'nonmetal' },
{ name: 'Xenon', symbol: 'Xe', number: 54, weight: 131.29, type: 'noblegas' },
],
[
{ name: 'Cesium', symbol: 'Cs', number: 55, weight: 132.91, type: 'metal' },
{ name: 'Barium', symbol: 'Ba', number: 56, weight: 137.33, type: 'metal' },
{ name: 'Lanthanum', symbol: 'La', number: 57, weight: 138.91, type: 'lanthanum' },
{ name: 'Hafnium', symbol: 'Hf', number: 72, weight: 178.49, type: 'metal' },
{ name: 'Tantalum', symbol: 'Ta', number: 73, weight: 180.95, type: 'metal' },
{ name: 'Tungsten', symbol: 'W', number: 74, weight: 183.84, type: 'metal' },
{ name: 'Rhenium', symbol: 'Re', number: 75, weight: 186.21, type: 'metal' },
{ name: 'Osmium', symbol: 'Os', number: 76, weight: 190.23, type: 'metal' },
{ name: 'Iridium', symbol: 'Ir', number: 77, weight: 192.22, type: 'metal' },
{ name: 'Platinum', symbol: 'Pt', number: 78, weight: 195.09, type: 'metal' },
{ name: 'Gold', symbol: 'Au', number: 79, weight: 196.97, type: 'metal' },
{ name: 'Mercury', symbol: 'Hg', number: 80, weight: 200.59, type: 'metal' },
{ name: 'Thallium', symbol: 'Tl', number: 81, weight: 204.38, type: 'metal' },
{ name: 'Lead', symbol: 'Pb', number: 82, weight: 207.2, type: 'metal' },
{ name: 'Bismuth', symbol: 'Bi', number: 83, weight: 208.98, type: 'metal' },
{ name: 'Polonium', symbol: 'Po', number: 84, weight: 209, type: 'metal' },
{ name: 'Astatine', symbol: 'At', number: 85, weight: 210, type: 'nonmetal' },
{ name: 'Radon', symbol: 'Rn', number: 86, weight: 222, type: 'noblegas' },
],
[
{ name: 'Francium', symbol: 'Fr', number: 87, weight: 223, type: 'metal' },
{ name: 'Radium', symbol: 'Ra', number: 88, weight: 226, type: 'metal' },
{ name: 'Actinium', symbol: 'Ac', number: 89, weight: 227, type: 'actinium' },
{ name: 'Rutherfordium', symbol: 'Rf', number: 104, weight: 267, type: 'metal' },
{ name: 'Dubnium', symbol: 'Db', number: 105, weight: 268, type: 'metal' },
{ name: 'Seaborgium', symbol: 'Sg', number: 106, weight: 271, type: 'metal' },
{ name: 'Bohrium', symbol: 'Bh', number: 107, weight: 272, type: 'metal' },
{ name: 'Hassium', symbol: 'Hs', number: 108, weight: 277, type: 'metal' },
{ name: 'Meitnerium', symbol: 'Mt', number: 109, weight: 278, type: 'metal' },
{ name: 'Darmstadtium', symbol: 'Ds', number: 110, weight: 281, type: 'metal' },
{ name: 'Roentgenium', symbol: 'Rg', number: 111, weight: 280, type: 'metal' },
{ name: 'Copernicium', symbol: 'Cn', number: 112, weight: 285, type: 'metal' },
{ name: 'Nihonium', symbol: 'Nh', number: 113, weight: 286, type: 'metal' },
{ name: 'Flerovium', symbol: 'Fl', number: 114, weight: 289, type: 'metal' },
{ name: 'Moscovium', symbol: 'Mc', number: 115, weight: 290, type: 'metal' },
{ name: 'Livermorium', symbol: 'Lv', number: 116, weight: 293, type: 'metal' },
{ name: 'Tennessine', symbol: 'Ts', number: 117, weight: 294, type: 'metal' },
{ name: 'Oganesson', symbol: 'Og', number: 118, weight: 294, type: 'noblegas' },
],
]
export const series = [
[
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: 'Cerium', symbol: 'Ce', number: 58, weight: 140.12, type: 'lanthanum' },
{ name: 'Praseodymium', symbol: 'Pr', number: 59, weight: 140.91, type: 'lanthanum' },
{ name: 'Neodymium', symbol: 'Nd', number: 60, weight: 144.24, type: 'lanthanum' },
{ name: 'Promethium', symbol: 'Pm', number: 61, weight: 145, type: 'lanthanum' },
{ name: 'Samarium', symbol: 'Sm', number: 62, weight: 150.36, type: 'lanthanum' },
{ name: 'Europium', symbol: 'Eu', number: 63, weight: 151.96, type: 'lanthanum' },
{ name: 'Gadolinium', symbol: 'Gd', number: 64, weight: 157.25, type: 'lanthanum' },
{ name: 'Terbium', symbol: 'Tb', number: 65, weight: 158.93, type: 'lanthanum' },
{ name: 'Dysprosium', symbol: 'Dy', number: 66, weight: 162.5, type: 'lanthanum' },
{ name: 'Holmium', symbol: 'Ho', number: 67, weight: 164.93, type: 'lanthanum' },
{ name: 'Erbium', symbol: 'Er', number: 68, weight: 167.26, type: 'lanthanum' },
{ name: 'Thulium', symbol: 'Tm', number: 69, weight: 168.93, type: 'lanthanum' },
{ name: 'Ytterbium', symbol: 'Yb', number: 70, weight: 173.04, type: 'lanthanum' },
{ name: 'Lutetium', symbol: 'Lu', number: 71, weight: 174.97, type: 'lanthanum' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
],
[
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
{ name: 'Thorium', symbol: 'Th', number: 90, weight: 232.04, type: 'actinium' },
{ name: 'Protactinium', symbol: 'Pa', number: 91, weight: 231.04, type: 'actinium' },
{ name: 'Uranium', symbol: 'U', number: 92, weight: 238.03, type: 'actinium' },
{ name: 'Neptunium', symbol: 'Np', number: 93, weight: 237, type: 'actinium' },
{ name: 'Plutonium', symbol: 'Pu', number: 94, weight: 244, type: 'actinium' },
{ name: 'Americium', symbol: 'Am', number: 95, weight: 243, type: 'actinium' },
{ name: 'Curium', symbol: 'Cm', number: 96, weight: 247, type: 'actinium' },
{ name: 'Berkelium', symbol: 'Bk', number: 97, weight: 247, type: 'actinium' },
{ name: 'Californium', symbol: 'Cf', number: 98, weight: 251, type: 'actinium' },
{ name: 'Einsteinium', symbol: 'Es', number: 99, weight: 252, type: 'actinium' },
{ name: 'Fermium', symbol: 'Fm', number: 100, weight: 257, type: 'actinium' },
{ name: 'Mendelevium', symbol: 'Md', number: 101, weight: 258, type: 'actinium' },
{ name: 'Nobelium', symbol: 'No', number: 102, weight: 259, type: 'actinium' },
{ name: 'Lawrencium', symbol: 'Lr', number: 103, weight: 262, type: 'actinium' },
{ name: '', symbol: '', number: -1, weight: 0, type: 'empty' },
],
];
export const niceTypes = {
'metal': "Metal",
'nonmetal': "Nonmetal",
'noblegas': "Noble gas",
'lanthanum': "Lanthanum",
'actinium': "Actinium"
}
-126
View File
@@ -1,126 +0,0 @@
const { GLib, Gtk } = imports.gi;
import App from "resource:///com/github/Aylur/ags/app.js";
import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
import Widget from "resource:///com/github/Aylur/ags/widget.js";
import { IconTabContainer } from "../.commonwidgets/tabcontainer.js";
const { Box, Label, Scrollable } = Widget;
const HYPRLAND_KEYBIND_CONFIG_FILE = userOptions.cheatsheet.keybinds.configPath ?
userOptions.cheatsheet.keybinds.configPath : `${GLib.get_user_config_dir()}/hypr/hyprland/keybinds.conf`;
const KEYBIND_SECTIONS_PER_PAGE = 3;
const getKeybindList = () => {
let data = Utils.exec(`${App.configDir}/scripts/hyprland/get_keybinds.py --path ${HYPRLAND_KEYBIND_CONFIG_FILE}`);
if (data == "\"error\"") {
Utils.timeout(2000, () => Utils.execAsync(['notify-send',
'Update path to keybinds',
'Keybinds hyprland config file not found. Check your user options.',
'-a', 'ags',
]).catch(print))
return { children: [] };
}
return JSON.parse(data);
};
const keybindList = getKeybindList();
const keySubstitutions = {
"Super": "󰖳",
"mouse_up": "Scroll ↓", // ikr, weird
"mouse_down": "Scroll ↑", // trust me bro
"mouse:272": "LMB",
"mouse:273": "RMB",
"mouse:275": "MouseBack",
"Slash": "/",
"Hash": "#"
}
const substituteKey = (key) => {
return keySubstitutions[key] || key;
}
const Keybind = (keybindData, type) => { // type: either "keys" or "actions"
const Key = (key) => Label({ // Specific keys
vpack: 'center',
className: `${['OR', '+'].includes(key) ? 'cheatsheet-key-notkey' : 'cheatsheet-key'} txt-small`,
label: substituteKey(key),
});
const Action = (text) => Label({ // Binds
xalign: 0,
label: getString(text),
className: "txt txt-small cheatsheet-action",
})
return Widget.Box({
className: "spacing-h-10 cheatsheet-bind-lineheight",
children: type == "keys" ? [
...(keybindData.mods.length > 0 ? [
...keybindData.mods.map(Key),
Key("+"),
] : []),
Key(keybindData.key),
] : [Action(keybindData.comment)],
})
}
const Section = (sectionData, scope) => {
const keys = Box({
vertical: true,
className: 'spacing-v-5',
children: sectionData.keybinds.map((data) => Keybind(data, "keys"))
})
const actions = Box({
vertical: true,
className: 'spacing-v-5',
children: sectionData.keybinds.map((data) => Keybind(data, "actions"))
})
const name = Label({
xalign: 0,
className: "cheatsheet-category-title txt margin-bottom-10",
label: getString(sectionData.name),
})
const binds = Box({
className: 'spacing-h-10',
children: [
keys,
actions,
]
})
const childrenSections = Box({
vertical: true,
className: 'spacing-v-15',
children: sectionData.children.map((data) => Section(data, scope + 1))
})
return Box({
vertical: true,
children: [
...((sectionData.name && sectionData.name.length > 0) ? [name] : []),
Box({
className: 'spacing-v-10',
children: [
binds,
childrenSections,
]
})
]
})
};
export default () => {
const numOfTabs = Math.ceil(keybindList.children.length / KEYBIND_SECTIONS_PER_PAGE);
const keybindPages = Array.from({ length: numOfTabs }, (_, i) => ({
iconWidget: Label({
className: "txt txt-small",
label: `${i + 1}`,
}),
name: `${i + 1}`,
child: Box({
className: 'spacing-h-30',
children: keybindList.children.slice(
KEYBIND_SECTIONS_PER_PAGE * i, 0 + KEYBIND_SECTIONS_PER_PAGE * (i + 1),
).map(data => Section(data, 1)),
}),
}));
return IconTabContainer({
iconWidgets: keybindPages.map((kbp) => kbp.iconWidget),
names: keybindPages.map((kbp) => kbp.name),
children: keybindPages.map((kbp) => kbp.child),
});
};
-146
View File
@@ -1,146 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import { setupCursorHover } from "../.widgetutils/cursorhover.js";
import PopupWindow from '../.widgethacks/popupwindow.js';
import Keybinds from "./keybinds.js";
import PeriodicTable from "./periodictable.js";
import { ExpandingIconTabContainer } from '../.commonwidgets/tabcontainer.js';
import { checkKeybind } from '../.widgetutils/keybind.js';
import clickCloseRegion from '../.commonwidgets/clickcloseregion.js';
const cheatsheets = [
{
name: getString('Keybinds'),
materialIcon: 'keyboard',
contentWidget: Keybinds,
},
{
name: getString('Periodic table'),
materialIcon: 'experiment',
contentWidget: PeriodicTable,
},
];
const CheatsheetHeader = () => Widget.CenterBox({
vertical: false,
startWidget: Widget.Box({}),
centerWidget: Widget.Box({
vertical: true,
className: "spacing-h-15",
children: [
Widget.Box({
hpack: 'center',
className: 'spacing-h-5 cheatsheet-title',
children: [
Widget.Label({
hpack: 'center',
css: 'margin-right: 0.682rem;',
className: 'txt-title',
label: getString('Cheat sheet'),
}),
Widget.Label({
vpack: 'center',
className: "cheatsheet-key txt-small",
label: "󰖳",
}),
Widget.Label({
vpack: 'center',
className: "cheatsheet-key-notkey txt-small",
label: "+",
}),
Widget.Label({
vpack: 'center',
className: "cheatsheet-key txt-small",
label: "/",
})
]
}),
]
}),
endWidget: Widget.Button({
vpack: 'start',
hpack: 'end',
className: "cheatsheet-closebtn icon-material txt txt-hugeass",
onClicked: () => {
closeWindowOnAllMonitors('cheatsheet');
},
child: Widget.Label({
className: 'icon-material txt txt-hugeass',
label: 'close'
}),
setup: setupCursorHover,
}),
});
const sheetContents = [];
const SheetContent = (id) => {
sheetContents[id] = ExpandingIconTabContainer({
tabsHpack: 'center',
tabSwitcherClassName: 'sidebar-icontabswitcher',
transitionDuration: userOptions.animations.durationLarge * 1.4,
icons: cheatsheets.map((api) => api.materialIcon),
names: cheatsheets.map((api) => api.name),
children: cheatsheets.map((api) => api.contentWidget()),
onChange: (self, id) => {
self.shown = cheatsheets[id].name;
}
});
return sheetContents[id];
}
export default (id) => {
const sheets = SheetContent(id);
const widgetContent = Widget.Box({
vertical: true,
className: "cheatsheet-bg spacing-v-5",
children: [
CheatsheetHeader(),
sheets,
]
});
return PopupWindow({
monitor: id,
name: `cheatsheet${id}`,
layer: 'top',
keymode: 'on-demand',
visible: false,
anchor: ['top', 'bottom', 'left', 'right'],
child: Widget.Box({
vertical: true,
children: [
clickCloseRegion({ name: 'cheatsheet' }),
Widget.Box({
children: [
clickCloseRegion({ name: 'cheatsheet' }),
widgetContent,
clickCloseRegion({ name: 'cheatsheet' }),
]
}),
clickCloseRegion({ name: 'cheatsheet' }),
],
setup: (self) => self.on('key-press-event', (widget, event) => { // Typing
// Whole sheet
if (checkKeybind(event, userOptions.keybinds.cheatsheet.nextTab))
sheetContents.forEach(tab => tab.nextTab())
else if (checkKeybind(event, userOptions.keybinds.cheatsheet.prevTab))
sheetContents.forEach(tab => tab.prevTab())
else if (checkKeybind(event, userOptions.keybinds.cheatsheet.cycleTab))
sheetContents.forEach(tab => tab.cycleTab())
// Keybinds
if (sheets.attribute.names[sheets.attribute.shown.value] == 'Keybinds') { // If Keybinds tab is focused
if (checkKeybind(event, userOptions.keybinds.cheatsheet.keybinds.nextTab)) {
sheetContents.forEach((sheet) => {
const toSwitchTab = sheet.attribute.children[sheet.attribute.shown.value];
toSwitchTab.nextTab();
})
}
else if (checkKeybind(event, userOptions.keybinds.cheatsheet.keybinds.prevTab)) {
sheetContents.forEach((sheet) => {
const toSwitchTab = sheet.attribute.children[sheet.attribute.shown.value];
toSwitchTab.prevTab();
})
}
}
})
})
});
}
@@ -1,94 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import { niceTypes, periodicTable, series } from "./data_periodictable.js";
const { Box, Button, Icon, Label, Revealer } = Widget;
export default () => {
const ElementTile = (element) => {
return Box({
vertical: true,
tooltipText: element.electronConfig ? `${element.electronConfig}` : null,
className: `cheatsheet-periodictable-${element.type}`,
children: element.name == '' ? null : [
Box({
className: 'padding-left-8 padding-right-8 padding-top-8',
children: [
Label({
label: `${element.number}`,
className: "cheatsheet-periodictable-elementnum txt-tiny txt-bold",
}),
Box({ hexpand: true }),
Label({
label: `${element.weight}`,
className: "txt-smaller",
})
]
}),
element.icon ? Icon({
icon: element.icon,
className: "txt-hugerass txt-bold",
}) : Label({
label: `${element.symbol}`,
className: "cheatsheet-periodictable-elementsymbol",
}),
Label({
label: `${element.name}`,
className: "txt-tiny",
})
]
})
}
const BoardColor = (type) => Box({
className: 'spacing-h-5',
children: [
Box({
homogeneous: true,
className: `cheatsheet-periodictable-legend-color-wrapper`,
children: [Box({
className: `cheatsheet-periodictable-legend-color-${type}`,
})]
}),
Label({
label: `${niceTypes[type]}`,
className: "txt txt-small",
})
]
})
const mainBoard = Box({
hpack: 'center',
vertical: true,
className: "spacing-v-3",
children: periodicTable.map((row, _) => Box({ // Rows
className: "spacing-h-5",
children: row.map((element, _) => ElementTile(element))
})),
});
const seriesBoard = Box({
hpack: 'center',
vertical: true,
className: "spacing-v-3",
children: series.map((row, _) => Box({ // Rows
className: "spacing-h-5",
children: row.map((element, _) => ElementTile(element))
})),
});
const legend = Box({
hpack: 'center',
className: 'spacing-h-20',
children: [
BoardColor('metal'),
BoardColor('nonmetal'),
BoardColor('noblegas'),
BoardColor('lanthanum'),
BoardColor('actinium'),
]
})
return Box({
vertical: true,
className: 'spacing-v-20',
children: [
mainBoard,
seriesBoard,
legend
]
})
}
-21
View File
@@ -1,21 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import { enableClickthrough } from "../.widgetutils/clickthrough.js";
export default (monitor = 0, ) => {
return Widget.Window({
monitor,
name: `crosshair${monitor}`,
layer: 'overlay',
exclusivity: 'ignore',
visible: false,
child: Widget.Icon({
icon: 'crosshair-symbolic',
css: `
font-size: ${userOptions.gaming.crosshair.size}px;
color: ${userOptions.gaming.crosshair.color};
`,
}),
setup: enableClickthrough,
});
}
@@ -1,14 +0,0 @@
export const quickLaunchItems = [
{
"name": "GitHub + Files×2",
"command": "github-desktop & nautilus --new-window & nautilus --new-window &"
},
{
"name": "Terminal×2",
"command": "foot & foot &"
},
{
"name": "Discord + Youtube + Github",
"command": "xdg-open 'https://discord.com/app' && xdg-open 'https://youtube.com/' && xdg-open 'https://github.com/' &"
},
]
@@ -1,24 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import WallpaperImage from './wallpaper.js';
import TimeAndLaunchesWidget from './timeandlaunches.js'
import SystemWidget from './system.js'
export default (monitor) => Widget.Window({
name: `desktopbackground${monitor}`,
// anchor: ['top', 'bottom', 'left', 'right'],
layer: 'background',
exclusivity: 'ignore',
visible: true,
child: Widget.Overlay({
child: WallpaperImage(monitor),
// child: Widget.Box({}),
overlays: [
TimeAndLaunchesWidget(),
SystemWidget(),
],
setup: (self) => {
self.set_overlay_pass_through(self.get_children()[1], true);
},
}),
});
@@ -1,161 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
const { Box, EventBox, Label, Revealer, Overlay } = Widget;
import { AnimatedCircProg } from "../.commonwidgets/cairo_circularprogress.js";
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
const ResourceValue = (name, icon, interval, valueUpdateCmd, displayFunc, props = {}) => Box({
...props,
className: 'bg-system-bg txt',
children: [
Revealer({
transition: 'slide_left',
transitionDuration: userOptions.animations.durationLarge,
child: Box({
vpack: 'center',
vertical: true,
className: 'margin-right-15',
children: [
Label({
xalign: 1,
className: 'txt-small txt',
label: `${name}`,
}),
Label({
xalign: 1,
className: 'titlefont txt-norm txt-onSecondaryContainer',
setup: (self) => self
.poll(interval, (label) => displayFunc(label))
,
})
]
})
}),
Overlay({
child: AnimatedCircProg({
className: 'bg-system-circprog',
extraSetup: (self) => self
.poll(interval, (self) => {
execAsync(['bash', '-c', `${valueUpdateCmd}`]).then((newValue) => {
self.css = `font-size: ${Math.round(newValue)}px;`
}).catch(print);
})
,
}),
overlays: [
MaterialIcon(`${icon}`, 'hugeass'),
],
setup: self => self.set_overlay_pass_through(self.get_children()[1], true),
}),
]
})
const resources = Box({
vpack: 'fill',
vertical: true,
className: 'spacing-v-15',
children: [
ResourceValue('Memory', 'memory', 10000, `free | awk '/^Mem/ {printf("%.2f\\n", ($3/$2) * 100)}'`,
(label) => {
execAsync(['bash', '-c', `free -h | awk '/^Mem/ {print $3 " / " $2}' | sed 's/Gi/Gib/g'`])
.then((output) => {
label.label = `${output}`
}).catch(print);
}, { hpack: 'end' }),
ResourceValue('Swap', 'swap_horiz', 10000, `free | awk '/^Swap/ {if ($2 > 0) printf("%.2f\\n", ($3/$2) * 100); else print "0";}'`,
(label) => {
execAsync(['bash', '-c', `free -h | awk '/^Swap/ {if ($2 != "0") print $3 " / " $2; else print "No swap"}' | sed 's/Gi/Gib/g'`])
.then((output) => {
label.label = `${output}`
}).catch(print);
}, { hpack: 'end' }),
ResourceValue('Disk space', 'hard_drive_2', 3600000, `echo $(df --output=pcent / | tr -dc '0-9')`,
(label) => {
execAsync(['bash', '-c', `df -h --output=avail / | awk 'NR==2{print $1}'`])
.then((output) => {
label.label = `${output} available`
}).catch(print);
}, { hpack: 'end' }),
]
});
const distroAndVersion = Box({
vertical: true,
children: [
Box({
hpack: 'end',
children: [
Label({
className: 'bg-distro-txt',
xalign: 0,
label: 'Hyping on ',
}),
Label({
className: 'bg-distro-name',
xalign: 0,
label: '<distro>',
setup: (label) => {
execAsync([`grep`, `-oP`, `PRETTY_NAME="\\K[^"]+`, `/etc/os-release`]).then(distro => {
label.label = distro;
}).catch(print);
},
}),
]
}),
Box({
hpack: 'end',
children: [
Label({
className: 'bg-distro-txt',
xalign: 0,
label: 'with ',
}),
Label({
className: 'bg-distro-name',
xalign: 0,
label: 'An environment idk',
setup: (label) => {
// hyprctl will return unsuccessfully if Hyprland isn't running
execAsync([`bash`, `-c`, `hyprctl version | grep -oP "Tag: v\\K\\d+\\.\\d+\\.\\d+"`]).then(version => {
label.label = `Hyprland ${version}`;
}).catch(() => execAsync([`bash`, `-c`, `sway -v | cut -d'-' -f1 | sed 's/sway version /v/'`]).then(version => {
label.label = `Sway ${version}`;
}).catch(print));
},
}),
]
})
]
})
export default () => Box({
hpack: 'end',
vpack: 'end',
children: [
EventBox({
child: Box({
hpack: 'end',
vpack: 'end',
className: 'bg-distro-box spacing-v-20',
vertical: true,
children: [
resources,
distroAndVersion,
]
}),
onPrimaryClickRelease: () => {
const kids = resources.get_children();
for (let i = 0; i < kids.length; i++) {
const child = kids[i];
const firstChild = child.get_children()[0];
firstChild.revealChild = !firstChild.revealChild;
}
},
})
],
})
@@ -1,74 +0,0 @@
const { GLib } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Service from 'resource:///com/github/Aylur/ags/service.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
const { execAsync, exec } = Utils;
const { Box, Label, Button, Revealer, EventBox } = Widget;
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
import { quickLaunchItems } from './data_quicklaunches.js'
const TimeAndDate = () => Box({
vertical: true,
className: 'spacing-v--5',
children: [
Label({
className: 'bg-time-clock',
xalign: 0,
label: GLib.DateTime.new_now_local().format(userOptions.time.format),
setup: (self) => self.poll(userOptions.time.interval, label => {
label.label = GLib.DateTime.new_now_local().format(userOptions.time.format);
}),
}),
Label({
className: 'bg-time-date',
xalign: 0,
label: GLib.DateTime.new_now_local().format(userOptions.time.dateFormatLong),
setup: (self) => self.poll(userOptions.time.dateInterval, (label) => {
label.label = GLib.DateTime.new_now_local().format(userOptions.time.dateFormatLong);
}),
}),
]
})
const QuickLaunches = () => Box({
vertical: true,
className: 'spacing-v-10',
children: [
Label({
xalign: 0,
className: 'bg-quicklaunch-title',
label: 'Quick Launches',
}),
Box({
hpack: 'start',
className: 'spacing-h-5',
children: quickLaunchItems.map((item, i) => Button({
onClicked: () => {
execAsync(['bash', '-c', `${item["command"]}`]).catch(print);
},
className: 'bg-quicklaunch-btn',
child: Label({
label: `${item["name"]}`,
}),
setup: (self) => {
setupCursorHover(self);
}
})),
})
]
})
export default () => Box({
hpack: 'start',
vpack: 'end',
vertical: true,
className: 'bg-time-box spacing-h--10',
children: [
TimeAndDate(),
// QuickLaunches(),
],
})
@@ -1,119 +0,0 @@
const { Gdk, GdkPixbuf, Gio, GLib, Gtk } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { exec, execAsync } = Utils;
const { Box, Button, Label, Stack } = Widget;
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
import Wallpaper from '../../services/wallpaper.js';
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
import { clamp } from '../.miscutils/mathfuncs.js';
import { monitors } from '../.commondata/hyprlanddata.js';
const DISABLE_AGS_WALLPAPER = true;
const SWITCHWALL_SCRIPT_PATH = `${App.configDir}/scripts/color_generation/switchwall.sh`;
const WALLPAPER_ZOOM_SCALE = 1.25; // For scrolling when we switch workspace
const MAX_WORKSPACES = 10;
export default (monitor = 0) => {
const WALLPAPER_OFFSCREEN_X = (WALLPAPER_ZOOM_SCALE - 1) * monitors[monitor].width;
const WALLPAPER_OFFSCREEN_Y = (WALLPAPER_ZOOM_SCALE - 1) * monitors[monitor].height;
const wallpaperImage = Widget.DrawingArea({
attribute: {
pixbuf: undefined,
workspace: 1,
sideleft: 0,
sideright: 0,
updatePos: (self) => {
self.setCss(`font-size: ${self.attribute.workspace - self.attribute.sideleft + self.attribute.sideright}px;`)
},
},
className: 'bg-wallpaper-transition',
setup: (self) => {
self.set_size_request(monitors[monitor].width, monitors[monitor].height);
self
// TODO: reduced updates using timeouts to reduce lag
// .hook(Hyprland.active.workspace, (self) => {
// self.attribute.workspace = Hyprland.active.workspace.id
// self.attribute.updatePos(self);
// })
// .hook(App, (box, name, visible) => { // Update on open
// if (self.attribute[name] === undefined) return;
// self.attribute[name] = (visible ? 1 : 0);
// self.attribute.updatePos(self);
// })
.on('draw', (self, cr) => {
if (!self.attribute.pixbuf) return;
const styleContext = self.get_style_context();
const workspace = styleContext.get_property('font-size', Gtk.StateFlags.NORMAL);
// Draw
Gdk.cairo_set_source_pixbuf(cr, self.attribute.pixbuf,
-(WALLPAPER_OFFSCREEN_X / (MAX_WORKSPACES + 1) * (clamp(workspace, 0, MAX_WORKSPACES + 1))),
-WALLPAPER_OFFSCREEN_Y / 2);
cr.paint();
})
.hook(Wallpaper, (self) => {
if (DISABLE_AGS_WALLPAPER) return;
const wallPath = Wallpaper.get(monitor);
if (!wallPath || wallPath === "") return;
self.attribute.pixbuf = GdkPixbuf.Pixbuf.new_from_file(wallPath);
const scale_x = monitors[monitor].width * WALLPAPER_ZOOM_SCALE / self.attribute.pixbuf.get_width();
const scale_y = monitors[monitor].height * WALLPAPER_ZOOM_SCALE / self.attribute.pixbuf.get_height();
const scale_factor = Math.max(scale_x, scale_y);
self.attribute.pixbuf = self.attribute.pixbuf.scale_simple(
Math.round(self.attribute.pixbuf.get_width() * scale_factor),
Math.round(self.attribute.pixbuf.get_height() * scale_factor),
GdkPixbuf.InterpType.BILINEAR
);
self.queue_draw();
}, 'updated');
;
}
,
});
const wallpaperPrompt = Box({
hpack: 'center',
vpack: 'center',
vertical: true,
className: 'spacing-v-10',
children: [
Label({
hpack: 'center',
justification: 'center',
className: 'txt-large',
label: `No wallpaper loaded.\nAn image ≥ ${monitors[monitor].width * WALLPAPER_ZOOM_SCALE} × ${monitors[monitor].height * WALLPAPER_ZOOM_SCALE} is recommended.`,
}),
Button({
hpack: 'center',
className: 'btn-primary',
label: `Select one`,
setup: setupCursorHover,
onClicked: (self) => Utils.execAsync([SWITCHWALL_SCRIPT_PATH]).catch(print),
}),
]
});
const stack = Stack({
transition: 'crossfade',
transitionDuration: userOptions.animations.durationLarge,
children: {
'disabled': Box({}),
'image': wallpaperImage,
'prompt': wallpaperPrompt,
},
setup: (self) => self
.hook(Wallpaper, (self) => {
if (DISABLE_AGS_WALLPAPER) {
self.shown = 'disabled';
return;
}
const wallPath = Wallpaper.get(monitor);
self.shown = ((wallPath && wallPath != "") ? 'image' : 'prompt');
}, 'updated')
,
})
return stack;
// return wallpaperImage;
}
-300
View File
@@ -1,300 +0,0 @@
const { Gtk, GLib } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { EventBox, Button } = Widget;
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
import Applications from 'resource:///com/github/Aylur/ags/service/applications.js';
const { execAsync, exec } = Utils;
const { Box, Revealer } = Widget;
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
import { getAllFiles, searchIcons } from './icons.js'
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
import { substitute } from '../.miscutils/icons.js';
const icon_files = userOptions.icons.searchPaths.map(e => getAllFiles(e)).flat(1)
let isPinned = false
let cachePath = new Map()
let timers = []
function clearTimes() {
timers.forEach(e => GLib.source_remove(e))
timers = []
}
function ExclusiveWindow(client) {
const fn = [
(client) => !(client !== null && client !== undefined),
// Jetbrains
(client) => client.title.includes("win"),
// Vscode
(client) => client.title === '' && client.class === ''
]
for (const item of fn) { if (item(client)) { return true } }
return false
}
const focus = ({ address }) => Utils.execAsync(`hyprctl dispatch focuswindow address:${address}`).catch(print);
const DockSeparator = (props = {}) => Box({
...props,
className: 'dock-separator',
})
const PinButton = () => Widget.Button({
className: 'dock-app-btn dock-app-btn-animate',
tooltipText: 'Pin Dock',
child: Widget.Box({
homogeneous: true,
className: 'dock-app-icon txt',
child: MaterialIcon('push_pin', 'hugeass')
}),
onClicked: (self) => {
isPinned = !isPinned
self.className = `${isPinned ? "pinned-dock-app-btn" : "dock-app-btn animate"} dock-app-btn-animate`
},
setup: setupCursorHover,
})
const LauncherButton = () => Widget.Button({
className: 'dock-app-btn dock-app-btn-animate',
tooltipText: 'Open launcher',
child: Widget.Box({
homogeneous: true,
className: 'dock-app-icon txt',
child: MaterialIcon('apps', 'hugerass')
}),
onClicked: (self) => {
App.toggleWindow('overview');
},
setup: setupCursorHover,
})
const AppButton = ({ icon, ...rest }) => Widget.Revealer({
attribute: {
'workspace': 0
},
revealChild: false,
transition: 'slide_right',
transitionDuration: userOptions.animations.durationLarge,
child: Widget.Button({
...rest,
className: 'dock-app-btn dock-app-btn-animate',
child: Widget.Box({
child: Widget.Overlay({
child: Widget.Box({
homogeneous: true,
className: 'dock-app-icon',
child: Widget.Icon({
icon: icon,
}),
}),
overlays: [Widget.Box({
class_name: 'indicator',
vpack: 'end',
hpack: 'center',
})],
}),
}),
setup: (button) => {
setupCursorHover(button);
}
})
});
const Taskbar = (monitor) => Widget.Box({
className: 'dock-apps',
attribute: {
monitor: monitor,
'map': new Map(),
'clientSortFunc': (a, b) => {
return a.attribute.workspace > b.attribute.workspace;
},
'update': (box, monitor) => {
for (let i = 0; i < Hyprland.clients.length; i++) {
const client = Hyprland.clients[i];
if (client["pid"] == -1) return;
const appClass = substitute(client.class);
// for (const appName of userOptions.dock.pinnedApps) {
// if (appClass.includes(appName.toLowerCase()))
// return null;
// }
let appClassLower = appClass.toLowerCase()
let path = ''
if (cachePath[appClassLower]) { path = cachePath[appClassLower] }
else {
path = searchIcons(appClass.toLowerCase(), icon_files)
cachePath[appClassLower] = path
}
if (path === '') { path = substitute(appClass) }
const newButton = AppButton({
icon: path,
tooltipText: `${client.title} (${appClass})`,
onClicked: () => focus(client),
});
newButton.attribute.workspace = client.workspace.id;
newButton.revealChild = true;
box.attribute.map.set(client.address, newButton);
}
box.children = Array.from(box.attribute.map.values());
},
'add': (box, address, monitor) => {
if (!address) { // First active emit is undefined
box.attribute.update(box);
return;
}
const newClient = Hyprland.clients.find(client => {
return client.address == address;
});
if (ExclusiveWindow(newClient)) { return }
let appClass = newClient.class
let appClassLower = appClass.toLowerCase()
let path = ''
if (cachePath[appClassLower]) { path = cachePath[appClassLower] }
else {
path = searchIcons(appClassLower, icon_files)
cachePath[appClassLower] = path
}
if (path === '') { path = substitute(appClass) }
const newButton = AppButton({
icon: path,
tooltipText: `${newClient.title} (${appClass})`,
onClicked: () => focus(newClient),
})
newButton.attribute.workspace = newClient.workspace.id;
box.attribute.map.set(address, newButton);
box.children = Array.from(box.attribute.map.values());
newButton.revealChild = true;
},
'remove': (box, address) => {
if (!address) return;
const removedButton = box.attribute.map.get(address);
if (!removedButton) return;
removedButton.revealChild = false;
Utils.timeout(userOptions.animations.durationLarge, () => {
removedButton.destroy();
box.attribute.map.delete(address);
box.children = Array.from(box.attribute.map.values());
})
},
},
setup: (self) => {
self.hook(Hyprland, (box, address) => box.attribute.add(box, address, self.monitor), 'client-added')
.hook(Hyprland, (box, address) => box.attribute.remove(box, address, self.monitor), 'client-removed')
Utils.timeout(100, () => self.attribute.update(self));
},
});
const PinnedApps = () => Widget.Box({
class_name: 'dock-apps',
homogeneous: true,
children: userOptions.dock.pinnedApps
.map(term => ({ app: Applications.query(term)?.[0], term }))
.filter(({ app }) => app)
.map(({ app, term = true }) => {
const newButton = AppButton({
// different icon, emm...
icon: userOptions.dock.searchPinnedAppIcons ?
searchIcons(app.name, icon_files) :
app.icon_name,
onClicked: () => {
for (const client of Hyprland.clients) {
if (client.class.toLowerCase().includes(term))
return focus(client);
}
app.launch();
},
onMiddleClick: () => app.launch(),
tooltipText: app.name,
setup: (self) => {
self.revealChild = true;
self.hook(Hyprland, button => {
const running = Hyprland.clients
.find(client => client.class.toLowerCase().includes(term)) || false;
button.toggleClassName('notrunning', !running);
button.toggleClassName('focused', Hyprland.active.client.address == running.address);
button.set_tooltip_text(running ? running.title : app.name);
}, 'notify::clients')
},
})
newButton.revealChild = true;
return newButton;
}),
});
export default (monitor = 0) => {
const dockContent = Box({
className: 'dock-bg spacing-h-5',
children: [
PinButton(),
PinnedApps(),
DockSeparator(),
Taskbar(),
LauncherButton(),
]
})
const dockRevealer = Revealer({
attribute: {
'updateShow': self => { // I only use mouse to resize. I don't care about keyboard resize if that's a thing
if (userOptions.dock.monitorExclusivity)
self.revealChild = Hyprland.active.monitor.id === monitor;
else
self.revealChild = true;
return self.revealChild
}
},
revealChild: false,
transition: 'slide_up',
transitionDuration: userOptions.animations.durationLarge,
child: dockContent,
setup: (self) => {
const callback = (self, trigger) => {
if (!userOptions.dock.trigger.includes(trigger)) return
const flag = self.attribute.updateShow(self)
if (flag) clearTimes();
const hidden = userOptions.dock.autoHide.find(e => e["trigger"] === trigger)
if (hidden) {
let id = Utils.timeout(hidden.interval, () => {
if (!isPinned) { self.revealChild = false }
timers = timers.filter(e => e !== id)
})
timers.push(id)
}
}
self
// .hook(Hyprland, (self) => self.attribute.updateShow(self))
.hook(Hyprland.active.workspace, self => callback(self, "workspace-active"))
.hook(Hyprland.active.client, self => callback(self, "client-active"))
.hook(Hyprland, self => callback(self, "client-added"), "client-added")
.hook(Hyprland, self => callback(self, "client-removed"), "client-removed")
},
})
return EventBox({
onHover: () => {
dockRevealer.revealChild = true;
clearTimes()
},
child: Box({
homogeneous: true,
css: `min-height: ${userOptions.dock.hiddenThickness}px;`,
children: [dockRevealer],
}),
setup: self => self.on("leave-notify-event", () => {
if (!isPinned) dockRevealer.revealChild = false;
clearTimes()
})
})
}
-63
View File
@@ -1,63 +0,0 @@
const { Gio, GLib } = imports.gi
const exists = (path) => Gio.File.new_for_path(path).query_exists(null);
export const levenshteinDistance = (a, b) => {
if (!a.length) { return b.length }
if (!b.length) { return a.length }
let f = Array.from(new Array(a.length + 1),
() => new Array(b.length + 1).fill(0))
for (let i = 0; i <= b.length; i++) { f[0][i] = i; }
for (let i = 0; i <= a.length; i++) { f[i][0] = i; }
for (let i = 1; i <= a.length; i++) {
for (let j = 1; j <= b.length; j++) {
if (a.charAt(i - 1) === b.charAt(j - 1)) {
f[i][j] = f[i-1][j-1]
} else {
f[i][j] = Math.min(f[i-1][j-1], Math.min(f[i][j-1], f[i-1][j])) + 1
}
}
}
return f[a.length][b.length]
}
export const getAllFiles = (dir, files = []) => {
if (!exists(dir)) { return [] }
const file = Gio.File.new_for_path(dir);
const enumerator = file.enumerate_children('standard::name,standard::type',
Gio.FileQueryInfoFlags.NONE, null);
for (const info of enumerator) {
if (info.get_file_type() === Gio.FileType.DIRECTORY) {
files.push(getAllFiles(`${dir}/${info.get_name()}`))
} else {
files.push(`${dir}/${info.get_name()}`)
}
}
return files.flat(1);
}
export const searchIcons = (appClass, files) => {
appClass = appClass.toLowerCase()
if (!files.length) { return "" }
let appro = 0x3f3f3f3f
let path = ""
for (const item of files) {
let score = levenshteinDistance(item.split("/").pop().toLowerCase().split(".")[0], appClass)
if (score < appro) {
appro = score
path = item
}
}
return path
}
-12
View File
@@ -1,12 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Dock from './dock.js';
export default (monitor = 0) => Widget.Window({
monitor,
name: `dock${monitor}`,
layer: userOptions.dock.layer,
anchor: ['bottom'],
exclusivity: 'normal',
visible: true,
child: Dock(monitor),
});
@@ -1,236 +0,0 @@
const { Gio, GLib } = imports.gi;
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import { ConfigToggle, ConfigMulipleSelection } from '../.commonwidgets/configwidgets.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync } = Utils;
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
import { showColorScheme } from '../../variables.js';
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
import { darkMode } from '../.miscutils/system.js';
const ColorBox = ({
name = 'Color',
...rest
}) => Widget.Box({
...rest,
homogeneous: true,
children: [
Widget.Label({
label: `${name}`,
})
]
})
const ColorSchemeSettingsRevealer = () => {
const headerButtonIcon = MaterialIcon('expand_more', 'norm');
const header = Widget.Button({
className: 'osd-settings-btn-arrow',
onClicked: () => {
content.revealChild = !content.revealChild;
headerButtonIcon.label = content.revealChild ? 'expand_less' : 'expand_more';
},
setup: setupCursorHover,
hpack: 'end',
child: headerButtonIcon,
});
const content = Widget.Revealer({
revealChild: false,
transition: 'slide_down',
transitionDuration: 200,
child: ColorSchemeSettings(),
setup: (self) => self.hook(isHoveredColorschemeSettings, (revealer) => {
if (isHoveredColorschemeSettings.value == false) {
setTimeout(() => {
if (isHoveredColorschemeSettings.value == false)
revealer.revealChild = false;
headerButtonIcon.label = 'expand_more';
}, 1500);
}
}),
});
return Widget.EventBox({
onHover: (self) => {
isHoveredColorschemeSettings.setValue(true);
},
onHoverLost: (self) => {
isHoveredColorschemeSettings.setValue(false);
},
child: Widget.Box({
vertical: true,
children: [
header,
content,
]
}),
});
}
function calculateSchemeInitIndex(optionsArr, searchValue = 'vibrant') {
if (searchValue == '')
searchValue = 'vibrant';
const flatArray = optionsArr.flatMap(subArray => subArray);
const result = flatArray.findIndex(element => element.value === searchValue);
const rowIndex = Math.floor(result / optionsArr[0].length);
const columnIndex = result % optionsArr[0].length;
return [rowIndex, columnIndex];
}
const schemeOptionsArr = [
[
{ name: getString('Tonal Spot'), value: 'tonalspot' },
{ name: getString('Fruit Salad'), value: 'fruitsalad' },
{ name: getString('Fidelity'), value: 'fidelity' },
{ name: getString('Rainbow'), value: 'rainbow' },
],
[
{ name: getString('Neutral'), value: 'neutral' },
{ name: getString('Monochrome'), value: 'monochrome' },
{ name: getString('Expressive'), value: 'expressive' },
{ name: getString('Vibrant'), value: 'vibrant' },
],
[
{ name: getString('Vibrant+'), value: 'morevibrant' },
],
//[
// { name: getString('Content'), value: 'content' },
//]
];
const LIGHTDARK_FILE_LOCATION = `${GLib.get_user_state_dir()}/ags/user/colormode.txt`;
const initTransparency = Utils.exec(`bash -c "sed -n \'2p\' ${LIGHTDARK_FILE_LOCATION}"`);
const initTransparencyVal = (initTransparency == "transparent") ? 1 : 0;
const initScheme = Utils.exec(`bash -c "sed -n \'3p\' ${LIGHTDARK_FILE_LOCATION}"`);
const initSchemeIndex = calculateSchemeInitIndex(schemeOptionsArr, initScheme);
const ColorSchemeSettings = () => Widget.Box({
className: 'osd-colorscheme-settings spacing-v-5 margin-20',
vertical: true,
vpack: 'center',
children: [
Widget.Box({
vertical: true,
children: [
Widget.Label({
xalign: 0,
className: 'txt-norm titlefont txt',
label: getString('Options'),
hpack: 'center',
}),
//////////////////
ConfigToggle({
icon: 'dark_mode',
name: getString('Dark Mode'),
desc: getString('Ya should go to sleep!'),
initValue: darkMode.value,
onChange: (_, newValue) => {
darkMode.value = !!newValue;
},
extraSetup: (self) => self.hook(darkMode, (self) => {
self.attribute.enabled.value = darkMode.value;
}),
}),
ConfigToggle({
icon: 'border_clear',
name: getString('Transparency'),
desc: getString('Make shell elements transparent'),
initValue: initTransparencyVal,
onChange: (self, newValue) => {
let transparency = newValue == 0 ? "opaque" : "transparent";
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_state_dir()}/ags/user && sed -i "2s/.*/${transparency}/" ${GLib.get_user_state_dir()}/ags/user/colormode.txt`])
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`]))
.catch(print);
},
}),
]
}),
Widget.Box({
vertical: true,
className: 'spacing-v-5',
children: [
Widget.Label({
xalign: 0,
className: 'txt-norm titlefont txt margin-top-5',
label: getString('Scheme styles'),
hpack: 'center',
}),
//////////////////
ConfigMulipleSelection({
hpack: 'center',
vpack: 'center',
optionsArr: schemeOptionsArr,
initIndex: initSchemeIndex,
onChange: (value, name) => {
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_state_dir()}/ags/user && sed -i "3s/.*/${value}/" ${GLib.get_user_state_dir()}/ags/user/colormode.txt`])
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`]))
.catch(print);
},
}),
]
})
]
});
const ColorschemeContent = () => Widget.Box({
className: 'osd-colorscheme spacing-v-5',
vertical: true,
hpack: 'center',
children: [
Widget.Label({
xalign: 0,
className: 'txt-norm titlefont txt',
label: getString('Color scheme'),
hpack: 'center',
}),
Widget.Box({
className: 'spacing-h-5',
hpack: 'center',
children: [
ColorBox({ name: 'P', className: 'osd-color osd-color-primary' }),
ColorBox({ name: 'S', className: 'osd-color osd-color-secondary' }),
ColorBox({ name: 'T', className: 'osd-color osd-color-tertiary' }),
ColorBox({ name: 'Sf', className: 'osd-color osd-color-surface' }),
ColorBox({ name: 'Sf-i', className: 'osd-color osd-color-inverseSurface' }),
ColorBox({ name: 'E', className: 'osd-color osd-color-error' }),
]
}),
Widget.Box({
className: 'spacing-h-5',
hpack: 'center',
children: [
ColorBox({ name: 'P-c', className: 'osd-color osd-color-primaryContainer' }),
ColorBox({ name: 'S-c', className: 'osd-color osd-color-secondaryContainer' }),
ColorBox({ name: 'T-c', className: 'osd-color osd-color-tertiaryContainer' }),
ColorBox({ name: 'Sf-c', className: 'osd-color osd-color-surfaceContainer' }),
ColorBox({ name: 'Sf-v', className: 'osd-color osd-color-surfaceVariant' }),
ColorBox({ name: 'E-c', className: 'osd-color osd-color-errorContainer' }),
]
}),
ColorSchemeSettingsRevealer(),
]
});
const isHoveredColorschemeSettings = Variable(false);
export default () => Widget.Revealer({
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
child: ColorschemeContent(),
setup: (self) => {
self
.hook(showColorScheme, (revealer) => {
if (showColorScheme.value == true)
revealer.revealChild = true;
else
revealer.revealChild = isHoveredColorschemeSettings.value;
})
.hook(isHoveredColorschemeSettings, (revealer) => {
if (isHoveredColorschemeSettings.value == false) {
setTimeout(() => {
if (isHoveredColorschemeSettings.value == false)
revealer.revealChild = showColorScheme.value;
}, 2000);
}
})
},
})
@@ -1,133 +0,0 @@
// This file is for brightness/volume indicators
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
const { Box, Label, ProgressBar } = Widget;
import { MarginRevealer } from '../.widgethacks/advancedrevealers.js';
import Brightness from '../../services/brightness.js';
import Indicator from '../../services/indicator.js';
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
const OsdValue = ({
name, icon, nameSetup = undefined, labelSetup, progressSetup,
extraClassName = '', extraProgressClassName = '',
...rest
}) => {
const valueName = Label({
xalign: 0, yalign: 0, hexpand: true,
className: 'osd-label',
label: `${name}`,
setup: nameSetup,
});
const valueNumber = Label({
hexpand: false, className: 'osd-value-txt',
setup: labelSetup,
});
return Box({ // Volume
hexpand: true,
className: `osd-bg osd-value ${extraClassName} spacing-h-5`,
attribute: {
'disable': () => {
valueNumber.label = '󰖭';
}
},
children: [
MaterialIcon(icon, 'hugeass', {vpack: 'center'}),
Box({
vertical: true,
className: 'spacing-v-5',
vpack: 'center',
children: [
Box({
children: [
valueName,
valueNumber,
]
}),
ProgressBar({
className: `osd-progress ${extraProgressClassName}`,
hexpand: true,
vertical: false,
setup: progressSetup,
})
]
})
],
...rest,
});
}
export default (monitor = 0) => {
const brightnessIndicator = OsdValue({
name: 'Brightness',
icon: 'light_mode',
extraClassName: 'osd-brightness',
extraProgressClassName: 'osd-brightness-progress',
labelSetup: (self) => self.hook(Brightness[monitor], self => {
self.label = `${Math.round(Brightness[monitor].screen_value * 100)}`;
}, 'notify::screen-value'),
progressSetup: (self) => self.hook(Brightness[monitor], (progress) => {
const updateValue = Brightness[monitor].screen_value;
if (updateValue !== progress.value) Indicator.popup(1);
progress.value = updateValue;
}, 'notify::screen-value'),
});
const volumeIndicator = OsdValue({
name: 'Volume',
icon: 'volume_up',
extraClassName: 'osd-volume',
extraProgressClassName: 'osd-volume-progress',
attribute: { headphones: undefined , device: undefined},
nameSetup: (self) => Utils.timeout(1, () => {
const updateAudioDevice = (self) => {
const usingHeadphones = (Audio.speaker?.stream?.port)?.toLowerCase().includes('headphone');
if (volumeIndicator.attribute.headphones === undefined ||
volumeIndicator.attribute.headphones !== usingHeadphones) {
volumeIndicator.attribute.headphones = usingHeadphones;
self.label = usingHeadphones ? 'Headphones' : 'Speakers';
// Indicator.popup(1);
}
}
self.hook(Audio, updateAudioDevice);
Utils.timeout(1000, updateAudioDevice);
}),
labelSetup: (self) => self.hook(Audio, (label) => {
const newDevice = (Audio.speaker?.name);
const updateValue = Math.round(Audio.speaker?.volume * 100);
if (!isNaN(updateValue)) {
if (newDevice === volumeIndicator.attribute.device && updateValue != label.label) {
Indicator.popup(1);
}
}
volumeIndicator.attribute.device = newDevice;
label.label = `${updateValue}`;
}),
progressSetup: (self) => self.hook(Audio, (progress) => {
const updateValue = Audio.speaker?.volume;
if (!isNaN(updateValue)) {
if (updateValue > 1) progress.value = 1;
else progress.value = updateValue;
}
}),
});
return MarginRevealer({
transition: 'slide_down',
showClass: 'osd-show',
hideClass: 'osd-hide',
extraSetup: (self) => self
.hook(Indicator, (revealer, value) => {
if (value > -1) revealer.attribute.show();
else revealer.attribute.hide();
}, 'popup')
,
child: Box({
hpack: 'center',
vertical: false,
className: 'spacing-h--10',
children: [
brightnessIndicator,
volumeIndicator,
]
})
});
}
-32
View File
@@ -1,32 +0,0 @@
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Indicator from '../../services/indicator.js';
import IndicatorValues from './indicatorvalues.js';
import MusicControls from './musiccontrols.js';
import ColorScheme from './colorscheme.js';
import NotificationPopups from './notificationpopups.js';
export default (monitor = 0) => Widget.Window({
name: `indicator${monitor}`,
monitor,
className: 'indicator',
layer: 'overlay',
// exclusivity: 'ignore',
visible: true,
anchor: ['top'],
child: Widget.EventBox({
onHover: () => { //make the widget hide when hovering
Indicator.popup(-1);
},
child: Widget.Box({
vertical: true,
className: 'osd-window',
css: 'min-height: 2px;',
children: [
IndicatorValues(monitor),
MusicControls(),
NotificationPopups(),
ColorScheme(),
]
})
}),
});
@@ -1,412 +0,0 @@
const { GLib } = imports.gi;
import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js';
const { exec, execAsync } = Utils;
const { Box, EventBox, Icon, Scrollable, Label, Button, Revealer } = Widget;
import { fileExists } from '../.miscutils/files.js';
import { AnimatedCircProg } from "../.commonwidgets/cairo_circularprogress.js";
import { showMusicControls } from '../../variables.js';
import { darkMode, hasPlasmaIntegration } from '../.miscutils/system.js';
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
const COMPILED_STYLE_DIR = `${GLib.get_user_cache_dir()}/ags/user/generated`
const LIGHTDARK_FILE_LOCATION = `${GLib.get_user_state_dir()}/ags/user/colormode.txt`;
const colorMode = Utils.exec(`bash -c "sed -n \'1p\' '${LIGHTDARK_FILE_LOCATION}'"`);
const lightDark = (colorMode == "light") ? 'light' : '';
const COVER_COLORSCHEME_SUFFIX = '_colorscheme.css';
var lastCoverPath = '';
function isRealPlayer(player) {
return (
// Remove unecessary native buses from browsers if there's plasma integration
!(hasPlasmaIntegration && player.busName.startsWith('org.mpris.MediaPlayer2.firefox')) &&
!(hasPlasmaIntegration && player.busName.startsWith('org.mpris.MediaPlayer2.chromium')) &&
// playerctld just copies other buses and we don't need duplicates
!player.busName.startsWith('org.mpris.MediaPlayer2.playerctld') &&
// Non-instance mpd bus
!(player.busName.endsWith('.mpd') && !player.busName.endsWith('MediaPlayer2.mpd'))
);
}
export const getPlayer = (name = userOptions.music.preferredPlayer) => Mpris.getPlayer(name) || Mpris.players[0] || null;
function lengthStr(length) {
const min = Math.floor(length / 60);
const sec = Math.floor(length % 60);
const sec0 = sec < 10 ? '0' : '';
return `${min}:${sec0}${sec}`;
}
function detectMediaSource(link) {
if (link.startsWith("file://")) {
if (link.includes('firefox-mpris'))
return '󰈹 Firefox'
return "󰈣 File";
}
let url = link.replace(/(^\w+:|^)\/\//, '');
let domain = url.match(/(?:[a-z]+\.)?([a-z]+\.[a-z]+)/i)[1];
if (domain == 'ytimg.com') return '󰗃 Youtube';
if (domain == 'discordapp.net') return '󰙯 Discord';
if (domain == 'sndcdn.com') return '󰓀 SoundCloud';
return domain;
}
const DEFAULT_MUSIC_FONT = 'Gabarito, sans-serif';
function getTrackfont(player) {
const title = player.trackTitle;
const artists = player.trackArtists.join(' ');
if (artists.includes('TANO*C') || artists.includes('USAO') || artists.includes('Kobaryo'))
return 'Chakra Petch'; // Rigid square replacement
if (title.includes('東方'))
return 'Crimson Text, serif'; // Serif for Touhou stuff
return DEFAULT_MUSIC_FONT;
}
function trimTrackTitle(title) {
if (!title) return '';
const cleanPatterns = [
/【[^】]*】/, // Touhou n weeb stuff
" [FREE DOWNLOAD]", // F-777
];
cleanPatterns.forEach((expr) => title = title.replace(expr, ''));
return title;
}
const TrackProgress = ({ player, ...rest }) => {
const _updateProgress = (circprog) => {
// const player = Mpris.getPlayer();
if (!player) return;
// Set circular progress (see definition of AnimatedCircProg for explanation)
circprog.css = `font-size: ${Math.max(player.position / player.length * 100, 0)}px;`
}
return AnimatedCircProg({
...rest,
className: 'osd-music-circprog',
vpack: 'center',
extraSetup: (self) => self
.hook(Mpris, _updateProgress)
.poll(3000, _updateProgress)
,
})
}
const TrackTitle = ({ player, ...rest }) => Label({
...rest,
label: 'No music playing',
xalign: 0,
truncate: 'end',
// wrap: true,
className: 'osd-music-title',
setup: (self) => self.hook(player, (self) => {
// Player name
self.label = player.trackTitle.length > 0 ? trimTrackTitle(player.trackTitle) : 'No media';
// Font based on track/artist
const fontForThisTrack = getTrackfont(player);
self.css = `font-family: ${fontForThisTrack}, ${DEFAULT_MUSIC_FONT};`;
}, 'notify::track-title'),
});
const TrackArtists = ({ player, ...rest }) => Label({
...rest,
xalign: 0,
className: 'osd-music-artists',
truncate: 'end',
setup: (self) => self.hook(player, (self) => {
self.label = player.trackArtists.length > 0 ? player.trackArtists.join(', ') : '';
}, 'notify::track-artists'),
})
const CoverArt = ({ player, ...rest }) => {
const fallbackCoverArt = Box({ // Fallback
className: 'osd-music-cover-fallback',
homogeneous: true,
children: [Label({
className: 'icon-material txt-gigantic txt-thin',
label: 'music_note',
})]
});
// const coverArtDrawingArea = Widget.DrawingArea({ className: 'osd-music-cover-art' });
// const coverArtDrawingAreaStyleContext = coverArtDrawingArea.get_style_context();
const realCoverArt = Box({
className: 'osd-music-cover-art',
homogeneous: true,
// children: [coverArtDrawingArea],
attribute: {
'pixbuf': null,
// 'showImage': (self, imagePath) => {
// const borderRadius = coverArtDrawingAreaStyleContext.get_property('border-radius', Gtk.StateFlags.NORMAL);
// const frameHeight = coverArtDrawingAreaStyleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
// const frameWidth = coverArtDrawingAreaStyleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
// let imageHeight = frameHeight;
// let imageWidth = frameWidth;
// // Get image dimensions
// execAsync(['identify', '-format', '{"w":%w,"h":%h}', imagePath])
// .then((output) => {
// const imageDimensions = JSON.parse(output);
// const imageAspectRatio = imageDimensions.w / imageDimensions.h;
// const displayedAspectRatio = imageWidth / imageHeight;
// if (imageAspectRatio >= displayedAspectRatio) {
// imageWidth = imageHeight * imageAspectRatio;
// } else {
// imageHeight = imageWidth / imageAspectRatio;
// }
// // Real stuff
// // TODO: fix memory leak(?)
// // if (self.attribute.pixbuf) {
// // self.attribute.pixbuf.unref();
// // self.attribute.pixbuf = null;
// // }
// self.attribute.pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(imagePath, imageWidth, imageHeight);
// coverArtDrawingArea.set_size_request(frameWidth, frameHeight);
// coverArtDrawingArea.connect("draw", (widget, cr) => {
// // Clip a rounded rectangle area
// cr.arc(borderRadius, borderRadius, borderRadius, Math.PI, 1.5 * Math.PI);
// cr.arc(frameWidth - borderRadius, borderRadius, borderRadius, 1.5 * Math.PI, 2 * Math.PI);
// cr.arc(frameWidth - borderRadius, frameHeight - borderRadius, borderRadius, 0, 0.5 * Math.PI);
// cr.arc(borderRadius, frameHeight - borderRadius, borderRadius, 0.5 * Math.PI, Math.PI);
// cr.closePath();
// cr.clip();
// // Paint image as bg, centered
// Gdk.cairo_set_source_pixbuf(cr, self.attribute.pixbuf,
// frameWidth / 2 - imageWidth / 2,
// frameHeight / 2 - imageHeight / 2
// );
// cr.paint();
// });
// }).catch(print)
// },
'updateCover': (self) => {
// const player = Mpris.getPlayer(); // Maybe no need to re-get player.. can't remember why I had this
// Player closed
// Note that cover path still remains, so we're checking title
if (!player || player.trackTitle == "" || !player.coverPath) {
self.css = `background-image: none;`; // CSS image
App.applyCss(`${COMPILED_STYLE_DIR}/style.css`);
return;
}
const coverPath = player.coverPath;
const stylePath = `${player.coverPath}${darkMode.value ? '' : '-l'}${COVER_COLORSCHEME_SUFFIX}`;
if (player.coverPath == lastCoverPath) { // Since 'notify::cover-path' emits on cover download complete
Utils.timeout(200, () => {
// self.attribute.showImage(self, coverPath);
self.css = `background-image: url('${coverPath}');`; // CSS image
});
}
lastCoverPath = player.coverPath;
// If a colorscheme has already been generated, skip generation
if (fileExists(stylePath)) {
// self.attribute.showImage(self, coverPath)
self.css = `background-image: url('${coverPath}');`; // CSS image
App.applyCss(stylePath);
return;
}
// Generate colors
execAsync(['bash', '-c',
`${App.configDir}/scripts/color_generation/generate_colors_material.py --path '${coverPath}' --mode ${darkMode.value ? 'dark' : 'light'} > ${GLib.get_user_state_dir()}/ags/scss/_musicmaterial.scss`])
.then(() => {
exec(`${App.configDir}/scripts/color_generation/pywal.sh -i "${player.coverPath}" -n -t -s -e -q ${darkMode.value ? '' : '-l'}`)
exec(`cp ${GLib.get_user_cache_dir()}/wal/colors.scss ${GLib.get_user_state_dir()}/ags/scss/_musicwal.scss`);
exec(`sass -I "${GLib.get_user_state_dir()}/ags/scss" -I "${App.configDir}/scss/fallback" "${App.configDir}/scss/_music.scss" "${stylePath}"`);
Utils.timeout(200, () => {
// self.attribute.showImage(self, coverPath)
self.css = `background-image: url('${coverPath}');`; // CSS image
});
App.applyCss(`${stylePath}`);
})
.catch(print);
},
},
setup: (self) => self
.hook(player, (self) => {
self.attribute.updateCover(self);
}, 'notify::cover-path')
,
});
return Box({
...rest,
className: 'osd-music-cover',
children: [
Widget.Overlay({
child: fallbackCoverArt,
overlays: [realCoverArt],
})
],
})
}
const TrackControls = ({ player, ...rest }) => Widget.Revealer({
revealChild: false,
transition: 'slide_right',
transitionDuration: userOptions.animations.durationLarge,
child: Widget.Box({
...rest,
vpack: 'center',
className: 'osd-music-controls spacing-h-3',
children: [
Button({
className: 'osd-music-controlbtn',
onClicked: () => player.previous(),
child: Label({
className: 'icon-material osd-music-controlbtn-txt',
label: 'skip_previous',
}),
setup: setupCursorHover
}),
Button({
className: 'osd-music-controlbtn',
onClicked: () => player.next(),
child: Label({
className: 'icon-material osd-music-controlbtn-txt',
label: 'skip_next',
}),
setup: setupCursorHover
}),
],
}),
setup: (self) => self.hook(Mpris, (self) => {
// const player = Mpris.getPlayer();
if (!player)
self.revealChild = false;
else
self.revealChild = true;
}, 'notify::play-back-status'),
});
const TrackSource = ({ player, ...rest }) => Widget.Revealer({
revealChild: false,
transition: 'slide_left',
transitionDuration: userOptions.animations.durationLarge,
child: Widget.Box({
...rest,
className: 'osd-music-pill spacing-h-5',
homogeneous: true,
children: [
Label({
hpack: 'fill',
justification: 'center',
className: 'icon-nerd',
setup: (self) => self.hook(player, (self) => {
self.label = detectMediaSource(player.trackCoverUrl);
}, 'notify::cover-path'),
}),
],
}),
setup: (self) => self.hook(Mpris, (self) => {
const mpris = Mpris.getPlayer('');
if (!mpris)
self.revealChild = false;
else
self.revealChild = true;
}),
});
const TrackTime = ({ player, ...rest }) => {
return Widget.Revealer({
revealChild: false,
transition: 'slide_left',
transitionDuration: userOptions.animations.durationLarge,
child: Widget.Box({
...rest,
vpack: 'center',
className: 'osd-music-pill spacing-h-5',
children: [
Label({
setup: (self) => self.poll(1000, (self) => {
// const player = Mpris.getPlayer();
if (!player) return;
self.label = lengthStr(player.position);
}),
}),
Label({ label: '/' }),
Label({
setup: (self) => self.hook(Mpris, (self) => {
// const player = Mpris.getPlayer();
if (!player) return;
self.label = lengthStr(player.length);
}),
}),
],
}),
setup: (self) => self.hook(Mpris, (self) => {
if (!player) self.revealChild = false;
else self.revealChild = true;
}),
})
}
const PlayState = ({ player }) => {
var position = 0;
const trackCircProg = TrackProgress({ player: player });
return Widget.Button({
className: 'osd-music-playstate',
child: Widget.Overlay({
child: trackCircProg,
overlays: [
Widget.Button({
className: 'osd-music-playstate-btn',
onClicked: () => player.playPause(),
child: Widget.Label({
justification: 'center',
hpack: 'fill',
vpack: 'center',
setup: (self) => self.hook(player, (label) => {
label.label = `${player.playBackStatus == 'Playing' ? 'pause' : 'play_arrow'}`;
}, 'notify::play-back-status'),
}),
setup: setupCursorHover
}),
],
passThrough: true,
}),
});
}
const MusicControlsWidget = (player) => Box({
className: 'osd-music spacing-h-20 test',
children: [
CoverArt({ player: player, vpack: 'center' }),
Box({
vertical: true,
className: 'spacing-v-5 osd-music-info',
children: [
Box({
vertical: true,
vpack: 'center',
hexpand: true,
children: [
TrackTitle({ player: player }),
TrackArtists({ player: player }),
]
}),
Box({ vexpand: true }),
Box({
className: 'spacing-h-10',
setup: (box) => {
box.pack_start(TrackControls({ player: player }), false, false, 0);
box.pack_end(PlayState({ player: player }), false, false, 0);
if(hasPlasmaIntegration || player.busName.startsWith('org.mpris.MediaPlayer2.chromium')) box.pack_end(TrackTime({ player: player }), false, false, 0)
// box.pack_end(TrackSource({ vpack: 'center', player: player }), false, false, 0);
}
})
]
})
]
})
export default () => Revealer({
transition: 'slide_down',
transitionDuration: userOptions.animations.durationLarge,
revealChild: false,
child: Box({
children: Mpris.bind("players")
.as(players => players.map((player) => (isRealPlayer(player) ? MusicControlsWidget(player) : null)))
}),
setup: (self) => self.hook(showMusicControls, (revealer) => {
revealer.revealChild = showMusicControls.value;
}),
})
@@ -1,45 +0,0 @@
// This file is for popup notifications
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
const { Box } = Widget;
import Notification from '../.commonwidgets/notification.js';
export default () => Box({
vertical: true,
hpack: 'center',
className: 'osd-notifs spacing-v-5-revealer',
attribute: {
'map': new Map(),
'dismiss': (box, id, force = false) => {
if (!id || !box.attribute.map.has(id))
return;
const notifWidget = box.attribute.map.get(id);
if (notifWidget == null || notifWidget.attribute.hovered && !force)
return; // cuz already destroyed
notifWidget.revealChild = false;
notifWidget.attribute.destroyWithAnims();
box.attribute.map.delete(id);
},
'notify': (box, id) => {
if (!id || Notifications.dnd) return;
if (!Notifications.getNotification(id)) return;
box.attribute.map.delete(id);
const notif = Notifications.getNotification(id);
const newNotif = Notification({
notifObject: notif,
isPopup: true,
});
box.attribute.map.set(id, newNotif);
box.pack_end(box.attribute.map.get(id), false, false, 0);
box.show_all();
},
},
setup: (self) => self
.hook(Notifications, (box, id) => box.attribute.notify(box, id), 'notified')
.hook(Notifications, (box, id) => box.attribute.dismiss(box, id), 'dismissed')
.hook(Notifications, (box, id) => box.attribute.dismiss(box, id, true), 'closed')
,
});

Some files were not shown because too many files have changed in this diff Show More