Restructure Config Categories
There are some problems with the way the config categories are laid out, and which settings are where. Changing any of these and moving these around is gonna cause some breaking changes here, but IMO these changes are necessary to create a more coherent configuration UX.
Just so we're on the same page, I'm gonna include a stub of the current configuration format, and by the end of the proposal, I'll provide a restructured stub that incorporates the changes I'm about to propose. Here's the current stub:
View Current Config Stub
[notification-center]
# Margin at the top of the notification center in pixels. This can be
# used to avoid overlap between the notification center and bars such
# as polybar or i3blocks.
marginTop = 0
# Margin at the bottom of the notification center in pixels.
marginBottom = 0
# Margin to the right of the notification center in pixels.
marginRight = 0
# Width of the notification center in pixels.
width = 500
# Monitor on which the notification center will be printed.
monitor = 0
# If true, the notification center will open on the screen, on which the
# mouse is
followMouse = false
# (Optional) Command to run at startup. This can be used to setup
# button states.
# startupCommand = "deadd-notification-center-startup"
# If newFirst is set to true, newest notifications appear on the top
# of the notification center. Else, notifications stack, from top to
# bottom.
newFirst = true
# Text size for the time in the notification center
timeTextSize = 32px
# If true, the transient field in notifications will be ignored and
# the notification will be persisted in the notification center anyways
ignoreTransient = false
# If true, markup (<u>, <i>, <b>, <a> , <img>) will be displayed properly
useMarkup = true
# If true, html entities (& for &, % for %, etc) will be parsed
# properly. This is useful for chromium-based apps, which tend to send
# these in notifications.
parseHtmlEntities = true
# If set to true, the parameter noClosedMsg can be set on
# notifications. If noClosedMsg is set to true on a notification,
# DBUS NotificationClosed messages will not be send for this
# notification.
configSendNotiClosedDbusMessage = false
# If set to true: If no icon is passed by the app_icon parameter
# and no application "desktop-entry"-hint is present, the notification
# center will try to guess the icon from the application name (if present).
# Default is true.
guessIconFromAppname = true
# See section "Notification based scripting" for an explanation
#match = "title=Abc;body=abc":"app=notify-send"
#modify = "transient=false"
#run = "":"killall notify-send"
[notification-center-notification-popup]
# Default timeout used for notifications in milli-seconds. This can
# be overwritten with the "-t" option (or "--expire-time") of the
# notify-send command.
notiDefaultTimeout = 10000
# Margin above notifications (in pixels). This can be used to avoid
# overlap between notifications and a bar such as polybar or i3blocks.
distanceTop = 50
# Margin on the right of the notification (in pixels).
distanceRight = 50
# Vertical distance between 2 notifications (in pixels).
distanceBetween = 20
# Width of the notifications.
width = 300
# Monitor on which the notification will be printed.
monitor = 0
# If true, the notifications will open on the screen, on which the
# mouse is
followMouse = false
# The display size of the application icons in the notification
# pop-ups and in the notification center
iconSize = 20
# Text size for the title in the notification pop-ups
titleTextSize = 16px
# Text size for the app name in the notification pop-ups
appNameTextSize = 12px
# Text size for the time in the notification pop-ups
timeTextSize = 12px
# The maximal display size of images that are part of notifications
# for notification pop-ups and in the notification center
maxImageSize = 100
# The mouse button for closing a popup. Must be either "mouse1",
# "mouse2", "mouse3", "mouse4", or "mouse5"
dismissButton = mouse1
# The mouse button for opening a popup with the default action.
# Must be either "mouse1", "mouse2", "mouse3", "mouse4", or "mouse5"
defaultActionButton = mouse3
[colors]
# Note about colors: Colors can be represented in (at least, I mean,
# who knows...) three different ways:
# 1. #RGB with "R", "G" and "B" hexadecimal numbers (0-9, A-F or
# a-f).
# 2. #RRGGBB with each occurrence of "R", "G" and "B" are hexadecimal
# numbers (0-9, A-F or a-f).
# 3. rgba(R, G, B, A) where "R", "G" and "B" are between 0 and 255
# and A is a floating point number between 0 and 1 representing
# the alpha channel (transparency).
# Background color for the notification center.
background = rgba(29, 27, 20, 0.6)
# Background color for the notification popups.
notiBackground = rgba(9, 0, 0, 0.5)
# Color for the text (summary, body and application name) in
# notification popups.
notiColor = #fef3f6
# Background color for "critical" notification popups.
critical = rgba(255, 0, 50, 0.5)
# Color for the text (summary, body and application name) in
# "critical" notification popups.
criticalColor = #FFF
# Background color for "critical" notifications in notification
# center.
criticalInCenter = rgba(155, 0, 20, 0.5)
# Color for the text (summary, body and application name) in
# "critical" notification in notification center.
criticalInCenterColor = #FFF
# Global text color
labelColor = #eae2e0
### These button configurations are applied globally (except they
### get overwritten in the [buttons] section. The buttons section
### only applies to the configurable buttons within the notification
### center, while these configs also apply to the buttons within
### notifications.)
# Color for the text in the buttons.
buttonColor = #eae2e0
# Background color of button in hover state (mouse over)
buttonHover = rgba(0, 20, 20, 0.2)
# Text color of button in hover state (mouse over)
buttonHoverColor = #fee
# Background color of button
buttonBackground = transparent
[buttons]
### This section describes the configurable buttons within the
### notification center and NOT the buttons that appear in the
### notifications
# Note: If you want your buttons in the notification center to be
# squares you should verify that the following equality holds:
# [notification-center]::width
# == [buttons]::buttonsPerRow * [buttons]::buttonHeight
# + ([buttons]::buttonsPerRow + 1) * [buttons]::buttonMargin
# Numbers of buttons that can be drawn on a row of the notification
# center.
buttonsPerRow = 5
# Height of buttons in the notification center (in pixels).
buttonHeight = 60
# Horizontal and vertical margin between each button in the
# notification center (in pixels).
buttonMargin = 2
# Labels written on the buttons in the notification center. Labels
# should be written between quotes and separated by a colon. For
# example:
# labels = "VPN":"Bluetooth":"Wifi":"Screensaver"
# Each label is represented as a clickable button in the notification
# center. The commands variable below define the commands that should
# be launched when the user clicks on the associated button. There
# should be the same number of entries in `commands` and in `labels`
# commands = "sudo vpnToggle":"bluetoothToggle":"wifiToggle":"screensaverToggle"
# Color of the labels of the custom buttons in the notification
# center.
buttonColor = #fee
# Color of the custom buttons' background in the notification center.
buttonBackground = rgba(255, 255, 255, 0.15)
# Color of the custom buttons' background in the notification center
# when hovered.
buttonHover = rgba(0, 20, 20, 0.2)
# Color of the labels of the custom buttons in the notification center
# when hovered.
buttonHoverColor = #fee
# Text size of the custom buttons in the notification center.
buttonTextSize = 12px;
# Color of the custom buttons' background in the notification center
# when its state is set to true as described in the Section Usage
buttonState1 = rgba(255,255,255,0.5)
# Color of the custom buttons' text in the notification center
# when its state is set to true as described in the Section Usage
buttonState1Color = #fff
# Color of the custom buttons' background, hovering, in the
# notification center when its state is set to true as described in
# the Section Usage
buttonState1Hover = rgba(0, 20, 20, 0.4)
# Color of the custom buttons' text, hovering, in the
# notification center when its state is set to true as described in
# the Section Usage
buttonState1HoverColor = #fee
# Color of the custom buttons' background, in the notification center
# when the button is clicked and not yet set to a new value via the
# method as described in Section Usage
buttonState2 = rgba(255,255,255,0.3)
# Color of the custom buttons' text, in the notification center
# when the button is clicked and not yet set to a new value via the
# method as described in Section Usage
buttonState2Color = #fff
# Color of the custom buttons' background,
# hovering, in the notification center when the button is clicked and
# not yet set to a new value via the method as described in Section
# Usage
buttonState2Hover = rgba(0, 20, 20, 0.3)
# Color of the custom buttons' text, hovering, in the notification
# center when the button is clicked and not yet set to a new value via
# the method as described in Section Usage
buttonState2HoverColor = #fee
Right off the bat, I have a few general complaints, and some quick notes:
- The categories use
kebab-case, but the settings themselves usecamelCase. IMO, kebab-case is a bit nicer for configuration files, or ini-style files. So, we should probably change all of the settings to make things a bit more consistent. - Many of the below examples will attempt to reduce the length of 'compound words' (e.g.
timeTextSize) by adding a dot between the 'parent' and the 'child' (e.g.time.text-size). This is just a nice addition, because it helps your eyes scan across the variable a bit better.
[notification-center]
- Some settings, like
useMarkup,parseHtmlEntities,guessIconFromAppname, etc, appear to be 'general' settings that affect all notifications, whether they're in the center, or whether they're a popup. Notification based scripting rules also falls under this criticism. - Some commands don't even really have anything to do with the notification center itself or notifications in general, such as
startupCommand. - Other settings, like
marginTop,followMouse,width,timeTextSize, etc, appear to be specific to the notification center itself, and do not apply to notifications at all.
I think the best way to resolve this problem is to split [notification-center] into 2 different categories: [notification-center] and [notification]. [notification] should be used for settings that should apply to all notifications. As we'll see, some settings from the [notification-center-notification-popup] section can be moved to this new [notification] section as well.
It might also help to create a [general] section. This would be a nice home for settings that really apply globally, like startupCommand. Not many of these settings exist yet, but many specific settings could have a global counterpart that they override, which would add a bit more logic to the configuration file.
For example, label color might have a global setting, but might also be overridden by the user in the notification center, or in the popup notifications.
[notification-center-notification-popup]
- Honestly, most of these settings don't have to do specifically with popup notifications. This includes
notiDefaultTimeout,iconSize,titleTextSize,appNameTextSize, etc. - This section's name is pretty verbose. Wouldn't
[notification.popup]or just[popup]be a bit better?
Settings like notiDefaultTimeout, iconSize, titleTextSize, appNameTextSize can just be moved to [notification]. I like the [notification.popup] name, because we could also use this same convention to have a [notification.in-center] section too, that might apply to all sections. For example, in #78, the shortening of the notification body should probably handled differently in the popup and the center.
Since there are many UI elements mentioned in this section, it might be best to use dot notation to better convey a parent-child relationship with some of these settings. For example:
-
iconSizeandappNameTextSizecan be renamed toapp.icon-sizeandapp.text-size. -
maxImageSizecan probably be renamed toicon-size, as long as there's a comment in the stub explaining that it's a maximum. -
titleTextSizecan likely be cut down totitle.text-size.
[colors]
- In this overview video, Brodie Robertson notes that this section was a bit confusing, since some things are handled by the GTK CSS, and some things are handled by this config. I kinda agree.
- It might make a bit more sense to move color settings to other sections, like how text size is handled.
I think there are a 2 main improvements that could be made in this category:
- As mentioned earlier, color-related settings should likely just be redistributed to other sections, since the sections seem to be organized more around UI 'views' than around lower-level UI concepts such as color. For example,
backgroundwould be renamed tobackgroundColorin the[notification-center]section. - To cut down on confusion about when / why to use GTK CSS, we should likely support the primary usecases for CSS in the config file. The most important usecase is arguably the font. After enough use cases are supported, we could drop the CSS section from the README to avoid confusion, and maybe put it in a wiki article or in a different 'advanced tips' file somewhere.
Restructured Stub
The main changes I used to restructure this stub were:
- Changed from
camelCasetokebab-case - renamed variables with more than 1 noun to use a
.separator between nouns. - Added a
[general]section for global defaults and misc. settings. - Added an 'overriding system' (honestly by override I just mean 'use if specific values are left out').
-
[notification-center]is now primarily used for things that specifically have to do with the actual notification center itself. - Added a
[notification]section, where settings that apply to all kinds of notifications live. Most settings came from the old[notification-center]and[notification-center-popup-notification]sections. - Renamed
[notification-center-popup-notification]to[notification-popup], and trimmed the fat from it. - Added
[notification.popup]and[notification.in-center], which are settings for popup notifications and notifications that are in-center, respectively. - Removed
[colors], and moved all its settings to more relevant sections.
View Restructured Config Stub
# Note about colors: Colors can be represented in (at least, I mean,
# who knows...) three different ways:
# 1. #RGB with "R", "G" and "B" hexadecimal numbers (0-9, A-F or
# a-f).
# 2. #RRGGBB with each occurrence of "R", "G" and "B" are hexadecimal
# numbers (0-9, A-F or a-f).
# 3. rgba(R, G, B, A) where "R", "G" and "B" are between 0 and 255
# and A is a floating point number between 0 and 1 representing
# the alpha channel (transparency).
[general]
# Default margin at the top of the notification center and popup area, specified
# in pixels. This can be used to avoid overlap between the
# notification-center/popups and bars such as polybar or i3blocks.
# This setting can be overridden in other sections.
margin-top = 0
# Default margin at the bottom of the notification center and popup area, in pixels.
# This setting can be overridden in other sections.
margin-bottom = 0
# Default margin to the right of the notification center and popup area, in pixels.
# This setting can be overridden in other sections.
margin-right = 0
# If true, all UI elements will be displayed on the monitor where the mouse is.
# This setting can be overridden in other sections.
follow-mouse = false
# Default text size.
# This setting can be overridden in other sections.
text-size = 16px
# Default text color
text-color = #eae2e0
# (Optional) Command to run at startup. This can be used to setup
# button states.
# startup-command = "deadd-notification-center-startup"
[notification-center]
# Margin at the top of the notification center in pixels. This can be
# used to avoid overlap between the notification center and bars such
# as polybar or i3blocks. Overrides [general]::margin-top.
margin-top = 0
# Margin at the bottom of the notification center in pixels. Overrides
# [general]::margin-bottom.
# margin-bottom = 0
# Margin to the right of the notification center in pixels. Overrides
# [general]::margin-right.
# margin-right = 0
# Width of the notification center in pixels.
width = 500
# Monitor on which the notification center will be printed.
monitor = 0
# If true, the notification center will open on the screen, on which the
# mouse is. Overrides [general]::follow-mouse.
follow-mouse = false
# If new-first is set to true, newest notifications appear on the top
# of the notification center. Else, notifications stack, from top to
# bottom.
new-first = true
# Text size for the time in the notification center. Overrides
# [general]::text-size.
time.text-size = 32px
# If true, the transient field in notifications will be ignored and
# the notification will be persisted in the notification center anyways
ignore-transient = false
# Background color for the notification center. Overrides
background-color = rgba(29, 27, 20, 0.6)
[notification]
# If true, markup (<u>, <i>, <b>, <a> , <img>) will be displayed properly
use-markup = true
# If true, html entities (& for &, % for %, etc) will be parsed
# properly. This is useful for chromium-based apps, which tend to send
# these in notifications.
parse-html-entities = true
# If set to true, the parameter noClosedMsg can be set on
# notifications. If noClosedMsg is set to true on a notification,
# DBUS NotificationClosed messages will not be send for this
# notification.
dbus.send-noti-closed = false
# If set to true: If no icon is passed by the app_icon parameter
# and no application "desktop-entry"-hint is present, the notification
# center will try to guess the icon from the application name (if present).
# Default is true.
app.guess-icon-from-name = true
# Default timeout used for notifications in milli-seconds. This can
# be overwritten with the "-t" option (or "--expire-time") of the
# notify-send command.
default-timeout = 10000
# The display size of the application icons.
app.icon-size = 20
# Text size for the app name in the notification pop-ups.
# Overrides [general]::text-size.
app.text-size = 12px
# The max display size of images that are part of notifications
# for notification pop-ups and in the notification center
icon-size = 100
# Text size for the title in the notification pop-ups.
# Overrides [general]::text-size.
title.text-size = 16px
# Text size for the time in the notification pop-ups.
# Overrides [general]::text-size.
time.text-size = 12px
# See section "Notification based scripting" for an explanation
#match = "title=Abc;body=abc":"app=notify-send"
#modify = "transient=false"
#run = "":"killall notify-send"
[notification.popup]
# Margin above notifications (in pixels). This can be used to avoid
# overlap between notifications and a bar such as polybar or i3blocks.
margin-top = 50
# Margin on the right of the notification (in pixels).
# Overrides [general]::margin-right.
margin-right = 50
# Vertical distance between 2 notifications (in pixels).
margin-between = 20
# Width of the popups.
width = 300
# Monitor that the popup will appear on.
monitor = 0
# If true, the notifications will open on the screen, on which the
# mouse is. Overrides [general]::follow-mouse.
follow-mouse = false
# Background color for notification popups.
background-color = rgba(9, 0, 0, 0.5)
# Background color for "critical" notification popups.
critical.background-color = rgba(255, 0, 50, 0.5)
# Color for the text (summary, body and application name) in
# notification popups. Overrides [general]::text-color.
text-color = #fef3f6
# Color for the text (summary, body and application name) in
# "critical" notification popups. Overrides [general]::text-color.
critical.text-color = #FFF
# The mouse button for closing a popup. Must be either "mouse1",
# "mouse2", "mouse3", "mouse4", or "mouse5"
dismiss-button = mouse1
# The mouse button for opening a popup with the default action.
# Must be either "mouse1", "mouse2", "mouse3", "mouse4", or "mouse5"
default-action-button = mouse3
[notification.in-center]
# Background color for "critical" notifications in notification
# center.
critical.background-color = rgba(155, 0, 20, 0.5)
# Color for the text (summary, body and application name) in
# "critical" notification in notification center. Overrides [general]::text-color.
critical.text-color = #59
[buttons]
### These button configurations are applied globally (except they
### get overwritten in the [buttons] section. The buttons section
### only applies to the configurable buttons within the notification
### center, while these configs also apply to the buttons within
### notifications.)
# Default background color for buttons. Can be overridden in
# [custom-buttons].
background-color = transparent
# Default text color for the text in the buttons. Overrides
# [general]::text-color. Can be overridden in [custom-buttons].
text-color = #eae2e0
# Default background color of button in hover state (mouse over).
# Can be overridden in [custom-buttons].
hover.background-color = rgba(0, 20, 20, 0.2)
# Default text color of button in hover state (mouse over).
# Overrides [general]::text-color. Can be overridden in [custom-buttons].
hover.text-color = #70
[custom-buttons]
### This section describes the configurable buttons within the
### notification center and NOT the buttons that appear in the
### notifications
# Note: If you want your buttons in the notification center to be
# squares you should verify that the following equality holds:
# [notification-center]::width
# == [custom-buttons]::buttons-per-row * [custom-buttons]::button-height
# + ([custom-buttons]::buttons-per-row + 1) * [custom-buttons]::button-margin
# Numbers of buttons that can be drawn on a row of the notification
# center.
buttons-per-row = 5
# Height of buttons in the notification center (in pixels).
button-height = 60
# Horizontal and vertical margin between each button in the
# notification center (in pixels).
button-margin = 2
# Labels written on the buttons in the notification center. Labels
# should be written between quotes and separated by a colon. For
# example:
# labels = "VPN":"Bluetooth":"Wifi":"Screensaver"
# Each label is represented as a clickable button in the notification
# center. The commands variable below define the commands that should
# be launched when the user clicks on the associated button. There
# should be the same number of entries in `commands` and in `labels`
# commands = "sudo vpnToggle":"bluetoothToggle":"wifiToggle":"screensaverToggle"
# Color of the labels of the custom buttons in the notification
# center. Overrides [buttons]::text-color.
text-color = #fee
# Color of the custom buttons' background in the notification center.
# Overrides [buttons]::background-color
background-color = rgba(255, 255, 255, 0.15)
# Color of the custom buttons' background in the notification center
# when hovered. Overrides [buttons]::hover.background-color.
hover.background-color = rgba(0, 20, 20, 0.2)
# Color of the labels of the custom buttons in the notification center
# when hovered. Overrides [buttons]::hover.text-color.
hover.text-color = #fee
# Text size of the custom buttons in the notification center.
# Overrides [general]::text-size.
text-size = 12px;
# Color of the custom buttons' background in the notification center
# when its state is set to true as described in the Section Usage.
# Overrides [buttons]::background-color.
state-1.background-color = rgba(255,255,255,0.5)
# Color of the custom buttons' text in the notification center
# when its state is set to true as described in the Section Usage
# Overrides [buttons]::text-color.
state-1.text-color = #fff
# Color of the custom buttons' background, hovering, in the
# notification center when its state is set to true as described in
# the Section Usage
# Overrides [buttons]::hover.background-color.
state-1.hover.background-color = rgba(0, 20, 20, 0.4)
# Color of the custom buttons' text, hovering, in the
# notification center when its state is set to true as described in
# the Section Usage
# Overrides [buttons]::hover.text-color.
state-1.hover.text-color = #fee
# Color of the custom buttons' background, in the notification center
# when the button is clicked and not yet set to a new value via the
# method as described in Section Usage
# Overrides [buttons]::background-color.
state-2.background-color = rgba(255,255,255,0.3)
# Color of the custom buttons' text, in the notification center
# when the button is clicked and not yet set to a new value via the
# method as described in Section Usage
# Overrides [buttons]::text-color.
state-2.text-color = #fff
# Color of the custom buttons' background,
# hovering, in the notification center when the button is clicked and
# not yet set to a new value via the method as described in Section
# Usage
# Overrides [buttons]::hover.background-color.
state-2.hover.background-color = rgba(0, 20, 20, 0.3)
# Color of the custom buttons' text, hovering, in the notification
# center when the button is clicked and not yet set to a new value via
# the method as described in Section Usage
# Overrides [buttons]::hover.text-color.
state-2.hover.text-color = #fee
Major refactor
I also think that the way configurations are handled is due for a major refactor. Currently, Config.hs is where most of the configuration-based code lives. Here are some ideas:
- It might make sense to give each section its own sub-type to nest inside the record. Things are a bit more orderly this way, and there's less large compound variable names, like
configPopupDefaultActionButton. - Abandon the use of
r,r', andr'', and just define a helper in a let binding. - Add support for a parsing scheme to be added here. Ideally, things like colors, mouse buttons, etc, can be parsed into internal haskell types at this point, so if the program can't parse the config correctly, it can halt immediately and inform the user. It's kinda not super safe to just be throwing strings around all the time. IIRC the library that's being used for config parsing should be capable of this.
This is stuff for a major version bump. I like the ideas overall. Some pointers:
Some text optimizations, but could be done in a PR.
Some commands don't even really have anything to do with the notification center itself or notifications in general, such as startupCommand.
Trueish. The original motivation for this command was to run a script to set the initial state of the buttons in the noti-center. Thus it is only relevant for the noti-center. I agree though, that might have been ill-fated thinking and this command should be more general.
Other settings, like marginTop, followMouse, width, timeTextSize, etc, appear to be specific to the notification center itself, and do not apply to notifications at all.
I think followMouse also influences, on which screen the notis pop up (not sure though). Width can be set on the noti-center and noti-popus separately, afaik.
In this overview video, Brodie Robertson notes that this section was a bit confusing, since some things are handled by the GTK CSS, and some things are handled by this config. I kinda agree. It might make a bit more sense to move color settings to other sections, like how text size is handled.
I saw that vid and can full-heartedly agree that the UX of this is... terrible. BUT: Doing it this way made it possible in the first place to make all that stuff configurable. If it was not for the gtk.css file, EVERYTHING would have to be doable manually through a coded way from the config. If we tell people, where they can modify the css and how, it opens up more opportunities for them to fully configure. Maybe, it should be better communicated why and how this works, though. Putting the existing color-configs in a new place is a good idea, though.
Abandon the use of r, r', and r'', and just define a helper in a let binding.
If you get it to work, sure. I did'nt do this to win beauty contests, but because the compiler was picky and I did'nt figure out how to do it in a better way. The issue seems to be, that the compiler does not really get the concept of polymorphism within a single function. That is why I defined a new r for each variable type, one for bools, one for numbers, one for strings (better naming could have helped). If there is a nice way around this, sure, all in for it :)
icon-size = 100
Should probably be named image-size
Good advice here. I didn't mention it, but I think we should also consider moving away from the ConfigFile library that's currently used. It's not very actively maintained, and it really makes parsing things like list content difficult.
IMO, the best chance we have for better data representation here is TOML, which is an ini-like markup language that seems pretty much entirely compatible with what we're already doing, with the exception that it comes with a well-defined spec, and the ability to represent arrays without wanting to off yourself.
toml-parser is a library that could be used to parse the config file. Here's a snippet of TOML so you can see what it's like:
# This is a TOML document.
title = "Example document"
[section]
string = "hello, world"
integers = [0, +1, -2, 3_333_333]
float = 4.2e10
inlinemap = { x = 1, y = 'two' }
[nesting]
[nesting.first]
longstring = """multiline "string" syntax"""
longquote = '''escapes \not \interpreted'''
[nesting.second]
datetime = 2017-05-04T12:13:14Z
lookinggood = true
I saw that vid and can full-heartedly agree that the UX of this is... terrible. BUT: Doing it this way made it possible in the first place to make all that stuff configurable. If it was not for the gtk.css file, EVERYTHING would have to be doable manually through a coded way from the config. If we tell people, where they can modify the css and how, it opens up more opportunities for them to fully configure. Maybe, it should be better communicated why and how this works, though.
That's fair, but at this point we already support a LOT of that in the config file itself. Like, at this point we have config support for:
- Text size for most identifiable lables
- Text color for most identifiable labels
- Background color for popups and the noti center
- Noti Image Size & Margins
Like, as I said previously, the most common use of the GTK is for things like setting the fonts. I'm not suggesting we drop support for CSS, since there are quite a few advanced features that the CSS can do that we probably wouldn't want to have in the config file. I just don't want users reaching for the css unless they know they need it.
Maybe we could have a example-user-style.css file in the repository root instead of a section in the README? We could put all the different CSS identifiers there. After the config file section in the readme, we could direct users to this file with something like:
If the config file doesn't cover your cosmetic needs, try writing a style.css file
I like your suggestions regarding toml, the toml-parser and the css stuff. I would be a little bit more verbouse on what the css is for and maybe keep the examples for hiding certain elements etc. but in general I think, your suggestions are reasonable.
Looking back over my TOML stuff, I'm realizing there are probably better libraries out there. Instead of going with toml-parser, we should probably instead go with tomland (which is in the stackage lts we're using) or htoml-megaparsec. tomland looks good though, since it's popular and actively maintained, and appears to provide first-class support for parsing TOML directly into haskell custom types, at least according to the readme.
One thing we should note about TOML atm is that the rgb syntax we used will need to be changed, which will also constitute a breaking change. TOML (afaik) doesn't support this kind of syntax yet. In the future, TOML could support that kind of syntax as an implementation-specific function call (track toml-lang/toml#707), in which case we'd just have our implementation call a function that could just parse this tuple into the RGB object.
I think, this kind of restructuring will be braking anyways. So that should not stop us
While working on #67 in noticed, that we should consider YAML for the configuration file. As YAML is a superset of JSON, we could use the same parser to communicate with the outside world concerning updating notifications. The format that describes how notifications should be altered could then be understood from the config file in the same way as JSON from a process (hope, that makes sense).
To illustrate:
I build a version of the DNC where you can pass in a script value. The DNC calls the script with the notification as parameter. The stdout of the script then is parsed as the modify-part as it would be in a config file. Now, that, sucks due to line brakes, special characters, etc. We need a real parser to do the job. For the communication between the script and the DNC I think JSON would be good.
For the config, JSON is ok-ish but YAML is better, due to having comments etc.
@MyriaCore if you have some time, feel free to checkout the draft I pushed today (see above). It's basically finished, but if you have some input, we could still incorporate it. The configuration categories are basically what you proposed, but in YAML for reasons stated above. Also, full script-wise modifications of notifications is possible now.
Obviously super late, sorry abt that. My notifs must not be working properly. Unfortunately, school is rly thing me down, but the functionality that YAML gives is actually really exciting. If I have more time I'll take a peek at the specific changes, but I'm into the idea!