mirror of
https://github.com/yusufipk/dikte.git
synced 2026-09-11 19:06:11 +00:00
Stop the indicator from making the window behind it flinch
Hiding the indicator unmapped its window, so KWin tore that window down and built a new one for the next dictation. On a tiled desktop the compositor repainted whatever sat underneath as it went, and the terminal behind visibly flinched every time a transcript landed. Measured with a KWin script: five show-and-hide rounds raised five windowAdded and five windowRemoved events, where there is now one of each for the life of the process. So the window stays mapped and paints nothing while idle. That has to be a real repaint rather than zero opacity: with the animation timer stopped nothing else damages the surface, and the stale frame sat on the screen until something unrelated, moving the mouse, made the compositor redraw it. The timer was also left running after the indicator went away, ticking thirty times a second over a window nobody could see. It stops now, and the finished message lingers for two seconds rather than one.
This commit is contained in:
+26
-5
@@ -35,6 +35,7 @@ class Overlay(QWidget):
|
|||||||
self.levels = [0.0] * BARS
|
self.levels = [0.0] * BARS
|
||||||
self.seconds = 0.0
|
self.seconds = 0.0
|
||||||
self._phase = 0.0
|
self._phase = 0.0
|
||||||
|
self._concealed = True
|
||||||
|
|
||||||
self.setWindowFlags(
|
self.setWindowFlags(
|
||||||
Qt.WindowType.FramelessWindowHint
|
Qt.WindowType.FramelessWindowHint
|
||||||
@@ -55,7 +56,7 @@ class Overlay(QWidget):
|
|||||||
|
|
||||||
self._hide_timer = QTimer(self)
|
self._hide_timer = QTimer(self)
|
||||||
self._hide_timer.setSingleShot(True)
|
self._hide_timer.setSingleShot(True)
|
||||||
self._hide_timer.timeout.connect(self.hide)
|
self._hide_timer.timeout.connect(self._conceal)
|
||||||
|
|
||||||
# ---- public API --------------------------------------------------
|
# ---- public API --------------------------------------------------
|
||||||
|
|
||||||
@@ -73,7 +74,7 @@ class Overlay(QWidget):
|
|||||||
self._hide_timer.stop()
|
self._hide_timer.stop()
|
||||||
self._appear()
|
self._appear()
|
||||||
|
|
||||||
def show_done(self, message="", msec=1100):
|
def show_done(self, message="", msec=2000):
|
||||||
self.state = "done"
|
self.state = "done"
|
||||||
self.message = message
|
self.message = message
|
||||||
self._appear()
|
self._appear()
|
||||||
@@ -93,9 +94,8 @@ class Overlay(QWidget):
|
|||||||
self._hide_timer.start(msec)
|
self._hide_timer.start(msec)
|
||||||
|
|
||||||
def dismiss(self):
|
def dismiss(self):
|
||||||
self._anim.stop()
|
|
||||||
self._hide_timer.stop()
|
self._hide_timer.stop()
|
||||||
self.hide()
|
self._conceal()
|
||||||
|
|
||||||
def push_level(self, level):
|
def push_level(self, level):
|
||||||
self.levels = self.levels[1:] + [level]
|
self.levels = self.levels[1:] + [level]
|
||||||
@@ -110,10 +110,28 @@ class Overlay(QWidget):
|
|||||||
self._reposition()
|
self._reposition()
|
||||||
if not self.isVisible():
|
if not self.isVisible():
|
||||||
self.show()
|
self.show()
|
||||||
self.raise_()
|
if self._concealed:
|
||||||
|
self.raise_()
|
||||||
|
self._concealed = False
|
||||||
if not self._anim.isActive():
|
if not self._anim.isActive():
|
||||||
self._anim.start()
|
self._anim.start()
|
||||||
|
|
||||||
|
def _conceal(self):
|
||||||
|
"""Empty the window out instead of unmapping it.
|
||||||
|
|
||||||
|
Unmapping tears the window down and the next dictation builds a new one,
|
||||||
|
which makes the compositor repaint whatever sits underneath: on a tiled
|
||||||
|
desktop the terminal behind visibly flinches every time the indicator
|
||||||
|
goes away. So the window stays mapped and simply paints nothing. It has
|
||||||
|
to be a real repaint, not just zero opacity: with the animation stopped
|
||||||
|
nothing else damages the surface, and the stale frame would sit on the
|
||||||
|
screen until some other event made the compositor redraw it.
|
||||||
|
"""
|
||||||
|
self._anim.stop()
|
||||||
|
self.state = "hidden"
|
||||||
|
self._concealed = True
|
||||||
|
self.repaint()
|
||||||
|
|
||||||
def _resize_to_content(self):
|
def _resize_to_content(self):
|
||||||
if self.state == "recording":
|
if self.state == "recording":
|
||||||
width = MIN_WIDTH
|
width = MIN_WIDTH
|
||||||
@@ -147,6 +165,9 @@ class Overlay(QWidget):
|
|||||||
# ---- painting --------------------------------------------------
|
# ---- painting --------------------------------------------------
|
||||||
|
|
||||||
def paintEvent(self, _event):
|
def paintEvent(self, _event):
|
||||||
|
if self.state == "hidden":
|
||||||
|
return # translucent window, nothing drawn means nothing shown
|
||||||
|
|
||||||
painter = QPainter(self)
|
painter = QPainter(self)
|
||||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
||||||
rect = QRectF(0.5, 0.5, self.width() - 1, self.height() - 1)
|
rect = QRectF(0.5, 0.5, self.width() - 1, self.height() - 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user