Tk Source Code

View Ticket
Login
2023-09-03
09:00 Ticket [bec431fc] NSWindow drag regions should only be invalidated on the Main Thread status still Open with 3 other changes artifact: 4177b3ad user: chrstphrchvz
07:48 Ticket [bec431fc]: 4 changes artifact: 50c2971c user: razagr
02:12 Ticket [bec431fc]: 3 changes artifact: cbd45a67 user: chrstphrchvz
2023-09-02
23:56 New ticket [bec431fc]. artifact: ace9aed1 user: razagr

Ticket UUID: bec431fc689e7ac73cc0ac9f26e7d7c35c3a1136
Title: NSWindow drag regions should only be invalidated on the Main Thread
Type: Bug Version: 8.6.13
Submitter: razagr Created on: 2023-09-02 23:56:50
Subsystem: 83. Mac OS X Build Assigned To: nobody
Priority: 5 Medium Severity: Severe
Status: Open Last Modified: 2023-09-03 09:00:14
Resolution: None Closed By: nobody
    Closed on:
Description:
When I try to use tkinter in python for filedialog, I get this error:

```
python3.10[3835:102344] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSWindow drag regions should only be invalidated on the Main Thread!'
*** First throw call stack:
(
        0   CoreFoundation                      0x000000018c49719c __exceptionPreprocess + 176
        1   libobjc.A.dylib                     0x000000018bfb64d4 objc_exception_throw + 60
        2   CoreFoundation                      0x000000018c4c03f4 _CFBundleGetValueForInfoKey + 0
        3   AppKit                              0x000000018f65ec14 -[NSWindow(NSWindow_Theme) _postWindowNeedsToResetDragMarginsUnlessPostingDisabled] + 320
        4   AppKit                              0x000000018f64cee8 -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 816
        5   AppKit                              0x000000018f64cbac -[NSWindow initWithContentRect:styleMask:backing:defer:] + 48
        6   Tk                                  0x00000002b91da634 TkMacOSXMakeRealWindowExist + 524
        7   Tk                                  0x00000002b91da2d4 TkWmMapWindow + 60
        8   Tk                                  0x00000002b913f984 TkInstallFrameMenu + 304
        9   Tcl                                 0x00000002b90742cc TclServiceIdle + 72
        10  Tcl                                 0x00000002b9054940 Tcl_DoOneEvent + 120
        11  Tk                                  0x00000002b91cd548 TkpInit + 768
        12  Tk                                  0x00000002b91384ac Tk_Init + 2360
        13  _tkinter.cpython-310-darwin.so      0x00000002b4e0e2c4 Tcl_AppInit + 80
        14  _tkinter.cpython-310-darwin.so      0x00000002b4e0826c Tkapp_New + 592
        15  _tkinter.cpython-310-darwin.so      0x00000002b4e07c1c _tkinter_create + 580
        16  libpython3.10.dylib                 0x0000000100898bec cfunction_vectorcall_FASTCALL + 268
        17  libpython3.10.dylib                 0x0000000100926970 call_function + 452
        18  libpython3.10.dylib                 0x00000001009236f0 _PyEval_EvalFrameDefault + 23436
        19  libpython3.10.dylib                 0x000000010091da58 _PyEval_Vector + 164
        20  libpython3.10.dylib                 0x00000001008526cc _PyObject_FastCallDictTstate + 272
        21  libpython3.10.dylib                 0x0000000100853198 _PyObject_Call_Prepend + 148
        22  libpython3.10.dylib                 0x00000001008bbf90 slot_tp_init + 104
        23  libpython3.10.dylib                 0x00000001008b3204 type_call + 372
        24  libpython3.10.dylib                 0x00000001008528a4 _PyObject_MakeTpCall + 360
        25  libpython3.10.dylib                 0x00000001009269d0 call_function + 548
        26  libpython3.10.dylib                 0x0000000100923768 _PyEval_EvalFrameDefault + 23556
        27  libpython3.10.dylib                 0x000000010091da58 _PyEval_Vector + 164
        28  libpython3.10.dylib                 0x0000000100926970 call_function + 452
        29  libpython3.10.dylib                 0x0000000100923768 _PyEval_EvalFrameDefault + 23556
        30  libpython3.10.dylib                 0x000000010091da58 _PyEval_Vector + 164
        31  libpython3.10.dylib                 0x0000000100926970 call_function + 452
        32  libpython3.10.dylib                 0x00000001009236c8 _PyEval_EvalFrameDefault + 23396
        33  libpython3.10.dylib                 0x000000010091da58 _PyEval_Vector + 164
        34  libpython3.10.dylib                 0x0000000100926970 call_function + 452
        35  libpython3.10.dylib                 0x00000001009236f0 _PyEval_EvalFrameDefault + 23436
        36  libpython3.10.dylib                 0x000000010091da58 _PyEval_Vector + 164
        37  libpython3.10.dylib                 0x00000001009239d4 _PyEval_EvalFrameDefault + 24176
        38  libpython3.10.dylib                 0x000000010091da58 _PyEval_Vector + 164
        39  libpython3.10.dylib                 0x000000010093e7b4 context_run + 288
        40  libpython3.10.dylib                 0x0000000100898cb4 cfunction_vectorcall_FASTCALL_KEYWORDS + 168
        41  libpython3.10.dylib                 0x00000001009239d4 _PyEval_EvalFrameDefault + 24176
        42  libpython3.10.dylib                 0x000000010091da58 _PyEval_Vector + 164
        43  libpython3.10.dylib                 0x0000000100926970 call_function + 452
        44  libpython3.10.dylib                 0x00000001009236c8 _PyEval_EvalFrameDefault + 23396
        45  libpython3.10.dylib                 0x000000010091da58 _PyEval_Vector + 164
        46  libpython3.10.dylib                 0x0000000100926970 call_function + 452
        47  libpython3.10.dylib                 0x00000001009236c8 _PyEval_EvalFrameDefault + 23396
        48  libpython3.10.dylib                 0x000000010091da58 _PyEval_Vector + 164
        49  libpython3.10.dylib                 0x0000000100854ff8 method_vectorcall + 308
        50  libpython3.10.dylib                 0x00000001009c1544 thread_run + 72
        51  libpython3.10.dylib                 0x0000000100973b38 pythread_wrapper + 28
        52  libsystem_pthread.dylib             0x000000018c33ffa8 _pthread_start + 148
        53  libsystem_pthread.dylib             0x000000018c33ada0 thread_start + 8
)
libc++abi: terminating due to uncaught exception of type NSException
```

