11import sys
22from PySide6 .QtWidgets import QApplication , QWidget
3- from PySide6 .QtGui import QCursor
4- from PySide6 .QtCore import QTimer , QEvent , Qt
3+ from PySide6 .QtGui import QCursor , QGuiApplication
4+ from PySide6 .QtCore import QTimer , QEvent , Qt , QPoint , QRect
55import qframelesswindow
66import time
77
8+ IS_WAYLAND = (QGuiApplication .platformName ().lower () == "wayland" )
9+
810BOUNCE_FACTOR = 0.9
911GRAVITY = 9.8
1012FRICTION = 1
@@ -53,9 +55,24 @@ def __init__(self):
5355 self .posX = center_x
5456 self .posY = center_y
5557
58+ self .setMouseTracking (True ) # chatgpt said i should add these two so ig i will hopefully it works
59+ self .setAttribute (Qt .WidgetAttribute .WA_NoMousePropagation , True )
60+
5661 # start the spawning anim!
5762 self .spawn_animation ()
5863
64+ def current_screen (self ):
65+ # Prefer the screen under the window center; fall back to windowHandle/screen
66+ center = self .frameGeometry ().center ()
67+ scr = QGuiApplication .screenAt (center )
68+ if scr is None and self .windowHandle ():
69+ scr = self .windowHandle ().screen ()
70+ return scr or QGuiApplication .primaryScreen ()
71+
72+ def current_bounds (self ) -> QRect :
73+ # Use availableGeometry (avoids panels)
74+ return self .current_screen ().availableGeometry ()
75+
5976 def eventFilter (self , obj , event ):
6077 if event .type () == QEvent .Type .MouseButtonPress :
6178 self .onMouseDown (event )
@@ -66,7 +83,14 @@ def eventFilter(self, obj, event):
6683 return False
6784
6885 def onMouseDown (self , event ):
69- self .grabMouse ()
86+ if IS_WAYLAND and self .windowHandle (): # wayland says no >:(
87+ # Hands window moving to the compositor; no need for our own dragging while pressed
88+ self .windowHandle ().startSystemMove ()
89+ # Optionally short-circuit your own dragging path while the button is held
90+ return
91+ else :
92+ self .grabMouse ()
93+
7094 self .velX = 0
7195 self .velY = 0
7296
@@ -80,7 +104,9 @@ def onMouseDown(self, event):
80104 self .mouseDown = True
81105
82106 def onMouseUp (self , event ):
83- self .releaseMouse ()
107+ if not IS_WAYLAND : # same thing as onmousedown
108+ self .releaseMouse ()
109+
84110 distancesX = []
85111 distancesY = []
86112
@@ -130,32 +156,38 @@ def spawn_animation(self, i=1):
130156 self .last_time = current_time
131157 QTimer .singleShot (16 , lambda : self .spawn_animation (i + int (250 * delta_time )))
132158
133- def check_window_collision (self ): # TODO: i just copy pasted from the other script, so it no way works
134- if not self .mouseDown :
135- width = self .screen_width - self .width ()
136- height = self .screen_height - self .height ()
137-
138- if self .posX < 0 :
139- distance = (self .posX - 0 ) / POP_FACTOR
140- self .velX = (- self .velX * BOUNCE_FACTOR ) + distance
141- self .posX = 0
142- elif self .posX > width :
143- distance = (self .posX - width ) / POP_FACTOR
144- self .velX = (- self .velX * BOUNCE_FACTOR ) + distance
145- self .posX = width
146-
147- if self .posY > height :
148- distance = (self .posY - height ) / POP_FACTOR
149- self .velY = (- self .velY * BOUNCE_FACTOR ) + distance
150- self .posY = height
151- if abs (self .velY ) < 0.1 :
152- self .velY = 0
153- elif self .posY < 38 :
154- distance = (self .posY - 38 ) / POP_FACTOR
155- self .velY = (- self .velY * BOUNCE_FACTOR ) + distance
156- self .posY = 38
157- if abs (self .velY ) < 0.1 :
158- self .velY = 0
159+ def check_window_collision (self ):
160+ if self .mouseDown :
161+ return
162+ g = self .current_bounds ()
163+ # limit box for top-left of the window
164+ max_x = g .right () - self .width () + 1
165+ max_y = g .bottom () - self .height () + 1
166+ min_x = g .left ()
167+ min_y = g .top ()
168+
169+ if self .posX < min_x :
170+ distance = (self .posX - min_x ) / POP_FACTOR
171+ self .velX = (- self .velX * BOUNCE_FACTOR ) + distance
172+ self .posX = min_x
173+ elif self .posX > max_x :
174+ distance = (self .posX - max_x ) / POP_FACTOR
175+ self .velX = (- self .velX * BOUNCE_FACTOR ) + distance
176+ self .posX = max_x
177+
178+ if self .posY < min_y :
179+ distance = (self .posY - min_y ) / POP_FACTOR
180+ self .velY = (- self .velY * BOUNCE_FACTOR ) + distance
181+ self .posY = min_y
182+ if abs (self .velY ) < 0.1 :
183+ self .velY = 0
184+ elif self .posY > max_y :
185+ distance = (self .posY - max_y ) / POP_FACTOR
186+ self .velY = (- self .velY * BOUNCE_FACTOR ) + distance
187+ self .posY = max_y
188+ if abs (self .velY ) < 0.1 :
189+ self .velY = 0
190+
159191
160192 def update_physics (self ):
161193 if self .mouseDown :
0 commit comments