Compare commits
11 Commits
v17.0
...
refresh-ex
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1a3cc7977 | ||
|
|
f8f9c18cef | ||
|
|
56bccf2b4f | ||
|
|
ec4eccd769 | ||
|
|
2ed026ba32 | ||
|
|
a4996c84bd | ||
|
|
7b42055a20 | ||
|
|
f628cba966 | ||
|
|
a922884485 | ||
|
|
66a6238014 | ||
|
|
5e8c65b87e |
34
.gitlab-ci.yml
Normal file
34
.gitlab-ci.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
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'
|
||||
@@ -286,6 +286,9 @@ 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( FILES tint2.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps )
|
||||
install( FILES tint2.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications )
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
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)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Latest stable release: 17.0
|
||||
Changes: https://gitlab.com/o9000/tint2/blob/17.0/ChangeLog
|
||||
# Latest stable release: 17.0.2
|
||||
Changes: https://gitlab.com/o9000/tint2/blob/17.0.2/ChangeLog
|
||||
|
||||
Documentation: [doc/tint2.md](doc/tint2.md)
|
||||
|
||||
@@ -8,7 +8,7 @@ Compile it with (after you install the [dependencies](https://gitlab.com/o9000/t
|
||||
```
|
||||
git clone https://gitlab.com/o9000/tint2.git
|
||||
cd tint2
|
||||
git checkout 17.0
|
||||
git checkout 17.0.2
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
|
||||
@@ -199,9 +199,9 @@ pre {
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="latest-stable-release-17-0"><span class="md2man-title">Latest</span> <span class="md2man-section">stable</span> <span class="md2man-date">release:</span> <span class="md2man-source">17.0</span><a name="latest-stable-release-17-0" href="#latest-stable-release-17-0" class="md2man-permalink" title="permalink"></a></h1><p>Changes: <a href="https://gitlab.com/o9000/tint2/blob/17.0/ChangeLog">https://gitlab.com/o9000/tint2/blob/17.0/ChangeLog</a></p><p>Documentation: <a href="manual.html">manual.html</a></p><p>Compile it with (after you install the <a href="https://gitlab.com/o9000/tint2/wikis/Install#dependencies">dependencies</a>):</p><div class="highlight"><pre class="highlight plaintext"><code>git clone https://gitlab.com/o9000/tint2.git
|
||||
<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
|
||||
cd tint2
|
||||
git checkout 17.0
|
||||
git checkout 17.0.2
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH TINT2 1 "2021\-04\-18" 17.0
|
||||
.TH TINT2 1 "2021\-12\-04" 17.0.2
|
||||
.SH NAME
|
||||
.PP
|
||||
tint2 \- lightweight panel/taskbar
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# TINT2 1 "2021-04-18" 17.0
|
||||
# TINT2 1 "2021-12-04" 17.0.2
|
||||
|
||||
## NAME
|
||||
tint2 - lightweight panel/taskbar
|
||||
|
||||
@@ -66,7 +66,8 @@ gpointer create_execp_frontend(gconstpointer arg, gpointer data)
|
||||
execp_backend->backend->monitor, panel->monitor);
|
||||
Execp *dummy = create_execp();
|
||||
dummy->frontend = (ExecpFrontend *)calloc(1, sizeof(ExecpFrontend));
|
||||
dummy->backend->instances = g_list_append(execp_backend->backend->instances, dummy);
|
||||
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",
|
||||
@@ -89,7 +90,11 @@ void destroy_execp(void *obj)
|
||||
free_and_null(execp->frontend);
|
||||
remove_area(&execp->area);
|
||||
free_area(&execp->area);
|
||||
free_and_null(execp);
|
||||
if (execp->dummy) {
|
||||
destroy_execp(execp);
|
||||
} else {
|
||||
free_and_null(execp);
|
||||
}
|
||||
} else {
|
||||
// This is a backend element
|
||||
destroy_timer(&execp->backend->timer);
|
||||
|
||||
@@ -97,6 +97,7 @@ 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.
|
||||
|
||||
@@ -545,6 +545,11 @@ 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));
|
||||
printf("TODO: refresh execp: %s\n", name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
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
|
||||
@@ -60,11 +60,10 @@ int is_tint2(Window window)
|
||||
return class_match;
|
||||
}
|
||||
|
||||
void handle_tint2_window(Window window, void *arg)
|
||||
void handle_tint2_window(Window window, char *action, char **args)
|
||||
{
|
||||
if (!is_tint2(window))
|
||||
return;
|
||||
char *action = (char *)arg;
|
||||
if (strcmp(action, "show") == 0) {
|
||||
fprintf(stderr, "Showing tint2 window: %lx\n", window);
|
||||
XEvent event = {};
|
||||
@@ -85,16 +84,40 @@ void handle_tint2_window(Window window, void *arg)
|
||||
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 too long\n");
|
||||
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, void *arg);
|
||||
typedef void window_callback_t(Window window, char *action, char **args);
|
||||
|
||||
void walk_windows(Window node, window_callback_t *callback, void *arg)
|
||||
void walk_windows(Window node, window_callback_t *callback, char *action, char **args)
|
||||
{
|
||||
callback(node, arg);
|
||||
callback(node, action, args);
|
||||
Window root = 0;
|
||||
Window parent = 0;
|
||||
Window *children = 0;
|
||||
@@ -104,7 +127,7 @@ void walk_windows(Window node, window_callback_t *callback, void *arg)
|
||||
return;
|
||||
}
|
||||
for (unsigned int i = 0; i < nchildren; i++) {
|
||||
walk_windows(children[i], callback, arg);
|
||||
walk_windows(children[i], callback, action, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,11 +141,12 @@ int main(int argc, char **argv)
|
||||
|
||||
argc--, argv++;
|
||||
if (!argc) {
|
||||
fprintf(stderr, "Usage: tint2-show [show|hide]\n");
|
||||
fprintf(stderr, "Usage: tint2-show [show|hide|refresh-execp]\n");
|
||||
exit(1);
|
||||
}
|
||||
char *action = argv[0];
|
||||
walk_windows(DefaultRootWindow(display), handle_tint2_window, action);
|
||||
char **args = argv + 1;
|
||||
walk_windows(DefaultRootWindow(display), handle_tint2_window, action, args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -122,6 +122,9 @@ 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,6 +91,7 @@ typedef struct Global_atom {
|
||||
Atom XdndActionCopy;
|
||||
Atom XdndFinished;
|
||||
Atom TARGETS;
|
||||
Atom TINT2_REFRESH_EXECP;
|
||||
} Global_atom;
|
||||
|
||||
typedef struct Property {
|
||||
|
||||
@@ -85,7 +85,6 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,31 +169,40 @@ 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 = -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.
|
||||
int best_match = 0;
|
||||
int best_area = -1;
|
||||
for (int i = 0; i < server.num_monitors; 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;
|
||||
}
|
||||
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 (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