@@ -33,14 +33,26 @@ pub struct PopupData {
3333
3434#[ derive( Debug ) ]
3535struct PopupInner {
36- surface : XdgShellSurface ,
36+ // Will always be Some, only needed to extract surface in destroy before
37+ // drop.
38+ surface : Option < XdgShellSurface > ,
3739 xdg_popup : xdg_popup:: XdgPopup ,
3840 pending_position : ( AtomicI32 , AtomicI32 ) ,
3941 pending_dimensions : ( AtomicI32 , AtomicI32 ) ,
4042 pending_token : AtomicU32 ,
4143 configure_state : AtomicU32 ,
4244}
4345
46+ impl PopupInner {
47+ pub fn surface ( & self ) -> & XdgShellSurface {
48+ & self . surface . as_ref ( ) . unwrap ( )
49+ }
50+
51+ pub fn destroy ( mut self ) -> XdgShellSurface {
52+ self . surface . take ( ) . unwrap ( )
53+ }
54+ }
55+
4456impl Popup {
4557 /// Create a new popup.
4658 ///
@@ -96,7 +108,7 @@ impl Popup {
96108 qh,
97109 PopupData { inner : weak. clone ( ) } ,
98110 ) ;
99- let surface = XdgShellSurface { surface, xdg_surface } ;
111+ let surface = XdgShellSurface { surface : Some ( surface ) , xdg_surface } ;
100112 let xdg_popup = surface. xdg_surface ( ) . get_popup (
101113 parent,
102114 position,
@@ -105,7 +117,7 @@ impl Popup {
105117 ) ;
106118
107119 PopupInner {
108- surface,
120+ surface : Some ( surface ) ,
109121 xdg_popup,
110122 pending_position : ( AtomicI32 :: new ( 0 ) , AtomicI32 :: new ( 0 ) ) ,
111123 pending_dimensions : ( AtomicI32 :: new ( -1 ) , AtomicI32 :: new ( -1 ) ) ,
@@ -122,20 +134,30 @@ impl Popup {
122134 }
123135
124136 pub fn xdg_shell_surface ( & self ) -> & XdgShellSurface {
125- & self . inner . surface
137+ & self . inner . surface ( )
126138 }
127139
128140 pub fn xdg_surface ( & self ) -> & xdg_surface:: XdgSurface {
129- self . inner . surface . xdg_surface ( )
141+ self . inner . surface ( ) . xdg_surface ( )
130142 }
131143
132144 pub fn wl_surface ( & self ) -> & wl_surface:: WlSurface {
133- self . inner . surface . wl_surface ( )
145+ self . inner . surface ( ) . wl_surface ( )
134146 }
135147
136148 pub fn reposition ( & self , position : & xdg_positioner:: XdgPositioner , token : u32 ) {
137149 self . xdg_popup ( ) . reposition ( position, token) ;
138150 }
151+
152+ /// Destroy the popup and extract the underlying surface. Note that reusing
153+ /// the surface for anything other than another xdg popup is a protocol
154+ /// violation, and that the buffer attached to the surface must be cleared
155+ /// before reuse as an xdg surface cannot have a buffer attached to it.
156+ pub fn destroy ( self ) -> Surface {
157+ // Should never panic because the only other Arc reference is a weak
158+ // reference.
159+ Arc :: into_inner ( self . inner ) . unwrap ( ) . destroy ( ) . destroy ( )
160+ }
139161}
140162
141163impl PopupData {
0 commit comments