Gracefully shut down systray
This commit is contained in:
parent
19c4bb3521
commit
387613b2f0
5 changed files with 103 additions and 46 deletions
|
@ -92,45 +92,59 @@ systrayRunner phi dispvar = do
|
|||
initSuccess <- withDisplay dispvar $ flip initSystray atoms
|
||||
|
||||
case initSuccess of
|
||||
Just xembedWindow -> flip evalStateT M.empty $ forever $ do
|
||||
m <- receiveMessage phi
|
||||
case (fromMessage m) of
|
||||
Just event ->
|
||||
handleEvent event phi dispvar xembedWindow
|
||||
_ ->
|
||||
case (fromMessage m) of
|
||||
Just (RenderIcon midParent window x y w h reset) -> do
|
||||
errorWindowRef <- liftIO $ newIORef []
|
||||
|
||||
withDisplay dispvar $ \disp -> do
|
||||
liftIO $ do
|
||||
sync disp False
|
||||
setErrorHandler $ \disp eventptr -> do
|
||||
event <- getErrorEvent eventptr
|
||||
when (ev_error_code event == fromIntegral badWindow) $ do
|
||||
errorWindows <- readIORef errorWindowRef
|
||||
writeIORef errorWindowRef (ev_resourceid event:errorWindows)
|
||||
|
||||
(_, x', y', w', h', _, _) <- liftIO $ getGeometry disp midParent
|
||||
let resize = (fromIntegral x) /= x' || (fromIntegral y) /= y' || (fromIntegral w) /= w' || (fromIntegral h) /= h'
|
||||
Just xembedWindow -> flip evalStateT M.empty $ do
|
||||
sendMessage phi HoldShutdown
|
||||
|
||||
forever $ do
|
||||
m <- receiveMessage phi
|
||||
case (fromMessage m) of
|
||||
Just event ->
|
||||
handleEvent event phi dispvar xembedWindow
|
||||
_ ->
|
||||
case (fromMessage m) of
|
||||
Just (RenderIcon midParent window x y w h reset) -> do
|
||||
errorWindowRef <- liftIO $ newIORef []
|
||||
|
||||
when resize $ liftIO $ do
|
||||
moveResizeWindow disp midParent (fromIntegral x) (fromIntegral y) (fromIntegral w) (fromIntegral h)
|
||||
resizeWindow disp window (fromIntegral w) (fromIntegral h)
|
||||
liftIO $ sync disp False
|
||||
|
||||
when (resize || reset) $ liftIO $ do
|
||||
clearArea disp midParent 0 0 (fromIntegral w) (fromIntegral h) True
|
||||
liftIO $ sync disp False
|
||||
clearArea disp window 0 0 (fromIntegral w) (fromIntegral h) True
|
||||
liftIO $ sync disp False
|
||||
|
||||
liftIO $ xSetErrorHandler
|
||||
|
||||
errorWindows <- liftIO $ readIORef errorWindowRef
|
||||
mapM_ (removeIcon phi disp) errorWindows
|
||||
_ ->
|
||||
return ()
|
||||
withDisplay dispvar $ \disp -> do
|
||||
liftIO $ flip catch (\_ -> return ()) $ do
|
||||
sync disp False
|
||||
setErrorHandler $ \disp eventptr -> do
|
||||
event <- getErrorEvent eventptr
|
||||
when (ev_error_code event == fromIntegral badWindow) $ do
|
||||
errorWindows <- readIORef errorWindowRef
|
||||
writeIORef errorWindowRef (ev_resourceid event:errorWindows)
|
||||
|
||||
(_, x', y', w', h', _, _) <- getGeometry disp midParent
|
||||
let resize = (fromIntegral x) /= x' || (fromIntegral y) /= y' || (fromIntegral w) /= w' || (fromIntegral h) /= h'
|
||||
|
||||
when resize $ do
|
||||
moveResizeWindow disp midParent (fromIntegral x) (fromIntegral y) (fromIntegral w) (fromIntegral h)
|
||||
resizeWindow disp window (fromIntegral w) (fromIntegral h)
|
||||
sync disp False
|
||||
|
||||
clearArea disp midParent 0 0 (fromIntegral w) (fromIntegral h) True
|
||||
sync disp False
|
||||
|
||||
when (resize || reset) $ do
|
||||
clearArea disp window 0 0 (fromIntegral w) (fromIntegral h) True
|
||||
sync disp False
|
||||
|
||||
xSetErrorHandler
|
||||
|
||||
errorWindows <- liftIO $ readIORef errorWindowRef
|
||||
mapM_ (removeIcon phi disp) errorWindows
|
||||
_ ->
|
||||
case (fromMessage m) of
|
||||
Just Shutdown -> do
|
||||
windows <- gets M.keys
|
||||
withDisplay dispvar $ \disp -> do
|
||||
mapM_ (removeIcon phi disp) windows
|
||||
liftIO $ do
|
||||
destroyWindow disp xembedWindow
|
||||
sync disp False
|
||||
sendMessage phi ReleaseShutdown
|
||||
_ ->
|
||||
return ()
|
||||
Nothing ->
|
||||
return ()
|
||||
|
||||
|
@ -265,8 +279,12 @@ removeIcon phi disp window = do
|
|||
sendMessage phi $ RemoveIcon window
|
||||
sendMessage phi Repaint
|
||||
liftIO $ do
|
||||
selectInput disp window $ noEventMask
|
||||
unmapWindow disp window
|
||||
reparentWindow disp window (defaultRootWindow disp) 0 0
|
||||
destroyWindow disp midParent
|
||||
sync disp False
|
||||
modify $ M.delete window
|
||||
_ ->
|
||||
return ()
|
||||
|
||||
|
|
|
@ -530,7 +530,7 @@ premultiply c = a .|. r .|. g .|. b
|
|||
|
||||
|
||||
getWindowScreen :: Xlib.Display -> [Xlib.Rectangle] -> Window -> IO Xlib.Rectangle
|
||||
getWindowScreen disp screens window = do
|
||||
getWindowScreen disp screens window = flip catch (\_ -> return $ head screens) $ do
|
||||
(_, _, _, width, height, _, _) <- Xlib.getGeometry disp window
|
||||
(ret, x, y, _) <- Xlib.translateCoordinates disp window (Xlib.defaultRootWindow disp) 0 0
|
||||
|
||||
|
|
Reference in a new issue