1
1
import logging
2
+ from typing import Optional
2
3
from settings import DEBUG
3
4
from core .widgets .base import BaseWidget
4
5
from core .utils .win32 .windows import WinEvent
21
22
SystemEventListener = None
22
23
logging .warning ("Failed to load Win32 System Event Listener" )
23
24
24
-
25
+ # Missing from win32con
26
+ WS_EX_NOREDIRECTIONBITMAP = 0x20_0000
27
+
25
28
class TaskbarWidget (BaseWidget ):
26
29
validation_schema = VALIDATION_SCHEMA
27
30
update_event = pyqtSignal (int ,WinEvent )
@@ -187,10 +190,8 @@ def _update_label(self, hwnd: int, win_info: dict, event: WinEvent) -> None:
187
190
if self ._animation ['enabled' ]:
188
191
self ._animate_icon (icon_label ,start_width = 0 ,end_width = icon_label .sizeHint ().width ())
189
192
190
- def _get_app_icon (self ,hwnd :int ,title :str ,process :dict ,event :WinEvent )-> None :
193
+ def _get_app_icon (self ,hwnd :int ,title :str ,process :dict ,event :WinEvent )-> Optional [ QPixmap ] :
191
194
try :
192
- if hwnd != win32gui .GetForegroundWindow ():
193
- return
194
195
pid = process ["pid" ]
195
196
196
197
if event != WinEvent .WinEventOutOfContext :
@@ -201,7 +202,7 @@ def _get_app_icon(self, hwnd: int, title:str, process: dict, event: WinEvent) ->
201
202
else :
202
203
icon_img = get_window_icon (hwnd ,self .dpi )
203
204
if icon_img :
204
- icon_img = icon_img .resize ((int (self ._label_icon_size * self .dpi ),int (self ._label_icon_size * self .dpi )),Image .LANCZOS ).convert ("RGBA" )
205
+ icon_img = icon_img .resize ((int (self ._label_icon_size * self .dpi ),int (self ._label_icon_size * self .dpi )),Image .Resampling . LANCZOS ).convert ("RGBA" )
205
206
else :
206
207
# UWP apps I hate it
207
208
if process ["name" ]== "ApplicationFrameHost.exe" :
@@ -211,9 +212,9 @@ def _get_app_icon(self, hwnd: int, title:str, process: dict, event: WinEvent) ->
211
212
return
212
213
else :
213
214
self ._update_retry_count = 0
215
+ if icon_img :
214
216
if not DEBUG :
215
217
self ._icon_cache [(hwnd ,title ,pid )]= icon_img
216
- if icon_img :
217
218
qimage = QImage (icon_img .tobytes (),icon_img .width ,icon_img .height ,QImage .Format .Format_RGBA8888 )
218
219
pixmap = QPixmap .fromImage (qimage )
219
220
else :
@@ -223,22 +224,23 @@ def _get_app_icon(self, hwnd: int, title:str, process: dict, event: WinEvent) ->
223
224
if DEBUG :
224
225
logging .exception (f"Failed to get icons for window with HWND{ hwnd } emitted by event{ event } " )
225
226
226
- def get_visible_windows (self ,hwnd :int ,win_info :dict ,event :WinEvent )-> None :
227
+ def get_visible_windows (self ,_ :int ,win_info :dict ,event :WinEvent )-> list [ tuple [ str , int , Optional [ QPixmap ], WinEvent ]] :
227
228
process = win_info ['process' ]
228
229
def is_window_visible_on_taskbar (hwnd ):
229
- if win32gui .IsWindowVisible (hwnd )and win32gui . GetWindowText ( hwnd ) :
230
+ if win32gui .IsWindowVisible (hwnd ):
230
231
ex_style = win32gui .GetWindowLong (hwnd ,win32con .GWL_EXSTYLE )
231
- if not (ex_style & win32con .WS_EX_TOOLWINDOW ):
232
+ if not (ex_style & win32con .WS_EX_TOOLWINDOW or ex_style == WS_EX_NOREDIRECTIONBITMAP ):
232
233
return True
233
234
return False
234
235
235
236
visible_windows = []
236
237
237
- def enum_windows_proc (hwnd ,lParam ):
238
+ def enum_windows_proc (hwnd ,_ ):
238
239
if is_window_visible_on_taskbar (hwnd ):
239
240
title = win32gui .GetWindowText (hwnd )
240
241
icon = self ._get_app_icon (hwnd ,title ,process ,event )
241
- visible_windows .append ((title ,hwnd ,icon ,process ))
242
+ if title and icon :
243
+ visible_windows .append ((title ,hwnd ,icon ,process ))
242
244
return True
243
245
win32gui .EnumWindows (enum_windows_proc ,None )
244
246
return visible_windows