diff --git a/i3/2746e0319b03a8a5a02b57a69b1fb47e0a9c22f1.patch b/i3/2746e0319b03a8a5a02b57a69b1fb47e0a9c22f1.patch new file mode 100644 index 0000000..3bc16bc --- /dev/null +++ b/i3/2746e0319b03a8a5a02b57a69b1fb47e0a9c22f1.patch @@ -0,0 +1,25 @@ +From 2746e0319b03a8a5a02b57a69b1fb47e0a9c22f1 Mon Sep 17 00:00:00 2001 +From: Michael Stapelberg +Date: Wed, 6 Nov 2024 19:17:37 +0100 +Subject: [PATCH] i3bar: work around weird clang compiler behavior + +clang used to not warn (= error, with -Werror) about this line. Oh well. +--- + i3bar/src/xcb.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c +index 4211123d44..f975826abf 100644 +--- a/i3bar/src/xcb.c ++++ b/i3bar/src/xcb.c +@@ -1515,7 +1515,9 @@ static void send_tray_clientmessage(void) { + static void init_tray(void) { + DLOG("Initializing system tray functionality\n"); + /* request the tray manager atom for the X11 display we are running on */ +- char atomname[strlen("_NET_SYSTEM_TRAY_S") + 11]; ++ /* The following line cannot use strlen as that makes compilation fail with ++ * some versions of clang (-Wgnu-folding-constant): */ ++ char atomname[18 /* strlen("_NET_SYSTEM_TRAY_S") */ + 11]; + snprintf(atomname, strlen("_NET_SYSTEM_TRAY_S") + 11, "_NET_SYSTEM_TRAY_S%d", screen); + xcb_intern_atom_cookie_t tray_cookie; + if (tray_reply == NULL) { diff --git a/i3/853b0d9161a5f99c8491751590229a449e4076b6.patch b/i3/853b0d9161a5f99c8491751590229a449e4076b6.patch new file mode 100644 index 0000000..13d83cf --- /dev/null +++ b/i3/853b0d9161a5f99c8491751590229a449e4076b6.patch @@ -0,0 +1,30 @@ +From 853b0d9161a5f99c8491751590229a449e4076b6 Mon Sep 17 00:00:00 2001 +From: Michael Stapelberg +Date: Mon, 30 Dec 2024 08:29:29 +0100 +Subject: [PATCH] i3bar: fix clang compilation error by using const size_t + (#6349) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Thanks to Shouη (@Shoun2137 on GitHub) for the suggestion. +--- + i3bar/src/xcb.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c +index f975826abf..146db172e3 100644 +--- a/i3bar/src/xcb.c ++++ b/i3bar/src/xcb.c +@@ -1517,8 +1517,9 @@ static void init_tray(void) { + /* request the tray manager atom for the X11 display we are running on */ + /* The following line cannot use strlen as that makes compilation fail with + * some versions of clang (-Wgnu-folding-constant): */ +- char atomname[18 /* strlen("_NET_SYSTEM_TRAY_S") */ + 11]; +- snprintf(atomname, strlen("_NET_SYSTEM_TRAY_S") + 11, "_NET_SYSTEM_TRAY_S%d", screen); ++ const size_t systray_len = strlen("_NET_SYSTEM_TRAY_S") + 11; ++ char atomname[systray_len]; ++ snprintf(atomname, systray_len, "_NET_SYSTEM_TRAY_S%d", screen); + xcb_intern_atom_cookie_t tray_cookie; + if (tray_reply == NULL) { + tray_cookie = xcb_intern_atom(xcb_connection, 0, strlen(atomname), atomname); diff --git a/i3/cfa4cf16bea809c7c715a86c428757e577c85254.patch b/i3/cfa4cf16bea809c7c715a86c428757e577c85254.patch new file mode 100644 index 0000000..3c03c47 --- /dev/null +++ b/i3/cfa4cf16bea809c7c715a86c428757e577c85254.patch @@ -0,0 +1,311 @@ +From cfa4cf16bea809c7c715a86c428757e577c85254 Mon Sep 17 00:00:00 2001 +From: Sergey Vlasov +Date: Tue, 22 Apr 2025 00:26:17 +0300 +Subject: [PATCH] Set `_NET_FRAME_EXTENTS` according to the actual decoration + size (#5944) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Inspired by #5384, but instead of just using the border width, this PR +reports the actual frame extents for the window, which may also include +the title bar (for floating windows and tiled windows in plain split +containers, but not for tiled windows in stacked/tabbed containers). + +The existing `con_border_style_rect()` function should already handle +all configuration options which can affect the decoration sizes (if it +does not, that would also show up in other places); its result just +needs to be converted into the format used by the `_NET_FRAME_EXTENTS` +property. + +This PR fixes #4292 probably in the best way possible (the reported +`_NET_FRAME_EXTENTS` values should always match the actual sizes of +window frame elements which are actually drawn into the X11 frame window +into which the client window is reparented). The only really problematic +case is with the stacked/tabbed containers, for which the title bar is +actually drawn into a completely separate window, therefore the title +bar size cannot be reported in `_NET_FRAME_EXTENTS` (actually I tried to +calculate the size of those decorations and add it to the top decoration +size, but that did not change the behavior of `picom`). + +
Large screenshots here (3840×2160) + +Example of configuration with `hide_edge_borders smart` — a single +window does not have borders, so only the top frame size is non-zero: + +![2024-03-09_21-41](https://github.com/i3/i3/assets/616082/d2f41206-89f8-465f-ba25-1f51075ba680) + +but multiple windows have borders: + +![2024-03-09_21-44](https://github.com/i3/i3/assets/616082/db7469e6-50eb-4687-83fd-88481691b361) + +Changing border width works too (although with `border normal 8` you can +see that the top border overlaps the title text, because on the i3 side +that border does not really exists, and `picom` just draws it over; also +the pixel sizes reported by `xprop` and `xwininfo` are not identical to +what is specified in i3, because I use 168 dpi on this system, therefore +4 px in the i3 config = 7 dpx): + +![2024-03-09_21-48](https://github.com/i3/i3/assets/616082/7f64d217-3218-4d03-ba15-3fe33e6161d1) + +Handling of tabbed containers is less perfect though. Here is a single +tabbed container with `hide_edge_borders smart`, so it does not really +have a border — note that all frame extents are zero, and the titlebar +is rounded separately (although it could easily be excluded from +rounding, that does not really help much): + +![2024-03-09_22-02](https://github.com/i3/i3/assets/616082/c6ea1106-b1d7-43b8-8354-bc6fbf45d87a) + +Once the border actually appears, you may notice that the top part of +the `picom` border actually gets drawn over the top part of the window, +partially obscuring the top line in this terminal (`picom` does not mind +that the top frame size is reported as 0): + +![2024-03-09_22-04](https://github.com/i3/i3/assets/616082/eb80fc5c-fa52-43f4-857e-94dc713221bf) + +Some examples of floating windows (no major problems there): + +![2024-03-09_22-09](https://github.com/i3/i3/assets/616082/3336c1cb-ee48-46ae-ab89-061be46bdb31) + +Options like `hide_edge_borders both` work too when gaps are removed +(although the resulting behavior with `picom` is probably not very +useful — the rounded border gets drawn only if all of the left, bottom +and right borders are present): + +![2024-03-09_22-15](https://github.com/i3/i3/assets/616082/9961db74-7c49-43f0-a90f-e9ab81474038) + +The same with `border pixel 8` (note that windows with only the top +border hidden still get the rounded border treatment by `picom`, but the +border overlaps the top part of the window): + +![2024-03-09_22-21](https://github.com/i3/i3/assets/616082/dd0a0fc6-701d-4e01-ba96-f3eb5131c95b) + +
+ +--------- + +Signed-off-by: Sergey Vlasov +Co-authored-by: Orestis Floros +--- + .../changes/5-set-_NET_FRAME_EXTENTS | 1 + + src/x.c | 18 ++ + testcases/t/323-net-frame-extents.t | 173 ++++++++++++++++++ + 3 files changed, 192 insertions(+) + create mode 100644 release-notes/changes/5-set-_NET_FRAME_EXTENTS + create mode 100644 testcases/t/323-net-frame-extents.t + +diff --git a/release-notes/changes/5-set-_NET_FRAME_EXTENTS b/release-notes/changes/5-set-_NET_FRAME_EXTENTS +new file mode 100644 +index 0000000000..0d40253a75 +--- /dev/null ++++ b/release-notes/changes/5-set-_NET_FRAME_EXTENTS +@@ -0,0 +1 @@ ++Set _NET_FRAME_EXTENTS according to the actual decoration size +diff --git a/src/x.c b/src/x.c +index e28c3d03b2..499c6e2330 100644 +--- a/src/x.c ++++ b/src/x.c +@@ -1126,6 +1126,24 @@ void x_push_node(Con *con) { + + set_shape_state(con, need_reshape); + ++ /* Set _NET_FRAME_EXTENTS according to the actual decoration size. */ ++ if (con != NULL && con->window != NULL) { ++ Rect bsr = con_border_style_rect(con); ++ Rect r = { ++ bsr.x, /* left */ ++ 0 - bsr.width - bsr.x, /* right */ ++ bsr.y, /* top */ ++ 0 - bsr.height - bsr.y /* bottom */ ++ }; ++ xcb_change_property( ++ conn, ++ XCB_PROP_MODE_REPLACE, ++ con->window->id, ++ A__NET_FRAME_EXTENTS, ++ XCB_ATOM_CARDINAL, 32, 4, ++ &r); ++ } ++ + /* Map if map state changed, also ensure that the child window + * is changed if we are mapped and there is a new, unmapped child window. + * Unmaps are handled in x_push_node_unmaps(). */ +diff --git a/testcases/t/323-net-frame-extents.t b/testcases/t/323-net-frame-extents.t +new file mode 100644 +index 0000000000..7098f21d5f +--- /dev/null ++++ b/testcases/t/323-net-frame-extents.t +@@ -0,0 +1,173 @@ ++#!perl ++# vim:ts=4:sw=4:expandtab ++# ++# Please read the following documents before working on tests: ++# • https://build.i3wm.org/docs/testsuite.html ++# (or docs/testsuite) ++# ++# • https://build.i3wm.org/docs/lib-i3test.html ++# (alternatively: perldoc ./testcases/lib/i3test.pm) ++# ++# • https://build.i3wm.org/docs/ipc.html ++# (or docs/ipc) ++# ++# • https://i3wm.org/downloads/modern_perl_a4.pdf ++# (unless you are already familiar with Perl) ++# ++# Verify _NET_FRAME_EXTENTS is set correctly ++# Ticket: #4292 ++# Bug still in: 4.24-8-g44b67d11 ++use i3test i3_autostart => 0; ++use X11::XCB qw(:all); ++ ++my $pid = launch_with_config('-default'); ++ ++sub net_frame_extents { ++ my ($window) = @_; ++ ++ my $cookie = $x->get_property( ++ 0, ++ $window->{id}, ++ $x->atom(name => '_NET_FRAME_EXTENTS')->id, ++ GET_PROPERTY_TYPE_ANY, ++ 0, ++ 4 ++ ); ++ ++ my $reply = $x->get_property_reply($cookie->{sequence}); ++ my $len = $reply->{length}; ++ return [] if $len == 0; ++ ++ return unpack("L$len", $reply->{value}); ++} ++ ++sub is_net_frame_extents { ++ my ($window, $expect, $msg) = @_; ++ $msg //= ""; ++ $msg = "frame extents $msg"; ++ $msg =~ s/\s+$//; ++ my @extents = net_frame_extents($window); ++ is_deeply(\@extents, $expect, "$msg: got: @extents want: @$expect"); ++} ++ ++subtest 'basic border styles' => sub { ++ my $w = open_window; ++ cmd 'border normal 3'; ++ is_net_frame_extents($w, [3, 3, 18, 3], "normal border with 3px width"); ++ ++ cmd 'border pixel 1'; ++ is_net_frame_extents($w, [1, 1, 1, 1], "pixel border with 1px width"); ++ ++ cmd 'border pixel 5'; ++ is_net_frame_extents($w, [5, 5, 5, 5], "pixel border with 5px width"); ++ ++ open_window; ++ is_net_frame_extents($w, [5, 5, 5, 5], "other window does not affect"); ++ cmd 'kill'; ++ ++ cmd 'border normal 0'; ++ is_net_frame_extents($w, [0, 0, 18, 0], "normal border with 0px width"); ++ ++ cmd 'border none'; ++ is_net_frame_extents($w, [0, 0, 0, 0], "no border"); ++}; ++ ++subtest 'multiple windows in different layouts' => sub { ++ fresh_workspace; ++ ++ my $w1 = open_window; ++ my $w2 = open_window; ++ my $w3 = open_window; ++ ++ cmd 'border normal 2'; ++ is_net_frame_extents($w1, [2, 2, 18, 2], "window 1 in splith layout with normal border"); ++ is_net_frame_extents($w2, [2, 2, 18, 2], "window 2 in splith layout with normal border"); ++ is_net_frame_extents($w3, [2, 2, 18, 2], "window 3 in splith layout with normal border"); ++ ++ cmd 'layout stacking'; ++ is_net_frame_extents($w1, [2, 2, 0, 2], "window 1 in stacking layout"); ++ is_net_frame_extents($w2, [2, 2, 0, 2], "window 2 in stacking layout"); ++ is_net_frame_extents($w3, [2, 2, 0, 2], "window 3 in stacking layout"); ++ ++ cmd 'layout tabbed'; ++ is_net_frame_extents($w1, [2, 2, 0, 2], "window 1 in tabbed layout"); ++ is_net_frame_extents($w2, [2, 2, 0, 2], "window 2 in tabbed layout"); ++ is_net_frame_extents($w3, [2, 2, 0, 2], "window 3 in tabbed layout"); ++ ++ cmd 'layout splitv'; ++ is_net_frame_extents($w1, [2, 2, 18, 2], "window 1 in splitv layout"); ++ is_net_frame_extents($w2, [2, 2, 18, 2], "window 2 in splitv layout"); ++ is_net_frame_extents($w3, [2, 2, 18, 2], "window 3 in splitv layout"); ++}; ++ ++sub launch_with_hide_edge_borders { ++ my ($value) = @_; ++ my $config = < sub { ++ launch_with_hide_edge_borders('none'); ++ my $w = open_window; ++ cmd 'border normal 3'; ++ is_net_frame_extents($w, [3, 3, 18, 3], "window with normal borders (hide_edge_borders none)"); ++ ++ launch_with_hide_edge_borders('vertical'); ++ $w = open_window; ++ cmd 'border normal 3'; ++ is_net_frame_extents($w, [0, 0, 18, 3], "window with hidden vertical borders"); ++ ++ launch_with_hide_edge_borders('horizontal'); ++ $w = open_window; ++ cmd 'border normal 3'; ++ is_net_frame_extents($w, [3, 3, 18, 0], "window with hidden horizontal borders"); ++ cmd 'border pixel 3'; ++ is_net_frame_extents($w, [3, 3, 0, 0], "window with hidden horizontal borders"); ++ ++ launch_with_hide_edge_borders('both'); ++ $w = open_window; ++ cmd 'border normal 3'; ++ is_net_frame_extents($w, [0, 0, 18, 0], "window with all edge borders hidden"); ++ cmd 'border pixel 3'; ++ is_net_frame_extents($w, [0, 0, 0, 0], "window with all edge borders hidden"); ++ ++ launch_with_hide_edge_borders('smart'); ++ $w = open_window; ++ cmd 'border normal 3'; ++ is_net_frame_extents($w, [0, 0, 18, 0], "window with smart borders (single window)"); ++ cmd 'border pixel 3'; ++ is_net_frame_extents($w, [0, 0, 0, 0], "window with smart borders (single window)"); ++ ++ my $w2 = open_window; ++ cmd 'border normal 5'; ++ is_net_frame_extents($w, [3, 3, 3, 3], "first window with smart borders (multiple windows)"); ++ is_net_frame_extents($w2, [5, 5, 18, 5], "second window with smart borders (multiple windows)"); ++ ++ exit_gracefully($pid); ++ launch_with_config('-default'); ++}; ++ ++subtest 'floating windows' => sub { ++ fresh_workspace; ++ my $w = open_window; ++ cmd 'border normal 4'; ++ is_net_frame_extents($w, [4, 4, 18, 4], "tiling window with normal border"); ++ ++ cmd 'floating enable'; ++ is_net_frame_extents($w, [4, 4, 18, 4], "floating window with normal border"); ++ ++ cmd 'border pixel 2'; ++ is_net_frame_extents($w, [2, 2, 2, 2], "floating window with pixel border"); ++ ++ cmd 'border none'; ++ is_net_frame_extents($w, [0, 0, 0, 0], "floating window with no border"); ++}; ++ ++done_testing; diff --git a/i3/i3.SlackBuild b/i3/i3.SlackBuild index 4da111b..1b498bd 100755 --- a/i3/i3.SlackBuild +++ b/i3/i3.SlackBuild @@ -29,7 +29,7 @@ PRGNAM=i3 VERSION=${VERSION:-4.24} -BUILD=${BUILD:-1} +BUILD=${BUILD:-2} TAG=${TAG:-_EXs} if [ -z "$ARCH" ]; then @@ -74,6 +74,10 @@ find -L . \ \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \ -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \+ +patch -p1 --verbose -i ${CWD}/cfa4cf16bea809c7c715a86c428757e577c85254.patch +patch -p1 --verbose -i ${CWD}/2746e0319b03a8a5a02b57a69b1fb47e0a9c22f1.patch +patch -p1 --verbose -i ${CWD}/853b0d9161a5f99c8491751590229a449e4076b6.patch + # Configure, build, and install: export CFLAGS="-g3 $SLKCFLAGS -flto -rdynamic" export CXXFLAGS="-g3 $SLKCFLAGS -flto -rdynamic"