code first install `pip install gradio`:
```
import gradio as gr
import tkinter as tk
from tkinter import filedialog

def select_directory(selected_folder):
    root = tk.Tk()
    root.withdraw()
    folder_path = filedialog.askdirectory()
    selected_folder.set_value(f"Selected Directory: {folder_path}")


with gr.Blocks(analytics_enabled=False) as ui_component:
    with gr.Row():
        selected_folder = gr.Textbox("", label="Selected Folder", lines=2)
        input_files = gr.Button("Select Directory")
        input_files.click(select_directory, selected_folder)

ui_component.launch()

```


I am using 
```
Python 3.10.11 (main, Sep  2 2023, 18:21:34) [Clang 14.0.3 (clang-1403.0.22.14.1)]
```
User Comments: chrstphrchvz added on 2023-09-03 09:00:14:

Thanks for providing the rest of the example.

Sorry, I am not familiar with gradio (which I confused with GNUradio, something completely different). Glancing at your example, it looks like gradio’s use of threads is abstracted away, so its threads/callbacks could simply be incompatible with certain kinds of Python code, including code which invokes native desktop GUI running outside of the web browser. And maybe trying to use a native desktop GUI dialog is not desirable, if either gradio has a preferred way of instead telling the web browser to show a file dialog, or if the intention is to use files from the user’s device rather than a remote server running gradio.

I increasingly suspect that this is an “XY problem”. What is the file dialog needed for? Based on that answer to that, I would then suggest asking the gradio community what to use instead.


razagr added on 2023-09-03 07:48:21:
added complete example code

chrstphrchvz added on 2023-09-03 02:12:59:

I am just an occasional contributor here; my comment is not authoritative.

Tk for macOS’ native Aqua UI currently must use macOS’ Cocoa/AppKit APIs from the “main thread” only. So it seems this issue is because Tkinter is being invoked from a non-main thread. However, it is not clear to me how exactly threads are being handled in the example provided; the code seems incomplete (where is select_directory() used?), and I am not familiar with how threads are used by the Python modules mentioned.

More enough information seems needed if the goal is to workaround this and still use the Tkinter file dialog. It may also be better discussed with those more familiar with threaded Python and Tkinter than the Tcl/Tk developers are. Maybe the file dialog can instead be shown using a different process, and could even use a different GUI toolkit, such with Zenity (GTK) or KDialog (Qt). (If you use GNURadio-companion, then those other toolkits may already be installed.)