@@ -26,7 +26,7 @@ use std::{
26
26
} ;
27
27
use tracing:: { debug, info} ;
28
28
use x11:: {
29
- xft:: { XftColor , XftColorAllocName , XftDrawCreate , XftDrawStringUtf8 } ,
29
+ xft:: { XftColor , XftColorAllocName , XftDraw , XftDrawCreate , XftDrawDestroy , XftDrawStringUtf8 } ,
30
30
xlib:: {
31
31
CapButt , Complex , CoordModeOrigin , Display , Drawable , False , JoinMiter , LineSolid , Window ,
32
32
XCopyArea , XCreateGC , XCreatePixmap , XDefaultColormap , XDefaultDepth , XDefaultVisual ,
@@ -419,6 +419,8 @@ impl<'a> Context<'a> {
419
419
) -> Result < ( u32 , u32 ) > {
420
420
// SAFETY:
421
421
// - the pointers for self.dpy and s.drawable are known to be non-null
422
+ // - we wrap the returned pointer in DropXftDraw to ensure that we correctly destroy
423
+ // the XftDraw we create here (see below)
422
424
let d = unsafe {
423
425
XftDrawCreate (
424
426
self . dpy ,
@@ -428,6 +430,8 @@ impl<'a> Context<'a> {
428
430
)
429
431
} ;
430
432
433
+ let _drop_draw = DropXftDraw { ptr : d } ;
434
+
431
435
let ( lpad, rpad) = ( padding. 0 as i32 , padding. 1 ) ;
432
436
let ( mut x, y) = ( lpad + self . dx , self . dy ) ;
433
437
let ( mut total_w, mut total_h) = ( x as u32 , 0 ) ;
@@ -461,7 +465,22 @@ impl<'a> Context<'a> {
461
465
total_h = max ( total_h, chunk_h) ;
462
466
}
463
467
464
- Ok ( ( total_w + rpad, total_h) )
468
+ return Ok ( ( total_w + rpad, total_h) ) ;
469
+
470
+ // There are multiple error paths here where we need to make sure that we correctly destroy
471
+ // the XftDraw we created. Rather than complicate the error handling we use a Drop wrapper
472
+ // to ensure that we run XftDrawDestroy when the function returns.
473
+
474
+ struct DropXftDraw {
475
+ ptr : * mut XftDraw ,
476
+ }
477
+
478
+ impl Drop for DropXftDraw {
479
+ fn drop ( & mut self ) {
480
+ // SAFETY: the pointer we have must be non-null
481
+ unsafe { XftDrawDestroy ( self . ptr ) } ;
482
+ }
483
+ }
465
484
}
466
485
467
486
/// Determine the width and height taken up by a given string in pixels.
0 commit comments