Compare commits

...

18 Commits

Author SHA1 Message Date
o9000
6cde7bef1e Release 0.14.1 2017-03-26 15:50:55 +02:00
o9000
b9ab0ae58e tint2conf: Fix bad code when compiling with clang 2017-03-26 15:47:16 +02:00
o9000
2c90c5640e tint2conf: Fix bad code when compiling with clang 2017-03-26 15:46:10 +02:00
o9000
cb43e76660 Release 0.14 2017-03-26 10:49:47 +02:00
o9000
0fc22b5cd6 Button: svg icon support 2017-03-26 10:39:02 +02:00
o9000
a2c5553f4f Button: make sure icon is optional 2017-03-25 15:50:32 +01:00
o9000
63dd4a3e6c Button: make sure icon is optional 2017-03-25 15:48:03 +01:00
o9000
a7fc86cfbb tint2conf: Fixes for buttons 2017-03-25 15:45:10 +01:00
o9000
d72aa2edfb Button: doc 2017-03-25 15:28:50 +01:00
o9000
54d361cf42 Button: mouse effects 2017-03-25 15:23:06 +01:00
o9000
153de1aa45 Button: bugfix 2017-03-25 15:19:57 +01:00
o9000
fc883a5dd8 Button: maximum icon size option 2017-03-25 14:53:21 +01:00
o9000
dfd735956c tint2conf: Update fr.po 2017-03-25 14:42:06 +01:00
o9000
a77b728110 tint2conf: Update po 2017-03-25 14:38:24 +01:00
o9000
5cfffd7c8e tint2conf: Update pot 2017-03-25 14:38:04 +01:00
o9000
a73c6928c3 tint2conf: Buttons 2017-03-25 14:36:40 +01:00
o9000
d5dfda296f Buttons 2017-03-25 14:17:27 +01:00
o9000
89d57f893c Revert get_version.sh 2017-03-25 12:02:20 +01:00
31 changed files with 6585 additions and 5143 deletions

View File

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

View File

