Merge branch 'refresh-execp-more' into 'master'

Completed refresh-execp

See merge request o9000/tint2!46
This commit is contained in:
Chris 2021-12-12 01:29:15 +00:00
commit 646dc4cb46
24 changed files with 3880 additions and 3704 deletions

View file

@ -35,6 +35,7 @@ Contributors:
heisenbug (https://gitlab.com/heisenbugh) : taskbar button tinting with icon color heisenbug (https://gitlab.com/heisenbugh) : taskbar button tinting with icon color
Fabian Carlström : taskbar sort order by app name Fabian Carlström : taskbar sort order by app name
Chris Billington (https://gitlab.com/chrisjbillington) : panel struts pivoting Chris Billington (https://gitlab.com/chrisjbillington) : panel struts pivoting
Arash Rohani <rohani.arash@pm.me> : helped with execp refresh
Translations: Translations:
Bosnian: Bosnian:

View file

@ -290,6 +290,7 @@ add_executable(tint2-send src/tint2-send/tint2-send.c)
target_link_libraries(tint2-send ${X11_LIBRARIES}) target_link_libraries(tint2-send ${X11_LIBRARIES})
install( TARGETS tint2 DESTINATION bin ) 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.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps )
install( FILES tint2.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications ) install( FILES tint2.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications )
install( FILES themes/tint2rc DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/xdg/tint2 ) install( FILES themes/tint2rc DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/xdg/tint2 )

View file

@ -595,6 +595,7 @@ panel_size = 94% 30
<h3 id="executor">Executor<a name="executor" href="#executor" class="md2man-permalink" title="permalink"></a></h3> <h3 id="executor">Executor<a name="executor" href="#executor" class="md2man-permalink" title="permalink"></a></h3>
<ul> <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 = 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_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_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> <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>

View file

@ -720,6 +720,8 @@ To hide the clock, comment \fB\fCtime1_format\fR and \fB\fCtime2_format\fR\&.
.IP \(bu 2 .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 \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 .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 \fB\fCexecp_command = text\fR : Command to execute. \fI(since 0.12.4)\fP
.IP \(bu 2 .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 \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

View file

@ -314,6 +314,7 @@ panel_size = 94% 30
<h3 id="executor">Executor<a name="executor" href="#executor" class="md2man-permalink" title="permalink"></a></h3> <h3 id="executor">Executor<a name="executor" href="#executor" class="md2man-permalink" title="permalink"></a></h3>
<ul> <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 = 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_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_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> <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>

View file

@ -593,6 +593,8 @@ 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 = 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_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)* * `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)*

View file

@ -683,6 +683,14 @@ void add_entry(char *key, char *value)
/* Execp */ /* Execp */
else if (strcmp(key, "execp") == 0) { else if (strcmp(key, "execp") == 0) {
panel_config.execp_list = g_list_append(panel_config.execp_list, create_execp()); 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) { } else if (strcmp(key, "execp_command") == 0) {
Execp *execp = get_or_create_last_execp(); Execp *execp = get_or_create_last_execp();
free_and_null(execp->backend->command); free_and_null(execp->backend->command);

View file

@ -20,6 +20,7 @@ extern bool debug_executors;
typedef struct ExecpBackend { typedef struct ExecpBackend {
// Config: // Config:
char name[21];
// Command to execute at a specified interval // Command to execute at a specified interval
char *command; char *command;
// Interval in seconds // Interval in seconds
@ -154,4 +155,6 @@ void execp_default_font_changed();
void handle_execp_events(); void handle_execp_events();
void execp_force_update(Execp *execp);
#endif // EXECPLUGIN_H #endif // EXECPLUGIN_H

View file

@ -32,7 +32,6 @@
#include <X11/extensions/Xdamage.h> #include <X11/extensions/Xdamage.h>
#include <Imlib2.h> #include <Imlib2.h>
#include <signal.h> #include <signal.h>
#include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <pwd.h> #include <pwd.h>
#include <time.h> #include <time.h>
@ -545,6 +544,15 @@ void handle_x_event(XEvent *e)
handle_dnd_position(&e->xclient); handle_dnd_position(&e->xclient);
} else if (e->xclient.message_type == server.atom.XdndDrop) { } else if (e->xclient.message_type == server.atom.XdndDrop) {
handle_dnd_drop(&e->xclient); 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)
execp_force_update(execp);
}
} }
break; break;
} }

View file

@ -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

View file

@ -45,8 +45,8 @@ int is_tint2(Window window)
XWindowAttributes attr = {}; XWindowAttributes attr = {};
if (!XGetWindowAttributes(display, window, &attr)) if (!XGetWindowAttributes(display, window, &attr))
return 0; return 0;
if (attr.map_state != IsViewable) // if (attr.map_state != IsViewable)
return 0; // return 0;
char *wm_class = get_property(window, XA_STRING, "WM_NAME"); char *wm_class = get_property(window, XA_STRING, "WM_NAME");
if (!wm_class) { if (!wm_class) {
@ -60,11 +60,10 @@ int is_tint2(Window window)
return class_match; 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)) if (!is_tint2(window))
return; return;
char *action = (char *)arg;
if (strcmp(action, "show") == 0) { if (strcmp(action, "show") == 0) {
fprintf(stderr, "Showing tint2 window: %lx\n", window); fprintf(stderr, "Showing tint2 window: %lx\n", window);
XEvent event = {}; XEvent event = {};
@ -85,16 +84,40 @@ void handle_tint2_window(Window window, void *arg)
event.xcrossing.same_screen = True; event.xcrossing.same_screen = True;
XSendEvent(display, window, False, 0, &event); XSendEvent(display, window, False, 0, &event);
XFlush(display); 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 { } else {
fprintf(stderr, "Error: unknown action %s\n", action); 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 root = 0;
Window parent = 0; Window parent = 0;
Window *children = 0; Window *children = 0;
@ -104,7 +127,7 @@ void walk_windows(Window node, window_callback_t *callback, void *arg)
return; return;
} }
for (unsigned int i = 0; i < nchildren; i++) { 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++; argc--, argv++;
if (!argc) { if (!argc) {
fprintf(stderr, "Usage: tint2-show [show|hide]\n"); fprintf(stderr, "Usage: tint2-send [show|hide|refresh-execp]\n");
exit(1); exit(1);
} }
char *action = argv[0]; 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; return 0;
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -4271,6 +4271,23 @@ void create_execp(GtkWidget *notebook, int i)
gtk_table_set_col_spacings(GTK_TABLE(table), COL_SPACING); gtk_table_set_col_spacings(GTK_TABLE(table), COL_SPACING);
row = 0, col = 2; 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")); label = gtk_label_new(_("Command"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_show(label); gtk_widget_show(label);

View file

@ -132,6 +132,7 @@ typedef struct Executor {
GtkWidget *container; GtkWidget *container;
GtkWidget *page_execp; GtkWidget *page_execp;
GtkWidget *page_label; GtkWidget *page_label;
GtkWidget *execp_name;
GtkWidget *execp_command, *execp_interval, *execp_has_icon, *execp_cache_icon, *execp_show_tooltip; 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, *execp_monitor;
GtkWidget *execp_left_command, *execp_right_command; GtkWidget *execp_left_command, *execp_right_command;

View file

@ -857,6 +857,7 @@ void config_write_execp(FILE *fp)
Executor *executor = &g_array_index(executors, Executor, i); Executor *executor = &g_array_index(executors, Executor, i);
fprintf(fp, "execp = new\n"); 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_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, "execp_interval = %d\n", (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(executor->execp_interval)));
fprintf(fp, fprintf(fp,
@ -1962,6 +1963,8 @@ void add_entry(char *key, char *value)
/* Executor */ /* Executor */
else if (strcmp(key, "execp") == 0) { else if (strcmp(key, "execp") == 0) {
execp_create_new(); 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) { } else if (strcmp(key, "execp_command") == 0) {
gtk_entry_set_text(GTK_ENTRY(execp_get_last()->execp_command), value); gtk_entry_set_text(GTK_ENTRY(execp_get_last()->execp_command), value);
} else if (strcmp(key, "execp_interval") == 0) { } else if (strcmp(key, "execp_interval") == 0) {

View file

@ -122,6 +122,9 @@ void server_init_atoms()
server.atom.XdndActionCopy = XInternAtom(server.display, "XdndActionCopy", False); server.atom.XdndActionCopy = XInternAtom(server.display, "XdndActionCopy", False);
server.atom.XdndFinished = XInternAtom(server.display, "XdndFinished", False); server.atom.XdndFinished = XInternAtom(server.display, "XdndFinished", False);
server.atom.TARGETS = XInternAtom(server.display, "TARGETS", 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) const char *GetAtomName(Display *disp, Atom a)

View file

@ -91,6 +91,7 @@ typedef struct Global_atom {
Atom XdndActionCopy; Atom XdndActionCopy;
Atom XdndFinished; Atom XdndFinished;
Atom TARGETS; Atom TARGETS;
Atom TINT2_REFRESH_EXECP;
} Global_atom; } Global_atom;
typedef struct Property { typedef struct Property {