Package: xfwm4
Version: 4.20.0-1
Severity: normal
Tags: patch upstream
X-Debbugs-Cc: uwe_deb...@arcor.de

Dear Maintainer,

in Firefox a video in a web page can be separated to an undecorated window
called
"Picture-in-Picture" by clicking a button on the right side of the video or in
the URL field.

Expected behaviour:
The Picture-in-Picture window (when entered with the mouse cursor) has a
double-arrow icon in the lower right corner that should toggle the fullscreen
state. Alternatively it should be possible to change this state (and the
stacking state) using the right click context menu.

Observed behaviour:
Nothing happens when the toggle icon is clicked. The relevant fields in the
right click context menu are greyed out. With most other window managers (e.g.
marco) toggling fullscreen mode works fine, so it's not a bug in Firefox.

Investigation of the Problem:
I've found out, that the Picture-in-Picture window has the properties
"transient"
and "WINDOW_UTILITY" (under some circumstances "WINDOW_NORMAL"). Unfortunately
the code of xfwm4 does not allow transient (or modal) windows to become
fullscreen.

Possible Solution:
The attached patch changes this restriction in a way that only modal windows
are
prevented from becoming fullscreen whereas transient windows aren't. In my
tests
this results in the expected behaviour.


-- System Information:
Debian Release: 13.0
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 6.12.35+deb13-amd64 (SMP w/4 CPU threads; PREEMPT)
Locale: LANG=C.UTF-8, LC_CTYPE=C.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages xfwm4 depends on:
ii  libc6                     2.41-9
ii  libcairo2                 1.18.4-1+b1
ii  libepoxy0                 1.5.10-2
ii  libgdk-pixbuf-2.0-0       2.42.12+dfsg-3
ii  libglib2.0-0t64           2.84.3-1
ii  libgtk-3-0t64             3.24.49-3
ii  libpango-1.0-0            1.56.3-1
ii  libpangocairo-1.0-0       1.56.3-1
ii  libstartup-notification0  0.12-8
ii  libwnck-3-0               43.2-1
ii  libx11-6                  2:1.8.12-1
ii  libxcomposite1            1:0.4.6-1
ii  libxdamage1               1:1.1.6-1+b2
ii  libxext6                  2:1.3.4-1+b3
ii  libxfce4ui-2-0            4.20.1-1
ii  libxfce4util7             4.20.1-1
ii  libxfconf-0-3             4.20.0-1
ii  libxfixes3                1:6.0.0-2+b4
ii  libxinerama1              2:1.1.4-3+b4
ii  libxpresent1              1.0.1-1+b2
ii  libxrandr2                2:1.5.4-1+b3
ii  libxrender1               1:0.9.12-1
ii  libxres1                  2:1.2.1-1+b2

Versions of packages xfwm4 recommends:
ii  librsvg2-common  2.60.0+dfsg-1

Versions of packages xfwm4 suggests:
ii  xfce4  4.20

-- no debconf information
Author: Uwe Krüger <uwe_deb...@arcor.de>
Description: Allow fullscreen/above/below for transients (e.g Firefox PIP)

diff -Nur xfwm4-4.20.0.orig/src/client.c xfwm4-4.20.0/src/client.c
--- xfwm4-4.20.0.orig/src/client.c      2024-12-15 10:38:47.000000000 +0100
+++ xfwm4-4.20.0/src/client.c   2025-07-14 13:24:52.724719548 +0200
@@ -3108,7 +3108,9 @@
         }
     }
 
-    if (!clientIsTransientOrModal (c) && (c->type == WINDOW_NORMAL) && 
!FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
+    if (!clientIsModal (c) &&
+        (c->type == WINDOW_NORMAL || c->type == WINDOW_UTILITY) &&
+        !FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
     {
         FLAG_TOGGLE (c->flags, CLIENT_FLAG_FULLSCREEN);
         clientUpdateFullscreenState (c);
@@ -3163,7 +3165,7 @@
     TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
 
     if ((c->type & WINDOW_REGULAR_FOCUSABLE) &&
-        !clientIsValidTransientOrModal (c) &&
+        !clientIsModal (c) &&
         !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
     {
         FLAG_UNSET (c->flags, CLIENT_FLAG_BELOW);
@@ -3178,7 +3180,7 @@
     TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
 
     if ((c->type & WINDOW_REGULAR_FOCUSABLE) &&
-        !clientIsValidTransientOrModal (c) &&
+        !clientIsModal (c) &&
         !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
     {
         FLAG_UNSET (c->flags, CLIENT_FLAG_ABOVE);
diff -Nur xfwm4-4.20.0.orig/src/events.c xfwm4-4.20.0/src/events.c
--- xfwm4-4.20.0.orig/src/events.c      2024-12-15 10:38:47.000000000 +0100
+++ xfwm4-4.20.0/src/events.c   2025-07-14 13:15:14.953509960 +0200
@@ -2551,7 +2551,7 @@
         ops |= MENU_OP_FULLSCREEN;
     }
 
-    if (is_transient || (c->type != WINDOW_NORMAL))
+    if (!(c->type & WINDOW_REGULAR_FOCUSABLE) || (c->type & 
WINDOW_MODAL_DIALOG))
     {
         insensitive |= MENU_OP_FULLSCREEN | MENU_OP_UNFULLSCREEN;
     }
@@ -2569,8 +2569,8 @@
         ops |= MENU_OP_ABOVE | MENU_OP_BELOW;
     }
 
-    if (is_transient ||
-        !(c->type & WINDOW_REGULAR_FOCUSABLE) ||
+    if (!(c->type & WINDOW_REGULAR_FOCUSABLE) ||
+        (c->type & WINDOW_MODAL_DIALOG) ||
         FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
     {
         insensitive |= MENU_OP_NORMAL | MENU_OP_ABOVE | MENU_OP_BELOW;
diff -Nur xfwm4-4.20.0.orig/src/netwm.c xfwm4-4.20.0/src/netwm.c
--- xfwm4-4.20.0.orig/src/netwm.c       2024-12-15 10:38:47.000000000 +0100
+++ xfwm4-4.20.0/src/netwm.c    2025-07-14 13:28:27.352965993 +0200
@@ -214,11 +214,10 @@
             }
             else if (atoms[i] == display_info->atoms[NET_WM_STATE_FULLSCREEN])
             {
-                if (!FLAG_TEST_ALL (c->flags, CLIENT_FLAG_ABOVE | 
CLIENT_FLAG_BELOW))
-                {
-                    TRACE ("fullscreen");
-                    FLAG_SET (c->flags, CLIENT_FLAG_FULLSCREEN);
-                }
+                TRACE ("fullscreen");
+                FLAG_UNSET (c->flags, CLIENT_FLAG_ABOVE);
+                FLAG_UNSET (c->flags, CLIENT_FLAG_BELOW);
+                FLAG_SET (c->flags, CLIENT_FLAG_FULLSCREEN);
             }
             else if (atoms[i] == display_info->atoms[NET_WM_STATE_ABOVE])
             {
@@ -484,7 +483,7 @@
     if ((first  == display_info->atoms[NET_WM_STATE_FULLSCREEN]) ||
         (second == display_info->atoms[NET_WM_STATE_FULLSCREEN]))
     {
-        if (!clientIsValidTransientOrModal (c))
+        if (!clientIsModal (c))
         {
             if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, 
CLIENT_FLAG_FULLSCREEN))
             {

Reply via email to