@@ -1,3 +1,11 @@
2017-03-26 0.14.1
- Fixes:
- Fixed tint2conf problem under FreeBSD (or generally any system using clang).
2017-03-26 0.14
- Enhancements:
- New plugin: button.
2017-03-25 0.13.3 2017-03-25 0.13.3
- Fixes: - Fixes:
- Fixed autohide for non-bottom panels (issue #632) - Fixed autohide for non-bottom panels (issue #632)

View File

@@ -1,5 +1,5 @@
# Latest stable release: 0.13.3 # Latest stable release: 0.14.1
Changes: https://gitlab.com/o9000/tint2/blob/0.13.3/ChangeLog Changes: https://gitlab.com/o9000/tint2/blob/0.14.1/ChangeLog
Documentation: [doc/tint2.md](doc/tint2.md) Documentation: [doc/tint2.md](doc/tint2.md)
@@ -8,7 +8,7 @@ Compile it with (after you install the [dependencies](https://gitlab.com/o9000/t
``` ```
git clone https://gitlab.com/o9000/tint2.git git clone https://gitlab.com/o9000/tint2.git
cd tint2 cd tint2
git checkout 0.13.3 git checkout 0.14.1
mkdir build mkdir build
cd build cd build
cmake .. cmake ..

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="#tooltip">Tooltip</a></p></li>
<li><p><a href="#battery">Battery</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="#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="#separator">Separator</a></p></li>
<li><p><a href="#example-configuration">Example configuration</a></p></li> <li><p><a href="#example-configuration">Example configuration</a></p></li>
</ul> </ul>
@@ -359,6 +360,7 @@ gradient_id_pressed = 2
<li><code>C</code> shows the Clock</li> <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>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>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> <li><code>:</code> adds a separator. You can specify more than one. <em>(since 0.13.0)</em></li>
</ul> </ul>
<p>For example, <code>panel_items = STC</code> will show the systray, the taskbar and the clock (from left to right).</p></li> <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,24 @@ execp_command = stdbuf -oL bwm-ng -o csv -t 1000 | awk -F ';' '/total/ { printf
execp_continuous = 1 execp_continuous = 1
execp_interval = 1 execp_interval = 1
</code></pre> </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_max_icon_size = integer</code> : Sets a limit to the icon size. Otherwise, the icon will expand to the edges. <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> <h3 id="separator">Separator<a name="separator" href="#separator" class="md2man-permalink" title="permalink"></a></h3>
<ul> <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> <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 +679,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_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> <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> </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>#--------------------------------------------- <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>.
## 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>.
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 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> 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 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

@@ -199,9 +199,9 @@ pre {
</style> </style>
</head> </head>
<body> <body>
<h1 id="latest-stable-release-0-13-3"><span class="md2man-title">Latest</span> <span class="md2man-section">stable</span> <span class="md2man-date">release:</span> <span class="md2man-source">0.13.3</span><a name="latest-stable-release-0-13-3" href="#latest-stable-release-0-13-3" class="md2man-permalink" title="permalink"></a></h1><p>Changes: <a href="https://gitlab.com/o9000/tint2/blob/0.13.3/ChangeLog">https://gitlab.com/o9000/tint2/blob/0.13.3/ChangeLog</a></p><p>Documentation: <a href="manual.html">manual.html</a></p><p>Compile it with (after you install the <a href="https://gitlab.com/o9000/tint2/wikis/Install#dependencies">dependencies</a>):</p><pre class="highlight plaintext"><code>git clone https://gitlab.com/o9000/tint2.git <h1 id="latest-stable-release-0-14-1"><span class="md2man-title">Latest</span> <span class="md2man-section">stable</span> <span class="md2man-date">release:</span> <span class="md2man-source">0.14.1</span><a name="latest-stable-release-0-14-1" href="#latest-stable-release-0-14-1" class="md2man-permalink" title="permalink"></a></h1><p>Changes: <a href="https://gitlab.com/o9000/tint2/blob/0.14.1/ChangeLog">https://gitlab.com/o9000/tint2/blob/0.14.1/ChangeLog</a></p><p>Documentation: <a href="manual.html">manual.html</a></p><p>Compile it with (after you install the <a href="https://gitlab.com/o9000/tint2/wikis/Install#dependencies">dependencies</a>):</p><pre class="highlight plaintext"><code>git clone https://gitlab.com/o9000/tint2.git
cd tint2 cd tint2
git checkout 0.13.3 git checkout 0.14.1
mkdir build mkdir build
cd build cd build
cmake .. cmake ..

View File

@@ -1,4 +1,4 @@
.TH TINT2 1 "2017\-03\-12" 0.13.3 .TH TINT2 1 "2017\-03\-26" 0.14.1
.SH NAME .SH NAME
.PP .PP
tint2 \- lightweight panel/taskbar tint2 \- lightweight panel/taskbar
@@ -67,6 +67,8 @@ Battery \[la]#battery\[ra]
.IP \(bu 2 .IP \(bu 2
Executor \[la]#executor\[ra] Executor \[la]#executor\[ra]
.IP \(bu 2 .IP \(bu 2
Button \[la]#button\[ra]
.IP \(bu 2
Separator \[la]#separator\[ra] Separator \[la]#separator\[ra]
.IP \(bu 2 .IP \(bu 2
Example configuration \[la]#example-configuration\[ra] Example configuration \[la]#example-configuration\[ra]
@@ -294,6 +296,8 @@ gradient_id_pressed = 2
.IP \(bu 2 .IP \(bu 2
\fB\fCE\fR adds an executor plugin. You can specify more than one. \fI(since 0.12.4)\fP \fB\fCE\fR adds an executor plugin. You can specify more than one. \fI(since 0.12.4)\fP
.IP \(bu 2 .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 \fB\fC:\fR adds a separator. You can specify more than one. \fI(since 0.13.0)\fP
.RE .RE
.PP .PP
@@ -800,6 +804,39 @@ execp_continuous = 1
execp_interval = 1 execp_interval = 1
.fi .fi
.RE .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_max_icon_size = integer\fR : Sets a limit to the icon size. Otherwise, the icon will expand to the edges. \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 .SS Separator
.RS .RS
.IP \(bu 2 .IP \(bu 2
@@ -817,144 +854,7 @@ execp_interval = 1
.RE .RE
.SS Example configuration .SS Example configuration
.PP .PP
.RS See /etc/xdg/tint2/tint2rc.
.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
.SH AUTHOR .SH AUTHOR
.PP .PP
tint2 was written by Thierry Lorthiois \[la]lorthiois@bbsoft.fr\[ra]\&. tint2 was written by Thierry Lorthiois \[la]lorthiois@bbsoft.fr\[ra]\&.

View File

@@ -1,4 +1,4 @@
# TINT2 1 "2017-03-12" 0.13.3 # TINT2 1 "2017-03-26" 0.14.1
## NAME ## NAME
tint2 - lightweight panel/taskbar tint2 - lightweight panel/taskbar
@@ -58,6 +58,8 @@ Goals:
* [Executor](#executor) * [Executor](#executor)
* [Button](#button)
* [Separator](#separator) * [Separator](#separator)
* [Example configuration](#example-configuration) * [Example configuration](#example-configuration)
@@ -244,6 +246,7 @@ gradient_id_pressed = 2
* `C` shows the Clock * `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)* * `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)* * `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)* * `:` 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). For example, `panel_items = STC` will show the systray, the taskbar and the clock (from left to right).
@@ -671,6 +674,33 @@ execp_continuous = 1
execp_interval = 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_max_icon_size = integer` : Sets a limit to the icon size. Otherwise, the icon will expand to the edges. *(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
* `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)* * `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 +717,7 @@ execp_interval = 1
### Example configuration ### Example configuration
``` See /etc/xdg/tint2/tint2rc.
#---------------------------------------------
## 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
```
## AUTHOR ## AUTHOR
tint2 was written by Thierry Lorthiois <lorthiois@bbsoft.fr>. tint2 was written by Thierry Lorthiois <lorthiois@bbsoft.fr>.

View File

@@ -1,6 +1,9 @@
#!/bin/sh #!/bin/sh
VERSION=0.13.3 MAJOR=0.14
DIRTY=""
VERSION=0.14
echo '#define VERSION_STRING "'$VERSION'"' > version.h echo '#define VERSION_STRING "'$VERSION'"' > version.h
echo $VERSION echo $VERSION

568
src/button/button.c Normal file
View File

@@ -0,0 +1,568 @@
#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] == 'P') {
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_hover = NULL;
button->frontend->icon_pressed = NULL;
button->frontend->icon_load_size = button->frontend->iconw;
if (!button->backend->icon_name)
return;
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 = load_image(new_icon_path, TRUE);
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 = load_image(new_icon_path, TRUE);
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;
if (button->backend->max_icon_size) {
icon_w = MIN(icon_w, button->backend->max_icon_size);
icon_h = MIN(icon_h, button->backend->max_icon_size);
}
} 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;
if (button->backend->max_icon_size) {
icon_w = MIN(icon_w, button->backend->max_icon_size);
icon_h = MIN(icon_h, button->backend->max_icon_size);
}
} 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) {
// Render icon
Imlib_Image image;
if (panel_config.mouse_effects) {
if (button->area.mouse_state == MOUSE_OVER)
image = button->frontend->icon_hover ? button->frontend->icon_hover : button->frontend->icon;
else if (button->area.mouse_state == MOUSE_DOWN)
image = button->frontend->icon_pressed ? button->frontend->icon_pressed : button->frontend->icon;
else
image = button->frontend->icon;
} else {
image = button->frontend->icon;
}
imlib_context_set_image(image);
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;
}

112
src/button/button.h Normal file
View File

@@ -0,0 +1,112 @@
#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;
int max_icon_size;
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; 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) void add_entry(char *key, char *value)
{ {
char *value1 = 0, *value2 = 0, *value3 = 0; char *value1 = 0, *value2 = 0, *value3 = 0;
@@ -738,6 +747,82 @@ void add_entry(char *key, char *value)
execp->backend->dwheel_command = strdup(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 && strlen(value)) {
Button *button = get_or_create_last_button();
button->backend->icon_name = strdup(value);
} else if (strcmp(key, "button_text") == 0 && strlen(value)) {
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 && strlen(value)) {
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_max_icon_size") == 0) {
Button *button = get_or_create_last_button();
extract_values(value, &value1, &value2, &value3);
button->backend->max_icon_size = MAX(0, atoi(value));
} 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 */ /* Clock */
else if (strcmp(key, "time1_format") == 0) { else if (strcmp(key, "time1_format") == 0) {
if (!new_config_file) { if (!new_config_file) {

View File

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

View File

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

View File

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

View File

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

View File

@@ -393,6 +393,7 @@ void init(int argc, char *argv[])
default_taskbar(); default_taskbar();
default_tooltip(); default_tooltip();
default_execp(); default_execp();
default_button();
default_panel(); default_panel();
// Read command line arguments // Read command line arguments
@@ -600,7 +601,7 @@ void init_X11_post_config()
for (int i = 0; data_dirs[i] != NULL; i++) { for (int i = 0; data_dirs[i] != NULL; i++) {
gchar *path = g_build_filename(data_dirs[i], "tint2", "default_icon.png", NULL); gchar *path = g_build_filename(data_dirs[i], "tint2", "default_icon.png", NULL);
if (g_file_test(path, G_FILE_TEST_EXISTS)) if (g_file_test(path, G_FILE_TEST_EXISTS))
default_icon = imlib_load_image(path); default_icon = load_image(path, TRUE);
g_free(path); g_free(path);
} }
if (!default_icon) { if (!default_icon) {
@@ -612,6 +613,7 @@ void init_X11_post_config()
void cleanup() void cleanup()
{ {
cleanup_button();
cleanup_execp(); cleanup_execp();
cleanup_systray(); cleanup_systray();
cleanup_tooltip(); cleanup_tooltip();
@@ -812,6 +814,8 @@ int tint2_handles_click(Panel *panel, XButtonEvent *e)
#endif #endif
if (click_execp(panel, e->x, e->y)) if (click_execp(panel, e->x, e->y))
return 1; return 1;
if (click_button(panel, e->x, e->y))
return 1;
return 0; return 0;
} }
@@ -975,6 +979,15 @@ void event_button_release(XEvent *e)
return; 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)) { 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); LauncherIcon *icon = click_launcher_icon(panel, e->xbutton.x, e->xbutton.y);
if (icon) { if (icon) {

View File

@@ -119,7 +119,7 @@ gchar *import_no_overwrite(const char *filepath)
if (!g_file_test(newpath, G_FILE_TEST_EXISTS)) { if (!g_file_test(newpath, G_FILE_TEST_EXISTS)) {
copy_file(filepath, newpath); copy_file(filepath, newpath);
theme_list_append(newpath); theme_list_append(newpath);
g_timeout_add(SNAPSHOT_TICK, (GSourceFunc)update_snapshot, NULL); g_timeout_add(SNAPSHOT_TICK, update_snapshot, NULL);
} }
return newpath; return newpath;
@@ -138,7 +138,7 @@ void import_with_overwrite(const char *filepath, const char *newpath)
if (theme_is_editable(newpath)) { if (theme_is_editable(newpath)) {
if (!theme_existed) { if (!theme_existed) {
theme_list_append(newpath); theme_list_append(newpath);
g_timeout_add(SNAPSHOT_TICK, (GSourceFunc)update_snapshot, NULL); g_timeout_add(SNAPSHOT_TICK, update_snapshot, NULL);
} else { } else {
int unused = system("killall -SIGUSR1 tint2 || pkill -SIGUSR1 -x tint2"); int unused = system("killall -SIGUSR1 tint2 || pkill -SIGUSR1 -x tint2");
(void)unused; (void)unused;
@@ -158,7 +158,7 @@ static void menuImportFile();
static void menuSaveAs(); static void menuSaveAs();
static void menuDelete(); static void menuDelete();
static void menuReset(); static void menuReset();
static void edit_theme(); static gboolean edit_theme(gpointer ignored);
static void make_selected_theme_default(); static void make_selected_theme_default();
static void menuAbout(); static void menuAbout();
static gboolean view_onPopupMenu(GtkWidget *treeview, gpointer userdata); static gboolean view_onPopupMenu(GtkWidget *treeview, gpointer userdata);
@@ -309,7 +309,7 @@ int main(int argc, char **argv)
argc--, argv++; argc--, argv++;
if (argc > 0) { if (argc > 0) {
load_specific_themes(argv, argc); load_specific_themes(argv, argc);
g_timeout_add(SNAPSHOT_TICK, (GSourceFunc)edit_theme, NULL); g_timeout_add(SNAPSHOT_TICK, edit_theme, NULL);
} }
gtk_widget_show_all(g_window); gtk_widget_show_all(g_window);
@@ -643,11 +643,11 @@ void select_theme(const char *given_path)
} }
// Edits the selected theme. If it is read-only, it copies first to ~. // Edits the selected theme. If it is read-only, it copies first to ~.
static void edit_theme() static gboolean edit_theme(gpointer ignored)
{ {
gchar *filepath = get_selected_theme_or_warn(); gchar *filepath = get_selected_theme_or_warn();
if (!filepath) if (!filepath)
return; return FALSE;
gboolean editable = theme_is_editable(filepath); gboolean editable = theme_is_editable(filepath);
if (!editable) { if (!editable) {
@@ -665,6 +665,8 @@ static void edit_theme()
g_free(filepath); g_free(filepath);
destroy_please_wait(); destroy_please_wait();
return FALSE;
} }
static void make_selected_theme_default() static void make_selected_theme_default()
@@ -702,7 +704,7 @@ static void make_selected_theme_default()
static void viewRowActivated(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data) static void viewRowActivated(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
{ {
edit_theme(); edit_theme(NULL);
} }
// ====== Theme load/reload ====== // ====== Theme load/reload ======
@@ -834,7 +836,7 @@ static void load_all_themes()
have_iter = gtk_tree_model_iter_next(model, &iter); have_iter = gtk_tree_model_iter_next(model, &iter);
} }
g_timeout_add(SNAPSHOT_TICK, (GSourceFunc)update_snapshot, NULL); g_timeout_add(SNAPSHOT_TICK, update_snapshot, NULL);
} }
} }
@@ -865,7 +867,7 @@ static void reload_all_themes()
have_iter = gtk_tree_model_iter_next(model, &iter); have_iter = gtk_tree_model_iter_next(model, &iter);
} }
g_timeout_add(SNAPSHOT_TICK, (GSourceFunc)update_snapshot, NULL); g_timeout_add(SNAPSHOT_TICK, update_snapshot, NULL);
} }
} }
@@ -899,7 +901,7 @@ static void load_specific_themes(char **paths, int count)
have_iter = gtk_tree_model_iter_next(model, &iter); have_iter = gtk_tree_model_iter_next(model, &iter);
} }
g_timeout_add(SNAPSHOT_TICK, (GSourceFunc)update_snapshot, NULL); g_timeout_add(SNAPSHOT_TICK, update_snapshot, NULL);
} }
} }
@@ -910,7 +912,7 @@ void refresh_current_theme()
GtkTreeModel *model; GtkTreeModel *model;
if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(sel), &model, &iter)) { if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(sel), &model, &iter)) {
gtk_list_store_set(theme_list_store, &iter, COL_SNAPSHOT, NULL, -1); gtk_list_store_set(theme_list_store, &iter, COL_SNAPSHOT, NULL, -1);
g_timeout_add(SNAPSHOT_TICK, (GSourceFunc)update_snapshot, NULL); g_timeout_add(SNAPSHOT_TICK, update_snapshot, NULL);
} }
} }
@@ -925,7 +927,7 @@ void refresh_theme(const char *given_path)
gtk_tree_model_get(model, &iter, COL_THEME_FILE, &filepath, -1); gtk_tree_model_get(model, &iter, COL_THEME_FILE, &filepath, -1);
if (g_str_equal(filepath, given_path)) { if (g_str_equal(filepath, given_path)) {
gtk_list_store_set(theme_list_store, &iter, COL_SNAPSHOT, NULL, -1); gtk_list_store_set(theme_list_store, &iter, COL_SNAPSHOT, NULL, -1);
g_timeout_add(SNAPSHOT_TICK, (GSourceFunc)update_snapshot, NULL); g_timeout_add(SNAPSHOT_TICK, update_snapshot, NULL);
g_free(filepath); g_free(filepath);
break; break;
} }

View File

@@ -15,7 +15,7 @@
#endif #endif
#define SNAPSHOT_TICK 190 #define SNAPSHOT_TICK 190
gboolean update_snapshot(); gboolean update_snapshot(gpointer ignored);
void menuApply(); void menuApply();
void refresh_current_theme(); void refresh_current_theme();
extern GtkWidget *g_window; extern GtkWidget *g_window;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -115,6 +115,9 @@ GArray *separators;
// Executors // Executors
GArray *executors; GArray *executors;
// Buttons
GArray *buttons;
// launcher // launcher
GtkListStore *launcher_apps, *all_apps; GtkListStore *launcher_apps, *all_apps;
@@ -155,6 +158,7 @@ void create_task_status(GtkWidget *notebook,
GtkWidget **task_status_background_set); GtkWidget **task_status_background_set);
void create_separator(GtkWidget *parent, int i); void create_separator(GtkWidget *parent, int i);
void create_execp(GtkWidget *parent, int i); void create_execp(GtkWidget *parent, int i);
void create_button(GtkWidget *parent, int i);
void create_clock(GtkWidget *parent); void create_clock(GtkWidget *parent);
void create_systemtray(GtkWidget *parent); void create_systemtray(GtkWidget *parent);
void create_battery(GtkWidget *parent); void create_battery(GtkWidget *parent);
@@ -227,6 +231,7 @@ GtkWidget *create_properties()
separators = g_array_new(FALSE, TRUE, sizeof(Separator)); separators = g_array_new(FALSE, TRUE, sizeof(Separator));
executors = g_array_new(FALSE, TRUE, sizeof(Executor)); executors = g_array_new(FALSE, TRUE, sizeof(Executor));
buttons = g_array_new(FALSE, TRUE, sizeof(Button));
// global layer // global layer
view = gtk_dialog_new(); view = gtk_dialog_new();
@@ -1048,6 +1053,11 @@ void create_panel_items(GtkWidget *parent)
itemsColName, _("Executor"), itemsColName, _("Executor"),
itemsColValue, "E", itemsColValue, "E",
-1); -1);
gtk_list_store_append(all_items, &iter);
gtk_list_store_set(all_items, &iter,
itemsColName, _("Button"),
itemsColValue, "P",
-1);
panel_items_view = gtk_tree_view_new(); panel_items_view = gtk_tree_view_new();
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(panel_items_view), gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(panel_items_view),
@@ -1208,6 +1218,7 @@ void set_panel_items(const char *items)
int separator_index = -1; int separator_index = -1;
int execp_index = -1; int execp_index = -1;
int button_index = -1;
for (; items && *items; items++) { for (; items && *items; items++) {
const char *value = NULL; const char *value = NULL;
@@ -1245,6 +1256,12 @@ void set_panel_items(const char *items)
sprintf(buffer, "%s %d", _("Executor"), execp_index + 1); sprintf(buffer, "%s %d", _("Executor"), execp_index + 1);
name = buffer; name = buffer;
value = "E"; value = "E";
} else if (v == 'P') {
button_index++;
buffer[0] = 0;
sprintf(buffer, "%s %d", _("Button"), button_index + 1);
name = buffer;
value = "P";
} else { } else {
continue; continue;
} }
@@ -1272,7 +1289,7 @@ void panel_add_item(GtkWidget *widget, gpointer data)
itemsColValue, &value, itemsColValue, &value,
-1); -1);
if (!panel_contains(value) || g_str_equal(value, ":") || g_str_equal(value, "E") || g_str_equal(value, "F")) { if (!panel_contains(value) || g_str_equal(value, ":") || g_str_equal(value, "E") || g_str_equal(value, "F") || g_str_equal(value, "P")) {
GtkTreeIter iter; GtkTreeIter iter;
gtk_list_store_append(panel_items, &iter); gtk_list_store_append(panel_items, &iter);
gtk_list_store_set(panel_items, &iter, gtk_list_store_set(panel_items, &iter,
@@ -1283,11 +1300,14 @@ void panel_add_item(GtkWidget *widget, gpointer data)
separator_create_new(); separator_create_new();
} else if (g_str_equal(value, "E")) { } else if (g_str_equal(value, "E")) {
execp_create_new(); execp_create_new();
} else if (g_str_equal(value, "P")) {
button_create_new();
} }
} }
} }
separator_update_indices(); separator_update_indices();
execp_update_indices(); execp_update_indices();
button_update_indices();
} }
void panel_remove_item(GtkWidget *widget, gpointer data) void panel_remove_item(GtkWidget *widget, gpointer data)
@@ -1320,6 +1340,14 @@ void panel_remove_item(GtkWidget *widget, gpointer data)
break; break;
} }
} }
} else if (g_str_equal(value, "P")) {
for (int i = 0; i < buttons->len; i++) {
Button *button = &g_array_index(buttons, Button, i);
if (g_str_equal(name, button->name)) {
button_remove(i);
break;
}
}
} }
gtk_list_store_remove(panel_items, &iter); gtk_list_store_remove(panel_items, &iter);
@@ -1327,6 +1355,7 @@ void panel_remove_item(GtkWidget *widget, gpointer data)
separator_update_indices(); separator_update_indices();
execp_update_indices(); execp_update_indices();
button_update_indices();
} }
void panel_move_item_down(GtkWidget *widget, gpointer data) void panel_move_item_down(GtkWidget *widget, gpointer data)
@@ -1380,6 +1409,21 @@ void panel_move_item_down(GtkWidget *widget, gpointer data)
Executor tmp = *executor1; Executor tmp = *executor1;
*executor1 = *executor2; *executor1 = *executor2;
*executor2 = tmp; *executor2 = tmp;
} else if (g_str_equal(value1, "P") && g_str_equal(value2, "P")) {
Button *button1 = NULL;
Button *button2 = NULL;
for (int i = 0; i < buttons->len; i++) {
Button *button = &g_array_index(buttons, Button, i);
if (g_str_equal(name1, button->name)) {
button1 = button;
}
if (g_str_equal(name2, button->name)) {
button2 = button;
}
}
Button tmp = *button1;
*button1 = *button2;
*button2 = tmp;
} }
gtk_list_store_swap(panel_items, &iter, &next); gtk_list_store_swap(panel_items, &iter, &next);
@@ -1387,6 +1431,7 @@ void panel_move_item_down(GtkWidget *widget, gpointer data)
} }
separator_update_indices(); separator_update_indices();
execp_update_indices(); execp_update_indices();
button_update_indices();
} }
void panel_move_item_up(GtkWidget *widget, gpointer data) void panel_move_item_up(GtkWidget *widget, gpointer data)
@@ -1441,6 +1486,21 @@ void panel_move_item_up(GtkWidget *widget, gpointer data)
Executor tmp = *executor1; Executor tmp = *executor1;
*executor1 = *executor2; *executor1 = *executor2;
*executor2 = tmp; *executor2 = tmp;
} else if (g_str_equal(value1, "P") && g_str_equal(value2, "P")) {
Button *button1 = NULL;
Button *button2 = NULL;
for (int i = 0; i < buttons->len; i++) {
Button *button = &g_array_index(buttons, Button, i);
if (g_str_equal(name1, button->name)) {
button1 = button;
}
if (g_str_equal(name2, button->name)) {
button2 = button;
}
}
Button tmp = *button1;
*button1 = *button2;
*button2 = tmp;
} }
gtk_list_store_swap(panel_items, &iter, &prev); gtk_list_store_swap(panel_items, &iter, &prev);
@@ -1449,6 +1509,7 @@ void panel_move_item_up(GtkWidget *widget, gpointer data)
} }
separator_update_indices(); separator_update_indices();
execp_update_indices(); execp_update_indices();
button_update_indices();
} }
enum { enum {
@@ -4160,6 +4221,290 @@ void create_execp(GtkWidget *notebook, int i)
change_paragraph(parent); change_paragraph(parent);
} }
void create_button(GtkWidget *notebook, int i)
{
GtkWidget *label;
GtkWidget *table;
int row, col;
GtkTooltips *tooltips = gtk_tooltips_new();
Button *button = &g_array_index(buttons, Button, i);
button->name[0] = 0;
sprintf(button->name, "%s %d", _("Button"), i + 1);
button->page_label = gtk_label_new(button->name);
gtk_widget_show(button->page_label);
button->page_button = gtk_vbox_new(FALSE, DEFAULT_HOR_SPACING);
button->container = addScrollBarToWidget(button->page_button);
gtk_container_set_border_width(GTK_CONTAINER(button->page_button), 10);
gtk_widget_show(button->page_button);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), button->container, button->page_label);
GtkWidget *parent = button->page_button;
table = gtk_table_new(1, 2, FALSE);
gtk_widget_show(table);
gtk_box_pack_start(GTK_BOX(parent), table, FALSE, FALSE, 0);
gtk_table_set_row_spacings(GTK_TABLE(table), ROW_SPACING);
gtk_table_set_col_spacings(GTK_TABLE(table), COL_SPACING);
row = 0, col = 2;
label = gtk_label_new(_("<b>Format</b>"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_label_set_use_markup(GTK_LABEL(label), TRUE); gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(parent), label, FALSE, FALSE, 0);
table = gtk_table_new(3, 10, FALSE);
gtk_widget_show(table);
gtk_box_pack_start(GTK_BOX(parent), table, FALSE, FALSE, 0);
gtk_table_set_row_spacings(GTK_TABLE(table), ROW_SPACING);
gtk_table_set_col_spacings(GTK_TABLE(table), COL_SPACING);
row = 0, col = 2;
label = gtk_label_new(_("Icon"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_icon = gtk_entry_new();
gtk_widget_show(button->button_icon);
gtk_entry_set_width_chars(GTK_ENTRY(button->button_icon), 50);
gtk_table_attach(GTK_TABLE(table), button->button_icon, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
row++, col = 2;
label = gtk_label_new(_("Text"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_text = gtk_entry_new();
gtk_widget_show(button->button_text);
gtk_entry_set_width_chars(GTK_ENTRY(button->button_text), 50);
gtk_table_attach(GTK_TABLE(table), button->button_text, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
row++, col = 2;
label = gtk_label_new(_("Tooltip"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_tooltip = gtk_entry_new();
gtk_widget_show(button->button_tooltip);
gtk_entry_set_width_chars(GTK_ENTRY(button->button_tooltip), 50);
gtk_table_attach(GTK_TABLE(table), button->button_tooltip, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
change_paragraph(parent);
label = gtk_label_new(_("<b>Mouse events</b>"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(parent), label, FALSE, FALSE, 0);
table = gtk_table_new(5, 10, FALSE);
gtk_widget_show(table);
gtk_box_pack_start(GTK_BOX(parent), table, FALSE, FALSE, 0);
gtk_table_set_row_spacings(GTK_TABLE(table), ROW_SPACING);
gtk_table_set_col_spacings(GTK_TABLE(table), COL_SPACING);
row = 0, col = 2;
label = gtk_label_new(_("Left click command"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_left_command = gtk_entry_new();
gtk_widget_show(button->button_left_command);
gtk_entry_set_width_chars(GTK_ENTRY(button->button_left_command), 50);
gtk_table_attach(GTK_TABLE(table), button->button_left_command, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
gtk_tooltips_set_tip(tooltips, button->button_left_command,
_("Specifies a command that will be executed when the button receives a left click."), NULL);
row++, col = 2;
label = gtk_label_new(_("Right click command"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_right_command = gtk_entry_new();
gtk_widget_show(button->button_right_command);
gtk_entry_set_width_chars(GTK_ENTRY(button->button_right_command), 50);
gtk_table_attach(GTK_TABLE(table), button->button_right_command, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
gtk_tooltips_set_tip(tooltips, button->button_right_command,
_("Specifies a command that will be executed when the button receives a right click."), NULL);
row++, col = 2;
label = gtk_label_new(_("Middle click command"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_mclick_command = gtk_entry_new();
gtk_widget_show(button->button_mclick_command);
gtk_entry_set_width_chars(GTK_ENTRY(button->button_mclick_command), 50);
gtk_table_attach(GTK_TABLE(table), button->button_mclick_command, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
gtk_tooltips_set_tip(tooltips, button->button_mclick_command,
_("Specifies a command that will be executed when the button receives a middle click."), NULL);
row++, col = 2;
label = gtk_label_new(_("Wheel scroll up command"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_uwheel_command = gtk_entry_new();
gtk_widget_show(button->button_uwheel_command);
gtk_entry_set_width_chars(GTK_ENTRY(button->button_uwheel_command), 50);
gtk_table_attach(GTK_TABLE(table), button->button_uwheel_command, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
gtk_tooltips_set_tip(tooltips, button->button_uwheel_command,
_("Specifies a command that will be executed when the button receives a mouse scroll up."), NULL);
row++, col = 2;
label = gtk_label_new(_("Wheel scroll down command"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_dwheel_command = gtk_entry_new();
gtk_widget_show(button->button_dwheel_command);
gtk_entry_set_width_chars(GTK_ENTRY(button->button_dwheel_command), 50);
gtk_table_attach(GTK_TABLE(table), button->button_dwheel_command, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
gtk_tooltips_set_tip(tooltips, button->button_dwheel_command,
_("Specifies a command that will be executed when the button receives a mouse scroll down."), NULL);
change_paragraph(parent);
label = gtk_label_new(_("<b>Appearance</b>"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(parent), label, FALSE, FALSE, 0);
table = gtk_table_new(3, 22, FALSE);
gtk_widget_show(table);
gtk_box_pack_start(GTK_BOX(parent), table, FALSE, FALSE, 0);
gtk_table_set_row_spacings(GTK_TABLE(table), ROW_SPACING);
gtk_table_set_col_spacings(GTK_TABLE(table), COL_SPACING);
row = 0, col = 2;
label = gtk_label_new(_("Background"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_background = create_background_combo(_("Button"));
gtk_widget_show(button->button_background);
gtk_table_attach(GTK_TABLE(table), button->button_background, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
gtk_tooltips_set_tip(tooltips, button->button_background, _("Selects the background used to display the button. "
"Backgrounds can be edited in the Backgrounds tab."), NULL);
row++, col = 2;
label = gtk_label_new(_("Horizontal padding"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_padding_x = gtk_spin_button_new_with_range(0, 500, 1);
gtk_widget_show(button->button_padding_x);
gtk_table_attach(GTK_TABLE(table), button->button_padding_x, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
gtk_tooltips_set_tip(tooltips, button->button_padding_x, _("Specifies the horizontal padding of the button. "
"This is the space between the border and the content inside."), NULL);
row++, col = 2;
label = gtk_label_new(_("Vertical padding"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_padding_y = gtk_spin_button_new_with_range(0, 500, 1);
gtk_widget_show(button->button_padding_y);
gtk_table_attach(GTK_TABLE(table), button->button_padding_y, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
gtk_tooltips_set_tip(tooltips, button->button_padding_y, _("Specifies the vertical padding of the button. "
"This is the space between the border and the content inside."), NULL);
row++, col = 1;
button->button_font_set = gtk_check_button_new();
gtk_widget_show(button->button_font_set);
gtk_table_attach(GTK_TABLE(table), button->button_font_set, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
gtk_tooltips_set_tip(tooltips, button->button_font_set, _("If not checked, the desktop theme font is used. If checked, the custom font specified here is used."), NULL);
col++;
label = gtk_label_new(_("Font"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_font = gtk_font_button_new_with_font(get_default_font());
gtk_widget_show(button->button_font);
gtk_table_attach(GTK_TABLE(table), button->button_font, col, col+3, row, row+1, GTK_FILL, 0, 0, 0);
col++;
gtk_font_button_set_show_style(GTK_FONT_BUTTON(button->button_font), TRUE);
gtk_signal_connect(GTK_OBJECT(button->button_font_set), "toggled", GTK_SIGNAL_FUNC(font_set_callback), button->button_font);
font_set_callback(button->button_font_set, button->button_font);
row++, col = 2;
label = gtk_label_new(_("Font color"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_font_color = gtk_color_button_new();
gtk_color_button_set_use_alpha(GTK_COLOR_BUTTON(button->button_font_color), TRUE);
gtk_widget_show(button->button_font_color);
gtk_table_attach(GTK_TABLE(table), button->button_font_color, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
row++, col = 2;
label = gtk_label_new(_("Centered"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_centered = gtk_check_button_new();
gtk_widget_show(button->button_centered);
gtk_table_attach(GTK_TABLE(table), button->button_centered, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
row++, col = 2;
label = gtk_label_new(_("Maximum icon size"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
button->button_max_icon_size = gtk_spin_button_new_with_range(0, 500, 1);
gtk_widget_show(button->button_max_icon_size);
gtk_table_attach(GTK_TABLE(table), button->button_max_icon_size, col, col+1, row, row+1, GTK_FILL, 0, 0, 0);
col++;
change_paragraph(parent);
}
void separator_create_new() void separator_create_new()
{ {
g_array_set_size(separators, separators->len + 1); g_array_set_size(separators, separators->len + 1);
@@ -4172,6 +4517,12 @@ void execp_create_new()
create_execp(notebook, executors->len - 1); create_execp(notebook, executors->len - 1);
} }
void button_create_new()
{
g_array_set_size(buttons, buttons->len + 1);
create_button(notebook, buttons->len - 1);
}
Separator *separator_get_last() Separator *separator_get_last()
{ {
if (separators->len <= 0) if (separators->len <= 0)
@@ -4186,6 +4537,13 @@ Executor *execp_get_last()
return &g_array_index(executors, Executor, executors->len - 1); return &g_array_index(executors, Executor, executors->len - 1);
} }
Button *button_get_last()
{
if (buttons->len <= 0)
button_create_new();
return &g_array_index(buttons, Button, buttons->len - 1);
}
void separator_remove(int i) void separator_remove(int i)
{ {
Separator *separator = &g_array_index(separators, Separator, i); Separator *separator = &g_array_index(separators, Separator, i);
@@ -4216,6 +4574,21 @@ void execp_remove(int i)
executors = g_array_remove_index(executors, i); executors = g_array_remove_index(executors, i);
} }
void button_remove(int i)
{
Button *button = &g_array_index(buttons, Button, i);
for (int i_page = 0; i_page < gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook)); i_page++) {
GtkWidget *page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i_page);
if (page == button->container) {
gtk_widget_hide(page);
gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), i_page);
}
}
buttons = g_array_remove_index(buttons, i);
}
void separator_update_indices() void separator_update_indices()
{ {
for (int i = 0; i < separators->len; i++) { for (int i = 0; i < separators->len; i++) {
@@ -4290,6 +4663,43 @@ void execp_update_indices()
} }
} }
void button_update_indices()
{
for (int i = 0; i < buttons->len; i++) {
Button *button = &g_array_index(buttons, Button, i);
sprintf(button->name, "%s %d", _("Button"), i + 1);
gtk_label_set_text(GTK_LABEL(button->page_label), button->name);
}
GtkTreeModel *model = GTK_TREE_MODEL(panel_items);
GtkTreeIter iter;
if (!gtk_tree_model_get_iter_first(model, &iter))
return;
int button_index = -1;
while (1) {
gchar *name;
gchar *value;
gtk_tree_model_get(model, &iter,
itemsColName, &name,
itemsColValue, &value,
-1);
if (g_str_equal(value, "P")) {
button_index++;
char buffer[256];
buffer[0] = 0;
sprintf(buffer, "%s %d", _("Button"), button_index + 1);
gtk_list_store_set(panel_items, &iter,
itemsColName, buffer,
-1);
}
if (!gtk_tree_model_iter_next(model, &iter))
break;
}
}
void create_systemtray(GtkWidget *parent) void create_systemtray(GtkWidget *parent)
{ {
GtkWidget *table; GtkWidget *table;

View File

@@ -151,6 +151,21 @@ typedef struct Executor {
extern GArray *executors; extern GArray *executors;
// Button
typedef struct Button {
char name[256];
GtkWidget *container;
GtkWidget *page_button;
GtkWidget *page_label;
GtkWidget *button_icon, *button_text, *button_tooltip;
GtkWidget *button_left_command, *button_right_command;
GtkWidget *button_mclick_command, *button_rclick_command, *button_uwheel_command, *button_dwheel_command;
GtkWidget *button_font, *button_font_set, *button_font_color, *button_padding_x, *button_padding_y, *button_centered;
GtkWidget *button_background, *button_max_icon_size;
} Button;
extern GArray *buttons;
// launcher // launcher
enum { enum {
@@ -264,6 +279,11 @@ Executor *execp_get_last();
void execp_remove(int i); void execp_remove(int i);
void execp_update_indices(); void execp_update_indices();
void button_create_new();
Button *button_get_last();
void button_remove(int i);
void button_update_indices();
void create_please_wait(GtkWindow *parent); void create_please_wait(GtkWindow *parent);
void process_events(); void process_events();
void destroy_please_wait(); void destroy_please_wait();

View File

@@ -866,6 +866,53 @@ void config_write_execp(FILE *fp)
} }
} }
void config_write_button(FILE *fp)
{
for (int i = 0; i < buttons->len; i++) {
fprintf(fp, "#-------------------------------------\n");
fprintf(fp, "# Button %d\n", i + 1);
Button *button = &g_array_index(buttons, Button, i);
fprintf(fp, "button = new\n");
if (strlen(gtk_entry_get_text(GTK_ENTRY(button->button_icon))))
fprintf(fp, "button_icon = %s\n", gtk_entry_get_text(GTK_ENTRY(button->button_icon)));
if (gtk_entry_get_text(GTK_ENTRY(button->button_text)))
fprintf(fp, "button_text = %s\n", gtk_entry_get_text(GTK_ENTRY(button->button_text)));
if (strlen(gtk_entry_get_text(GTK_ENTRY(button->button_tooltip))))
fprintf(fp, "button_tooltip = %s\n", gtk_entry_get_text(GTK_ENTRY(button->button_tooltip)));
fprintf(fp, "button_lclick_command = %s\n", gtk_entry_get_text(GTK_ENTRY(button->button_left_command)));
fprintf(fp, "button_rclick_command = %s\n", gtk_entry_get_text(GTK_ENTRY(button->button_right_command)));
fprintf(fp, "button_mclick_command = %s\n", gtk_entry_get_text(GTK_ENTRY(button->button_mclick_command)));
fprintf(fp, "button_uwheel_command = %s\n", gtk_entry_get_text(GTK_ENTRY(button->button_uwheel_command)));
fprintf(fp, "button_dwheel_command = %s\n", gtk_entry_get_text(GTK_ENTRY(button->button_dwheel_command)));
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button->button_font_set)))
fprintf(fp, "button_font = %s\n", gtk_font_button_get_font_name(GTK_FONT_BUTTON(button->button_font)));
GdkColor color;
gtk_color_button_get_color(GTK_COLOR_BUTTON(button->button_font_color), &color);
config_write_color(fp,
"button_font_color",
color,
gtk_color_button_get_alpha(GTK_COLOR_BUTTON(button->button_font_color)) * 100 / 0xffff);
fprintf(fp,
"button_padding = %d %d\n",
(int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(button->button_padding_x)),
(int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(button->button_padding_y)));
fprintf(fp, "button_background_id = %d\n", gtk_combo_box_get_active(GTK_COMBO_BOX(button->button_background)));
fprintf(fp,
"button_centered = %d\n",
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button->button_centered)) ? 1 : 0);
fprintf(fp,
"button_max_icon_size = %d\n",
(int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(button->button_max_icon_size)));
fprintf(fp, "\n");
}
}
void config_write_tooltip(FILE *fp) void config_write_tooltip(FILE *fp)
{ {
fprintf(fp, "#-------------------------------------\n"); fprintf(fp, "#-------------------------------------\n");
@@ -939,6 +986,7 @@ void config_save_file(const char *path)
config_write_battery(fp); config_write_battery(fp);
config_write_separator(fp); config_write_separator(fp);
config_write_execp(fp); config_write_execp(fp);
config_write_button(fp);
config_write_tooltip(fp); config_write_tooltip(fp);
checksum = checksum_txt(fp); checksum = checksum_txt(fp);
@@ -1888,6 +1936,51 @@ void add_entry(char *key, char *value)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(execp_get_last()->execp_centered), atoi(value)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(execp_get_last()->execp_centered), atoi(value));
} }
/* Button */
else if (strcmp(key, "button") == 0) {
button_create_new();
} else if (strcmp(key, "button_icon") == 0) {
gtk_entry_set_text(GTK_ENTRY(button_get_last()->button_icon), value);
} else if (strcmp(key, "button_text") == 0) {
gtk_entry_set_text(GTK_ENTRY(button_get_last()->button_text), value);
} else if (strcmp(key, "button_tooltip") == 0) {
gtk_entry_set_text(GTK_ENTRY(button_get_last()->button_tooltip), value);
} else if (strcmp(key, "button_lclick_command") == 0) {
gtk_entry_set_text(GTK_ENTRY(button_get_last()->button_left_command), value);
} else if (strcmp(key, "button_rclick_command") == 0) {
gtk_entry_set_text(GTK_ENTRY(button_get_last()->button_right_command), value);
} else if (strcmp(key, "button_mclick_command") == 0) {
gtk_entry_set_text(GTK_ENTRY(button_get_last()->button_mclick_command), value);
} else if (strcmp(key, "button_uwheel_command") == 0) {
gtk_entry_set_text(GTK_ENTRY(button_get_last()->button_uwheel_command), value);
} else if (strcmp(key, "button_dwheel_command") == 0) {
gtk_entry_set_text(GTK_ENTRY(button_get_last()->button_dwheel_command), value);
} else if (strcmp(key, "button_font") == 0) {
gtk_font_button_set_font_name(GTK_FONT_BUTTON(button_get_last()->button_font), value);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_get_last()->button_font_set), TRUE);
} else if (strcmp(key, "button_font_color") == 0) {
extract_values(value, &value1, &value2, &value3);
GdkColor col;
hex2gdk(value1, &col);
gtk_color_button_set_color(GTK_COLOR_BUTTON(button_get_last()->button_font_color), &col);
if (value2) {
int alpha = atoi(value2);
gtk_color_button_set_alpha(GTK_COLOR_BUTTON(button_get_last()->button_font_color), (alpha * 65535) / 100);
}
} else if (strcmp(key, "button_padding") == 0) {
extract_values(value, &value1, &value2, &value3);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(button_get_last()->button_padding_x), atoi(value1));
if (value2)
gtk_spin_button_set_value(GTK_SPIN_BUTTON(button_get_last()->button_padding_y), atoi(value2));
} else if (strcmp(key, "button_background_id") == 0) {
int id = background_index_safe(atoi(value));
gtk_combo_box_set_active(GTK_COMBO_BOX(button_get_last()->button_background), id);
} else if (strcmp(key, "button_centered") == 0) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_get_last()->button_centered), atoi(value));
} else if (strcmp(key, "button_max_icon_size") == 0) {
gtk_spin_button_set_value(GTK_SPIN_BUTTON(button_get_last()->button_max_icon_size), atoi(value));
}
if (value1) if (value1)
free(value1); free(value1);
if (value2) if (value2)

View File

@@ -153,7 +153,7 @@ void theme_list_append(const gchar *path)
g_free(suffix); g_free(suffix);
} }
gboolean update_snapshot() gboolean update_snapshot(gpointer ignored)
{ {
{ {
gchar *tint2_cache_dir = g_build_filename(g_get_user_cache_dir(), "tint2", NULL); gchar *tint2_cache_dir = g_build_filename(g_get_user_cache_dir(), "tint2", NULL);

View File

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

View File

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