Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clicking on a textbox on Linux makes to the entire program freeze #26

Open
JakoDel opened this issue Feb 29, 2024 · 2 comments
Open

Clicking on a textbox on Linux makes to the entire program freeze #26

JakoDel opened this issue Feb 29, 2024 · 2 comments

Comments

@JakoDel
Copy link

JakoDel commented Feb 29, 2024

Well this was the issue I actually wanted to post lol. I'm referring to textboxes like the one that shows up when using the download ROM feature. if you need logs tell me how to get them and I'll share them asap.
for reference, I'm using stock Fedora 39 with GNOME 45.
Thanks!

@JakoDel JakoDel changed the title Trying to click on a textbox on Linux makes to the entire program freeze Clicking on a textbox on Linux makes to the entire program freeze Feb 29, 2024
@ColdWindScholar
Copy link
Owner

ok,This issue has been present since the development of the Linux version of the tool, and we are working to find a solution to it

@MinDeaDBlood
Copy link

Okay, here's the full translation of the last response into English:

Alright, let's break down the identified problems in specific files in more detail and propose more specific solutions.

Specific Problems to Fix (Detailed):

  1. tool.py (Key File):

    • Problem: This file is the core of the GUI, and any long-running operations directly inside its event handlers can cause freezes.
      • Details: tool.py contains the main Tkinter loop that manages the entire interface. If the processing of a click or other event takes too long in this loop, the entire GUI freezes and becomes unresponsive.
    • Mouse Events:
      • Problem: All bindings to events like <Button-1>, <Double-Button-1>, <MouseWheel>, and similar on widgets (e.g., Listbox, Canvas, Label) may cause slowdowns.
      • Why it's a problem: Mouse events can be generated frequently, and if their handlers perform complex or resource-intensive operations, they will block the main GUI thread, leading to a freeze. This is especially critical when using bindings on many widgets.
      • Solution:
        • Minimize the code inside bindings. Only register data or call other async functions.
        • Use the .after method to call functions that need to be executed on the main thread.
        • Check if scroll events are handled correctly, especially how ListBox works with its canvas.
    • LoadAnim:
      • Problem: The class uses threads for animation, but calls GUI functions directly (self.run(), self.stop()).
      • Why it's a problem: The GUI has to be updated only by the main thread.
      • Solution:
        • Replace the call to self.run() with self.master.gif_label.after(30, self.run, ind) and self.stop() with self.master.gif_label.after(30, self.stop()) to execute in the main thread.
        • Avoid starting and canceling animations directly.
    • MagiskPatcher:
      • Problem: The boot.img patching process is run in the main thread (and apk loading).
      • Why it's a problem: These operations can be time-consuming and will block the GUI.
      • Solution:
        • Move the entire patching process to a separate thread using create_thread.
        • Update any GUI elements (such as button text or progress bars) using the .after method.
  2. controls.py:

    • ListBox and ScrollFrame:
      • Problem: The MouseWheel event might cause freezes, especially when scrolling quickly.
      • Why it's a problem: yview_scroll might be called too often, overwhelming the GUI.
      • Solution:
        • Use a timer to reduce scroll calls during rapid mouse wheel usage.
        • Consider using bindings to yscrollcommand instead of MouseWheel.
        • Look at custom scrollbar solutions.
  3. editor.py:

    • p_bind and refs:
      • Problem: Double-click event handling and updating of the file list are done in the main thread.
      • Why it's a problem: Searching files, reading directories, or loading large files can take a lot of time and cause freezes.
      • Solution:
        • Use create_thread to handle these events in separate threads.
        • GUI updates (e.g., self.show.delete(0, END), self.show.insert(...)) must be done via .after.
    • load():
      • Problem: File loading is done in the main thread.
      • Why it's a problem: Loading can be time-consuming, especially with large files.
      • Solution:
        • Move the file loading to a separate thread.
        • Update the self.text widget using .after.
  4. mkc_filedialog.py and AI_engine.py:

    • askopenfilenames, askdirectorys and suggest():
      • Problem: Using self.wait_window() for window lifecycle.
      • Why it's a problem: wait_window() blocks the main GUI thread until the Toplevel is closed.
      • Solution:
        • Replace self.wait_window() with calls to self.destroy() using the .after method.
        • All file system operations should be moved into a separate thread.
  5. utils.py:

    • create_thread:
      • Problem: Though it creates threads, it is not always ideal.
      • Why it's a problem: Calling join isn't thread-safe and blocks the main thread.
      • Solution: Remove join from create_thread and use a more sophisticated way of managing threads.
    • move_center:
      • Problem: Called in the main thread.
      • Why it's a problem: Causes GUI updates that do not need to be in the main thread.
      • Solution:
        • Move the window initialization to .after.
    • File Reading:
      • Problem: File reading operations (simg2img, LogoDumper) block the main thread.
      • Why it's a problem: File operations can be time-consuming.
      • Solution: Move file reading to a separate thread.

Additional Recommendations:

  • Study third-party libraries:

    • Review the documentation for sv_ttk and confirm that you're using the library correctly.
    • If possible, create a minimal example with sv_ttk to check if the problem is in the library.
  • Improve logging: Add more detail to your logging. This will help pinpoint where delays are occurring.

  • Profiling: If the freezes persist, use Python's profiling tools to find "hot spots" in your code where execution takes too long.

  • Asynchrony: For more complex logic consider the usage of asyncio.

Why this is so important:
Tkinter and other GUI frameworks operate in a main loop. Freezes happen when a function or infinite loop inside the mainloop takes too much time. Moving long running tasks into separate threads is the only way to keep the application responsive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants