Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97a8eade1d |
@@ -1,34 +0,0 @@
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- release
|
||||
|
||||
variables:
|
||||
DEBIAN_FRONTEND: 'noninteractive'
|
||||
|
||||
job-build:
|
||||
stage: build
|
||||
image: ubuntu:rolling
|
||||
script:
|
||||
- sed -Ei 's/^# deb-src /deb-src /' /etc/apt/sources.list
|
||||
- apt-get update
|
||||
- apt-get build-dep -y tint2
|
||||
- apt-get install -y libgtk-3-dev git
|
||||
- git clean -ffdx
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake ..
|
||||
- make -j
|
||||
|
||||
job-release:
|
||||
stage: release
|
||||
image: registry.gitlab.com/gitlab-org/release-cli:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG =~ /^v.*/
|
||||
script:
|
||||
- echo 'running release_job'
|
||||
release:
|
||||
name: 'Release $CI_COMMIT_TAG'
|
||||
description: 'Release $CI_COMMIT_TAG / $CI_COMMIT_SHA'
|
||||
tag_name: '$CI_COMMIT_TAG'
|
||||
ref: '$CI_COMMIT_SHA'
|
||||
1
AUTHORS
1
AUTHORS
@@ -35,7 +35,6 @@ Contributors:
|
||||
heisenbug (https://gitlab.com/heisenbugh) : taskbar button tinting with icon color
|
||||
Fabian Carlström : taskbar sort order by app name
|
||||
Chris Billington (https://gitlab.com/chrisjbillington) : panel struts pivoting
|
||||
Arash Rohani <rohani.arash@pm.me> : helped with execp refresh
|
||||
|
||||
Translations:
|
||||
Bosnian:
|
||||
|
||||
@@ -286,11 +286,7 @@ add_dependencies( tint2 version )
|
||||
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}" )
|
||||
|
||||
add_executable(tint2-send src/tint2-send/tint2-send.c)
|
||||
target_link_libraries(tint2-send ${X11_LIBRARIES})
|
||||
|
||||
install( TARGETS tint2 DESTINATION bin )
|
||||
install( TARGETS tint2-send DESTINATION bin )
|
||||
install( FILES tint2.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps )
|
||||
install( FILES tint2.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications )
|
||||
install( FILES themes/tint2rc DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/xdg/tint2 )
|
||||
|
||||
22
ChangeLog
22
ChangeLog
@@ -1,24 +1,3 @@
|
||||
2021-12-11 master
|
||||
- Enhancements:
|
||||
- Added command to refresh executors (issue #747)
|
||||
2021-12-04 17.0.2
|
||||
- Fixes:
|
||||
- On dual monitor, when minimizing Chrome window it minimizes on the wrong monitor panel (issue #818)
|
||||
2021-05-29 17.0.1
|
||||
- Fixes:
|
||||
- Crash on panel cleanup in single-monitor execp (issue #801)
|
||||
2021-04-18 17.0
|
||||
- Fixes:
|
||||
- Crash when a window icon is large (issue #786) (santouits)
|
||||
- Minute clock doesn't update (issue #786)
|
||||
- Scrollbars in tint2conf (issue #796)
|
||||
- Preserve item order when skipping executors (issue #799)
|
||||
- Image memory leak (issues #704, #721) (Adam M. Trofa)
|
||||
- Incorrect timeout microsecond computation leading to high CPU usage (issue #800)
|
||||
- Enhancements:
|
||||
- Port tint2conf to gtk3 (issue #380)
|
||||
- execp_monitor config (issue #799)
|
||||
- Improved executor examples (Nikita Zlobin)
|
||||
2019-07-14 16.7
|
||||
- Fixes:
|
||||
- Fix spacing around icons in executor without text in vertical panels (issue #716)
|
||||
@@ -1052,4 +1031,3 @@ released tint-0.2
|
||||
.
|
||||
.
|
||||
.
|
||||
.
|
||||
|
||||
10
README.md
10
README.md
@@ -1,9 +1,5 @@
|
||||
# Latest stable release: 17.0.2
|
||||
|
||||
The final release of tint2 is 17.0.2.
|
||||
The code is frozen and no more feature requests are accepted.
|
||||
|
||||
Changes: https://gitlab.com/o9000/tint2/blob/17.0.2/ChangeLog
|
||||
# Latest stable release: 16.7
|
||||
Changes: https://gitlab.com/o9000/tint2/blob/16.7/ChangeLog
|
||||
|
||||
Documentation: [doc/tint2.md](doc/tint2.md)
|
||||
|
||||
@@ -12,7 +8,7 @@ Compile it with (after you install the [dependencies](https://gitlab.com/o9000/t
|
||||
```
|
||||
git clone https://gitlab.com/o9000/tint2.git
|
||||
cd tint2
|
||||
git checkout 17.0.2
|
||||
git checkout 16.7
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
|
||||
@@ -595,7 +595,6 @@ panel_size = 94% 30
|
||||
<h3 id="executor">Executor<a name="executor" href="#executor" class="md2man-permalink" title="permalink"></a></h3>
|
||||
<ul>
|
||||
<li><p><code>execp = new</code> : Begins the configuration of a new executor plugin. Multiple such plugins are supported; just use multiple <code>E</code>s in <code>panel_items</code>. <em>(since 0.12.4)</em></p></li>
|
||||
<li><p><code>execp_name = text</code> : A name that can be used with <code>tint2-send refresh-execp</code> to re-execute the command.</p></li>
|
||||
<li><p><code>execp_command = text</code> : Command to execute. <em>(since 0.12.4)</em></p></li>
|
||||
<li><p><code>execp_interval = integer</code> : The command is executed again after <code>execp_interval</code> seconds from the moment it exits. If zero, the command is executed only once. <em>(since 0.12.4)</em></p></li>
|
||||
<li><p><code>execp_continuous = integer</code> : If non-zero, the last <code>execp_continuous</code> lines from the output of the command are displayed, every <code>execp_continuous</code> lines; this is useful for showing the output of commands that run indefinitely, such as <code>ping 127.0.0.1</code>. If zero, the output of the command is displayed after it finishes executing. <em>(since 0.12.4)</em></p></li>
|
||||
@@ -610,7 +609,6 @@ panel_size = 94% 30
|
||||
<li><p><code>execp_background_id = integer</code> : Which background to use. <em>(since 0.12.4)</em></p></li>
|
||||
<li><p><code>execp_centered = boolean (0 or 1)</code> : Whether to center the text. <em>(since 0.12.4)</em></p></li>
|
||||
<li><p><code>execp_padding = horizontal_padding vertical_padding spacing_between_icon_and_text</code> <em>(since 0.12.4)</em></p></li>
|
||||
<li><p><code>execp_monitor = integer (1, 2, ...), primary or all</code> : On which monitor to draw the executor. The first monitor is <code>1</code>. <em>(since 17.0)</em></p></li>
|
||||
<li><p><code>execp_lclick_command = text</code> : Command to execute on left click. If not defined, <code>execp_command</code> is executed immediately, unless it is currently running. <em>(since 0.12.4)</em></p></li>
|
||||
<li><p><code>execp_mclick_command = text</code> : Command to execute on right click. If not defined, <code>execp_command</code> is executed immediately, unless it is currently running. <em>(since 0.12.4)</em></p></li>
|
||||
<li><p><code>execp_rclick_command = text</code> : Command to execute on middle click. If not defined, <code>execp_command</code> is executed immediately, unless it is currently running. <em>(since 0.12.4)</em></p></li>
|
||||
@@ -649,13 +647,13 @@ execp_command = ping -i 1 -c 1 -W 1 -O -D -n $(ip route | grep default | grep vi
|
||||
execp_continuous = 0
|
||||
execp_interval = 1
|
||||
execp_markup = 1
|
||||
</code></pre></div><h5 id="memory-usage">Memory usage<a name="memory-usage" href="#memory-usage" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code># Note the use of "stdbuf -oL" to force the program to flush the output line by line.
|
||||
</code></pre></div><h5 id="memory-usage">Memory usage<a name="memory-usage" href="#memory-usage" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code>execp = new
|
||||
execp_command = free | awk '/^-/ { printf "Mem: '$(free -h | awk '/^Mem:/ { print $2 }')' %.0f%%\n", 100*$3/($3+$4); fflush(stdout) }'
|
||||
execp_interval = 5
|
||||
execp_continuous = 0
|
||||
</code></pre></div><h5 id="network-load">Network load<a name="network-load" href="#network-load" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code># Note the use of "stdbuf -oL" to force the program to flush the output line by line.
|
||||
execp = new
|
||||
execp_command = free -b -s1 | stdbuf -oL awk '/^Mem:/ { printf "Mem: %s %.0f%%\n", $2, 100 * ($2 - $7) / $2 }' | stdbuf -oL numfmt --to=iec-i --field=2 -d' '
|
||||
execp_interval = 1
|
||||
execp_continuous = 1
|
||||
</code></pre></div><h5 id="network-load">Network load<a name="network-load" href="#network-load" class="md2man-permalink" title="permalink"></a></h5><div class="highlight"><pre class="highlight plaintext"><code>execp = new
|
||||
execp_command = stdbuf -oL bwm-ng -o csv -t 1000 | stdbuf -oL awk -F ';' '/total/ { printf "Net: %.0f Mb/s\n", ($5*8/1.0e6) }'
|
||||
execp_command = stdbuf -oL bwm-ng -o csv -t 1000 | awk -F ';' '/total/ { printf "Net: %.0f Mb/s\n", ($5*8/1.0e6) }; fflush(stdout)'
|
||||
execp_continuous = 1
|
||||
execp_interval = 1
|
||||
</code></pre></div><h3 id="button">Button<a name="button" href="#button" class="md2man-permalink" title="permalink"></a></h3>
|
||||
|
||||
@@ -199,9 +199,9 @@ pre {
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="latest-stable-release-17-0-2"><span class="md2man-title">Latest</span> <span class="md2man-section">stable</span> <span class="md2man-date">release:</span> <span class="md2man-source">17.0.2</span><a name="latest-stable-release-17-0-2" href="#latest-stable-release-17-0-2" class="md2man-permalink" title="permalink"></a></h1><p>Changes: <a href="https://gitlab.com/o9000/tint2/blob/17.0.2/ChangeLog">https://gitlab.com/o9000/tint2/blob/17.0.2/ChangeLog</a></p><p>Documentation: <a href="manual.html">manual.html</a></p><p>Compile it with (after you install the <a href="https://gitlab.com/o9000/tint2/wikis/Install#dependencies">dependencies</a>):</p><div class="highlight"><pre class="highlight plaintext"><code>git clone https://gitlab.com/o9000/tint2.git
|
||||
<h1 id="latest-stable-release-16-7"><span class="md2man-title">Latest</span> <span class="md2man-section">stable</span> <span class="md2man-date">release:</span> <span class="md2man-source">16.7</span><a name="latest-stable-release-16-7" href="#latest-stable-release-16-7" class="md2man-permalink" title="permalink"></a></h1><p>Changes: <a href="https://gitlab.com/o9000/tint2/blob/16.7/ChangeLog">https://gitlab.com/o9000/tint2/blob/16.7/ChangeLog</a></p><p>Documentation: <a href="manual.html">manual.html</a></p><p>Compile it with (after you install the <a href="https://gitlab.com/o9000/tint2/wikis/Install#dependencies">dependencies</a>):</p><div class="highlight"><pre class="highlight plaintext"><code>git clone https://gitlab.com/o9000/tint2.git
|
||||
cd tint2
|
||||
git checkout 17.0.2
|
||||
git checkout 16.7
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
|
||||
10
doc/tint2.1
10
doc/tint2.1
@@ -1,4 +1,4 @@
|
||||
.TH TINT2 1 "2021\-12\-04" 17.0.2
|
||||
.TH TINT2 1 "2019\-07\-14" 16.7
|
||||
.SH NAME
|
||||
.PP
|
||||
tint2 \- lightweight panel/taskbar
|
||||
@@ -720,8 +720,6 @@ To hide the clock, comment \fB\fCtime1_format\fR and \fB\fCtime2_format\fR\&.
|
||||
.IP \(bu 2
|
||||
\fB\fCexecp = new\fR : Begins the configuration of a new executor plugin. Multiple such plugins are supported; just use multiple \fB\fCE\fRs in \fB\fCpanel_items\fR\&. \fI(since 0.12.4)\fP
|
||||
.IP \(bu 2
|
||||
\fB\fCexecp_name = text\fR : A name that can be used with \fB\fCtint2\-send refresh\-execp\fR to re\-execute the command.
|
||||
.IP \(bu 2
|
||||
\fB\fCexecp_command = text\fR : Command to execute. \fI(since 0.12.4)\fP
|
||||
.IP \(bu 2
|
||||
\fB\fCexecp_interval = integer\fR : The command is executed again after \fB\fCexecp_interval\fR seconds from the moment it exits. If zero, the command is executed only once. \fI(since 0.12.4)\fP
|
||||
@@ -750,8 +748,6 @@ To hide the clock, comment \fB\fCtime1_format\fR and \fB\fCtime2_format\fR\&.
|
||||
.IP \(bu 2
|
||||
\fB\fCexecp_padding = horizontal_padding vertical_padding spacing_between_icon_and_text\fR \fI(since 0.12.4)\fP
|
||||
.IP \(bu 2
|
||||
\fB\fCexecp_monitor = integer (1, 2, ...), primary or all\fR : On which monitor to draw the executor. The first monitor is \fB\fC1\fR\&. \fI(since 17.0)\fP
|
||||
.IP \(bu 2
|
||||
\fB\fCexecp_lclick_command = text\fR : Command to execute on left click. If not defined, \fB\fCexecp_command\fR is executed immediately, unless it is currently running. \fI(since 0.12.4)\fP
|
||||
.IP \(bu 2
|
||||
\fB\fCexecp_mclick_command = text\fR : Command to execute on right click. If not defined, \fB\fCexecp_command\fR is executed immediately, unless it is currently running. \fI(since 0.12.4)\fP
|
||||
@@ -837,7 +833,7 @@ execp_markup = 1
|
||||
.nf
|
||||
# Note the use of "stdbuf \-oL" to force the program to flush the output line by line.
|
||||
execp = new
|
||||
execp_command = free \-b \-s1 | stdbuf \-oL awk '/^Mem:/ { printf "Mem: %s %.0f%%\\n", $2, 100 * ($2 \- $7) / $2 }' | stdbuf \-oL numfmt \-\-to=iec\-i \-\-field=2 \-d' '
|
||||
execp_command = free -b -s1 | stdbuf -oL awk '/^Mem:/ { printf "Mem: %s %.0f%%\n", $2, 100 * ($2 - $7) / $2 }' | stdbuf -oL numfmt --to=iec-i --field=2 -d' '
|
||||
execp_interval = 1
|
||||
execp_continuous = 1
|
||||
.fi
|
||||
@@ -847,7 +843,7 @@ execp_continuous = 1
|
||||
.RS
|
||||
.nf
|
||||
execp = new
|
||||
execp_command = stdbuf \-oL bwm\-ng \-o csv \-t 1000 | stdbuf \-oL awk \-F ';' '/total/ { printf "Net: %.0f Mb/s\\n", ($5*8/1.0e6) }'
|
||||
execp_command = stdbuf \-oL bwm\-ng \-o csv \-t 1000 | stdbuf -oL awk \-F ';' '/total/ { printf "Net: %.0f Mb/s\\n", ($5*8/1.0e6) }'
|
||||
execp_continuous = 1
|
||||
execp_interval = 1
|
||||
.fi
|
||||
|
||||
@@ -314,7 +314,6 @@ panel_size = 94% 30
|
||||
<h3 id="executor">Executor<a name="executor" href="#executor" class="md2man-permalink" title="permalink"></a></h3>
|
||||
<ul>
|
||||
<li><p><code>execp = new</code> : Begins the configuration of a new executor plugin. Multiple such plugins are supported; just use multiple <code>E</code>s in <code>panel_items</code>. <em>(since 0.12.4)</em></p></li>
|
||||
<li><p><code>execp_name = text</code> : A name that can be used with <code>tint2-send refresh-execp</code> to re-execute the command.</p></li>
|
||||
<li><p><code>execp_command = text</code> : Command to execute. <em>(since 0.12.4)</em></p></li>
|
||||
<li><p><code>execp_interval = integer</code> : The command is executed again after <code>execp_interval</code> seconds from the moment it exits. If zero, the command is executed only once. <em>(since 0.12.4)</em></p></li>
|
||||
<li><p><code>execp_continuous = integer</code> : If non-zero, the last <code>execp_continuous</code> lines from the output of the command are displayed, every <code>execp_continuous</code> lines; this is useful for showing the output of commands that run indefinitely, such as <code>ping 127.0.0.1</code>. If zero, the output of the command is displayed after it finishes executing. <em>(since 0.12.4)</em></p></li>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# TINT2 1 "2021-12-04" 17.0.2
|
||||
# TINT2 1 "2019-07-14" 16.7
|
||||
|
||||
## NAME
|
||||
tint2 - lightweight panel/taskbar
|
||||
@@ -593,8 +593,6 @@ The action semantics:
|
||||
|
||||
* `execp = new` : Begins the configuration of a new executor plugin. Multiple such plugins are supported; just use multiple `E`s in `panel_items`. *(since 0.12.4)*
|
||||
|
||||
* `execp_name = text` : A name that can be used with `tint2-send refresh-execp` to re-execute the command.
|
||||
|
||||
* `execp_command = text` : Command to execute. *(since 0.12.4)*
|
||||
|
||||
* `execp_interval = integer` : The command is executed again after `execp_interval` seconds from the moment it exits. If zero, the command is executed only once. *(since 0.12.4)*
|
||||
@@ -623,8 +621,6 @@ The action semantics:
|
||||
|
||||
* `execp_padding = horizontal_padding vertical_padding spacing_between_icon_and_text` *(since 0.12.4)*
|
||||
|
||||
* `execp_monitor = integer (1, 2, ...), primary or all` : On which monitor to draw the executor. The first monitor is `1`. *(since 17.0)*
|
||||
|
||||
* `execp_lclick_command = text` : Command to execute on left click. If not defined, `execp_command` is executed immediately, unless it is currently running. *(since 0.12.4)*
|
||||
* `execp_mclick_command = text` : Command to execute on right click. If not defined, `execp_command` is executed immediately, unless it is currently running. *(since 0.12.4)*
|
||||
* `execp_rclick_command = text` : Command to execute on middle click. If not defined, `execp_command` is executed immediately, unless it is currently running. *(since 0.12.4)*
|
||||
|
||||
@@ -6,7 +6,7 @@ Build-Depends: cmake,
|
||||
debhelper (>= 9),
|
||||
libcairo2-dev,
|
||||
libglib2.0-dev,
|
||||
libgtk-3-dev,
|
||||
libgtk2.0-dev,
|
||||
libimlib2-dev,
|
||||
libpango1.0-dev,
|
||||
librsvg2-dev,
|
||||
|
||||
11
src/config.c
11
src/config.c
@@ -683,14 +683,6 @@ void add_entry(char *key, char *value)
|
||||
/* Execp */
|
||||
else if (strcmp(key, "execp") == 0) {
|
||||
panel_config.execp_list = g_list_append(panel_config.execp_list, create_execp());
|
||||
} else if (strcmp(key, "execp_name") == 0) {
|
||||
Execp *execp = get_or_create_last_execp();
|
||||
execp->backend->name[0] = 0;
|
||||
if (strlen(value) > sizeof(execp->backend->name) - 1)
|
||||
fprintf(stderr, RED "tint2: execp_name cannot be more than %ld bytes: '%s'" RESET "\n",
|
||||
sizeof(execp->backend->name) - 1, value);
|
||||
else if (strlen(value) > 0)
|
||||
snprintf(execp->backend->name, sizeof(execp->backend->name), value);
|
||||
} else if (strcmp(key, "execp_command") == 0) {
|
||||
Execp *execp = get_or_create_last_execp();
|
||||
free_and_null(execp->backend->command);
|
||||
@@ -705,9 +697,6 @@ void add_entry(char *key, char *value)
|
||||
} else {
|
||||
execp->backend->interval = v;
|
||||
}
|
||||
} else if (strcmp(key, "execp_monitor") == 0) {
|
||||
Execp *execp = get_or_create_last_execp();
|
||||
execp->backend->monitor = config_get_monitor(value);
|
||||
} else if (strcmp(key, "execp_has_icon") == 0) {
|
||||
Execp *execp = get_or_create_last_execp();
|
||||
execp->backend->has_icon = atoi(value);
|
||||
|
||||
@@ -43,36 +43,13 @@ Execp *create_execp()
|
||||
execp->backend->cache_icon = TRUE;
|
||||
execp->backend->centered = TRUE;
|
||||
execp->backend->font_color.alpha = 0.5;
|
||||
execp->backend->monitor = -1;
|
||||
INIT_TIMER(execp->backend->timer);
|
||||
execp->backend->bg = &g_array_index(backgrounds, Background, 0);
|
||||
execp->backend->buf_stdout_capacity = 1024;
|
||||
execp->backend->buf_stdout = calloc(execp->backend->buf_stdout_capacity, 1);
|
||||
execp->backend->buf_stderr_capacity = 1024;
|
||||
execp->backend->buf_stderr = calloc(execp->backend->buf_stderr_capacity, 1);
|
||||
execp->backend->text = strdup("");
|
||||
execp->backend->icon_path = NULL;
|
||||
return execp;
|
||||
}
|
||||
|
||||
gpointer create_execp_frontend(gconstpointer arg, gpointer data)
|
||||
{
|
||||
Execp *execp_backend = (Execp *)arg;
|
||||
Panel *panel = data;
|
||||
if (execp_backend->backend->monitor >= 0 &&
|
||||
panel->monitor != execp_backend->backend->monitor) {
|
||||
printf("Skipping executor '%s' with monitor %d for panel on monitor %d\n",
|
||||
execp_backend->backend->command,
|
||||
execp_backend->backend->monitor, panel->monitor);
|
||||
Execp *dummy = create_execp();
|
||||
dummy->frontend = (ExecpFrontend *)calloc(1, sizeof(ExecpFrontend));
|
||||
dummy->backend->instances = g_list_append(dummy->backend->instances, dummy);
|
||||
dummy->dummy = true;
|
||||
return dummy;
|
||||
}
|
||||
printf("Creating executor '%s' with monitor %d for panel on monitor %d\n",
|
||||
execp_backend->backend->command,
|
||||
execp_backend->backend->monitor, panel->monitor);
|
||||
|
||||
Execp *execp_frontend = (Execp *)calloc(1, sizeof(Execp));
|
||||
execp_frontend->backend = execp_backend->backend;
|
||||
@@ -90,11 +67,7 @@ void destroy_execp(void *obj)
|
||||
free_and_null(execp->frontend);
|
||||
remove_area(&execp->area);
|
||||
free_area(&execp->area);
|
||||
if (execp->dummy) {
|
||||
destroy_execp(execp);
|
||||
} else {
|
||||
free_and_null(execp);
|
||||
}
|
||||
free_and_null(execp);
|
||||
} else {
|
||||
// This is a backend element
|
||||
destroy_timer(&execp->backend->timer);
|
||||
@@ -171,6 +144,12 @@ void init_execp()
|
||||
// Set missing config options
|
||||
if (!execp->backend->bg)
|
||||
execp->backend->bg = &g_array_index(backgrounds, Background, 0);
|
||||
execp->backend->buf_stdout_capacity = 1024;
|
||||
execp->backend->buf_stdout = calloc(execp->backend->buf_stdout_capacity, 1);
|
||||
execp->backend->buf_stderr_capacity = 1024;
|
||||
execp->backend->buf_stderr = calloc(execp->backend->buf_stderr_capacity, 1);
|
||||
execp->backend->text = strdup("");
|
||||
execp->backend->icon_path = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +163,7 @@ void init_execp_panel(void *p)
|
||||
|
||||
// panel->execp_list is now a copy of the pointer panel_config.execp_list
|
||||
// We make it a deep copy
|
||||
panel->execp_list = g_list_copy_deep(panel_config.execp_list, create_execp_frontend, panel);
|
||||
panel->execp_list = g_list_copy_deep(panel_config.execp_list, create_execp_frontend, NULL);
|
||||
|
||||
for (GList *l = panel->execp_list; l; l = l->next) {
|
||||
Execp *execp = l->data;
|
||||
|
||||
@@ -20,12 +20,10 @@ extern bool debug_executors;
|
||||
|
||||
typedef struct ExecpBackend {
|
||||
// Config:
|
||||
char name[21];
|
||||
// Command to execute at a specified interval
|
||||
char *command;
|
||||
// Interval in seconds
|
||||
int interval;
|
||||
int monitor;
|
||||
// 1 if first line of output is an icon path
|
||||
gboolean has_icon;
|
||||
gboolean cache_icon;
|
||||
@@ -98,7 +96,6 @@ typedef struct Execp {
|
||||
ExecpBackend *backend;
|
||||
// Set only for frontend Execp items.
|
||||
ExecpFrontend *frontend;
|
||||
bool dummy;
|
||||
} Execp;
|
||||
|
||||
// Called before the config is read and panel_config/panels are created.
|
||||
@@ -155,6 +152,4 @@ void execp_default_font_changed();
|
||||
|
||||
void handle_execp_events();
|
||||
|
||||
void execp_force_update(Execp *execp);
|
||||
|
||||
#endif // EXECPLUGIN_H
|
||||
|
||||
12
src/main.c
12
src/main.c
@@ -32,6 +32,7 @@
|
||||
#include <X11/extensions/Xdamage.h>
|
||||
#include <Imlib2.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <time.h>
|
||||
@@ -544,17 +545,6 @@ void handle_x_event(XEvent *e)
|
||||
handle_dnd_position(&e->xclient);
|
||||
} else if (e->xclient.message_type == server.atom.XdndDrop) {
|
||||
handle_dnd_drop(&e->xclient);
|
||||
} else if (e->xclient.message_type == server.atom.TINT2_REFRESH_EXECP &&
|
||||
e->xclient.format == 8) {
|
||||
char name[sizeof(e->xclient.data.b) + 1] = {};
|
||||
memcpy(name, e->xclient.data.b, sizeof(e->xclient.data.b));
|
||||
for (GList *l = panel_config.execp_list; l; l = l->next) {
|
||||
Execp *execp = (Execp *)l->data;
|
||||
if (strncmp(name, execp->backend->name, sizeof(execp->backend->name) - 1) == 0) {
|
||||
fprintf(stderr, "tint2: Refreshing executor: %s\n", name);
|
||||
execp_force_update(execp);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -269,9 +269,8 @@ void init_panel()
|
||||
init_freespace_panel(p);
|
||||
if (panel_items_order[k] == ':')
|
||||
init_separator_panel(p);
|
||||
if (panel_items_order[k] == 'E') {
|
||||
if (panel_items_order[k] == 'E')
|
||||
init_execp_panel(p);
|
||||
}
|
||||
if (panel_items_order[k] == 'P')
|
||||
init_button_panel(p);
|
||||
}
|
||||
|
||||
@@ -292,10 +292,9 @@ void on_change_systray(void *obj)
|
||||
}
|
||||
|
||||
TrayWindow *traywin;
|
||||
GSList *l, *next;
|
||||
GSList *l;
|
||||
int i;
|
||||
for (i = 1, l = systray.list_icons; l; i++, l = next) {
|
||||
next = l->next;
|
||||
for (i = 1, l = systray.list_icons; l; i++, l = l->next) {
|
||||
traywin = (TrayWindow *)l->data;
|
||||
|
||||
traywin->y = posy;
|
||||
|
||||
12
src/tint2-send/Makefile
Normal file
12
src/tint2-send/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
ifeq ($(PREFIX),)
|
||||
PREFIX := /usr/local
|
||||
endif
|
||||
|
||||
tint2-send: tint2-send.c
|
||||
$(CC) tint2-send.c -lX11 -o tint2-send
|
||||
|
||||
install: tint2-send
|
||||
install -m 755 tint2-send $(DESTDIR)/$(PREFIX)/bin/
|
||||
|
||||
clean:
|
||||
rm -f tint2-send
|
||||
@@ -45,8 +45,8 @@ int is_tint2(Window window)
|
||||
XWindowAttributes attr = {};
|
||||
if (!XGetWindowAttributes(display, window, &attr))
|
||||
return 0;
|
||||
// if (attr.map_state != IsViewable)
|
||||
// return 0;
|
||||
if (attr.map_state != IsViewable)
|
||||
return 0;
|
||||
|
||||
char *wm_class = get_property(window, XA_STRING, "WM_NAME");
|
||||
if (!wm_class) {
|
||||
@@ -60,10 +60,11 @@ int is_tint2(Window window)
|
||||
return class_match;
|
||||
}
|
||||
|
||||
void handle_tint2_window(Window window, char *action, char **args)
|
||||
void handle_tint2_window(Window window, void *arg)
|
||||
{
|
||||
if (!is_tint2(window))
|
||||
return;
|
||||
char *action = (char *)arg;
|
||||
if (strcmp(action, "show") == 0) {
|
||||
fprintf(stderr, "Showing tint2 window: %lx\n", window);
|
||||
XEvent event = {};
|
||||
@@ -84,40 +85,16 @@ void handle_tint2_window(Window window, char *action, char **args)
|
||||
event.xcrossing.same_screen = True;
|
||||
XSendEvent(display, window, False, 0, &event);
|
||||
XFlush(display);
|
||||
} else if (strcmp(action, "refresh-execp") == 0) {
|
||||
XEvent event = {};
|
||||
char *name = args[0];
|
||||
if (!name) {
|
||||
fprintf(stderr, "Error: missing execp name\n");
|
||||
return;
|
||||
}
|
||||
if (!name[0]) {
|
||||
fprintf(stderr, "Error: empty execp name\n");
|
||||
return;
|
||||
}
|
||||
if (strlen(name) > sizeof(event.xclient.data.b)) {
|
||||
fprintf(stderr, "Error: execp name bigger than %ld bytes\n", sizeof(event.xclient.data.b));
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "Refreshing execp '%s' for window: %lx\n", name, window);
|
||||
event.xclient.type = ClientMessage;
|
||||
event.xclient.window = window;
|
||||
event.xclient.send_event = True;
|
||||
event.xclient.message_type = XInternAtom(display, "_TINT2_REFRESH_EXECP", False);
|
||||
event.xclient.format = 8;
|
||||
strncpy(event.xclient.data.b, name, sizeof(event.xclient.data.b));
|
||||
XSendEvent(display, window, False, 0, &event);
|
||||
XFlush(display);
|
||||
} else {
|
||||
fprintf(stderr, "Error: unknown action %s\n", action);
|
||||
}
|
||||
}
|
||||
|
||||
typedef void window_callback_t(Window window, char *action, char **args);
|
||||
typedef void window_callback_t(Window window, void *arg);
|
||||
|
||||
void walk_windows(Window node, window_callback_t *callback, char *action, char **args)
|
||||
void walk_windows(Window node, window_callback_t *callback, void *arg)
|
||||
{
|
||||
callback(node, action, args);
|
||||
callback(node, arg);
|
||||
Window root = 0;
|
||||
Window parent = 0;
|
||||
Window *children = 0;
|
||||
@@ -127,7 +104,7 @@ void walk_windows(Window node, window_callback_t *callback, char *action, char *
|
||||
return;
|
||||
}
|
||||
for (unsigned int i = 0; i < nchildren; i++) {
|
||||
walk_windows(children[i], callback, action, args);
|
||||
walk_windows(children[i], callback, arg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,12 +118,11 @@ int main(int argc, char **argv)
|
||||
|
||||
argc--, argv++;
|
||||
if (!argc) {
|
||||
fprintf(stderr, "Usage: tint2-send [show|hide|refresh-execp]\n");
|
||||
fprintf(stderr, "Usage: tint2-show [show|hide]\n");
|
||||
exit(1);
|
||||
}
|
||||
char *action = argv[0];
|
||||
char **args = argv + 1;
|
||||
walk_windows(DefaultRootWindow(display), handle_tint2_window, action, args);
|
||||
walk_windows(DefaultRootWindow(display), handle_tint2_window, action);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ add_definitions( -DINSTALL_PREFIX=\"${CMAKE_INSTALL_PREFIX}\" )
|
||||
add_definitions( -DLOCALEDIR=\"${CMAKE_INSTALL_FULL_LOCALEDIR}\" )
|
||||
add_definitions( -DGETTEXT_PACKAGE=\"tint2conf\" )
|
||||
add_definitions( -DDGLIB_DISABLE_DEPRECATION_WARNINGS=1 )
|
||||
set_target_properties( tint2conf PROPERTIES COMPILE_FLAGS "-Wall -Wpointer-arith -fno-strict-aliasing -pthread -std=c99 -Werror-implicit-function-declaration -Wno-deprecated -Wno-deprecated-declarations" )
|
||||
set_target_properties( tint2conf PROPERTIES COMPILE_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wpointer-arith -fno-strict-aliasing -pthread -std=c99 -Werror-implicit-function-declaration -Wno-deprecated -Wno-deprecated-declarations" )
|
||||
set_target_properties( tint2conf PROPERTIES LINK_FLAGS "-pthread" )
|
||||
|
||||
add_subdirectory(po)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -234,17 +234,10 @@ GtkWidget *create_properties()
|
||||
dialog_vbox3 = gtk_dialog_get_content_area(GTK_DIALOG(view));
|
||||
gtk_widget_show(dialog_vbox3);
|
||||
|
||||
GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_box_pack_start(GTK_BOX(dialog_vbox3), scroll, TRUE, TRUE, 1);
|
||||
gtk_widget_show(scroll);
|
||||
|
||||
notebook = gtk_notebook_new();
|
||||
gtk_widget_show(notebook);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(notebook), 5);
|
||||
gtk_container_add(GTK_CONTAINER(scroll), notebook);
|
||||
gtk_box_pack_start(GTK_BOX(dialog_vbox3), notebook, TRUE, TRUE, 6);
|
||||
gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_LEFT);
|
||||
|
||||
button = gtk_button_new_from_stock("gtk-apply");
|
||||
@@ -4271,23 +4264,6 @@ void create_execp(GtkWidget *notebook, int i)
|
||||
gtk_table_set_col_spacings(GTK_TABLE(table), COL_SPACING);
|
||||
row = 0, col = 2;
|
||||
|
||||
label = gtk_label_new(_("Name"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
|
||||
gtk_widget_show(label);
|
||||
gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0);
|
||||
col++;
|
||||
|
||||
executor->execp_name = gtk_entry_new();
|
||||
gtk_widget_show(executor->execp_name);
|
||||
gtk_entry_set_width_chars(GTK_ENTRY(executor->execp_name), 20);
|
||||
gtk_entry_set_max_length(GTK_ENTRY(executor->execp_name), 20);
|
||||
gtk_table_attach(GTK_TABLE(table), executor->execp_name, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0);
|
||||
col++;
|
||||
gtk_widget_set_tooltip_text(executor->execp_name,
|
||||
_("Specifies a name that can be used with `tint2-send refresh-execp` to re-execute "
|
||||
"the command."));
|
||||
|
||||
row++, col = 2;
|
||||
label = gtk_label_new(_("Command"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
|
||||
gtk_widget_show(label);
|
||||
@@ -4391,31 +4367,6 @@ void create_execp(GtkWidget *notebook, int i)
|
||||
"that print data downloaded from the Internet is a potential security risk."),
|
||||
NULL);
|
||||
|
||||
row++, col = 2;
|
||||
label = gtk_label_new(_("Monitor"));
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
|
||||
gtk_widget_show(label);
|
||||
gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0);
|
||||
col++;
|
||||
|
||||
executor->execp_monitor = gtk_combo_box_text_new();
|
||||
gtk_widget_show(executor->execp_monitor);
|
||||
gtk_table_attach(GTK_TABLE(table), executor->execp_monitor, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0);
|
||||
col++;
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(executor->execp_monitor), _("All"));
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(executor->execp_monitor), _("Primary"));
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(executor->execp_monitor), _("1"));
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(executor->execp_monitor), _("2"));
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(executor->execp_monitor), _("3"));
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(executor->execp_monitor), _("4"));
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(executor->execp_monitor), _("5"));
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(executor->execp_monitor), _("6"));
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(executor->execp_monitor), 0);
|
||||
gtk_tooltips_set_tip(tooltips,
|
||||
executor->execp_monitor,
|
||||
_("Specifies the monitor on which to place the executor."),
|
||||
NULL);
|
||||
|
||||
change_paragraph(parent);
|
||||
|
||||
label = gtk_label_new(_("<b>Mouse events</b>"));
|
||||
|
||||
@@ -132,9 +132,8 @@ typedef struct Executor {
|
||||
GtkWidget *container;
|
||||
GtkWidget *page_execp;
|
||||
GtkWidget *page_label;
|
||||
GtkWidget *execp_name;
|
||||
GtkWidget *execp_command, *execp_interval, *execp_has_icon, *execp_cache_icon, *execp_show_tooltip;
|
||||
GtkWidget *execp_continuous, *execp_markup, *execp_tooltip, *execp_monitor;
|
||||
GtkWidget *execp_continuous, *execp_markup, *execp_tooltip;
|
||||
GtkWidget *execp_left_command, *execp_right_command;
|
||||
GtkWidget *execp_mclick_command, *execp_rclick_command, *execp_uwheel_command, *execp_dwheel_command;
|
||||
GtkWidget *execp_font, *execp_font_set, *execp_font_color, *execp_padding_x, *execp_padding_y, *execp_centered;
|
||||
|
||||
@@ -857,7 +857,6 @@ void config_write_execp(FILE *fp)
|
||||
Executor *executor = &g_array_index(executors, Executor, i);
|
||||
|
||||
fprintf(fp, "execp = new\n");
|
||||
fprintf(fp, "execp_name = %s\n", gtk_entry_get_text(GTK_ENTRY(executor->execp_name)));
|
||||
fprintf(fp, "execp_command = %s\n", gtk_entry_get_text(GTK_ENTRY(executor->execp_command)));
|
||||
fprintf(fp, "execp_interval = %d\n", (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(executor->execp_interval)));
|
||||
fprintf(fp,
|
||||
@@ -872,16 +871,6 @@ void config_write_execp(FILE *fp)
|
||||
fprintf(fp,
|
||||
"execp_markup = %d\n",
|
||||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(executor->execp_markup)) ? 1 : 0);
|
||||
fprintf(fp, "execp_monitor = ");
|
||||
if (gtk_combo_box_get_active(GTK_COMBO_BOX(executor->execp_monitor)) <= 0) {
|
||||
fprintf(fp, "all");
|
||||
} else if (gtk_combo_box_get_active(GTK_COMBO_BOX(executor->execp_monitor)) == 1) {
|
||||
fprintf(fp, "primary");
|
||||
} else {
|
||||
fprintf(fp, "%d", MAX(1, gtk_combo_box_get_active(GTK_COMBO_BOX(executor->execp_monitor)) - 1));
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
|
||||
if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(executor->execp_show_tooltip))) {
|
||||
fprintf(fp, "execp_tooltip = \n");
|
||||
} else {
|
||||
@@ -1963,8 +1952,6 @@ void add_entry(char *key, char *value)
|
||||
/* Executor */
|
||||
else if (strcmp(key, "execp") == 0) {
|
||||
execp_create_new();
|
||||
} else if (strcmp(key, "execp_name") == 0) {
|
||||
gtk_entry_set_text(GTK_ENTRY(execp_get_last()->execp_name), value);
|
||||
} else if (strcmp(key, "execp_command") == 0) {
|
||||
gtk_entry_set_text(GTK_ENTRY(execp_get_last()->execp_command), value);
|
||||
} else if (strcmp(key, "execp_interval") == 0) {
|
||||
@@ -1977,23 +1964,6 @@ void add_entry(char *key, char *value)
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(execp_get_last()->execp_continuous), atoi(value));
|
||||
} else if (strcmp(key, "execp_markup") == 0) {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(execp_get_last()->execp_markup), atoi(value));
|
||||
} else if (strcmp(key, "execp_monitor") == 0) {
|
||||
if (strcmp(value, "all") == 0)
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(execp_get_last()->execp_monitor), 0);
|
||||
else if (strcmp(value, "primary") == 0)
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(execp_get_last()->execp_monitor), 1);
|
||||
else if (strcmp(value, "1") == 0)
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(execp_get_last()->execp_monitor), 2);
|
||||
else if (strcmp(value, "2") == 0)
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(execp_get_last()->execp_monitor), 3);
|
||||
else if (strcmp(value, "3") == 0)
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(execp_get_last()->execp_monitor), 4);
|
||||
else if (strcmp(value, "4") == 0)
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(execp_get_last()->execp_monitor), 5);
|
||||
else if (strcmp(value, "5") == 0)
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(execp_get_last()->execp_monitor), 6);
|
||||
else if (strcmp(value, "6") == 0)
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(execp_get_last()->execp_monitor), 7);
|
||||
} else if (strcmp(key, "execp_tooltip") == 0) {
|
||||
if (strlen(value) > 0) {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(execp_get_last()->execp_show_tooltip), 1);
|
||||
|
||||
@@ -794,8 +794,8 @@ Imlib_Image load_image(const char *path, int cached)
|
||||
static unsigned long counter = 0;
|
||||
if (debug_icons)
|
||||
fprintf(stderr, "tint2: loading icon %s\n", path);
|
||||
image = imlib_load_image(path);
|
||||
#ifdef HAVE_RSVG
|
||||
image = imlib_load_image(path);
|
||||
if (!image && g_str_has_suffix(path, ".svg")) {
|
||||
char tmp_filename[128];
|
||||
snprintf(tmp_filename, sizeof(tmp_filename), "/tmp/tint2-%d-%lu.png", (int)getpid(), counter);
|
||||
@@ -825,8 +825,11 @@ Imlib_Image load_image(const char *path, int cached)
|
||||
unlink(tmp_filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
image = imlib_load_image(path);
|
||||
}
|
||||
imlib_context_set_image(image);
|
||||
imlib_image_set_changes_on_disk();
|
||||
return image;
|
||||
|
||||
@@ -122,9 +122,6 @@ void server_init_atoms()
|
||||
server.atom.XdndActionCopy = XInternAtom(server.display, "XdndActionCopy", False);
|
||||
server.atom.XdndFinished = XInternAtom(server.display, "XdndFinished", False);
|
||||
server.atom.TARGETS = XInternAtom(server.display, "TARGETS", False);
|
||||
|
||||
// tint2 atoms
|
||||
server.atom.TINT2_REFRESH_EXECP = XInternAtom(server.display, "_TINT2_REFRESH_EXECP", False);
|
||||
}
|
||||
|
||||
const char *GetAtomName(Display *disp, Atom a)
|
||||
|
||||
@@ -91,7 +91,6 @@ typedef struct Global_atom {
|
||||
Atom XdndActionCopy;
|
||||
Atom XdndFinished;
|
||||
Atom TARGETS;
|
||||
Atom TINT2_REFRESH_EXECP;
|
||||
} Global_atom;
|
||||
|
||||
typedef struct Property {
|
||||
|
||||
@@ -85,6 +85,7 @@ static void sigchld_handler(int sig)
|
||||
int savedErrno = errno;
|
||||
ssize_t unused = write(sigchild_pipe[1], "x", 1);
|
||||
(void)unused;
|
||||
fsync(sigchild_pipe[1]);
|
||||
errno = savedErrno;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,8 +131,7 @@ struct timeval *get_duration_to_next_timer_expiration()
|
||||
next_timer->expiration_time_ms_,
|
||||
next_timer->period_ms_);
|
||||
result.tv_sec = duration / 1000;
|
||||
duration -= result.tv_sec * 1000;
|
||||
result.tv_usec = 1000 * duration;
|
||||
result.tv_usec = 1000 * (duration - result.tv_sec);
|
||||
return &result;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,40 +169,31 @@ int get_window_desktop(Window win)
|
||||
return best_match;
|
||||
}
|
||||
|
||||
#define swap(a, b) do { __typeof__(a) _tmp = (a); (a) = (b); (b) = _tmp; } while(0)
|
||||
|
||||
int get_interval_overlap(int a1, int a2, int b1, int b2)
|
||||
{
|
||||
if (a1 > b1) {
|
||||
swap(a1, b1);
|
||||
swap(a2, b2);
|
||||
}
|
||||
if (b1 <= a2)
|
||||
return a2 - b1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_window_monitor(Window win)
|
||||
{
|
||||
int x, y, w, h;
|
||||
get_window_coordinates(win, &x, &y, &w, &h);
|
||||
|
||||
int best_match = 0;
|
||||
int best_area = -1;
|
||||
int best_match = -1;
|
||||
int match_right = 0;
|
||||
int match_bottom = 0;
|
||||
// There is an ambiguity when a window is right on the edge between screens.
|
||||
// In that case, prefer the monitor which is on the right and bottom of the window's top-left corner.
|
||||
for (int i = 0; i < server.num_monitors; i++) {
|
||||
int commonx = get_interval_overlap(x, x + w, server.monitors[i].x, server.monitors[i].x + server.monitors[i].width);
|
||||
int commony = get_interval_overlap(y, y + h, server.monitors[i].y, server.monitors[i].y + server.monitors[i].height);
|
||||
int area = commonx * commony;
|
||||
if (0)
|
||||
printf("Monitor %d (%dx%d+%dx%d): win (%dx%d+%dx%d) area %dx%d=%d\n",
|
||||
i, server.monitors[i].x, server.monitors[i].y, server.monitors[i].width, server.monitors[i].height,
|
||||
x, y, w, h,
|
||||
commonx, commony, area);
|
||||
if (area > best_area) {
|
||||
best_area = area;
|
||||
best_match = i;
|
||||
if (x >= server.monitors[i].x && x <= (server.monitors[i].x + server.monitors[i].width) &&
|
||||
y >= server.monitors[i].y && y <= (server.monitors[i].y + server.monitors[i].height)) {
|
||||
int current_right = x < (server.monitors[i].x + server.monitors[i].width);
|
||||
int current_bottom = y < (server.monitors[i].y + server.monitors[i].height);
|
||||
if (best_match < 0 || (!match_right && current_right) || (!match_bottom && current_bottom)) {
|
||||
best_match = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best_match < 0)
|
||||
best_match = 0;
|
||||
// fprintf(stderr, "tint2: desktop %d, window %lx %s : monitor %d, (%d, %d)\n", 1 + get_current_desktop(), win,
|
||||
// get_task(win) ? get_task(win)->title : "??", best_match+1, x, y);
|
||||
return best_match;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user