Skip to content

Commit 77c1ee9

Browse files
authored
Avoid using a destroyed glfw window (#448)
* Avoid using a destroyed glfw window * Improve more
1 parent 7a5f5f0 commit 77c1ee9

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

wgpu/gui/glfw.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def __init__(self, *, size=None, title=None, **kwargs):
142142
# Register callbacks. We may get notified too often, but that's
143143
# ok, they'll result in a single draw.
144144
glfw.set_framebuffer_size_callback(self._window, weakbind(self._on_size_change))
145-
glfw.set_window_close_callback(self._window, weakbind(self._on_close))
145+
glfw.set_window_close_callback(self._window, weakbind(self._check_close))
146146
glfw.set_window_refresh_callback(self._window, weakbind(self._on_window_dirty))
147147
glfw.set_window_focus_callback(self._window, weakbind(self._on_window_dirty))
148148
set_window_content_scale_callback(
@@ -183,10 +183,19 @@ def _on_size_change(self, *args):
183183
self._determine_size()
184184
self._request_draw()
185185

186+
def _check_close(self, *args):
187+
# Follow the close flow that glfw intended.
188+
# This method can be overloaded and the close-flag can be set to False
189+
# using set_window_should_close() if now is not a good time to close.
190+
if self._window is not None and glfw.window_should_close(self._window):
191+
self._on_close()
192+
186193
def _on_close(self, *args):
187194
all_glfw_canvases.discard(self)
188-
glfw.destroy_window(self._window) # not just glfw.hide_window
189-
self._handle_event_and_flush({"event_type": "close"})
195+
if self._window is not None:
196+
glfw.destroy_window(self._window) # not just glfw.hide_window
197+
self._window = None
198+
self._handle_event_and_flush({"event_type": "close"})
190199

191200
def _on_window_dirty(self, *args):
192201
self._request_draw()
@@ -202,6 +211,8 @@ def _mark_ready_for_draw(self):
202211
glfw.post_empty_event() # Awake the event loop, if it's in wait-mode
203212

204213
def _determine_size(self):
214+
if self._window is None:
215+
return
205216
# Because the value of get_window_size is in physical-pixels
206217
# on some systems and in logical-pixels on other, we use the
207218
# framebuffer size and pixel ratio to derive the logical size.
@@ -222,6 +233,8 @@ def _determine_size(self):
222233
self._handle_event_and_flush(ev)
223234

224235
def _set_logical_size(self, new_logical_size):
236+
if self._window is None:
237+
return
225238
# There is unclarity about the window size in "screen pixels".
226239
# It appears that on Windows and X11 its the same as the
227240
# framebuffer size, and on macOS it's logical pixels.
@@ -299,11 +312,12 @@ def _request_draw(self):
299312
call_later(self._get_draw_wait_time(), self._mark_ready_for_draw)
300313

301314
def close(self):
302-
glfw.set_window_should_close(self._window, True)
303-
self._on_close()
315+
if self._window is not None:
316+
glfw.set_window_should_close(self._window, True)
317+
self._check_close()
304318

305319
def is_closed(self):
306-
return glfw.window_should_close(self._window)
320+
return self._window is None
307321

308322
# User events
309323

0 commit comments

Comments
 (0)