Skip to content
This repository has been archived by the owner on Apr 18, 2023. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'vanilla/next' into gaps-next
Browse files Browse the repository at this point in the history
  • Loading branch information
Airblader committed Apr 14, 2020
2 parents b530a07 + 831a52d commit 97c0d40
Show file tree
Hide file tree
Showing 15 changed files with 379 additions and 101 deletions.
16 changes: 12 additions & 4 deletions docs/i3-pod2html
Expand Up @@ -4,8 +4,14 @@
use strict;
use warnings;
use Pod::Simple::HTML;
use Getopt::Long;
use v5.10;

my $stylesurl = '';

GetOptions("stylesurl=s" => \$stylesurl)
or die "parsing flags";

$Pod::Simple::HTML::Tagmap{'Verbatim'} = '<pre><tt>';
$Pod::Simple::HTML::Tagmap{'VerbatimFormatted'} = '<pre><tt>';
$Pod::Simple::HTML::Tagmap{'/Verbatim'} = '</tt></pre>';
Expand All @@ -22,16 +28,17 @@ open(my $out, '>', $ARGV[1]) or die "Couldn’t open $ARGV[1] for writing: $!\n"
my $parser = Pod::Simple::HTML->new();

$parser->index(1);
$parser->html_header_before_title(
<<'EOF'
if ($stylesurl ne '') {
$parser->html_header_before_title(
<<EOF
<!doctype html>
<html lang="en">
<head>
<link rel="icon" type="image/png" href="/favicon.png">
<meta charset="utf-8">
<meta name="generator" content="Pod::Simple::HTML">
<meta name="description" content="i3 Perl documentation">
<link rel="stylesheet" href="https://i3wm.org/css/style.css" type="text/css" />
<link rel="stylesheet" href="$stylesurl/style.css" type="text/css" />
<style type="text/css">
.pod pre {
background: #333;
Expand Down Expand Up @@ -63,7 +70,8 @@ tt {
</style>
<title>
EOF
);
);
}
$parser->html_header_after_title(
<<'EOF'
</title>
Expand Down
10 changes: 10 additions & 0 deletions docs/userguide
Expand Up @@ -1917,8 +1917,18 @@ con_id::
to match only the currently focused window.
floating::
Only matches floating windows. This criterion requires no value.
floating_from::
Like +floating+ but this criterion takes two possible values: "auto"
and "user". With "auto", only windows that were automatically opened as
floating are matched. With "user", only windows that the user made
floating are matched.
tiling::
Only matches tiling windows. This criterion requires no value.
tiling_from::
Like +tiling+ but this criterion takes two possible values: "auto" and
"user". With "auto", only windows that were automatically opened as
tiling are matched. With "user", only windows that the user made tiling
are matched.

The criteria +class+, +instance+, +role+, +title+, +workspace+ and +mark+ are
actually regular expressions (PCRE). See +pcresyntax(3)+ or +perldoc perlre+ for
Expand Down
2 changes: 2 additions & 0 deletions generate-command-parser.pl
Expand Up @@ -218,6 +218,8 @@ sub slurp {
# quote of the literal. We can do strdup(literal + 1); then :).
$token_name =~ s/'$//;
}
# Escape double quotes:
$token_name =~ s,",\\",g;
my $next_state = $token->{next_state};
if ($next_state =~ /^call /) {
($call_identifier) = ($next_state =~ /^call ([0-9]+)$/);
Expand Down
1 change: 1 addition & 0 deletions i3-dmenu-desktop
Expand Up @@ -143,6 +143,7 @@ find(
$desktops{$relative} = $File::Find::name;
},
no_chdir => 1,
follow_fast => 1,
},
@searchdirs
);
Expand Down
4 changes: 4 additions & 0 deletions include/data.h
Expand Up @@ -549,7 +549,11 @@ struct Match {
} dock;
xcb_window_t id;
enum { WM_ANY = 0,
WM_TILING_AUTO,
WM_TILING_USER,
WM_TILING,
WM_FLOATING_AUTO,
WM_FLOATING_USER,
WM_FLOATING } window_mode;
Con *con_id;

Expand Down
38 changes: 28 additions & 10 deletions parser-specs/config.spec
Expand Up @@ -208,16 +208,18 @@ state NO_FOCUS_END:

# Criteria: Used by for_window and assign.
state CRITERIA:
ctype = 'class' -> CRITERION
ctype = 'instance' -> CRITERION
ctype = 'window_role' -> CRITERION
ctype = 'con_id' -> CRITERION
ctype = 'id' -> CRITERION
ctype = 'window_type' -> CRITERION
ctype = 'con_mark' -> CRITERION
ctype = 'title' -> CRITERION
ctype = 'urgent' -> CRITERION
ctype = 'workspace' -> CRITERION
ctype = 'class' -> CRITERION
ctype = 'instance' -> CRITERION
ctype = 'window_role' -> CRITERION
ctype = 'con_id' -> CRITERION
ctype = 'id' -> CRITERION
ctype = 'window_type' -> CRITERION
ctype = 'con_mark' -> CRITERION
ctype = 'title' -> CRITERION
ctype = 'urgent' -> CRITERION
ctype = 'workspace' -> CRITERION
ctype = 'floating_from' -> CRITERION_FROM
ctype = 'tiling_from' -> CRITERION_FROM
ctype = 'tiling', 'floating'
-> call cfg_criteria_add($ctype, NULL); CRITERIA
']'
Expand All @@ -226,6 +228,22 @@ state CRITERIA:
state CRITERION:
'=' -> CRITERION_STR

state CRITERION_FROM:
'=' -> CRITERION_FROM_STR_START

state CRITERION_FROM_STR_START:
'"' -> CRITERION_FROM_STR
kind = 'auto', 'user'
-> call cfg_criteria_add($ctype, $kind); CRITERIA

state CRITERION_FROM_STR:
kind = 'auto', 'user'
-> CRITERION_FROM_STR_END

state CRITERION_FROM_STR_END:
'"'
-> call cfg_criteria_add($ctype, $kind); CRITERIA

state CRITERION_STR:
cvalue = word
-> call cfg_criteria_add($ctype, $cvalue); CRITERIA
Expand Down
24 changes: 23 additions & 1 deletion src/handlers.c
Expand Up @@ -842,6 +842,7 @@ static void handle_client_message(xcb_client_message_event_t *event) {
DLOG("The window was requested to be visible on all workspaces, making it sticky and floating.\n");

floating_enable(con, false);
con->floating = FLOATING_AUTO_ON;

con->sticky = true;
ewmh_update_sticky(con->window->id, true);
Expand Down Expand Up @@ -1156,6 +1157,25 @@ static bool handle_strut_partial_change(Con *con, xcb_get_property_reply_t *prop
return true;
}

/*
* Handles the _I3_FLOATING_WINDOW property to properly run assignments for
* floating window changes.
*
* This is needed to correctly run the assignments after changes in floating
* windows which are triggered by user commands (floating enable | disable). In
* that case, we can't call run_assignments because it will modify the parser
* state when it needs to parse the user-specified action, breaking the parser
* state for the original command.
*
*/
static bool handle_i3_floating(Con *con, xcb_get_property_reply_t *prop) {
DLOG("floating change for con %p\n", con);

remanage_window(con);

return true;
}

/* Returns false if the event could not be processed (e.g. the window could not
* be found), true otherwise */
typedef bool (*cb_property_handler_t)(Con *con, xcb_get_property_reply_t *property);
Expand All @@ -1177,6 +1197,7 @@ static struct property_handler_t property_handlers[] = {
{0, 128, handle_class_change},
{0, UINT_MAX, handle_strut_partial_change},
{0, UINT_MAX, handle_window_type},
{0, UINT_MAX, handle_i3_floating},
{0, 5 * sizeof(uint64_t), handle_motif_hints_change}};
#define NUM_HANDLERS (sizeof(property_handlers) / sizeof(struct property_handler_t))

Expand All @@ -1198,7 +1219,8 @@ void property_handlers_init(void) {
property_handlers[7].atom = XCB_ATOM_WM_CLASS;
property_handlers[8].atom = A__NET_WM_STRUT_PARTIAL;
property_handlers[9].atom = A__NET_WM_WINDOW_TYPE;
property_handlers[10].atom = A__MOTIF_WM_HINTS;
property_handlers[10].atom = A_I3_FLOATING_WINDOW;
property_handlers[11].atom = A__MOTIF_WM_HINTS;
}

static void property_notify(uint8_t state, xcb_window_t window, xcb_atom_t atom) {
Expand Down
13 changes: 13 additions & 0 deletions src/load_layout.c
Expand Up @@ -171,6 +171,19 @@ static int json_end_map(void *ctx) {
con_attach(json_node, json_node->parent, true);
LOG("Creating window\n");
x_con_init(json_node);

/* Fix erroneous JSON input regarding floating containers to avoid
* crashing, see #3901. */
const int old_floating_mode = json_node->floating;
if (old_floating_mode >= FLOATING_AUTO_ON && json_node->parent->type != CT_FLOATING_CON) {
LOG("Fixing floating node without CT_FLOATING_CON parent\n");

/* Force floating_enable to work */
json_node->floating = FLOATING_AUTO_OFF;
floating_enable(json_node, false);
json_node->floating = old_floating_mode;
}

json_node = json_node->parent;
incomplete--;
DLOG("incomplete = %d\n", incomplete);
Expand Down
1 change: 1 addition & 0 deletions src/manage.c
Expand Up @@ -538,6 +538,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
bool automatic_border = (motif_border_style == BS_NORMAL);

floating_enable(nc, automatic_border);
nc->floating = FLOATING_AUTO_ON;
}

/* explicitly set the border width to the default */
Expand Down
70 changes: 63 additions & 7 deletions src/match.c
Expand Up @@ -215,15 +215,43 @@ bool match_matches_window(Match *match, i3Window *window) {
}

if (match->window_mode != WM_ANY) {
if ((con = con_by_window_id(window->id)) == NULL)
if ((con = con_by_window_id(window->id)) == NULL) {
return false;
}

const bool floating = (con_inside_floating(con) != NULL);

if ((match->window_mode == WM_TILING && floating) ||
(match->window_mode == WM_FLOATING && !floating)) {
LOG("window_mode does not match\n");
return false;
switch (match->window_mode) {
case WM_TILING_AUTO:
if (con->floating != FLOATING_AUTO_OFF) {
return false;
}
break;
case WM_TILING_USER:
if (con->floating != FLOATING_USER_OFF) {
return false;
}
break;
case WM_TILING:
if (con_inside_floating(con) != NULL) {
return false;
}
break;
case WM_FLOATING_AUTO:
if (con->floating != FLOATING_AUTO_ON) {
return false;
}
break;
case WM_FLOATING_USER:
if (con->floating != FLOATING_USER_ON) {
return false;
}
break;
case WM_FLOATING:
if (con_inside_floating(con) == NULL) {
return false;
}
break;
case WM_ANY:
assert(false);
}

LOG("window_mode matches\n");
Expand Down Expand Up @@ -367,10 +395,38 @@ void match_parse_property(Match *match, const char *ctype, const char *cvalue) {
return;
}

if (strcmp(ctype, "tiling_from") == 0 &&
cvalue != NULL &&
strcmp(cvalue, "auto") == 0) {
match->window_mode = WM_TILING_AUTO;
return;
}

if (strcmp(ctype, "tiling_from") == 0 &&
cvalue != NULL &&
strcmp(cvalue, "user") == 0) {
match->window_mode = WM_TILING_USER;
return;
}

if (strcmp(ctype, "floating") == 0) {
match->window_mode = WM_FLOATING;
return;
}

if (strcmp(ctype, "floating_from") == 0 &&
cvalue != NULL &&
strcmp(cvalue, "auto") == 0) {
match->window_mode = WM_FLOATING_AUTO;
return;
}

if (strcmp(ctype, "floating_from") == 0 &&
cvalue != NULL &&
strcmp(cvalue, "user") == 0) {
match->window_mode = WM_FLOATING_USER;
return;
}

ELOG("Unknown criterion: %s\n", ctype);
}

0 comments on commit 97c0d40

Please sign in to comment.