mirror of
https://github.com/i3/i3.git
synced 2026-02-04 23:45:31 +00:00
provide I3_WINDOW_ID to processes called with exec when possible (#6160)
fixes #1729
This commit is contained in:
@ -30,7 +30,7 @@
|
||||
* (and ID) should be created, which is the default and encouraged behavior.
|
||||
*
|
||||
*/
|
||||
void start_application(const char *command, bool no_startup_id);
|
||||
void start_application(const char *command, bool no_startup_id, xcb_window_t window_id);
|
||||
|
||||
/**
|
||||
* Deletes a startup sequence, ignoring whether its timeout has elapsed.
|
||||
|
||||
@ -1262,7 +1262,9 @@ void cmd_exec(I3_CMD, const char *nosn, const char *command) {
|
||||
|
||||
TAILQ_FOREACH (current, &OWINDOWS, owindows) {
|
||||
DLOG("should execute %s, no_startup_id = %d\n", command, no_startup_id);
|
||||
start_application(command, no_startup_id);
|
||||
start_application(
|
||||
command, no_startup_id,
|
||||
current->con->window == NULL ? XCB_NONE : current->con->window->id);
|
||||
}
|
||||
|
||||
ysuccess(true);
|
||||
|
||||
@ -1175,7 +1175,7 @@ int main(int argc, char *argv[]) {
|
||||
struct Autostart *exec = TAILQ_FIRST(&autostarts);
|
||||
|
||||
LOG("auto-starting %s\n", exec->command);
|
||||
start_application(exec->command, exec->no_startup_id);
|
||||
start_application(exec->command, exec->no_startup_id, XCB_NONE);
|
||||
|
||||
FREE(exec->command);
|
||||
TAILQ_REMOVE(&autostarts, exec, autostarts);
|
||||
@ -1188,7 +1188,7 @@ int main(int argc, char *argv[]) {
|
||||
struct Autostart *exec_always = TAILQ_FIRST(&autostarts_always);
|
||||
|
||||
LOG("auto-starting (always!) %s\n", exec_always->command);
|
||||
start_application(exec_always->command, exec_always->no_startup_id);
|
||||
start_application(exec_always->command, exec_always->no_startup_id, XCB_NONE);
|
||||
|
||||
FREE(exec_always->command);
|
||||
TAILQ_REMOVE(&autostarts_always, exec_always, autostarts_always);
|
||||
@ -1204,7 +1204,7 @@ int main(int argc, char *argv[]) {
|
||||
barconfig->verbose ? "-V" : "",
|
||||
barconfig->id, current_socketpath);
|
||||
LOG("Starting bar process: %s\n", command);
|
||||
start_application(command, true);
|
||||
start_application(command, true, XCB_NONE);
|
||||
free(command);
|
||||
}
|
||||
|
||||
|
||||
@ -129,8 +129,11 @@ void startup_sequence_delete(struct Startup_Sequence *sequence) {
|
||||
* The no_startup_id flag determines whether a startup notification context
|
||||
* (and ID) should be created, which is the default and encouraged behavior.
|
||||
*
|
||||
* The window_id, if given, will be provided to the child process via the
|
||||
* I3_WINDOW_ID environment variable.
|
||||
*
|
||||
*/
|
||||
void start_application(const char *command, bool no_startup_id) {
|
||||
void start_application(const char *command, bool no_startup_id, xcb_window_t window_id) {
|
||||
SnLauncherContext *context = NULL;
|
||||
|
||||
if (!no_startup_id) {
|
||||
@ -194,6 +197,13 @@ void start_application(const char *command, bool no_startup_id) {
|
||||
}
|
||||
setenv("I3SOCK", current_socketpath, 1);
|
||||
|
||||
if (window_id != XCB_NONE) {
|
||||
char *window_id_str;
|
||||
sasprintf(&window_id_str, "%d", window_id);
|
||||
setenv("I3_WINDOW_ID", window_id_str, 1);
|
||||
free(window_id_str);
|
||||
}
|
||||
|
||||
execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, NULL);
|
||||
err(EXIT_FAILURE, "execl return"); /* only reached on error */
|
||||
}
|
||||
|
||||
@ -15,10 +15,15 @@
|
||||
# (unless you are already familiar with Perl)
|
||||
#
|
||||
use i3test i3_autostart => 0;
|
||||
use POSIX qw(mkfifo);
|
||||
use File::Temp qw(:POSIX);
|
||||
use X11::XCB qw(PROP_MODE_REPLACE);
|
||||
|
||||
my (@nodes);
|
||||
|
||||
my $exec_tmp = tmpnam();
|
||||
mkfifo($exec_tmp, 0600) or BAIL_OUT "Could not create FIFO in $exec_tmp: $!";
|
||||
|
||||
my $config = <<'EOT';
|
||||
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
|
||||
|
||||
@ -51,6 +56,11 @@ for_window [window_role="i3test"] border none
|
||||
for_window [workspace="trigger"] floating enable, mark triggered
|
||||
EOT
|
||||
|
||||
$config .= <<EOT;
|
||||
# test 13
|
||||
for_window [class="exec"] exec echo "\$I3_WINDOW_ID" > "$exec_tmp"
|
||||
EOT
|
||||
|
||||
# test all window types
|
||||
my %window_types = (
|
||||
'normal' => '_NET_WM_WINDOW_TYPE_NORMAL',
|
||||
@ -390,6 +400,21 @@ is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'triggered' ], "mark set for workspa
|
||||
|
||||
kill_all_windows;
|
||||
|
||||
##############################################################
|
||||
# 13: check that we pass $I3_WINDOW_ID to exec'ed subprocesses
|
||||
##############################################################
|
||||
|
||||
$window = open_window(wm_class => 'exec');
|
||||
|
||||
open my $fh, '<', $exec_tmp
|
||||
or die "couldn't open FIFO $exec_tmp for reading: $!";
|
||||
chomp(my $window_id = do { local $/; <$fh> });
|
||||
is($window_id, $window->id, "got the expected window id from \$I3_WINDOW_ID");
|
||||
|
||||
kill_all_windows;
|
||||
|
||||
unlink($exec_tmp);
|
||||
|
||||
##############################################################
|
||||
|
||||
exit_gracefully($pid);
|
||||
|
||||
Reference in New Issue
Block a user