Open Bug 1833195 Opened 2 years ago Updated 1 month ago

Size of restored window always increases after maximizing and restarting Firefox

Categories

(Core :: Widget: Gtk, defect)

Firefox 113
defect

Tracking

()

UNCONFIRMED

People

(Reporter: bugseforuns, Unassigned)

References

(Blocks 2 open bugs)

Details

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/113.0

Steps to reproduce:

Steps to reproduce:

  1. make sure your Firefox runs natively on Wayland (I can't reproduce when Firefox runs on Xwayland)
  2. open Firefox
  3. restore Firefox and resize it using any GUI element as reference (in my screen recording I used the icons on desktop as reference)
  4. maximize Firefox
  5. restart Firefox
  6. restore Firefox
  7. repeat the steps 4-6 a few times

Please watch the attached video showing the bug.

Actual results:

The size of the restored Firefox window increases every time you repeat
the steps 4-6. At some point, the restored Firefox window will not even fit to the screen anymore.

Expected results:

The size of the restored Firefox window should not increase after the provided steps.

The Bugbug bot thinks this bug should belong to the 'Core::Widget: Gtk' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → Widget: Gtk
Product: Firefox → Core
See Also: → 1833187

Do you still see it? I think Emilio did a fix for it some time ago.
Thanks.

Flags: needinfo?(bugseforuns)

The bug persists with Firefox 117 on Arch Linux running the Wayland session of KDE Plasma 5.27.7.

Flags: needinfo?(bugseforuns)

I'm still seeing this on Firefox 141.

It happens for every new window that opens maximized, even without restarting Firefox. The restored window size is 90 pixels wider and taller than it should be, eventually pushing the window controls off screen.

Do you happen to have the "Titlebar" checkbox enabled in customize mode?

Flags: needinfo?(bugseforuns)

"Title Bar" is off. With it on, the window size is correct.

I enabled logging and performed the following steps:

  1. Set the window size to 1000x1000
  2. Maximized it
  3. Opened a new window (Ctrl+N)
  4. Restored the new window (it's now 1090x1090)

It appears 45 pixel margins gets added on a second time somewhere, going from 1090 (with margins) to 1180. The log output is from after clicking restore.

nsWindow::SetSizeMode 0
    set normal
configure event 0,0 -> 1090 x 1090 direct mGdkWindow scale 1 (scaled size 1090 x 1090)
RecomputeBounds(0)
bounds: (x=0, y=0, w=2560, h=1396) -> (x=0, y=0, w=1090, h=1090) ((x=0, y=0, w=1090, h=1090) unconstrained)
margin: (t=0, r=0, b=0, l=0) -> (t=0, r=0, b=0, l=0)
nsWindow::DispatchResized() size [1090, 1090]
GtkCompositorWidget::NotifyClientSizeChanged() to 1090 x 1090
nsWindow::OnWindowStateEvent for 7f777da04260 changed 0x15404 new_window_state 0x15480
 Normal
 Tiled: 0
RecomputeBounds(0)
bounds: (x=0, y=0, w=1090, h=1090) -> (x=0, y=0, w=1090, h=1090) ((x=0, y=0, w=1090, h=1090) unconstrained)
margin: (t=0, r=0, b=0, l=0) -> (t=0, r=0, b=0, l=0)
nsWindow::OnWindowStateEvent for 7f7790cfdfc0 changed 0x15404 new_window_state 0x15480
nsWindow::SetHasMappedToplevel(1)
 quick return because IS_MOZ_CONTAINER(aWidget) is true
moz_container_wayland_size_allocate [7f777449b300] 45,45 -> 1000 x 1000
nsWindow::OnContainerSizeAllocate 45,45 -> 1000 x 1000
moz_container_wayland_size_allocate [7f777449b300] 45,45 -> 1090 x 1090
nsWindow::OnContainerSizeAllocate 45,45 -> 1090 x 1090
nsWindow::OnExposeEvent GdkWindow [7f7768dd8a60] XID [0x0]
MaybeRecomputeBounds 1
RecomputeBounds(1)
bounds: (x=0, y=0, w=1090, h=1090) -> (x=0, y=0, w=1180, h=1180) ((x=0, y=0, w=1180, h=1180) unconstrained)
margin: (t=0, r=0, b=0, l=0) -> (t=45, r=45, b=45, l=45)
nsWindow::CheckForRollup() aAlwaysRollup 1
nsWindow::DispatchResized() size [1180, 1180]
GtkCompositorWidget::NotifyClientSizeChanged() to 1090 x 1090
nsWindow::RequestRepaint()
redirect painting to OMTC rendering...
configure event 0,0 -> 1180 x 1180 direct mGdkWindow scale 1 (scaled size 1180 x 1180)

After some experimenting, I found removing this "bit evil" block of code in nsWindow::OnWindowStateEvent partially helps (from bug 1449166).

  if (!mIsShown) {
    aEvent->changed_mask = static_cast<GdkWindowState>(
        aEvent->changed_mask & ~GDK_WINDOW_STATE_MAXIMIZED);
  } else if (aEvent->changed_mask & GDK_WINDOW_STATE_WITHDRAWN &&
             aEvent->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) {
    aEvent->changed_mask = static_cast<GdkWindowState>(
        aEvent->changed_mask | GDK_WINDOW_STATE_MAXIMIZED);
  }

The initial window created at startup still unmaximizes to the wrong size (enlarged by the CSD border/shadow size), but additional new windows unmaximize correctly. I don't know why the behaviour different.

(In reply to Emilio Cobos Álvarez (:emilio) from comment #5)

Do you happen to have the "Titlebar" checkbox enabled in customize mode?

I keep "Title bar" unchecked. I'm unable to reproduce with Firefox 142 if "Title bar" is checked.

Flags: needinfo?(bugseforuns)
Severity: -- → S3

I managed to get correct unmaximized sizes everywhere, but it doesn't feel like the best solution.

In nsWindow::OnWindowStateEvent, skip over the above change_mask stuff only for Wayland. It's still needed for X11 to prevent the window shrinking.

In nsWindow::SetSizeMode, just before maximizing, show and resize the window (Wayland and CSD only I guess).

  if (!mIsShown && !GdkIsX11Display() && ToplevelUsesCSD()) {
    Show(true);
    GdkRectangle size = DevicePixelsToGdkSizeRoundUp(mBounds.Size());
    gtk_window_resize(GTK_WINDOW(mShell), size.width , size.height);
  }
  gtk_window_maximize(GTK_WINDOW(mShell));

146 broke my previous "fix" but it's simpler now. In SetSizeMode, don't show the window, just resize:

gtk_window_resize(GTK_WINDOW(mShell), mClientArea.width, mClientArea.height);

OnWindowStateEvent is the same as before.

(In reply to davesm110 from comment #11)

146 broke my previous "fix" but it's simpler now. In SetSizeMode, don't show the window, just resize:

gtk_window_resize(GTK_WINDOW(mShell), mClientArea.width, mClientArea.height);

OnWindowStateEvent is the same as before.

gtk_window_resize() takes window size with CSD decoration size - so I'd expect you'll get smaller window (except for popups which have zero margin).

(In reply to Martin Stránský [:stransky] (ni? me) from comment #12)

(In reply to davesm110 from comment #11)

146 broke my previous "fix" but it's simpler now. In SetSizeMode, don't show the window, just resize:

gtk_window_resize(GTK_WINDOW(mShell), mClientArea.width, mClientArea.height);

OnWindowStateEvent is the same as before.

gtk_window_resize() takes window size with CSD decoration size - so I'd expect you'll get smaller window (except for popups which have zero margin).

Yes, that's what happens on X11.

Normally, windows get reduced by the CSD margin size before maximizing, and expanded again when unmaximizing. On Wayland, windows created in an already-maximized state have no margins, so they don't shrink, but do still get expanded again when unmaximizing.

It seems calling gtk_window_resize first allows the margins to be calculated, but there's probably a better fix.

You need to log in before you can comment on or make changes to this bug.