3838from ..utils .math import calculate_line , calculate_distance
3939from ..utils .monitor import MonitorData
4040from ..utils .system import SUPPORTS_TRAY , set_autostart , remove_autostart , split_autostart
41+ from ..utils .system import UserResizeAppListener
4142from ..utils .update import is_latest_version , background_update
4243
4344if TYPE_CHECKING :
@@ -193,6 +194,7 @@ def __init__(self, component: GUI) -> None:
193194 self .component = component
194195 self .config = GlobalConfig ()
195196
197+ # Set initial states
196198 self .pause_redraw = 0
197199 self .pause_colour_change = False
198200 self ._pixel_redraw_queue : list [tuple [tuple [int , int ] | None , tuple [int , int ] | None , tuple [int , int ] | None ]] = []
@@ -220,6 +222,10 @@ def __init__(self, component: GUI) -> None:
220222 self ._network_speed = NetworkSpeedStats ()
221223 self .state = ipc .TrackingState .Paused
222224
225+ # Setup threads
226+ self ._resize_listener = UserResizeAppListener ()
227+ self ._resize_listener .start ()
228+
223229 # Setup UI
224230 self .ui = layout .Ui_MainWindow ()
225231 self .ui .setupUi (self )
@@ -853,7 +859,7 @@ def resolutions(self, resolutions: dict[tuple[int, int], tuple[int, bool]]) -> N
853859 def resolution_toggled (self , value : bool ) -> None :
854860 """Toggle rendering of a particular resolution in a profile."""
855861 checkbox = cast (QtWidgets .QCheckBox , self .sender ())
856- sanitised_profile_name , profile_name = self ._get_profile_data ()
862+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
857863 if sanitised_profile_name is None or profile_name is None :
858864 return
859865 width , height = map (int , checkbox .text ().split ('x' ))
@@ -875,7 +881,7 @@ def multi_monitor_change(self) -> None:
875881 """Change the multiple monitor option."""
876882 if not self .ui .opts_monitor .isChecked ():
877883 return
878- sanitised_profile_name , profile_name = self ._get_profile_data ()
884+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
879885 if sanitised_profile_name is None :
880886 return
881887 self .component .send_data (ipc .ToggleProfileMultiMonitor (sanitised_profile_name , self .ui .multi_monitor .isChecked ()))
@@ -885,7 +891,7 @@ def multi_monitor_override_toggle(self, checked: bool) -> None:
885891 """Enable or disable the multi monitor override."""
886892 if not self .ui .opts_monitor .isEnabled ():
887893 return
888- sanitised_profile_name , profile_name = self ._get_profile_data ()
894+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
889895 if sanitised_profile_name is None :
890896 return
891897 self .component .send_data (ipc .ToggleProfileMultiMonitor (sanitised_profile_name , self .ui .multi_monitor .isChecked () if checked else None ))
@@ -1030,7 +1036,7 @@ def manual_save_profile(self) -> None:
10301036 return
10311037 self .save_profile_request_sent = True
10321038
1033- sanitised_profile_name , profile_name = self ._get_profile_data ()
1039+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
10341040 if sanitised_profile_name is not None :
10351041 self .component .send_data (ipc .Save (sanitised_profile_name ))
10361042
@@ -1042,7 +1048,7 @@ def toggle_autosave(self, state: QtCore.Qt.CheckState) -> None:
10421048 @QtCore .Slot (int )
10431049 def profile_changed (self , idx : int ) -> None :
10441050 """Change the profile and trigger a redraw."""
1045- sanitised_profile_name , profile_name = self ._get_profile_data (idx )
1051+ sanitised_profile_name , profile_name = self ._selected_profile_data (idx )
10461052
10471053 if sanitised_profile_name is not None and not self ._redrawing_profiles :
10481054 self .request_profile_data (sanitised_profile_name )
@@ -1051,7 +1057,7 @@ def profile_changed(self, idx: int) -> None:
10511057 self .set_profile_modified_text ()
10521058
10531059 def request_profile_data (self , sanitised_profile_name : str ) -> None :
1054- """Request loading profile data."""
1060+ """Request loading profile data from the background process ."""
10551061 self .component .send_data (ipc .ProfileDataRequest (sanitised_profile_name ,
10561062 self ._profile_names [sanitised_profile_name ]))
10571063
@@ -1069,8 +1075,11 @@ def request_profile_data(self, sanitised_profile_name: str) -> None:
10691075 self ._is_loading_profile += 1
10701076 self .start_rendering_timer ()
10711077
1072- def _get_profile_data (self , idx : int | None = None ) -> tuple [str , str ] | tuple [None , None ]:
1073- """Get the selected profile name from the combobox."""
1078+ def _selected_profile_data (self , idx : int | None = None ) -> tuple [str , str ] | tuple [None , None ]:
1079+ """Get the selected profile name from the combobox.
1080+
1081+ Returns the sanitised profile name and actual name.
1082+ """
10741083 if idx is None :
10751084 sanitised_profile_name = self .ui .current_profile .currentData ()
10761085 else :
@@ -1309,7 +1318,7 @@ def _request_thumbnail(self) -> bool:
13091318
13101319 width = self .ui .thumbnail .width ()
13111320 height = self .ui .thumbnail .height ()
1312- sanitised_profile_name , profile_name = self ._get_profile_data ()
1321+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
13131322 if sanitised_profile_name is None :
13141323 return False
13151324
@@ -1346,7 +1355,7 @@ def _request_thumbnail(self) -> bool:
13461355 return True
13471356
13481357 def get_render_layer_data (self , file_path : str | None = None ) -> Iterator [ipc .RenderLayer ]:
1349- sanitised_profile_name , profile_name = self ._get_profile_data ()
1358+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
13501359 if sanitised_profile_name is None :
13511360 return
13521361
@@ -1473,7 +1482,7 @@ def request_render(self) -> None:
14731482 case _:
14741483 name = 'Data'
14751484
1476- sanitised_profile_name , profile_name = self ._get_profile_data ()
1485+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
14771486 if sanitised_profile_name is None or profile_name is None :
14781487 return
14791488 profile_safe = re .sub (r'[^\w_.)( -]' , '' , profile_name )
@@ -1686,11 +1695,11 @@ def _process_message(self, message: ipc.Message) -> None:
16861695 im .save (message .request .file_path )
16871696 os .startfile (message .request .file_path )
16881697
1689- case ipc .MouseHeld () if self .is_live and self .mouse_tracking_enabled :
1698+ case ipc .MouseHeld () if self .is_live and self .mouse_tracking_enabled and not self . app_resizing :
16901699 self .mouse_held_count += 1
16911700
16921701 case ipc .MouseMove () if self .is_live and self .mouse_tracking_enabled :
1693- if self .render_type == ipc .RenderType .MouseMovement :
1702+ if self .render_type == ipc .RenderType .MouseMovement and not self . app_resizing :
16941703 self .draw_pixmap_line (message .position , self .cursor_data .position )
16951704 self .update_track_data (self .cursor_data , message .position )
16961705 self .ui .stat_distance .setText (format_distance (self .cursor_data .distance ))
@@ -2273,11 +2282,18 @@ def update_track_data(self, data: MapData, position: tuple[int, int]) -> None:
22732282 @property
22742283 def is_live (self ) -> bool :
22752284 """Determine if the visible data is live."""
2276- sanitised_profile_name , profile_name = self ._get_profile_data ()
2285+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
22772286 if sanitised_profile_name is None :
22782287 return False
22792288 return sanitised_profile_name == sanitise_profile_name (self .current_profile .name )
22802289
2290+ @property
2291+ def app_resizing (self ) -> bool :
2292+ """Determine if the focused application is being resized."""
2293+ if self .current_profile .name == DEFAULT_PROFILE_NAME :
2294+ return False
2295+ return self ._resize_listener .triggered
2296+
22812297 @property
22822298 def mouse_tracking_enabled (self ) -> bool :
22832299 """Determine if mouse tracking is enabled."""
@@ -2361,7 +2377,7 @@ def update_thumbnail_size(self) -> None:
23612377
23622378 def delete_mouse (self ) -> None :
23632379 """Request deletion of mouse data for the current profile."""
2364- sanitised_profile_name , profile_name = self ._get_profile_data ()
2380+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
23652381 if sanitised_profile_name is None or profile_name is None :
23662382 return None
23672383
@@ -2385,7 +2401,7 @@ def delete_mouse(self) -> None:
23852401
23862402 def delete_keyboard (self ) -> None :
23872403 """Request deletion of keyboard data for the current profile."""
2388- sanitised_profile_name , profile_name = self ._get_profile_data ()
2404+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
23892405 if sanitised_profile_name is None or profile_name is None :
23902406 return None
23912407
@@ -2408,7 +2424,7 @@ def delete_keyboard(self) -> None:
24082424
24092425 def delete_gamepad (self ) -> None :
24102426 """Request deletion of gamepad data for the current profile."""
2411- sanitised_profile_name , profile_name = self ._get_profile_data ()
2427+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
24122428 if sanitised_profile_name is None or profile_name is None :
24132429 return None
24142430
@@ -2432,7 +2448,7 @@ def delete_gamepad(self) -> None:
24322448
24332449 def delete_network (self ) -> None :
24342450 """Request deletion of network data for the current profile."""
2435- sanitised_profile_name , profile_name = self ._get_profile_data ()
2451+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
24362452 if sanitised_profile_name is None or profile_name is None :
24372453 return None
24382454
@@ -2455,7 +2471,7 @@ def delete_network(self) -> None:
24552471
24562472 def delete_profile (self ) -> None :
24572473 """Delete the selected profile."""
2458- sanitised_profile_name , profile_name = self ._get_profile_data ()
2474+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
24592475 if sanitised_profile_name is None or profile_name is None :
24602476 return None
24612477
@@ -2484,7 +2500,7 @@ def delete_profile(self) -> None:
24842500 def toggle_profile_mouse_tracking (self , state : QtCore .Qt .CheckState ) -> None :
24852501 if not self .ui .track_mouse .isEnabled ():
24862502 return
2487- sanitised_profile_name , profile_name = self ._get_profile_data ()
2503+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
24882504 if sanitised_profile_name is None :
24892505 return
24902506
@@ -2495,7 +2511,7 @@ def toggle_profile_mouse_tracking(self, state: QtCore.Qt.CheckState) -> None:
24952511 def toggle_profile_keyboard_tracking (self , state : QtCore .Qt .CheckState ) -> None :
24962512 if not self .ui .track_keyboard .isEnabled ():
24972513 return
2498- sanitised_profile_name , profile_name = self ._get_profile_data ()
2514+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
24992515 if sanitised_profile_name is None :
25002516 return
25012517
@@ -2506,7 +2522,7 @@ def toggle_profile_keyboard_tracking(self, state: QtCore.Qt.CheckState) -> None:
25062522 def toggle_profile_gamepad_tracking (self , state : QtCore .Qt .CheckState ) -> None :
25072523 if not self .ui .track_gamepad .isEnabled ():
25082524 return
2509- sanitised_profile_name , profile_name = self ._get_profile_data ()
2525+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
25102526 if sanitised_profile_name is None :
25112527 return
25122528
@@ -2517,7 +2533,7 @@ def toggle_profile_gamepad_tracking(self, state: QtCore.Qt.CheckState) -> None:
25172533 def toggle_profile_network_tracking (self , state : QtCore .Qt .CheckState ) -> None :
25182534 if not self .ui .track_network .isEnabled ():
25192535 return
2520- sanitised_profile_name , profile_name = self ._get_profile_data ()
2536+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
25212537 if sanitised_profile_name is None :
25222538 return
25232539
@@ -2572,7 +2588,7 @@ def mark_profiles_unsaved(self, *profile_names: str) -> None:
25722588
25732589 def set_profile_modified_text (self ) -> None :
25742590 """Set the text if the profile has been modified."""
2575- sanitised_profile_name , profile_name = self ._get_profile_data ()
2591+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
25762592 if sanitised_profile_name is not None and sanitised_profile_name in self ._unsaved_profiles :
25772593 self .ui .profile_modified .setText ('Yes' )
25782594 self .ui .profile_save .setEnabled (self .state != ipc .TrackingState .Stopped )
@@ -2788,7 +2804,7 @@ def export_mouse_stats(self) -> None:
27882804 dialog .setNameFilters (['CSV Files (*.csv)"' ])
27892805 dialog .setDefaultSuffix ('csv' )
27902806
2791- sanitised_profile_name , profile_name = self ._get_profile_data ()
2807+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
27922808 if sanitised_profile_name is None or profile_name is None :
27932809 return
27942810 profile_safe = re .sub (r'[^\w_.)( -]' , '' , profile_name )
@@ -2806,7 +2822,7 @@ def export_keyboard_stats(self) -> None:
28062822 dialog .setNameFilters (['CSV Files (*.csv)"' ])
28072823 dialog .setDefaultSuffix ('csv' )
28082824
2809- sanitised_profile_name , profile_name = self ._get_profile_data ()
2825+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
28102826 if sanitised_profile_name is None or profile_name is None :
28112827 return
28122828 profile_safe = re .sub (r'[^\w_.)( -]' , '' , profile_name )
@@ -2824,7 +2840,7 @@ def export_gamepad_stats(self) -> None:
28242840 dialog .setNameFilters (['CSV Files (*.csv)"' ])
28252841 dialog .setDefaultSuffix ('csv' )
28262842
2827- sanitised_profile_name , profile_name = self ._get_profile_data ()
2843+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
28282844 if sanitised_profile_name is None or profile_name is None :
28292845 return
28302846 profile_safe = re .sub (r'[^\w_.)( -]' , '' , profile_name )
@@ -2842,7 +2858,7 @@ def export_network_stats(self) -> None:
28422858 dialog .setNameFilters (['CSV Files (*.csv)"' ])
28432859 dialog .setDefaultSuffix ('csv' )
28442860
2845- sanitised_profile_name , profile_name = self ._get_profile_data ()
2861+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
28462862 if sanitised_profile_name is None or profile_name is None :
28472863 return
28482864 profile_safe = re .sub (r'[^\w_.)( -]' , '' , profile_name )
@@ -2860,7 +2876,7 @@ def export_daily_stats(self) -> None:
28602876 dialog .setNameFilters (['CSV Files (*.csv)"' ])
28612877 dialog .setDefaultSuffix ('csv' )
28622878
2863- sanitised_profile_name , profile_name = self ._get_profile_data ()
2879+ sanitised_profile_name , profile_name = self ._selected_profile_data ()
28642880 if sanitised_profile_name is None or profile_name is None :
28652881 return
28662882 profile_safe = re .sub (r'[^\w_.)( -]' , '' , profile_name )
0 commit comments