Compare commits

...

77 Commits
16.0 ... v16.4

Author SHA1 Message Date
Chris Lee
8a7ba9bf50 Release 16.4 2018-05-03 04:06:13 +00:00
Chris Lee
ffa6e5ba49 Change new release script to also publish to remote (issue #707) 2018-05-03 03:58:05 +00:00
Chris Lee
d1f5a46a73 Fix executor verbosity (issue #699) 2018-04-17 19:48:55 +00:00
Chris Lee
131704081c Fix imlib leak (issue #704) 2018-04-17 19:37:10 +00:00
Chris Lee
21466cc94e Update authors file 2018-04-17 19:22:06 +00:00
Chris Lee
e06b63e1dc Release 16.3 2018-04-17 19:19:00 +00:00
Chris Lee
9a03b8b4e6 Update changelog 2018-04-17 19:18:50 +00:00
o9000
47bc01d608 Scaling: limit to 8x 2018-02-10 10:52:10 +00:00
o9000
0e4b3bd32e Merge branch 'fix_urgent_delay' into 'master'
Fix one second delay before urgent task starts to blink

See merge request o9000/tint2!30
2018-02-10 10:50:22 +00:00
arza
9ac0cd1254 Fix one second delay before urgent task starts to blink 2018-02-10 07:35:08 +02:00
o9000
73ab9b6930 Merge branch 'master' into 'master'
Fix typo around wiki link

See merge request o9000/tint2!29
2018-02-09 21:28:16 +00:00
Michael Vetter
96361ab1cd Fix typo around wiki link 2018-02-09 13:50:36 +01:00
o9000
b9589450bb Executor: Fix layout (issue #695) 2018-01-26 21:20:23 +00:00
o9000
b810bad93f Release 16.2 2018-01-21 07:04:15 +00:00
o9000
b85362b5c7 Update doc and changelog 2018-01-21 07:03:07 +00:00
o9000
03675b152d Match perfectly text layout and drawing parameters #693 2018-01-20 08:56:58 +00:00
o9000
c3fdd76b58 packaging 2018-01-19 23:23:59 +00:00
o9000
04ba5a6617 Do not spin when battery is unplugged 2018-01-19 23:20:44 +00:00
o9000
f5f8792d42 Update translations 2018-01-19 22:00:26 +00:00
o9000
965a2665b0 Scaling support - scale by screen height (issue #656) 2018-01-19 21:37:56 +00:00
o9000
b2b0119f4d Fix use after free in DPI computation 2018-01-19 21:21:22 +00:00
o9000
41e49ef4e6 Do not spin when battery is unplugged 2018-01-19 21:20:03 +00:00
o9000
25dd623618 Likely fix for #693 2018-01-19 21:19:18 +00:00
o9000
28b1174c0f Remove dead code 2018-01-19 20:49:38 +00:00
o9000
b70edc437c Possible fix for issue #693 2018-01-18 21:41:32 +00:00
o9000
bf58e16b83 Possible fix for issue #693 2018-01-18 21:31:44 +00:00
o9000
3190c5b7de Scaling support - tooltips (issue #656) 2018-01-17 21:12:17 +00:00
o9000
5db0dceec2 Scaling support - doc (issue #656) 2018-01-17 05:49:02 +00:00
o9000
5c5f507e54 Scaling support in tint2conf - translations (issue #656) 2018-01-17 05:40:46 +00:00
o9000
d301ada47a Scaling support in tint2conf - translations (issue #656) 2018-01-17 05:37:15 +00:00
o9000
b3f9834313 Scaling support in tint2conf (issue #656) 2018-01-17 05:27:56 +00:00
o9000
c7b23ee94a Scale panel elements (issue #656) 2018-01-17 05:19:32 +00:00
o9000
12f04e3055 Scale panel window size (issue #656) 2018-01-17 04:13:01 +00:00
o9000
7f62594cf6 Add config option (issue #656) 2018-01-17 03:54:49 +00:00
o9000
405c2c9286 Compute monitor DPI (issue #656) 2018-01-17 03:51:32 +00:00
o9000
90a445868c Update changelog 2018-01-15 06:13:05 +00:00
o9000
427afc61b5 Distribute size correctly between taskbars when center alignment is used and there is only one visible taskbar (Fixes issue #691) 2018-01-14 17:31:46 +00:00
o9000
ee92fac10e Add a timeout to the version checker script 2017-12-31 09:20:15 +00:00
o9000
95eea350fe Add a timeout to the version checker script 2017-12-31 09:15:34 +00:00
o9000
8242b494bc Release 16.1 2017-12-30 09:29:29 +00:00
o9000
1c6377f570 Remove tint2 ppa 2017-12-29 16:28:30 +01:00
o9000
dd1fd28114 Embed default icon, in case it is not found on the system (e.g. tint2 not installed, just compiled) 2017-12-29 16:10:58 +01:00
o9000
b4610fcb6e CI script: remove ANSI color codes 2017-12-29 14:45:47 +01:00
o9000
eb0e6765f9 Taskbar: setup timers in init_() to allow restart 2017-12-29 14:38:06 +01:00
o9000
5ee278d3ca CI script: set a timeout in case unit tests hang 2017-12-29 14:04:02 +01:00
o9000
fb438031c3 Fix CI script 2017-12-29 13:51:04 +01:00
o9000
e5380f8e29 Timer: rename timeout -> timer 2017-12-29 13:10:47 +01:00
o9000
c064ec70ed Fix CI script 2017-12-29 12:53:29 +01:00
o9000
a9a9a753bc Timer: new implementation (merge complete) 2017-12-29 06:32:55 +01:00
o9000
38bee65b58 Timer: new implementation (all tests pass) 2017-12-29 06:21:53 +01:00
o9000
f64cf199e4 Timer: new implementation (merge finished, tests failing) 2017-12-28 22:45:20 +01:00
o9000
0911dcaed1 Timer: new implementation (needs merge) 2017-12-28 21:54:14 +01:00
o9000
c41d75e54e Integrate unit tests in ci script 2017-12-28 19:28:57 +01:00
o9000
8e0bdcaedd Timer: more tests 2017-12-28 13:22:32 +01:00
o9000
be4554b89d Timer: more tests 2017-12-28 11:39:41 +01:00
o9000
82d7fdc8f9 Timer: more tests 2017-12-28 10:42:09 +01:00
o9000
e046cb88ab Timer: more tests 2017-12-28 10:34:53 +01:00
o9000
300ef518cb Timer: more tests 2017-12-28 09:43:00 +01:00
o9000
457d51e267 Task, Button: add a bit of slack in the pango text layout, to avoid wrapping due to rounding errors 2017-12-28 09:14:02 +01:00
o9000
1b48efe738 Executor: add a bit of slack in the pango text layout, to avoid wrapping due to rounding errors 2017-12-28 09:11:43 +01:00
o9000
40e01e2abf Timer: add testing base 2017-12-27 22:18:02 +01:00
o9000
a7ca1b739b Workaround broken timer code (SIGSEGV on recent gcc) 2017-12-27 21:15:12 +01:00
o9000
750cbd572c Cleanup cmakefile 2017-12-21 17:27:05 +01:00
o9000
75c2a2084d get_version.sh: allow running outside source tree 2017-12-21 17:25:33 +01:00
o9000
9b17461f74 Updated changelog 2017-12-21 12:54:25 +01:00
o9000
a185f625f9 Proper fix for time_t printing 2017-12-21 12:33:09 +01:00
o9000
3a9181eff5 Fix packaged version check for OpenBSD 2017-12-21 12:31:17 +01:00
o9000
5cea67171b Do not report 3rd party library warnings 2017-12-21 12:27:57 +01:00
o9000
328a35f949 A bit of refactoring 2017-12-21 12:06:23 +01:00
o9000
cab9c3bddd A bit of refactoring 2017-12-21 12:05:37 +01:00
o9000
5dd814773a A bit of refactoring 2017-12-21 11:57:49 +01:00
o9000
f4384b786c Fix includes in strlcat 2017-12-21 11:47:59 +01:00
o9000
5bc83561e0 Regression tests: use proper OS names 2017-12-21 11:45:57 +01:00
o9000
375e965a3a Silence time_t warning 2017-12-21 11:44:41 +01:00
o9000
67e25b8102 Replace strcat with strlcat 2017-12-21 11:42:07 +01:00
o9000
c96201930b Replace sprintf with snprintf 2017-12-21 11:22:11 +01:00
o9000
6bf72a030a Update changelog 2017-12-20 20:27:28 +01:00
70 changed files with 6163 additions and 4337 deletions

View File

@@ -6,6 +6,7 @@ tint2 is developped by :
- Ovidiu M <mrovi9000 at gmail.com> : launcher, bug fixes
- Mishael A Sibiryakov (death@junki.org) : freespace
- Sebastian Reichel <sre@ring0.de> : battery, various fixes, debian package maintainer
- Chris Lee <chrlee at protonmail> : bug fixes, maintainer starting with v16.3
tint2 is based on the ttm source code (http://code.google.com/p/ttm/)
- 2007-2008 Pål Staurland <staura@gmail.com>

View File

@@ -134,6 +134,7 @@ set( SOURCES src/config.c
src/util/tracing.c
src/mouse_actions.c
src/drag_and_drop.c
src/default_icon.c
src/clock/clock.c
src/systray/systraybar.c
src/launcher/launcher.c
@@ -157,6 +158,7 @@ set( SOURCES src/config.c
src/util/timer.c
src/util/cache.c
src/util/color.c
src/util/strlcat.c
src/util/print.c
src/util/gradient.c
src/util/test.c
@@ -246,7 +248,7 @@ else()
SET(TRACING_L_FLAGS "")
endif()
add_custom_target( version ALL "${PROJECT_SOURCE_DIR}/get_version.sh" -- "\"${PROJECT_SOURCE_DIR}/\"" )
add_custom_target( version ALL "${PROJECT_SOURCE_DIR}/get_version.sh" )
link_directories( ${X11_LIBRARY_DIRS}
${PANGOCAIRO_LIBRARY_DIRS}

View File

@@ -1,3 +1,28 @@
2018-05-03 16.4
- Update AUTHORS
- Fixes:
- Fix leak in image loading (issue #704)
- Executors no longer log unless env var DEBUG_EXECUTORS is set
2018-04-17 16.3
- Fixes:
- Layout in executor (issue #695)
- Other small issues
2018-01-21 16.2
- Fixes:
- Proper fix for issue #688
- Fix bad word wrapping (issue #693)
- Enhancements:
- Preliminary high DPI support
2017-12-30 16.1
- Fixes:
- Fixed several use-after-free errors in the timer code
- Merged patches and fixed other warnings on OpenBSD
- Task, Button, Executor: add a bit of slack in the pango text layout,
to avoid wrapping due to rounding errors
2017-12-20 16.0
- Fixes:
- Taskbar: `taskbar_distribute_size = 1` now playes well with `task_align = center` and
@@ -6,7 +31,8 @@
- Added Spanish translation (contributed by Vicmz)
- Executor: updated tooltip documentation (issue #676)
- Systray: warn on duplicate config option systray_name_filter (issue #652)
- Changed standard from C99 to C11 to support generic printing for unit tests
- Taskbar: thumbnail support in tooltips
- Use C11 if possible to support generic printing for unit tests (should fall back to C99)
2017-11-05 15.3
- Fixes:
@@ -976,3 +1002,7 @@ released tint-0.2
.
.
.
.
.
.
.

View File

@@ -1,5 +1,5 @@
# Latest stable release: 16.0
Changes: https://gitlab.com/o9000/tint2/blob/16.0/ChangeLog
# Latest stable release: 16.4
Changes: https://gitlab.com/o9000/tint2/blob/16.4/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.0
git checkout 16.4
mkdir build
cd build
cmake ..
@@ -97,4 +97,3 @@ 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)

View File

@@ -386,6 +386,8 @@ gradient_id_pressed = 2
<li><code>width</code> and <code>height</code> can be specified without units (e.g. <code>123</code>) as pixels, or followed by <code>%</code> as percentages of the monitor size (e.g. <code>50%</code>). Use <code>100%</code> for full monitor width/height.
Example:</li>
</ul></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:
panel_size = 94% 30
@@ -605,7 +607,7 @@ panel_size = 94% 30
<li><p><code>execp_cache_icon = boolean (0 or 1)</code> : If <code>execp_cache_icon = 0</code>, the image is reloaded each time the command is executed (useful if the image file is changed on disk by the program executed by <code>execp_command</code>). <em>(since 0.12.4)</em></p></li>
<li><p><code>execp_icon_w = integer</code> : You can use <code>execp_icon_w</code> and <code>execp_icon_h</code> to resize the image. If one of them is zero/missing, the image is rescaled proportionally. If both of them are zero/missing, the image is not rescaled. <em>(since 0.12.4)</em></p></li>
<li><p><code>execp_icon_h = integer</code> : See <code>execp_icon_w</code>. <em>(since 0.12.4)</em></p></li>
<li><p><code>execp_tooltip = text</code> : The tooltip. If left empty, no tooltip is displayed. If missing, the standard error of the command is shown as a tooltip (an ANSI clear screen sequence can reset the contents, bash: <code>printf '\e[2J'</code>, C: <code>printf(&quot;\x1b[2J&quot;);</code>). If the standard error is empty, the tooltip will show information about the time when the command was last executed. <em>(since 0.12.4)</em></p></li>
<li><p><code>execp_tooltip = text</code> : The tooltip. If left empty, no tooltip is displayed. If missing, the standard error of the command is shown as a tooltip (an ANSI clear screen sequence can reset the contents, bash: <code>printf &#39;\e[2J&#39;</code>, C: <code>printf(&quot;\x1b[2J&quot;);</code>). If the standard error is empty, the tooltip will show information about the time when the command was last executed. <em>(since 0.12.4)</em></p></li>
<li><p><code>execp_font = [FAMILY-LIST] [STYLE-OPTIONS] [SIZE]</code> : The font used to draw the text. <em>(since 0.12.4)</em></p></li>
<li><p><code>execp_font_color = color opacity</code> : The font color. <em>(since 0.12.4)</em></p></li>
<li><p><code>execp_markup = boolean (0 or 1)</code> : If non-zero, the output of the command is treated as Pango markup, which allows rich text formatting. The format is <a href="https://developer.gnome.org/pygtk/stable/pango-markup-language.html">documented here</a>. Note that using this with commands that print data downloaded from the Internet is a possible security risk. <em>(since 0.12.4)</em></p></li>

View File

@@ -199,9 +199,9 @@ pre {
</style>
</head>
<body>
<h1 id="latest-stable-release-16-0"><span class="md2man-title">Latest</span> <span class="md2man-section">stable</span> <span class="md2man-date">release:</span> <span class="md2man-source">16.0</span><a name="latest-stable-release-16-0" href="#latest-stable-release-16-0" class="md2man-permalink" title="permalink"></a></h1><p>Changes: <a href="https://gitlab.com/o9000/tint2/blob/16.0/ChangeLog">https://gitlab.com/o9000/tint2/blob/16.0/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-4"><span class="md2man-title">Latest</span> <span class="md2man-section">stable</span> <span class="md2man-date">release:</span> <span class="md2man-source">16.4</span><a name="latest-stable-release-16-4" href="#latest-stable-release-16-4" class="md2man-permalink" title="permalink"></a></h1><p>Changes: <a href="https://gitlab.com/o9000/tint2/blob/16.4/ChangeLog">https://gitlab.com/o9000/tint2/blob/16.4/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
git checkout 16.0
git checkout 16.4
mkdir build
cd build
cmake ..
@@ -269,8 +269,7 @@ 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>
Home)</li>
<li><a href="https://gitlab.com/o9000/tint2/wikis/Home">Tint2 wiki</a></li>
</ul>
</body>
</html>

View File

@@ -1,4 +1,4 @@
.TH TINT2 1 "2017\-12\-20" 16.0
.TH TINT2 1 "2018\-05\-03" 16.4
.SH NAME
.PP
tint2 \- lightweight panel/taskbar
@@ -343,6 +343,10 @@ Use \fB\fCpanel_monitor = all\fR to get a separate panel per monitor
\fB\fCwidth\fR and \fB\fCheight\fR can be specified without units (e.g. \fB\fC123\fR) as pixels, or followed by \fB\fC%\fR as percentages of the monitor size (e.g. \fB\fC50%\fR). Use \fB\fC100%\fR for full monitor width/height.
Example:
.RE
.IP \(bu 2
\fB\fCscale_relative_to_dpi = integer\fR : 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.
.IP \(bu 2
\fB\fCscale_relative_to_screen_height = integer\fR : Similar to \fB\fCscale_relative_to_dpi\fR, except the scaling factor is computed as the ratio between the monitor height and \fB\fCscale_relative_to_screen_height\fR\&. The effect is cumulative with \fB\fCscale_relative_to_dpi\fR, i.e. if both options are present, the factors are multiplied.
.RE
.PP
.RS

View File

@@ -1,4 +1,4 @@
# TINT2 1 "2017-12-20" 16.0
# TINT2 1 "2018-05-03" 16.4
## NAME
tint2 - lightweight panel/taskbar
@@ -279,6 +279,10 @@ gradient_id_pressed = 2
* `width` and `height` can be specified without units (e.g. `123`) as pixels, or followed by `%` as percentages of the monitor size (e.g. `50%`). Use `100%` for full monitor width/height.
Example:
* `scale_relative_to_dpi = integer` : 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.
* `scale_relative_to_screen_height = integer` : Similar to `scale_relative_to_dpi`, except the scaling factor is computed as the ratio between the monitor height and `scale_relative_to_screen_height`. The effect is cumulative with `scale_relative_to_dpi`, i.e. if both options are present, the factors are multiplied.
```
# The panel's width is 94% the size of the monitor, the height is 30 pixels:
panel_size = 94% 30

View File

@@ -4,7 +4,10 @@ SCRIPT_DIR=$(dirname "$0")
DIRTY=""
VERSION=""
if [ -d ${SCRIPT_DIR}/.git ] && git status 1>/dev/null 2>/dev/null
OLD_DIR=$(pwd)
cd ${SCRIPT_DIR}
if [ -d .git ] && git status 1>/dev/null 2>/dev/null
then
git update-index -q --ignore-submodules --refresh
# Disallow unstaged changes in the working tree
@@ -37,10 +40,10 @@ then
VERSION=$(git describe 2>/dev/null)$DIRTY
elif git log -n 1 1>/dev/null 2>/dev/null
then
VERSION=$(head -n 1 "${SCRIPT_DIR}/ChangeLog" | cut -d ' ' -f 2)
VERSION=$(head -n 1 "ChangeLog" | cut -d ' ' -f 2)
if [ "$VERSION" = "master" ]
then
PREVIOUS=$(grep '^2' "${SCRIPT_DIR}/ChangeLog" | head -n 2 | tail -n 1 | cut -d ' ' -f 2)
PREVIOUS=$(grep '^2' "ChangeLog" | head -n 2 | tail -n 1 | cut -d ' ' -f 2)
HASH=$(git log -n 1 --pretty=format:%cI.%ct.%h | tr -d ':' | tr -d '-' | tr '.' '-' | sed 's/T[0-9\+]*//g' 2>/dev/null)
VERSION=$PREVIOUS-next-$HASH
fi
@@ -49,13 +52,15 @@ fi
if [ -z "$VERSION" ]
then
VERSION=$(head -n 1 "${SCRIPT_DIR}/ChangeLog" | cut -d ' ' -f 2)
VERSION=$(head -n 1 "ChangeLog" | cut -d ' ' -f 2)
if [ "$VERSION" = "master" ]
then
VERSION=$VERSION-$(head -n 1 "${SCRIPT_DIR}/ChangeLog" | cut -d ' ' -f 1)
VERSION=$VERSION-$(head -n 1 "ChangeLog" | cut -d ' ' -f 1)
fi
fi
cd "${OLD_DIR}"
VERSION=$(echo "$VERSION" | sed 's/^v//')
echo '#define VERSION_STRING "'$VERSION'"' > version.h

View File

@@ -194,3 +194,9 @@ if __name__ == '__main__':
choice = raw_input().lower()
if choice != "y":
run("git reset --hard HEAD~ ; git tag -d %s ; git tag -d %s" % (version, readable_version))
sys.exit(1)
print "Publish? [y/n]"
choice = raw_input().lower()
if choice != "y":
sys.exit(1)
run("git push origin master && git push --tags origin master")

View File

@@ -21,7 +21,7 @@ then
exit 1
fi
rm -f version.h
VERSION=$(git describe --exact-match 2>/dev/null)
VERSION=$(false 2>/dev/null)
if [ $? -eq 0 ]
then
VERSION=$(echo "$VERSION" | sed 's/^v//')
@@ -49,7 +49,7 @@ echo "echo \"#define VERSION_STRING \\\"$VERSION\\\"\" > version.h" > $DIR/get_v
# Copy the debian files into the source directory
cp -r debian $DIR/debian
for DISTRO in trusty xenial zesty artful
for DISTRO in trusty xenial artful bionic
do
# Cleanup from previous builds
rm -rf tint2_$VERSION-*

View File

@@ -15,7 +15,7 @@ git reset --hard
git pull
~/tint2/packaging/version_status.py > packaging.tmp.md
timeout -k 10 600 ~/tint2/packaging/version_status.py > packaging.tmp.md
cat packaging.tmp.md > packaging.md
rm packaging.tmp.md

View File

@@ -367,7 +367,7 @@ def get_freebsd_versions():
def get_openbsd_versions():
print >> sys.stderr, "OpenBSD ..."
makefile = http_download_txt("http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/ports/x11/tint2/Makefile?rev=1.5&content-type=text/plain")
makefile = http_download_txt("http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/ports/x11/tint2/Makefile?content-type=text/plain")
versions = []
version = None
for line in makefile.split("\n"):

View File

@@ -41,7 +41,7 @@ struct BatteryState battery_state;
gboolean battery_enabled;
gboolean battery_tooltip_enabled;
int percentage_hide;
static timeout *battery_timeout;
static Timer battery_timer;
#define BATTERY_BUF_SIZE 256
static char buf_bat_line1[BATTERY_BUF_SIZE];
@@ -76,7 +76,7 @@ void default_battery()
percentage_hide = 101;
battery_low_cmd_sent = FALSE;
battery_full_cmd_sent = FALSE;
battery_timeout = NULL;
INIT_TIMER(battery_timer);
bat1_has_font = FALSE;
bat1_font_desc = NULL;
bat1_format = NULL;
@@ -127,8 +127,7 @@ void cleanup_battery()
ac_connected_cmd = NULL;
free(ac_disconnected_cmd);
ac_disconnected_cmd = NULL;
stop_timeout(battery_timeout);
battery_timeout = NULL;
destroy_timer(&battery_timer);
battery_found = FALSE;
battery_os_free();
@@ -226,7 +225,8 @@ void init_battery()
battery_found = battery_os_init();
battery_timeout = add_timeout(10, 30000, update_battery_tick, 0, &battery_timeout);
if (!battery_timer.enabled_)
change_timer(&battery_timer, true, 30000, 30000, update_battery_tick, 0);
update_battery();
}
@@ -273,6 +273,7 @@ void init_battery_panel(void *p)
bat1_format = strdup("%p");
bat2_format = strdup("%t");
}
update_battery_tick(NULL);
}
void battery_init_fonts()
@@ -421,6 +422,7 @@ gboolean resize_battery(void *obj)
void draw_battery(void *obj, cairo_t *c)
{
Battery *battery = (Battery *)obj;
Panel *panel = (Panel *)battery->area.panel;
draw_text_area(&battery->area,
c,
buf_bat_line1,
@@ -429,7 +431,8 @@ void draw_battery(void *obj, cairo_t *c)
bat2_font_desc,
battery->bat1_posy,
battery->bat2_posy,
&battery->font_color);
&battery->font_color,
panel->scale);
}
void battery_dump_geometry(void *obj, int indent)

View File

@@ -269,9 +269,9 @@ 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 horiz_padding = (panel_horizontal ? button->area.paddingxlr : button->area.paddingy) * panel->scale;
int vert_padding = (panel_horizontal ? button->area.paddingy : button->area.paddingxlr) * panel->scale;
int interior_padding = button->area.paddingx * panel->scale;
int icon_w, icon_h;
if (button->backend->icon_name) {
@@ -280,18 +280,17 @@ int button_compute_desired_size(void *obj)
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);
icon_w = MIN(icon_w, button->backend->max_icon_size * panel->scale);
icon_h = MIN(icon_h, button->backend->max_icon_size * panel->scale);
}
} else {
icon_h = icon_w = 0;
}
int txt_height_ink, txt_height, txt_width;
int 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,
@@ -300,10 +299,11 @@ int button_compute_desired_size(void *obj)
strlen(button->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
button->backend->centered ? PANGO_ALIGN_CENTER : PANGO_ALIGN_LEFT,
FALSE,
panel->scale);
} else {
get_text_size2(button->backend->font_desc,
&txt_height_ink,
&txt_height,
&txt_width,
panel->area.height,
@@ -313,10 +313,12 @@ int button_compute_desired_size(void *obj)
strlen(button->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
button->backend->centered ? PANGO_ALIGN_CENTER : PANGO_ALIGN_LEFT,
FALSE,
panel->scale);
}
} else {
txt_height_ink = txt_height = txt_width = 0;
txt_height = txt_width = 0;
}
if (panel_horizontal) {
@@ -336,9 +338,9 @@ gboolean resize_button(void *obj)
Button *button = (Button *)obj;
Panel *panel = (Panel *)button->area.panel;
Area *area = &button->area;
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 horiz_padding = (panel_horizontal ? button->area.paddingxlr : button->area.paddingy) * panel->scale;
int vert_padding = (panel_horizontal ? button->area.paddingy : button->area.paddingxlr) * panel->scale;
int interior_padding = button->area.paddingx * panel->scale;
int icon_w, icon_h;
if (button->backend->icon_name) {
@@ -347,8 +349,8 @@ gboolean resize_button(void *obj)
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);
icon_w = MIN(icon_w, button->backend->max_icon_size * panel->scale);
icon_h = MIN(icon_h, button->backend->max_icon_size * panel->scale);
}
} else {
icon_h = icon_w = 0;
@@ -369,10 +371,9 @@ gboolean resize_button(void *obj)
available_h = panel->area.height;
}
int txt_height_ink, txt_height, txt_width;
int txt_height, txt_width;
if (button->backend->text) {
get_text_size2(button->backend->font_desc,
&txt_height_ink,
&txt_height,
&txt_width,
available_h,
@@ -381,9 +382,11 @@ gboolean resize_button(void *obj)
strlen(button->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
button->backend->centered ? PANGO_ALIGN_CENTER : PANGO_ALIGN_LEFT,
FALSE,
panel->scale);
} else {
txt_height_ink = txt_height = txt_width = 0;
txt_height = txt_width = 0;
}
gboolean result = FALSE;
@@ -436,6 +439,7 @@ gboolean resize_button(void *obj)
void draw_button(void *obj, cairo_t *c)
{
Button *button = obj;
Panel *panel = (Panel *)button->area.panel;
if (button->frontend->icon) {
// Render icon
@@ -457,10 +461,12 @@ void draw_button(void *obj, cairo_t *c)
// Render text
if (button->backend->text) {
PangoLayout *layout = pango_cairo_create_layout(c);
PangoContext *context = pango_cairo_create_context(c);
pango_cairo_context_set_resolution(context, 96 * panel->scale);
PangoLayout *layout = pango_layout_new(context);
pango_layout_set_font_description(layout, button->backend->font_desc);
pango_layout_set_width(layout, button->frontend->textw * PANGO_SCALE);
pango_layout_set_width(layout, (button->frontend->textw + TINT2_PANGO_SLACK) * 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);
@@ -475,6 +481,7 @@ void draw_button(void *obj, cairo_t *c)
panel_config.font_shadow);
g_object_unref(layout);
g_object_unref(context);
}
}

View File

@@ -51,7 +51,7 @@ static char buf_time[256];
static char buf_date[256];
static char buf_tooltip[512];
int clock_enabled;
static timeout *clock_timeout;
static Timer clock_timer;
void clock_init_fonts();
char *clock_get_tooltip(void *obj);
@@ -61,11 +61,11 @@ void clock_dump_geometry(void *obj, int indent);
void default_clock()
{
clock_enabled = 0;
clock_timeout = NULL;
time1_format = NULL;
time1_timezone = NULL;
time2_format = NULL;
time2_timezone = NULL;
INIT_TIMER(clock_timer);
time_tooltip_format = NULL;
time_tooltip_timezone = NULL;
clock_lclick_command = NULL;
@@ -110,8 +110,7 @@ void cleanup_clock()
clock_uwheel_command = NULL;
free(clock_dwheel_command);
clock_dwheel_command = NULL;
stop_timeout(clock_timeout);
clock_timeout = NULL;
destroy_timer(&clock_timer);
}
struct tm *clock_gettime_for_tz(const char *timezone)
@@ -155,7 +154,7 @@ void update_clocks_sec(void *arg)
{
gettimeofday(&time_clock, 0);
update_clocks();
clock_timeout = add_timeout(ms_until_second_change(&time_clock), 0, update_clocks_sec, 0, &clock_timeout);
change_timer(&clock_timer, true, ms_until_second_change(&time_clock), 0, update_clocks_sec, 0);
}
void update_clocks_min(void *arg)
@@ -167,7 +166,7 @@ void update_clocks_min(void *arg)
if (time_clock.tv_sec % 60 == 0 || time_clock.tv_sec - old_sec > 60 || (time1_format && !buf_time[0]) || (time2_format && !buf_date[0]))
update_clocks();
old_sec = time_clock.tv_sec;
clock_timeout = add_timeout(ms_until_second_change(&time_clock), 0, update_clocks_min, 0, &clock_timeout);
change_timer(&clock_timer, true, ms_until_second_change(&time_clock), 0, update_clocks_min, 0);
}
gboolean time_format_needs_sec_ticks(char *time_format)
@@ -216,7 +215,7 @@ void init_clock_panel(void *p)
strftime(buf_tooltip, sizeof(buf_tooltip), time_tooltip_format, clock_gettime_for_tz(time_tooltip_timezone));
}
if (!clock_timeout) {
if (!clock_timer.enabled_) {
if (time_format_needs_sec_ticks(time1_format) || time_format_needs_sec_ticks(time2_format)) {
update_clocks_sec(NULL);
} else {
@@ -262,10 +261,8 @@ void clock_default_font_changed()
}
void clock_compute_text_geometry(Clock *clock,
int *time_height_ink,
int *time_height,
int *time_width,
int *date_height_ink,
int *date_height,
int *date_width)
{
@@ -274,10 +271,8 @@ void clock_compute_text_geometry(Clock *clock,
time2_format ? buf_date : NULL,
time1_font_desc,
time2_font_desc,
time_height_ink,
time_height,
time_width,
date_height_ink,
date_height,
date_width);
}
@@ -307,6 +302,7 @@ gboolean resize_clock(void *obj)
void draw_clock(void *obj, cairo_t *c)
{
Clock *clock = (Clock *)obj;
Panel *panel = (Panel *)clock->area.panel;
draw_text_area(&clock->area,
c,
buf_time,
@@ -315,7 +311,8 @@ void draw_clock(void *obj, cairo_t *c)
time2_font_desc,
clock->time1_posy,
clock->time2_posy,
&clock->font);
&clock->font,
panel->scale);
}
void clock_dump_geometry(void *obj, int indent)

View File

@@ -244,7 +244,11 @@ void add_entry(char *key, char *value)
char *value1 = 0, *value2 = 0, *value3 = 0;
/* Background and border */
if (strcmp(key, "rounded") == 0) {
if (strcmp(key, "scale_relative_to_dpi") == 0) {
ui_scale_dpi_ref = atof(value);
} else if (strcmp(key, "scale_relative_to_screen_height") == 0) {
ui_scale_monitor_size_ref = atof(value);
} else if (strcmp(key, "rounded") == 0) {
// 'rounded' is the first parameter => alloc a new background
if (backgrounds->len > 0) {
Background *bg = &g_array_index(backgrounds, Background, backgrounds->len - 1);

5
src/default_icon.c Normal file

File diff suppressed because one or more lines are too long

10
src/default_icon.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef default_icon_h
#define default_icon_h
#include <Imlib2.h>
extern int default_icon_width;
extern int default_icon_height;
extern DATA32 default_icon_data[];
#endif

View File

@@ -20,6 +20,8 @@
#define MAX_TOOLTIP_LEN 4096
bool debug_executors = false;
void execp_timer_callback(void *arg);
char *execp_get_tooltip(void *obj);
void execp_init_fonts();
@@ -41,6 +43,7 @@ Execp *create_execp()
execp->backend->cache_icon = TRUE;
execp->backend->centered = TRUE;
execp->backend->font_color.alpha = 0.5;
INIT_TIMER(execp->backend->timer);
return execp;
}
@@ -67,8 +70,7 @@ void destroy_execp(void *obj)
free_and_null(execp);
} else {
// This is a backend element
stop_timeout(execp->backend->timer);
execp->backend->timer = NULL;
destroy_timer(&execp->backend->timer);
free_icon(execp->backend->icon);
free_and_null(execp->backend->buf_stdout);
@@ -192,7 +194,7 @@ void init_execp_panel(void *p)
execp->area.on_screen = TRUE;
instantiate_area_gradients(&execp->area);
execp->backend->timer = add_timeout(10, 0, execp_timer_callback, execp, &execp->backend->timer);
change_timer(&execp->backend->timer, true, 10, 0, execp_timer_callback, execp);
execp_update_post_read(execp);
}
@@ -304,7 +306,6 @@ void execp_compute_icon_text_geometry(Execp *execp,
int *icon_w,
int *icon_h,
gboolean *text_next_line,
int *txt_height_ink,
int *txt_height,
int *txt_width,
int *new_size,
@@ -312,9 +313,9 @@ void execp_compute_icon_text_geometry(Execp *execp,
{
Panel *panel = (Panel *)execp->area.panel;
Area *area = &execp->area;
*horiz_padding = (panel_horizontal ? area->paddingxlr : area->paddingy);
*vert_padding = (panel_horizontal ? area->paddingy : area->paddingxlr);
*interior_padding = area->paddingx;
*horiz_padding = (panel_horizontal ? area->paddingxlr : area->paddingy) * panel->scale;
*vert_padding = (panel_horizontal ? area->paddingy : area->paddingxlr) * panel->scale;
*interior_padding = area->paddingx * panel->scale;
if (reload_icon(execp)) {
if (execp->backend->icon) {
@@ -333,7 +334,7 @@ void execp_compute_icon_text_geometry(Execp *execp,
int available_w, available_h;
if (panel_horizontal) {
available_w = panel->area.width;
available_h = area->height - 2 * area->paddingy - left_right_border_width(area);
available_h = area->height - 2 * *vert_padding - left_right_border_width(area);
} else {
available_w = !text_next_line
? area->width - *icon_w - (*icon_w ? *interior_padding : 0) - 2 * *horiz_padding -
@@ -342,7 +343,6 @@ void execp_compute_icon_text_geometry(Execp *execp,
available_h = panel->area.height;
}
get_text_size2(execp->backend->font_desc,
txt_height_ink,
txt_height,
txt_width,
available_h,
@@ -351,7 +351,9 @@ void execp_compute_icon_text_geometry(Execp *execp,
strlen(execp->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
execp->backend->has_markup);
execp->backend->centered ? PANGO_ALIGN_CENTER : PANGO_ALIGN_LEFT,
execp->backend->has_markup,
panel->scale);
*resized = FALSE;
if (panel_horizontal) {
@@ -385,7 +387,7 @@ int execp_compute_desired_size(void *obj)
int horiz_padding, vert_padding, interior_padding;
int icon_w, icon_h;
gboolean text_next_line;
int txt_height_ink, txt_height, txt_width;
int txt_height, txt_width;
int new_size;
gboolean resized;
execp_compute_icon_text_geometry(execp,
@@ -395,7 +397,6 @@ int execp_compute_desired_size(void *obj)
&icon_w,
&icon_h,
&text_next_line,
&txt_height_ink,
&txt_height,
&txt_width,
&new_size,
@@ -410,7 +411,7 @@ gboolean resize_execp(void *obj)
int horiz_padding, vert_padding, interior_padding;
int icon_w, icon_h;
gboolean text_next_line;
int txt_height_ink, txt_height, txt_width;
int txt_height, txt_width;
int new_size;
gboolean resized;
execp_compute_icon_text_geometry(execp,
@@ -420,7 +421,6 @@ gboolean resize_execp(void *obj)
&icon_w,
&icon_h,
&text_next_line,
&txt_height_ink,
&txt_height,
&txt_width,
&new_size,
@@ -476,7 +476,11 @@ gboolean resize_execp(void *obj)
void draw_execp(void *obj, cairo_t *c)
{
Execp *execp = (Execp *)obj;
PangoLayout *layout = pango_cairo_create_layout(c);
Panel *panel = (Panel *)execp->area.panel;
PangoContext *context = pango_cairo_create_context(c);
pango_cairo_context_set_resolution(context, 96 * panel->scale);
PangoLayout *layout = pango_layout_new(context);
if (execp->backend->has_icon && execp->backend->icon) {
imlib_context_set_image(execp->backend->icon);
@@ -486,7 +490,8 @@ void draw_execp(void *obj, cairo_t *c)
// draw layout
pango_layout_set_font_description(layout, execp->backend->font_desc);
pango_layout_set_width(layout, execp->frontend->textw * PANGO_SCALE);
pango_layout_set_width(layout, (execp->frontend->textw + TINT2_PANGO_SLACK) * PANGO_SCALE);
pango_layout_set_height(layout, (execp->frontend->texth + TINT2_PANGO_SLACK) * PANGO_SCALE);
pango_layout_set_alignment(layout, execp->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);
@@ -504,6 +509,7 @@ void draw_execp(void *obj, cairo_t *c)
panel_config.font_shadow);
g_object_unref(layout);
g_object_unref(context);
}
void execp_dump_geometry(void *obj, int indent)
@@ -540,10 +546,8 @@ void execp_force_update(Execp *execp)
if (execp->backend->child_pipe_stdout > 0) {
// Command currently running, nothing to do
} else {
if (execp->backend->timer)
stop_timeout(execp->backend->timer);
// Run command right away
execp->backend->timer = add_timeout(10, 0, execp_timer_callback, execp, &execp->backend->timer);
change_timer(&execp->backend->timer, true, 10, 0, execp_timer_callback, execp);
}
}
@@ -633,7 +637,8 @@ void execp_timer_callback(void *arg)
close(pipe_fd_stderr[0]);
return;
} else if (child == 0) {
fprintf(stderr, "tint2: Executing: %s\n", execp->backend->command);
if (debug_executors)
fprintf(stderr, "tint2: Executing: %s\n", execp->backend->command);
// We are in the child
close(pipe_fd_stdout[0]);
dup2(pipe_fd_stdout[1], 1); // 1 is stdout
@@ -757,8 +762,7 @@ gboolean read_execp(void *obj)
close(execp->backend->child_pipe_stderr);
execp->backend->child_pipe_stderr = -1;
if (execp->backend->interval)
execp->backend->timer =
add_timeout(execp->backend->interval * 1000, 0, execp_timer_callback, execp, &execp->backend->timer);
change_timer(&execp->backend->timer, true, execp->backend->interval * 1000, 0, execp_timer_callback, execp);
}
char *ansi_clear_screen = (char*)"\x1b[2J";
@@ -882,22 +886,22 @@ gboolean read_execp(void *obj)
return FALSE;
}
const char *time_to_string(int seconds, char *buffer)
const char *time_to_string(int seconds, char *buffer, size_t buffer_size)
{
if (seconds < 60) {
sprintf(buffer, "%ds", seconds);
snprintf(buffer, buffer_size, "%ds", seconds);
} else if (seconds < 60 * 60) {
int m = seconds / 60;
seconds = seconds % 60;
int s = seconds;
sprintf(buffer, "%d:%ds", m, s);
snprintf(buffer, buffer_size, "%d:%ds", m, s);
} else {
int h = seconds / (60 * 60);
seconds = seconds % (60 * 60);
int m = seconds / 60;
seconds = seconds % 60;
int s = seconds;
sprintf(buffer, "%d:%d:%ds", h, m, s);
snprintf(buffer, buffer_size, "%d:%d:%ds", h, m, s);
}
return buffer;
}
@@ -923,35 +927,39 @@ char *execp_get_tooltip(void *obj)
if (execp->backend->last_update_finish_time) {
// We updated at least once
if (execp->backend->interval > 0) {
sprintf(execp->backend->tooltip_text,
"Last update finished %s ago (took %s). Next update starting in %s.",
time_to_string((int)(now - execp->backend->last_update_finish_time), tmp_buf1),
time_to_string((int)execp->backend->last_update_duration, tmp_buf2),
time_to_string((int)(execp->backend->interval - (now - execp->backend->last_update_finish_time)),
tmp_buf3));
snprintf(execp->backend->tooltip_text,
sizeof(execp->backend->tooltip_text),
"Last update finished %s ago (took %s). Next update starting in %s.",
time_to_string((int)(now - execp->backend->last_update_finish_time), tmp_buf1, sizeof(tmp_buf1)),
time_to_string((int)execp->backend->last_update_duration, tmp_buf2, sizeof(tmp_buf2)),
time_to_string((int)(execp->backend->interval - (now - execp->backend->last_update_finish_time)),
tmp_buf3, sizeof(tmp_buf3)));
} else {
sprintf(execp->backend->tooltip_text,
"Last update finished %s ago (took %s).",
time_to_string((int)(now - execp->backend->last_update_finish_time), tmp_buf1),
time_to_string((int)execp->backend->last_update_duration, tmp_buf2));
snprintf(execp->backend->tooltip_text,
sizeof(execp->backend->tooltip_text),
"Last update finished %s ago (took %s).",
time_to_string((int)(now - execp->backend->last_update_finish_time), tmp_buf1, sizeof(tmp_buf1)),
time_to_string((int)execp->backend->last_update_duration, tmp_buf2, sizeof(tmp_buf2)));
}
} else {
// we never requested an update
sprintf(execp->backend->tooltip_text, "Never updated. No update scheduled.");
snprintf(execp->backend->tooltip_text, sizeof(execp->backend->tooltip_text), "Never updated. No update scheduled.");
}
} else {
// Currently executing command
if (execp->backend->last_update_finish_time) {
// we finished updating at least once
sprintf(execp->backend->tooltip_text,
"Last update finished %s ago. Update in progress (started %s ago).",
time_to_string((int)(now - execp->backend->last_update_finish_time), tmp_buf1),
time_to_string((int)(now - execp->backend->last_update_start_time), tmp_buf3));
snprintf(execp->backend->tooltip_text,
sizeof(execp->backend->tooltip_text),
"Last update finished %s ago. Update in progress (started %s ago).",
time_to_string((int)(now - execp->backend->last_update_finish_time), tmp_buf1, sizeof(tmp_buf1)),
time_to_string((int)(now - execp->backend->last_update_start_time), tmp_buf3, sizeof(tmp_buf3)));
} else {
// we never finished an update
sprintf(execp->backend->tooltip_text,
"First update in progress (started %s seconds ago).",
time_to_string((int)(now - execp->backend->last_update_start_time), tmp_buf1));
snprintf(execp->backend->tooltip_text,
sizeof(execp->backend->tooltip_text),
"First update in progress (started %s seconds ago).",
time_to_string((int)(now - execp->backend->last_update_start_time), tmp_buf1, sizeof(tmp_buf1)));
}
}
return strdup(execp->backend->tooltip_text);

View File

@@ -8,6 +8,8 @@
#include "common.h"
#include "timer.h"
extern bool debug_executors;
// Architecture:
// Panel panel_config contains an array of Execp, each storing all config options and all the state variables.
// Only these run commands.
@@ -46,7 +48,7 @@ typedef struct ExecpBackend {
Background *bg;
// Backend state:
timeout *timer;
Timer timer;
int child_pipe_stdout;
int child_pipe_stderr;
pid_t child;

View File

@@ -65,14 +65,14 @@ void cleanup_freespace(Panel *panel)
panel->freespace_list = NULL;
}
int freespace_get_max_size(Panel *p)
int freespace_get_max_size(Panel *panel)
{
if (panel_shrink)
return 0;
// Get space used by every element except the freespace
int size = 0;
int spacers = 0;
for (GList *walk = p->area.children; walk; walk = g_list_next(walk)) {
for (GList *walk = panel->area.children; walk; walk = g_list_next(walk)) {
Area *a = (Area *)walk->data;
if (!a->on_screen)
@@ -83,15 +83,15 @@ int freespace_get_max_size(Panel *p)
}
if (panel_horizontal)
size += a->width + p->area.paddingx;
size += a->width + panel->area.paddingx * panel->scale;
else
size += a->height + p->area.paddingy;
size += a->height + panel->area.paddingy * panel->scale;
}
if (panel_horizontal)
size = p->area.width - size - left_right_border_width(&p->area) - p->area.paddingxlr;
size = panel->area.width - size - left_right_border_width(&panel->area) - panel->area.paddingxlr * panel->scale;
else
size = p->area.height - size - top_bottom_border_width(&p->area) - p->area.paddingxlr;
size = panel->area.height - size - top_bottom_border_width(&panel->area) - panel->area.paddingxlr * panel->scale;
return size / spacers;
}

View File

@@ -12,6 +12,7 @@
#include <X11/extensions/XShm.h>
#include "config.h"
#include "default_icon.h"
#include "drag_and_drop.h"
#include "fps_distribution.h"
#include "panel.h"
@@ -50,7 +51,13 @@ void handle_cli_arguments(int argc, char **argv)
fprintf(stdout, "tint2 version %s\n", VERSION_STRING);
exit(0);
} else if (strcmp(argv[i], "--test") == 0) {
run_all_tests();
run_all_tests(false);
exit(0);
} else if (strcmp(argv[i], "--test-verbose") == 0) {
run_all_tests(true);
exit(0);
} else if (strcmp(argv[i], "--dump-image-data") == 0) {
dump_image_data(argv[i+1], argv[i+2]);
exit(0);
} else if (strcmp(argv[i], "-c") == 0) {
if (i + 1 < argc) {
@@ -98,6 +105,8 @@ void handle_env_vars()
debug_frames = getenv("DEBUG_FRAMES") != NULL;
debug_dnd = getenv("DEBUG_DND") != NULL;
debug_thumbnails = getenv("DEBUG_THUMBNAILS") != NULL;
debug_timers = getenv("DEBUG_TIMERS") != NULL;
debug_executors = getenv("DEBUG_EXECUTORS") != NULL;
if (debug_fps) {
init_fps_distribution();
char *s = getenv("TRACING_FPS_THRESHOLD");
@@ -107,25 +116,25 @@ void handle_env_vars()
}
}
static timeout *detect_compositor_timer = NULL;
static Timer detect_compositor_timer = DEFAULT_TIMER;
static int detect_compositor_timer_counter = 0;
void detect_compositor(void *arg)
{
if (server.composite_manager) {
stop_timeout(detect_compositor_timer);
stop_timer(&detect_compositor_timer);
return;
}
detect_compositor_timer_counter--;
if (detect_compositor_timer_counter < 0) {
stop_timeout(detect_compositor_timer);
stop_timer(&detect_compositor_timer);
return;
}
// No compositor, check for one
if (XGetSelectionOwner(server.display, server.atom._NET_WM_CM_S0) != None) {
stop_timeout(detect_compositor_timer);
stop_timer(&detect_compositor_timer);
// Restart tint2
fprintf(stderr, "tint2: Detected compositor, restarting tint2...\n");
kill(getpid(), SIGUSR1);
@@ -138,15 +147,15 @@ void start_detect_compositor()
if (server.composite_manager)
return;
stop_timeout(detect_compositor_timer);
// Check every 0.5 seconds for up to 30 seconds
detect_compositor_timer_counter = 60;
detect_compositor_timer = add_timeout(500, 500, detect_compositor, 0, &detect_compositor_timer);
INIT_TIMER(detect_compositor_timer);
change_timer(&detect_compositor_timer, true, 500, 500, detect_compositor, 0);
}
void create_default_elements()
{
default_timeout();
default_timers();
default_systray();
memset(&server, 0, sizeof(server));
#ifdef ENABLE_BATTERY
@@ -161,6 +170,22 @@ void create_default_elements()
default_panel();
}
void load_default_task_icon()
{
const gchar *const *data_dirs = g_get_system_data_dirs();
for (int i = 0; data_dirs[i] != NULL; i++) {
gchar *path = g_build_filename(data_dirs[i], "tint2", "default_icon.png", NULL);
if (g_file_test(path, G_FILE_TEST_EXISTS))
default_icon = load_image(path, TRUE);
g_free(path);
}
if (!default_icon) {
default_icon = imlib_create_image_using_data(default_icon_width,
default_icon_height,
default_icon_data);
}
}
void init_post_config()
{
server_init_visual();
@@ -171,20 +196,7 @@ void init_post_config()
imlib_context_set_colormap(server.colormap);
init_signals_postconfig();
// load default icon
const gchar *const *data_dirs = g_get_system_data_dirs();
for (int i = 0; data_dirs[i] != NULL; i++) {
gchar *path = g_build_filename(data_dirs[i], "tint2", "default_icon.png", NULL);
if (g_file_test(path, G_FILE_TEST_EXISTS))
default_icon = load_image(path, TRUE);
g_free(path);
}
if (!default_icon) {
fprintf(stderr,
RED "Could not load default_icon.png. Please check that tint2 has been installed correctly!" RESET
"\n");
}
load_default_task_icon();
XSync(server.display, False);
}
@@ -226,10 +238,10 @@ void init(int argc, char **argv)
setlinebuf(stdout);
setlinebuf(stderr);
default_config();
handle_env_vars();
handle_cli_arguments(argc, argv);
create_default_elements();
init_signals();
handle_env_vars();
init_X11_pre_config();
if (!config_read()) {
@@ -263,6 +275,7 @@ void cleanup()
cleanup_battery();
#endif
cleanup_separator();
cleanup_taskbar();
cleanup_panel();
cleanup_config();
@@ -277,7 +290,7 @@ void cleanup()
xsettings_client = NULL;
cleanup_server();
cleanup_timeout();
cleanup_timers();
if (server.display)
XCloseDisplay(server.display);

View File

@@ -60,9 +60,9 @@ void expand_exec(DesktopEntry *entry, const char *path)
// %c -> Name
// %k -> path
if (entry->exec) {
char *exec2 = calloc(strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) +
(entry->icon ? strlen(entry->icon) : 1) + 100,
1);
size_t buf_size = strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) +
(entry->icon ? strlen(entry->icon) : 1) + 100;
char *exec2 = calloc(buf_size, 1);
char *p, *q;
// p will never point to an escaped char
for (p = entry->exec, q = exec2; *p; p++, q++) {
@@ -82,23 +82,30 @@ void expand_exec(DesktopEntry *entry, const char *path)
if (!*p)
break;
if (*p == 'i' && entry->icon != NULL) {
sprintf(q, "--icon '%s'", entry->icon);
snprintf(q, buf_size, "--icon '%s'", entry->icon);
char *old = q;
q += strlen("--icon ''");
q += strlen(entry->icon);
buf_size -= (size_t)(q - old);
q--; // To balance the q++ in the for
} else if (*p == 'c' && entry->name != NULL) {
sprintf(q, "'%s'", entry->name);
snprintf(q, buf_size, "'%s'", entry->name);
char *old = q;
q += strlen("''");
q += strlen(entry->name);
buf_size -= (size_t)(q - old);
q--; // To balance the q++ in the for
} else if (*p == 'c') {
sprintf(q, "'%s'", path);
snprintf(q, buf_size, "'%s'", path);
char *old = q;
q += strlen("''");
q += strlen(path);
buf_size -= (size_t)(q - old);
q--; // To balance the q++ in the for
} else if (*p == 'f' || *p == 'F') {
sprintf(q, "%c%c", '%', *p);
snprintf(q, buf_size, "%c%c", '%', *p);
q += 2;
buf_size -= 2;
q--; // To balance the q++ in the for
} else {
// We don't care about other expansions

View File

@@ -48,7 +48,7 @@ int parse_theme_line(char *line, char **key, char **value)
return parse_dektop_line(line, key, value);
}
GSList *icon_locations = NULL;
static GSList *icon_locations = NULL;
// Do not free the result.
const GSList *get_icon_locations()
{
@@ -74,6 +74,21 @@ const GSList *get_icon_locations()
return icon_locations;
}
static GSList *icon_extensions = NULL;
const GSList *get_icon_extensions()
{
if (icon_extensions)
return icon_extensions;
icon_extensions = g_slist_append(icon_extensions, ".png");
icon_extensions = g_slist_append(icon_extensions, ".xpm");
#ifdef HAVE_RSVG
icon_extensions = g_slist_append(icon_extensions, ".svg");
#endif
icon_extensions = g_slist_append(icon_extensions, "");
return icon_extensions;
}
IconTheme *make_theme(const char *name)
{
IconTheme *theme = calloc(1, sizeof(IconTheme));
@@ -535,41 +550,42 @@ gint compare_theme_directories(gconstpointer a, gconstpointer b, gpointer size_q
return abs(da->size - size) - abs(db->size - size);
}
Bool is_full_path(const char *s)
{
if (!s)
return FALSE;
return s[0] == '/';
}
Bool file_exists(const char *path)
{
return g_file_test(path, G_FILE_TEST_EXISTS);
}
char *icon_path_from_full_path(const char *s)
{
if (is_full_path(s) && file_exists(s))
return strdup(s);
return NULL;
}
char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
{
if (icon_name == NULL)
if (!icon_name)
return NULL;
// If the icon_name is already a path and the file exists, return it
if (strstr(icon_name, "/") == icon_name) {
if (g_file_test(icon_name, G_FILE_TEST_EXISTS))
return strdup(icon_name);
else
return NULL;
}
char *result = icon_path_from_full_path(icon_name);
if (result)
return result;
const GSList *basenames = get_icon_locations();
GSList *extensions = NULL;
extensions = g_slist_append(extensions, ".png");
extensions = g_slist_append(extensions, ".xpm");
#ifdef HAVE_RSVG
extensions = g_slist_append(extensions, ".svg");
#endif
// if the icon name already contains one of the extensions (e.g. vlc.png instead of vlc) add a special entry
for (GSList *ext = extensions; ext; ext = g_slist_next(ext)) {
char *extension = (char *)ext->data;
if (strlen(icon_name) > strlen(extension) &&
strcmp(extension, icon_name + strlen(icon_name) - strlen(extension)) == 0) {
extensions = g_slist_append(extensions, "");
break;
}
}
const GSList *extensions = get_icon_extensions();
GSList *theme;
// Best size match
// Contrary to the freedesktop spec, we are not choosing the closest icon in size, but the next larger icon
// otherwise the quality is usually crap (for size 22, if you can choose 16 or 32, you're better with 32)
// otherwise the quality is worse when scaling up (for size 22, if you can choose 16 or 32, you're better with 32)
// We do fallback to the closest size if we cannot find a larger or equal icon
// These 3 variables are used for keeping the closest size match
@@ -582,7 +598,7 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
char *next_larger = NULL;
GSList *next_larger_theme = NULL;
int file_name_size = 4096;
size_t file_name_size = 4096;
char *file_name = calloc(file_name_size, 1);
for (theme = themes; theme; theme = g_slist_next(theme)) {
@@ -607,7 +623,7 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
fprintf(stderr, "tint2: Searching directory: %s\n", ((IconThemeDir *)dir->data)->name);
const GSList *base;
for (base = basenames; base; base = g_slist_next(base)) {
for (GSList *ext = extensions; ext; ext = g_slist_next(ext)) {
for (const GSList *ext = extensions; ext; ext = g_slist_next(ext)) {
char *base_name = (char *)base->data;
char *theme_name = ((IconTheme *)theme->data)->name;
char *dir_name = ((IconThemeDir *)dir->data)->name;
@@ -621,7 +637,7 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
}
file_name[0] = 0;
// filename = directory/$(themename)/subdirectory/iconname.extension
sprintf(file_name, "%s/%s/%s/%s%s", base_name, theme_name, dir_name, icon_name, extension);
snprintf(file_name, (size_t)file_name_size, "%s/%s/%s/%s%s", base_name, theme_name, dir_name, icon_name, extension);
if (debug_icons)
fprintf(stderr, "tint2: Checking %s\n", file_name);
if (g_file_test(file_name, G_FILE_TEST_EXISTS)) {
@@ -662,12 +678,10 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
free(file_name);
file_name = NULL;
if (next_larger) {
g_slist_free(extensions);
free(best_file_name);
return next_larger;
}
if (best_file_name) {
g_slist_free(extensions);
return best_file_name;
}
@@ -676,18 +690,18 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
if (debug_icons)
fprintf(stderr, "tint2: Searching unthemed icons\n");
for (const GSList *base = basenames; base; base = g_slist_next(base)) {
for (GSList *ext = extensions; ext; ext = g_slist_next(ext)) {
for (const GSList *ext = extensions; ext; ext = g_slist_next(ext)) {
char *base_name = (char *)base->data;
char *extension = (char *)ext->data;
file_name = calloc(strlen(base_name) + strlen(icon_name) + strlen(extension) + 100, 1);
size_t file_name_size2 = strlen(base_name) + strlen(icon_name) + strlen(extension) + 100;
file_name = calloc(file_name_size2, 1);
// filename = directory/iconname.extension
sprintf(file_name, "%s/%s%s", base_name, icon_name, extension);
snprintf(file_name, file_name_size2, "%s/%s%s", base_name, icon_name, extension);
if (debug_icons)
fprintf(stderr, "tint2: Checking %s\n", file_name);
if (g_file_test(file_name, G_FILE_TEST_EXISTS)) {
if (debug_icons)
fprintf(stderr, "tint2: Found %s\n", file_name);
g_slist_free(extensions);
return file_name;
} else {
free(file_name);
@@ -697,7 +711,6 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
}
}
g_slist_free(extensions);
return NULL;
}

View File

@@ -112,7 +112,7 @@ void init_launcher_panel(void *p)
return;
// This will be recomputed on resize, we just initialize to a non-zero value
launcher->icon_size = launcher_max_icon_size > 0 ? launcher_max_icon_size : 24;
launcher->icon_size = launcher_max_icon_size > 0 ? launcher_max_icon_size * panel->scale : 24;
launcher->area.on_screen = TRUE;
schedule_panel_redraw();
@@ -174,11 +174,12 @@ void cleanup_launcher_theme(Launcher *launcher)
int launcher_compute_icon_size(Launcher *launcher)
{
Panel *panel = launcher->area.panel;
int icon_size = panel_horizontal ? launcher->area.height : launcher->area.width;
icon_size = icon_size - MAX(left_right_border_width(&launcher->area), top_bottom_border_width(&launcher->area)) -
(2 * launcher->area.paddingy);
if (launcher_max_icon_size > 0 && icon_size > launcher_max_icon_size)
icon_size = launcher_max_icon_size;
(2 * launcher->area.paddingy * panel->scale);
if (launcher_max_icon_size)
icon_size = MIN(icon_size, launcher_max_icon_size * panel->scale);
return icon_size;
}
@@ -189,6 +190,7 @@ void launcher_compute_geometry(Launcher *launcher,
int *icons_per_row,
int *margin)
{
Panel *panel = (Panel*)launcher->area.panel;
int count = 0;
for (GSList *l = launcher->list_icons; l; l = l->next) {
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
@@ -204,25 +206,25 @@ void launcher_compute_geometry(Launcher *launcher,
if (!count) {
*size = 0;
} else {
int height = launcher->area.height - top_bottom_border_width(&launcher->area) - 2 * launcher->area.paddingy;
int height = launcher->area.height - top_bottom_border_width(&launcher->area) - 2 * launcher->area.paddingy * panel->scale;
// here icons_per_column always higher than 0
*icons_per_column = (height + launcher->area.paddingx) / (*icon_size + launcher->area.paddingx);
*margin = height - (*icons_per_column - 1) * (*icon_size + launcher->area.paddingx) - *icon_size;
*icons_per_column = (height + launcher->area.paddingx * panel->scale) / (*icon_size + launcher->area.paddingx * panel->scale);
*margin = height - (*icons_per_column - 1) * (*icon_size + launcher->area.paddingx * panel->scale) - *icon_size;
*icons_per_row = count / *icons_per_column + (count % *icons_per_column != 0);
*size = left_right_border_width(&launcher->area) + 2 * launcher->area.paddingxlr +
(*icon_size * *icons_per_row) + ((*icons_per_row - 1) * launcher->area.paddingx);
*size = left_right_border_width(&launcher->area) + 2 * launcher->area.paddingxlr * panel->scale +
(*icon_size * *icons_per_row) + ((*icons_per_row - 1) * launcher->area.paddingx * panel->scale);
}
} else {
if (!count) {
*size = 0;
} else {
int width = launcher->area.width - top_bottom_border_width(&launcher->area) - 2 * launcher->area.paddingy;
int width = launcher->area.width - top_bottom_border_width(&launcher->area) - 2 * launcher->area.paddingy * panel->scale;
// here icons_per_row always higher than 0
*icons_per_row = (width + launcher->area.paddingx) / (*icon_size + launcher->area.paddingx);
*margin = width - (*icons_per_row - 1) * (*icon_size + launcher->area.paddingx) - *icon_size;
*icons_per_row = (width + launcher->area.paddingx * panel->scale) / (*icon_size + launcher->area.paddingx * panel->scale);
*margin = width - (*icons_per_row - 1) * (*icon_size + launcher->area.paddingx * panel->scale) - *icon_size;
*icons_per_column = count / *icons_per_row + (count % *icons_per_row != 0);
*size = top_bottom_border_width(&launcher->area) + 2 * launcher->area.paddingxlr +
(*icon_size * *icons_per_column) + ((*icons_per_column - 1) * launcher->area.paddingx);
*size = top_bottom_border_width(&launcher->area) + 2 * launcher->area.paddingxlr * panel->scale +
(*icon_size * *icons_per_column) + ((*icons_per_column - 1) * launcher->area.paddingx * panel->scale);
}
}
}
@@ -239,6 +241,7 @@ int launcher_compute_desired_size(void *obj)
gboolean resize_launcher(void *obj)
{
Launcher *launcher = (Launcher *)obj;
Panel *panel = (Panel*)launcher->area.panel;
int size, icons_per_column, icons_per_row, margin;
launcher_compute_geometry(launcher, &size, &launcher->icon_size, &icons_per_column, &icons_per_row, &margin);
@@ -281,11 +284,11 @@ gboolean resize_launcher(void *obj)
int posx, posy;
int start;
if (panel_horizontal) {
posy = start = top_border_width(&launcher->area) + launcher->area.paddingy + margin / 2;
posx = left_border_width(&launcher->area) + launcher->area.paddingxlr;
posy = start = top_border_width(&launcher->area) + launcher->area.paddingy * panel->scale + margin / 2;
posx = left_border_width(&launcher->area) + launcher->area.paddingxlr * panel->scale;
} else {
posx = start = left_border_width(&launcher->area) + launcher->area.paddingy + margin / 2;
posy = top_border_width(&launcher->area) + launcher->area.paddingxlr;
posx = start = left_border_width(&launcher->area) + launcher->area.paddingy * panel->scale + margin / 2;
posy = top_border_width(&launcher->area) + launcher->area.paddingxlr * panel->scale;
}
int i = 0;
@@ -300,17 +303,17 @@ gboolean resize_launcher(void *obj)
// fprintf(stderr, "tint2: launcher %d : %d,%d\n", i, posx, posy);
if (panel_horizontal) {
if (i % icons_per_column) {
posy += launcher->icon_size + launcher->area.paddingx;
posy += launcher->icon_size + launcher->area.paddingx * panel->scale;
} else {
posy = start;
posx += (launcher->icon_size + launcher->area.paddingx);
posx += (launcher->icon_size + launcher->area.paddingx * panel->scale);
}
} else {
if (i % icons_per_row) {
posx += launcher->icon_size + launcher->area.paddingx;
posx += launcher->icon_size + launcher->area.paddingx * panel->scale;
} else {
posx = start;
posy += (launcher->icon_size + launcher->area.paddingx);
posy += (launcher->icon_size + launcher->area.paddingx * panel->scale);
}
}
}
@@ -470,7 +473,7 @@ void launcher_load_icons(Launcher *launcher)
launcherIcon->area.size_mode = LAYOUT_FIXED;
launcherIcon->area._resize = NULL;
launcherIcon->area._compute_desired_size = launcher_icon_compute_desired_size;
sprintf(launcherIcon->area.name, "LauncherIcon %d", index);
snprintf(launcherIcon->area.name, sizeof(launcherIcon->area.name), "LauncherIcon %d", index);
launcherIcon->area.resize_needed = 0;
launcherIcon->area.has_mouse_over_effect = panel_config.mouse_effects;
launcherIcon->area.has_mouse_press_effect = launcherIcon->area.has_mouse_over_effect;

View File

@@ -723,7 +723,7 @@ void handle_panel_refresh()
if (debug_frames) {
for (int i = 0; i < num_panels; i++) {
char path[256];
sprintf(path, "tint2-%d-panel-%d-frame-%d.png", getpid(), i, frame);
snprintf(path, sizeof(path), "tint2-%d-panel-%d-frame-%d.png", getpid(), i, frame);
save_panel_screenshot(&panels[i], path);
}
}
@@ -748,7 +748,7 @@ void run_tint2_event_loop()
// Wait for an event and handle it
ts_event_read = 0;
if (XPending(server.display) > 0 || select(max_fd + 1, &fds, 0, 0, get_next_timeout()) >= 0) {
if (XPending(server.display) > 0 || select(max_fd + 1, &fds, 0, 0, get_duration_to_next_timer_expiration()) >= 0) {
#ifdef HAVE_TRACING
start_tracing((void*)run_tint2_event_loop);
#endif

View File

@@ -79,11 +79,16 @@ int num_panels;
GArray *backgrounds;
GArray *gradients;
double ui_scale_dpi_ref;
double ui_scale_monitor_size_ref;
Imlib_Image default_icon;
char *default_font = NULL;
void default_panel()
{
ui_scale_dpi_ref = 0;
ui_scale_monitor_size_ref = 0;
panels = NULL;
num_panels = 0;
default_icon = NULL;
@@ -130,8 +135,6 @@ void cleanup_panel()
if (!panels)
return;
cleanup_taskbar();
for (int i = 0; i < num_panels; i++) {
Panel *p = &panels[i];
@@ -145,7 +148,7 @@ void cleanup_panel()
if (p->main_win)
XDestroyWindow(server.display, p->main_win);
p->main_win = 0;
stop_timeout(p->autohide_timeout);
destroy_timer(&p->autohide_timer);
cleanup_freespace(p);
}
@@ -207,6 +210,7 @@ void init_panel()
panels = calloc(num_panels, sizeof(Panel));
for (int i = 0; i < num_panels; i++) {
memcpy(&panels[i], &panel_config, sizeof(Panel));
INIT_TIMER(panels[i].autohide_timer);
}
fprintf(stderr,
@@ -219,6 +223,17 @@ void init_panel()
if (panel_config.monitor < 0)
p->monitor = i;
if (ui_scale_dpi_ref > 0 && server.monitors[p->monitor].dpi > 0)
p->scale = server.monitors[p->monitor].dpi / ui_scale_dpi_ref;
else
p->scale = 1;
if (ui_scale_monitor_size_ref > 0)
p->scale *= server.monitors[p->monitor].height / ui_scale_monitor_size_ref;
if (p->scale > 8 || p->scale < 1./8) {
fprintf(stderr, RED "tint2: panel %d having scale %g outside bounds, resetting to 1.0" RESET "\n", i + 1, p->scale);
p->scale = 1;
}
fprintf(stderr, BLUE "tint2: panel %d uses scale %g " RESET "\n", i + 1, p->scale);
if (!p->area.bg)
p->area.bg = &g_array_index(backgrounds, Background, 0);
p->area.parent = p;
@@ -356,6 +371,19 @@ void panel_compute_size(Panel *panel)
}
}
if (!panel->fractional_width) {
if (panel_horizontal)
panel->area.width *= panel->scale;
else
panel->area.height *= panel->scale;
}
if (!panel->fractional_height) {
if (panel_horizontal)
panel->area.height *= panel->scale;
else
panel->area.width *= panel->scale;
}
if (panel->area.width + panel->marginx > server.monitors[panel->monitor].width)
panel->area.width = server.monitors[panel->monitor].width - panel->marginx;
if (panel->area.height + panel->marginy > server.monitors[panel->monitor].height)
@@ -450,9 +478,9 @@ gboolean resize_panel(void *obj)
if (!taskbar->area.on_screen)
continue;
if (panel_horizontal)
taskbar->area.width = 2 * taskbar->area.paddingxlr;
taskbar->area.width = 2 * taskbar->area.paddingxlr * panel->scale;
else
taskbar->area.height = 2 * taskbar->area.paddingxlr;
taskbar->area.height = 2 * taskbar->area.paddingxlr * panel->scale;
if (taskbarname_enabled && taskbar->area.children) {
Area *name = (Area *)taskbar->area.children->data;
if (name->on_screen) {
@@ -469,9 +497,9 @@ gboolean resize_panel(void *obj)
continue;
if (!first_child) {
if (panel_horizontal)
taskbar->area.width += taskbar->area.paddingx;
taskbar->area.width += taskbar->area.paddingx * panel->scale;
else
taskbar->area.height += taskbar->area.paddingy;
taskbar->area.height += taskbar->area.paddingy * panel->scale;
}
first_child = FALSE;
}
@@ -529,6 +557,8 @@ gboolean resize_panel(void *obj)
}
} else if (taskbar_alignment == ALIGN_CENTER) {
slack /= 2;
Taskbar *left_taskbar = NULL;
Taskbar *right_taskbar = NULL;
for (int i = 0; i < panel->num_desktops; i++) {
Taskbar *taskbar = &panel->taskbar[i];
if (!taskbar->area.on_screen)
@@ -538,6 +568,7 @@ gboolean resize_panel(void *obj)
else
taskbar->area.height += slack;
taskbar->area.alignment = ALIGN_RIGHT;
left_taskbar = taskbar;
break;
}
for (int i = panel->num_desktops - 1; i >= 0; i--) {
@@ -549,8 +580,11 @@ gboolean resize_panel(void *obj)
else
taskbar->area.height += slack;
taskbar->area.alignment = ALIGN_LEFT;
right_taskbar = taskbar;
break;
}
if (left_taskbar == right_taskbar)
left_taskbar->area.alignment = ALIGN_CENTER;
}
} else {
// No tasks => expand the first visible taskbar
@@ -1060,15 +1094,15 @@ Button *click_button(Panel *panel, int x, int y)
return NULL;
}
void stop_autohide_timeout(Panel *p)
void stop_autohide_timer(Panel *p)
{
stop_timeout(p->autohide_timeout);
stop_timer(&p->autohide_timer);
}
void autohide_show(void *p)
{
Panel *panel = (Panel *)p;
stop_autohide_timeout(panel);
stop_autohide_timer(panel);
panel->is_hidden = 0;
XMapSubwindows(server.display, panel->main_win); // systray windows
set_panel_window_geometry(panel);
@@ -1080,7 +1114,7 @@ void autohide_show(void *p)
void autohide_hide(void *p)
{
Panel *panel = (Panel *)p;
stop_autohide_timeout(panel);
stop_autohide_timer(panel);
set_panel_layer(panel, panel_layer);
panel->is_hidden = TRUE;
XUnmapSubwindows(server.display, panel->main_win); // systray windows
@@ -1092,7 +1126,7 @@ void autohide_trigger_show(Panel *p)
{
if (!p)
return;
change_timeout(&p->autohide_timeout, panel_autohide_show_timeout, 0, autohide_show, p);
change_timer(&p->autohide_timer, true, panel_autohide_show_timeout, 0, autohide_show, p);
}
void autohide_trigger_hide(Panel *p)
@@ -1107,7 +1141,7 @@ void autohide_trigger_hide(Panel *p)
if (child)
return; // mouse over one of the system tray icons
change_timeout(&p->autohide_timeout, panel_autohide_hide_timeout, 0, autohide_hide, p);
change_timer(&p->autohide_timer, true, panel_autohide_hide_timeout, 0, autohide_hide, p);
}
void shrink_panel(Panel *panel)

View File

@@ -95,6 +95,8 @@ extern gboolean debug_fps;
extern double tracing_fps_threshold;
extern gboolean debug_frames;
extern gboolean debug_thumbnails;
extern double ui_scale_dpi_ref;
extern double ui_scale_monitor_size_ref;
typedef struct Panel {
Area area;
@@ -117,6 +119,7 @@ typedef struct Panel {
int mouse_pressed_alpha;
int mouse_pressed_saturation;
int mouse_pressed_brightness;
double scale;
// Per-panel parameters and states for Taskbar and Task
GlobalTaskbar g_taskbar;
@@ -144,7 +147,7 @@ typedef struct Panel {
gboolean is_hidden;
int hidden_width, hidden_height;
Pixmap hidden_pixmap;
timeout *autohide_timeout;
Timer autohide_timer;
} Panel;
extern Panel panel_config;

View File

@@ -115,31 +115,33 @@ void cleanup_separator()
int separator_compute_desired_size(void *obj)
{
Separator *separator = (Separator *)obj;
Panel *panel = (Panel*)separator->area.panel;
if (!separator->area.on_screen)
return 0;
if (panel_horizontal)
return separator->thickness + 2 * separator->area.paddingxlr + left_right_border_width(&separator->area);
return separator->thickness + 2 * separator->area.paddingxlr * panel->scale + left_right_border_width(&separator->area);
else
return separator->thickness + 2 * separator->area.paddingxlr + top_bottom_border_width(&separator->area);
return separator->thickness + 2 * separator->area.paddingxlr * panel->scale + top_bottom_border_width(&separator->area);
}
gboolean resize_separator(void *obj)
{
Separator *separator = (Separator *)obj;
Panel *panel = (Panel*)separator->area.panel;
if (!separator->area.on_screen)
return FALSE;
if (panel_horizontal) {
separator->area.width =
separator->thickness + 2 * separator->area.paddingxlr + left_right_border_width(&separator->area);
separator->thickness + 2 * separator->area.paddingxlr * panel->scale + left_right_border_width(&separator->area);
separator->length =
separator->area.height - 2 * separator->area.paddingy - top_bottom_border_width(&separator->area);
separator->area.height - 2 * separator->area.paddingy * panel->scale - top_bottom_border_width(&separator->area);
} else {
separator->area.height =
separator->thickness + 2 * separator->area.paddingxlr + top_bottom_border_width(&separator->area);
separator->thickness + 2 * separator->area.paddingxlr * panel->scale + top_bottom_border_width(&separator->area);
separator->length =
separator->area.width - 2 * separator->area.paddingy - left_right_border_width(&separator->area);
separator->area.width - 2 * separator->area.paddingy * panel->scale - left_right_border_width(&separator->area);
}
schedule_redraw(&separator->area);

View File

@@ -141,11 +141,12 @@ void init_systray_panel(void *p)
void systray_compute_geometry(int *size)
{
Panel *panel = (Panel*)systray.area.panel;
systray.icon_size = panel_horizontal ? systray.area.height : systray.area.width;
systray.icon_size -=
MAX(left_right_border_width(&systray.area), top_bottom_border_width(&systray.area)) + 2 * systray.area.paddingy;
MAX(left_right_border_width(&systray.area), top_bottom_border_width(&systray.area)) + 2 * systray.area.paddingy * panel->scale;
if (systray_max_icon_size > 0)
systray.icon_size = MIN(systray.icon_size, systray_max_icon_size);
systray.icon_size = MIN(systray.icon_size, systray_max_icon_size * panel->scale);
int count = 0;
for (GSList *l = systray.list_icons; l; l = l->next) {
@@ -153,24 +154,24 @@ void systray_compute_geometry(int *size)
}
if (panel_horizontal) {
int height = systray.area.height - top_bottom_border_width(&systray.area) - 2 * systray.area.paddingy;
int height = systray.area.height - top_bottom_border_width(&systray.area) - 2 * systray.area.paddingy * panel->scale;
// here icons_per_column always higher than 0
systray.icons_per_column = (height + systray.area.paddingx) / (systray.icon_size + systray.area.paddingx);
systray.icons_per_column = (height + systray.area.paddingx * panel->scale) / (systray.icon_size + systray.area.paddingx * panel->scale);
systray.margin =
height - (systray.icons_per_column - 1) * (systray.icon_size + systray.area.paddingx) - systray.icon_size;
height - (systray.icons_per_column - 1) * (systray.icon_size + systray.area.paddingx * panel->scale) - systray.icon_size;
systray.icons_per_row = count / systray.icons_per_column + (count % systray.icons_per_column != 0);
*size = left_right_border_width(&systray.area) + 2 * systray.area.paddingxlr +
(systray.icon_size * systray.icons_per_row) + ((systray.icons_per_row - 1) * systray.area.paddingx);
*size = left_right_border_width(&systray.area) + 2 * systray.area.paddingxlr * panel->scale +
(systray.icon_size * systray.icons_per_row) + ((systray.icons_per_row - 1) * systray.area.paddingx * panel->scale);
} else {
int width = systray.area.width - left_right_border_width(&systray.area) - 2 * systray.area.paddingy;
int width = systray.area.width - left_right_border_width(&systray.area) - 2 * systray.area.paddingy * panel->scale;
// here icons_per_row always higher than 0
systray.icons_per_row = (width + systray.area.paddingx) / (systray.icon_size + systray.area.paddingx);
systray.icons_per_row = (width + systray.area.paddingx * panel->scale) / (systray.icon_size + systray.area.paddingx * panel->scale);
systray.margin =
width - (systray.icons_per_row - 1) * (systray.icon_size + systray.area.paddingx) - systray.icon_size;
width - (systray.icons_per_row - 1) * (systray.icon_size + systray.area.paddingx * panel->scale) - systray.icon_size;
systray.icons_per_column = count / systray.icons_per_row + (count % systray.icons_per_row != 0);
*size = top_bottom_border_width(&systray.area) + (2 * systray.area.paddingxlr) +
*size = top_bottom_border_width(&systray.area) + (2 * systray.area.paddingxlr * panel->scale) +
(systray.icon_size * systray.icons_per_column) +
((systray.icons_per_column - 1) * systray.area.paddingx);
((systray.icons_per_column - 1) * systray.area.paddingx * panel->scale);
}
}
@@ -281,13 +282,13 @@ void on_change_systray(void *obj)
int posx, posy;
int start;
if (panel_horizontal) {
posy = start = top_border_width(&panel->area) + panel->area.paddingy + top_border_width(&systray.area) +
systray.area.paddingy + systray.margin / 2;
posx = systray.area.posx + left_border_width(&systray.area) + systray.area.paddingxlr;
posy = start = top_border_width(&panel->area) + panel->area.paddingy * panel->scale + top_border_width(&systray.area) +
systray.area.paddingy * panel->scale + systray.margin / 2;
posx = systray.area.posx + left_border_width(&systray.area) + systray.area.paddingxlr * panel->scale;
} else {
posx = start = left_border_width(&panel->area) + panel->area.paddingy + left_border_width(&systray.area) +
systray.area.paddingy + systray.margin / 2;
posy = systray.area.posy + top_border_width(&systray.area) + systray.area.paddingxlr;
posx = start = left_border_width(&panel->area) + panel->area.paddingy * panel->scale + left_border_width(&systray.area) +
systray.area.paddingy * panel->scale + systray.margin / 2;
posy = systray.area.posy + top_border_width(&systray.area) + systray.area.paddingxlr * panel->scale;
}
TrayWindow *traywin;
@@ -312,17 +313,17 @@ void on_change_systray(void *obj)
traywin->height = systray.icon_size;
if (panel_horizontal) {
if (i % systray.icons_per_column) {
posy += systray.icon_size + systray.area.paddingx;
posy += systray.icon_size + systray.area.paddingx * panel->scale;
} else {
posy = start;
posx += (systray.icon_size + systray.area.paddingx);
posx += (systray.icon_size + systray.area.paddingx * panel->scale);
}
} else {
if (i % systray.icons_per_row) {
posx += systray.icon_size + systray.area.paddingx;
posx += systray.icon_size + systray.area.paddingx * panel->scale;
} else {
posx = start;
posy += (systray.icon_size + systray.area.paddingx);
posy += (systray.icon_size + systray.area.paddingx * panel->scale);
}
}
@@ -543,11 +544,11 @@ static gint compare_traywindows(gconstpointer a, gconstpointer b)
const TrayWindow *traywin_b = (const TrayWindow *)b;
#if 0
// This breaks pygtk2 StatusIcon with blinking activated
if (traywin_a->empty && !traywin_b->empty)
return 1 * (systray.sort == SYSTRAY_SORT_RIGHT2LEFT ? -1 : 1);
if (!traywin_a->empty && traywin_b->empty)
return -1 * (systray.sort == SYSTRAY_SORT_RIGHT2LEFT ? -1 : 1);
// This breaks pygtk2 StatusIcon with blinking activated
if (traywin_a->empty && !traywin_b->empty)
return 1 * (systray.sort == SYSTRAY_SORT_RIGHT2LEFT ? -1 : 1);
if (!traywin_a->empty && traywin_b->empty)
return -1 * (systray.sort == SYSTRAY_SORT_RIGHT2LEFT ? -1 : 1);
#endif
if (systray.sort == SYSTRAY_SORT_ASCENDING || systray.sort == SYSTRAY_SORT_DESCENDING) {
@@ -730,6 +731,8 @@ gboolean add_icon(Window win)
traywin->pid = pid;
traywin->name = name;
traywin->chrono = chrono;
INIT_TIMER(traywin->render_timer);
INIT_TIMER(traywin->resize_timer);
chrono++;
show(&systray.area);
@@ -940,8 +943,8 @@ void remove_icon(TrayWindow *traywin)
XDestroyWindow(server.display, traywin->parent);
XSync(server.display, False);
XSetErrorHandler(old);
stop_timeout(traywin->render_timeout);
stop_timeout(traywin->resize_timeout);
destroy_timer(&traywin->render_timer);
destroy_timer(&traywin->resize_timer);
free(traywin->name);
if (traywin->image) {
imlib_context_set_image(traywin->image);
@@ -1055,9 +1058,8 @@ void systray_reconfigure_event(TrayWindow *traywin, XEvent *e)
if (traywin->bad_size_counter < min_bad_resize_events) {
systray_resize_icon(traywin);
} else {
if (!traywin->resize_timeout)
traywin->resize_timeout =
add_timeout(fast_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
if (!traywin->resize_timer.enabled_)
change_timer(&traywin->resize_timer, true, fast_resize_period, 0, systray_resize_icon, traywin);
}
} else {
if (traywin->bad_size_counter == max_bad_resize_events) {
@@ -1071,14 +1073,13 @@ void systray_reconfigure_event(TrayWindow *traywin, XEvent *e)
// FIXME Normally we should force the icon to resize fill_color to the size we resized it to when we
// embedded it.
// However this triggers a resize loop in new versions of GTK, which we must avoid.
if (!traywin->resize_timeout)
traywin->resize_timeout =
add_timeout(slow_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
if (!traywin->resize_timer.enabled_)
change_timer(&traywin->resize_timer, true, slow_resize_period, 0, systray_resize_icon, traywin);
return;
}
} else {
// Correct size
stop_timeout(traywin->resize_timeout);
stop_timer(&traywin->resize_timer);
}
// Resize and redraw the systray
@@ -1135,9 +1136,8 @@ void systray_resize_request_event(TrayWindow *traywin, XEvent *e)
if (traywin->bad_size_counter < min_bad_resize_events) {
systray_resize_icon(traywin);
} else {
if (!traywin->resize_timeout)
traywin->resize_timeout =
add_timeout(fast_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
if (!traywin->resize_timer.enabled_)
change_timer(&traywin->resize_timer, true, fast_resize_period, 0, systray_resize_icon, traywin);
}
} else {
if (traywin->bad_size_counter == max_bad_resize_events) {
@@ -1150,14 +1150,13 @@ void systray_resize_request_event(TrayWindow *traywin, XEvent *e)
// Delayed resize
// FIXME Normally we should force the icon to resize to the size we resized it to when we embedded it.
// However this triggers a resize loop in some versions of GTK, which we must avoid.
if (!traywin->resize_timeout)
traywin->resize_timeout =
add_timeout(slow_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
if (!traywin->resize_timer.enabled_)
change_timer(&traywin->resize_timer, true, slow_resize_period, 0, systray_resize_icon, traywin);
return;
}
} else {
// Correct size
stop_timeout(traywin->resize_timeout);
stop_timer(&traywin->resize_timer);
}
// Resize and redraw the systray
@@ -1224,8 +1223,7 @@ void systray_render_icon_composited(void *t)
if (compare_timespecs(&earliest_render, &now) > 0) {
traywin->num_fast_renders++;
if (traywin->num_fast_renders > max_fast_refreshes) {
traywin->render_timeout =
add_timeout(min_refresh_period, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
change_timer(&traywin->render_timer, true, min_refresh_period, 0, systray_render_icon_composited, traywin);
if (systray_profile)
fprintf(stderr,
YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering" RESET "\n",
@@ -1244,8 +1242,7 @@ void systray_render_icon_composited(void *t)
if (traywin->width == 0 || traywin->height == 0) {
// reschedule rendering since the geometry information has not yet been processed (can happen on slow cpu)
traywin->render_timeout =
add_timeout(min_refresh_period, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
change_timer(&traywin->render_timer, true, min_refresh_period, 0, systray_render_icon_composited, traywin);
if (systray_profile)
fprintf(stderr,
YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering" RESET "\n",
@@ -1257,10 +1254,7 @@ void systray_render_icon_composited(void *t)
return;
}
if (traywin->render_timeout) {
stop_timeout(traywin->render_timeout);
traywin->render_timeout = NULL;
}
stop_timer(&traywin->render_timer);
// good systray icons support 32 bit depth, but some icons are still 24 bit.
// We create a heuristic mask for these icons, i.e. we get the rgb value in the top left corner, and
@@ -1423,9 +1417,7 @@ void systray_render_icon(void *t)
// __LINE__,
// traywin->win,
// traywin->name);
stop_timeout(traywin->render_timeout);
traywin->render_timeout =
add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
change_timer(&traywin->render_timer, true, min_refresh_period, 0, systray_render_icon, traywin);
return;
}
@@ -1448,19 +1440,13 @@ void systray_render_icon(void *t)
unsigned int width, height, depth;
Window root;
if (!XGetGeometry(server.display, traywin->win, &root, &xpos, &ypos, &width, &height, &border_width, &depth)) {
stop_timeout(traywin->render_timeout);
if (!traywin->render_timeout)
traywin->render_timeout =
add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
change_timer(&traywin->render_timer, true, min_refresh_period, 0, systray_render_icon, traywin);
systray_render_icon_from_image(traywin);
XSetErrorHandler(old);
return;
} else {
if (xpos != 0 || ypos != 0 || width != traywin->width || height != traywin->height) {
stop_timeout(traywin->render_timeout);
if (!traywin->render_timeout)
traywin->render_timeout =
add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
change_timer(&traywin->render_timer, true, min_refresh_period, 0, systray_render_icon, traywin);
systray_render_icon_from_image(traywin);
if (systray_profile)
fprintf(stderr,

View File

@@ -56,11 +56,11 @@ typedef struct {
// Members used for rendering
struct timespec time_last_render;
int num_fast_renders;
timeout *render_timeout;
Timer render_timer;
// Members used for resizing
int bad_size_counter;
struct timespec time_last_resize;
timeout *resize_timeout;
Timer resize_timer;
// Icon contents if we are compositing the icon, otherwise null
Imlib_Image image;
// XDamage

View File

@@ -35,7 +35,7 @@
#include "tooltip.h"
#include "window.h"
timeout *urgent_timeout;
Timer urgent_timer;
GSList *urgent_list;
void task_dump_geometry(void *obj, int indent);
@@ -429,7 +429,7 @@ void draw_task_icon(Task *task, int text_width)
else
task->_icon_x = (task->area.width - panel->g_task.icon_size1) / 2;
} else {
task->_icon_x = left_border_width(&task->area) + task->area.paddingxlr;
task->_icon_x = left_border_width(&task->area) + task->area.paddingxlr * panel->scale;
}
// Render
@@ -459,11 +459,13 @@ void draw_task(void *obj, cairo_t *c)
task->_text_width = 0;
if (panel->g_task.has_text) {
PangoLayout *layout = pango_cairo_create_layout(c);
PangoContext *context = pango_cairo_create_context(c);
pango_cairo_context_set_resolution(context, 96 * panel->scale);
PangoLayout *layout = pango_layout_new(context);
pango_layout_set_font_description(layout, panel->g_task.font_desc);
pango_layout_set_text(layout, task->title, -1);
pango_layout_set_width(layout, ((Taskbar *)task->area.parent)->text_width * PANGO_SCALE);
pango_layout_set_width(layout, (((Taskbar *)task->area.parent)->text_width + TINT2_PANGO_SLACK) * PANGO_SCALE);
pango_layout_set_height(layout, panel->g_task.text_height * PANGO_SCALE);
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
@@ -480,6 +482,7 @@ void draw_task(void *obj, cairo_t *c)
draw_text(layout, c, panel->g_task.text_posx, task->_text_posy, config_text, panel->font_shadow);
g_object_unref(layout);
g_object_unref(context);
}
if (panel->g_task.has_icon)
@@ -532,7 +535,7 @@ int task_compute_desired_size(void *obj)
{
Task *task = (Task *)obj;
Panel *panel = (Panel *)task->area.panel;
int size = panel_horizontal ? panel->g_task.maximum_width : panel->g_task.maximum_height;
int size = (panel_horizontal ? panel->g_task.maximum_width : panel->g_task.maximum_height) * panel->scale;
return size;
}
@@ -652,12 +655,13 @@ void task_refresh_thumbnail(Task *task)
return;
if (task->current_state == TASK_ICONIFIED)
return;
Panel *panel = (Panel*)task->area.panel;
double now = get_time();
if (now - task->thumbnail_last_update < 0.1)
return;
if (debug_thumbnails)
fprintf(stderr, "tint2: thumbnail for window: %s" RESET "\n", task->title ? task->title : "");
cairo_surface_t *thumbnail = get_window_thumbnail(task->win, panel_config.g_task.thumbnail_width);
cairo_surface_t *thumbnail = get_window_thumbnail(task->win, panel_config.g_task.thumbnail_width * panel->scale);
if (!thumbnail)
return;
if (task->thumbnail)
@@ -754,8 +758,8 @@ void blink_urgent(void *arg)
GSList *urgent_task = urgent_list;
while (urgent_task) {
Task *t = urgent_task->data;
if (t->urgent_tick < max_tick_urgent) {
if (t->urgent_tick++ % 2)
if (t->urgent_tick <= max_tick_urgent) {
if (++t->urgent_tick % 2)
set_task_state(t, TASK_URGENT);
else
set_task_state(t, window_is_iconified(t->win) ? TASK_ICONIFIED : TASK_NORMAL);
@@ -782,8 +786,8 @@ void add_urgent(Task *task)
// not yet in the list, so we have to add it
urgent_list = g_slist_prepend(urgent_list, task);
if (!urgent_timeout)
urgent_timeout = add_timeout(10, 1000, blink_urgent, 0, &urgent_timeout);
if (!urgent_timer.enabled_)
change_timer(&urgent_timer, true, 10, 1000, blink_urgent, 0);
Panel *panel = task->area.panel;
if (panel->is_hidden)
@@ -793,10 +797,8 @@ void add_urgent(Task *task)
void del_urgent(Task *task)
{
urgent_list = g_slist_remove(urgent_list, task);
if (!urgent_list) {
stop_timeout(urgent_timeout);
urgent_timeout = NULL;
}
if (!urgent_list)
stop_timer(&urgent_timer);
}
void task_handle_mouse_event(Task *task, MouseAction action)

View File

@@ -84,7 +84,7 @@ typedef struct Task {
double thumbnail_last_update;
} Task;
extern timeout *urgent_timeout;
extern Timer urgent_timer;
extern GSList *urgent_list;
Task *add_task(Window win);

View File

@@ -47,9 +47,9 @@ gboolean hide_taskbar_if_empty;
gboolean always_show_all_desktop_tasks;
TaskbarSortMethod taskbar_sort_method;
Alignment taskbar_alignment;
static timeout *thumbnail_update_timer_all;
static timeout *thumbnail_update_timer_active;
static timeout *thumbnail_update_timer_tooltip;
static Timer thumbnail_update_timer_all;
static Timer thumbnail_update_timer_active;
static Timer thumbnail_update_timer_tooltip;
static GList *taskbar_task_orderings = NULL;
static GList *taskbar_thumbnail_jobs_done = NULL;
@@ -80,7 +80,6 @@ void free_ptr_array(gpointer data)
void default_taskbar()
{
win_to_task = NULL;
urgent_timeout = NULL;
urgent_list = NULL;
taskbar_enabled = FALSE;
taskbar_distribute_size = FALSE;
@@ -89,9 +88,6 @@ void default_taskbar()
hide_task_diff_monitor = FALSE;
hide_taskbar_if_empty = FALSE;
always_show_all_desktop_tasks = FALSE;
thumbnail_update_timer_all = NULL;
thumbnail_update_timer_active = NULL;
thumbnail_update_timer_tooltip = NULL;
taskbar_thumbnail_jobs_done = NULL;
taskbar_sort_method = TASKBAR_NOSORT;
taskbar_alignment = ALIGN_LEFT;
@@ -134,9 +130,9 @@ void taskbar_save_orderings()
void cleanup_taskbar()
{
stop_timeout(thumbnail_update_timer_all);
stop_timeout(thumbnail_update_timer_active);
stop_timeout(thumbnail_update_timer_tooltip);
destroy_timer(&thumbnail_update_timer_all);
destroy_timer(&thumbnail_update_timer_active);
destroy_timer(&thumbnail_update_timer_tooltip);
g_list_free(taskbar_thumbnail_jobs_done);
taskbar_save_orderings();
if (win_to_task) {
@@ -170,7 +166,7 @@ void cleanup_taskbar()
g_slist_free(urgent_list);
urgent_list = NULL;
stop_timeout(urgent_timeout);
destroy_timer(&urgent_timer);
for (int state = 0; state < TASK_STATE_COUNT; state++) {
g_list_free(panel_config.g_task.gradient[state]);
@@ -184,6 +180,11 @@ void cleanup_taskbar()
void init_taskbar()
{
INIT_TIMER(urgent_timer);
INIT_TIMER(thumbnail_update_timer_all);
INIT_TIMER(thumbnail_update_timer_active);
INIT_TIMER(thumbnail_update_timer_tooltip);
if (!panel_config.g_task.has_text && !panel_config.g_task.has_icon) {
panel_config.g_task.has_text = panel_config.g_task.has_icon = 1;
}
@@ -237,15 +238,15 @@ void init_taskbar_panel(void *p)
panel->g_taskbar.area.resize_needed = 1;
panel->g_taskbar.area.on_screen = TRUE;
if (panel_horizontal) {
panel->g_taskbar.area.posy = top_border_width(&panel->area) + panel->area.paddingy;
panel->g_taskbar.area.posy = top_border_width(&panel->area) + panel->area.paddingy * panel->scale;
panel->g_taskbar.area.height =
panel->area.height - top_bottom_border_width(&panel->area) - 2 * panel->area.paddingy;
panel->area.height - top_bottom_border_width(&panel->area) - 2 * panel->area.paddingy * panel->scale;
panel->g_taskbar.area_name.posy = panel->g_taskbar.area.posy;
panel->g_taskbar.area_name.height = panel->g_taskbar.area.height;
} else {
panel->g_taskbar.area.posx = left_border_width(&panel->area) + panel->area.paddingy;
panel->g_taskbar.area.posx = left_border_width(&panel->area) + panel->area.paddingy * panel->scale;
panel->g_taskbar.area.width =
panel->area.width - left_right_border_width(&panel->area) - 2 * panel->area.paddingy;
panel->area.width - left_right_border_width(&panel->area) - 2 * panel->area.paddingy * panel->scale;
panel->g_taskbar.area_name.posx = panel->g_taskbar.area.posx;
panel->g_taskbar.area_name.width = panel->g_taskbar.area.width;
}
@@ -303,19 +304,19 @@ void init_taskbar_panel(void *p)
if (panel_horizontal) {
panel->g_task.area.posy = panel->g_taskbar.area.posy +
top_bg_border_width(panel->g_taskbar.background[TASKBAR_NORMAL]) +
panel->g_taskbar.area.paddingy;
panel->g_taskbar.area.paddingy * panel->scale;
panel->g_task.area.width = panel->g_task.maximum_width;
panel->g_task.area.height = panel->g_taskbar.area.height -
top_bottom_bg_border_width(panel->g_taskbar.background[TASKBAR_NORMAL]) -
2 * panel->g_taskbar.area.paddingy;
2 * panel->g_taskbar.area.paddingy * panel->scale;
} else {
panel->g_task.area.posx = panel->g_taskbar.area.posx +
left_bg_border_width(panel->g_taskbar.background[TASKBAR_NORMAL]) +
panel->g_taskbar.area.paddingy;
panel->g_taskbar.area.paddingy * panel->scale;
panel->g_task.area.width = panel->g_taskbar.area.width -
left_right_bg_border_width(panel->g_taskbar.background[TASKBAR_NORMAL]) -
2 * panel->g_taskbar.area.paddingy;
panel->g_task.area.height = panel->g_task.maximum_height;
2 * panel->g_taskbar.area.paddingy * panel->scale;
panel->g_task.area.height = panel->g_task.maximum_height * panel->scale;
}
for (int j = 0; j < TASK_STATE_COUNT; ++j) {
@@ -332,9 +333,8 @@ void init_taskbar_panel(void *p)
}
// compute vertical position : text and icon
int height_ink, height, width;
int height, width;
get_text_size2(panel->g_task.font_desc,
&height_ink,
&height,
&width,
panel->area.height,
@@ -343,17 +343,19 @@ void init_taskbar_panel(void *p)
5,
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_END,
FALSE);
panel->g_task.centered ? PANGO_ALIGN_CENTER : PANGO_ALIGN_LEFT,
FALSE,
panel->scale);
panel->g_task.text_posx = left_bg_border_width(panel->g_task.background[0]) + panel->g_task.area.paddingxlr;
panel->g_task.text_posx = left_bg_border_width(panel->g_task.background[0]) + panel->g_task.area.paddingxlr * panel->scale;
panel->g_task.text_height =
panel->g_task.area.height - (2 * panel->g_task.area.paddingy) - top_bottom_border_width(&panel->g_task.area);
panel->g_task.area.height - (2 * panel->g_task.area.paddingy * panel->scale) - top_bottom_border_width(&panel->g_task.area);
if (panel->g_task.has_icon) {
panel->g_task.icon_size1 = MIN(MIN(panel->g_task.maximum_width, panel->g_task.maximum_height),
panel->g_task.icon_size1 = MIN(MIN(panel->g_task.maximum_width * panel->scale, panel->g_task.maximum_height * panel->scale),
MIN(panel->g_task.area.width, panel->g_task.area.height)) -
2 * panel->g_task.area.paddingy - MAX(left_right_border_width(&panel->g_task.area),
2 * panel->g_task.area.paddingy * panel->scale - MAX(left_right_border_width(&panel->g_task.area),
top_bottom_border_width(&panel->g_task.area));
panel->g_task.text_posx += panel->g_task.icon_size1 + panel->g_task.area.paddingx;
panel->g_task.text_posx += panel->g_task.icon_size1 + panel->g_task.area.paddingx * panel->scale;
panel->g_task.icon_posy = (panel->g_task.area.height - panel->g_task.icon_size1) / 2;
}
@@ -384,12 +386,13 @@ void taskbar_start_thumbnail_timer(ThumbnailUpdateMode mode)
return;
if (debug_thumbnails)
fprintf(stderr, BLUE "tint2: taskbar_start_thumbnail_timer %s" RESET "\n", mode == THUMB_MODE_ACTIVE_WINDOW ? "active" : mode == THUMB_MODE_TOOLTIP_WINDOW ? "tooltip" : "all");
change_timeout(mode == THUMB_MODE_ALL ? &thumbnail_update_timer_all :
change_timer(mode == THUMB_MODE_ALL ? &thumbnail_update_timer_all :
mode == THUMB_MODE_ACTIVE_WINDOW ? &thumbnail_update_timer_active : &thumbnail_update_timer_tooltip,
mode == THUMB_MODE_TOOLTIP_WINDOW ? 1000 : 500,
mode == THUMB_MODE_ALL ? 10 * 1000 : 0,
taskbar_update_thumbnails,
(void *)(long)mode);
true,
mode == THUMB_MODE_TOOLTIP_WINDOW ? 1000 : 500,
mode == THUMB_MODE_ALL ? 10 * 1000 : 0,
taskbar_update_thumbnails,
(void *)(long)mode);
}
void taskbar_init_fonts()
@@ -571,12 +574,12 @@ gboolean resize_taskbar(void *obj)
}
}
taskbar->text_width = text_width - panel->g_task.text_posx - right_border_width(&panel->g_task.area) -
panel->g_task.area.paddingxlr;
panel->g_task.area.paddingxlr * panel->scale;
} else {
relayout_with_constraint(&taskbar->area, panel->g_task.maximum_height);
relayout_with_constraint(&taskbar->area, panel->g_task.maximum_height * panel->scale);
taskbar->text_width = taskbar->area.width - (2 * panel->g_taskbar.area.paddingy) - panel->g_task.text_posx -
right_border_width(&panel->g_task.area) - panel->g_task.area.paddingxlr;
taskbar->text_width = taskbar->area.width - (2 * panel->g_taskbar.area.paddingy * panel->scale) - panel->g_task.text_posx -
right_border_width(&panel->g_task.area) - panel->g_task.area.paddingxlr * panel->scale;
}
return FALSE;
}
@@ -844,7 +847,7 @@ void taskbar_update_thumbnails(void *arg)
if (mode == THUMB_MODE_ALL) {
double now = get_time();
if (now - start_time > 0.030) {
change_timeout(&thumbnail_update_timer_all, 50, 10 * 1000, taskbar_update_thumbnails, arg);
change_timer(&thumbnail_update_timer_all, true, 50, 10 * 1000, taskbar_update_thumbnails, arg);
return;
}
}
@@ -855,7 +858,7 @@ void taskbar_update_thumbnails(void *arg)
if (taskbar_thumbnail_jobs_done) {
g_list_free(taskbar_thumbnail_jobs_done);
taskbar_thumbnail_jobs_done = NULL;
change_timeout(&thumbnail_update_timer_all, 10 * 1000, 10 * 1000, taskbar_update_thumbnails, arg);
change_timer(&thumbnail_update_timer_all, true, 10 * 1000, 10 * 1000, taskbar_update_thumbnails, arg);
}
}
}

View File

@@ -134,9 +134,8 @@ int taskbarname_compute_desired_size(void *obj)
{
TaskbarName *taskbar_name = (TaskbarName *)obj;
Panel *panel = (Panel *)taskbar_name->area.panel;
int name_height, name_width, name_height_ink;
int name_height, name_width;
get_text_size2(panel_config.taskbarname_font_desc,
&name_height_ink,
&name_height,
&name_width,
panel->area.height,
@@ -145,12 +144,14 @@ int taskbarname_compute_desired_size(void *obj)
strlen(taskbar_name->name),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
PANGO_ALIGN_CENTER,
FALSE,
panel->scale);
if (panel_horizontal) {
return name_width + 2 * taskbar_name->area.paddingxlr + left_right_border_width(&taskbar_name->area);
return name_width + 2 * taskbar_name->area.paddingxlr * panel->scale + left_right_border_width(&taskbar_name->area);
} else {
return name_height + 2 * taskbar_name->area.paddingxlr + top_bottom_border_width(&taskbar_name->area);
return name_height + 2 * taskbar_name->area.paddingxlr * panel->scale + top_bottom_border_width(&taskbar_name->area);
}
}
@@ -161,9 +162,8 @@ gboolean resize_taskbarname(void *obj)
schedule_redraw(&taskbar_name->area);
int name_height, name_width, name_height_ink;
int name_height, name_width;
get_text_size2(panel_config.taskbarname_font_desc,
&name_height_ink,
&name_height,
&name_width,
panel->area.height,
@@ -172,7 +172,9 @@ gboolean resize_taskbarname(void *obj)
strlen(taskbar_name->name),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
PANGO_ALIGN_CENTER,
FALSE,
panel->scale);
gboolean result = FALSE;
int new_size = taskbarname_compute_desired_size(obj);
@@ -195,11 +197,14 @@ gboolean resize_taskbarname(void *obj)
void draw_taskbarname(void *obj, cairo_t *c)
{
TaskbarName *taskbar_name = obj;
Panel *panel = (Panel *)taskbar_name->area.panel;
Taskbar *taskbar = taskbar_name->area.parent;
Color *config_text = (taskbar->desktop == server.desktop) ? &taskbarname_active_font : &taskbarname_font;
// draw content
PangoLayout *layout = pango_cairo_create_layout(c);
PangoContext *context = pango_cairo_create_context(c);
pango_cairo_context_set_resolution(context, 96 * panel->scale);
PangoLayout *layout = pango_layout_new(context);
pango_layout_set_font_description(layout, panel_config.taskbarname_font_desc);
pango_layout_set_width(layout, taskbar_name->area.width * PANGO_SCALE);
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
@@ -213,6 +218,7 @@ void draw_taskbarname(void *obj, cairo_t *c)
draw_text(layout, c, 0, taskbar_name->posy, config_text, ((Panel *)taskbar_name->area.panel)->font_shadow);
g_object_unref(layout);
g_object_unref(context);
}
void update_desktop_names()

View File

@@ -23,8 +23,12 @@ set(SOURCES ../util/common.c
../util/strnatcmp.c
../util/cache.c
../util/timer.c
../util/test.c
../util/print.c
../util/signals.c
../config.c
../util/server.c
../util/strlcat.c
../launcher/apps-common.c
../launcher/icon-theme-common.c
md4.c

View File

@@ -100,7 +100,7 @@ char *file_name_from_path(const char *filepath)
void make_backup(const char *filepath)
{
gchar *backup_path = g_strdup_printf("%s.backup.%ld", filepath, time(NULL));
gchar *backup_path = g_strdup_printf("%s.backup.%lld", filepath, (long long)time(NULL));
copy_file(filepath, backup_path);
g_free(backup_path);
}

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

View File

@@ -20,7 +20,9 @@
#include "gui.h"
#include "background_gui.h"
#include "gradient_gui.h"
#include "strlcat.h"
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,
@@ -180,7 +182,7 @@ void applyClicked(GtkWidget *widget, gpointer data)
gchar *filepath = get_current_theme_path();
if (filepath) {
if (config_is_manual(filepath)) {
gchar *backup_path = g_strdup_printf("%s.backup.%ld", filepath, time(NULL));
gchar *backup_path = g_strdup_printf("%s.backup.%lld", filepath, (long long)time(NULL));
copy_file(filepath, backup_path);
g_free(backup_path);
}
@@ -599,6 +601,32 @@ void create_panel(GtkWidget *parent)
"for centered panels, it is evenly distributed on both sides of the panel."),
NULL);
row++;
col = 2;
label = gtk_label_new(_("Scale relative to DPI"));
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++;
scale_relative_to_dpi = gtk_spin_button_new_with_range(0, 9000, 1);
gtk_widget_show(scale_relative_to_dpi);
gtk_table_attach(GTK_TABLE(table), scale_relative_to_dpi, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0);
col++;
row++;
col = 2;
label = gtk_label_new(_("Scale relative to screen height"));
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++;
scale_relative_to_screen_height = gtk_spin_button_new_with_range(0, 9000, 1);
gtk_widget_show(scale_relative_to_screen_height);
gtk_table_attach(GTK_TABLE(table), scale_relative_to_screen_height, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0);
col++;
change_paragraph(parent);
label = gtk_label_new(_("<b>Appearance</b>"));
@@ -1256,7 +1284,8 @@ gboolean panel_contains(const char *value)
char *get_panel_items()
{
char *result = calloc(1, 256 * sizeof(char));
size_t buf_size = 256;
char *result = calloc(buf_size, 1);
GtkTreeModel *model = GTK_TREE_MODEL(panel_items);
GtkTreeIter i;
@@ -1267,7 +1296,7 @@ char *get_panel_items()
while (1) {
gchar *v;
gtk_tree_model_get(model, &i, itemsColValue, &v, -1);
strcat(result, v);
strlcat(result, v, buf_size);
if (!gtk_tree_model_iter_next(model, &i)) {
break;
@@ -1312,19 +1341,19 @@ void set_panel_items(const char *items)
} else if (v == ':') {
separator_index++;
buffer[0] = 0;
sprintf(buffer, "%s %d", _("Separator"), separator_index + 1);
snprintf(buffer, sizeof(buffer), "%s %d", _("Separator"), separator_index + 1);
name = buffer;
value = ":";
} else if (v == 'E') {
execp_index++;
buffer[0] = 0;
sprintf(buffer, "%s %d", _("Executor"), execp_index + 1);
snprintf(buffer, sizeof(buffer), "%s %d", _("Executor"), execp_index + 1);
name = buffer;
value = "E";
} else if (v == 'P') {
button_index++;
buffer[0] = 0;
sprintf(buffer, "%s %d", _("Button"), button_index + 1);
snprintf(buffer, sizeof(buffer), "%s %d", _("Button"), button_index + 1);
name = buffer;
value = "P";
} else {
@@ -4097,7 +4126,7 @@ void create_separator(GtkWidget *notebook, int i)
Separator *separator = &g_array_index(separators, Separator, i);
separator->name[0] = 0;
sprintf(separator->name, "%s %d", _("Separator"), i + 1);
snprintf(separator->name, sizeof(separator->name), "%s %d", _("Separator"), i + 1);
separator->page_label = gtk_label_new(separator->name);
gtk_widget_show(separator->page_label);
separator->page_separator = gtk_vbox_new(FALSE, DEFAULT_HOR_SPACING);
@@ -4223,7 +4252,7 @@ void create_execp(GtkWidget *notebook, int i)
Executor *executor = &g_array_index(executors, Executor, i);
executor->name[0] = 0;
sprintf(executor->name, "%s %d", _("Executor"), i + 1);
snprintf(executor->name, sizeof(executor->name), "%s %d", _("Executor"), i + 1);
executor->page_label = gtk_label_new(executor->name);
gtk_widget_show(executor->page_label);
executor->page_execp = gtk_vbox_new(FALSE, DEFAULT_HOR_SPACING);
@@ -4644,7 +4673,7 @@ void create_button(GtkWidget *notebook, int i)
Button *button = &g_array_index(buttons, Button, i);
button->name[0] = 0;
sprintf(button->name, "%s %d", _("Button"), i + 1);
snprintf(button->name, sizeof(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);
@@ -5033,7 +5062,7 @@ void separator_update_indices()
{
for (int i = 0; i < separators->len; i++) {
Separator *separator = &g_array_index(separators, Separator, i);
sprintf(separator->name, "%s %d", _("Separator"), i + 1);
snprintf(separator->name, sizeof(separator->name), "%s %d", _("Separator"), i + 1);
gtk_label_set_text(GTK_LABEL(separator->page_label), separator->name);
}
@@ -5051,7 +5080,7 @@ void separator_update_indices()
separator_index++;
char buffer[256];
buffer[0] = 0;
sprintf(buffer, "%s %d", _("Separator"), separator_index + 1);
snprintf(buffer, sizeof(buffer), "%s %d", _("Separator"), separator_index + 1);
gtk_list_store_set(panel_items, &iter, itemsColName, buffer, -1);
}
@@ -5065,7 +5094,7 @@ void execp_update_indices()
{
for (int i = 0; i < executors->len; i++) {
Executor *executor = &g_array_index(executors, Executor, i);
sprintf(executor->name, "%s %d", _("Executor"), i + 1);
snprintf(executor->name, sizeof(executor->name), "%s %d", _("Executor"), i + 1);
gtk_label_set_text(GTK_LABEL(executor->page_label), executor->name);
}
@@ -5083,7 +5112,7 @@ void execp_update_indices()
execp_index++;
char buffer[256];
buffer[0] = 0;
sprintf(buffer, "%s %d", _("Executor"), execp_index + 1);
snprintf(buffer, sizeof(buffer), "%s %d", _("Executor"), execp_index + 1);
gtk_list_store_set(panel_items, &iter, itemsColName, buffer, -1);
}
@@ -5097,7 +5126,7 @@ 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);
snprintf(button->name, sizeof(button->name), "%s %d", _("Button"), i + 1);
gtk_label_set_text(GTK_LABEL(button->page_label), button->name);
}
@@ -5115,7 +5144,7 @@ void button_update_indices()
button_index++;
char buffer[256];
buffer[0] = 0;
sprintf(buffer, "%s %d", _("Button"), button_index + 1);
snprintf(buffer, sizeof(buffer), "%s %d", _("Button"), button_index + 1);
gtk_list_store_set(panel_items, &iter, itemsColName, buffer, -1);
}

View File

@@ -9,6 +9,7 @@
#include "../launcher/icon-theme-common.h"
// panel
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,

View File

@@ -69,23 +69,23 @@ void config_read_file(const char *path)
if (!config_has_panel_items) {
char panel_items[256];
panel_items[0] = 0;
strcat(panel_items, "T");
strlcat(panel_items, "T", sizeof(panel_items));
if (config_has_battery) {
if (config_battery_enabled)
strcat(panel_items, "B");
strlcat(panel_items, "B", sizeof(panel_items));
} else {
if (no_items_battery_enabled)
strcat(panel_items, "B");
strlcat(panel_items, "B", sizeof(panel_items));
}
if (config_has_systray) {
if (config_systray_enabled)
strcat(panel_items, "S");
strlcat(panel_items, "S", sizeof(panel_items));
} else {
if (no_items_systray_enabled)
strcat(panel_items, "S");
strlcat(panel_items, "S", sizeof(panel_items));
}
if (no_items_clock_enabled)
strcat(panel_items, "C");
strlcat(panel_items, "C", sizeof(panel_items));
set_panel_items(panel_items);
}
}
@@ -242,13 +242,13 @@ void config_write_backgrounds(FILE *fp)
char sides[10];
sides[0] = '\0';
if (sideTop)
strcat(sides, "T");
strlcat(sides, "T", sizeof(sides));
if (sideBottom)
strcat(sides, "B");
strlcat(sides, "B", sizeof(sides));
if (sideLeft)
strcat(sides, "L");
strlcat(sides, "L", sizeof(sides));
if (sideRight)
strcat(sides, "R");
strlcat(sides, "R", sizeof(sides));
fprintf(fp, "border_sides = %s\n", sides);
fprintf(fp, "border_content_tint_weight = %d\n", (int)(border_weight));
@@ -378,6 +378,13 @@ void config_write_panel(FILE *fp)
(int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(mouse_pressed_icon_saturation)),
(int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(mouse_pressed_icon_brightness)));
fprintf(fp,
"scale_relative_to_dpi = %d\n",
(int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(scale_relative_to_dpi)));
fprintf(fp,
"scale_relative_to_screen_height = %d\n",
(int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(scale_relative_to_screen_height)));
fprintf(fp, "\n");
}
@@ -478,7 +485,7 @@ void config_write_task_font_color(FILE *fp, char *name, GtkWidget *task_color)
GdkColor color;
gtk_color_button_get_color(GTK_COLOR_BUTTON(task_color), &color);
char full_name[128];
sprintf(full_name, "task%s_font_color", name);
snprintf(full_name, sizeof(full_name), "task%s_font_color", name);
config_write_color(fp, full_name, color, gtk_color_button_get_alpha(GTK_COLOR_BUTTON(task_color)) * 100 / 0xffff);
}
@@ -489,7 +496,7 @@ void config_write_task_icon_osb(FILE *fp,
GtkWidget *widget_brightness)
{
char full_name[128];
sprintf(full_name, "task%s_icon_asb", name);
snprintf(full_name, sizeof(full_name), "task%s_icon_asb", name);
fprintf(fp,
"%s = %d %d %d\n",
full_name,
@@ -501,7 +508,7 @@ void config_write_task_icon_osb(FILE *fp,
void config_write_task_background(FILE *fp, char *name, GtkWidget *task_background)
{
char full_name[128];
sprintf(full_name, "task%s_background_id", name);
snprintf(full_name, sizeof(full_name), "task%s_background_id", name);
fprintf(fp, "%s = %d\n", full_name, gtk_combo_box_get_active(GTK_COMBO_BOX(task_background)));
}
@@ -1108,7 +1115,13 @@ void add_entry(char *key, char *value)
char *value1 = 0, *value2 = 0, *value3 = 0;
/* Gradients */
if (strcmp(key, "gradient") == 0) {
if (strcmp(key, "scale_relative_to_dpi") == 0) {
extract_values(value, &value1, &value2, &value3);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(scale_relative_to_dpi), atoi(value1));
} else if (strcmp(key, "scale_relative_to_screen_height") == 0) {
extract_values(value, &value1, &value2, &value3);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(scale_relative_to_screen_height), atoi(value1));
} else if (strcmp(key, "gradient") == 0) {
finalize_gradient();
GradientConfigType t;
if (g_str_equal(value, "horizontal"))

View File

@@ -207,7 +207,7 @@ gboolean update_snapshot(gpointer ignored)
char hash[MD4_HEX_SIZE + 4];
md4hexf(path, hash);
strcat(hash, ".png");
strlcat(hash, ".png", sizeof(hash));
gchar *snap = g_build_filename(g_get_user_cache_dir(), "tint2", hash, NULL);
pixbuf = force_refresh ? NULL : gdk_pixbuf_new_from_file(snap, NULL);

View File

@@ -31,9 +31,9 @@ static int x, y, width, height;
static gboolean just_shown;
// the next functions are helper functions for tooltip handling
void start_show_timeout();
void start_hide_timeout();
void stop_tooltip_timeout();
void start_show_timer();
void start_hide_timer();
void stop_tooltip_timer();
void tooltip_init_fonts();
@@ -44,6 +44,9 @@ void default_tooltip()
// give the tooltip some reasonable default values
memset(&g_tooltip, 0, sizeof(Tooltip));
INIT_TIMER(g_tooltip.visibility_timer);
INIT_TIMER(g_tooltip.update_timer);
g_tooltip.font_color.rgb[0] = 1;
g_tooltip.font_color.rgb[1] = 1;
g_tooltip.font_color.rgb[2] = 1;
@@ -53,8 +56,9 @@ void default_tooltip()
void cleanup_tooltip()
{
stop_tooltip_timeout();
stop_timeout(g_tooltip.update_timeout);
stop_tooltip_timer();
destroy_timer(&g_tooltip.visibility_timer);
destroy_timer(&g_tooltip.update_timer);
tooltip_hide(NULL);
tooltip_update_contents_for(NULL);
if (g_tooltip.window)
@@ -121,9 +125,9 @@ void tooltip_trigger_show(Area *area, Panel *p, XEvent *e)
if (g_tooltip.mapped && g_tooltip.area != area) {
tooltip_update_contents_for(area);
tooltip_update();
stop_tooltip_timeout();
stop_tooltip_timer();
} else if (!g_tooltip.mapped) {
start_show_timeout();
start_show_timer();
}
}
@@ -149,7 +153,9 @@ void tooltip_update_geometry()
cairo_surface_t *cs = cairo_xlib_surface_create(server.display, g_tooltip.window, server.visual, width, height);
cairo_t *c = cairo_create(cs);
PangoLayout *layout = pango_cairo_create_layout(c);
PangoContext *context = pango_cairo_create_context(c);
pango_cairo_context_set_resolution(context, 96 * panel->scale);
PangoLayout *layout = pango_layout_new(context);
pango_layout_set_font_description(layout, g_tooltip.font_desc);
PangoRectangle r1, r2;
@@ -157,7 +163,7 @@ void tooltip_update_geometry()
pango_layout_get_pixel_extents(layout, &r1, &r2);
int max_width = MIN(r2.width * 5, screen_width * 2 / 3);
if (g_tooltip.image && cairo_image_surface_get_width(g_tooltip.image) > 0) {
max_width = left_right_bg_border_width(g_tooltip.bg) + 2 * g_tooltip.paddingx +
max_width = left_right_bg_border_width(g_tooltip.bg) + 2 * g_tooltip.paddingx * panel->scale +
cairo_image_surface_get_width(g_tooltip.image);
}
pango_layout_set_width(layout, max_width * PANGO_SCALE);
@@ -165,12 +171,12 @@ void tooltip_update_geometry()
pango_layout_set_text(layout, g_tooltip.tooltip_text ? g_tooltip.tooltip_text : "1234567890abcdef", -1);
pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
pango_layout_get_pixel_extents(layout, &r1, &r2);
width = left_right_bg_border_width(g_tooltip.bg) + 2 * g_tooltip.paddingx + r2.width;
height = top_bottom_bg_border_width(g_tooltip.bg) + 2 * g_tooltip.paddingy + r2.height;
width = left_right_bg_border_width(g_tooltip.bg) + 2 * g_tooltip.paddingx * panel->scale + r2.width;
height = top_bottom_bg_border_width(g_tooltip.bg) + 2 * g_tooltip.paddingy * panel->scale + r2.height;
if (g_tooltip.image && cairo_image_surface_get_width(g_tooltip.image) > 0) {
width = left_right_bg_border_width(g_tooltip.bg) + 2 * g_tooltip.paddingx +
width = left_right_bg_border_width(g_tooltip.bg) + 2 * g_tooltip.paddingx * panel->scale +
cairo_image_surface_get_width(g_tooltip.image);
height += g_tooltip.paddingy + cairo_image_surface_get_height(g_tooltip.image);
height += g_tooltip.paddingy * panel->scale + cairo_image_surface_get_height(g_tooltip.image);
}
if (panel_horizontal && panel_position & BOTTOM)
@@ -183,6 +189,7 @@ void tooltip_update_geometry()
x = panel->posx - width;
g_object_unref(layout);
g_object_unref(context);
cairo_destroy(c);
cairo_surface_destroy(cs);
}
@@ -239,6 +246,7 @@ void tooltip_update()
tooltip_hide(0);
return;
}
Panel *panel = g_tooltip.panel;
tooltip_update_geometry();
if (just_shown) {
@@ -273,7 +281,9 @@ void tooltip_update()
Color fc = g_tooltip.font_color;
cairo_set_source_rgba(c, fc.rgb[0], fc.rgb[1], fc.rgb[2], fc.alpha);
PangoLayout *layout = pango_cairo_create_layout(c);
PangoContext *context = pango_cairo_create_context(c);
pango_cairo_context_set_resolution(context, 96 * panel->scale);
PangoLayout *layout = pango_layout_new(context);
pango_layout_set_font_description(layout, g_tooltip.font_desc);
pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
pango_layout_set_text(layout, g_tooltip.tooltip_text, -1);
@@ -285,15 +295,16 @@ void tooltip_update()
// I do not know why this is the right way, but with the below cairo_move_to it seems to be centered (horiz. and
// vert.)
cairo_move_to(c,
-r1.x / 2 + left_bg_border_width(g_tooltip.bg) + g_tooltip.paddingx,
-r1.y / 2 + 1 + top_bg_border_width(g_tooltip.bg) + g_tooltip.paddingy);
-r1.x / 2 + left_bg_border_width(g_tooltip.bg) + g_tooltip.paddingx * panel->scale,
-r1.y / 2 + 1 + top_bg_border_width(g_tooltip.bg) + g_tooltip.paddingy * panel->scale);
pango_cairo_show_layout(c, layout);
g_object_unref(layout);
g_object_unref(context);
if (g_tooltip.image) {
cairo_translate(c,
left_bg_border_width(g_tooltip.bg) + g_tooltip.paddingx,
height - bottom_bg_border_width(g_tooltip.bg) - g_tooltip.paddingy - cairo_image_surface_get_height(g_tooltip.image));
left_bg_border_width(g_tooltip.bg) + g_tooltip.paddingx * panel->scale,
height - bottom_bg_border_width(g_tooltip.bg) - g_tooltip.paddingy * panel->scale - cairo_image_surface_get_height(g_tooltip.image));
cairo_set_source_surface(c, g_tooltip.image, 0, 0);
cairo_paint(c);
}
@@ -306,10 +317,10 @@ void tooltip_trigger_hide()
{
if (g_tooltip.mapped) {
tooltip_update_contents_for(NULL);
start_hide_timeout();
start_hide_timer();
} else {
// tooltip not visible yet, but maybe a timeout is still pending
stop_tooltip_timeout();
// tooltip not visible yet, but maybe a timer is still pending
stop_tooltip_timer();
}
}
@@ -323,19 +334,19 @@ void tooltip_hide(void *arg)
g_tooltip.area = NULL;
}
void start_show_timeout()
void start_show_timer()
{
change_timeout(&g_tooltip.timeout, g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
change_timer(&g_tooltip.visibility_timer, true, g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
}
void start_hide_timeout()
void start_hide_timer()
{
change_timeout(&g_tooltip.timeout, g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
change_timer(&g_tooltip.visibility_timer, true, g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
}
void stop_tooltip_timeout()
void stop_tooltip_timer()
{
stop_timeout(g_tooltip.timeout);
stop_timer(&g_tooltip.visibility_timer);
}
void tooltip_update_contents_timeout(void *arg)
@@ -356,7 +367,7 @@ void tooltip_update_contents_for(Area *area)
if (g_tooltip.image)
cairo_surface_reference(g_tooltip.image);
else
change_timeout(&g_tooltip.update_timeout, 300, 0, tooltip_update_contents_timeout, NULL);
change_timer(&g_tooltip.update_timer, true, 300, 0, tooltip_update_contents_timeout, NULL);
}
g_tooltip.area = area;
}

View File

@@ -36,8 +36,8 @@ typedef struct {
PangoFontDescription *font_desc;
Color font_color;
Background *bg;
timeout *timeout;
timeout *update_timeout;
Timer visibility_timer;
Timer update_timer;
cairo_surface_t *image;
} Tooltip;

View File

@@ -929,10 +929,8 @@ void area_compute_text_geometry(Area *area,
const char *line2,
PangoFontDescription *line1_font_desc,
PangoFontDescription *line2_font_desc,
int *line1_height_ink,
int *line1_height,
int *line1_width,
int *line2_height_ink,
int *line2_height,
int *line2_width)
{
@@ -941,7 +939,6 @@ void area_compute_text_geometry(Area *area,
if (line1 && line1[0])
get_text_size2(line1_font_desc,
line1_height_ink,
line1_height,
line1_width,
available_h,
@@ -950,13 +947,14 @@ void area_compute_text_geometry(Area *area,
strlen(line1),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
PANGO_ALIGN_CENTER,
FALSE,
((Panel*)area->panel)->scale);
else
*line1_width = *line1_height_ink = *line1_height = 0;
*line1_width = *line1_height = 0;
if (line2 && line2[0])
get_text_size2(line2_font_desc,
line2_height_ink,
line2_height,
line2_width,
available_h,
@@ -965,9 +963,11 @@ void area_compute_text_geometry(Area *area,
strlen(line2),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
PANGO_ALIGN_CENTER,
FALSE,
((Panel*)area->panel)->scale);
else
*line2_width = *line2_height_ink = *line2_height = 0;
*line2_width = *line2_height = 0;
}
int text_area_compute_desired_size(Area *area,
@@ -976,16 +976,14 @@ int text_area_compute_desired_size(Area *area,
PangoFontDescription *line1_font_desc,
PangoFontDescription *line2_font_desc)
{
int line1_height_ink, line1_height, line1_width, line2_height_ink, line2_height, line2_width;
int line1_height, line1_width, line2_height, line2_width;
area_compute_text_geometry(area,
line1,
line2,
line1_font_desc,
line2_font_desc,
&line1_height_ink,
&line1_height,
&line1_width,
&line2_height_ink,
&line2_height,
&line2_width);
@@ -1010,17 +1008,15 @@ gboolean resize_text_area(Area *area,
schedule_redraw(area);
int line1_height_ink, line1_height, line1_width;
int line2_height_ink, line2_height, line2_width;
int line1_height, line1_width;
int line2_height, line2_width;
area_compute_text_geometry(area,
line1,
line2,
line1_font_desc,
line2_font_desc,
&line1_height_ink,
&line1_height,
&line1_width,
&line2_height_ink,
&line2_height,
&line2_width);
@@ -1067,12 +1063,16 @@ void draw_text_area(Area *area,
PangoFontDescription *line2_font_desc,
int line1_posy,
int line2_posy,
Color *color)
Color *color,
double scale)
{
int inner_w, inner_h;
area_compute_inner_size(area, &inner_w, &inner_h);
PangoLayout *layout = pango_cairo_create_layout(c);
PangoContext *context = pango_cairo_create_context(c);
pango_cairo_context_set_resolution(context, 96 * scale);
PangoLayout *layout = pango_layout_new(context);
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
@@ -1096,6 +1096,7 @@ void draw_text_area(Area *area,
}
g_object_unref(layout);
g_object_unref(context);
}
Area *compute_element_area(Area *area, Element element)

View File

@@ -273,10 +273,8 @@ void area_compute_text_geometry(Area *area,
const char *line2,
PangoFontDescription *line1_font_desc,
PangoFontDescription *line2_font_desc,
int *line1_height_ink,
int *line1_height,
int *line1_width,
int *line2_height_ink,
int *line2_height,
int *line2_width);
int text_area_compute_desired_size(Area *area,
@@ -299,7 +297,8 @@ void draw_text_area(Area *area,
PangoFontDescription *line2_font_desc,
int line1_posy,
int line2_posy,
Color *color);
Color *color,
double scale);
int left_border_width(Area *a);
int right_border_width(Area *a);

View File

@@ -191,7 +191,7 @@ const char *signal_name(int sig)
return "SIGSYS: Bad system call.";
}
static char s[64];
sprintf(s, "SIG=%d: Unknown", sig);
snprintf(s, sizeof(s), "SIG=%d: Unknown", sig);
return s;
}
@@ -266,7 +266,7 @@ extern char *config_path;
int setenvd(const char *name, const int value)
{
char buf[256];
sprintf(buf, "%d", value);
snprintf(buf, sizeof(buf), "%d", value);
return setenv(name, buf, 1);
}
@@ -461,9 +461,10 @@ char *expand_tilde(const char *s)
{
const gchar *home = g_get_home_dir();
if (home && (strcmp(s, "~") == 0 || strstr(s, "~/") == s)) {
char *result = calloc(strlen(home) + strlen(s), 1);
strcat(result, home);
strcat(result, s + 1);
size_t buf_size = strlen(home) + strlen(s);
char *result = calloc(buf_size, 1);
strlcat(result, home, buf_size);
strlcat(result, s + 1, buf_size);
return result;
} else {
return strdup(s);
@@ -476,14 +477,16 @@ char *contract_tilde(const char *s)
if (!home)
return strdup(s);
char *home_slash = calloc(strlen(home) + 2, 1);
strcat(home_slash, home);
strcat(home_slash, "/");
size_t buf_size = strlen(home) + 2;
char *home_slash = calloc(buf_size, 1);
strlcat(home_slash, home, buf_size);
strlcat(home_slash, "/", buf_size);
if ((strcmp(s, home) == 0 || strstr(s, home_slash) == s)) {
char *result = calloc(strlen(s) - strlen(home) + 2, 1);
strcat(result, "~");
strcat(result, s + strlen(home));
size_t buf_size2 = strlen(s) - strlen(home) + 2;
char *result = calloc(buf_size2, 1);
strlcat(result, "~", buf_size2);
strlcat(result, s + strlen(home), buf_size2);
free(home_slash);
return result;
} else {
@@ -786,14 +789,10 @@ Imlib_Image load_image(const char *path, int cached)
{
Imlib_Image image;
#ifdef HAVE_RSVG
if (cached) {
image = imlib_load_image_immediately(path);
} else {
image = imlib_load_image_immediately_without_cache(path);
}
image = imlib_load_image(path);
if (!image && g_str_has_suffix(path, ".svg")) {
char tmp_filename[128];
sprintf(tmp_filename, "/tmp/tint2-%d.png", (int)getpid());
snprintf(tmp_filename, sizeof(tmp_filename), "/tmp/tint2-%d.png", (int)getpid());
int fd = open(tmp_filename, O_CREAT | O_EXCL, 0600);
if (fd >= 0) {
// We fork here because librsvg allocates memory like crazy
@@ -815,19 +814,17 @@ Imlib_Image load_image(const char *path, int cached)
// Parent
close(fd);
waitpid(pid, 0, 0);
image = imlib_load_image_immediately_without_cache(tmp_filename);
image = imlib_load_image_immediately(tmp_filename);
unlink(tmp_filename);
}
}
} else
#endif
{
if (cached) {
image = imlib_load_image_immediately(path);
} else {
image = imlib_load_image_immediately_without_cache(path);
}
image = imlib_load_image(path);
}
imlib_context_set_image(image);
imlib_image_set_changes_on_disk();
return image;
}
@@ -921,30 +918,35 @@ void clear_pixmap(Pixmap p, int x, int y, int w, int h)
XRenderFreePicture(server.display, pict);
}
void get_text_size2(const PangoFontDescription *font,
int *height_ink,
int *height,
int *width,
int available_height,
int available_width,
const char *text,
int text_len,
PangoWrapMode wrap,
PangoEllipsizeMode ellipsis,
gboolean markup)
void get_text_size(const PangoFontDescription *font,
int *height,
int *width,
int available_height,
int available_width,
const char *text,
int text_len,
PangoWrapMode wrap,
PangoEllipsizeMode ellipsis,
PangoAlignment alignment,
gboolean markup,
double scale)
{
PangoRectangle rect_ink, rect;
available_width = MAX(0, available_width);
available_height = MAX(0, available_height);
Pixmap pmap = XCreatePixmap(server.display, server.root_win, available_height, available_width, server.depth);
cairo_surface_t *cs =
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, available_height, available_width);
cairo_xlib_surface_create(server.display, pmap, server.visual, available_height, available_width);
cairo_t *c = cairo_create(cs);
PangoLayout *layout = pango_cairo_create_layout(c);
PangoContext *context = pango_cairo_create_context(c);
pango_cairo_context_set_resolution(context, 96 * scale);
PangoLayout *layout = pango_layout_new(context);
pango_layout_set_width(layout, available_width * PANGO_SCALE);
pango_layout_set_height(layout, available_height * PANGO_SCALE);
pango_layout_set_alignment(layout, alignment);
pango_layout_set_wrap(layout, wrap);
pango_layout_set_ellipsize(layout, ellipsis);
pango_layout_set_font_description(layout, font);
@@ -955,14 +957,63 @@ void get_text_size2(const PangoFontDescription *font,
pango_layout_set_markup(layout, text, text_len);
pango_layout_get_pixel_extents(layout, &rect_ink, &rect);
*height_ink = rect_ink.height;
*height = rect.height;
*width = rect.width;
// fprintf(stderr, "tint2: dimension : %d - %d\n", rect_ink.height, rect.height);
g_object_unref(layout);
g_object_unref(context);
cairo_destroy(c);
cairo_surface_destroy(cs);
XFreePixmap(server.display, pmap);
}
void get_text_size2(const PangoFontDescription *font,
int *height,
int *width,
int available_height,
int available_width,
const char *text,
int text_len,
PangoWrapMode wrap,
PangoEllipsizeMode ellipsis,
PangoAlignment alignment,
gboolean markup,
double scale)
{
get_text_size(font, height, width, available_height, available_width, text, text_len, wrap, ellipsis, alignment, markup, scale);
// We do multiple passes, because pango sucks
int actual_height, actual_width, overflow = 0;
while (true) {
get_text_size(font, &actual_height, &actual_width, *height, *width, text, text_len, wrap, ellipsis, alignment, markup, scale);
if (actual_height <= *height)
break;
if (*width >= available_width)
break;
overflow = 1;
fprintf(stderr, "tint2: text overflows, recomputing: available %dx%d, computed %dx%d, actual %dx%d: %s\n",
available_width,
available_height,
*width,
*height,
actual_width,
actual_height,
text);
(*width)++;
}
if (overflow) {
*height = actual_height;
fprintf(stderr, "tint2: text final size computed as: available %dx%d, computed %dx%d, actual %dx%d: %s\n",
available_width,
available_height,
*width,
*height,
actual_width,
actual_height,
text);
}
}
#if !GLIB_CHECK_VERSION(2, 34, 0)
@@ -1111,3 +1162,63 @@ void adjust_color(Color *color, int alpha, int saturation, int brightness)
color->rgb[1] = g / 255.;
color->rgb[2] = b / 255.;
}
void dump_image_data(const char *file_name, const char *name)
{
Imlib_Image image = load_image(file_name, false);
if (!image) {
fprintf(stderr, "tint2: Could not load image from file\n");
return;
}
gchar *header_name = g_strdup_printf("%s.h", name);
gchar *guard = g_strdup_printf("%s_h", name);
FILE *header = fopen(header_name, "wt");
fprintf(header,
"#ifndef %s\n"
"#define %s\n"
"\n"
"#include <Imlib2.h>\n"
"\n"
"extern int %s_width;\n"
"extern int %s_height;\n"
"extern DATA32 %s_data[];\n"
"\n"
"#endif\n",
guard,
guard,
name,
name,
name);
fclose(header);
g_free(guard);
g_free(header_name);
imlib_context_set_image(image);
gchar *source_name = g_strdup_printf("%s.c", name);
FILE *source = fopen(source_name, "wt");
fprintf(source,
"#include <%s.h>\n"
"\n"
"int %s_width = %d;\n"
"int %s_height = %d;\n"
"DATA32 %s_data[] = {",
name,
name,
imlib_image_get_width(),
name,
imlib_image_get_height(),
name);
size_t size = (size_t)imlib_image_get_width() * (size_t)imlib_image_get_height();
DATA32 *data = imlib_image_get_data_for_reading_only();
for (size_t i = 0; i < size; i++) {
fprintf(source, "%s%u", i == 0 ? "" : ", ", data[i]);
}
fprintf(source, "};\n");
fclose(source);
g_free(source_name);
imlib_free_image();
}

View File

@@ -7,12 +7,14 @@
#define COMMON_H
#define WM_CLASS_TINT "panel"
#define TINT2_PANGO_SLACK 0
#include <glib.h>
#include <Imlib2.h>
#include <pango/pangocairo.h>
#include "area.h"
#include "colors.h"
#include "strlcat.h"
#define MAX3(a, b, c) MAX(MAX(a, b), c)
#define MIN3(a, b, c) MIN(MIN(a, b), c)
@@ -112,7 +114,6 @@ void create_heuristic_mask(DATA32 *data, int w, int h);
void render_image(Drawable d, int x, int y);
void get_text_size2(const PangoFontDescription *font,
int *height_ink,
int *height,
int *width,
int available_height,
@@ -121,7 +122,9 @@ void get_text_size2(const PangoFontDescription *font,
int text_len,
PangoWrapMode wrap,
PangoEllipsizeMode ellipsis,
gboolean markup);
PangoAlignment alignment,
gboolean markup,
double scale);
void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color, int font_shadow);
@@ -148,6 +151,8 @@ GString *tint2_g_string_replace(GString *s, const char *from, const char *to);
void get_image_mean_color(const Imlib_Image image, Color *mean_color);
void dump_image_data(const char *file_name, const char *name);
#define free_and_null(p) \
{ \
free(p); \

View File

@@ -19,11 +19,11 @@
**************************************************************************/
#include <X11/extensions/Xdamage.h>
#include <X11/extensions/Xrender.h>
#include <X11/extensions/Xrandr.h>
#include <X11/extensions/Xrender.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -311,6 +311,21 @@ void sort_monitors()
qsort(server.monitors, server.num_monitors, sizeof(Monitor), compare_monitor_pos);
}
int compute_dpi(XRRCrtcInfo *crtc, XRROutputInfo *output)
{
double width = output->mm_width;
double height = output->mm_height;
double x_res = crtc->width;
double y_res = crtc->height;
if (width > 0 && height > 0) {
int dpi_x = x_res / width * 25.4;
int dpi_y = y_res / height * 25.4;
return MAX(dpi_x, dpi_y);
}
return 0;
}
void get_monitors()
{
if (XineramaIsActive(server.display)) {
@@ -339,12 +354,22 @@ void get_monitors()
server.monitors[i_monitor].width = crtc_info->width;
server.monitors[i_monitor].height = crtc_info->height;
server.monitors[i_monitor].names = calloc((crtc_info->noutput + 1), sizeof(gchar *));
server.monitors[i_monitor].dpi = 96;
for (int j = 0; j < crtc_info->noutput; ++j) {
XRROutputInfo *output_info = XRRGetOutputInfo(server.display, res, crtc_info->outputs[j]);
fprintf(stderr, "tint2: xRandr: Linking output %s with crtc %d\n", output_info->name, i);
server.monitors[i_monitor].names[j] = g_strdup(output_info->name);
XRRFreeOutputInfo(output_info);
server.monitors[i_monitor].primary = crtc_info->outputs[j] == primary_output;
int dpi = compute_dpi(crtc_info, output_info);
if (dpi)
server.monitors[i_monitor].dpi = dpi;
fprintf(stderr,
BLUE "tint2: xRandr: Linking output %s with crtc %d, resolution %dx%d, DPI %d" RESET "\n",
output_info->name,
i,
server.monitors[i_monitor].width,
server.monitors[i_monitor].height,
server.monitors[i_monitor].dpi);
XRRFreeOutputInfo(output_info);
}
server.monitors[i_monitor].names[crtc_info->noutput] = NULL;
XRRFreeCrtcInfo(crtc_info);
@@ -357,6 +382,7 @@ void get_monitors()
server.monitors[i].width = info[i].width;
server.monitors[i].height = info[i].height;
server.monitors[i].names = NULL;
server.monitors[i].dpi = 96;
}
}
@@ -393,6 +419,7 @@ void get_monitors()
server.monitors[0].width = DisplayWidth(server.display, server.screen);
server.monitors[0].height = DisplayHeight(server.display, server.screen);
server.monitors[0].names = 0;
server.monitors[0].dpi = 96;
}
}
@@ -523,7 +550,8 @@ int get_current_desktop()
// fprintf(stderr, "tint2: \n");
// fprintf(stderr, "tint2: Work area size: %d x %d\n", work_area_width, work_area_height);
// fprintf(stderr, "tint2: Viewport pos: %d x %d\n", viewport_x, viewport_y);
// fprintf(stderr, "tint2: Viewport i: %d\n", (viewport_y / work_area_height) * ncols + viewport_x / work_area_width);
// fprintf(stderr, "tint2: Viewport i: %d\n", (viewport_y / work_area_height) * ncols + viewport_x /
//work_area_width);
int result = (viewport_y / work_area_height) * ncols + viewport_x / work_area_width;
return MAX(0, MIN(server.num_desktops - 1, result));

View File

@@ -107,6 +107,7 @@ typedef struct Monitor {
int y;
int width;
int height;
int dpi;
gboolean primary;
gchar **names;
} Monitor;

View File

@@ -1,9 +1,11 @@
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#ifndef TINT2CONF
#ifdef HAVE_SN
#include <libsn/sn.h>
#endif
#endif
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -34,6 +36,7 @@ void reset_signals()
sigprocmask(SIG_SETMASK, &signal_set, NULL);
}
#ifndef TINT2CONF
void init_signals()
{
// Set signal handlers
@@ -164,3 +167,4 @@ int get_signal_pending()
{
return signal_pending;
}
#endif

60
src/util/strlcat.c Normal file
View File

@@ -0,0 +1,60 @@
/* $NetBSD: strlcat.c,v 1.4 2005/05/16 06:55:48 lukem Exp $ */
/* from NetBSD: strlcat.c,v 1.16 2003/10/27 00:12:42 lukem Exp */
/* from OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "strlcat.h"
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}

16
src/util/strlcat.h Normal file
View File

@@ -0,0 +1,16 @@
#ifndef STRLCAT_H
#define STRLCAT_H
#include <stddef.h>
#include <stdint.h>
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t strlcat(char *dst, const char *src, size_t siz);
#endif

View File

@@ -58,10 +58,17 @@ err:
free(output_name);
}
static void crash(int sig)
{
kill(getpid(), SIGSEGV);
}
__attribute__((noreturn))
static void run_test_child(TestListItem *item)
{
reset_signals();
struct sigaction sa = {.sa_handler = crash};
sigaction(SIGINT, &sa, 0);
redirect_test_output(item->name);
bool result = true;
item->test(&result);
@@ -120,10 +127,12 @@ static Status run_test(TestListItem *item)
pid_t pid = fork();
if (pid == 0)
run_test_child(item);
struct sigaction sa = {.sa_handler = SIG_IGN};
sigaction(SIGINT, &sa, 0);
return run_test_parent(item, pid);
}
void run_all_tests()
void run_all_tests(bool verbose)
{
fprintf(stdout, BLUE "tint2: Running %d tests..." RESET "\n", g_list_length(all_tests));
size_t count = 0, succeeded = 0, failed = 0;
@@ -138,6 +147,19 @@ void run_all_tests()
} else {
fprintf(stdout, RED "failed" RESET "\n");
failed++;
if (verbose) {
char *log_name = test_log_name_from_test_name(item->name);
FILE *log = fopen(log_name, "rt");
if (log) {
char buffer[4096];
size_t num_read;
while ((num_read = fread(buffer, 1, sizeof(buffer), log)) > 0) {
fwrite(buffer, 1, num_read, stdout);
}
fclose(log);
}
free(log_name);
}
}
}
if (failed == 0)
@@ -146,14 +168,16 @@ void run_all_tests()
fprintf(stdout, BLUE "tint2: " RED "%lu" BLUE " out of %lu tests " RED "failed." RESET "\n", failed, count);
}
#if 0
TEST(dummy) {
int x = 2;
int y = 2;
ASSERT_EQUAL(x, y);
}
TEST(dummyBad) {
TEST(dummy_bad) {
int x = 2;
int y = 3;
ASSERT_EQUAL(x, y);
}
#endif

View File

@@ -16,7 +16,7 @@ void register_test_(Test *test, const char *name);
} \
void test_##name(Status *test_result_)
void run_all_tests();
void run_all_tests(bool verbose);
#define FAIL_TEST_ \
*test_result_ = FAILURE; \
@@ -29,7 +29,7 @@ void run_all_tests();
#define ASSERT_EQUAL(a, b) \
if (!(a == b)) { \
printf("Assertion failed: %s == %s: ", #a, #b); \
printf("%s:%d: Assertion failed: %s == %s: ", __FILE__, __LINE__, #a, #b); \
print(a); \
printf(" != "); \
print(b); \
@@ -38,7 +38,7 @@ void run_all_tests();
#define ASSERT_DIFFERENT(a, b) \
if (a == b) { \
printf("Assertion failed: %s != %s: ", #a, #b); \
printf("%s:%d: Assertion failed: %s != %s: ", __FILE__, __LINE__, #a, #b); \
print(a); \
printf(" == "); \
print(b); \
@@ -48,7 +48,7 @@ void run_all_tests();
#define ASSERT_STR_EQUAL(a, b) \
if (strcmp(a, b) != 0) { \
printf("Assertion failed: %s == %s: ", #a, #b); \
printf("%s:%d: Assertion failed: %s == %s: ", __FILE__, __LINE__, #a, #b); \
print(a); \
printf(" != "); \
print(b); \
@@ -57,7 +57,7 @@ void run_all_tests();
#define ASSERT_STR_DIFFERENT(a, b) \
if (strcmp(a, b) == 0) { \
printf("Assertion failed: %s != %s: ", #a, #b); \
printf("%s:%d: Assertion failed: %s != %s: ", __FILE__, __LINE__, #a, #b); \
print(a); \
printf(" == "); \
print(b); \

File diff suppressed because it is too large Load Diff

View File

@@ -21,45 +21,52 @@
#include <glib.h>
#include <time.h>
#include <sys/time.h>
#include "bool.h"
// Single shot timers (i.e. timers with interval_msec == 0) are deleted automatically as soon as they expire,
// i.e. you do not need to stop them, however it is safe to call stop_timeout for these timers.
// You can pass the address of the variable storing the pointer to the timer as 'self' in add_timeout, in which
// case it is used to clear the pointer if the timer is destroyed automatically. This enforces the timeout pointers
// to be either valid or NULL.
// Periodic timeouts are aligned to each other whenever possible, i.e. one interval_msec is an
// integral multiple of the other.
extern bool debug_timers;
typedef struct _timeout timeout;
typedef void TimerCallback(void *arg);
// Initializes default global data.
void default_timeout();
typedef struct {
char name_[64];
bool enabled_;
long long expiration_time_ms_;
int period_ms_;
TimerCallback *callback_;
void *arg_;
bool handled_;
} Timer;
// Cleans up: stops all timers and frees memory.
void cleanup_timeout();
#define DEFAULT_TIMER {"", 0, 0, 0, 0, 0, 0}
// Installs a timer with the first timeout after 'value_msec' and then an optional periodic timeout every
// 'interval_msec' (set it to 0 to prevent periodic timeouts).
// '_callback' is the function called when the timer reaches the timeout.
// 'arg' is the argument passed to the callback function.
// 'self' is an optional pointer to a timeout* variable. If non-NULL, the variable is set to NULL when the timer
// is destroyed (with stop_timeout, cleanup_timeout or when the timer expires and it is single-shot).
// Returns a pointer to the timer, which is needed for stopping/changing it.
timeout *add_timeout(int value_msec, int interval_msec, void (*_callback)(void *), void *arg, timeout **self);
#define INIT_TIMER(t) init_timer(&t, #t)
// Changes timer 't'. If it does not exist, a new timer is created, with self set to 't'.
void change_timeout(timeout **t, int value_msec, int interval_msec, void (*_callback)(void *), void *arg);
// Initialize the timer module.
void default_timers();
// Stops the timer 't'
void stop_timeout(timeout *t);
// Destroy the timer module.
void cleanup_timers();
// Get the time when the next installed timer will expire, or NULL if there is no timer.
// Do not free the pointer; but it is safe to change its contents.
struct timeval *get_next_timeout();
// Initialize a timer. Caller keeps ownership.
void init_timer(Timer *timer, const char *name);
// Callback of all expired timeouts
// Destroy a timer. Does not free() the pointer.
void destroy_timer(Timer *timer);
// Modify a timer.
void change_timer(Timer *timer, bool enabled, int delay_ms, int period_ms, TimerCallback *callback, void *arg);
void stop_timer(Timer *timer);
// Get the time duration to the next expiration time, or NULL if there is no active timer.
// Do not free the pointer; it is harmless to change its contents.
struct timeval *get_duration_to_next_timer_expiration();
// Trigger all expired timers, and reschedule them if they are periodic timers
void handle_expired_timers();
// Time helper functions.
// Returns -1 if t1 < t2, 0 if t1 == t2, 1 if t1 > t2
gint compare_timespecs(const struct timespec *t1, const struct timespec *t2);
@@ -69,6 +76,7 @@ struct timespec add_msec_to_timespec(struct timespec ts, int msec);
// At the first call returns zero.
double profiling_get_time();
// Get current time in seconds, from an unspecified origin.
double get_time();
#endif // TIMER_H

View File

@@ -49,8 +49,9 @@ char *addr2name(void *func)
free(strings);
return result;
#else
char *result = (char*) calloc(32, 1);
sprintf(result, "%p", func);
const size_t buf_size = 32;
char *result = (char*) calloc(buf_size, 1);
snprintf(result, buf_size, "%p", func);
return result;
#endif
}

View File

@@ -10,6 +10,7 @@ sys.setdefaultencoding('utf8')
import argparse
import datetime
import os
import re
import signal
import subprocess
import time
@@ -39,6 +40,10 @@ def print_err(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def clear_ansi_codes(s):
return re.sub(r"\x1B\[[0-9;]*[a-zA-Z]", "", s)
def run(cmd, output=False):
return subprocess.Popen(cmd,
stdin=devnull,
@@ -188,6 +193,7 @@ def test(tint2path, config, use_asan):
mem, mem_detail = get_mem_usage(tint2.pid)
stop(tint2)
out, _ = tint2.communicate()
out = clear_ansi_codes(out)
exitcode = tint2.returncode
if exitcode != 0 and exitcode != 23:
print("tint2 crashed with exit code {0}!".format(exitcode))
@@ -222,6 +228,41 @@ def test(tint2path, config, use_asan):
stop_xvfb()
def run_unit_tests(tint2path, use_asan):
print("# Unit tests", "(ASAN on)" if use_asan else "")
start_xvfb()
sleep(1)
start_xsettings()
start_wm()
sleep(1)
compton = start_compositor()
sleep(1)
os.environ["DEBUG_FPS"] = "1"
os.environ["ASAN_OPTIONS"] = "detect_leaks=1:exitcode=0"
tint2 = run([tint2path, "--test-verbose"], True)
time_limit = time.time() + 60
while tint2.poll() == None:
if time.time() < time_limit:
time.sleep(1)
continue
tint2.stop()
out, _ = tint2.communicate()
out = clear_ansi_codes(out)
exitcode = tint2.returncode
if exitcode != 0 and exitcode != 23:
print("tint2 crashed with exit code {0}!".format(exitcode))
print("Output:")
print("```\n" + out.strip() + "\n```")
return
if "tests succeeded" in out:
num_tests = [line for line in out.split("\n") if "tint2: Running" in line][0]
print("All {0} tests succeeded.".format(num_tests))
return
if "tests failed" in out:
print("```\n" + out.strip() + "\n```")
stop_xvfb()
def show_timestamp():
utc_datetime = datetime.datetime.utcnow()
print("Last updated:", utc_datetime.strftime("%Y-%m-%d %H:%M UTC"))
@@ -296,13 +337,13 @@ def compile_remotely_and_report(host):
print("Status: Failed!", error)
print("Output:")
print("```\n" + out.strip() + "\n```")
if "warning:" in out:
warnings = [ line for line in out.split("\n") if "warning:" in line and ".so." not in line.split(":", 1)[0] ]
if warnings:
print("Status: Succeeded with warnings!", warning)
print("Warnings:")
print("```", end="")
for line in out.split("\n"):
if "warning:" in line:
print(line, end="")
for line in warnings:
print(line, end="")
print("```", end="")
else:
print("Status: Succeeded in %.1f seconds" % (duration,), ok)
@@ -373,10 +414,11 @@ def main():
show_timestamp()
show_git_info(args.src_dir)
show_system_info()
compile_remotely_and_report("freebsd")
compile_remotely_and_report("openbsd")
compile_remotely_and_report("FreeBSD")
compile_remotely_and_report("OpenBSD")
for use_asan in [True, False]:
compile_and_report(args.src_dir, use_asan)
run_unit_tests("./build/tint2", use_asan)
run_tests(use_asan)

View File

@@ -1,9 +1,16 @@
// ADD PREDEFINED MACROS HERE!
#define HAVE_RSVG 1
#define HAVE_SN 1
#define DISABLE_BACKTRACE 1
#define ENABLE_BATTERY 1
#define ENABLE_UEVENT 1
#define GETTEXT_PACKAGE
#define HAVE_TRACING
#define ENABLE_EXECINFO
#define GETTEXT_PACKAGE "tint2conf"
#define HAS_GENERIC 1
#define HAVE_RSVG 1
#define HAVE_SN 1
#define HAVE_VERSION_H 1
#define INSTALL_PREFIX "/usr/local"
#define LOCALEDIR "/usr/local/share/locale"
#define SN_API_NOT_YET_FROZEN
#define _BSD_SOURCE
#define _DEFAULT_SOURCE
#define _POSIX_C_SOURCE=200809L
#define _WITH_GETLINE

View File

@@ -20,6 +20,9 @@ src/battery/battery.c
src/battery/battery.h
src/clock/clock.c
src/clock/clock.h
src/default_icon.c
src/default_icon.c
src/default_icon.h
src/execplugin/execplugin.c
src/execplugin/execplugin.h
src/launcher/launcher.c
@@ -58,6 +61,10 @@ src/util/blur.c
src/util/blur.h
src/util/common.c
src/util/common.h
src/util/server.c
src/util/server.h
src/util/strlcat.c
src/util/strlcat.h
src/util/timer.c
src/util/timer.h
src/util/window.c

View File

@@ -22,6 +22,11 @@
/usr/include/librsvg-2.0
/usr/include/gdk-pixbuf-2.0
/usr/include/startup-notification-1.0
/usr/include/gtk-2.0
/usr/lib/x86_64-linux-gnu/gtk-2.0/include
/usr/include/atk-1.0
/usr/include/gio-unix-2.0
/usr/include/harfbuzz
/usr/include
po
src/tint2conf/po