Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8242b494bc | ||
|
|
1c6377f570 | ||
|
|
dd1fd28114 | ||
|
|
b4610fcb6e | ||
|
|
eb0e6765f9 | ||
|
|
5ee278d3ca | ||
|
|
fb438031c3 | ||
|
|
e5380f8e29 | ||
|
|
c064ec70ed | ||
|
|
a9a9a753bc | ||
|
|
38bee65b58 | ||
|
|
f64cf199e4 | ||
|
|
0911dcaed1 | ||
|
|
c41d75e54e | ||
|
|
8e0bdcaedd | ||
|
|
be4554b89d | ||
|
|
82d7fdc8f9 | ||
|
|
e046cb88ab | ||
|
|
300ef518cb | ||
|
|
457d51e267 | ||
|
|
1b48efe738 | ||
|
|
40e01e2abf | ||
|
|
a7ca1b739b | ||
|
|
750cbd572c | ||
|
|
75c2a2084d | ||
|
|
9b17461f74 | ||
|
|
a185f625f9 | ||
|
|
3a9181eff5 | ||
|
|
5cea67171b | ||
|
|
328a35f949 | ||
|
|
cab9c3bddd | ||
|
|
5dd814773a | ||
|
|
f4384b786c | ||
|
|
5bc83561e0 | ||
|
|
375e965a3a | ||
|
|
67e25b8102 | ||
|
|
c96201930b | ||
|
|
6bf72a030a | ||
|
|
63d0d98a5c | ||
|
|
e739023529 | ||
|
|
a7a9c5cdae | ||
|
|
50822bd2fd | ||
|
|
00c79073f0 | ||
|
|
f5b36b37b6 | ||
|
|
c635f46439 | ||
|
|
16a359f944 | ||
|
|
9a972f4c25 | ||
|
|
9d06ac0157 | ||
|
|
cfac6a645d | ||
|
|
648c7c109f | ||
|
|
8946f93254 | ||
|
|
58e030de5d | ||
|
|
c2f8c210f8 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,3 +1,7 @@
|
|||||||
build
|
build
|
||||||
*.user
|
*.user
|
||||||
version.h
|
version.h
|
||||||
|
*.pyc
|
||||||
|
*.todo
|
||||||
|
packaging/make_ubuntu2.sh
|
||||||
|
test_*.log
|
||||||
|
|||||||
@@ -62,6 +62,17 @@ else()
|
|||||||
set(BACKTRACE_L_FLAGS "")
|
set(BACKTRACE_L_FLAGS "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
check_c_source_compiles(
|
||||||
|
"#define print(x) _Generic((x), default : print_unknown)(x) \n void print_unknown(){} \n int main () { print(0); }"
|
||||||
|
HAS_GENERIC)
|
||||||
|
|
||||||
|
if(HAS_GENERIC)
|
||||||
|
add_definitions(-DHAS_GENERIC)
|
||||||
|
set(CSTD "c11")
|
||||||
|
else()
|
||||||
|
set(CSTD "c99")
|
||||||
|
endif(HAS_GENERIC)
|
||||||
|
|
||||||
if( ENABLE_RSVG )
|
if( ENABLE_RSVG )
|
||||||
pkg_check_modules( RSVG librsvg-2.0>=2.14.0 )
|
pkg_check_modules( RSVG librsvg-2.0>=2.14.0 )
|
||||||
endif( ENABLE_RSVG )
|
endif( ENABLE_RSVG )
|
||||||
@@ -116,13 +127,14 @@ include_directories( ${PROJECT_BINARY_DIR}
|
|||||||
|
|
||||||
set( SOURCES src/config.c
|
set( SOURCES src/config.c
|
||||||
src/panel.c
|
src/panel.c
|
||||||
src/server.c
|
src/util/server.c
|
||||||
src/main.c
|
src/main.c
|
||||||
src/init.c
|
src/init.c
|
||||||
src/signals.c
|
src/util/signals.c
|
||||||
src/tracing.c
|
src/util/tracing.c
|
||||||
src/mouse_actions.c
|
src/mouse_actions.c
|
||||||
src/drag_and_drop.c
|
src/drag_and_drop.c
|
||||||
|
src/default_icon.c
|
||||||
src/clock/clock.c
|
src/clock/clock.c
|
||||||
src/systray/systraybar.c
|
src/systray/systraybar.c
|
||||||
src/launcher/launcher.c
|
src/launcher/launcher.c
|
||||||
@@ -146,7 +158,10 @@ set( SOURCES src/config.c
|
|||||||
src/util/timer.c
|
src/util/timer.c
|
||||||
src/util/cache.c
|
src/util/cache.c
|
||||||
src/util/color.c
|
src/util/color.c
|
||||||
|
src/util/strlcat.c
|
||||||
|
src/util/print.c
|
||||||
src/util/gradient.c
|
src/util/gradient.c
|
||||||
|
src/util/test.c
|
||||||
src/util/uevent.c
|
src/util/uevent.c
|
||||||
src/util/window.c )
|
src/util/window.c )
|
||||||
|
|
||||||
@@ -233,7 +248,7 @@ else()
|
|||||||
SET(TRACING_L_FLAGS "")
|
SET(TRACING_L_FLAGS "")
|
||||||
endif()
|
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}
|
link_directories( ${X11_LIBRARY_DIRS}
|
||||||
${PANGOCAIRO_LIBRARY_DIRS}
|
${PANGOCAIRO_LIBRARY_DIRS}
|
||||||
@@ -267,7 +282,7 @@ endif( RT_LIBRARY )
|
|||||||
target_link_libraries( tint2 m )
|
target_link_libraries( tint2 m )
|
||||||
|
|
||||||
add_dependencies( tint2 version )
|
add_dependencies( tint2 version )
|
||||||
set_target_properties( tint2 PROPERTIES COMPILE_FLAGS "-Wall -Wpointer-arith -fno-strict-aliasing -pthread -std=c99 ${ASAN_C_FLAGS} ${TRACING_C_FLAGS}" )
|
set_target_properties( tint2 PROPERTIES COMPILE_FLAGS "-Wall -Wpointer-arith -fno-strict-aliasing -pthread -std=${CSTD} ${ASAN_C_FLAGS} ${TRACING_C_FLAGS}" )
|
||||||
set_target_properties( tint2 PROPERTIES LINK_FLAGS "-pthread -fno-strict-aliasing ${ASAN_L_FLAGS} ${BACKTRACE_L_FLAGS} ${TRACING_L_FLAGS}" )
|
set_target_properties( tint2 PROPERTIES LINK_FLAGS "-pthread -fno-strict-aliasing ${ASAN_L_FLAGS} ${BACKTRACE_L_FLAGS} ${TRACING_L_FLAGS}" )
|
||||||
|
|
||||||
install( TARGETS tint2 DESTINATION bin )
|
install( TARGETS tint2 DESTINATION bin )
|
||||||
|
|||||||
16
ChangeLog
16
ChangeLog
@@ -1,8 +1,20 @@
|
|||||||
2017-11-10 master
|
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
|
||||||
|
`task_align = right` (issue #688)
|
||||||
- Enhancements:
|
- Enhancements:
|
||||||
- Added Spanish translation (contributed by Vicmz)
|
- Added Spanish translation (contributed by Vicmz)
|
||||||
- Executor: updated tooltip documentation (issue #676)
|
- Executor: updated tooltip documentation (issue #676)
|
||||||
- Systray: warn on duplicate config option systray_name_filter (issue #652)
|
- Systray: warn on duplicate config option systray_name_filter (issue #652)
|
||||||
|
- 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
|
2017-11-05 15.3
|
||||||
- Fixes:
|
- Fixes:
|
||||||
@@ -971,3 +983,5 @@ released tint-0.2
|
|||||||
.
|
.
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -1,5 +1,5 @@
|
|||||||
# Latest stable release: 15.3
|
# Latest stable release: 16.1
|
||||||
Changes: https://gitlab.com/o9000/tint2/blob/15.3/ChangeLog
|
Changes: https://gitlab.com/o9000/tint2/blob/16.1/ChangeLog
|
||||||
|
|
||||||
Documentation: [doc/tint2.md](doc/tint2.md)
|
Documentation: [doc/tint2.md](doc/tint2.md)
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ Compile it with (after you install the [dependencies](https://gitlab.com/o9000/t
|
|||||||
```
|
```
|
||||||
git clone https://gitlab.com/o9000/tint2.git
|
git clone https://gitlab.com/o9000/tint2.git
|
||||||
cd tint2
|
cd tint2
|
||||||
git checkout 15.3
|
git checkout 16.1
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake ..
|
cmake ..
|
||||||
@@ -61,9 +61,9 @@ tint2 is a simple panel/taskbar made for modern X window managers. It was specif
|
|||||||
|
|
||||||
# Known issues
|
# Known issues
|
||||||
|
|
||||||
* Graphic glitches on Intel graphics cards can be avoided by changing the acceleration method to UXA ([issue 595](https://gitlab.com/o9000/tint2/issues/595))
|
* Graphical glitches on Intel graphics cards can be avoided by changing the acceleration method to UXA ([issue 595](https://gitlab.com/o9000/tint2/issues/595))
|
||||||
* Window managers that do not follow exactly the EWMH specification might not interact well with tint2 (known issues for [awesome](https://gitlab.com/o9000/tint2/issues/385), [bspwm](https://gitlab.com/o9000/tint2/issues/524). [openbox-multihead](https://gitlab.com/o9000/tint2/issues/456))
|
* Window managers that do not follow exactly the EWMH specification might not interact well with tint2 ([issue 627](https://gitlab.com/o9000/tint2/issues/627)).
|
||||||
* Full transparency requires a compositor such as Compton (if not provided already by the window manager, as in Compiz/Unity, KDE or XFCE)
|
* Full transparency requires a compositor such as Compton (if not provided already by the window manager, as in Compiz/Unity, KDE or XFCE).
|
||||||
|
|
||||||
# How can I help out?
|
# How can I help out?
|
||||||
|
|
||||||
|
|||||||
@@ -605,7 +605,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_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_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_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("\x1b[2J");</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 '\e[2J'</code>, C: <code>printf("\x1b[2J");</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 = [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_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>
|
<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>
|
||||||
|
|||||||
@@ -199,9 +199,9 @@ pre {
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1 id="latest-stable-release-15-3"><span class="md2man-title">Latest</span> <span class="md2man-section">stable</span> <span class="md2man-date">release:</span> <span class="md2man-source">15.3</span><a name="latest-stable-release-15-3" href="#latest-stable-release-15-3" class="md2man-permalink" title="permalink"></a></h1><p>Changes: <a href="https://gitlab.com/o9000/tint2/blob/15.3/ChangeLog">https://gitlab.com/o9000/tint2/blob/15.3/ChangeLog</a></p><p>Documentation: <a href="manual.html">manual.html</a></p><p>Compile it with (after you install the <a href="https://gitlab.com/o9000/tint2/wikis/Install#dependencies">dependencies</a>):</p><pre class="highlight plaintext"><code>git clone https://gitlab.com/o9000/tint2.git
|
<h1 id="latest-stable-release-16-1"><span class="md2man-title">Latest</span> <span class="md2man-section">stable</span> <span class="md2man-date">release:</span> <span class="md2man-source">16.1</span><a name="latest-stable-release-16-1" href="#latest-stable-release-16-1" class="md2man-permalink" title="permalink"></a></h1><p>Changes: <a href="https://gitlab.com/o9000/tint2/blob/16.1/ChangeLog">https://gitlab.com/o9000/tint2/blob/16.1/ChangeLog</a></p><p>Documentation: <a href="manual.html">manual.html</a></p><p>Compile it with (after you install the <a href="https://gitlab.com/o9000/tint2/wikis/Install#dependencies">dependencies</a>):</p><pre class="highlight plaintext"><code>git clone https://gitlab.com/o9000/tint2.git
|
||||||
cd tint2
|
cd tint2
|
||||||
git checkout 15.3
|
git checkout 16.1
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake ..
|
cmake ..
|
||||||
@@ -239,9 +239,9 @@ update-mime-database /usr/local/share/mime
|
|||||||
</ul>
|
</ul>
|
||||||
<h1 id="known-issues">Known issues<a name="known-issues" href="#known-issues" class="md2man-permalink" title="permalink"></a></h1>
|
<h1 id="known-issues">Known issues<a name="known-issues" href="#known-issues" class="md2man-permalink" title="permalink"></a></h1>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Graphic glitches on Intel graphics cards can be avoided by changing the acceleration method to UXA (<a href="https://gitlab.com/o9000/tint2/issues/595">issue 595</a>)</li>
|
<li>Graphical glitches on Intel graphics cards can be avoided by changing the acceleration method to UXA (<a href="https://gitlab.com/o9000/tint2/issues/595">issue 595</a>)</li>
|
||||||
<li>Window managers that do not follow exactly the EWMH specification might not interact well with tint2 (known issues for <a href="https://gitlab.com/o9000/tint2/issues/385">awesome</a>, <a href="https://gitlab.com/o9000/tint2/issues/524">bspwm</a>. <a href="https://gitlab.com/o9000/tint2/issues/456">openbox-multihead</a>)</li>
|
<li>Window managers that do not follow exactly the EWMH specification might not interact well with tint2 (<a href="https://gitlab.com/o9000/tint2/issues/627">issue 627</a>).</li>
|
||||||
<li>Full transparency requires a compositor such as Compton (if not provided already by the window manager, as in Compiz/Unity, KDE or XFCE)</li>
|
<li>Full transparency requires a compositor such as Compton (if not provided already by the window manager, as in Compiz/Unity, KDE or XFCE).</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h1 id="how-can-i-help-out">How can I help out?<a name="how-can-i-help-out" href="#how-can-i-help-out" class="md2man-permalink" title="permalink"></a></h1>
|
<h1 id="how-can-i-help-out">How can I help out?<a name="how-can-i-help-out" href="#how-can-i-help-out" class="md2man-permalink" title="permalink"></a></h1>
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.TH TINT2 1 "2017\-11\-05" 15.3
|
.TH TINT2 1 "2017\-12\-30" 16.1
|
||||||
.SH NAME
|
.SH NAME
|
||||||
.PP
|
.PP
|
||||||
tint2 \- lightweight panel/taskbar
|
tint2 \- lightweight panel/taskbar
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# TINT2 1 "2017-11-05" 15.3
|
# TINT2 1 "2017-12-30" 16.1
|
||||||
|
|
||||||
## NAME
|
## NAME
|
||||||
tint2 - lightweight panel/taskbar
|
tint2 - lightweight panel/taskbar
|
||||||
|
|||||||
@@ -4,7 +4,10 @@ SCRIPT_DIR=$(dirname "$0")
|
|||||||
DIRTY=""
|
DIRTY=""
|
||||||
VERSION=""
|
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
|
then
|
||||||
git update-index -q --ignore-submodules --refresh
|
git update-index -q --ignore-submodules --refresh
|
||||||
# Disallow unstaged changes in the working tree
|
# Disallow unstaged changes in the working tree
|
||||||
@@ -37,10 +40,10 @@ then
|
|||||||
VERSION=$(git describe 2>/dev/null)$DIRTY
|
VERSION=$(git describe 2>/dev/null)$DIRTY
|
||||||
elif git log -n 1 1>/dev/null 2>/dev/null
|
elif git log -n 1 1>/dev/null 2>/dev/null
|
||||||
then
|
then
|
||||||
VERSION=$(head -n 1 "${SCRIPT_DIR}/ChangeLog" | cut -d ' ' -f 2)
|
VERSION=$(head -n 1 "ChangeLog" | cut -d ' ' -f 2)
|
||||||
if [ "$VERSION" = "master" ]
|
if [ "$VERSION" = "master" ]
|
||||||
then
|
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)
|
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
|
VERSION=$PREVIOUS-next-$HASH
|
||||||
fi
|
fi
|
||||||
@@ -49,13 +52,15 @@ fi
|
|||||||
|
|
||||||
if [ -z "$VERSION" ]
|
if [ -z "$VERSION" ]
|
||||||
then
|
then
|
||||||
VERSION=$(head -n 1 "${SCRIPT_DIR}/ChangeLog" | cut -d ' ' -f 2)
|
VERSION=$(head -n 1 "ChangeLog" | cut -d ' ' -f 2)
|
||||||
if [ "$VERSION" = "master" ]
|
if [ "$VERSION" = "master" ]
|
||||||
then
|
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
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
cd "${OLD_DIR}"
|
||||||
|
|
||||||
VERSION=$(echo "$VERSION" | sed 's/^v//')
|
VERSION=$(echo "$VERSION" | sed 's/^v//')
|
||||||
|
|
||||||
echo '#define VERSION_STRING "'$VERSION'"' > version.h
|
echo '#define VERSION_STRING "'$VERSION'"' > version.h
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
rm -f version.h
|
rm -f version.h
|
||||||
VERSION=$(git describe --exact-match 2>/dev/null)
|
VERSION=$(false 2>/dev/null)
|
||||||
if [ $? -eq 0 ]
|
if [ $? -eq 0 ]
|
||||||
then
|
then
|
||||||
VERSION=$(echo "$VERSION" | sed 's/^v//')
|
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
|
# Copy the debian files into the source directory
|
||||||
cp -r debian $DIR/debian
|
cp -r debian $DIR/debian
|
||||||
|
|
||||||
for DISTRO in trusty xenial zesty artful
|
for DISTRO in trusty xenial zesty artful bionic
|
||||||
do
|
do
|
||||||
# Cleanup from previous builds
|
# Cleanup from previous builds
|
||||||
rm -rf tint2_$VERSION-*
|
rm -rf tint2_$VERSION-*
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ def get_freebsd_versions():
|
|||||||
|
|
||||||
def get_openbsd_versions():
|
def get_openbsd_versions():
|
||||||
print >> sys.stderr, "OpenBSD ..."
|
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 = []
|
versions = []
|
||||||
version = None
|
version = None
|
||||||
for line in makefile.split("\n"):
|
for line in makefile.split("\n"):
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ struct BatteryState battery_state;
|
|||||||
gboolean battery_enabled;
|
gboolean battery_enabled;
|
||||||
gboolean battery_tooltip_enabled;
|
gboolean battery_tooltip_enabled;
|
||||||
int percentage_hide;
|
int percentage_hide;
|
||||||
static timeout *battery_timeout;
|
static Timer battery_timer;
|
||||||
|
|
||||||
#define BATTERY_BUF_SIZE 256
|
#define BATTERY_BUF_SIZE 256
|
||||||
static char buf_bat_line1[BATTERY_BUF_SIZE];
|
static char buf_bat_line1[BATTERY_BUF_SIZE];
|
||||||
@@ -76,7 +76,7 @@ void default_battery()
|
|||||||
percentage_hide = 101;
|
percentage_hide = 101;
|
||||||
battery_low_cmd_sent = FALSE;
|
battery_low_cmd_sent = FALSE;
|
||||||
battery_full_cmd_sent = FALSE;
|
battery_full_cmd_sent = FALSE;
|
||||||
battery_timeout = NULL;
|
INIT_TIMER(battery_timer);
|
||||||
bat1_has_font = FALSE;
|
bat1_has_font = FALSE;
|
||||||
bat1_font_desc = NULL;
|
bat1_font_desc = NULL;
|
||||||
bat1_format = NULL;
|
bat1_format = NULL;
|
||||||
@@ -127,8 +127,7 @@ void cleanup_battery()
|
|||||||
ac_connected_cmd = NULL;
|
ac_connected_cmd = NULL;
|
||||||
free(ac_disconnected_cmd);
|
free(ac_disconnected_cmd);
|
||||||
ac_disconnected_cmd = NULL;
|
ac_disconnected_cmd = NULL;
|
||||||
stop_timeout(battery_timeout);
|
destroy_timer(&battery_timer);
|
||||||
battery_timeout = NULL;
|
|
||||||
battery_found = FALSE;
|
battery_found = FALSE;
|
||||||
|
|
||||||
battery_os_free();
|
battery_os_free();
|
||||||
@@ -226,7 +225,7 @@ void init_battery()
|
|||||||
|
|
||||||
battery_found = battery_os_init();
|
battery_found = battery_os_init();
|
||||||
|
|
||||||
battery_timeout = add_timeout(10, 30000, update_battery_tick, 0, &battery_timeout);
|
change_timer(&battery_timer, true, 10, 30000, update_battery_tick, 0);
|
||||||
|
|
||||||
update_battery();
|
update_battery();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -460,7 +460,7 @@ void draw_button(void *obj, cairo_t *c)
|
|||||||
PangoLayout *layout = pango_cairo_create_layout(c);
|
PangoLayout *layout = pango_cairo_create_layout(c);
|
||||||
|
|
||||||
pango_layout_set_font_description(layout, button->backend->font_desc);
|
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 + 1) * PANGO_SCALE);
|
||||||
pango_layout_set_alignment(layout, button->backend->centered ? PANGO_ALIGN_CENTER : PANGO_ALIGN_LEFT);
|
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_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
||||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ static char buf_time[256];
|
|||||||
static char buf_date[256];
|
static char buf_date[256];
|
||||||
static char buf_tooltip[512];
|
static char buf_tooltip[512];
|
||||||
int clock_enabled;
|
int clock_enabled;
|
||||||
static timeout *clock_timeout;
|
static Timer clock_timer;
|
||||||
|
|
||||||
void clock_init_fonts();
|
void clock_init_fonts();
|
||||||
char *clock_get_tooltip(void *obj);
|
char *clock_get_tooltip(void *obj);
|
||||||
@@ -61,11 +61,11 @@ void clock_dump_geometry(void *obj, int indent);
|
|||||||
void default_clock()
|
void default_clock()
|
||||||
{
|
{
|
||||||
clock_enabled = 0;
|
clock_enabled = 0;
|
||||||
clock_timeout = NULL;
|
|
||||||
time1_format = NULL;
|
time1_format = NULL;
|
||||||
time1_timezone = NULL;
|
time1_timezone = NULL;
|
||||||
time2_format = NULL;
|
time2_format = NULL;
|
||||||
time2_timezone = NULL;
|
time2_timezone = NULL;
|
||||||
|
INIT_TIMER(clock_timer);
|
||||||
time_tooltip_format = NULL;
|
time_tooltip_format = NULL;
|
||||||
time_tooltip_timezone = NULL;
|
time_tooltip_timezone = NULL;
|
||||||
clock_lclick_command = NULL;
|
clock_lclick_command = NULL;
|
||||||
@@ -110,8 +110,7 @@ void cleanup_clock()
|
|||||||
clock_uwheel_command = NULL;
|
clock_uwheel_command = NULL;
|
||||||
free(clock_dwheel_command);
|
free(clock_dwheel_command);
|
||||||
clock_dwheel_command = NULL;
|
clock_dwheel_command = NULL;
|
||||||
stop_timeout(clock_timeout);
|
destroy_timer(&clock_timer);
|
||||||
clock_timeout = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tm *clock_gettime_for_tz(const char *timezone)
|
struct tm *clock_gettime_for_tz(const char *timezone)
|
||||||
@@ -155,7 +154,7 @@ void update_clocks_sec(void *arg)
|
|||||||
{
|
{
|
||||||
gettimeofday(&time_clock, 0);
|
gettimeofday(&time_clock, 0);
|
||||||
update_clocks();
|
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)
|
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]))
|
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();
|
update_clocks();
|
||||||
old_sec = time_clock.tv_sec;
|
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)
|
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));
|
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)) {
|
if (time_format_needs_sec_ticks(time1_format) || time_format_needs_sec_ticks(time2_format)) {
|
||||||
update_clocks_sec(NULL);
|
update_clocks_sec(NULL);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
5
src/default_icon.c
Normal file
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
10
src/default_icon.h
Normal 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
|
||||||
@@ -41,6 +41,7 @@ Execp *create_execp()
|
|||||||
execp->backend->cache_icon = TRUE;
|
execp->backend->cache_icon = TRUE;
|
||||||
execp->backend->centered = TRUE;
|
execp->backend->centered = TRUE;
|
||||||
execp->backend->font_color.alpha = 0.5;
|
execp->backend->font_color.alpha = 0.5;
|
||||||
|
INIT_TIMER(execp->backend->timer);
|
||||||
return execp;
|
return execp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,8 +68,7 @@ void destroy_execp(void *obj)
|
|||||||
free_and_null(execp);
|
free_and_null(execp);
|
||||||
} else {
|
} else {
|
||||||
// This is a backend element
|
// This is a backend element
|
||||||
stop_timeout(execp->backend->timer);
|
destroy_timer(&execp->backend->timer);
|
||||||
execp->backend->timer = NULL;
|
|
||||||
|
|
||||||
free_icon(execp->backend->icon);
|
free_icon(execp->backend->icon);
|
||||||
free_and_null(execp->backend->buf_stdout);
|
free_and_null(execp->backend->buf_stdout);
|
||||||
@@ -192,7 +192,7 @@ void init_execp_panel(void *p)
|
|||||||
execp->area.on_screen = TRUE;
|
execp->area.on_screen = TRUE;
|
||||||
instantiate_area_gradients(&execp->area);
|
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);
|
execp_update_post_read(execp);
|
||||||
}
|
}
|
||||||
@@ -486,7 +486,7 @@ void draw_execp(void *obj, cairo_t *c)
|
|||||||
|
|
||||||
// draw layout
|
// draw layout
|
||||||
pango_layout_set_font_description(layout, execp->backend->font_desc);
|
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 + 1) * PANGO_SCALE);
|
||||||
pango_layout_set_alignment(layout, execp->backend->centered ? PANGO_ALIGN_CENTER : PANGO_ALIGN_LEFT);
|
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_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
||||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
||||||
@@ -540,10 +540,8 @@ void execp_force_update(Execp *execp)
|
|||||||
if (execp->backend->child_pipe_stdout > 0) {
|
if (execp->backend->child_pipe_stdout > 0) {
|
||||||
// Command currently running, nothing to do
|
// Command currently running, nothing to do
|
||||||
} else {
|
} else {
|
||||||
if (execp->backend->timer)
|
|
||||||
stop_timeout(execp->backend->timer);
|
|
||||||
// Run command right away
|
// 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -757,8 +755,7 @@ gboolean read_execp(void *obj)
|
|||||||
close(execp->backend->child_pipe_stderr);
|
close(execp->backend->child_pipe_stderr);
|
||||||
execp->backend->child_pipe_stderr = -1;
|
execp->backend->child_pipe_stderr = -1;
|
||||||
if (execp->backend->interval)
|
if (execp->backend->interval)
|
||||||
execp->backend->timer =
|
change_timer(&execp->backend->timer, true, execp->backend->interval * 1000, 0, execp_timer_callback, execp);
|
||||||
add_timeout(execp->backend->interval * 1000, 0, execp_timer_callback, execp, &execp->backend->timer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ansi_clear_screen = (char*)"\x1b[2J";
|
char *ansi_clear_screen = (char*)"\x1b[2J";
|
||||||
@@ -882,22 +879,22 @@ gboolean read_execp(void *obj)
|
|||||||
return FALSE;
|
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) {
|
if (seconds < 60) {
|
||||||
sprintf(buffer, "%ds", seconds);
|
snprintf(buffer, buffer_size, "%ds", seconds);
|
||||||
} else if (seconds < 60 * 60) {
|
} else if (seconds < 60 * 60) {
|
||||||
int m = seconds / 60;
|
int m = seconds / 60;
|
||||||
seconds = seconds % 60;
|
seconds = seconds % 60;
|
||||||
int s = seconds;
|
int s = seconds;
|
||||||
sprintf(buffer, "%d:%ds", m, s);
|
snprintf(buffer, buffer_size, "%d:%ds", m, s);
|
||||||
} else {
|
} else {
|
||||||
int h = seconds / (60 * 60);
|
int h = seconds / (60 * 60);
|
||||||
seconds = seconds % (60 * 60);
|
seconds = seconds % (60 * 60);
|
||||||
int m = seconds / 60;
|
int m = seconds / 60;
|
||||||
seconds = seconds % 60;
|
seconds = seconds % 60;
|
||||||
int s = seconds;
|
int s = seconds;
|
||||||
sprintf(buffer, "%d:%d:%ds", h, m, s);
|
snprintf(buffer, buffer_size, "%d:%d:%ds", h, m, s);
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
@@ -923,35 +920,39 @@ char *execp_get_tooltip(void *obj)
|
|||||||
if (execp->backend->last_update_finish_time) {
|
if (execp->backend->last_update_finish_time) {
|
||||||
// We updated at least once
|
// We updated at least once
|
||||||
if (execp->backend->interval > 0) {
|
if (execp->backend->interval > 0) {
|
||||||
sprintf(execp->backend->tooltip_text,
|
snprintf(execp->backend->tooltip_text,
|
||||||
|
sizeof(execp->backend->tooltip_text),
|
||||||
"Last update finished %s ago (took %s). Next update starting in %s.",
|
"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)(now - execp->backend->last_update_finish_time), tmp_buf1, sizeof(tmp_buf1)),
|
||||||
time_to_string((int)execp->backend->last_update_duration, tmp_buf2),
|
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)),
|
time_to_string((int)(execp->backend->interval - (now - execp->backend->last_update_finish_time)),
|
||||||
tmp_buf3));
|
tmp_buf3, sizeof(tmp_buf3)));
|
||||||
} else {
|
} else {
|
||||||
sprintf(execp->backend->tooltip_text,
|
snprintf(execp->backend->tooltip_text,
|
||||||
|
sizeof(execp->backend->tooltip_text),
|
||||||
"Last update finished %s ago (took %s).",
|
"Last update finished %s ago (took %s).",
|
||||||
time_to_string((int)(now - execp->backend->last_update_finish_time), tmp_buf1),
|
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));
|
time_to_string((int)execp->backend->last_update_duration, tmp_buf2, sizeof(tmp_buf2)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// we never requested an update
|
// 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 {
|
} else {
|
||||||
// Currently executing command
|
// Currently executing command
|
||||||
if (execp->backend->last_update_finish_time) {
|
if (execp->backend->last_update_finish_time) {
|
||||||
// we finished updating at least once
|
// we finished updating at least once
|
||||||
sprintf(execp->backend->tooltip_text,
|
snprintf(execp->backend->tooltip_text,
|
||||||
|
sizeof(execp->backend->tooltip_text),
|
||||||
"Last update finished %s ago. Update in progress (started %s ago).",
|
"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_finish_time), tmp_buf1, sizeof(tmp_buf1)),
|
||||||
time_to_string((int)(now - execp->backend->last_update_start_time), tmp_buf3));
|
time_to_string((int)(now - execp->backend->last_update_start_time), tmp_buf3, sizeof(tmp_buf3)));
|
||||||
} else {
|
} else {
|
||||||
// we never finished an update
|
// we never finished an update
|
||||||
sprintf(execp->backend->tooltip_text,
|
snprintf(execp->backend->tooltip_text,
|
||||||
|
sizeof(execp->backend->tooltip_text),
|
||||||
"First update in progress (started %s seconds ago).",
|
"First update in progress (started %s seconds ago).",
|
||||||
time_to_string((int)(now - execp->backend->last_update_start_time), tmp_buf1));
|
time_to_string((int)(now - execp->backend->last_update_start_time), tmp_buf1, sizeof(tmp_buf1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strdup(execp->backend->tooltip_text);
|
return strdup(execp->backend->tooltip_text);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ typedef struct ExecpBackend {
|
|||||||
Background *bg;
|
Background *bg;
|
||||||
|
|
||||||
// Backend state:
|
// Backend state:
|
||||||
timeout *timer;
|
Timer timer;
|
||||||
int child_pipe_stdout;
|
int child_pipe_stdout;
|
||||||
int child_pipe_stderr;
|
int child_pipe_stderr;
|
||||||
pid_t child;
|
pid_t child;
|
||||||
|
|||||||
62
src/init.c
62
src/init.c
@@ -12,11 +12,13 @@
|
|||||||
#include <X11/extensions/XShm.h>
|
#include <X11/extensions/XShm.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "default_icon.h"
|
||||||
#include "drag_and_drop.h"
|
#include "drag_and_drop.h"
|
||||||
#include "fps_distribution.h"
|
#include "fps_distribution.h"
|
||||||
#include "panel.h"
|
#include "panel.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "signals.h"
|
#include "signals.h"
|
||||||
|
#include "test.h"
|
||||||
#include "tooltip.h"
|
#include "tooltip.h"
|
||||||
#include "tracing.h"
|
#include "tracing.h"
|
||||||
#include "uevent.h"
|
#include "uevent.h"
|
||||||
@@ -48,6 +50,15 @@ void handle_cli_arguments(int argc, char **argv)
|
|||||||
} else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
|
} else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
|
||||||
fprintf(stdout, "tint2 version %s\n", VERSION_STRING);
|
fprintf(stdout, "tint2 version %s\n", VERSION_STRING);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
} else if (strcmp(argv[i], "--test") == 0) {
|
||||||
|
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) {
|
} else if (strcmp(argv[i], "-c") == 0) {
|
||||||
if (i + 1 < argc) {
|
if (i + 1 < argc) {
|
||||||
i++;
|
i++;
|
||||||
@@ -94,6 +105,7 @@ void handle_env_vars()
|
|||||||
debug_frames = getenv("DEBUG_FRAMES") != NULL;
|
debug_frames = getenv("DEBUG_FRAMES") != NULL;
|
||||||
debug_dnd = getenv("DEBUG_DND") != NULL;
|
debug_dnd = getenv("DEBUG_DND") != NULL;
|
||||||
debug_thumbnails = getenv("DEBUG_THUMBNAILS") != NULL;
|
debug_thumbnails = getenv("DEBUG_THUMBNAILS") != NULL;
|
||||||
|
debug_timers = getenv("DEBUG_TIMERS") != NULL;
|
||||||
if (debug_fps) {
|
if (debug_fps) {
|
||||||
init_fps_distribution();
|
init_fps_distribution();
|
||||||
char *s = getenv("TRACING_FPS_THRESHOLD");
|
char *s = getenv("TRACING_FPS_THRESHOLD");
|
||||||
@@ -103,25 +115,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;
|
static int detect_compositor_timer_counter = 0;
|
||||||
|
|
||||||
void detect_compositor(void *arg)
|
void detect_compositor(void *arg)
|
||||||
{
|
{
|
||||||
if (server.composite_manager) {
|
if (server.composite_manager) {
|
||||||
stop_timeout(detect_compositor_timer);
|
stop_timer(&detect_compositor_timer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
detect_compositor_timer_counter--;
|
detect_compositor_timer_counter--;
|
||||||
if (detect_compositor_timer_counter < 0) {
|
if (detect_compositor_timer_counter < 0) {
|
||||||
stop_timeout(detect_compositor_timer);
|
stop_timer(&detect_compositor_timer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No compositor, check for one
|
// No compositor, check for one
|
||||||
if (XGetSelectionOwner(server.display, server.atom._NET_WM_CM_S0) != None) {
|
if (XGetSelectionOwner(server.display, server.atom._NET_WM_CM_S0) != None) {
|
||||||
stop_timeout(detect_compositor_timer);
|
stop_timer(&detect_compositor_timer);
|
||||||
// Restart tint2
|
// Restart tint2
|
||||||
fprintf(stderr, "tint2: Detected compositor, restarting tint2...\n");
|
fprintf(stderr, "tint2: Detected compositor, restarting tint2...\n");
|
||||||
kill(getpid(), SIGUSR1);
|
kill(getpid(), SIGUSR1);
|
||||||
@@ -134,15 +146,15 @@ void start_detect_compositor()
|
|||||||
if (server.composite_manager)
|
if (server.composite_manager)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
stop_timeout(detect_compositor_timer);
|
|
||||||
// Check every 0.5 seconds for up to 30 seconds
|
// Check every 0.5 seconds for up to 30 seconds
|
||||||
detect_compositor_timer_counter = 60;
|
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()
|
void create_default_elements()
|
||||||
{
|
{
|
||||||
default_timeout();
|
default_timers();
|
||||||
default_systray();
|
default_systray();
|
||||||
memset(&server, 0, sizeof(server));
|
memset(&server, 0, sizeof(server));
|
||||||
#ifdef ENABLE_BATTERY
|
#ifdef ENABLE_BATTERY
|
||||||
@@ -157,6 +169,22 @@ void create_default_elements()
|
|||||||
default_panel();
|
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()
|
void init_post_config()
|
||||||
{
|
{
|
||||||
server_init_visual();
|
server_init_visual();
|
||||||
@@ -167,20 +195,7 @@ void init_post_config()
|
|||||||
imlib_context_set_colormap(server.colormap);
|
imlib_context_set_colormap(server.colormap);
|
||||||
|
|
||||||
init_signals_postconfig();
|
init_signals_postconfig();
|
||||||
|
load_default_task_icon();
|
||||||
// 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");
|
|
||||||
}
|
|
||||||
|
|
||||||
XSync(server.display, False);
|
XSync(server.display, False);
|
||||||
}
|
}
|
||||||
@@ -222,10 +237,10 @@ void init(int argc, char **argv)
|
|||||||
setlinebuf(stdout);
|
setlinebuf(stdout);
|
||||||
setlinebuf(stderr);
|
setlinebuf(stderr);
|
||||||
default_config();
|
default_config();
|
||||||
|
handle_env_vars();
|
||||||
handle_cli_arguments(argc, argv);
|
handle_cli_arguments(argc, argv);
|
||||||
create_default_elements();
|
create_default_elements();
|
||||||
init_signals();
|
init_signals();
|
||||||
handle_env_vars();
|
|
||||||
|
|
||||||
init_X11_pre_config();
|
init_X11_pre_config();
|
||||||
if (!config_read()) {
|
if (!config_read()) {
|
||||||
@@ -259,6 +274,7 @@ void cleanup()
|
|||||||
cleanup_battery();
|
cleanup_battery();
|
||||||
#endif
|
#endif
|
||||||
cleanup_separator();
|
cleanup_separator();
|
||||||
|
cleanup_taskbar();
|
||||||
cleanup_panel();
|
cleanup_panel();
|
||||||
cleanup_config();
|
cleanup_config();
|
||||||
|
|
||||||
@@ -273,7 +289,7 @@ void cleanup()
|
|||||||
xsettings_client = NULL;
|
xsettings_client = NULL;
|
||||||
|
|
||||||
cleanup_server();
|
cleanup_server();
|
||||||
cleanup_timeout();
|
cleanup_timers();
|
||||||
|
|
||||||
if (server.display)
|
if (server.display)
|
||||||
XCloseDisplay(server.display);
|
XCloseDisplay(server.display);
|
||||||
|
|||||||
@@ -60,9 +60,9 @@ void expand_exec(DesktopEntry *entry, const char *path)
|
|||||||
// %c -> Name
|
// %c -> Name
|
||||||
// %k -> path
|
// %k -> path
|
||||||
if (entry->exec) {
|
if (entry->exec) {
|
||||||
char *exec2 = calloc(strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) +
|
size_t buf_size = strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) +
|
||||||
(entry->icon ? strlen(entry->icon) : 1) + 100,
|
(entry->icon ? strlen(entry->icon) : 1) + 100;
|
||||||
1);
|
char *exec2 = calloc(buf_size, 1);
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
// p will never point to an escaped char
|
// p will never point to an escaped char
|
||||||
for (p = entry->exec, q = exec2; *p; p++, q++) {
|
for (p = entry->exec, q = exec2; *p; p++, q++) {
|
||||||
@@ -82,23 +82,30 @@ void expand_exec(DesktopEntry *entry, const char *path)
|
|||||||
if (!*p)
|
if (!*p)
|
||||||
break;
|
break;
|
||||||
if (*p == 'i' && entry->icon != NULL) {
|
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("--icon ''");
|
||||||
q += strlen(entry->icon);
|
q += strlen(entry->icon);
|
||||||
|
buf_size -= (size_t)(q - old);
|
||||||
q--; // To balance the q++ in the for
|
q--; // To balance the q++ in the for
|
||||||
} else if (*p == 'c' && entry->name != NULL) {
|
} 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("''");
|
||||||
q += strlen(entry->name);
|
q += strlen(entry->name);
|
||||||
|
buf_size -= (size_t)(q - old);
|
||||||
q--; // To balance the q++ in the for
|
q--; // To balance the q++ in the for
|
||||||
} else if (*p == 'c') {
|
} else if (*p == 'c') {
|
||||||
sprintf(q, "'%s'", path);
|
snprintf(q, buf_size, "'%s'", path);
|
||||||
|
char *old = q;
|
||||||
q += strlen("''");
|
q += strlen("''");
|
||||||
q += strlen(path);
|
q += strlen(path);
|
||||||
|
buf_size -= (size_t)(q - old);
|
||||||
q--; // To balance the q++ in the for
|
q--; // To balance the q++ in the for
|
||||||
} else if (*p == 'f' || *p == 'F') {
|
} else if (*p == 'f' || *p == 'F') {
|
||||||
sprintf(q, "%c%c", '%', *p);
|
snprintf(q, buf_size, "%c%c", '%', *p);
|
||||||
q += 2;
|
q += 2;
|
||||||
|
buf_size -= 2;
|
||||||
q--; // To balance the q++ in the for
|
q--; // To balance the q++ in the for
|
||||||
} else {
|
} else {
|
||||||
// We don't care about other expansions
|
// We don't care about other expansions
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ int parse_theme_line(char *line, char **key, char **value)
|
|||||||
return parse_dektop_line(line, key, value);
|
return parse_dektop_line(line, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList *icon_locations = NULL;
|
static GSList *icon_locations = NULL;
|
||||||
// Do not free the result.
|
// Do not free the result.
|
||||||
const GSList *get_icon_locations()
|
const GSList *get_icon_locations()
|
||||||
{
|
{
|
||||||
@@ -74,6 +74,21 @@ const GSList *get_icon_locations()
|
|||||||
return 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 *make_theme(const char *name)
|
||||||
{
|
{
|
||||||
IconTheme *theme = calloc(1, sizeof(IconTheme));
|
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);
|
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)
|
char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
||||||
{
|
{
|
||||||
if (icon_name == NULL)
|
if (!icon_name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// If the icon_name is already a path and the file exists, return it
|
char *result = icon_path_from_full_path(icon_name);
|
||||||
if (strstr(icon_name, "/") == icon_name) {
|
if (result)
|
||||||
if (g_file_test(icon_name, G_FILE_TEST_EXISTS))
|
return result;
|
||||||
return strdup(icon_name);
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const GSList *basenames = get_icon_locations();
|
const GSList *basenames = get_icon_locations();
|
||||||
GSList *extensions = NULL;
|
const GSList *extensions = get_icon_extensions();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GSList *theme;
|
GSList *theme;
|
||||||
|
|
||||||
// Best size match
|
// Best size match
|
||||||
// Contrary to the freedesktop spec, we are not choosing the closest icon in size, but the next larger icon
|
// 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
|
// 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
|
// 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;
|
char *next_larger = NULL;
|
||||||
GSList *next_larger_theme = 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);
|
char *file_name = calloc(file_name_size, 1);
|
||||||
|
|
||||||
for (theme = themes; theme; theme = g_slist_next(theme)) {
|
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);
|
fprintf(stderr, "tint2: Searching directory: %s\n", ((IconThemeDir *)dir->data)->name);
|
||||||
const GSList *base;
|
const GSList *base;
|
||||||
for (base = basenames; base; base = g_slist_next(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 *base_name = (char *)base->data;
|
||||||
char *theme_name = ((IconTheme *)theme->data)->name;
|
char *theme_name = ((IconTheme *)theme->data)->name;
|
||||||
char *dir_name = ((IconThemeDir *)dir->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;
|
file_name[0] = 0;
|
||||||
// filename = directory/$(themename)/subdirectory/iconname.extension
|
// 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)
|
if (debug_icons)
|
||||||
fprintf(stderr, "tint2: Checking %s\n", file_name);
|
fprintf(stderr, "tint2: Checking %s\n", file_name);
|
||||||
if (g_file_test(file_name, G_FILE_TEST_EXISTS)) {
|
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);
|
free(file_name);
|
||||||
file_name = NULL;
|
file_name = NULL;
|
||||||
if (next_larger) {
|
if (next_larger) {
|
||||||
g_slist_free(extensions);
|
|
||||||
free(best_file_name);
|
free(best_file_name);
|
||||||
return next_larger;
|
return next_larger;
|
||||||
}
|
}
|
||||||
if (best_file_name) {
|
if (best_file_name) {
|
||||||
g_slist_free(extensions);
|
|
||||||
return best_file_name;
|
return best_file_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,18 +690,18 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
|||||||
if (debug_icons)
|
if (debug_icons)
|
||||||
fprintf(stderr, "tint2: Searching unthemed icons\n");
|
fprintf(stderr, "tint2: Searching unthemed icons\n");
|
||||||
for (const GSList *base = basenames; base; base = g_slist_next(base)) {
|
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 *base_name = (char *)base->data;
|
||||||
char *extension = (char *)ext->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
|
// 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)
|
if (debug_icons)
|
||||||
fprintf(stderr, "tint2: Checking %s\n", file_name);
|
fprintf(stderr, "tint2: Checking %s\n", file_name);
|
||||||
if (g_file_test(file_name, G_FILE_TEST_EXISTS)) {
|
if (g_file_test(file_name, G_FILE_TEST_EXISTS)) {
|
||||||
if (debug_icons)
|
if (debug_icons)
|
||||||
fprintf(stderr, "tint2: Found %s\n", file_name);
|
fprintf(stderr, "tint2: Found %s\n", file_name);
|
||||||
g_slist_free(extensions);
|
|
||||||
return file_name;
|
return file_name;
|
||||||
} else {
|
} else {
|
||||||
free(file_name);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -470,7 +470,7 @@ void launcher_load_icons(Launcher *launcher)
|
|||||||
launcherIcon->area.size_mode = LAYOUT_FIXED;
|
launcherIcon->area.size_mode = LAYOUT_FIXED;
|
||||||
launcherIcon->area._resize = NULL;
|
launcherIcon->area._resize = NULL;
|
||||||
launcherIcon->area._compute_desired_size = launcher_icon_compute_desired_size;
|
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.resize_needed = 0;
|
||||||
launcherIcon->area.has_mouse_over_effect = panel_config.mouse_effects;
|
launcherIcon->area.has_mouse_over_effect = panel_config.mouse_effects;
|
||||||
launcherIcon->area.has_mouse_press_effect = launcherIcon->area.has_mouse_over_effect;
|
launcherIcon->area.has_mouse_press_effect = launcherIcon->area.has_mouse_over_effect;
|
||||||
|
|||||||
@@ -723,7 +723,7 @@ void handle_panel_refresh()
|
|||||||
if (debug_frames) {
|
if (debug_frames) {
|
||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
char path[256];
|
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);
|
save_panel_screenshot(&panels[i], path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -748,7 +748,7 @@ void run_tint2_event_loop()
|
|||||||
|
|
||||||
// Wait for an event and handle it
|
// Wait for an event and handle it
|
||||||
ts_event_read = 0;
|
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
|
#ifdef HAVE_TRACING
|
||||||
start_tracing((void*)run_tint2_event_loop);
|
start_tracing((void*)run_tint2_event_loop);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
58
src/panel.c
58
src/panel.c
@@ -130,8 +130,6 @@ void cleanup_panel()
|
|||||||
if (!panels)
|
if (!panels)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cleanup_taskbar();
|
|
||||||
|
|
||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
Panel *p = &panels[i];
|
Panel *p = &panels[i];
|
||||||
|
|
||||||
@@ -145,7 +143,7 @@ void cleanup_panel()
|
|||||||
if (p->main_win)
|
if (p->main_win)
|
||||||
XDestroyWindow(server.display, p->main_win);
|
XDestroyWindow(server.display, p->main_win);
|
||||||
p->main_win = 0;
|
p->main_win = 0;
|
||||||
stop_timeout(p->autohide_timeout);
|
destroy_timer(&p->autohide_timer);
|
||||||
cleanup_freespace(p);
|
cleanup_freespace(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,6 +205,7 @@ void init_panel()
|
|||||||
panels = calloc(num_panels, sizeof(Panel));
|
panels = calloc(num_panels, sizeof(Panel));
|
||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
memcpy(&panels[i], &panel_config, sizeof(Panel));
|
memcpy(&panels[i], &panel_config, sizeof(Panel));
|
||||||
|
INIT_TIMER(panels[i].autohide_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@@ -494,9 +493,11 @@ gboolean resize_panel(void *obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Distribute the remaining size between tasks
|
// Distribute the remaining size between taskbars
|
||||||
if (num_tasks > 0) {
|
if (num_tasks > 0) {
|
||||||
int task_size = total_size / num_tasks;
|
int task_size = total_size / num_tasks;
|
||||||
|
if (taskbar_alignment != ALIGN_LEFT)
|
||||||
|
task_size = MIN(task_size, panel_horizontal ? panel_config.g_task.maximum_width : panel_config.g_task.maximum_height);
|
||||||
for (int i = 0; i < panel->num_desktops; i++) {
|
for (int i = 0; i < panel->num_desktops; i++) {
|
||||||
Taskbar *taskbar = &panel->taskbar[i];
|
Taskbar *taskbar = &panel->taskbar[i];
|
||||||
if (!taskbar->area.on_screen)
|
if (!taskbar->area.on_screen)
|
||||||
@@ -513,6 +514,43 @@ gboolean resize_panel(void *obj)
|
|||||||
taskbar->area.height += task_size;
|
taskbar->area.height += task_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int slack = total_size - task_size * num_tasks;
|
||||||
|
if (taskbar_alignment == ALIGN_RIGHT) {
|
||||||
|
for (int i = 0; i < panel->num_desktops; i++) {
|
||||||
|
Taskbar *taskbar = &panel->taskbar[i];
|
||||||
|
if (!taskbar->area.on_screen)
|
||||||
|
continue;
|
||||||
|
if (panel_horizontal)
|
||||||
|
taskbar->area.width += slack;
|
||||||
|
else
|
||||||
|
taskbar->area.height += slack;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (taskbar_alignment == ALIGN_CENTER) {
|
||||||
|
slack /= 2;
|
||||||
|
for (int i = 0; i < panel->num_desktops; i++) {
|
||||||
|
Taskbar *taskbar = &panel->taskbar[i];
|
||||||
|
if (!taskbar->area.on_screen)
|
||||||
|
continue;
|
||||||
|
if (panel_horizontal)
|
||||||
|
taskbar->area.width += slack;
|
||||||
|
else
|
||||||
|
taskbar->area.height += slack;
|
||||||
|
taskbar->area.alignment = ALIGN_RIGHT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (int i = panel->num_desktops - 1; i >= 0; i--) {
|
||||||
|
Taskbar *taskbar = &panel->taskbar[i];
|
||||||
|
if (!taskbar->area.on_screen)
|
||||||
|
continue;
|
||||||
|
if (panel_horizontal)
|
||||||
|
taskbar->area.width += slack;
|
||||||
|
else
|
||||||
|
taskbar->area.height += slack;
|
||||||
|
taskbar->area.alignment = ALIGN_LEFT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// No tasks => expand the first visible taskbar
|
// No tasks => expand the first visible taskbar
|
||||||
for (int i = 0; i < panel->num_desktops; i++) {
|
for (int i = 0; i < panel->num_desktops; i++) {
|
||||||
@@ -1021,15 +1059,15 @@ Button *click_button(Panel *panel, int x, int y)
|
|||||||
return NULL;
|
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)
|
void autohide_show(void *p)
|
||||||
{
|
{
|
||||||
Panel *panel = (Panel *)p;
|
Panel *panel = (Panel *)p;
|
||||||
stop_autohide_timeout(panel);
|
stop_autohide_timer(panel);
|
||||||
panel->is_hidden = 0;
|
panel->is_hidden = 0;
|
||||||
XMapSubwindows(server.display, panel->main_win); // systray windows
|
XMapSubwindows(server.display, panel->main_win); // systray windows
|
||||||
set_panel_window_geometry(panel);
|
set_panel_window_geometry(panel);
|
||||||
@@ -1041,7 +1079,7 @@ void autohide_show(void *p)
|
|||||||
void autohide_hide(void *p)
|
void autohide_hide(void *p)
|
||||||
{
|
{
|
||||||
Panel *panel = (Panel *)p;
|
Panel *panel = (Panel *)p;
|
||||||
stop_autohide_timeout(panel);
|
stop_autohide_timer(panel);
|
||||||
set_panel_layer(panel, panel_layer);
|
set_panel_layer(panel, panel_layer);
|
||||||
panel->is_hidden = TRUE;
|
panel->is_hidden = TRUE;
|
||||||
XUnmapSubwindows(server.display, panel->main_win); // systray windows
|
XUnmapSubwindows(server.display, panel->main_win); // systray windows
|
||||||
@@ -1053,7 +1091,7 @@ void autohide_trigger_show(Panel *p)
|
|||||||
{
|
{
|
||||||
if (!p)
|
if (!p)
|
||||||
return;
|
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)
|
void autohide_trigger_hide(Panel *p)
|
||||||
@@ -1068,7 +1106,7 @@ void autohide_trigger_hide(Panel *p)
|
|||||||
if (child)
|
if (child)
|
||||||
return; // mouse over one of the system tray icons
|
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)
|
void shrink_panel(Panel *panel)
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ typedef struct Panel {
|
|||||||
gboolean is_hidden;
|
gboolean is_hidden;
|
||||||
int hidden_width, hidden_height;
|
int hidden_width, hidden_height;
|
||||||
Pixmap hidden_pixmap;
|
Pixmap hidden_pixmap;
|
||||||
timeout *autohide_timeout;
|
Timer autohide_timer;
|
||||||
} Panel;
|
} Panel;
|
||||||
|
|
||||||
extern Panel panel_config;
|
extern Panel panel_config;
|
||||||
|
|||||||
@@ -730,6 +730,8 @@ gboolean add_icon(Window win)
|
|||||||
traywin->pid = pid;
|
traywin->pid = pid;
|
||||||
traywin->name = name;
|
traywin->name = name;
|
||||||
traywin->chrono = chrono;
|
traywin->chrono = chrono;
|
||||||
|
INIT_TIMER(traywin->render_timer);
|
||||||
|
INIT_TIMER(traywin->resize_timer);
|
||||||
chrono++;
|
chrono++;
|
||||||
|
|
||||||
show(&systray.area);
|
show(&systray.area);
|
||||||
@@ -940,8 +942,8 @@ void remove_icon(TrayWindow *traywin)
|
|||||||
XDestroyWindow(server.display, traywin->parent);
|
XDestroyWindow(server.display, traywin->parent);
|
||||||
XSync(server.display, False);
|
XSync(server.display, False);
|
||||||
XSetErrorHandler(old);
|
XSetErrorHandler(old);
|
||||||
stop_timeout(traywin->render_timeout);
|
destroy_timer(&traywin->render_timer);
|
||||||
stop_timeout(traywin->resize_timeout);
|
destroy_timer(&traywin->resize_timer);
|
||||||
free(traywin->name);
|
free(traywin->name);
|
||||||
if (traywin->image) {
|
if (traywin->image) {
|
||||||
imlib_context_set_image(traywin->image);
|
imlib_context_set_image(traywin->image);
|
||||||
@@ -1055,9 +1057,8 @@ void systray_reconfigure_event(TrayWindow *traywin, XEvent *e)
|
|||||||
if (traywin->bad_size_counter < min_bad_resize_events) {
|
if (traywin->bad_size_counter < min_bad_resize_events) {
|
||||||
systray_resize_icon(traywin);
|
systray_resize_icon(traywin);
|
||||||
} else {
|
} else {
|
||||||
if (!traywin->resize_timeout)
|
if (!traywin->resize_timer.enabled_)
|
||||||
traywin->resize_timeout =
|
change_timer(&traywin->resize_timer, true, fast_resize_period, 0, systray_resize_icon, traywin);
|
||||||
add_timeout(fast_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (traywin->bad_size_counter == max_bad_resize_events) {
|
if (traywin->bad_size_counter == max_bad_resize_events) {
|
||||||
@@ -1071,14 +1072,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
|
// FIXME Normally we should force the icon to resize fill_color to the size we resized it to when we
|
||||||
// embedded it.
|
// embedded it.
|
||||||
// However this triggers a resize loop in new versions of GTK, which we must avoid.
|
// However this triggers a resize loop in new versions of GTK, which we must avoid.
|
||||||
if (!traywin->resize_timeout)
|
if (!traywin->resize_timer.enabled_)
|
||||||
traywin->resize_timeout =
|
change_timer(&traywin->resize_timer, true, slow_resize_period, 0, systray_resize_icon, traywin);
|
||||||
add_timeout(slow_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Correct size
|
// Correct size
|
||||||
stop_timeout(traywin->resize_timeout);
|
stop_timer(&traywin->resize_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize and redraw the systray
|
// Resize and redraw the systray
|
||||||
@@ -1135,9 +1135,8 @@ void systray_resize_request_event(TrayWindow *traywin, XEvent *e)
|
|||||||
if (traywin->bad_size_counter < min_bad_resize_events) {
|
if (traywin->bad_size_counter < min_bad_resize_events) {
|
||||||
systray_resize_icon(traywin);
|
systray_resize_icon(traywin);
|
||||||
} else {
|
} else {
|
||||||
if (!traywin->resize_timeout)
|
if (!traywin->resize_timer.enabled_)
|
||||||
traywin->resize_timeout =
|
change_timer(&traywin->resize_timer, true, fast_resize_period, 0, systray_resize_icon, traywin);
|
||||||
add_timeout(fast_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (traywin->bad_size_counter == max_bad_resize_events) {
|
if (traywin->bad_size_counter == max_bad_resize_events) {
|
||||||
@@ -1150,14 +1149,13 @@ void systray_resize_request_event(TrayWindow *traywin, XEvent *e)
|
|||||||
// Delayed resize
|
// Delayed resize
|
||||||
// FIXME Normally we should force the icon to resize to the size we resized it to when we embedded it.
|
// 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.
|
// However this triggers a resize loop in some versions of GTK, which we must avoid.
|
||||||
if (!traywin->resize_timeout)
|
if (!traywin->resize_timer.enabled_)
|
||||||
traywin->resize_timeout =
|
change_timer(&traywin->resize_timer, true, slow_resize_period, 0, systray_resize_icon, traywin);
|
||||||
add_timeout(slow_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Correct size
|
// Correct size
|
||||||
stop_timeout(traywin->resize_timeout);
|
stop_timer(&traywin->resize_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize and redraw the systray
|
// Resize and redraw the systray
|
||||||
@@ -1224,8 +1222,7 @@ void systray_render_icon_composited(void *t)
|
|||||||
if (compare_timespecs(&earliest_render, &now) > 0) {
|
if (compare_timespecs(&earliest_render, &now) > 0) {
|
||||||
traywin->num_fast_renders++;
|
traywin->num_fast_renders++;
|
||||||
if (traywin->num_fast_renders > max_fast_refreshes) {
|
if (traywin->num_fast_renders > max_fast_refreshes) {
|
||||||
traywin->render_timeout =
|
change_timer(&traywin->render_timer, true, min_refresh_period, 0, systray_render_icon_composited, traywin);
|
||||||
add_timeout(min_refresh_period, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
|
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering" RESET "\n",
|
YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering" RESET "\n",
|
||||||
@@ -1244,8 +1241,7 @@ void systray_render_icon_composited(void *t)
|
|||||||
|
|
||||||
if (traywin->width == 0 || traywin->height == 0) {
|
if (traywin->width == 0 || traywin->height == 0) {
|
||||||
// reschedule rendering since the geometry information has not yet been processed (can happen on slow cpu)
|
// reschedule rendering since the geometry information has not yet been processed (can happen on slow cpu)
|
||||||
traywin->render_timeout =
|
change_timer(&traywin->render_timer, true, min_refresh_period, 0, systray_render_icon_composited, traywin);
|
||||||
add_timeout(min_refresh_period, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
|
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering" RESET "\n",
|
YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering" RESET "\n",
|
||||||
@@ -1257,10 +1253,7 @@ void systray_render_icon_composited(void *t)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (traywin->render_timeout) {
|
stop_timer(&traywin->render_timer);
|
||||||
stop_timeout(traywin->render_timeout);
|
|
||||||
traywin->render_timeout = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// good systray icons support 32 bit depth, but some icons are still 24 bit.
|
// 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
|
// We create a heuristic mask for these icons, i.e. we get the rgb value in the top left corner, and
|
||||||
@@ -1423,9 +1416,7 @@ void systray_render_icon(void *t)
|
|||||||
// __LINE__,
|
// __LINE__,
|
||||||
// traywin->win,
|
// traywin->win,
|
||||||
// traywin->name);
|
// traywin->name);
|
||||||
stop_timeout(traywin->render_timeout);
|
change_timer(&traywin->render_timer, true, min_refresh_period, 0, systray_render_icon, traywin);
|
||||||
traywin->render_timeout =
|
|
||||||
add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1448,19 +1439,13 @@ void systray_render_icon(void *t)
|
|||||||
unsigned int width, height, depth;
|
unsigned int width, height, depth;
|
||||||
Window root;
|
Window root;
|
||||||
if (!XGetGeometry(server.display, traywin->win, &root, &xpos, &ypos, &width, &height, &border_width, &depth)) {
|
if (!XGetGeometry(server.display, traywin->win, &root, &xpos, &ypos, &width, &height, &border_width, &depth)) {
|
||||||
stop_timeout(traywin->render_timeout);
|
change_timer(&traywin->render_timer, true, min_refresh_period, 0, systray_render_icon, traywin);
|
||||||
if (!traywin->render_timeout)
|
|
||||||
traywin->render_timeout =
|
|
||||||
add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
|
|
||||||
systray_render_icon_from_image(traywin);
|
systray_render_icon_from_image(traywin);
|
||||||
XSetErrorHandler(old);
|
XSetErrorHandler(old);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (xpos != 0 || ypos != 0 || width != traywin->width || height != traywin->height) {
|
if (xpos != 0 || ypos != 0 || width != traywin->width || height != traywin->height) {
|
||||||
stop_timeout(traywin->render_timeout);
|
change_timer(&traywin->render_timer, true, min_refresh_period, 0, systray_render_icon, traywin);
|
||||||
if (!traywin->render_timeout)
|
|
||||||
traywin->render_timeout =
|
|
||||||
add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
|
|
||||||
systray_render_icon_from_image(traywin);
|
systray_render_icon_from_image(traywin);
|
||||||
if (systray_profile)
|
if (systray_profile)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
|||||||
@@ -56,11 +56,11 @@ typedef struct {
|
|||||||
// Members used for rendering
|
// Members used for rendering
|
||||||
struct timespec time_last_render;
|
struct timespec time_last_render;
|
||||||
int num_fast_renders;
|
int num_fast_renders;
|
||||||
timeout *render_timeout;
|
Timer render_timer;
|
||||||
// Members used for resizing
|
// Members used for resizing
|
||||||
int bad_size_counter;
|
int bad_size_counter;
|
||||||
struct timespec time_last_resize;
|
struct timespec time_last_resize;
|
||||||
timeout *resize_timeout;
|
Timer resize_timer;
|
||||||
// Icon contents if we are compositing the icon, otherwise null
|
// Icon contents if we are compositing the icon, otherwise null
|
||||||
Imlib_Image image;
|
Imlib_Image image;
|
||||||
// XDamage
|
// XDamage
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
#include "tooltip.h"
|
#include "tooltip.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
timeout *urgent_timeout;
|
Timer urgent_timer;
|
||||||
GSList *urgent_list;
|
GSList *urgent_list;
|
||||||
|
|
||||||
void task_dump_geometry(void *obj, int indent);
|
void task_dump_geometry(void *obj, int indent);
|
||||||
@@ -463,7 +463,7 @@ void draw_task(void *obj, cairo_t *c)
|
|||||||
pango_layout_set_font_description(layout, panel->g_task.font_desc);
|
pango_layout_set_font_description(layout, panel->g_task.font_desc);
|
||||||
pango_layout_set_text(layout, task->title, -1);
|
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 + 1) * PANGO_SCALE);
|
||||||
pango_layout_set_height(layout, panel->g_task.text_height * 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_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
||||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
|
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
|
||||||
@@ -782,8 +782,8 @@ void add_urgent(Task *task)
|
|||||||
// not yet in the list, so we have to add it
|
// not yet in the list, so we have to add it
|
||||||
urgent_list = g_slist_prepend(urgent_list, task);
|
urgent_list = g_slist_prepend(urgent_list, task);
|
||||||
|
|
||||||
if (!urgent_timeout)
|
if (!urgent_timer.enabled_)
|
||||||
urgent_timeout = add_timeout(10, 1000, blink_urgent, 0, &urgent_timeout);
|
change_timer(&urgent_timer, true, 10, 1000, blink_urgent, 0);
|
||||||
|
|
||||||
Panel *panel = task->area.panel;
|
Panel *panel = task->area.panel;
|
||||||
if (panel->is_hidden)
|
if (panel->is_hidden)
|
||||||
@@ -793,10 +793,8 @@ void add_urgent(Task *task)
|
|||||||
void del_urgent(Task *task)
|
void del_urgent(Task *task)
|
||||||
{
|
{
|
||||||
urgent_list = g_slist_remove(urgent_list, task);
|
urgent_list = g_slist_remove(urgent_list, task);
|
||||||
if (!urgent_list) {
|
if (!urgent_list)
|
||||||
stop_timeout(urgent_timeout);
|
stop_timer(&urgent_timer);
|
||||||
urgent_timeout = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void task_handle_mouse_event(Task *task, MouseAction action)
|
void task_handle_mouse_event(Task *task, MouseAction action)
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ typedef struct Task {
|
|||||||
double thumbnail_last_update;
|
double thumbnail_last_update;
|
||||||
} Task;
|
} Task;
|
||||||
|
|
||||||
extern timeout *urgent_timeout;
|
extern Timer urgent_timer;
|
||||||
extern GSList *urgent_list;
|
extern GSList *urgent_list;
|
||||||
|
|
||||||
Task *add_task(Window win);
|
Task *add_task(Window win);
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ gboolean hide_taskbar_if_empty;
|
|||||||
gboolean always_show_all_desktop_tasks;
|
gboolean always_show_all_desktop_tasks;
|
||||||
TaskbarSortMethod taskbar_sort_method;
|
TaskbarSortMethod taskbar_sort_method;
|
||||||
Alignment taskbar_alignment;
|
Alignment taskbar_alignment;
|
||||||
static timeout *thumbnail_update_timer_all;
|
static Timer thumbnail_update_timer_all;
|
||||||
static timeout *thumbnail_update_timer_active;
|
static Timer thumbnail_update_timer_active;
|
||||||
static timeout *thumbnail_update_timer_tooltip;
|
static Timer thumbnail_update_timer_tooltip;
|
||||||
|
|
||||||
static GList *taskbar_task_orderings = NULL;
|
static GList *taskbar_task_orderings = NULL;
|
||||||
static GList *taskbar_thumbnail_jobs_done = NULL;
|
static GList *taskbar_thumbnail_jobs_done = NULL;
|
||||||
@@ -80,7 +80,6 @@ void free_ptr_array(gpointer data)
|
|||||||
void default_taskbar()
|
void default_taskbar()
|
||||||
{
|
{
|
||||||
win_to_task = NULL;
|
win_to_task = NULL;
|
||||||
urgent_timeout = NULL;
|
|
||||||
urgent_list = NULL;
|
urgent_list = NULL;
|
||||||
taskbar_enabled = FALSE;
|
taskbar_enabled = FALSE;
|
||||||
taskbar_distribute_size = FALSE;
|
taskbar_distribute_size = FALSE;
|
||||||
@@ -89,9 +88,6 @@ void default_taskbar()
|
|||||||
hide_task_diff_monitor = FALSE;
|
hide_task_diff_monitor = FALSE;
|
||||||
hide_taskbar_if_empty = FALSE;
|
hide_taskbar_if_empty = FALSE;
|
||||||
always_show_all_desktop_tasks = 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_thumbnail_jobs_done = NULL;
|
||||||
taskbar_sort_method = TASKBAR_NOSORT;
|
taskbar_sort_method = TASKBAR_NOSORT;
|
||||||
taskbar_alignment = ALIGN_LEFT;
|
taskbar_alignment = ALIGN_LEFT;
|
||||||
@@ -134,9 +130,9 @@ void taskbar_save_orderings()
|
|||||||
|
|
||||||
void cleanup_taskbar()
|
void cleanup_taskbar()
|
||||||
{
|
{
|
||||||
stop_timeout(thumbnail_update_timer_all);
|
destroy_timer(&thumbnail_update_timer_all);
|
||||||
stop_timeout(thumbnail_update_timer_active);
|
destroy_timer(&thumbnail_update_timer_active);
|
||||||
stop_timeout(thumbnail_update_timer_tooltip);
|
destroy_timer(&thumbnail_update_timer_tooltip);
|
||||||
g_list_free(taskbar_thumbnail_jobs_done);
|
g_list_free(taskbar_thumbnail_jobs_done);
|
||||||
taskbar_save_orderings();
|
taskbar_save_orderings();
|
||||||
if (win_to_task) {
|
if (win_to_task) {
|
||||||
@@ -170,7 +166,7 @@ void cleanup_taskbar()
|
|||||||
g_slist_free(urgent_list);
|
g_slist_free(urgent_list);
|
||||||
urgent_list = NULL;
|
urgent_list = NULL;
|
||||||
|
|
||||||
stop_timeout(urgent_timeout);
|
destroy_timer(&urgent_timer);
|
||||||
|
|
||||||
for (int state = 0; state < TASK_STATE_COUNT; state++) {
|
for (int state = 0; state < TASK_STATE_COUNT; state++) {
|
||||||
g_list_free(panel_config.g_task.gradient[state]);
|
g_list_free(panel_config.g_task.gradient[state]);
|
||||||
@@ -184,6 +180,11 @@ void cleanup_taskbar()
|
|||||||
|
|
||||||
void init_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) {
|
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;
|
panel_config.g_task.has_text = panel_config.g_task.has_icon = 1;
|
||||||
}
|
}
|
||||||
@@ -384,8 +385,9 @@ void taskbar_start_thumbnail_timer(ThumbnailUpdateMode mode)
|
|||||||
return;
|
return;
|
||||||
if (debug_thumbnails)
|
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");
|
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_ACTIVE_WINDOW ? &thumbnail_update_timer_active : &thumbnail_update_timer_tooltip,
|
||||||
|
true,
|
||||||
mode == THUMB_MODE_TOOLTIP_WINDOW ? 1000 : 500,
|
mode == THUMB_MODE_TOOLTIP_WINDOW ? 1000 : 500,
|
||||||
mode == THUMB_MODE_ALL ? 10 * 1000 : 0,
|
mode == THUMB_MODE_ALL ? 10 * 1000 : 0,
|
||||||
taskbar_update_thumbnails,
|
taskbar_update_thumbnails,
|
||||||
@@ -844,7 +846,7 @@ void taskbar_update_thumbnails(void *arg)
|
|||||||
if (mode == THUMB_MODE_ALL) {
|
if (mode == THUMB_MODE_ALL) {
|
||||||
double now = get_time();
|
double now = get_time();
|
||||||
if (now - start_time > 0.030) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -855,7 +857,7 @@ void taskbar_update_thumbnails(void *arg)
|
|||||||
if (taskbar_thumbnail_jobs_done) {
|
if (taskbar_thumbnail_jobs_done) {
|
||||||
g_list_free(taskbar_thumbnail_jobs_done);
|
g_list_free(taskbar_thumbnail_jobs_done);
|
||||||
taskbar_thumbnail_jobs_done = NULL;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,12 @@ set(SOURCES ../util/common.c
|
|||||||
../util/strnatcmp.c
|
../util/strnatcmp.c
|
||||||
../util/cache.c
|
../util/cache.c
|
||||||
../util/timer.c
|
../util/timer.c
|
||||||
|
../util/test.c
|
||||||
|
../util/print.c
|
||||||
|
../util/signals.c
|
||||||
../config.c
|
../config.c
|
||||||
../server.c
|
../util/server.c
|
||||||
|
../util/strlcat.c
|
||||||
../launcher/apps-common.c
|
../launcher/apps-common.c
|
||||||
../launcher/icon-theme-common.c
|
../launcher/icon-theme-common.c
|
||||||
md4.c
|
md4.c
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ char *file_name_from_path(const char *filepath)
|
|||||||
|
|
||||||
void make_backup(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);
|
copy_file(filepath, backup_path);
|
||||||
g_free(backup_path);
|
g_free(backup_path);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "background_gui.h"
|
#include "background_gui.h"
|
||||||
#include "gradient_gui.h"
|
#include "gradient_gui.h"
|
||||||
|
#include "strlcat.h"
|
||||||
|
|
||||||
GtkWidget *panel_width, *panel_height, *panel_margin_x, *panel_margin_y, *panel_padding_x, *panel_padding_y,
|
GtkWidget *panel_width, *panel_height, *panel_margin_x, *panel_margin_y, *panel_padding_x, *panel_padding_y,
|
||||||
*panel_spacing;
|
*panel_spacing;
|
||||||
@@ -180,7 +181,7 @@ void applyClicked(GtkWidget *widget, gpointer data)
|
|||||||
gchar *filepath = get_current_theme_path();
|
gchar *filepath = get_current_theme_path();
|
||||||
if (filepath) {
|
if (filepath) {
|
||||||
if (config_is_manual(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);
|
copy_file(filepath, backup_path);
|
||||||
g_free(backup_path);
|
g_free(backup_path);
|
||||||
}
|
}
|
||||||
@@ -1256,7 +1257,8 @@ gboolean panel_contains(const char *value)
|
|||||||
|
|
||||||
char *get_panel_items()
|
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);
|
GtkTreeModel *model = GTK_TREE_MODEL(panel_items);
|
||||||
|
|
||||||
GtkTreeIter i;
|
GtkTreeIter i;
|
||||||
@@ -1267,7 +1269,7 @@ char *get_panel_items()
|
|||||||
while (1) {
|
while (1) {
|
||||||
gchar *v;
|
gchar *v;
|
||||||
gtk_tree_model_get(model, &i, itemsColValue, &v, -1);
|
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)) {
|
if (!gtk_tree_model_iter_next(model, &i)) {
|
||||||
break;
|
break;
|
||||||
@@ -1312,19 +1314,19 @@ void set_panel_items(const char *items)
|
|||||||
} else if (v == ':') {
|
} else if (v == ':') {
|
||||||
separator_index++;
|
separator_index++;
|
||||||
buffer[0] = 0;
|
buffer[0] = 0;
|
||||||
sprintf(buffer, "%s %d", _("Separator"), separator_index + 1);
|
snprintf(buffer, sizeof(buffer), "%s %d", _("Separator"), separator_index + 1);
|
||||||
name = buffer;
|
name = buffer;
|
||||||
value = ":";
|
value = ":";
|
||||||
} else if (v == 'E') {
|
} else if (v == 'E') {
|
||||||
execp_index++;
|
execp_index++;
|
||||||
buffer[0] = 0;
|
buffer[0] = 0;
|
||||||
sprintf(buffer, "%s %d", _("Executor"), execp_index + 1);
|
snprintf(buffer, sizeof(buffer), "%s %d", _("Executor"), execp_index + 1);
|
||||||
name = buffer;
|
name = buffer;
|
||||||
value = "E";
|
value = "E";
|
||||||
} else if (v == 'P') {
|
} else if (v == 'P') {
|
||||||
button_index++;
|
button_index++;
|
||||||
buffer[0] = 0;
|
buffer[0] = 0;
|
||||||
sprintf(buffer, "%s %d", _("Button"), button_index + 1);
|
snprintf(buffer, sizeof(buffer), "%s %d", _("Button"), button_index + 1);
|
||||||
name = buffer;
|
name = buffer;
|
||||||
value = "P";
|
value = "P";
|
||||||
} else {
|
} else {
|
||||||
@@ -4097,7 +4099,7 @@ void create_separator(GtkWidget *notebook, int i)
|
|||||||
Separator *separator = &g_array_index(separators, Separator, i);
|
Separator *separator = &g_array_index(separators, Separator, i);
|
||||||
|
|
||||||
separator->name[0] = 0;
|
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);
|
separator->page_label = gtk_label_new(separator->name);
|
||||||
gtk_widget_show(separator->page_label);
|
gtk_widget_show(separator->page_label);
|
||||||
separator->page_separator = gtk_vbox_new(FALSE, DEFAULT_HOR_SPACING);
|
separator->page_separator = gtk_vbox_new(FALSE, DEFAULT_HOR_SPACING);
|
||||||
@@ -4223,7 +4225,7 @@ void create_execp(GtkWidget *notebook, int i)
|
|||||||
Executor *executor = &g_array_index(executors, Executor, i);
|
Executor *executor = &g_array_index(executors, Executor, i);
|
||||||
|
|
||||||
executor->name[0] = 0;
|
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);
|
executor->page_label = gtk_label_new(executor->name);
|
||||||
gtk_widget_show(executor->page_label);
|
gtk_widget_show(executor->page_label);
|
||||||
executor->page_execp = gtk_vbox_new(FALSE, DEFAULT_HOR_SPACING);
|
executor->page_execp = gtk_vbox_new(FALSE, DEFAULT_HOR_SPACING);
|
||||||
@@ -4644,7 +4646,7 @@ void create_button(GtkWidget *notebook, int i)
|
|||||||
Button *button = &g_array_index(buttons, Button, i);
|
Button *button = &g_array_index(buttons, Button, i);
|
||||||
|
|
||||||
button->name[0] = 0;
|
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);
|
button->page_label = gtk_label_new(button->name);
|
||||||
gtk_widget_show(button->page_label);
|
gtk_widget_show(button->page_label);
|
||||||
button->page_button = gtk_vbox_new(FALSE, DEFAULT_HOR_SPACING);
|
button->page_button = gtk_vbox_new(FALSE, DEFAULT_HOR_SPACING);
|
||||||
@@ -5033,7 +5035,7 @@ void separator_update_indices()
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < separators->len; i++) {
|
for (int i = 0; i < separators->len; i++) {
|
||||||
Separator *separator = &g_array_index(separators, Separator, 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);
|
gtk_label_set_text(GTK_LABEL(separator->page_label), separator->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5051,7 +5053,7 @@ void separator_update_indices()
|
|||||||
separator_index++;
|
separator_index++;
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
buffer[0] = 0;
|
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);
|
gtk_list_store_set(panel_items, &iter, itemsColName, buffer, -1);
|
||||||
}
|
}
|
||||||
@@ -5065,7 +5067,7 @@ void execp_update_indices()
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < executors->len; i++) {
|
for (int i = 0; i < executors->len; i++) {
|
||||||
Executor *executor = &g_array_index(executors, Executor, 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);
|
gtk_label_set_text(GTK_LABEL(executor->page_label), executor->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5083,7 +5085,7 @@ void execp_update_indices()
|
|||||||
execp_index++;
|
execp_index++;
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
buffer[0] = 0;
|
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);
|
gtk_list_store_set(panel_items, &iter, itemsColName, buffer, -1);
|
||||||
}
|
}
|
||||||
@@ -5097,7 +5099,7 @@ void button_update_indices()
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < buttons->len; i++) {
|
for (int i = 0; i < buttons->len; i++) {
|
||||||
Button *button = &g_array_index(buttons, Button, 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);
|
gtk_label_set_text(GTK_LABEL(button->page_label), button->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5115,7 +5117,7 @@ void button_update_indices()
|
|||||||
button_index++;
|
button_index++;
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
buffer[0] = 0;
|
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);
|
gtk_list_store_set(panel_items, &iter, itemsColName, buffer, -1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,23 +69,23 @@ void config_read_file(const char *path)
|
|||||||
if (!config_has_panel_items) {
|
if (!config_has_panel_items) {
|
||||||
char panel_items[256];
|
char panel_items[256];
|
||||||
panel_items[0] = 0;
|
panel_items[0] = 0;
|
||||||
strcat(panel_items, "T");
|
strlcat(panel_items, "T", sizeof(panel_items));
|
||||||
if (config_has_battery) {
|
if (config_has_battery) {
|
||||||
if (config_battery_enabled)
|
if (config_battery_enabled)
|
||||||
strcat(panel_items, "B");
|
strlcat(panel_items, "B", sizeof(panel_items));
|
||||||
} else {
|
} else {
|
||||||
if (no_items_battery_enabled)
|
if (no_items_battery_enabled)
|
||||||
strcat(panel_items, "B");
|
strlcat(panel_items, "B", sizeof(panel_items));
|
||||||
}
|
}
|
||||||
if (config_has_systray) {
|
if (config_has_systray) {
|
||||||
if (config_systray_enabled)
|
if (config_systray_enabled)
|
||||||
strcat(panel_items, "S");
|
strlcat(panel_items, "S", sizeof(panel_items));
|
||||||
} else {
|
} else {
|
||||||
if (no_items_systray_enabled)
|
if (no_items_systray_enabled)
|
||||||
strcat(panel_items, "S");
|
strlcat(panel_items, "S", sizeof(panel_items));
|
||||||
}
|
}
|
||||||
if (no_items_clock_enabled)
|
if (no_items_clock_enabled)
|
||||||
strcat(panel_items, "C");
|
strlcat(panel_items, "C", sizeof(panel_items));
|
||||||
set_panel_items(panel_items);
|
set_panel_items(panel_items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,13 +242,13 @@ void config_write_backgrounds(FILE *fp)
|
|||||||
char sides[10];
|
char sides[10];
|
||||||
sides[0] = '\0';
|
sides[0] = '\0';
|
||||||
if (sideTop)
|
if (sideTop)
|
||||||
strcat(sides, "T");
|
strlcat(sides, "T", sizeof(sides));
|
||||||
if (sideBottom)
|
if (sideBottom)
|
||||||
strcat(sides, "B");
|
strlcat(sides, "B", sizeof(sides));
|
||||||
if (sideLeft)
|
if (sideLeft)
|
||||||
strcat(sides, "L");
|
strlcat(sides, "L", sizeof(sides));
|
||||||
if (sideRight)
|
if (sideRight)
|
||||||
strcat(sides, "R");
|
strlcat(sides, "R", sizeof(sides));
|
||||||
fprintf(fp, "border_sides = %s\n", sides);
|
fprintf(fp, "border_sides = %s\n", sides);
|
||||||
|
|
||||||
fprintf(fp, "border_content_tint_weight = %d\n", (int)(border_weight));
|
fprintf(fp, "border_content_tint_weight = %d\n", (int)(border_weight));
|
||||||
@@ -478,7 +478,7 @@ void config_write_task_font_color(FILE *fp, char *name, GtkWidget *task_color)
|
|||||||
GdkColor color;
|
GdkColor color;
|
||||||
gtk_color_button_get_color(GTK_COLOR_BUTTON(task_color), &color);
|
gtk_color_button_get_color(GTK_COLOR_BUTTON(task_color), &color);
|
||||||
char full_name[128];
|
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);
|
config_write_color(fp, full_name, color, gtk_color_button_get_alpha(GTK_COLOR_BUTTON(task_color)) * 100 / 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,7 +489,7 @@ void config_write_task_icon_osb(FILE *fp,
|
|||||||
GtkWidget *widget_brightness)
|
GtkWidget *widget_brightness)
|
||||||
{
|
{
|
||||||
char full_name[128];
|
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,
|
fprintf(fp,
|
||||||
"%s = %d %d %d\n",
|
"%s = %d %d %d\n",
|
||||||
full_name,
|
full_name,
|
||||||
@@ -501,7 +501,7 @@ void config_write_task_icon_osb(FILE *fp,
|
|||||||
void config_write_task_background(FILE *fp, char *name, GtkWidget *task_background)
|
void config_write_task_background(FILE *fp, char *name, GtkWidget *task_background)
|
||||||
{
|
{
|
||||||
char full_name[128];
|
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)));
|
fprintf(fp, "%s = %d\n", full_name, gtk_combo_box_get_active(GTK_COMBO_BOX(task_background)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ gboolean update_snapshot(gpointer ignored)
|
|||||||
|
|
||||||
char hash[MD4_HEX_SIZE + 4];
|
char hash[MD4_HEX_SIZE + 4];
|
||||||
md4hexf(path, hash);
|
md4hexf(path, hash);
|
||||||
strcat(hash, ".png");
|
strlcat(hash, ".png", sizeof(hash));
|
||||||
|
|
||||||
gchar *snap = g_build_filename(g_get_user_cache_dir(), "tint2", hash, NULL);
|
gchar *snap = g_build_filename(g_get_user_cache_dir(), "tint2", hash, NULL);
|
||||||
pixbuf = force_refresh ? NULL : gdk_pixbuf_new_from_file(snap, NULL);
|
pixbuf = force_refresh ? NULL : gdk_pixbuf_new_from_file(snap, NULL);
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ static int x, y, width, height;
|
|||||||
static gboolean just_shown;
|
static gboolean just_shown;
|
||||||
|
|
||||||
// the next functions are helper functions for tooltip handling
|
// the next functions are helper functions for tooltip handling
|
||||||
void start_show_timeout();
|
void start_show_timer();
|
||||||
void start_hide_timeout();
|
void start_hide_timer();
|
||||||
void stop_tooltip_timeout();
|
void stop_tooltip_timer();
|
||||||
|
|
||||||
void tooltip_init_fonts();
|
void tooltip_init_fonts();
|
||||||
|
|
||||||
@@ -44,6 +44,9 @@ void default_tooltip()
|
|||||||
// give the tooltip some reasonable default values
|
// give the tooltip some reasonable default values
|
||||||
memset(&g_tooltip, 0, sizeof(Tooltip));
|
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[0] = 1;
|
||||||
g_tooltip.font_color.rgb[1] = 1;
|
g_tooltip.font_color.rgb[1] = 1;
|
||||||
g_tooltip.font_color.rgb[2] = 1;
|
g_tooltip.font_color.rgb[2] = 1;
|
||||||
@@ -53,8 +56,9 @@ void default_tooltip()
|
|||||||
|
|
||||||
void cleanup_tooltip()
|
void cleanup_tooltip()
|
||||||
{
|
{
|
||||||
stop_tooltip_timeout();
|
stop_tooltip_timer();
|
||||||
stop_timeout(g_tooltip.update_timeout);
|
destroy_timer(&g_tooltip.visibility_timer);
|
||||||
|
destroy_timer(&g_tooltip.update_timer);
|
||||||
tooltip_hide(NULL);
|
tooltip_hide(NULL);
|
||||||
tooltip_update_contents_for(NULL);
|
tooltip_update_contents_for(NULL);
|
||||||
if (g_tooltip.window)
|
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) {
|
if (g_tooltip.mapped && g_tooltip.area != area) {
|
||||||
tooltip_update_contents_for(area);
|
tooltip_update_contents_for(area);
|
||||||
tooltip_update();
|
tooltip_update();
|
||||||
stop_tooltip_timeout();
|
stop_tooltip_timer();
|
||||||
} else if (!g_tooltip.mapped) {
|
} else if (!g_tooltip.mapped) {
|
||||||
start_show_timeout();
|
start_show_timer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,10 +310,10 @@ void tooltip_trigger_hide()
|
|||||||
{
|
{
|
||||||
if (g_tooltip.mapped) {
|
if (g_tooltip.mapped) {
|
||||||
tooltip_update_contents_for(NULL);
|
tooltip_update_contents_for(NULL);
|
||||||
start_hide_timeout();
|
start_hide_timer();
|
||||||
} else {
|
} else {
|
||||||
// tooltip not visible yet, but maybe a timeout is still pending
|
// tooltip not visible yet, but maybe a timer is still pending
|
||||||
stop_tooltip_timeout();
|
stop_tooltip_timer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,19 +327,19 @@ void tooltip_hide(void *arg)
|
|||||||
g_tooltip.area = NULL;
|
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)
|
void tooltip_update_contents_timeout(void *arg)
|
||||||
@@ -356,7 +360,7 @@ void tooltip_update_contents_for(Area *area)
|
|||||||
if (g_tooltip.image)
|
if (g_tooltip.image)
|
||||||
cairo_surface_reference(g_tooltip.image);
|
cairo_surface_reference(g_tooltip.image);
|
||||||
else
|
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;
|
g_tooltip.area = area;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ typedef struct {
|
|||||||
PangoFontDescription *font_desc;
|
PangoFontDescription *font_desc;
|
||||||
Color font_color;
|
Color font_color;
|
||||||
Background *bg;
|
Background *bg;
|
||||||
timeout *timeout;
|
Timer visibility_timer;
|
||||||
timeout *update_timeout;
|
Timer update_timer;
|
||||||
cairo_surface_t *image;
|
cairo_surface_t *image;
|
||||||
} Tooltip;
|
} Tooltip;
|
||||||
|
|
||||||
|
|||||||
17
src/util/bool.h
Normal file
17
src/util/bool.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef BOOL_H
|
||||||
|
#define BOOL_H
|
||||||
|
|
||||||
|
#ifndef bool
|
||||||
|
#define bool int
|
||||||
|
#define false 0
|
||||||
|
#define true 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SUCCESS true
|
||||||
|
#define FAILURE false
|
||||||
|
|
||||||
|
#ifndef Status
|
||||||
|
typedef int Status;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
10
src/util/colors.h
Normal file
10
src/util/colors.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef COLORS_H
|
||||||
|
#define COLORS_H
|
||||||
|
|
||||||
|
#define GREEN "\033[1;32m"
|
||||||
|
#define YELLOW "\033[1;33m"
|
||||||
|
#define RED "\033[1;31m"
|
||||||
|
#define BLUE "\033[1;34m"
|
||||||
|
#define RESET "\033[0m"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "../server.h"
|
#include "server.h"
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
@@ -191,7 +191,7 @@ const char *signal_name(int sig)
|
|||||||
return "SIGSYS: Bad system call.";
|
return "SIGSYS: Bad system call.";
|
||||||
}
|
}
|
||||||
static char s[64];
|
static char s[64];
|
||||||
sprintf(s, "SIG=%d: Unknown", sig);
|
snprintf(s, sizeof(s), "SIG=%d: Unknown", sig);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +266,7 @@ extern char *config_path;
|
|||||||
int setenvd(const char *name, const int value)
|
int setenvd(const char *name, const int value)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
sprintf(buf, "%d", value);
|
snprintf(buf, sizeof(buf), "%d", value);
|
||||||
return setenv(name, buf, 1);
|
return setenv(name, buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,9 +461,10 @@ char *expand_tilde(const char *s)
|
|||||||
{
|
{
|
||||||
const gchar *home = g_get_home_dir();
|
const gchar *home = g_get_home_dir();
|
||||||
if (home && (strcmp(s, "~") == 0 || strstr(s, "~/") == s)) {
|
if (home && (strcmp(s, "~") == 0 || strstr(s, "~/") == s)) {
|
||||||
char *result = calloc(strlen(home) + strlen(s), 1);
|
size_t buf_size = strlen(home) + strlen(s);
|
||||||
strcat(result, home);
|
char *result = calloc(buf_size, 1);
|
||||||
strcat(result, s + 1);
|
strlcat(result, home, buf_size);
|
||||||
|
strlcat(result, s + 1, buf_size);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
return strdup(s);
|
return strdup(s);
|
||||||
@@ -476,14 +477,16 @@ char *contract_tilde(const char *s)
|
|||||||
if (!home)
|
if (!home)
|
||||||
return strdup(s);
|
return strdup(s);
|
||||||
|
|
||||||
char *home_slash = calloc(strlen(home) + 2, 1);
|
size_t buf_size = strlen(home) + 2;
|
||||||
strcat(home_slash, home);
|
char *home_slash = calloc(buf_size, 1);
|
||||||
strcat(home_slash, "/");
|
strlcat(home_slash, home, buf_size);
|
||||||
|
strlcat(home_slash, "/", buf_size);
|
||||||
|
|
||||||
if ((strcmp(s, home) == 0 || strstr(s, home_slash) == s)) {
|
if ((strcmp(s, home) == 0 || strstr(s, home_slash) == s)) {
|
||||||
char *result = calloc(strlen(s) - strlen(home) + 2, 1);
|
size_t buf_size2 = strlen(s) - strlen(home) + 2;
|
||||||
strcat(result, "~");
|
char *result = calloc(buf_size2, 1);
|
||||||
strcat(result, s + strlen(home));
|
strlcat(result, "~", buf_size2);
|
||||||
|
strlcat(result, s + strlen(home), buf_size2);
|
||||||
free(home_slash);
|
free(home_slash);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
@@ -793,7 +796,7 @@ Imlib_Image load_image(const char *path, int cached)
|
|||||||
}
|
}
|
||||||
if (!image && g_str_has_suffix(path, ".svg")) {
|
if (!image && g_str_has_suffix(path, ".svg")) {
|
||||||
char tmp_filename[128];
|
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);
|
int fd = open(tmp_filename, O_CREAT | O_EXCL, 0600);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
// We fork here because librsvg allocates memory like crazy
|
// We fork here because librsvg allocates memory like crazy
|
||||||
@@ -1111,3 +1114,63 @@ void adjust_color(Color *color, int alpha, int saturation, int brightness)
|
|||||||
color->rgb[1] = g / 255.;
|
color->rgb[1] = g / 255.;
|
||||||
color->rgb[2] = b / 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();
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,12 +12,8 @@
|
|||||||
#include <Imlib2.h>
|
#include <Imlib2.h>
|
||||||
#include <pango/pangocairo.h>
|
#include <pango/pangocairo.h>
|
||||||
#include "area.h"
|
#include "area.h"
|
||||||
|
#include "colors.h"
|
||||||
#define GREEN "\033[1;32m"
|
#include "strlcat.h"
|
||||||
#define YELLOW "\033[1;33m"
|
|
||||||
#define RED "\033[1;31m"
|
|
||||||
#define BLUE "\033[1;34m"
|
|
||||||
#define RESET "\033[0m"
|
|
||||||
|
|
||||||
#define MAX3(a, b, c) MAX(MAX(a, b), c)
|
#define MAX3(a, b, c) MAX(MAX(a, b), c)
|
||||||
#define MIN3(a, b, c) MIN(MIN(a, b), c)
|
#define MIN3(a, b, c) MIN(MIN(a, b), c)
|
||||||
@@ -153,6 +149,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 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) \
|
#define free_and_null(p) \
|
||||||
{ \
|
{ \
|
||||||
free(p); \
|
free(p); \
|
||||||
|
|||||||
83
src/util/print.c
Normal file
83
src/util/print.c
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
int print_uchar(unsigned char v)
|
||||||
|
{
|
||||||
|
return printf("%u", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_char(char v)
|
||||||
|
{
|
||||||
|
return printf("%c", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_short(short v)
|
||||||
|
{
|
||||||
|
return printf("%d", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_ushort(unsigned short v)
|
||||||
|
{
|
||||||
|
return printf("%u", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_int(int v)
|
||||||
|
{
|
||||||
|
return printf("%d", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_uint(unsigned v)
|
||||||
|
{
|
||||||
|
return printf("%u", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_long(long v)
|
||||||
|
{
|
||||||
|
return printf("%ld", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_ulong(unsigned long v)
|
||||||
|
{
|
||||||
|
return printf("%lu", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_long_long(long long v)
|
||||||
|
{
|
||||||
|
return printf("%lld", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_ulong_long(unsigned long long v)
|
||||||
|
{
|
||||||
|
return printf("%llu", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_float(float v)
|
||||||
|
{
|
||||||
|
return printf("%f", (double)v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_double(double v)
|
||||||
|
{
|
||||||
|
return printf("%f", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_long_double(long double v)
|
||||||
|
{
|
||||||
|
return printf("%Lf", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_string(char *s)
|
||||||
|
{
|
||||||
|
return printf("%s", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_pointer(void *v)
|
||||||
|
{
|
||||||
|
return printf("%p", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_unknown()
|
||||||
|
{
|
||||||
|
return printf("(variable of unknown type)");
|
||||||
|
}
|
||||||
61
src/util/print.h
Normal file
61
src/util/print.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#ifndef PRINT_H
|
||||||
|
#define PRINT_H
|
||||||
|
|
||||||
|
#ifdef HAS_GENERIC
|
||||||
|
|
||||||
|
int print_uchar(unsigned char v);
|
||||||
|
|
||||||
|
int print_char(char v);
|
||||||
|
|
||||||
|
int print_short(short v);
|
||||||
|
|
||||||
|
int print_ushort(unsigned short v);
|
||||||
|
|
||||||
|
int print_int(int v);
|
||||||
|
|
||||||
|
int print_uint(unsigned v);
|
||||||
|
|
||||||
|
int print_long(long v);
|
||||||
|
|
||||||
|
int print_ulong(unsigned long v);
|
||||||
|
|
||||||
|
int print_long_long(long long v);
|
||||||
|
|
||||||
|
int print_ulong_long(unsigned long long v);
|
||||||
|
|
||||||
|
int print_float(float v);
|
||||||
|
|
||||||
|
int print_double(double v);
|
||||||
|
|
||||||
|
int print_long_double(long double v);
|
||||||
|
|
||||||
|
int print_string(char *s);
|
||||||
|
|
||||||
|
int print_pointer(void *v);
|
||||||
|
|
||||||
|
int print_unknown();
|
||||||
|
|
||||||
|
#define print(x) \
|
||||||
|
_Generic((x), \
|
||||||
|
unsigned char: print_uchar, \
|
||||||
|
char: print_char, \
|
||||||
|
short int: print_short, \
|
||||||
|
unsigned short int: print_ushort, \
|
||||||
|
int: print_int, \
|
||||||
|
unsigned int: print_uint, \
|
||||||
|
long int: print_long, \
|
||||||
|
unsigned long int: print_ulong, \
|
||||||
|
long long int: print_long_long, \
|
||||||
|
unsigned long long int: print_ulong_long, \
|
||||||
|
float: print_float, \
|
||||||
|
double: print_double, \
|
||||||
|
long double: print_long_double, \
|
||||||
|
char *: print_string, \
|
||||||
|
void *: print_pointer, \
|
||||||
|
default : print_unknown)(x)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define print(...) printf("Omitted, the compiler does not support C11 generics.\n")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#ifndef TINT2CONF
|
||||||
#ifdef HAVE_SN
|
#ifdef HAVE_SN
|
||||||
#include <libsn/sn.h>
|
#include <libsn/sn.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -34,6 +36,7 @@ void reset_signals()
|
|||||||
sigprocmask(SIG_SETMASK, &signal_set, NULL);
|
sigprocmask(SIG_SETMASK, &signal_set, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TINT2CONF
|
||||||
void init_signals()
|
void init_signals()
|
||||||
{
|
{
|
||||||
// Set signal handlers
|
// Set signal handlers
|
||||||
@@ -164,3 +167,4 @@ int get_signal_pending()
|
|||||||
{
|
{
|
||||||
return signal_pending;
|
return signal_pending;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
60
src/util/strlcat.c
Normal file
60
src/util/strlcat.c
Normal 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
16
src/util/strlcat.h
Normal 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
|
||||||
183
src/util/test.c
Normal file
183
src/util/test.c
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
#include <fcntl.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "colors.h"
|
||||||
|
#include "signals.h"
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
typedef struct TestListItem {
|
||||||
|
Test *test;
|
||||||
|
const char *name;
|
||||||
|
} TestListItem;
|
||||||
|
|
||||||
|
static GList *all_tests = NULL;
|
||||||
|
|
||||||
|
void register_test_(Test *test, const char *name)
|
||||||
|
{
|
||||||
|
TestListItem *item = (TestListItem *)calloc(sizeof(TestListItem), 1);
|
||||||
|
item->test = test;
|
||||||
|
item->name = name;
|
||||||
|
all_tests = g_list_append(all_tests, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *test_log_name_from_test_name(const char *test_name)
|
||||||
|
{
|
||||||
|
char *output_name = g_strdup_printf("test_%s.log", test_name);
|
||||||
|
char *result = strdup(output_name);
|
||||||
|
g_free(output_name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void redirect_test_output(const char *test_name)
|
||||||
|
{
|
||||||
|
char *output_name = test_log_name_from_test_name(test_name);
|
||||||
|
int fd = open(output_name, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||||
|
if (fd == -1)
|
||||||
|
goto err;
|
||||||
|
if (dup2(fd, STDOUT_FILENO) == -1)
|
||||||
|
goto err;
|
||||||
|
if (dup2(fd, STDERR_FILENO) == -1)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
free(output_name);
|
||||||
|
return;
|
||||||
|
err:
|
||||||
|
fprintf(stderr, "tint2: Could not redirect test output to file name: %s\n", output_name);
|
||||||
|
if (fd != -1)
|
||||||
|
close(fd);
|
||||||
|
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);
|
||||||
|
exit(result ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FILE *open_test_log(const char *test_name)
|
||||||
|
{
|
||||||
|
char *output_name = test_log_name_from_test_name(test_name);
|
||||||
|
FILE *log = fopen(output_name, "a");
|
||||||
|
free(output_name);
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Status run_test_parent(TestListItem *item, pid_t child)
|
||||||
|
{
|
||||||
|
FILE *log = open_test_log(item->name);
|
||||||
|
if (child == -1) {
|
||||||
|
fprintf(log, "\n" "Test failed, fork failed\n");
|
||||||
|
fclose(log);
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int child_status;
|
||||||
|
pid_t ret_pid = waitpid(child, &child_status, 0);
|
||||||
|
if (ret_pid != child) {
|
||||||
|
fprintf(log, "\n" "Test failed, waitpid failed\n");
|
||||||
|
fclose(log);
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
if (WIFEXITED(child_status)) {
|
||||||
|
int exit_status = WEXITSTATUS(child_status);
|
||||||
|
if (exit_status == EXIT_SUCCESS) {
|
||||||
|
fprintf(log, "\n" "Test succeeded.\n");
|
||||||
|
fclose(log);
|
||||||
|
return SUCCESS;
|
||||||
|
} else {
|
||||||
|
fprintf(log, "\n" "Test failed, exit status: %d.\n", exit_status);
|
||||||
|
fclose(log);
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
} else if (WIFSIGNALED(child_status)) {
|
||||||
|
int signal = WTERMSIG(child_status);
|
||||||
|
fprintf(log, "\n" "Test failed, child killed by signal: %d.\n", signal);
|
||||||
|
fclose(log);
|
||||||
|
return FAILURE;
|
||||||
|
} else {
|
||||||
|
fprintf(log, "\n" "Test failed, waitpid failed.\n");
|
||||||
|
fclose(log);
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(bool verbose)
|
||||||
|
{
|
||||||
|
fprintf(stdout, BLUE "tint2: Running %d tests..." RESET "\n", g_list_length(all_tests));
|
||||||
|
size_t count = 0, succeeded = 0, failed = 0;
|
||||||
|
for (GList *l = all_tests; l; l = l->next) {
|
||||||
|
TestListItem *item = (TestListItem *)l->data;
|
||||||
|
Status status = run_test(item);
|
||||||
|
count++;
|
||||||
|
fprintf(stdout, BLUE "tint2: Test " YELLOW "%s" BLUE ": ", item->name);
|
||||||
|
if (status == SUCCESS) {
|
||||||
|
fprintf(stdout, GREEN "succeeded" RESET "\n");
|
||||||
|
succeeded++;
|
||||||
|
} 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)
|
||||||
|
fprintf(stdout, BLUE "tint2: " GREEN "all %lu tests succeeded." RESET "\n", count);
|
||||||
|
else
|
||||||
|
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(dummy_bad) {
|
||||||
|
int x = 2;
|
||||||
|
int y = 3;
|
||||||
|
ASSERT_EQUAL(x, y);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
72
src/util/test.h
Normal file
72
src/util/test.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#ifndef TEST_H
|
||||||
|
#define TEST_H
|
||||||
|
|
||||||
|
#include "bool.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
typedef void Test(Status *test_result_);
|
||||||
|
|
||||||
|
void register_test_(Test *test, const char *name);
|
||||||
|
|
||||||
|
#define TEST(name) \
|
||||||
|
void test_##name(Status *test_result_); \
|
||||||
|
__attribute__((constructor)) void test_register_##name() \
|
||||||
|
{ \
|
||||||
|
register_test_(test_##name, #name); \
|
||||||
|
} \
|
||||||
|
void test_##name(Status *test_result_)
|
||||||
|
|
||||||
|
void run_all_tests(bool verbose);
|
||||||
|
|
||||||
|
#define FAIL_TEST_ \
|
||||||
|
*test_result_ = FAILURE; \
|
||||||
|
return;
|
||||||
|
|
||||||
|
#define ASSERT(value) \
|
||||||
|
if (!(value)) { \
|
||||||
|
FAIL_TEST_ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ASSERT_EQUAL(a, b) \
|
||||||
|
if (!(a == b)) { \
|
||||||
|
printf("%s:%d: Assertion failed: %s == %s: ", __FILE__, __LINE__, #a, #b); \
|
||||||
|
print(a); \
|
||||||
|
printf(" != "); \
|
||||||
|
print(b); \
|
||||||
|
FAIL_TEST_ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ASSERT_DIFFERENT(a, b) \
|
||||||
|
if (a == b) { \
|
||||||
|
printf("%s:%d: Assertion failed: %s != %s: ", __FILE__, __LINE__, #a, #b); \
|
||||||
|
print(a); \
|
||||||
|
printf(" == "); \
|
||||||
|
print(b); \
|
||||||
|
FAIL_TEST_ \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define ASSERT_STR_EQUAL(a, b) \
|
||||||
|
if (strcmp(a, b) != 0) { \
|
||||||
|
printf("%s:%d: Assertion failed: %s == %s: ", __FILE__, __LINE__, #a, #b); \
|
||||||
|
print(a); \
|
||||||
|
printf(" != "); \
|
||||||
|
print(b); \
|
||||||
|
FAIL_TEST_ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ASSERT_STR_DIFFERENT(a, b) \
|
||||||
|
if (strcmp(a, b) == 0) { \
|
||||||
|
printf("%s:%d: Assertion failed: %s != %s: ", __FILE__, __LINE__, #a, #b); \
|
||||||
|
print(a); \
|
||||||
|
printf(" == "); \
|
||||||
|
print(b); \
|
||||||
|
FAIL_TEST_ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ASSERT_TRUE(value) ASSERT_EQUAL(value, 1)
|
||||||
|
#define ASSERT_FALSE(value) ASSERT_EQUAL(value, 0)
|
||||||
|
#define ASSERT_NULL(value) ASSERT_EQUAL(value, NULL)
|
||||||
|
#define ASSERT_NON_NULL(value) ASSERT_DIFFERENT(value, NULL)
|
||||||
|
|
||||||
|
#endif
|
||||||
1997
src/util/timer.c
1997
src/util/timer.c
File diff suppressed because it is too large
Load Diff
@@ -21,45 +21,52 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/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,
|
extern bool debug_timers;
|
||||||
// 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.
|
|
||||||
|
|
||||||
typedef struct _timeout timeout;
|
typedef void TimerCallback(void *arg);
|
||||||
|
|
||||||
// Initializes default global data.
|
typedef struct {
|
||||||
void default_timeout();
|
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.
|
#define DEFAULT_TIMER {"", 0, 0, 0, 0, 0, 0}
|
||||||
void cleanup_timeout();
|
|
||||||
|
|
||||||
// Installs a timer with the first timeout after 'value_msec' and then an optional periodic timeout every
|
#define INIT_TIMER(t) init_timer(&t, #t)
|
||||||
// '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);
|
|
||||||
|
|
||||||
// Changes timer 't'. If it does not exist, a new timer is created, with self set to 't'.
|
// Initialize the timer module.
|
||||||
void change_timeout(timeout **t, int value_msec, int interval_msec, void (*_callback)(void *), void *arg);
|
void default_timers();
|
||||||
|
|
||||||
// Stops the timer 't'
|
// Destroy the timer module.
|
||||||
void stop_timeout(timeout *t);
|
void cleanup_timers();
|
||||||
|
|
||||||
// Get the time when the next installed timer will expire, or NULL if there is no timer.
|
// Initialize a timer. Caller keeps ownership.
|
||||||
// Do not free the pointer; but it is safe to change its contents.
|
void init_timer(Timer *timer, const char *name);
|
||||||
struct timeval *get_next_timeout();
|
|
||||||
|
|
||||||
// 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();
|
void handle_expired_timers();
|
||||||
|
|
||||||
|
// Time helper functions.
|
||||||
|
|
||||||
// Returns -1 if t1 < t2, 0 if t1 == t2, 1 if t1 > t2
|
// Returns -1 if t1 < t2, 0 if t1 == t2, 1 if t1 > t2
|
||||||
gint compare_timespecs(const struct timespec *t1, const struct timespec *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.
|
// At the first call returns zero.
|
||||||
double profiling_get_time();
|
double profiling_get_time();
|
||||||
|
|
||||||
|
// Get current time in seconds, from an unspecified origin.
|
||||||
double get_time();
|
double get_time();
|
||||||
|
|
||||||
#endif // TIMER_H
|
#endif // TIMER_H
|
||||||
|
|||||||
@@ -49,8 +49,9 @@ char *addr2name(void *func)
|
|||||||
free(strings);
|
free(strings);
|
||||||
return result;
|
return result;
|
||||||
#else
|
#else
|
||||||
char *result = (char*) calloc(32, 1);
|
const size_t buf_size = 32;
|
||||||
sprintf(result, "%p", func);
|
char *result = (char*) calloc(buf_size, 1);
|
||||||
|
snprintf(result, buf_size, "%p", func);
|
||||||
return result;
|
return result;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@ sys.setdefaultencoding('utf8')
|
|||||||
import argparse
|
import argparse
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import signal
|
import signal
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
@@ -39,6 +40,10 @@ def print_err(*args, **kwargs):
|
|||||||
print(*args, file=sys.stderr, **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):
|
def run(cmd, output=False):
|
||||||
return subprocess.Popen(cmd,
|
return subprocess.Popen(cmd,
|
||||||
stdin=devnull,
|
stdin=devnull,
|
||||||
@@ -188,6 +193,7 @@ def test(tint2path, config, use_asan):
|
|||||||
mem, mem_detail = get_mem_usage(tint2.pid)
|
mem, mem_detail = get_mem_usage(tint2.pid)
|
||||||
stop(tint2)
|
stop(tint2)
|
||||||
out, _ = tint2.communicate()
|
out, _ = tint2.communicate()
|
||||||
|
out = clear_ansi_codes(out)
|
||||||
exitcode = tint2.returncode
|
exitcode = tint2.returncode
|
||||||
if exitcode != 0 and exitcode != 23:
|
if exitcode != 0 and exitcode != 23:
|
||||||
print("tint2 crashed with exit code {0}!".format(exitcode))
|
print("tint2 crashed with exit code {0}!".format(exitcode))
|
||||||
@@ -222,6 +228,41 @@ def test(tint2path, config, use_asan):
|
|||||||
stop_xvfb()
|
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():
|
def show_timestamp():
|
||||||
utc_datetime = datetime.datetime.utcnow()
|
utc_datetime = datetime.datetime.utcnow()
|
||||||
print("Last updated:", utc_datetime.strftime("%Y-%m-%d %H:%M UTC"))
|
print("Last updated:", utc_datetime.strftime("%Y-%m-%d %H:%M UTC"))
|
||||||
@@ -285,6 +326,29 @@ def compile_and_report(src_dir, use_asan):
|
|||||||
print("Status: Succeeded in %.1f seconds" % (duration,), ok)
|
print("Status: Succeeded in %.1f seconds" % (duration,), ok)
|
||||||
|
|
||||||
|
|
||||||
|
def compile_remotely_and_report(host):
|
||||||
|
print_err("Compiling on {0}...".format(host))
|
||||||
|
print("# Compilation on {0}".format(host))
|
||||||
|
start = time.time()
|
||||||
|
c = run("ssh worker@{0} 'cd tint2 && git pull && mkdir -p build && rm -rf build && mkdir -p build && cd build && cmake .. && make && ./tint2 --version'".format(host), True)
|
||||||
|
out, _ = c.communicate()
|
||||||
|
duration = time.time() - start
|
||||||
|
if c.returncode != 0:
|
||||||
|
print("Status: Failed!", error)
|
||||||
|
print("Output:")
|
||||||
|
print("```\n" + out.strip() + "\n```")
|
||||||
|
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 warnings:
|
||||||
|
print(line, end="")
|
||||||
|
print("```", end="")
|
||||||
|
else:
|
||||||
|
print("Status: Succeeded in %.1f seconds" % (duration,), ok)
|
||||||
|
|
||||||
|
|
||||||
def run_test(config, index, use_asan):
|
def run_test(config, index, use_asan):
|
||||||
print_err("Running test", index, "for config", config)
|
print_err("Running test", index, "for config", config)
|
||||||
print("# Test", index, "(ASAN on)" if use_asan else "")
|
print("# Test", index, "(ASAN on)" if use_asan else "")
|
||||||
@@ -350,8 +414,11 @@ def main():
|
|||||||
show_timestamp()
|
show_timestamp()
|
||||||
show_git_info(args.src_dir)
|
show_git_info(args.src_dir)
|
||||||
show_system_info()
|
show_system_info()
|
||||||
|
compile_remotely_and_report("FreeBSD")
|
||||||
|
compile_remotely_and_report("OpenBSD")
|
||||||
for use_asan in [True, False]:
|
for use_asan in [True, False]:
|
||||||
compile_and_report(args.src_dir, use_asan)
|
compile_and_report(args.src_dir, use_asan)
|
||||||
|
run_unit_tests("./build/tint2", use_asan)
|
||||||
run_tests(use_asan)
|
run_tests(use_asan)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
18
tint2.config
18
tint2.config
@@ -1,8 +1,16 @@
|
|||||||
// ADD PREDEFINED MACROS HERE!
|
// ADD PREDEFINED MACROS HERE!
|
||||||
#define HAVE_RSVG 1
|
#define DISABLE_BACKTRACE 1
|
||||||
#define HAVE_SN 1
|
|
||||||
#define ENABLE_BATTERY 1
|
#define ENABLE_BATTERY 1
|
||||||
#define ENABLE_UEVENT 1
|
#define ENABLE_UEVENT 1
|
||||||
#define GETTEXT_PACKAGE
|
#define GETTEXT_PACKAGE "tint2conf"
|
||||||
#define HAVE_TRACING
|
#define HAS_GENERIC 1
|
||||||
#define ENABLE_EXECINFO
|
#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
|
||||||
|
|||||||
17
tint2.files
17
tint2.files
@@ -20,6 +20,9 @@ src/battery/battery.c
|
|||||||
src/battery/battery.h
|
src/battery/battery.h
|
||||||
src/clock/clock.c
|
src/clock/clock.c
|
||||||
src/clock/clock.h
|
src/clock/clock.h
|
||||||
|
src/default_icon.c
|
||||||
|
src/default_icon.c
|
||||||
|
src/default_icon.h
|
||||||
src/execplugin/execplugin.c
|
src/execplugin/execplugin.c
|
||||||
src/execplugin/execplugin.h
|
src/execplugin/execplugin.h
|
||||||
src/launcher/launcher.c
|
src/launcher/launcher.c
|
||||||
@@ -58,6 +61,8 @@ src/util/blur.c
|
|||||||
src/util/blur.h
|
src/util/blur.h
|
||||||
src/util/common.c
|
src/util/common.c
|
||||||
src/util/common.h
|
src/util/common.h
|
||||||
|
src/util/strlcat.c
|
||||||
|
src/util/strlcat.h
|
||||||
src/util/timer.c
|
src/util/timer.c
|
||||||
src/util/timer.h
|
src/util/timer.h
|
||||||
src/util/window.c
|
src/util/window.c
|
||||||
@@ -237,3 +242,15 @@ src/signals.c
|
|||||||
src/signals.h
|
src/signals.h
|
||||||
src/tracing.c
|
src/tracing.c
|
||||||
src/tracing.h
|
src/tracing.h
|
||||||
|
src/util/test.c
|
||||||
|
src/util/test.h
|
||||||
|
src/util/bool.h
|
||||||
|
src/util/colors.h
|
||||||
|
src/util/print.c
|
||||||
|
src/util/print.h
|
||||||
|
src/util/test.c
|
||||||
|
src/util/test.h
|
||||||
|
src/util/tracing.h
|
||||||
|
src/util/tracing.c
|
||||||
|
src/util/signals.h
|
||||||
|
src/util/signals.c
|
||||||
|
|||||||
@@ -1,22 +1,33 @@
|
|||||||
.
|
.
|
||||||
|
./build
|
||||||
./src
|
./src
|
||||||
./src/battery
|
./src/battery
|
||||||
./src/clock
|
./src/clock
|
||||||
./src/execplugin
|
|
||||||
./src/launcher
|
|
||||||
./src/sysmon
|
|
||||||
./src/systray
|
./src/systray
|
||||||
./src/taskbar
|
./src/taskbar
|
||||||
./src/tint2conf
|
./src/launcher
|
||||||
./src/tooltip
|
./src/tooltip
|
||||||
./src/util
|
./src/util
|
||||||
/usr/include
|
./src/execplugin
|
||||||
/usr/include/gtk-2.0
|
./src/button
|
||||||
/usr/include/glib-2.0
|
./src/freespace
|
||||||
/usr/include/gdk-pixbuf-2.0
|
./src/separator
|
||||||
/usr/include/cairo
|
|
||||||
/usr/include/pango-1.0
|
/usr/include/pango-1.0
|
||||||
|
/usr/include/cairo
|
||||||
|
/usr/include/glib-2.0
|
||||||
|
/usr/lib/x86_64-linux-gnu/glib-2.0/include
|
||||||
|
/usr/include/pixman-1
|
||||||
|
/usr/include/freetype2
|
||||||
|
/usr/include/libpng12
|
||||||
|
/usr/include/librsvg-2.0
|
||||||
|
/usr/include/gdk-pixbuf-2.0
|
||||||
/usr/include/startup-notification-1.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
|
po
|
||||||
src/tint2conf/po
|
src/tint2conf/po
|
||||||
src/freespace
|
src/freespace
|
||||||
|
|||||||
Reference in New Issue
Block a user