Skip to content

Commit 71b5db5

Browse files
committed
Do not store the popup state in the Popup but only a weak pointer
Reason: Because wayland or the event loop could destroy the popup and therefore it is anymore available
1 parent 1a7b9fd commit 71b5db5

2 files changed

Lines changed: 56 additions & 35 deletions

File tree

winit-wayland/src/event_loop/mod.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -484,17 +484,11 @@ impl EventLoop {
484484
})
485485
.is_some()
486486
{
487-
println!("Windows to close found: {windows_to_close:?}");
488487
for w in windows_to_close.into_iter().rev() {
489488
self.with_state(|state| {
490-
if state.windows.get_mut().get_mut(&w).is_none() {
491-
println!("Window id not found: {w:?}");
492-
}
493489
let parent =
494490
state.windows.get_mut().get_mut(&w).unwrap().lock().unwrap().parent();
495491

496-
println!("Closing window: {w:?}, Parent: {parent:?}");
497-
498492
parent
499493
.and_then(|p| state.windows.get_mut().get_mut(&p))
500494
.map(|p| p.lock().unwrap().remove_child(&w));

winit-wayland/src/popup.rs

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use core::sync::atomic::Ordering;
22
use std::sync::atomic::AtomicBool;
3-
use std::sync::{Arc, Mutex};
3+
use std::sync::{Arc, Mutex, Weak};
44

55
use dpi::{LogicalPosition, PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size};
66
use rwh_06::RawWindowHandle;
@@ -35,7 +35,10 @@ pub struct Popup {
3535
popup: SctkPopup,
3636

3737
/// The state of the popup.
38-
popup_state: Arc<Mutex<WindowState>>,
38+
/// The only single truth of the state is stored
39+
/// in the event loop state, because if the server decides to destroy the popup
40+
/// we cannot use it anymore
41+
popup_state: Weak<Mutex<WindowState>>,
3942

4043
/// Window id.
4144
window_id: WindowId,
@@ -201,7 +204,7 @@ impl Popup {
201204

202205
Ok(Self {
203206
popup,
204-
popup_state,
207+
popup_state: Arc::downgrade(&popup_state),
205208
window_id,
206209
display: event_loop_window_target.handle.connection.display().clone(),
207210
handles: Handles {
@@ -241,11 +244,13 @@ impl CoreWindow for Popup {
241244

242245
#[inline]
243246
fn title(&self) -> String {
244-
self.popup_state.lock().unwrap().title().to_owned()
247+
let Some(s) = self.popup_state.upgrade() else { return String::new() };
248+
s.lock().unwrap().title().to_owned()
245249
}
246250

247251
fn pre_present_notify(&self) {
248-
self.popup_state.lock().unwrap().request_frame_callback();
252+
let Some(s) = self.popup_state.upgrade() else { return };
253+
s.lock().unwrap().request_frame_callback();
249254
}
250255

251256
fn reset_dead_keys(&self) {
@@ -262,7 +267,8 @@ impl CoreWindow for Popup {
262267
}
263268

264269
fn set_outer_position(&self, position: Position) {
265-
let state = self.popup_state.lock().unwrap();
270+
let Some(s) = self.popup_state.upgrade() else { return };
271+
let state = s.lock().unwrap();
266272
if let WindowType::Popup { popup, positioner, .. } = &state.window {
267273
let position = position.to_logical(state.scale_factor());
268274
positioner.set_offset(position.x, position.y);
@@ -271,20 +277,23 @@ impl CoreWindow for Popup {
271277
}
272278

273279
fn surface_size(&self) -> PhysicalSize<u32> {
274-
let popup_state = self.popup_state.lock().unwrap();
280+
let Some(s) = self.popup_state.upgrade() else { return PhysicalSize::default() };
281+
let popup_state = s.lock().unwrap();
275282
let scale_factor = popup_state.scale_factor();
276283
super::logical_to_physical_rounded(popup_state.surface_size(), scale_factor)
277284
}
278285

279286
fn request_surface_size(&self, size: Size) -> Option<PhysicalSize<u32>> {
280-
let mut popup_state = self.popup_state.lock().unwrap();
287+
let Some(s) = self.popup_state.upgrade() else { return None };
288+
let mut popup_state = s.lock().unwrap();
281289
popup_state.request_surface_size(size);
282290
self.request_redraw();
283291
Some(size.to_physical(popup_state.scale_factor()))
284292
}
285293

286294
fn outer_size(&self) -> PhysicalSize<u32> {
287-
let popup_state = self.popup_state.lock().unwrap();
295+
let Some(s) = self.popup_state.upgrade() else { return PhysicalSize::default() };
296+
let popup_state = s.lock().unwrap();
288297
let scale_factor = popup_state.scale_factor();
289298
super::logical_to_physical_rounded(popup_state.outer_size(), scale_factor)
290299
}
@@ -296,7 +305,8 @@ impl CoreWindow for Popup {
296305
fn set_min_surface_size(&self, min_size: Option<Size>) {
297306
let scale_factor = self.scale_factor();
298307
let min_size = min_size.map(|size| size.to_logical(scale_factor));
299-
self.popup_state.lock().unwrap().set_min_surface_size(min_size);
308+
let Some(s) = self.popup_state.upgrade() else { return };
309+
s.lock().unwrap().set_min_surface_size(min_size);
300310
// NOTE: Requires commit to be applied.
301311
self.request_redraw();
302312
}
@@ -306,33 +316,38 @@ impl CoreWindow for Popup {
306316
fn set_max_surface_size(&self, max_size: Option<Size>) {
307317
let scale_factor = self.scale_factor();
308318
let max_size = max_size.map(|size| size.to_logical(scale_factor));
309-
self.popup_state.lock().unwrap().set_max_surface_size(max_size);
319+
let Some(s) = self.popup_state.upgrade() else { return };
320+
s.lock().unwrap().set_max_surface_size(max_size);
310321
// NOTE: Requires commit to be applied.
311322
self.request_redraw();
312323
}
313324

314325
fn surface_resize_increments(&self) -> Option<PhysicalSize<u32>> {
315-
let popup_state = self.popup_state.lock().unwrap();
326+
let Some(s) = self.popup_state.upgrade() else { return None };
327+
let popup_state = s.lock().unwrap();
316328
let scale_factor = popup_state.scale_factor();
317329
popup_state
318330
.resize_increments()
319331
.map(|size| super::logical_to_physical_rounded(size, scale_factor))
320332
}
321333

322334
fn set_surface_resize_increments(&self, increments: Option<Size>) {
323-
let mut popup_state = self.popup_state.lock().unwrap();
335+
let Some(s) = self.popup_state.upgrade() else { return };
336+
let mut popup_state = s.lock().unwrap();
324337
let scale_factor = popup_state.scale_factor();
325338
let increments = increments.map(|size| size.to_logical(scale_factor));
326339
popup_state.set_resize_increments(increments);
327340
}
328341

329342
fn set_title(&self, title: &str) {
330-
self.popup_state.lock().unwrap().set_title(title.to_owned());
343+
let Some(s) = self.popup_state.upgrade() else { return };
344+
s.lock().unwrap().set_title(title.to_owned());
331345
}
332346

333347
#[inline]
334348
fn set_transparent(&self, transparent: bool) {
335-
self.popup_state.lock().unwrap().set_transparent(transparent);
349+
let Some(s) = self.popup_state.upgrade() else { return };
350+
s.lock().unwrap().set_transparent(transparent);
336351
}
337352

338353
fn set_visible(&self, _visible: bool) {
@@ -389,12 +404,14 @@ impl CoreWindow for Popup {
389404

390405
#[inline]
391406
fn scale_factor(&self) -> f64 {
392-
self.popup_state.lock().unwrap().scale_factor()
407+
let Some(s) = self.popup_state.upgrade() else { return 1.0 };
408+
s.lock().unwrap().scale_factor()
393409
}
394410

395411
#[inline]
396412
fn set_blur(&self, blur: bool) {
397-
if self.popup_state.lock().unwrap().set_blur(blur) {
413+
let Some(s) = self.popup_state.upgrade() else { return };
414+
if s.lock().unwrap().set_blur(blur) {
398415
self.request_redraw();
399416
}
400417
}
@@ -420,7 +437,8 @@ impl CoreWindow for Popup {
420437

421438
#[inline]
422439
fn request_ime_update(&self, request: ImeRequest) -> Result<(), ImeRequestError> {
423-
let state_changed = self.popup_state.lock().unwrap().request_ime_update(request)?;
440+
let Some(s) = self.popup_state.upgrade() else { return Ok(()) };
441+
let state_changed = s.lock().unwrap().request_ime_update(request)?;
424442

425443
if let Some(allowed) = state_changed {
426444
let event = WindowEvent::Ime(if allowed { Ime::Enabled } else { Ime::Disabled });
@@ -432,13 +450,15 @@ impl CoreWindow for Popup {
432450

433451
#[inline]
434452
fn ime_capabilities(&self) -> Option<ImeCapabilities> {
435-
self.popup_state.lock().unwrap().ime_allowed()
453+
let Some(s) = self.popup_state.upgrade() else { return None };
454+
s.lock().unwrap().ime_allowed()
436455
}
437456

438457
fn focus_window(&self) {}
439458

440459
fn has_focus(&self) -> bool {
441-
self.popup_state.lock().unwrap().has_focus()
460+
let Some(s) = self.popup_state.upgrade() else { return false };
461+
s.lock().unwrap().has_focus()
442462
}
443463

444464
fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
@@ -457,31 +477,33 @@ impl CoreWindow for Popup {
457477
fn set_content_protected(&self, _protected: bool) {}
458478

459479
fn set_cursor(&self, cursor: Cursor) {
460-
let popup_state = &mut self.popup_state.lock().unwrap();
461-
480+
let Some(s) = self.popup_state.upgrade() else { return };
481+
let mut popup_state = s.lock().unwrap();
462482
match cursor {
463483
Cursor::Icon(icon) => popup_state.set_cursor(icon),
464484
Cursor::Custom(cursor) => popup_state.set_custom_cursor(cursor),
465485
}
466486
}
467487

468488
fn set_cursor_position(&self, position: Position) -> Result<(), RequestError> {
469-
let scale_factor = self.scale_factor();
489+
let Some(s) = self.popup_state.upgrade() else { return Err(RequestError::Ignored) };
490+
let scale_factor = s.lock().unwrap().scale_factor();
470491
let position = position.to_logical(scale_factor);
471-
self.popup_state
472-
.lock()
492+
s.lock()
473493
.unwrap()
474494
.set_cursor_position(position)
475495
// Request redraw on success, since the state is double buffered.
476496
.map(|_| self.request_redraw())
477497
}
478498

479499
fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), RequestError> {
480-
self.popup_state.lock().unwrap().set_cursor_grab(mode)
500+
let Some(s) = self.popup_state.upgrade() else { return Err(RequestError::Ignored) };
501+
s.lock().unwrap().set_cursor_grab(mode)
481502
}
482503

483504
fn set_cursor_visible(&self, visible: bool) {
484-
self.popup_state.lock().unwrap().set_cursor_visible(visible);
505+
let Some(s) = self.popup_state.upgrade() else { return };
506+
s.lock().unwrap().set_cursor_visible(visible);
485507
}
486508

487509
fn drag_window(&self) -> Result<(), RequestError> {
@@ -539,9 +561,11 @@ impl Drop for Popup {
539561

540562
impl rwh_06::HasWindowHandle for Popup {
541563
fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
564+
if self.popup_state.upgrade().is_none() {
565+
return Err(rwh_06::HandleError::Unavailable);
566+
};
542567
let raw = rwh_06::WaylandWindowHandle::new({
543-
let state = self.popup_state.lock().unwrap();
544-
let ptr = state.window.wl_surface().id().as_ptr();
568+
let ptr = self.popup.wl_surface().id().as_ptr();
545569
std::ptr::NonNull::new(ptr as *mut _).expect("wl_surface will never be null")
546570
});
547571

@@ -551,6 +575,9 @@ impl rwh_06::HasWindowHandle for Popup {
551575

552576
impl rwh_06::HasDisplayHandle for Popup {
553577
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
578+
if self.popup_state.upgrade().is_none() {
579+
return Err(rwh_06::HandleError::Unavailable);
580+
};
554581
let raw = rwh_06::WaylandDisplayHandle::new({
555582
let ptr = self.display.id().as_ptr();
556583
std::ptr::NonNull::new(ptr as *mut _).expect("wl_proxy should never be null")

0 commit comments

Comments
 (0)