Compare commits
19 Commits
thumb-xren
...
v16.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78313502d3 | ||
|
|
3eae1ba912 | ||
|
|
22ce7c5427 | ||
|
|
784edaccd2 | ||
|
|
b9c313cd18 | ||
|
|
10723b1db5 | ||
|
|
89c02d3912 | ||
|
|
da75999832 | ||
|
|
bff1a337f3 | ||
|
|
2f372364f0 | ||
|
|
a83e057414 | ||
|
|
7f070b4f45 | ||
|
|
a859727ff3 | ||
|
|
6c36f79aae | ||
|
|
d682756012 | ||
|
|
b6c19da36c | ||
|
|
372b51a4fa | ||
|
|
86dcaa7a83 | ||
|
|
2b0f6a9869 |
1
AUTHORS
1
AUTHORS
@@ -34,6 +34,7 @@ Contributors:
|
||||
aaaz (https://gitlab.com/aaaz) : clock fixes
|
||||
heisenbug (https://gitlab.com/heisenbugh) : taskbar button tinting with icon color
|
||||
Fabian Carlström : taskbar sort order by app name
|
||||
Chris Billington (https://gitlab.com/chrisjbillington) : panel struts pivoting
|
||||
|
||||
Translations:
|
||||
Bosnian:
|
||||
|
||||
16
ChangeLog
16
ChangeLog
@@ -1,8 +1,13 @@
|
||||
2019-02-17 master
|
||||
- Fix spacing around icons in executor without text in vertical panels (issue #716)
|
||||
- Fix Bug: Clock Only Updates Every Minute With Format %s (issue #724)
|
||||
- Fix markup drawing when font shadow enabled (issue #709)
|
||||
- Blink battery when low (issue #723)
|
||||
2019-07-14 16.7
|
||||
- Fixes:
|
||||
- Fix spacing around icons in executor without text in vertical panels (issue #716)
|
||||
- Fix Bug: Clock Only Updates Every Minute With Format %s (issue #724)
|
||||
- Fix markup drawing when font shadow enabled (issue #709)
|
||||
- Struts pivoting: workaround for panel positioning between monitors in mutter (Chris Billington)
|
||||
- Enhancements:
|
||||
- Blink battery when discharging and low (issue #723)
|
||||
- Add support for battery percentage without % sign (issue #730)
|
||||
- Expand leading ~ in icon paths
|
||||
|
||||
2018-08-05 16.6.1
|
||||
- Fix packaging regression for debian (issue #715)
|
||||
@@ -1025,3 +1030,4 @@ released tint-0.2
|
||||
.
|
||||
.
|
||||
.
|
||||
.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Latest stable release: 16.6.1
|
||||
Changes: https://gitlab.com/o9000/tint2/blob/16.6.1/ChangeLog
|
||||
# Latest stable release: 16.7
|
||||
Changes: https://gitlab.com/o9000/tint2/blob/16.7/ChangeLog
|
||||
|
||||
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
|
||||
cd tint2
|
||||
git checkout 16.6.1
|
||||
git checkout 16.7
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
@@ -97,3 +97,4 @@ tint2 is a simple panel/taskbar made for modern X window managers. It was specif
|
||||
## More
|
||||
|
||||
* [Tint2 wiki](https://gitlab.com/o9000/tint2/wikis/Home)
|
||||
Home)
|
||||
|
||||
@@ -273,7 +273,7 @@ Try to respect as much as possible the order of the options as given below.</p><
|
||||
<li><p><code>border_content_tint_weight = integer</code> : Mixes the border color with the content color (for tasks, this is the average color of the window icon). Values must be between 0 (no mixing) and 100 (fully replaces the color). <em>(since 16.0)</em></p></li>
|
||||
<li><p><code>background_content_tint_weight = integer</code> : Mixes the background color with the content color (for tasks, this is the average color of the window icon). Values must be between 0 (no mixing) and 100 (fully replaces the color). <em>(since 16.0)</em></p></li>
|
||||
</ul>
|
||||
<p>You can define as many backgrounds as you want. For example, the following config defines two backgrounds:</p><pre class="highlight plaintext"><code>rounded = 1
|
||||
<p>You can define as many backgrounds as you want. For example, the following config defines two backgrounds:</p><div class="highlight"><pre class="highlight plaintext"><code>rounded = 1
|
||||
border_width = 0
|
||||
background_color = #282828 100
|
||||
border_color = #000000 0
|
||||
@@ -282,16 +282,14 @@ rounded = 1
|
||||
border_width = 0
|
||||
background_color = #f6b655 90
|
||||
border_color = #cccccc 40
|
||||
</code></pre>
|
||||
<p>tint2 automatically identifies each background with a number starting from 1 (1, 2, ...).
|
||||
Afterwards, you can apply a background to objects (panel, taskbar, task, clock, systray) using the background id, for example:</p><pre class="highlight plaintext"><code>panel_background_id = 1
|
||||
</code></pre></div><p>tint2 automatically identifies each background with a number starting from 1 (1, 2, ...).
|
||||
Afterwards, you can apply a background to objects (panel, taskbar, task, clock, systray) using the background id, for example:</p><div class="highlight"><pre class="highlight plaintext"><code>panel_background_id = 1
|
||||
taskbar_background_id = 0
|
||||
task_background_id = 0
|
||||
task_active_background_id = 2
|
||||
systray_background_id = 0
|
||||
clock_background_id = 0
|
||||
</code></pre>
|
||||
<p>Identifier 0 refers to a special background which is fully transparent, identifier 1 applies the first background defined in the config file etc.</p><h3 id="gradients">Gradients<a name="gradients" href="#gradients" class="md2man-permalink" title="permalink"></a></h3><p>(Available since 0.13.0)</p><p>Backgrounds also allow specifying gradient layers
|
||||
</code></pre></div><p>Identifier 0 refers to a special background which is fully transparent, identifier 1 applies the first background defined in the config file etc.</p><h3 id="gradients">Gradients<a name="gradients" href="#gradients" class="md2man-permalink" title="permalink"></a></h3><p>(Available since 0.13.0)</p><p>Backgrounds also allow specifying gradient layers
|
||||
that are drawn on top of the solid color background.</p><p>First the user must define one or more gradients in the config file,
|
||||
each starting with <code>gradient = TYPE</code>. These must be added before backgrounds.</p><p>Then gradients can be added by index to backgrounds,
|
||||
using the <code>gradient_id = INDEX</code>, <code>gradient_id_hover = INDEX</code> and
|
||||
@@ -300,21 +298,17 @@ the gradient index, starting from 1.</p><h4 id="gradient-types">Gradient types<a
|
||||
* vertical gradients: top-to-bottom;
|
||||
* horizontal gradients: left-to-right;
|
||||
* radial gradients: center-to-corners.</p><p>The user must specify the start and end colors, and can optionally add extra color stops in between
|
||||
using the <code>color_stop</code> option, as explained below.</p><h5 id="vertical-gradient-with-color-varying-from-the-top-edge-to-the-bottom-edge-two-colors">Vertical gradient, with color varying from the top edge to the bottom edge, two colors<a name="vertical-gradient-with-color-varying-from-the-top-edge-to-the-bottom-edge-two-colors" href="#vertical-gradient-with-color-varying-from-the-top-edge-to-the-bottom-edge-two-colors" class="md2man-permalink" title="permalink"></a></h5><pre class="highlight plaintext"><code>gradient = vertical
|
||||
using the <code>color_stop</code> option, as explained below.</p><h5 id="vertical-gradient-with-color-varying-from-the-top-edge-to-the-bottom-edge-two-colors">Vertical gradient, with color varying from the top edge to the bottom edge, two colors<a name="vertical-gradient-with-color-varying-from-the-top-edge-to-the-bottom-edge-two-colors" href="#vertical-gradient-with-color-varying-from-the-top-edge-to-the-bottom-edge-two-colors" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code>gradient = vertical
|
||||
start_color = #rrggbb opacity
|
||||
end_color = #rrggbb opacity
|
||||
</code></pre>
|
||||
<h5 id="horizontal-gradient-with-color-varying-from-the-left-edge-to-the-right-edge-two-colors">Horizontal gradient, with color varying from the left edge to the right edge, two colors<a name="horizontal-gradient-with-color-varying-from-the-left-edge-to-the-right-edge-two-colors" href="#horizontal-gradient-with-color-varying-from-the-left-edge-to-the-right-edge-two-colors" class="md2man-permalink" title="permalink"></a></h5><pre class="highlight plaintext"><code>gradient = horizontal
|
||||
</code></pre></div><h5 id="horizontal-gradient-with-color-varying-from-the-left-edge-to-the-right-edge-two-colors">Horizontal gradient, with color varying from the left edge to the right edge, two colors<a name="horizontal-gradient-with-color-varying-from-the-left-edge-to-the-right-edge-two-colors" href="#horizontal-gradient-with-color-varying-from-the-left-edge-to-the-right-edge-two-colors" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code>gradient = horizontal
|
||||
start_color = #rrggbb opacity
|
||||
end_color = #rrggbb opacity
|
||||
</code></pre>
|
||||
<h5 id="radial-gradient-with-color-varying-from-the-center-to-the-corner-two-colors">Radial gradient, with color varying from the center to the corner, two colors:<a name="radial-gradient-with-color-varying-from-the-center-to-the-corner-two-colors" href="#radial-gradient-with-color-varying-from-the-center-to-the-corner-two-colors" class="md2man-permalink" title="permalink"></a></h5><pre class="highlight plaintext"><code>gradient = radial
|
||||
</code></pre></div><h5 id="radial-gradient-with-color-varying-from-the-center-to-the-corner-two-colors">Radial gradient, with color varying from the center to the corner, two colors:<a name="radial-gradient-with-color-varying-from-the-center-to-the-corner-two-colors" href="#radial-gradient-with-color-varying-from-the-center-to-the-corner-two-colors" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code>gradient = radial
|
||||
start_color = #rrggbb opacity
|
||||
end_color = #rrggbb opacity
|
||||
</code></pre>
|
||||
<h5 id="adding-extra-color-stops-0-and-100-remain-fixed-more-colors-at-x-between-the-start-and-end-control-points">Adding extra color stops (0% and 100% remain fixed, more colors at x% between the start and end control points)<a name="adding-extra-color-stops-0-and-100-remain-fixed-more-colors-at-x-between-the-start-and-end-control-points" href="#adding-extra-color-stops-0-and-100-remain-fixed-more-colors-at-x-between-the-start-and-end-control-points" class="md2man-permalink" title="permalink"></a></h5><pre class="highlight plaintext"><code>color_stop = percentage #rrggbb opacity
|
||||
</code></pre>
|
||||
<h4 id="gradient-examples">Gradient examples<a name="gradient-examples" href="#gradient-examples" class="md2man-permalink" title="permalink"></a></h4><pre class="highlight plaintext"><code># Gradient 1: thin film effect
|
||||
</code></pre></div><h5 id="adding-extra-color-stops-0-and-100-remain-fixed-more-colors-at-x-between-the-start-and-end-control-points">Adding extra color stops (0% and 100% remain fixed, more colors at x% between the start and end control points)<a name="adding-extra-color-stops-0-and-100-remain-fixed-more-colors-at-x-between-the-start-and-end-control-points" href="#adding-extra-color-stops-0-and-100-remain-fixed-more-colors-at-x-between-the-start-and-end-control-points" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code>color_stop = percentage #rrggbb opacity
|
||||
</code></pre></div><h4 id="gradient-examples">Gradient examples<a name="gradient-examples" href="#gradient-examples" class="md2man-permalink" title="permalink"></a></h4><div class="highlight"><pre class="highlight plaintext"><code># Gradient 1: thin film effect
|
||||
gradient = horizontal
|
||||
start_color = #111122 30
|
||||
end_color = #112211 30
|
||||
@@ -350,8 +344,7 @@ gradient_id_hover = 4
|
||||
gradient_id_pressed = 2
|
||||
|
||||
[...]
|
||||
</code></pre>
|
||||
<h3 id="panel">Panel<a name="panel" href="#panel" class="md2man-permalink" title="permalink"></a></h3>
|
||||
</code></pre></div><h3 id="panel">Panel<a name="panel" href="#panel" class="md2man-permalink" title="permalink"></a></h3>
|
||||
<ul>
|
||||
<li><p><code>panel_items = LTSBC</code> defines the items tint2 will show and the order of those items. Each letter refers to an item, defined as:</p>
|
||||
<ul>
|
||||
@@ -389,10 +382,9 @@ Example:</li>
|
||||
<li><p><code>scale_relative_to_dpi = integer</code> : If set to a non-zero value, HiDPI scaling is enabled. Each panel is visible on a different monitor. Thus each panel has a specific scaling factor. The scaling factor is computed as the ratio between the monitor DPI (obtained from the dimensions in pixels and millimeters from RandR) and a configured reference DPI - this is the DPI for which exising user configs looked normal, for backward compatibility.</p></li>
|
||||
<li><p><code>scale_relative_to_screen_height = integer</code> : Similar to <code>scale_relative_to_dpi</code>, except the scaling factor is computed as the ratio between the monitor height and <code>scale_relative_to_screen_height</code>. The effect is cumulative with <code>scale_relative_to_dpi</code>, i.e. if both options are present, the factors are multiplied.</p></li>
|
||||
</ul>
|
||||
<pre class="highlight plaintext"><code># The panel's width is 94% the size of the monitor, the height is 30 pixels:
|
||||
<div class="highlight"><pre class="highlight plaintext"><code># The panel's width is 94% the size of the monitor, the height is 30 pixels:
|
||||
panel_size = 94% 30
|
||||
</code></pre>
|
||||
|
||||
</code></pre></div>
|
||||
<ul>
|
||||
<li><p><code>panel_shrink = boolean (0 or 1)</code> : If set to 1, the panel will shrink to a compact size dynamically. <em>(since 0.13)</em></p></li>
|
||||
<li><p><code>panel_margin = horizontal_margin vertical_margin</code> : The margins define the distance between the panel and the horizontal/vertical monitor edge. Use <code>0</code> to obtain a panel with the same size as the edge of the monitor (no margin).</p></li>
|
||||
@@ -407,8 +399,9 @@ panel_size = 94% 30
|
||||
<li><p><code>panel_background_id = integer</code> : Which background to use for the panel.</p></li>
|
||||
<li><p><code>wm_menu = boolean (0 or 1)</code> : Defines if tint2 forwards unhandled mouse events to your window manager. Useful for window managers such as openbox, which display the start menu if you right click on the desktop.</p></li>
|
||||
<li><p><code>panel_dock = boolean (0 or 1)</code> : Defines if tint2 is placed into the window manager's dock. For the openbox window manager it is advised to also use a modifier for the moveButton option, otherwise the mouse click is not forwarded to tint2 (in ~/.config/openbox/rc.xml).</p></li>
|
||||
<li><p><code>panel_pivot_struts = boolean (0 or 1)</code> : Defines if tint2 lies to the window manager about its orientation (horizontal vs vertical) when requesting reserved space with STRUTs (see <code>strut_policy</code> below). On some window managers, this allows placing a panel in the middle of the virtual screen, e.g. on the bottom edge of the top monitor in a vertical dual-monitor setup. </p></li>
|
||||
<li><p><code>panel_layer = bottom/normal/top</code> : Places tint2 into the bottom/normal/top layer. This is helpful for specifying if the panel can be covered by other windows or not. The default is the bottom layer, but with real transparency normal or top layer may be a nice alternative.</p></li>
|
||||
<li><p><code>strut_policy = follow_size/minimum/none</code> : STRUTs are used by the window manager to decide the size of maximized windows. Note: on multi-monitor (Xinerama) setups, the panel must be placed at the edge (not in the middle) of the virtual screen for this to work correctly.</p>
|
||||
<li><p><code>strut_policy = follow_size/minimum/none</code> : STRUTs are used by the window manager to decide the size of maximized windows. Note: on multi-monitor (Xinerama) setups, the panel generally must be placed at the edge (not in the middle) of the virtual screen for this to work correctly (though on some window managers, setting <code>panel_pivot_struts</code> may work around this limitation). </p>
|
||||
<ul>
|
||||
<li><code>follow_size</code> means that the maximized windows always resize to have a common edge with tint2.</li>
|
||||
<li><code>minimum</code> means that the maximized windows always expand to have a common edge with the hidden panel. This is useful if the <code>autohide</code> option is enabled.</li>
|
||||
@@ -585,6 +578,7 @@ panel_size = 94% 30
|
||||
<li>%h: Hours left until completely charged/discharged (estimated).</li>
|
||||
<li>%t: Time left. Shows "hrs:mins" when charging/discharging, or "Ful\" when full.</li>
|
||||
<li>%p: Percentage. Includes the % sign.</li>
|
||||
<li>%P: Percentage. Without the % sign.</li>
|
||||
</ul></li>
|
||||
<li><p><code>bat2_format = FORMAT_STRING</code> : Format for battery line 2. Default: %t. <em>(since 1.0)</em></p></li>
|
||||
<li><p><code>battery_padding = horizontal_padding vertical_padding</code></p></li>
|
||||
@@ -621,15 +615,13 @@ panel_size = 94% 30
|
||||
<li><p><code>execp_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.12.4)</em></p></li>
|
||||
<li><p><code>execp_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.12.4)</em></p></li>
|
||||
</ul>
|
||||
<h4 id="executor-samples">Executor samples<a name="executor-samples" href="#executor-samples" class="md2man-permalink" title="permalink"></a></h4><h5 id="print-the-hostname">Print the hostname<a name="print-the-hostname" href="#print-the-hostname" class="md2man-permalink" title="permalink"></a></h5><pre class="highlight plaintext"><code>execp = new
|
||||
<h4 id="executor-samples">Executor samples<a name="executor-samples" href="#executor-samples" class="md2man-permalink" title="permalink"></a></h4><h5 id="print-the-hostname">Print the hostname<a name="print-the-hostname" href="#print-the-hostname" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code>execp = new
|
||||
execp_command = hostname
|
||||
execp_interval = 0
|
||||
</code></pre>
|
||||
<h5 id="print-disk-usage-for-the-root-partition-every-10-seconds">Print disk usage for the root partition every 10 seconds<a name="print-disk-usage-for-the-root-partition-every-10-seconds" href="#print-disk-usage-for-the-root-partition-every-10-seconds" class="md2man-permalink" title="permalink"></a></h5><pre class="highlight plaintext"><code>execp = new
|
||||
</code></pre></div><h5 id="print-disk-usage-for-the-root-partition-every-10-seconds">Print disk usage for the root partition every 10 seconds<a name="print-disk-usage-for-the-root-partition-every-10-seconds" href="#print-disk-usage-for-the-root-partition-every-10-seconds" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code>execp = new
|
||||
execp_command = df -h | awk '/\/$/ { print $6 ": " $2 " " $5}'
|
||||
execp_interval = 10
|
||||
</code></pre>
|
||||
<h5 id="button-with-icon-and-rich-text-executes-command-when-clicked">Button with icon and rich text, executes command when clicked<a name="button-with-icon-and-rich-text-executes-command-when-clicked" href="#button-with-icon-and-rich-text-executes-command-when-clicked" class="md2man-permalink" title="permalink"></a></h5><pre class="highlight plaintext"><code>execp = new
|
||||
</code></pre></div><h5 id="button-with-icon-and-rich-text-executes-command-when-clicked">Button with icon and rich text, executes command when clicked<a name="button-with-icon-and-rich-text-executes-command-when-clicked" href="#button-with-icon-and-rich-text-executes-command-when-clicked" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code>execp = new
|
||||
execp_command = echo /usr/share/icons/elementary-xfce/emblems/24/emblem-colors-blue.png; echo '<span foreground="#7f7">Click</span> <span foreground="#77f">me</span> <span foreground="#f77">pls</span>'
|
||||
execp_has_icon = 1
|
||||
execp_interval = 0
|
||||
@@ -641,36 +633,30 @@ execp_padding = 2 0
|
||||
execp_tooltip = I will tell you a secret...
|
||||
execp_lclick_command = zenity --info "--text=$(uname -sr)"
|
||||
execp_background_id = 2
|
||||
</code></pre>
|
||||
<h5 id="desktop-pager-with-text">Desktop pager with text<a name="desktop-pager-with-text" href="#desktop-pager-with-text" class="md2man-permalink" title="permalink"></a></h5><pre class="highlight plaintext"><code>execp = new
|
||||
</code></pre></div><h5 id="desktop-pager-with-text">Desktop pager with text<a name="desktop-pager-with-text" href="#desktop-pager-with-text" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code>execp = new
|
||||
execp_command = xprop -root -spy | awk '/^_NET_CURRENT_DESKTOP/ { print "Workspace " ($3 + 1) ; fflush(); }'
|
||||
execp_interval = 1
|
||||
execp_continuous = 1
|
||||
</code></pre>
|
||||
<h5 id="desktop-pager-with-icon">Desktop pager with icon<a name="desktop-pager-with-icon" href="#desktop-pager-with-icon" class="md2man-permalink" title="permalink"></a></h5><pre class="highlight plaintext"><code>execp_command = xprop -root -spy | awk -v home="$HOME" '/^_NET_CURRENT_DESKTOP/ { print home "/.config/myPager/" ($3 + 1) ".png\n" ; fflush(); }'
|
||||
</code></pre></div><h5 id="desktop-pager-with-icon">Desktop pager with icon<a name="desktop-pager-with-icon" href="#desktop-pager-with-icon" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code>execp_command = xprop -root -spy | awk -v home="$HOME" '/^_NET_CURRENT_DESKTOP/ { print home "/.config/myPager/" ($3 + 1) ".png\n" ; fflush(); }'
|
||||
execp_interval = 1
|
||||
execp_has_icon = 1
|
||||
execp_cache_icon = 1
|
||||
execp_continuous = 2
|
||||
</code></pre>
|
||||
<h5 id="round-trip-time-to-the-gateway-refreshed-every-second">Round-trip time to the gateway, refreshed every second<a name="round-trip-time-to-the-gateway-refreshed-every-second" href="#round-trip-time-to-the-gateway-refreshed-every-second" class="md2man-permalink" title="permalink"></a></h5><pre class="highlight plaintext"><code>execp = new
|
||||
</code></pre></div><h5 id="round-trip-time-to-the-gateway-refreshed-every-second">Round-trip time to the gateway, refreshed every second<a name="round-trip-time-to-the-gateway-refreshed-every-second" href="#round-trip-time-to-the-gateway-refreshed-every-second" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code>execp = new
|
||||
execp_command = ping -i 1 -c 1 -W 1 -O -D -n $(ip route | grep default | grep via | grep -o '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*') | awk '/no/ { print "<span foreground=\"#faa\">timeout</span>"; fflush(); }; /time=/ { gsub(/time=/, "", $8); printf "<span foreground=\"#7af\">%3.0f %s</span>\n", $8, $9; fflush(); } '
|
||||
execp_continuous = 0
|
||||
execp_interval = 1
|
||||
execp_markup = 1
|
||||
</code></pre>
|
||||
<h5 id="memory-usage">Memory usage<a name="memory-usage" href="#memory-usage" class="md2man-permalink" title="permalink"></a></h5><pre class="highlight plaintext"><code>execp = new
|
||||
</code></pre></div><h5 id="memory-usage">Memory usage<a name="memory-usage" href="#memory-usage" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code>execp = new
|
||||
execp_command = free | awk '/^-/ { printf "Mem: '$(free -h | awk '/^Mem:/ { print $2 }')' %.0f%%\n", 100*$3/($3+$4); fflush(stdout) }'
|
||||
execp_interval = 5
|
||||
execp_continuous = 0
|
||||
</code></pre>
|
||||
<h5 id="network-load">Network load<a name="network-load" href="#network-load" class="md2man-permalink" title="permalink"></a></h5><pre class="highlight plaintext"><code># Note the use of "stdbuf -oL" to force the program to flush the output line by line.
|
||||
</code></pre></div><h5 id="network-load">Network load<a name="network-load" href="#network-load" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code># Note the use of "stdbuf -oL" to force the program to flush the output line by line.
|
||||
execp = new
|
||||
execp_command = stdbuf -oL bwm-ng -o csv -t 1000 | awk -F ';' '/total/ { printf "Net: %.0f Mb/s\n", ($5*8/1.0e6) }; fflush(stdout)'
|
||||
execp_continuous = 1
|
||||
execp_interval = 1
|
||||
</code></pre>
|
||||
<h3 id="button">Button<a name="button" href="#button" class="md2man-permalink" title="permalink"></a></h3>
|
||||
</code></pre></div><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>
|
||||
@@ -702,6 +688,7 @@ It is based on ttm, originally written by Pål Staurland <a href="mailto:staura@
|
||||
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's default location
|
||||
for documentation files, usually <code>/usr/share/doc/tint2</code> or <code>/usr/local/share/doc/tint2</code>.
|
||||
.
|
||||
.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -199,19 +199,17 @@ pre {
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="latest-stable-release-16-6-1"><span class="md2man-title">Latest</span> <span class="md2man-section">stable</span> <span class="md2man-date">release:</span> <span class="md2man-source">16.6.1</span><a name="latest-stable-release-16-6-1" href="#latest-stable-release-16-6-1" class="md2man-permalink" title="permalink"></a></h1><p>Changes: <a href="https://gitlab.com/o9000/tint2/blob/16.6.1/ChangeLog">https://gitlab.com/o9000/tint2/blob/16.6.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
|
||||
<h1 id="latest-stable-release-16-7"><span class="md2man-title">Latest</span> <span class="md2man-section">stable</span> <span class="md2man-date">release:</span> <span class="md2man-source">16.7</span><a name="latest-stable-release-16-7" href="#latest-stable-release-16-7" class="md2man-permalink" title="permalink"></a></h1><p>Changes: <a href="https://gitlab.com/o9000/tint2/blob/16.7/ChangeLog">https://gitlab.com/o9000/tint2/blob/16.7/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><div class="highlight"><pre class="highlight plaintext"><code>git clone https://gitlab.com/o9000/tint2.git
|
||||
cd tint2
|
||||
git checkout 16.6.1
|
||||
git checkout 16.7
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make -j4
|
||||
</code></pre>
|
||||
<p>To install, run (as root):</p><pre class="highlight plaintext"><code>make install
|
||||
</code></pre></div><p>To install, run (as root):</p><div class="highlight"><pre class="highlight plaintext"><code>make install
|
||||
update-icon-caches /usr/local/share/icons/hicolor
|
||||
update-mime-database /usr/local/share/mime
|
||||
</code></pre>
|
||||
<p>And then you can run the panel <code>tint2</code> and the configuration program <code>tint2conf</code>.</p><p>Please report any problems to <a href="https://gitlab.com/o9000/tint2/issues">https://gitlab.com/o9000/tint2/issues</a>. Your feedback is much appreciated.</p><p>P.S. GitLab is now the official location of the tint2 project, migrated from Google Code, which is shutting down. In case you are wondering why not GitHub, BitBucket etc., we chose GitLab because it is open source, it is mature and works well, looks cool and has a very nice team.</p><h1 id="what-is-tint2">What is tint2?<a name="what-is-tint2" href="#what-is-tint2" class="md2man-permalink" title="permalink"></a></h1><p>tint2 is a simple panel/taskbar made for modern X window managers. It was specifically made for Openbox but it should also work with other window managers (GNOME, KDE, XFCE etc.). It is based on ttm <a href="https://code.google.com/p/ttm/">https://code.google.com/p/ttm/</a>.</p><h1 id="features">Features<a name="features" href="#features" class="md2man-permalink" title="permalink"></a></h1>
|
||||
</code></pre></div><p>And then you can run the panel <code>tint2</code> and the configuration program <code>tint2conf</code>.</p><p>Please report any problems to <a href="https://gitlab.com/o9000/tint2/issues">https://gitlab.com/o9000/tint2/issues</a>. Your feedback is much appreciated.</p><p>P.S. GitLab is now the official location of the tint2 project, migrated from Google Code, which is shutting down. In case you are wondering why not GitHub, BitBucket etc., we chose GitLab because it is open source, it is mature and works well, looks cool and has a very nice team.</p><h1 id="what-is-tint2">What is tint2?<a name="what-is-tint2" href="#what-is-tint2" class="md2man-permalink" title="permalink"></a></h1><p>tint2 is a simple panel/taskbar made for modern X window managers. It was specifically made for Openbox but it should also work with other window managers (GNOME, KDE, XFCE etc.). It is based on ttm <a href="https://code.google.com/p/ttm/">https://code.google.com/p/ttm/</a>.</p><h1 id="features">Features<a name="features" href="#features" class="md2man-permalink" title="permalink"></a></h1>
|
||||
<ul>
|
||||
<li>Panel with taskbar, system tray, clock and launcher icons;</li>
|
||||
<li>Easy to customize: color/transparency on fonts, icons, borders and backgrounds;</li>
|
||||
@@ -269,7 +267,8 @@ update-mime-database /usr/local/share/mime
|
||||
</ul>
|
||||
<h2 id="more">More<a name="more" href="#more" class="md2man-permalink" title="permalink"></a></h2>
|
||||
<ul>
|
||||
<li><a href="https://gitlab.com/o9000/tint2/wikis/Home">Tint2 wiki</a></li>
|
||||
<li><a href="https://gitlab.com/o9000/tint2/wikis/Home">Tint2 wiki</a>
|
||||
Home)</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH TINT2 1 "2018\-08\-05" 16.6.1
|
||||
.TH TINT2 1 "2019\-07\-14" 16.7
|
||||
.SH NAME
|
||||
.PP
|
||||
tint2 \- lightweight panel/taskbar
|
||||
@@ -379,9 +379,11 @@ panel_size = 94% 30
|
||||
.IP \(bu 2
|
||||
\fB\fCpanel_dock = boolean (0 or 1)\fR : Defines if tint2 is placed into the window manager's dock. For the openbox window manager it is advised to also use a modifier for the moveButton option, otherwise the mouse click is not forwarded to tint2 (in ~/.config/openbox/rc.xml).
|
||||
.IP \(bu 2
|
||||
\fB\fCpanel_pivot_struts = boolean (0 or 1)\fR : Defines if tint2 lies to the window manager about its orientation (horizontal vs vertical) when requesting reserved space with STRUTs (see \fB\fCstrut_policy\fR below). On some window managers, this allows placing a panel in the middle of the virtual screen, e.g. on the bottom edge of the top monitor in a vertical dual\-monitor setup.
|
||||
.IP \(bu 2
|
||||
\fB\fCpanel_layer = bottom/normal/top\fR : Places tint2 into the bottom/normal/top layer. This is helpful for specifying if the panel can be covered by other windows or not. The default is the bottom layer, but with real transparency normal or top layer may be a nice alternative.
|
||||
.IP \(bu 2
|
||||
\fB\fCstrut_policy = follow_size/minimum/none\fR : STRUTs are used by the window manager to decide the size of maximized windows. Note: on multi\-monitor (Xinerama) setups, the panel must be placed at the edge (not in the middle) of the virtual screen for this to work correctly.
|
||||
\fB\fCstrut_policy = follow_size/minimum/none\fR : STRUTs are used by the window manager to decide the size of maximized windows. Note: on multi\-monitor (Xinerama) setups, the panel generally must be placed at the edge (not in the middle) of the virtual screen for this to work correctly (though on some window managers, setting \fB\fCpanel_pivot_struts\fR may work around this limitation).
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
\fB\fCfollow_size\fR means that the maximized windows always resize to have a common edge with tint2.
|
||||
@@ -687,6 +689,8 @@ To hide the clock, comment \fB\fCtime1_format\fR and \fB\fCtime2_format\fR\&.
|
||||
%t: Time left. Shows "hrs:mins" when charging/discharging, or "Ful\[rs]" when full.
|
||||
.IP \(bu 2
|
||||
%p: Percentage. Includes the % sign.
|
||||
.IP \(bu 2
|
||||
%P: Percentage. Without the % sign.
|
||||
.RE
|
||||
.IP \(bu 2
|
||||
\fB\fCbat2_format = FORMAT_STRING\fR : Format for battery line 2. Default: %t. \fI(since 1.0)\fP
|
||||
@@ -910,3 +914,4 @@ and the wiki page at \[la]https://gitlab.com/o9000/tint2/wikis/home\[ra]\&.
|
||||
This documentation is also provided in HTML and Markdown format in the system's default location
|
||||
for documentation files, usually \fB\fC/usr/share/doc/tint2\fR or \fB\fC/usr/local/share/doc/tint2\fR\&.
|
||||
\&.
|
||||
\&.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# TINT2 1 "2018-08-05" 16.6.1
|
||||
# TINT2 1 "2019-07-14" 16.7
|
||||
|
||||
## NAME
|
||||
tint2 - lightweight panel/taskbar
|
||||
@@ -306,9 +306,11 @@ panel_size = 94% 30
|
||||
|
||||
* `panel_dock = boolean (0 or 1)` : Defines if tint2 is placed into the window manager's dock. For the openbox window manager it is advised to also use a modifier for the moveButton option, otherwise the mouse click is not forwarded to tint2 (in ~/.config/openbox/rc.xml).
|
||||
|
||||
* `panel_pivot_struts = boolean (0 or 1)` : Defines if tint2 lies to the window manager about its orientation (horizontal vs vertical) when requesting reserved space with STRUTs (see `strut_policy` below). On some window managers, this allows placing a panel in the middle of the virtual screen, e.g. on the bottom edge of the top monitor in a vertical dual-monitor setup.
|
||||
|
||||
* `panel_layer = bottom/normal/top` : Places tint2 into the bottom/normal/top layer. This is helpful for specifying if the panel can be covered by other windows or not. The default is the bottom layer, but with real transparency normal or top layer may be a nice alternative.
|
||||
|
||||
* `strut_policy = follow_size/minimum/none` : STRUTs are used by the window manager to decide the size of maximized windows. Note: on multi-monitor (Xinerama) setups, the panel must be placed at the edge (not in the middle) of the virtual screen for this to work correctly.
|
||||
* `strut_policy = follow_size/minimum/none` : STRUTs are used by the window manager to decide the size of maximized windows. Note: on multi-monitor (Xinerama) setups, the panel generally must be placed at the edge (not in the middle) of the virtual screen for this to work correctly (though on some window managers, setting `panel_pivot_struts` may work around this limitation).
|
||||
* `follow_size` means that the maximized windows always resize to have a common edge with tint2.
|
||||
* `minimum` means that the maximized windows always expand to have a common edge with the hidden panel. This is useful if the `autohide` option is enabled.
|
||||
* `none` means that the maximized windows use the full screen size.
|
||||
@@ -563,6 +565,7 @@ The action semantics:
|
||||
* %h: Hours left until completely charged/discharged (estimated).
|
||||
* %t: Time left. Shows "hrs:mins" when charging/discharging, or "Ful\" when full.
|
||||
* %p: Percentage. Includes the % sign.
|
||||
* %P: Percentage. Without the % sign.
|
||||
|
||||
* `bat2_format = FORMAT_STRING` : Format for battery line 2. Default: %t. *(since 1.0)*
|
||||
|
||||
@@ -766,3 +769,4 @@ and the wiki page at https://gitlab.com/o9000/tint2/wikis/home.
|
||||
This documentation is also provided in HTML and Markdown format in the system's default location
|
||||
for documentation files, usually `/usr/share/doc/tint2` or `/usr/local/share/doc/tint2`.
|
||||
.
|
||||
.
|
||||
|
||||
@@ -55,13 +55,14 @@ def cmd(s):
|
||||
|
||||
|
||||
def run(s):
|
||||
proc = subprocess.Popen(cmd(s), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
|
||||
proc = subprocess.Popen(cmd(s), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
|
||||
ret = proc.wait()
|
||||
out = proc.communicate()[0]
|
||||
out, err = proc.communicate()
|
||||
for line in out.split("\n"):
|
||||
debug(ansi_pinky + line + ansi_reset)
|
||||
debug(ansi_pinky + "Exit code: " + str(ret))
|
||||
if ret != 0:
|
||||
print(err)
|
||||
raise Exception("Command failed!")
|
||||
return out
|
||||
|
||||
|
||||
79
packaging/compile-deps.sh
Executable file
79
packaging/compile-deps.sh
Executable file
@@ -0,0 +1,79 @@
|
||||
#!/bin/bash
|
||||
|
||||
PS4='\e[99;33m${BASH_SOURCE}:$LINENO\e[0m '
|
||||
set -e
|
||||
set -x
|
||||
|
||||
sudo apt-get install ninja-build python2.7 wget
|
||||
sudo apt-get build-dep libx11-6 libxrender1 libcairo2 libglib2.0-0 libpango-1.0-0 libimlib2 librsvg2-2
|
||||
|
||||
export PKG_CONFIG_PATH=""
|
||||
|
||||
DEPS=$HOME/tint2-deps
|
||||
X11=$(pkg-config --modversion x11)
|
||||
XRENDER=$(pkg-config --modversion xrender)
|
||||
XCOMPOSITE=$(pkg-config --modversion xcomposite)
|
||||
XDAMAGE=$(pkg-config --modversion xdamage)
|
||||
XEXT=$(pkg-config --modversion xext)
|
||||
XRANDR=$(pkg-config --modversion xrandr)
|
||||
XINERAMA=$(pkg-config --modversion xinerama)
|
||||
IMLIB=$(pkg-config --modversion imlib2)
|
||||
GLIB=$(pkg-config --modversion glib-2.0)
|
||||
CAIRO=$(pkg-config --modversion cairo)
|
||||
PANGO=$(pkg-config --modversion pango)
|
||||
PIXBUF=$(pkg-config --modversion gdk-pixbuf-2.0)
|
||||
RSVG=$(pkg-config --modversion librsvg-2.0)
|
||||
|
||||
mkdir -p $DEPS/src
|
||||
|
||||
function two_digits() {
|
||||
echo "$@" | cut -d. -f 1-2
|
||||
}
|
||||
|
||||
function download_and_build() {
|
||||
URL="$1"
|
||||
shift
|
||||
CFGARGS="$@"
|
||||
ARCHIVE="$(basename "$URL")"
|
||||
NAME="$(echo "$ARCHIVE" | sed s/\.tar.*$//g)"
|
||||
|
||||
cd "$DEPS/src"
|
||||
rm -rf "$ARCHIVE"
|
||||
rm -rf "$NAME"
|
||||
wget "$URL" -O "$ARCHIVE"
|
||||
tar xf "$ARCHIVE"
|
||||
cd "$NAME"
|
||||
export PKG_CONFIG_PATH="$DEPS/lib/pkgconfig"
|
||||
export PATH="$DEPS/bin:$PATH"
|
||||
export CFLAGS="-O0 -fno-common -fno-omit-frame-pointer -rdynamic -fsanitize=address -g"
|
||||
export LDFLAGS="-Wl,--no-as-needed -Wl,-z,defs -O0 -fno-common -fno-omit-frame-pointer -rdynamic -fsanitize=address -fuse-ld=gold -g -ldl -lasan"
|
||||
if [[ -x ./configure ]]
|
||||
then
|
||||
./configure "--prefix=$DEPS" "$@"
|
||||
make -j
|
||||
make install
|
||||
elif [[ -f meson.build ]]
|
||||
then
|
||||
mkdir build
|
||||
cd build
|
||||
meson "--prefix=$DEPS" "$@" ..
|
||||
ninja install
|
||||
else
|
||||
echo "unknown build method"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
download_and_build "https://www.x.org/archive/individual/lib/libX11-$X11.tar.gz" --enable-static=no
|
||||
download_and_build "https://www.x.org/archive//individual/lib/libXrender-$XRENDER.tar.gz" --enable-static=no
|
||||
download_and_build "https://www.x.org/archive//individual/lib/libXcomposite-$XCOMPOSITE.tar.gz" --enable-static=no
|
||||
download_and_build "https://www.x.org/archive//individual/lib/libXdamage-$XDAMAGE.tar.gz" --enable-static=no
|
||||
download_and_build "https://www.x.org/archive//individual/lib/libXext-$XEXT.tar.gz" --enable-static=no
|
||||
download_and_build "https://www.x.org/archive//individual/lib/libXrandr-$XRANDR.tar.gz" --enable-static=no
|
||||
download_and_build "https://www.x.org/archive//individual/lib/libXinerama-$XINERAMA.tar.gz" --enable-static=no
|
||||
download_and_build "https://downloads.sourceforge.net/enlightenment/imlib2-$IMLIB.tar.bz2" --enable-static=no
|
||||
download_and_build "https://ftp.gnome.org/pub/gnome/sources/glib/$(two_digits "$GLIB")/glib-$GLIB.tar.xz" --enable-debug=yes
|
||||
download_and_build "https://ftp.gnome.org/pub/gnome/sources/gdk-pixbuf/$(two_digits "$PIXBUF")/gdk-pixbuf-$PIXBUF.tar.xz"
|
||||
download_and_build "https://cairographics.org/snapshots/cairo-$CAIRO.tar.xz"
|
||||
download_and_build "https://ftp.gnome.org/pub/gnome/sources/pango/$(two_digits "$PANGO")/pango-$PANGO.tar.xz"
|
||||
download_and_build "https://ftp.gnome.org/pub/gnome/sources/librsvg/$(two_digits "$RSVG")/librsvg-$RSVG.tar.xz" --enable-pixbuf-loader
|
||||
24
packaging/configure
vendored
24
packaging/configure
vendored
@@ -52,6 +52,7 @@ def pkg_config(lib):
|
||||
lf = _pkgconfig(lib, '--libs-only-l')
|
||||
cf = _pkgconfig(lib, '--cflags')
|
||||
ldf = _pkgconfig(lib, '--libs-only-L')
|
||||
print("Found", lib, "in:", ldf)
|
||||
return (lf, cf, ldf)
|
||||
|
||||
|
||||
@@ -110,6 +111,14 @@ def install_dir(prefix, suffix, dest_dir, dest_suffix=''):
|
||||
return result
|
||||
|
||||
|
||||
def remove_duplicates(ls):
|
||||
result = []
|
||||
for x in ls:
|
||||
if x not in result:
|
||||
result.append(x)
|
||||
return result
|
||||
|
||||
|
||||
class Executable(object):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
@@ -126,9 +135,9 @@ class Executable(object):
|
||||
f.write('# Executable: {}\n'.format(self.name))
|
||||
ninja_write_vars(f, **{
|
||||
'cc_' + self.name: self.cc,
|
||||
'cflags_' + self.name: ninja_join(self.cflags),
|
||||
'lflags_' + self.name: ninja_join(self.lflags),
|
||||
'libs_' + self.name: ninja_join(self.libs)})
|
||||
'cflags_' + self.name: ninja_join(remove_duplicates(self.cflags)),
|
||||
'lflags_' + self.name: ninja_join(remove_duplicates(self.lflags)),
|
||||
'libs_' + self.name: ninja_join(remove_duplicates(self.libs))})
|
||||
ninja_write_rule(f, 'cc_' + self.name,
|
||||
command='$cc_{} -MMD -MT $out -MF $out.d $cflags_{} -c $in -o $out'.format(self.name, self.name),
|
||||
description='CC $out',
|
||||
@@ -339,11 +348,13 @@ for dep in ['x11',
|
||||
'xext',
|
||||
'xrender',
|
||||
'xrandr>=1.3',
|
||||
'gmodule-2.0',
|
||||
'gio-2.0',
|
||||
'glib-2.0',
|
||||
'gobject-2.0',
|
||||
'pangocairo',
|
||||
'pango',
|
||||
'cairo',
|
||||
'glib-2.0',
|
||||
'gobject-2.0',
|
||||
'imlib2>=1.4.2']:
|
||||
lib, cf, lf = pkg_config(dep)
|
||||
LIBS += lib
|
||||
@@ -409,7 +420,8 @@ if args.asan or args.memory_tracing or args.tracing:
|
||||
trace_flags = ['-O0',
|
||||
'-fno-common',
|
||||
'-fno-omit-frame-pointer',
|
||||
'-rdynamic']
|
||||
'-rdynamic',
|
||||
'-DUSE_REAL_MALLOC']
|
||||
CFLAGS += trace_flags
|
||||
LFLAGS += trace_flags + ['-fuse-ld=gold']
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@ char *battery_dwheel_command;
|
||||
gboolean battery_found;
|
||||
gboolean battery_warn;
|
||||
gboolean battery_warn_red;
|
||||
Background *battery_warn_bg;
|
||||
|
||||
char *battery_sys_prefix = (char *)"";
|
||||
|
||||
@@ -84,7 +83,6 @@ void default_battery()
|
||||
INIT_TIMER(battery_blink_timer);
|
||||
battery_warn = FALSE;
|
||||
battery_warn_red = FALSE;
|
||||
battery_warn_bg = NULL;
|
||||
bat1_has_font = FALSE;
|
||||
bat1_font_desc = NULL;
|
||||
bat1_format = NULL;
|
||||
@@ -138,7 +136,6 @@ void cleanup_battery()
|
||||
destroy_timer(&battery_timer);
|
||||
destroy_timer(&battery_blink_timer);
|
||||
battery_found = FALSE;
|
||||
free_and_null(battery_warn_bg);
|
||||
|
||||
battery_os_free();
|
||||
}
|
||||
@@ -174,6 +171,7 @@ void battery_update_text(char *dest, char *format)
|
||||
// %h : Hours left (estimated).
|
||||
// %t : Time left. This is equivalent to the old behaviour; i.e. "(plugged in)" or "hrs:mins" otherwise.
|
||||
// %p : Percentage left. Includes the % sign.
|
||||
// %P : Percentage left without the % sign.
|
||||
if (*c == '%') {
|
||||
c++;
|
||||
o++; // Skip the format control character.
|
||||
@@ -202,6 +200,10 @@ void battery_update_text(char *dest, char *format)
|
||||
snprintf(buf, sizeof(buf), "%d%%", battery_state.percentage);
|
||||
strnappend(dest, buf, BATTERY_BUF_SIZE);
|
||||
break;
|
||||
case 'P':
|
||||
snprintf(buf, sizeof(buf), "%d", battery_state.percentage);
|
||||
strnappend(dest, buf, BATTERY_BUF_SIZE);
|
||||
break;
|
||||
case 't':
|
||||
if (battery_state.state == BATTERY_FULL) {
|
||||
snprintf(buf, sizeof(buf), "Full");
|
||||
@@ -325,30 +327,8 @@ void blink_battery(void *arg)
|
||||
if (!battery_enabled)
|
||||
return;
|
||||
battery_warn_red = battery_warn ? !battery_warn_red : FALSE;
|
||||
if (battery_warn_red && !battery_warn_bg) {
|
||||
battery_warn_bg = calloc(1, sizeof(*battery_warn_bg));
|
||||
*battery_warn_bg = *panel_config.battery.area.bg;
|
||||
battery_warn_bg->fill_color.alpha = 1.0;
|
||||
battery_warn_bg->border.color.alpha = 1.0;
|
||||
}
|
||||
if (battery_warn_red) {
|
||||
battery_warn_bg->fill_color.rgb[0] = 0.6;
|
||||
battery_warn_bg->fill_color.rgb[1] = 0.1;
|
||||
battery_warn_bg->fill_color.rgb[2] = 0.1;
|
||||
battery_warn_bg->border.color.rgb[0] = 0.5;
|
||||
battery_warn_bg->border.color.rgb[1] = 0.0;
|
||||
battery_warn_bg->border.color.rgb[2] = 0.0;
|
||||
} else {
|
||||
battery_warn_bg->fill_color.rgb[0] = 0.9;
|
||||
battery_warn_bg->fill_color.rgb[1] = 0.7;
|
||||
battery_warn_bg->fill_color.rgb[2] = 0.1;
|
||||
battery_warn_bg->border.color.rgb[0] = 0.7;
|
||||
battery_warn_bg->border.color.rgb[1] = 0.5;
|
||||
battery_warn_bg->border.color.rgb[2] = 0.1;
|
||||
}
|
||||
for (int i = 0; i < num_panels; i++) {
|
||||
if (panels[i].battery.area.on_screen) {
|
||||
panels[i].battery.area.bg = battery_warn_bg;
|
||||
schedule_redraw(&panels[i].battery.area);
|
||||
}
|
||||
}
|
||||
@@ -403,8 +383,8 @@ void update_battery_tick(void *arg)
|
||||
}
|
||||
|
||||
if (!battery_blink_timer.enabled_) {
|
||||
if (battery_state.percentage < battery_low_status &&
|
||||
battery_state.state == BATTERY_DISCHARGING) {
|
||||
if ((battery_state.percentage < battery_low_status &&
|
||||
battery_state.state == BATTERY_DISCHARGING) || debug_blink) {
|
||||
change_timer(&battery_blink_timer, true, 10, 1000, blink_battery, 0);
|
||||
battery_warn = TRUE;
|
||||
}
|
||||
@@ -495,6 +475,12 @@ void draw_battery(void *obj, cairo_t *c)
|
||||
battery->bat2_posy,
|
||||
&battery->font_color,
|
||||
panel->scale);
|
||||
if (battery_warn && battery_warn_red) {
|
||||
cairo_set_source_rgba(c, 1, 0, 0, 1);
|
||||
cairo_set_line_width(c, 0);
|
||||
cairo_rectangle(c, 0, 0, battery->area.width, battery->area.height);
|
||||
cairo_fill(c);
|
||||
}
|
||||
}
|
||||
|
||||
void battery_dump_geometry(void *obj, int indent)
|
||||
|
||||
@@ -508,6 +508,8 @@ void add_entry(char *key, char *value)
|
||||
wm_menu = atoi(value);
|
||||
else if (strcmp(key, "panel_dock") == 0)
|
||||
panel_dock = atoi(value);
|
||||
else if (strcmp(key, "panel_pivot_struts") == 0)
|
||||
panel_pivot_struts = atoi(value);
|
||||
else if (strcmp(key, "urgent_nb_of_blink") == 0)
|
||||
max_tick_urgent = atoi(value);
|
||||
else if (strcmp(key, "panel_layer") == 0) {
|
||||
@@ -792,7 +794,7 @@ void add_entry(char *key, char *value)
|
||||
} else if (strcmp(key, "button_icon") == 0) {
|
||||
if (strlen(value)) {
|
||||
Button *button = get_or_create_last_button();
|
||||
button->backend->icon_name = strdup(value);
|
||||
button->backend->icon_name = expand_tilde(value);
|
||||
}
|
||||
} else if (strcmp(key, "button_text") == 0) {
|
||||
if (strlen(value)) {
|
||||
|
||||
@@ -891,7 +891,7 @@ gboolean read_execp(void *obj)
|
||||
} else {
|
||||
execp->backend->text = strdup("");
|
||||
}
|
||||
execp->backend->icon_path = strdup(execp->backend->buf_stdout);
|
||||
execp->backend->icon_path = expand_tilde(execp->backend->buf_stdout);
|
||||
}
|
||||
size_t len = strlen(execp->backend->text);
|
||||
if (len > 0 && execp->backend->text[len - 1] == '\n')
|
||||
|
||||
@@ -107,6 +107,8 @@ void handle_env_vars()
|
||||
debug_thumbnails = getenv("DEBUG_THUMBNAILS") != NULL;
|
||||
debug_timers = getenv("DEBUG_TIMERS") != NULL;
|
||||
debug_executors = getenv("DEBUG_EXECUTORS") != NULL;
|
||||
debug_blink = getenv("DEBUG_BLINK") != NULL;
|
||||
thumb_use_shm = getenv("TINT2_THUMBNAIL_SHM") != NULL;
|
||||
if (debug_fps) {
|
||||
init_fps_distribution();
|
||||
char *s = getenv("TRACING_FPS_THRESHOLD");
|
||||
|
||||
@@ -566,6 +566,10 @@ char *icon_path_from_full_path(const char *s)
|
||||
{
|
||||
if (is_full_path(s) && file_exists(s))
|
||||
return strdup(s);
|
||||
char *expanded = expand_tilde(s);
|
||||
if (is_full_path(expanded) && file_exists(expanded))
|
||||
return expanded;
|
||||
free(expanded);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
13
src/main.c
13
src/main.c
@@ -797,6 +797,19 @@ void tint2(int argc, char **argv, gboolean *restart)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifdef USE_REAL_MALLOC
|
||||
if (!getenv("G_SLICE") && setenv("G_SLICE", "always-malloc", 1) == 0) {
|
||||
fprintf(stderr,
|
||||
YELLOW "tint2: reexecuting tint2 without glib slice allocator..." RESET "\n");
|
||||
execvp(argv[0], argv);
|
||||
fprintf(stderr, RED "tint2: %s %d: execvp failed! carrying on..." RESET "\n",
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
#else
|
||||
fprintf(stderr, "tint2: Using glib slice allocator (default). "
|
||||
"Run tint2 with environment variable G_SLICE=always-malloc "
|
||||
"in case of strange behavior or crashes\n");
|
||||
#endif
|
||||
gboolean restart;
|
||||
do {
|
||||
restart = FALSE;
|
||||
|
||||
51
src/panel.c
51
src/panel.c
@@ -49,6 +49,7 @@ MouseAction mouse_tilt_right;
|
||||
TaskbarMode taskbar_mode;
|
||||
gboolean wm_menu;
|
||||
gboolean panel_dock;
|
||||
gboolean panel_pivot_struts;
|
||||
Layer panel_layer;
|
||||
PanelPosition panel_position;
|
||||
gboolean panel_horizontal;
|
||||
@@ -59,7 +60,7 @@ gboolean debug_geometry;
|
||||
gboolean debug_gradients;
|
||||
gboolean startup_notifications;
|
||||
gboolean debug_thumbnails;
|
||||
|
||||
gboolean debug_blink;
|
||||
gboolean panel_autohide;
|
||||
int panel_autohide_show_timeout;
|
||||
int panel_autohide_hide_timeout;
|
||||
@@ -103,6 +104,7 @@ void default_panel()
|
||||
panel_shrink = FALSE;
|
||||
panel_strut_policy = STRUT_FOLLOW_SIZE;
|
||||
panel_dock = FALSE; // default not in the dock
|
||||
panel_pivot_struts = FALSE;
|
||||
panel_layer = BOTTOM_LAYER; // default is bottom layer
|
||||
panel_window_name = strdup("tint2");
|
||||
wm_menu = FALSE;
|
||||
@@ -610,6 +612,21 @@ gboolean resize_panel(void *obj)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define STRUT_LEFT 0
|
||||
#define STRUT_RIGHT 1
|
||||
#define STRUT_TOP 2
|
||||
#define STRUT_BOTTOM 3
|
||||
#define STRUT_LEFT_Y1 4
|
||||
#define STRUT_LEFT_Y2 5
|
||||
#define STRUT_RIGHT_Y1 6
|
||||
#define STRUT_RIGHT_Y2 7
|
||||
#define STRUT_TOP_X1 8
|
||||
#define STRUT_TOP_X2 9
|
||||
#define STRUT_BOTTOM_X1 10
|
||||
#define STRUT_BOTTOM_X2 11
|
||||
#define STRUT_COUNT 12
|
||||
#define STRUT_COUNT_OLD 4
|
||||
|
||||
void update_strut(Panel *p)
|
||||
{
|
||||
if (panel_strut_policy == STRUT_NONE) {
|
||||
@@ -624,36 +641,36 @@ void update_strut(Panel *p)
|
||||
int d3;
|
||||
XGetGeometry(server.display, server.root_win, &d2, &d3, &d3, &screen_width, &screen_height, &d1, &d1);
|
||||
Monitor monitor = server.monitors[p->monitor];
|
||||
long struts[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
if (panel_horizontal) {
|
||||
long struts[STRUT_COUNT] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
if (panel_horizontal ^ panel_pivot_struts) {
|
||||
int height = p->area.height + p->marginy;
|
||||
if (panel_strut_policy == STRUT_MINIMUM || (panel_strut_policy == STRUT_FOLLOW_SIZE && panel_autohide && p->is_hidden))
|
||||
height = p->hidden_height;
|
||||
if (panel_position & TOP) {
|
||||
struts[2] = height + monitor.y;
|
||||
struts[8] = p->posx;
|
||||
struts[STRUT_TOP] = height + monitor.y;
|
||||
struts[STRUT_TOP_X1] = p->posx;
|
||||
// p->area.width - 1 allowed full screen on monitor 2
|
||||
struts[9] = p->posx + p->area.width - 1;
|
||||
struts[STRUT_TOP_X2] = p->posx + p->area.width - 1;
|
||||
} else {
|
||||
struts[3] = height + screen_height - monitor.y - monitor.height;
|
||||
struts[10] = p->posx;
|
||||
struts[STRUT_BOTTOM] = height + screen_height - monitor.y - monitor.height;
|
||||
struts[STRUT_BOTTOM_X1] = p->posx;
|
||||
// p->area.width - 1 allowed full screen on monitor 2
|
||||
struts[11] = p->posx + p->area.width - 1;
|
||||
struts[STRUT_BOTTOM_X2] = p->posx + p->area.width - 1;
|
||||
}
|
||||
} else {
|
||||
int width = p->area.width + p->marginx;
|
||||
if (panel_strut_policy == STRUT_MINIMUM || (panel_strut_policy == STRUT_FOLLOW_SIZE && panel_autohide && p->is_hidden))
|
||||
width = p->hidden_width;
|
||||
if (panel_position & LEFT) {
|
||||
struts[0] = width + monitor.x;
|
||||
struts[4] = p->posy;
|
||||
struts[STRUT_LEFT] = width + monitor.x;
|
||||
struts[STRUT_LEFT_Y1] = p->posy;
|
||||
// p->area.width - 1 allowed full screen on monitor 2
|
||||
struts[5] = p->posy + p->area.height - 1;
|
||||
struts[STRUT_LEFT_Y2] = p->posy + p->area.height - 1;
|
||||
} else {
|
||||
struts[1] = width + screen_width - monitor.x - monitor.width;
|
||||
struts[6] = p->posy;
|
||||
struts[STRUT_RIGHT] = width + screen_width - monitor.x - monitor.width;
|
||||
struts[STRUT_RIGHT_Y1] = p->posy;
|
||||
// p->area.width - 1 allowed full screen on monitor 2
|
||||
struts[7] = p->posy + p->area.height - 1;
|
||||
struts[STRUT_RIGHT_Y2] = p->posy + p->area.height - 1;
|
||||
}
|
||||
}
|
||||
// Old specification : fluxbox need _NET_WM_STRUT.
|
||||
@@ -664,7 +681,7 @@ void update_strut(Panel *p)
|
||||
32,
|
||||
PropModeReplace,
|
||||
(unsigned char *)&struts,
|
||||
4);
|
||||
STRUT_COUNT_OLD);
|
||||
XChangeProperty(server.display,
|
||||
p->main_win,
|
||||
server.atom._NET_WM_STRUT_PARTIAL,
|
||||
@@ -672,7 +689,7 @@ void update_strut(Panel *p)
|
||||
32,
|
||||
PropModeReplace,
|
||||
(unsigned char *)&struts,
|
||||
12);
|
||||
STRUT_COUNT);
|
||||
}
|
||||
|
||||
void set_panel_items_order(Panel *p)
|
||||
|
||||
@@ -69,6 +69,7 @@ typedef enum Strut {
|
||||
extern TaskbarMode taskbar_mode;
|
||||
extern gboolean wm_menu;
|
||||
extern gboolean panel_dock;
|
||||
extern gboolean panel_pivot_struts;
|
||||
extern Layer panel_layer;
|
||||
extern char *panel_window_name;
|
||||
extern PanelPosition panel_position;
|
||||
@@ -97,6 +98,8 @@ extern gboolean debug_frames;
|
||||
extern gboolean debug_thumbnails;
|
||||
extern double ui_scale_dpi_ref;
|
||||
extern double ui_scale_monitor_size_ref;
|
||||
extern gboolean thumb_use_shm;
|
||||
extern gboolean debug_blink;
|
||||
|
||||
typedef struct Panel {
|
||||
Area area;
|
||||
|
||||
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
File diff suppressed because it is too large
Load Diff
@@ -25,8 +25,8 @@
|
||||
GtkWidget *scale_relative_to_dpi, *scale_relative_to_screen_height;
|
||||
GtkWidget *panel_width, *panel_height, *panel_margin_x, *panel_margin_y, *panel_padding_x, *panel_padding_y,
|
||||
*panel_spacing;
|
||||
GtkWidget *panel_wm_menu, *panel_dock, *panel_autohide, *panel_autohide_show_time, *panel_autohide_hide_time,
|
||||
*panel_autohide_size;
|
||||
GtkWidget *panel_wm_menu, *panel_dock, *panel_pivot_struts, *panel_autohide, *panel_autohide_show_time,
|
||||
*panel_autohide_hide_time, *panel_autohide_size;
|
||||
GtkWidget *panel_combo_strut_policy, *panel_combo_layer, *panel_combo_width_type, *panel_combo_height_type,
|
||||
*panel_combo_monitor;
|
||||
GtkWidget *panel_window_name, *disable_transparency;
|
||||
@@ -1015,6 +1015,27 @@ void create_panel(GtkWidget *parent)
|
||||
"The exact behavior depends on the window manager and its configuration."),
|
||||
NULL);
|
||||
|
||||
row++;
|
||||
col = 2;
|
||||
label = gtk_label_new(_("Pivot reserved space"));
|
||||
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++;
|
||||
|
||||
panel_pivot_struts = gtk_check_button_new();
|
||||
gtk_widget_show(panel_pivot_struts);
|
||||
gtk_table_attach(GTK_TABLE(table), panel_pivot_struts, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0);
|
||||
col++;
|
||||
gtk_tooltips_set_tip(tooltips,
|
||||
panel_pivot_struts,
|
||||
_("If enabled, the space reserved for the panel (if \"Maximised windows\" is set to "
|
||||
"match the panel size or hidden panel size) will be given to the window manager as if "
|
||||
"the panel were the opposite orientation (horizontal vs vertical) than it actually is. "
|
||||
"On some window managers this allows placing a panel in the middle of the virtual screen, "
|
||||
"e.g. on the bottom edge of the top screen in a vertical dual-monitor setup."),
|
||||
NULL);
|
||||
|
||||
row++;
|
||||
col = 2;
|
||||
label = gtk_label_new(_("Panel layer"));
|
||||
@@ -5824,7 +5845,8 @@ void create_battery(GtkWidget *parent)
|
||||
" %m: Minutes left until completely charged/discharged (estimated).\n"
|
||||
" %h: Hours left until completely charged/discharged (estimated).\n"
|
||||
" %t: Time left. Shows \"hrs:mins\" when charging/discharging, or \"Full\".\n"
|
||||
" %p: Percentage. Includes the % sign.";
|
||||
" %p: Percentage. Includes the % sign.\n"
|
||||
" %p: Percentage. Without the % sign.";
|
||||
gtk_tooltips_set_tip(tooltips,
|
||||
battery_format1,
|
||||
_(bat_format_spec),
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
extern GtkWidget *scale_relative_to_dpi, *scale_relative_to_screen_height;
|
||||
extern GtkWidget *panel_width, *panel_height, *panel_margin_x, *panel_margin_y, *panel_padding_x, *panel_padding_y,
|
||||
*panel_spacing;
|
||||
extern GtkWidget *panel_wm_menu, *panel_dock, *panel_autohide, *panel_autohide_show_time, *panel_autohide_hide_time,
|
||||
*panel_autohide_size;
|
||||
extern GtkWidget *panel_wm_menu, *panel_dock, *panel_pivot_struts, *panel_autohide, *panel_autohide_show_time,
|
||||
*panel_autohide_hide_time, *panel_autohide_size;
|
||||
extern GtkWidget *panel_combo_strut_policy, *panel_combo_layer, *panel_combo_width_type, *panel_combo_height_type,
|
||||
*panel_combo_monitor;
|
||||
extern GtkWidget *panel_window_name, *disable_transparency;
|
||||
|
||||
@@ -295,6 +295,7 @@ void config_write_panel(FILE *fp)
|
||||
fprintf(fp, "panel_background_id = %d\n", gtk_combo_box_get_active(GTK_COMBO_BOX(panel_background)));
|
||||
fprintf(fp, "wm_menu = %d\n", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel_wm_menu)) ? 1 : 0);
|
||||
fprintf(fp, "panel_dock = %d\n", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel_dock)) ? 1 : 0);
|
||||
fprintf(fp, "panel_pivot_struts = %d\n", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel_pivot_struts)) ? 1 : 0);
|
||||
|
||||
fprintf(fp, "panel_position = ");
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(screen_position[POS_BLH]))) {
|
||||
@@ -1384,6 +1385,8 @@ void add_entry(char *key, char *value)
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel_wm_menu), atoi(value));
|
||||
} else if (strcmp(key, "panel_dock") == 0) {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel_dock), atoi(value));
|
||||
} else if (strcmp(key, "panel_pivot_struts") == 0) {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel_pivot_struts), atoi(value));
|
||||
} else if (strcmp(key, "panel_layer") == 0) {
|
||||
if (strcmp(value, "bottom") == 0)
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(panel_combo_layer), 2);
|
||||
|
||||
@@ -478,14 +478,14 @@ void draw(Area *a)
|
||||
a->_clear(a);
|
||||
}
|
||||
|
||||
cairo_surface_t *cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, a->width, a->height);
|
||||
cairo_surface_t *cs = cairo_xlib_surface_create(server.display, a->pix, server.visual, a->width, a->height);
|
||||
cairo_t *c = cairo_create(cs);
|
||||
|
||||
draw_background(a, c);
|
||||
|
||||
if (a->_draw_foreground)
|
||||
a->_draw_foreground(a, c);
|
||||
|
||||
draw_cairo_surface_to_xpixmap(cs, a->pix);
|
||||
cairo_destroy(c);
|
||||
cairo_surface_destroy(cs);
|
||||
}
|
||||
|
||||
@@ -1229,19 +1229,3 @@ void dump_image_data(const char *file_name, const char *name)
|
||||
|
||||
imlib_free_image();
|
||||
}
|
||||
|
||||
void draw_cairo_surface_to_xpixmap(cairo_surface_t *cs, Pixmap pix)
|
||||
{
|
||||
int w = cairo_image_surface_get_width(cs);
|
||||
int h = cairo_image_surface_get_height(cs);
|
||||
cairo_surface_t *cs_xlib = cairo_xlib_surface_create(server.display, pix, server.visual, w, h);
|
||||
cairo_xlib_surface_set_size(cs_xlib, w, h);
|
||||
cairo_t *c_xlib = cairo_create(cs_xlib);
|
||||
|
||||
cairo_set_source_surface(c_xlib, cs, 0, 0);
|
||||
cairo_paint(c_xlib);
|
||||
cairo_surface_flush(cs_xlib);
|
||||
|
||||
cairo_destroy(c_xlib);
|
||||
cairo_surface_destroy(cs_xlib);
|
||||
}
|
||||
|
||||
@@ -154,8 +154,6 @@ void get_image_mean_color(const Imlib_Image image, Color *mean_color);
|
||||
|
||||
void dump_image_data(const char *file_name, const char *name);
|
||||
|
||||
void draw_cairo_surface_to_xpixmap(cairo_surface_t *cs, Pixmap pix);
|
||||
|
||||
#define free_and_null(p) \
|
||||
{ \
|
||||
free(p); \
|
||||
|
||||
@@ -371,7 +371,7 @@ void smooth_thumbnail(cairo_surface_t *image_surface)
|
||||
const size_t rmask = 0xff0000;
|
||||
const size_t gmask = 0xff00;
|
||||
const size_t bmask = 0xff;
|
||||
for (size_t i = 0; i < tw * (th - 1) - 1; i++) {
|
||||
for (size_t i = 0; i < tw * (th - 1) - 1 && i < tw * th; i++) {
|
||||
u_int32_t c1 = data[i];
|
||||
u_int32_t c2 = data[i + 1];
|
||||
u_int32_t c3 = data[i + tw];
|
||||
@@ -390,13 +390,27 @@ void smooth_thumbnail(cairo_surface_t *image_surface)
|
||||
cairo_surface_t *get_window_thumbnail_ximage(Window win, size_t size, gboolean use_shm)
|
||||
{
|
||||
cairo_surface_t *result = NULL;
|
||||
XWindowAttributes wa;
|
||||
XWindowAttributes wa = {};
|
||||
if (!XGetWindowAttributes(server.display, win, &wa) || wa.width <= 0 || wa.height <= 0 ||
|
||||
wa.map_state != IsViewable)
|
||||
wa.map_state != IsViewable) {
|
||||
if (debug_thumbnails) {
|
||||
fprintf(stderr, "tint2: could not get thumbnail, invalid geometry %d x %d\n",
|
||||
wa.width, wa.height);
|
||||
}
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (window_is_iconified(win))
|
||||
if (window_is_iconified(win)) {
|
||||
if (debug_thumbnails) {
|
||||
fprintf(stderr, "tint2: could not get thumbnail, minimized window\n");
|
||||
}
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (debug_thumbnails) {
|
||||
fprintf(stderr, "tint2: getting thumbnail for window with size %d x %d\n",
|
||||
wa.width, wa.height);
|
||||
}
|
||||
|
||||
size_t w, h;
|
||||
w = (size_t)wa.width;
|
||||
@@ -414,8 +428,20 @@ cairo_surface_t *get_window_thumbnail_ximage(Window win, size_t size, gboolean u
|
||||
fw = tw;
|
||||
ox = oy = 0;
|
||||
}
|
||||
if (!w || !h || !tw || !th || !fw)
|
||||
if (debug_thumbnails) {
|
||||
fprintf(stderr,
|
||||
"tint2: thumbnail size %zu x %zu, "
|
||||
"proportional width %zu, offset %zu\n",
|
||||
tw, th, fw, ox);
|
||||
}
|
||||
if (!w || !h || !tw || !th || !fw) {
|
||||
if (debug_thumbnails) {
|
||||
fprintf(stderr, "tint2: could not get thumbnail, invalid thumbnail size: "
|
||||
"%zu x %zu => %zu x %zu, %zu\n",
|
||||
w, h, tw, th, fw);
|
||||
}
|
||||
goto err0;
|
||||
}
|
||||
|
||||
XShmSegmentInfo shminfo;
|
||||
XImage *ximg;
|
||||
@@ -445,7 +471,7 @@ cairo_surface_t *get_window_thumbnail_ximage(Window win, size_t size, gboolean u
|
||||
goto err1;
|
||||
}
|
||||
shminfo.shmaddr = ximg->data = (char *)shmat(shminfo.shmid, 0, 0);
|
||||
if (!shminfo.shmaddr) {
|
||||
if (shminfo.shmaddr == (void*)-1) {
|
||||
fprintf(stderr, RED "tint2: !shmat" RESET "\n");
|
||||
goto err2;
|
||||
}
|
||||
@@ -461,8 +487,18 @@ cairo_surface_t *get_window_thumbnail_ximage(Window win, size_t size, gboolean u
|
||||
}
|
||||
|
||||
XGetWindowAttributes(server.display, win, &wa);
|
||||
if (wa.map_state != IsViewable)
|
||||
if (wa.map_state != IsViewable) {
|
||||
if (debug_thumbnails) {
|
||||
fprintf(stderr, "tint2: could not get thumbnail, window not viewable\n");
|
||||
}
|
||||
goto err4;
|
||||
}
|
||||
|
||||
if (debug_thumbnails) {
|
||||
fprintf(stderr,
|
||||
"tint2: creating cairo surface with size %zu x %zu = %zu px\n",
|
||||
tw, th, tw * th);
|
||||
}
|
||||
|
||||
result = cairo_image_surface_create(CAIRO_FORMAT_RGB24, (int)tw, (int)th);
|
||||
u_int32_t *data = (u_int32_t *)cairo_image_surface_get_data(result);
|
||||
@@ -500,23 +536,25 @@ cairo_surface_t *get_window_thumbnail_ximage(Window win, size_t size, gboolean u
|
||||
for (size_t yt = 0, y = 0; yt < th; yt++, y += ystep) {
|
||||
for (size_t xt = 0, x = 0; xt < fw; xt++, x += xstep) {
|
||||
size_t j = yt * tw + ox + xt;
|
||||
u_int32_t c1 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x1) / prec), (int)((y + offset_y1) / prec));
|
||||
u_int32_t c2 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x2) / prec), (int)((y + offset_y2) / prec));
|
||||
u_int32_t c3 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x3) / prec), (int)((y + offset_y3) / prec));
|
||||
u_int32_t c4 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x4) / prec), (int)((y + offset_y4) / prec));
|
||||
u_int32_t c5 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x5) / prec), (int)((y + offset_y5) / prec));
|
||||
u_int32_t c6 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x6) / prec), (int)((y + offset_y6) / prec));
|
||||
u_int32_t c7 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x7) / prec), (int)((y + offset_y7) / prec));
|
||||
u_int32_t b = ((c1 & bmask) + (c2 & bmask) + (c3 & bmask) + (c4 & bmask) + (c5 & bmask) * 2 + (c6 & bmask) +
|
||||
(c7 & bmask)) /
|
||||
8;
|
||||
u_int32_t g = ((c1 & gmask) + (c2 & gmask) + (c3 & gmask) + (c4 & gmask) + (c5 & gmask) * 2 + (c6 & gmask) +
|
||||
(c7 & gmask)) /
|
||||
8;
|
||||
u_int32_t r = ((c1 & rmask) + (c2 & rmask) + (c3 & rmask) + (c4 & rmask) + (c5 & rmask) * 2 + (c6 & rmask) +
|
||||
(c7 & rmask)) /
|
||||
8;
|
||||
data[j] = (r & rmask) | (g & gmask) | (b & bmask);
|
||||
if (j < tw * th) {
|
||||
u_int32_t c1 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x1) / prec), (int)((y + offset_y1) / prec));
|
||||
u_int32_t c2 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x2) / prec), (int)((y + offset_y2) / prec));
|
||||
u_int32_t c3 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x3) / prec), (int)((y + offset_y3) / prec));
|
||||
u_int32_t c4 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x4) / prec), (int)((y + offset_y4) / prec));
|
||||
u_int32_t c5 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x5) / prec), (int)((y + offset_y5) / prec));
|
||||
u_int32_t c6 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x6) / prec), (int)((y + offset_y6) / prec));
|
||||
u_int32_t c7 = (u_int32_t)GetPixel(ximg, (int)((x + offset_x7) / prec), (int)((y + offset_y7) / prec));
|
||||
u_int32_t b = ((c1 & bmask) + (c2 & bmask) + (c3 & bmask) + (c4 & bmask) + (c5 & bmask) * 2 + (c6 & bmask) +
|
||||
(c7 & bmask)) /
|
||||
8;
|
||||
u_int32_t g = ((c1 & gmask) + (c2 & gmask) + (c3 & gmask) + (c4 & gmask) + (c5 & gmask) * 2 + (c6 & gmask) +
|
||||
(c7 & gmask)) /
|
||||
8;
|
||||
u_int32_t r = ((c1 & rmask) + (c2 & rmask) + (c3 & rmask) + (c4 & rmask) + (c5 & rmask) * 2 + (c6 & rmask) +
|
||||
(c7 & rmask)) /
|
||||
8;
|
||||
data[j] = (r & rmask) | (g & gmask) | (b & bmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Convert to argb32
|
||||
@@ -542,6 +580,7 @@ cairo_surface_t *get_window_thumbnail_ximage(Window win, size_t size, gboolean u
|
||||
|
||||
// 2nd pass
|
||||
smooth_thumbnail(result);
|
||||
cairo_surface_mark_dirty(result);
|
||||
|
||||
if (ximg) {
|
||||
XDestroyImage(ximg);
|
||||
@@ -559,7 +598,7 @@ err2:
|
||||
err1:
|
||||
if (ximg)
|
||||
XDestroyImage(ximg);
|
||||
err0:
|
||||
err0:
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -575,11 +614,12 @@ gboolean cairo_surface_is_blank(cairo_surface_t *image_surface)
|
||||
return empty;
|
||||
}
|
||||
|
||||
gboolean thumb_use_shm = FALSE;
|
||||
|
||||
cairo_surface_t *get_window_thumbnail(Window win, int size)
|
||||
{
|
||||
cairo_surface_t *image_surface = NULL;
|
||||
const gboolean shm_allowed = FALSE;
|
||||
if (shm_allowed && server.has_shm && server.composite_manager) {
|
||||
if (thumb_use_shm && server.has_shm && server.composite_manager) {
|
||||
image_surface = get_window_thumbnail_ximage(win, (size_t)size, TRUE);
|
||||
if (image_surface && cairo_surface_is_blank(image_surface)) {
|
||||
cairo_surface_destroy(image_surface);
|
||||
|
||||
Reference in New Issue
Block a user