https://bugs.kde.org/show_bug.cgi?id=528447

            Bug ID: 528447
           Summary: App window is placed on screen and only moves to the
                    memorized spot ~1–2 s later (hide re-maps on unhide,
                    minimize to taskbar: app stays mapped)
    Classification: Plasma
           Product: kwin
      Version First 6.6.6
       Reported In:
          Platform: Ubuntu
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: wayland-generic
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

## STEPS TO REPRODUCE

1. Save the script below as `hide_show_test.py` and run it with `python3`
(needs `python3-pyqt6`).
   It opens a window and logs to `/tmp/hide-show-test.log`.
2. Move the window anywhere on any screen.
3. Close it with the X button — it hides and re-opens 2 s later, four times.
4. Watch where it re-appears; compare the log with `org.kde.KWin /Scripting`
positions if wanted.

## OBSERVED RESULT

The re-opened window is first placed at a position it held earlier in the
session, and only then
moved to the position it was closed at:

```
22:05:52  closed at      457,200  (DP-1)
22:05:55  re-opened  -> 2594,144  (eDP-1)   <- first placement
22:05:56             ->  457,200  (DP-1)    <- then the closed position
22:06:11  re-opened  -> 1955,352 -> 2353,357 -> 1955,352   (same screen, ~400
px detour)
```

Qt's own `geometry()` never matches either position; it reports the top-left of
the output the
window lands on.

## EXPECTED RESULT

The window re-appears at the position it was closed at, without a first
placement elsewhere and
without a visible move.

## SOFTWARE/OS VERSIONS

```
Operating System: Ubuntu 26.04.1 LTS (kernel 7.0)
KDE Plasma Version: 6.6.6
KDE Frameworks Version: 6.24.0
Qt Version: 6.10.2 (KWin reports Qt 6.10.2, XCB 1.17.0)
Graphics Platform: Wayland
```

## ADDITIONAL INFORMATION

Minimal reproducer (only `python3-pyqt6` required; logs to
`/tmp/hide-show-test.log`):

```python
#!/usr/bin/python3
"""Reproducer: a window that hides on close and re-opens itself four times."""
import sys
import time

from PyQt6.QtCore import QSettings, QTimer
from PyQt6.QtWidgets import QApplication, QLabel, QMainWindow

MAX_CYCLES = 4
LOG_PATH = "/tmp/hide-show-test.log"

log = open(LOG_PATH, "w", buffering=1)


def note(text: str) -> None:
    line = f"{time.strftime('%H:%M:%S')} {text}"
    print(line, flush=True)
    log.write(line + "\n")


class Window(QMainWindow):
    def __init__(self) -> None:
        super().__init__()
        self._settings = QSettings("hide-show-test", "geometry")
        self.setWindowTitle("hide/show test")
        self.setCentralWidget(QLabel("move me, then close with X"))
        geometry = self._settings.value("geometry")
        if geometry is not None:
            self.restoreGeometry(geometry)
        else:
            self.resize(700, 500)

    def closeEvent(self, event) -> None:
        # keep the process alive and the window out of the taskbar, as a tray
app does
        self._settings.setValue("geometry", self.saveGeometry())
        self.hide()
        event.ignore()


app = QApplication(sys.argv[:1])
app.setApplicationName("hide-show-test")
app.setQuitOnLastWindowClosed(False)
window = Window()

state = {"cycles": 0, "visible": False, "finished": False}


def reopen() -> None:
    window.show()
    window.raise_()
    window.activateWindow()


def tick() -> None:
    if state["finished"]:
        return
    visible = window.isVisible()
    if state["visible"] and not visible:
        state["cycles"] += 1
        note(f"closed #{state['cycles']}
qt_geometry={window.geometry().getRect()}")
        if state["cycles"] >= MAX_CYCLES:
            state["finished"] = True
            note("done")
            QTimer.singleShot(800, app.quit)
            return
        QTimer.singleShot(2000, reopen)
    elif visible and not state["visible"]:
        note(f"shown qt_geometry={window.geometry().getRect()}")
    state["visible"] = visible


timer = QTimer()
timer.timeout.connect(tick)
timer.start(200)
note(f"log file: {LOG_PATH}")
reopen()
sys.exit(app.exec())
```

Notes:

- The same happens with the window merely hidden and shown again, without a
close event.
- It does **not** happen when the window stays mapped (minimised instead of
hidden), and it does not
  happen with `QT_QPA_PLATFORM=xcb` (XWayland), where the window opens directly
at the restored
  position.
- Not specific to one output or one driver: reproduced with two outputs (eDP-1,
DP-1) and with three
  (eDP-1, DVI-I-1, DVI-I-2 over DisplayLink), and with the window moved only
within one screen.
- Remove the form's `***` boilerplate before submitting.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to