This commit is contained in:
o9000 2017-03-25 14:17:27 +01:00
parent 89d57f893c
commit d5dfda296f
15 changed files with 901 additions and 428 deletions

View file

@ -100,6 +100,7 @@ include_directories( ${PROJECT_BINARY_DIR}
src/tooltip
src/util
src/execplugin
src/button
src/freespace
src/separator
${X11_INCLUDE_DIRS}
@ -128,6 +129,7 @@ set( SOURCES src/config.c
src/taskbar/taskbarname.c
src/tooltip/tooltip.c
src/execplugin/execplugin.c
src/button/button.c
src/freespace/freespace.c
src/separator/separator.c
src/tint2rc.c

View file

@ -1,3 +1,7 @@
2017-03-25 master
- Enhancements:
- New plugin: button.
2017-03-25 0.13.3
- Fixes:
- Fixed autohide for non-bottom panels (issue #632)

View file

@ -229,6 +229,7 @@ It was specifically made for Openbox but it should also work with other window m
<li><p><a href="#tooltip">Tooltip</a></p></li>
<li><p><a href="#battery">Battery</a></p></li>
<li><p><a href="#executor">Executor</a></p></li>
<li><p><a href="#button">Button</a></p></li>
<li><p><a href="#separator">Separator</a></p></li>
<li><p><a href="#example-configuration">Example configuration</a></p></li>
</ul>
@ -359,6 +360,7 @@ gradient_id_pressed = 2
<li><code>C</code> shows the Clock</li>
<li><code>F</code> adds an extensible spacer (freespace). You can specify more than one. Has no effect if <code>T</code> is also present. <em>(since 0.12)</em></li>
<li><code>E</code> adds an executor plugin. You can specify more than one. <em>(since 0.12.4)</em></li>
<li><code>P</code> adds a push button. You can specify more than one. <em>(since 0.14)</em></li>
<li><code>:</code> adds a separator. You can specify more than one. <em>(since 0.13.0)</em></li>
</ul>
<p>For example, <code>panel_items = STC</code> will show the systray, the taskbar and the clock (from left to right).</p></li>
@ -650,6 +652,23 @@ execp_command = stdbuf -oL bwm-ng -o csv -t 1000 | awk -F ';' '/total/ { printf
execp_continuous = 1
execp_interval = 1
</code></pre>
<h3 id="button">Button<a name="button" href="#button" class="md2man-permalink" title="permalink"></a></h3>
<ul>
<li><p><code>button = new</code> : Begins the configuration of a new button. Multiple such plugins are supported; just use multiple <code>P</code>s in <code>panel_items</code>. <em>(since 0.14)</em></p></li>
<li><p><code>button_icon = text</code> : Name or path of icon (or empty). <em>(since 0.14)</em></p></li>
<li><p><code>button_text = text</code> : Text to display (or empty). <em>(since 0.14)</em></p></li>
<li><p><code>button_tooltip = text</code> : The tooltip (or empty). <em>(since 0.14)</em></p></li>
<li><p><code>button_font = [FAMILY-LIST] [STYLE-OPTIONS] [SIZE]</code> : The font used to draw the text. <em>(since 0.14)</em></p></li>
<li><p><code>button_font_color = color opacity</code> : The font color. <em>(since 0.14)</em></p></li>
<li><p><code>button_background_id = integer</code> : Which background to use. <em>(since 0.14)</em></p></li>
<li><p><code>button_centered = boolean (0 or 1)</code> : Whether to center the text. <em>(since 0.14)</em></p></li>
<li><p><code>button_padding = horizontal_padding vertical_padding spacing_between_icon_and_text</code> <em>(since 0.14)</em></p></li>
<li><p><code>button_lclick_command = text</code> : Command to execute on left click. If not defined, <code>execp_command</code> is executed immediately, unless it is currently running. <em>(since 0.14)</em></p></li>
<li><p><code>button_mclick_command = text</code> : Command to execute on right click. If not defined, <code>execp_command</code> is executed immediately, unless it is currently running. <em>(since 0.14)</em></p></li>
<li><p><code>button_rclick_command = text</code> : Command to execute on middle click. If not defined, <code>execp_command</code> is executed immediately, unless it is currently running. <em>(since 0.14)</em></p></li>
<li><p><code>button_uwheel_command = text</code> : Command to execute on wheel scroll up. If not defined, <code>execp_command</code> is executed immediately, unless it is currently running. <em>(since 0.14)</em></p></li>
<li><p><code>button_dwheel_command = text</code> : Command to execute on wheel scroll down. If not defined, <code>execp_command</code> is executed immediately, unless it is currently running. <em>(since 0.14)</em></p></li>
</ul>
<h3 id="separator">Separator<a name="separator" href="#separator" class="md2man-permalink" title="permalink"></a></h3>
<ul>
<li><p><code>separator = new</code> : Begins the configuration of a new separator. Multiple such plugins are supported; just use multiple <code>:</code>s in <code>panel_items</code>. <em>(since 0.13.0)</em></p></li>
@ -659,142 +678,7 @@ execp_interval = 1
<li><p><code>separator_size = integer</code> : The thickness of the separator. Does not include the border and padding. For example, if the style is <code>line</code>, this is the line thickness; if the style is <code>dots</code>, this is the dot&#39;s diameter. <em>(since 0.13.0)</em></p></li>
<li><p><code>separator_padding = side_padding cap_padding</code> : The padding to add to the sides of the separator, in pixels. <em>(since 0.13.0)</em></p></li>
</ul>
<h3 id="example-configuration">Example configuration<a name="example-configuration" href="#example-configuration" class="md2man-permalink" title="permalink"></a></h3><pre class="highlight plaintext"><code>#---------------------------------------------
## TINT2 CONFIG FILE
#---------------------------------------------
#---------------------------------------------
## BACKGROUND AND BORDER
#---------------------------------------------
rounded = 7
border_width = 2
background_color = #000000 60
border_color = #ffffff 18
rounded = 5
border_width = 0
background_color = #ffffff 40
border_color = #ffffff 50
rounded = 5
border_width = 0
background_color = #ffffff 18
border_color = #ffffff 70
#---------------------------------------------
## PANEL
#---------------------------------------------
panel_monitor = all
panel_position = bottom center
panel_size = 94% 30
panel_margin = 0 0
panel_padding = 7 0
font_shadow = 0
panel_background_id = 1
wm_menu = 0
panel_dock = 0
panel_layer = bottom
#---------------------------------------------
## TASKBAR
#---------------------------------------------
#taskbar_mode = multi_desktop
taskbar_mode = single_desktop
taskbar_padding = 2 3 2
taskbar_background_id = 0
#taskbar_active_background_id = 0
#---------------------------------------------
## TASKS
#---------------------------------------------
task_icon = 1
task_text = 1
task_maximum_size = 140 35
task_centered = 1
task_padding = 6 3
task_font = sans 7
task_font_color = #ffffff 70
task_background_id = 3
task_icon_asb = 100 0 0
## replace STATUS by 'urgent', 'active' or 'iconified'
#task_STATUS_background_id = 2
#task_STATUS_font_color = #ffffff 85
#task_STATUS_icon_asb = 100 0 0
## example:
task_active_background_id = 2
task_active_font_color = #ffffff 85
task_active_icon_asb = 100 0 0
urgent_nb_of_blink = 8
#---------------------------------------------
## SYSTRAYBAR
#---------------------------------------------
systray = 1
systray_padding = 0 4 5
systray_background_id = 0
systray_sort = left2right
systray_icon_size = 0
systray_icon_asb = 100 0 0
#---------------------------------------------
## CLOCK
#---------------------------------------------
time1_format = %H:%M
time1_font = sans 8
time2_format = %A %d %B
time2_font = sans 6
clock_font_color = #ffffff 76
clock_padding = 1 0
clock_background_id = 0
#clock_lclick_command = xclock
clock_rclick_command = orage
#clock_tooltip = %A %d %B
#time1_timezone = :US/Hawaii
#time2_timezone = :Europe/Berlin
#clock_tooltip_timezone = :/usr/share/zoneinfo/Europe/Paris
#---------------------------------------------
## BATTERY
#---------------------------------------------
battery = 0
battery_hide = 98
battery_low_status = 10
battery_low_cmd = notify-send "battery low"
bat1_font = sans 8
bat2_font = sans 6
battery_font_color = #ffffff 76
battery_padding = 1 0
battery_background_id = 0
#---------------------------------------------
## TOOLTIP
#---------------------------------------------
tooltip = 0
tooltip_padding = 2 2
tooltip_show_timeout = 0.7
tooltip_hide_timeout = 0.3
tooltip_background_id = 1
tooltip_font_color = #OOOOOO 80
tooltip_font = sans 10
#---------------------------------------------
## MOUSE ACTION ON TASK
#---------------------------------------------
mouse_middle = none
mouse_right = close
mouse_scroll_up = toggle
mouse_scroll_down = iconify
#---------------------------------------------
## AUTOHIDE OPTIONS
#---------------------------------------------
autohide = 0
autohide_show_timeout = 0.3
autohide_hide_timeout = 2
autohide_height = 4
strut_policy = minimum
</code></pre>
<h2 id="author">AUTHOR<a name="author" href="#author" class="md2man-permalink" title="permalink"></a></h2><p>tint2 was written by Thierry Lorthiois <a href="mailto:lorthiois@bbsoft.fr">lorthiois@bbsoft.fr</a>.
<h3 id="example-configuration">Example configuration<a name="example-configuration" href="#example-configuration" class="md2man-permalink" title="permalink"></a></h3><p>See /etc/xdg/tint2/tint2rc.</p><h2 id="author">AUTHOR<a name="author" href="#author" class="md2man-permalink" title="permalink"></a></h2><p>tint2 was written by Thierry Lorthiois <a href="mailto:lorthiois@bbsoft.fr">lorthiois@bbsoft.fr</a>.
It is based on ttm, originally written by Pål Staurland <a href="mailto:staura@gmail.com">staura@gmail.com</a>.</p><p>This manual page was originally written by Daniel Moerner <a href="mailto:dmoerner@gmail.com">dmoerner@gmail.com</a>, for the Debian project (but may be used by others).
It was adopted from the tint2 docs.</p><h2 id="see-also">SEE ALSO<a name="see-also" href="#see-also" class="md2man-permalink" title="permalink"></a></h2><p>The main website <a href="https://gitlab.com/o9000/tint2">https://gitlab.com/o9000/tint2</a>
and the wiki page at <a href="https://gitlab.com/o9000/tint2/wikis/home">https://gitlab.com/o9000/tint2/wikis/home</a>.</p><p>This documentation is also provided in HTML and Markdown format in the system&#39;s default location

View file

@ -67,6 +67,8 @@ Battery \[la]#battery\[ra]
.IP \(bu 2
Executor \[la]#executor\[ra]
.IP \(bu 2
Button \[la]#button\[ra]
.IP \(bu 2
Separator \[la]#separator\[ra]
.IP \(bu 2
Example configuration \[la]#example-configuration\[ra]
@ -294,6 +296,8 @@ gradient_id_pressed = 2
.IP \(bu 2
\fB\fCE\fR adds an executor plugin. You can specify more than one. \fI(since 0.12.4)\fP
.IP \(bu 2
\fB\fCP\fR adds a push button. You can specify more than one. \fI(since 0.14)\fP
.IP \(bu 2
\fB\fC:\fR adds a separator. You can specify more than one. \fI(since 0.13.0)\fP
.RE
.PP
@ -800,6 +804,37 @@ execp_continuous = 1
execp_interval = 1
.fi
.RE
.SS Button
.RS
.IP \(bu 2
\fB\fCbutton = new\fR : Begins the configuration of a new button. Multiple such plugins are supported; just use multiple \fB\fCP\fRs in \fB\fCpanel_items\fR\&. \fI(since 0.14)\fP
.IP \(bu 2
\fB\fCbutton_icon = text\fR : Name or path of icon (or empty). \fI(since 0.14)\fP
.IP \(bu 2
\fB\fCbutton_text = text\fR : Text to display (or empty). \fI(since 0.14)\fP
.IP \(bu 2
\fB\fCbutton_tooltip = text\fR : The tooltip (or empty). \fI(since 0.14)\fP
.IP \(bu 2
\fB\fCbutton_font = [FAMILY\-LIST] [STYLE\-OPTIONS] [SIZE]\fR : The font used to draw the text. \fI(since 0.14)\fP
.IP \(bu 2
\fB\fCbutton_font_color = color opacity\fR : The font color. \fI(since 0.14)\fP
.IP \(bu 2
\fB\fCbutton_background_id = integer\fR : Which background to use. \fI(since 0.14)\fP
.IP \(bu 2
\fB\fCbutton_centered = boolean (0 or 1)\fR : Whether to center the text. \fI(since 0.14)\fP
.IP \(bu 2
\fB\fCbutton_padding = horizontal_padding vertical_padding spacing_between_icon_and_text\fR \fI(since 0.14)\fP
.IP \(bu 2
\fB\fCbutton_lclick_command = text\fR : Command to execute on left click. If not defined, \fB\fCexecp_command\fR is executed immediately, unless it is currently running. \fI(since 0.14)\fP
.IP \(bu 2
\fB\fCbutton_mclick_command = text\fR : Command to execute on right click. If not defined, \fB\fCexecp_command\fR is executed immediately, unless it is currently running. \fI(since 0.14)\fP
.IP \(bu 2
\fB\fCbutton_rclick_command = text\fR : Command to execute on middle click. If not defined, \fB\fCexecp_command\fR is executed immediately, unless it is currently running. \fI(since 0.14)\fP
.IP \(bu 2
\fB\fCbutton_uwheel_command = text\fR : Command to execute on wheel scroll up. If not defined, \fB\fCexecp_command\fR is executed immediately, unless it is currently running. \fI(since 0.14)\fP
.IP \(bu 2
\fB\fCbutton_dwheel_command = text\fR : Command to execute on wheel scroll down. If not defined, \fB\fCexecp_command\fR is executed immediately, unless it is currently running. \fI(since 0.14)\fP
.RE
.SS Separator
.RS
.IP \(bu 2
@ -817,144 +852,7 @@ execp_interval = 1
.RE
.SS Example configuration
.PP
.RS
.nf
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
## TINT2 CONFIG FILE
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
## BACKGROUND AND BORDER
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
rounded = 7
border_width = 2
background_color = #000000 60
border_color = #ffffff 18
rounded = 5
border_width = 0
background_color = #ffffff 40
border_color = #ffffff 50
rounded = 5
border_width = 0
background_color = #ffffff 18
border_color = #ffffff 70
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
## PANEL
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
panel_monitor = all
panel_position = bottom center
panel_size = 94% 30
panel_margin = 0 0
panel_padding = 7 0
font_shadow = 0
panel_background_id = 1
wm_menu = 0
panel_dock = 0
panel_layer = bottom
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
## TASKBAR
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
#taskbar_mode = multi_desktop
taskbar_mode = single_desktop
taskbar_padding = 2 3 2
taskbar_background_id = 0
#taskbar_active_background_id = 0
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
## TASKS
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
task_icon = 1
task_text = 1
task_maximum_size = 140 35
task_centered = 1
task_padding = 6 3
task_font = sans 7
task_font_color = #ffffff 70
task_background_id = 3
task_icon_asb = 100 0 0
## replace STATUS by 'urgent', 'active' or 'iconified'
#task_STATUS_background_id = 2
#task_STATUS_font_color = #ffffff 85
#task_STATUS_icon_asb = 100 0 0
## example:
task_active_background_id = 2
task_active_font_color = #ffffff 85
task_active_icon_asb = 100 0 0
urgent_nb_of_blink = 8
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
## SYSTRAYBAR
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
systray = 1
systray_padding = 0 4 5
systray_background_id = 0
systray_sort = left2right
systray_icon_size = 0
systray_icon_asb = 100 0 0
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
## CLOCK
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
time1_format = %H:%M
time1_font = sans 8
time2_format = %A %d %B
time2_font = sans 6
clock_font_color = #ffffff 76
clock_padding = 1 0
clock_background_id = 0
#clock_lclick_command = xclock
clock_rclick_command = orage
#clock_tooltip = %A %d %B
#time1_timezone = :US/Hawaii
#time2_timezone = :Europe/Berlin
#clock_tooltip_timezone = :/usr/share/zoneinfo/Europe/Paris
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
## BATTERY
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
battery = 0
battery_hide = 98
battery_low_status = 10
battery_low_cmd = notify\-send "battery low"
bat1_font = sans 8
bat2_font = sans 6
battery_font_color = #ffffff 76
battery_padding = 1 0
battery_background_id = 0
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
## TOOLTIP
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
tooltip = 0
tooltip_padding = 2 2
tooltip_show_timeout = 0.7
tooltip_hide_timeout = 0.3
tooltip_background_id = 1
tooltip_font_color = #OOOOOO 80
tooltip_font = sans 10
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
## MOUSE ACTION ON TASK
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
mouse_middle = none
mouse_right = close
mouse_scroll_up = toggle
mouse_scroll_down = iconify
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
## AUTOHIDE OPTIONS
#\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
autohide = 0
autohide_show_timeout = 0.3
autohide_hide_timeout = 2
autohide_height = 4
strut_policy = minimum
.fi
.RE
See /etc/xdg/tint2/tint2rc.
.SH AUTHOR
.PP
tint2 was written by Thierry Lorthiois \[la]lorthiois@bbsoft.fr\[ra]\&.

View file

@ -58,6 +58,8 @@ Goals:
* [Executor](#executor)
* [Button](#button)
* [Separator](#separator)
* [Example configuration](#example-configuration)
@ -244,6 +246,7 @@ gradient_id_pressed = 2
* `C` shows the Clock
* `F` adds an extensible spacer (freespace). You can specify more than one. Has no effect if `T` is also present. *(since 0.12)*
* `E` adds an executor plugin. You can specify more than one. *(since 0.12.4)*
* `P` adds a push button. You can specify more than one. *(since 0.14)*
* `:` adds a separator. You can specify more than one. *(since 0.13.0)*
For example, `panel_items = STC` will show the systray, the taskbar and the clock (from left to right).
@ -671,6 +674,32 @@ execp_continuous = 1
execp_interval = 1
```
### Button
* `button = new` : Begins the configuration of a new button. Multiple such plugins are supported; just use multiple `P`s in `panel_items`. *(since 0.14)*
* `button_icon = text` : Name or path of icon (or empty). *(since 0.14)*
* `button_text = text` : Text to display (or empty). *(since 0.14)*
* `button_tooltip = text` : The tooltip (or empty). *(since 0.14)*
* `button_font = [FAMILY-LIST] [STYLE-OPTIONS] [SIZE]` : The font used to draw the text. *(since 0.14)*
* `button_font_color = color opacity` : The font color. *(since 0.14)*
* `button_background_id = integer` : Which background to use. *(since 0.14)*
* `button_centered = boolean (0 or 1)` : Whether to center the text. *(since 0.14)*
* `button_padding = horizontal_padding vertical_padding spacing_between_icon_and_text` *(since 0.14)*
* `button_lclick_command = text` : Command to execute on left click. If not defined, `execp_command` is executed immediately, unless it is currently running. *(since 0.14)*
* `button_mclick_command = text` : Command to execute on right click. If not defined, `execp_command` is executed immediately, unless it is currently running. *(since 0.14)*
* `button_rclick_command = text` : Command to execute on middle click. If not defined, `execp_command` is executed immediately, unless it is currently running. *(since 0.14)*
* `button_uwheel_command = text` : Command to execute on wheel scroll up. If not defined, `execp_command` is executed immediately, unless it is currently running. *(since 0.14)*
* `button_dwheel_command = text` : Command to execute on wheel scroll down. If not defined, `execp_command` is executed immediately, unless it is currently running. *(since 0.14)*
### Separator
* `separator = new` : Begins the configuration of a new separator. Multiple such plugins are supported; just use multiple `:`s in `panel_items`. *(since 0.13.0)*
@ -687,142 +716,7 @@ execp_interval = 1
### Example configuration
```
#---------------------------------------------
## TINT2 CONFIG FILE
#---------------------------------------------
#---------------------------------------------
## BACKGROUND AND BORDER
#---------------------------------------------
rounded = 7
border_width = 2
background_color = #000000 60
border_color = #ffffff 18
rounded = 5
border_width = 0
background_color = #ffffff 40
border_color = #ffffff 50
rounded = 5
border_width = 0
background_color = #ffffff 18
border_color = #ffffff 70
#---------------------------------------------
## PANEL
#---------------------------------------------
panel_monitor = all
panel_position = bottom center
panel_size = 94% 30
panel_margin = 0 0
panel_padding = 7 0
font_shadow = 0
panel_background_id = 1
wm_menu = 0
panel_dock = 0
panel_layer = bottom
#---------------------------------------------
## TASKBAR
#---------------------------------------------
#taskbar_mode = multi_desktop
taskbar_mode = single_desktop
taskbar_padding = 2 3 2
taskbar_background_id = 0
#taskbar_active_background_id = 0
#---------------------------------------------
## TASKS
#---------------------------------------------
task_icon = 1
task_text = 1
task_maximum_size = 140 35
task_centered = 1
task_padding = 6 3
task_font = sans 7
task_font_color = #ffffff 70
task_background_id = 3
task_icon_asb = 100 0 0
## replace STATUS by 'urgent', 'active' or 'iconified'
#task_STATUS_background_id = 2
#task_STATUS_font_color = #ffffff 85
#task_STATUS_icon_asb = 100 0 0
## example:
task_active_background_id = 2
task_active_font_color = #ffffff 85
task_active_icon_asb = 100 0 0
urgent_nb_of_blink = 8
#---------------------------------------------
## SYSTRAYBAR
#---------------------------------------------
systray = 1
systray_padding = 0 4 5
systray_background_id = 0
systray_sort = left2right
systray_icon_size = 0
systray_icon_asb = 100 0 0
#---------------------------------------------
## CLOCK
#---------------------------------------------
time1_format = %H:%M
time1_font = sans 8
time2_format = %A %d %B
time2_font = sans 6
clock_font_color = #ffffff 76
clock_padding = 1 0
clock_background_id = 0
#clock_lclick_command = xclock
clock_rclick_command = orage
#clock_tooltip = %A %d %B
#time1_timezone = :US/Hawaii
#time2_timezone = :Europe/Berlin
#clock_tooltip_timezone = :/usr/share/zoneinfo/Europe/Paris
#---------------------------------------------
## BATTERY
#---------------------------------------------
battery = 0
battery_hide = 98
battery_low_status = 10
battery_low_cmd = notify-send "battery low"
bat1_font = sans 8
bat2_font = sans 6
battery_font_color = #ffffff 76
battery_padding = 1 0
battery_background_id = 0
#---------------------------------------------
## TOOLTIP
#---------------------------------------------
tooltip = 0
tooltip_padding = 2 2
tooltip_show_timeout = 0.7
tooltip_hide_timeout = 0.3
tooltip_background_id = 1
tooltip_font_color = #OOOOOO 80
tooltip_font = sans 10
#---------------------------------------------
## MOUSE ACTION ON TASK
#---------------------------------------------
mouse_middle = none
mouse_right = close
mouse_scroll_up = toggle
mouse_scroll_down = iconify
#---------------------------------------------
## AUTOHIDE OPTIONS
#---------------------------------------------
autohide = 0
autohide_show_timeout = 0.3
autohide_hide_timeout = 2
autohide_height = 4
strut_policy = minimum
```
See /etc/xdg/tint2/tint2rc.
## AUTHOR
tint2 was written by Thierry Lorthiois <lorthiois@bbsoft.fr>.

543
src/button/button.c Normal file
View file

@ -0,0 +1,543 @@
#include "button.h"
#include <string.h>
#include <stdio.h>
#include <cairo.h>
#include <cairo-xlib.h>
#include <math.h>
#include <pango/pangocairo.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <fcntl.h>
#include "window.h"
#include "server.h"
#include "panel.h"
#include "timer.h"
#include "common.h"
char *button_get_tooltip(void *obj);
void button_init_fonts();
int button_compute_desired_size(void *obj);
void button_dump_geometry(void *obj, int indent);
void default_button()
{
}
Button *create_button()
{
Button *button = calloc(1, sizeof(Button));
button->backend = calloc(1, sizeof(ButtonBackend));
button->backend->centered = TRUE;
button->backend->font_color.alpha = 0.5;
return button;
}
gpointer create_button_frontend(gconstpointer arg, gpointer data)
{
Button *button_backend = (Button *)arg;
Button *button_frontend = calloc(1, sizeof(Button));
button_frontend->backend = button_backend->backend;
button_backend->backend->instances = g_list_append(button_backend->backend->instances, button_frontend);
button_frontend->frontend = calloc(1, sizeof(ButtonFrontend));
return button_frontend;
}
void destroy_button(void *obj)
{
Button *button = (Button *)obj;
if (button->frontend) {
// This is a frontend element
if (button->frontend->icon) {
imlib_context_set_image(button->frontend->icon);
imlib_free_image();
button->frontend->icon = NULL;
}
button->backend->instances = g_list_remove_all(button->backend->instances, button);
free_and_null(button->frontend);
remove_area(&button->area);
free_area(&button->area);
free_and_null(button);
} else {
// This is a backend element
free_and_null(button->backend->text);
free_and_null(button->backend->icon_name);
free_and_null(button->backend->tooltip);
button->backend->bg = NULL;
pango_font_description_free(button->backend->font_desc);
button->backend->font_desc = NULL;
free_and_null(button->backend->lclick_command);
free_and_null(button->backend->mclick_command);
free_and_null(button->backend->rclick_command);
free_and_null(button->backend->dwheel_command);
free_and_null(button->backend->uwheel_command);
if (button->backend->instances) {
fprintf(stderr, "Error: Attempt to destroy backend while there are still frontend instances!\n");
exit(-1);
}
free(button->backend);
free(button);
}
}
void init_button()
{
GList *to_remove = panel_config.button_list;
for (int k = 0; k < strlen(panel_items_order) && to_remove; k++) {
if (panel_items_order[k] == 'E') {
to_remove = to_remove->next;
}
}
if (to_remove) {
if (to_remove == panel_config.button_list) {
g_list_free_full(to_remove, destroy_button);
panel_config.button_list = NULL;
} else {
// Cut panel_config.button_list
if (to_remove->prev)
to_remove->prev->next = NULL;
to_remove->prev = NULL;
// Remove all elements of to_remove and to_remove itself
g_list_free_full(to_remove, destroy_button);
}
}
button_init_fonts();
for (GList *l = panel_config.button_list; l; l = l->next) {
Button *button = l->data;
// Set missing config options
if (!button->backend->bg)
button->backend->bg = &g_array_index(backgrounds, Background, 0);
}
}
void init_button_panel(void *p)
{
Panel *panel = (Panel *)p;
// Make sure this is only done once if there are multiple items
if (panel->button_list && ((Button *)panel->button_list->data)->frontend)
return;
// panel->button_list is now a copy of the pointer panel_config.button_list
// We make it a deep copy
panel->button_list = g_list_copy_deep(panel_config.button_list, create_button_frontend, NULL);
load_icon_themes();
for (GList *l = panel->button_list; l; l = l->next) {
Button *button = l->data;
button->area.bg = button->backend->bg;
button->area.paddingx = button->backend->paddingx;
button->area.paddingy = button->backend->paddingy;
button->area.paddingxlr = button->backend->paddingxlr;
button->area.parent = panel;
button->area.panel = panel;
button->area._dump_geometry = button_dump_geometry;
button->area._compute_desired_size = button_compute_desired_size;
snprintf(button->area.name, sizeof(button->area.name), "Button");
button->area._draw_foreground = draw_button;
button->area.size_mode = LAYOUT_FIXED;
button->area._resize = resize_button;
button->area._get_tooltip_text = button_get_tooltip;
button->area._is_under_mouse = full_width_area_is_under_mouse;
button->area.has_mouse_press_effect =
panel_config.mouse_effects &&
(button->area.has_mouse_over_effect = button->backend->lclick_command || button->backend->mclick_command ||
button->backend->rclick_command || button->backend->uwheel_command ||
button->backend->dwheel_command);
button->area.resize_needed = TRUE;
button->area.on_screen = TRUE;
instantiate_area_gradients(&button->area);
button_reload_icon(button);
}
}
void button_init_fonts()
{
for (GList *l = panel_config.button_list; l; l = l->next) {
Button *button = l->data;
if (!button->backend->font_desc)
button->backend->font_desc = pango_font_description_from_string(get_default_font());
}
}
void button_default_font_changed()
{
gboolean needs_update = FALSE;
for (GList *l = panel_config.button_list; l; l = l->next) {
Button *button = l->data;
if (!button->backend->has_font) {
pango_font_description_free(button->backend->font_desc);
button->backend->font_desc = NULL;
needs_update = TRUE;
}
}
if (!needs_update)
return;
button_init_fonts();
for (int i = 0; i < num_panels; i++) {
for (GList *l = panels[i].button_list; l; l = l->next) {
Button *button = l->data;
if (!button->backend->has_font) {
button->area.resize_needed = TRUE;
schedule_redraw(&button->area);
}
}
}
schedule_panel_redraw();
}
void button_reload_icon(Button *button)
{
free_icon(button->frontend->icon);
free_icon(button->frontend->icon_hover);
free_icon(button->frontend->icon_pressed);
button->frontend->icon = NULL;
button->frontend->icon_load_size = button->frontend->iconw;
char *new_icon_path = get_icon_path(icon_theme_wrapper, button->backend->icon_name, button->frontend->iconw, TRUE);
if (new_icon_path)
button->frontend->icon = imlib_load_image_immediately(new_icon_path);
free(new_icon_path);
// On loading error, fallback to default
if (!button->frontend->icon) {
new_icon_path = get_icon_path(icon_theme_wrapper, DEFAULT_ICON, button->frontend->iconw, TRUE);
if (new_icon_path)
button->frontend->icon = imlib_load_image_immediately(new_icon_path);
free(new_icon_path);
}
Imlib_Image original = button->frontend->icon;
button->frontend->icon = scale_icon(button->frontend->icon, button->frontend->iconw);
free_icon(original);
if (panel_config.mouse_effects) {
button->frontend->icon_hover = adjust_icon(button->frontend->icon,
panel_config.mouse_over_alpha,
panel_config.mouse_over_saturation,
panel_config.mouse_over_brightness);
button->frontend->icon_pressed = adjust_icon(button->frontend->icon,
panel_config.mouse_pressed_alpha,
panel_config.mouse_pressed_saturation,
panel_config.mouse_pressed_brightness);
}
schedule_redraw(&button->area);
}
void button_default_icon_theme_changed()
{
for (int i = 0; i < num_panels; i++) {
for (GList *l = panels[i].button_list; l; l = l->next) {
Button *button = l->data;
button_reload_icon(button);
}
}
schedule_panel_redraw();
}
void cleanup_button()
{
// Cleanup frontends
for (int i = 0; i < num_panels; i++) {
g_list_free_full(panels[i].button_list, destroy_button);
panels[i].button_list = NULL;
}
// Cleanup backends
g_list_free_full(panel_config.button_list, destroy_button);
panel_config.button_list = NULL;
}
int button_compute_desired_size(void *obj)
{
Button *button = (Button *)obj;
Panel *panel = (Panel *)button->area.panel;
int horiz_padding = (panel_horizontal ? button->area.paddingxlr : button->area.paddingy);
int vert_padding = (panel_horizontal ? button->area.paddingy : button->area.paddingxlr);
int interior_padding = button->area.paddingx;
int icon_w, icon_h;
if (button->backend->icon_name) {
if (panel_horizontal)
icon_h = icon_w = button->area.height - top_bottom_border_width(&button->area) - 2 * vert_padding;
else
icon_h = icon_w = button->area.width - left_right_border_width(&button->area) - 2 * horiz_padding;
} else {
icon_h = icon_w = 0;
}
int txt_height_ink, txt_height, txt_width;
if (button->backend->text) {
if (panel_horizontal) {
get_text_size2(button->backend->font_desc,
&txt_height_ink,
&txt_height,
&txt_width,
panel->area.height,
panel->area.width,
button->backend->text,
strlen(button->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
} else {
get_text_size2(button->backend->font_desc,
&txt_height_ink,
&txt_height,
&txt_width,
panel->area.height,
button->area.width - icon_w - (icon_w ? interior_padding : 0) -
2 * horiz_padding - left_right_border_width(&button->area),
button->backend->text,
strlen(button->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
}
} else {
txt_height_ink = txt_height = txt_width = 0;
}
if (panel_horizontal) {
int new_size = txt_width + icon_w + (txt_width && icon_w ? interior_padding : 0);
new_size += 2 * horiz_padding + left_right_border_width(&button->area);
return new_size;
} else {
int new_size;
new_size = txt_height + 2 * vert_padding + top_bottom_border_width(&button->area);
new_size = MAX(new_size, icon_h + 2 * vert_padding + top_bottom_border_width(&button->area));
return new_size;
}
}
gboolean resize_button(void *obj)
{
Button *button = (Button *)obj;
Panel *panel = (Panel *)button->area.panel;
int horiz_padding = (panel_horizontal ? button->area.paddingxlr : button->area.paddingy);
int vert_padding = (panel_horizontal ? button->area.paddingy : button->area.paddingxlr);
int interior_padding = button->area.paddingx;
int icon_w, icon_h;
if (button->backend->icon_name) {
if (panel_horizontal)
icon_h = icon_w = button->area.height - top_bottom_border_width(&button->area) - 2 * vert_padding;
else
icon_h = icon_w = button->area.width - left_right_border_width(&button->area) - 2 * horiz_padding;
} else {
icon_h = icon_w = 0;
}
button->frontend->iconw = icon_w;
button->frontend->iconh = icon_h;
if (button->frontend->icon_load_size != button->frontend->iconw)
button_reload_icon(button);
int txt_height_ink, txt_height, txt_width;
if (button->backend->text) {
if (panel_horizontal) {
get_text_size2(button->backend->font_desc,
&txt_height_ink,
&txt_height,
&txt_width,
panel->area.height,
panel->area.width,
button->backend->text,
strlen(button->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
} else {
get_text_size2(button->backend->font_desc,
&txt_height_ink,
&txt_height,
&txt_width,
panel->area.height,
button->area.width - icon_w - (icon_w ? interior_padding : 0) -
2 * horiz_padding - left_right_border_width(&button->area),
button->backend->text,
strlen(button->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
}
} else {
txt_height_ink = txt_height = txt_width = 0;
}
gboolean result = FALSE;
if (panel_horizontal) {
int new_size = txt_width + icon_w + (txt_width && icon_w ? interior_padding : 0);
new_size += 2 * horiz_padding + left_right_border_width(&button->area);
if (new_size != button->area.width) {
button->area.width = new_size;
result = TRUE;
}
} else {
int new_size;
new_size = txt_height + 2 * vert_padding + top_bottom_border_width(&button->area);
new_size = MAX(new_size, icon_h + 2 * vert_padding + top_bottom_border_width(&button->area));
if (new_size != button->area.height) {
button->area.height = new_size;
result = TRUE;
}
}
button->frontend->textw = txt_width;
button->frontend->texth = txt_height;
if (button->backend->centered) {
if (icon_w) {
button->frontend->icony = (button->area.height - icon_h) / 2;
button->frontend->iconx = (button->area.width - txt_width - (txt_width ? interior_padding : 0) - icon_w) / 2;
button->frontend->texty = (button->area.height - txt_height) / 2;
button->frontend->textx = button->frontend->iconx + icon_w + interior_padding;
} else {
button->frontend->texty = (button->area.height - txt_height) / 2;
button->frontend->textx = (button->area.width - txt_width) / 2;
}
} else {
if (icon_w) {
button->frontend->icony = (button->area.height - icon_h) / 2;
button->frontend->iconx = left_border_width(&button->area) + horiz_padding;
button->frontend->texty = (button->area.height - txt_height) / 2;
button->frontend->textx = button->frontend->iconx + icon_w + interior_padding;
} else {
button->frontend->texty = (button->area.height - txt_height) / 2;
button->frontend->textx = left_border_width(&button->area) + horiz_padding;
}
}
schedule_redraw(&button->area);
return result;
}
void draw_button(void *obj, cairo_t *c)
{
Button *button = obj;
if (button->frontend->icon) {
imlib_context_set_image(button->frontend->icon);
// Render icon
render_image(button->area.pix, button->frontend->iconx, button->frontend->icony);
}
// Render text
if (button->backend->text) {
PangoLayout *layout = pango_cairo_create_layout(c);
pango_layout_set_font_description(layout, button->backend->font_desc);
pango_layout_set_width(layout, button->frontend->textw * PANGO_SCALE);
pango_layout_set_alignment(layout, button->backend->centered ? PANGO_ALIGN_CENTER : PANGO_ALIGN_LEFT);
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
pango_layout_set_text(layout, button->backend->text, strlen(button->backend->text));
pango_cairo_update_layout(c, layout);
draw_text(layout,
c,
button->frontend->textx,
button->frontend->texty,
&button->backend->font_color,
panel_config.font_shadow);
g_object_unref(layout);
}
}
void button_dump_geometry(void *obj, int indent)
{
Button *button = obj;
if (button->frontend->icon) {
Imlib_Image tmp = imlib_context_get_image();
imlib_context_set_image(button->frontend->icon);
fprintf(stderr,
"%*sIcon: x = %d, y = %d, w = %d, h = %d\n",
indent,
"",
button->frontend->iconx,
button->frontend->icony,
imlib_image_get_width(),
imlib_image_get_height());
if (tmp)
imlib_context_set_image(tmp);
}
fprintf(stderr,
"%*sText: x = %d, y = %d, w = %d, align = %s, text = %s\n",
indent,
"",
button->frontend->textx,
button->frontend->texty,
button->frontend->textw,
button->backend->centered ? "center" : "left",
button->backend->text);
}
void button_action(void *obj, int mouse_button, int x, int y)
{
Button *button = obj;
char *command = NULL;
switch (mouse_button) {
case 1:
command = button->backend->lclick_command;
break;
case 2:
command = button->backend->mclick_command;
break;
case 3:
command = button->backend->rclick_command;
break;
case 4:
command = button->backend->uwheel_command;
break;
case 5:
command = button->backend->dwheel_command;
break;
}
if (command) {
char *full_cmd = g_strdup_printf("export BUTTON_X=%d;"
"export BUTTON_Y=%d;"
"export BUTTON_W=%d;"
"export BUTTON_H=%d; %s",
x,
y,
button->area.width,
button->area.height,
command);
pid_t pid = fork();
if (pid < 0) {
fprintf(stderr, "Could not fork\n");
} else if (pid == 0) {
// Child process
// Allow children to exist after parent destruction
setsid();
// Run the command
execl("/bin/sh", "/bin/sh", "-c", full_cmd, NULL);
fprintf(stderr, "Failed to execlp %s\n", full_cmd);
exit(1);
}
}
}
char *button_get_tooltip(void *obj)
{
Button *button = obj;
if (button->backend->tooltip && strlen(button->backend->tooltip) > 0)
return strdup(button->backend->tooltip);
return NULL;
}

111
src/button/button.h Normal file
View file

@ -0,0 +1,111 @@
#ifndef BUTTON_H
#define BUTTON_H
#include <sys/time.h>
#include <pango/pangocairo.h>
#include "area.h"
#include "common.h"
#include "timer.h"
// Architecture:
// Panel panel_config contains an array of Button, each storing all config options and all the state variables.
// Only these run commands.
//
// Tint2 maintains an array of Panels, one for each monitor. Each stores an array of Button which was initially copied
// from panel_config. Each works as a frontend to the corresponding Button in panel_config as backend, using the
// backend's config and state variables.
typedef struct ButtonBackend {
// Config:
char *icon_name;
char *text;
char *tooltip;
gboolean centered;
gboolean has_font;
PangoFontDescription *font_desc;
Color font_color;
char *lclick_command;
char *mclick_command;
char *rclick_command;
char *uwheel_command;
char *dwheel_command;
// paddingxlr = horizontal padding left/right
// paddingx = horizontal padding between childs
int paddingxlr, paddingx, paddingy;
Background *bg;
// List of Button which are frontends for this backend, one for each panel
GList *instances;
} ButtonBackend;
typedef struct ButtonFrontend {
// Frontend state:
Imlib_Image icon;
Imlib_Image icon_hover;
Imlib_Image icon_pressed;
int icon_load_size;
int iconx;
int icony;
int iconw;
int iconh;
int textx;
int texty;
int textw;
int texth;
} ButtonFrontend;
typedef struct Button {
Area area;
// All elements have the backend pointer set. However only backend elements have ownership.
ButtonBackend *backend;
// Set only for frontend Button items.
ButtonFrontend *frontend;
} Button;
// Called before the config is read and panel_config/panels are created.
// Afterwards, the config parsing code creates the array of Button in panel_config and populates the configuration fields
// in the backend.
// Probably does nothing.
void default_button();
// Creates a new Button item with only the backend field set. The state is NOT initialized. The config is initialized to
// the default values.
// This will be used by the config code to populate its backedn config fields.
Button *create_button();
void destroy_button(void *obj);
// Called after the config is read and panel_config is populated, but before panels are created.
// Initializes the state of the backend items.
// panel_config.panel_items is used to determine which backend items are enabled. The others should be destroyed and
// removed from panel_config.button_list.
void init_button();
// Called after each on-screen panel is created, with a pointer to the panel.
// Initializes the state of the frontend items. Also adds a pointer to it in backend->instances.
// At this point the Area has not been added yet to the GUI tree, but it will be added right away.
void init_button_panel(void *panel);
// Called just before the panels are destroyed. Afterwards, tint2 exits or restarts and reads the config again.
// Releases all frontends and then all the backends.
// The frontend items are not freed by this function, only their members. The items are Areas which are freed in the
// GUI element tree cleanup function (remove_area).
void cleanup_button();
// Called on draw, obj = pointer to the front-end Button item.
void draw_button(void *obj, cairo_t *c);
// Called on resize, obj = pointer to the front-end Button item.
// Returns 1 if the new size is different than the previous size.
gboolean resize_button(void *obj);
// Called on mouse click event.
void button_action(void *obj, int button, int x, int y);
void button_default_font_changed();
void button_default_icon_theme_changed();
void button_reload_icon(Button *button);
#endif // BUTTON_H

View file

@ -221,6 +221,15 @@ Execp *get_or_create_last_execp()
return (Execp *)g_list_last(panel_config.execp_list)->data;
}
Button *get_or_create_last_button()
{
if (!panel_config.button_list) {
fprintf(stderr, "Warning: button items should start with 'button = new'\n");
panel_config.button_list = g_list_append(panel_config.button_list, create_button());
}
return (Button *)g_list_last(panel_config.button_list)->data;
}
void add_entry(char *key, char *value)
{
char *value1 = 0, *value2 = 0, *value3 = 0;
@ -738,6 +747,78 @@ void add_entry(char *key, char *value)
execp->backend->dwheel_command = strdup(value);
}
/* Button */
else if (strcmp(key, "button") == 0) {
panel_config.button_list = g_list_append(panel_config.button_list, create_button());
} else if (strcmp(key, "button_icon") == 0) {
Button *button = get_or_create_last_button();
button->backend->icon_name = strdup(value);
} else if (strcmp(key, "button_text") == 0) {
Button *button = get_or_create_last_button();
free_and_null(button->backend->text);
button->backend->text = strdup(value);
} else if (strcmp(key, "button_tooltip") == 0) {
Button *button = get_or_create_last_button();
free_and_null(button->backend->tooltip);
button->backend->tooltip = strdup(value);
} else if (strcmp(key, "button_font") == 0) {
Button *button = get_or_create_last_button();
pango_font_description_free(button->backend->font_desc);
button->backend->font_desc = pango_font_description_from_string(value);
button->backend->has_font = TRUE;
} else if (strcmp(key, "button_font_color") == 0) {
Button *button = get_or_create_last_button();
extract_values(value, &value1, &value2, &value3);
get_color(value1, button->backend->font_color.rgb);
if (value2)
button->backend->font_color.alpha = atoi(value2) / 100.0;
else
button->backend->font_color.alpha = 0.5;
} else if (strcmp(key, "button_padding") == 0) {
Button *button = get_or_create_last_button();
extract_values(value, &value1, &value2, &value3);
button->backend->paddingxlr = button->backend->paddingx = atoi(value1);
if (value2)
button->backend->paddingy = atoi(value2);
else
button->backend->paddingy = 0;
if (value3)
button->backend->paddingx = atoi(value3);
} else if (strcmp(key, "button_background_id") == 0) {
Button *button = get_or_create_last_button();
int id = atoi(value);
id = (id < backgrounds->len && id >= 0) ? id : 0;
button->backend->bg = &g_array_index(backgrounds, Background, id);
} else if (strcmp(key, "button_centered") == 0) {
Button *button = get_or_create_last_button();
button->backend->centered = atoi(value);
} else if (strcmp(key, "button_lclick_command") == 0) {
Button *button = get_or_create_last_button();
free_and_null(button->backend->lclick_command);
if (strlen(value) > 0)
button->backend->lclick_command = strdup(value);
} else if (strcmp(key, "button_mclick_command") == 0) {
Button *button = get_or_create_last_button();
free_and_null(button->backend->mclick_command);
if (strlen(value) > 0)
button->backend->mclick_command = strdup(value);
} else if (strcmp(key, "button_rclick_command") == 0) {
Button *button = get_or_create_last_button();
free_and_null(button->backend->rclick_command);
if (strlen(value) > 0)
button->backend->rclick_command = strdup(value);
} else if (strcmp(key, "button_uwheel_command") == 0) {
Button *button = get_or_create_last_button();
free_and_null(button->backend->uwheel_command);
if (strlen(value) > 0)
button->backend->uwheel_command = strdup(value);
} else if (strcmp(key, "button_dwheel_command") == 0) {
Button *button = get_or_create_last_button();
free_and_null(button->backend->dwheel_command);
if (strlen(value) > 0)
button->backend->dwheel_command = strdup(value);
}
/* Clock */
else if (strcmp(key, "time1_format") == 0) {
if (!new_config_file) {

View file

@ -54,6 +54,8 @@ int startup_notifications;
Background *launcher_icon_bg;
GList *launcher_icon_gradients;
IconThemeWrapper *icon_theme_wrapper;
Imlib_Image scale_icon(Imlib_Image original, int icon_size);
void free_icon(Imlib_Image icon);
void launcher_icon_dump_geometry(void *obj, int indent);
@ -114,10 +116,16 @@ void init_launcher_panel(void *p)
schedule_panel_redraw();
instantiate_area_gradients(&launcher->area);
launcher_load_themes(launcher);
load_icon_themes();
launcher_load_icons(launcher);
}
void free_icon_themes()
{
free_themes(icon_theme_wrapper);
icon_theme_wrapper = NULL;
}
void cleanup_launcher()
{
for (int i = 0; i < num_panels; i++) {
@ -160,9 +168,6 @@ void cleanup_launcher_theme(Launcher *launcher)
}
g_slist_free(launcher->list_icons);
launcher->list_icons = NULL;
free_themes(launcher->icon_theme_wrapper);
launcher->icon_theme_wrapper = NULL;
}
int launcher_compute_icon_size(Launcher *launcher)
@ -246,7 +251,7 @@ gboolean resize_launcher(void *obj)
launcher_reload_icon_image(launcher, launcherIcon);
}
}
save_icon_cache(launcher->icon_theme_wrapper);
save_icon_cache(icon_theme_wrapper);
int count = 0;
gboolean needs_repositioning = FALSE;
@ -565,13 +570,13 @@ void launcher_reload_icon_image(Launcher *launcher, LauncherIcon *launcherIcon)
free_icon(launcherIcon->image_pressed);
launcherIcon->image = NULL;
char *new_icon_path = get_icon_path(launcher->icon_theme_wrapper, launcherIcon->icon_name, launcherIcon->icon_size, TRUE);
char *new_icon_path = get_icon_path(icon_theme_wrapper, launcherIcon->icon_name, launcherIcon->icon_size, TRUE);
if (new_icon_path)
launcherIcon->image = load_image(new_icon_path, 1);
// On loading error, fallback to default
if (!launcherIcon->image) {
free(new_icon_path);
new_icon_path = get_icon_path(launcher->icon_theme_wrapper, DEFAULT_ICON, launcherIcon->icon_size, TRUE);
new_icon_path = get_icon_path(icon_theme_wrapper, DEFAULT_ICON, launcherIcon->icon_size, TRUE);
if (new_icon_path)
launcherIcon->image = imlib_load_image_immediately(new_icon_path);
}
@ -595,10 +600,11 @@ void launcher_reload_icon_image(Launcher *launcher, LauncherIcon *launcherIcon)
schedule_redraw(&launcherIcon->area);
}
// Populates the icon_theme_wrapper list
void launcher_load_themes(Launcher *launcher)
void load_icon_themes()
{
launcher->icon_theme_wrapper =
if (icon_theme_wrapper)
return;
icon_theme_wrapper =
load_themes(launcher_icon_theme_override
? (icon_theme_name_config ? icon_theme_name_config
: icon_theme_name_xsettings ? icon_theme_name_xsettings : "hicolor")
@ -608,14 +614,9 @@ void launcher_load_themes(Launcher *launcher)
void launcher_default_icon_theme_changed()
{
if (!launcher_enabled)
return;
if (launcher_icon_theme_override && icon_theme_name_config)
return;
for (int i = 0; i < num_panels; i++) {
Launcher *launcher = &panels[i].launcher;
cleanup_launcher_theme(launcher);
launcher_load_themes(launcher);
launcher_load_icons(launcher);
launcher->area.resize_needed = 1;
}

View file

@ -12,12 +12,15 @@
#include "xsettings-client.h"
#include "icon-theme-common.h"
extern IconThemeWrapper *icon_theme_wrapper;
void load_icon_themes();
void free_icon_themes();
typedef struct Launcher {
// always start with area
Area area;
GSList *list_apps; // List of char*, each is a path to a app.desktop file
GSList *list_icons; // List of LauncherIcon*
IconThemeWrapper *icon_theme_wrapper;
int icon_size;
} Launcher;
@ -65,8 +68,6 @@ void launcher_default_icon_theme_changed();
// Populates the list_icons list
void launcher_load_icons(Launcher *launcher);
// Populates the list_themes list
void launcher_load_themes(Launcher *launcher);
void launcher_action(LauncherIcon *icon, XEvent *e);
void test_launcher_read_desktop_file();

View file

@ -180,6 +180,8 @@ void init_panel()
fprintf(stderr, "panel items: %s\n", panel_items_order);
icon_theme_wrapper = NULL;
init_tooltip();
init_systray();
init_launcher();
@ -190,6 +192,7 @@ void init_panel()
init_taskbar();
init_separator();
init_execp();
init_button();
// number of panels (one monitor or 'all' monitors)
if (panel_config.monitor >= 0)
@ -247,6 +250,8 @@ void init_panel()
init_separator_panel(p);
if (panel_items_order[k] == 'E')
init_execp_panel(p);
if (panel_items_order[k] == 'P')
init_button_panel(p);
}
set_panel_items_order(p);
@ -603,6 +608,7 @@ void set_panel_items_order(Panel *p)
int i_execp = 0;
int i_separator = 0;
int i_freespace = 0;
int i_button = 0;
for (int k = 0; k < strlen(panel_items_order); k++) {
if (panel_items_order[k] == 'L') {
p->area.children = g_list_append(p->area.children, &p->launcher);
@ -640,6 +646,12 @@ void set_panel_items_order(Panel *p)
if (item)
p->area.children = g_list_append(p->area.children, (Area *)item->data);
}
if (panel_items_order[k] == 'P') {
GList *item = g_list_nth(p->button_list, i_button);
i_button++;
if (item)
p->area.children = g_list_append(p->area.children, (Area *)item->data);
}
}
initialize_positions(&p->area, 0);
}
@ -986,6 +998,16 @@ Execp *click_execp(Panel *panel, int x, int y)
return NULL;
}
Button *click_button(Panel *panel, int x, int y)
{
for (GList *l = panel->button_list; l; l = l->next) {
Button *button = (Button *)l->data;
if (area_is_under_mouse(button, x, y))
return button;
}
return NULL;
}
void stop_autohide_timeout(Panel *p)
{
stop_timeout(p->autohide_timeout);
@ -1082,7 +1104,16 @@ const char *get_default_font()
void default_icon_theme_changed()
{
if (!launcher_enabled && !panel_config.button_list)
return;
if (launcher_icon_theme_override && icon_theme_name_config)
return;
free_icon_themes();
load_icon_themes();
launcher_default_icon_theme_changed();
button_default_icon_theme_changed();
}
void default_font_changed()
@ -1092,6 +1123,7 @@ void default_font_changed()
#endif
clock_default_font_changed();
execp_default_font_changed();
button_default_font_changed();
taskbar_default_font_changed();
taskbarname_default_font_changed();
tooltip_default_font_changed();

View file

@ -23,6 +23,7 @@
#include "freespace.h"
#include "execplugin.h"
#include "separator.h"
#include "button.h"
#ifdef ENABLE_BATTERY
#include "battery.h"
@ -135,6 +136,7 @@ typedef struct Panel {
GList *freespace_list;
GList *separator_list;
GList *execp_list;
GList *button_list;
// Autohide
gboolean is_hidden;
@ -189,6 +191,7 @@ Battery *click_battery(Panel *panel, int x, int y);
Area *click_area(Panel *panel, int x, int y);
Execp *click_execp(Panel *panel, int x, int y);
Button *click_button(Panel *panel, int x, int y);
void autohide_show(void *p);
void autohide_hide(void *p);
@ -200,4 +203,7 @@ const char *get_default_font();
void default_icon_theme_changed();
void default_font_changed();
void free_icon(Imlib_Image icon);
Imlib_Image scale_icon(Imlib_Image original, int icon_size);
#endif

View file

@ -393,6 +393,7 @@ void init(int argc, char *argv[])
default_taskbar();
default_tooltip();
default_execp();
default_button();
default_panel();
// Read command line arguments
@ -612,6 +613,7 @@ void init_X11_post_config()
void cleanup()
{
cleanup_button();
cleanup_execp();
cleanup_systray();
cleanup_tooltip();
@ -812,6 +814,8 @@ int tint2_handles_click(Panel *panel, XButtonEvent *e)
#endif
if (click_execp(panel, e->x, e->y))
return 1;
if (click_button(panel, e->x, e->y))
return 1;
return 0;
}
@ -975,6 +979,15 @@ void event_button_release(XEvent *e)
return;
}
Button *button = click_button(panel, e->xbutton.x, e->xbutton.y);
if (button) {
button_action(button, e->xbutton.button, e->xbutton.x - button->area.posx, e->xbutton.y - button->area.posy);
if (panel_layer == BOTTOM_LAYER)
XLowerWindow(server.display, panel->main_win);
task_drag = 0;
return;
}
if (e->xbutton.button == 1 && click_launcher(panel, e->xbutton.x, e->xbutton.y)) {
LauncherIcon *icon = click_launcher_icon(panel, e->xbutton.x, e->xbutton.y);
if (icon) {

View file

@ -223,3 +223,5 @@ src/tint2conf/md4.h
src/tint2conf/md4.c
src/tint2rc.c
src/tint2rc.h
src/button/button.c
src/button/button.h

View file

@ -24,3 +24,4 @@ src/execplugin
src/separator
themes
doc
src/button