{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} ----------------------------------------------------------------------------- -- | -- Module : XMonad.Layout.DecorationEx.Widgets -- Description : Definitions for decoration widgets (window buttons etc) -- Copyright : 2023 Ilya Portnov -- License : BSD-style (see xmonad/LICENSE) -- -- Maintainer : portnov84@rambler.ru -- Stability : unstable -- Portability : unportable -- -- This module contains data types and utilities to deal with decoration -- widgets. A widget is anything that is displayed on window decoration, -- and, optionally, can react on clicks. Examples of widgets are usual -- window buttons (minimize, maximize, close), window icon and window title. ----------------------------------------------------------------------------- module XMonad.Layout.DecorationEx.Widgets ( -- * Data types StandardCommand (..), TextWidget (..), GenericWidget (..), StandardWidget, -- * Utility functions isWidgetChecked, -- * Presets for standard widgets titleW, toggleStickyW, minimizeW, maximizeW, closeW, dwmpromoteW, moveToNextGroupW,moveToPrevGroupW ) where import XMonad import qualified XMonad.StackSet as W import XMonad.Actions.DwmPromote import qualified XMonad.Actions.CopyWindow as CW import qualified XMonad.Layout.Groups.Examples as Ex import XMonad.Layout.Maximize import XMonad.Actions.Minimize import XMonad.Actions.WindowMenu import XMonad.Layout.DecorationEx.Common import XMonad.Layout.DecorationEx.Engine -- | Standard window commands. -- -- One can extend this list by simply doing -- -- > data MyWindowCommand = -- > Std StandardCommand -- > | SomeFancyCommand -- -- > instance WindowCommand MyWindowCommand where ... -- -- > type MyWidget = GenericWidget MyWindowCommand -- data StandardCommand = FocusWindow -- ^ Focus the window | FocusUp -- ^ Move focus to previous window | FocusDown -- ^ Move focus to following window | MoveToNextGroup -- ^ Move the window to the next group (see "XMonad.Layout.Groups") | MoveToPrevGroup -- ^ Move the window to the previous group | DwmPromote -- ^ Execute @dwmpromote@ (see "XMonad.Actions.DwmPromote") | ToggleSticky -- ^ Make window sticky or unstick it (see "XMonad.Actions.CopyWindow") | ToggleMaximize -- ^ Maximize or restore window (see "XMonad.Layout.Maximize") | Minimize -- ^ Minimize window (see "XMonad.Actions.Minimize") | CloseWindow -- ^ Close the window | GridWindowMenu -- ^ Show window menu via "XMonad.Actions.GridSelect" (see "XMonad.Actions.WindowMenu") deriving (Eq, Show, Read) instance Default StandardCommand where def = FocusWindow instance WindowCommand StandardCommand where executeWindowCommand FocusWindow w = do focus w return False executeWindowCommand FocusUp _ = do windows W.focusUp withFocused maximizeWindowAndFocus return True executeWindowCommand FocusDown _ = do windows W.focusDown withFocused maximizeWindowAndFocus return True executeWindowCommand MoveToNextGroup w = do focus w Ex.moveToGroupDown False return True executeWindowCommand MoveToPrevGroup w = do focus w Ex.moveToGroupUp False return True executeWindowCommand CloseWindow w = do killWindow w return True executeWindowCommand DwmPromote w = do focus w dwmpromote return True executeWindowCommand ToggleSticky w = do focus w copies <- CW.wsContainingCopies if null copies then windows CW.copyToAll else CW.killAllOtherCopies return True executeWindowCommand ToggleMaximize w = do sendMessage $ maximizeRestore w focus w return True executeWindowCommand Minimize w = do minimizeWindow w return True executeWindowCommand GridWindowMenu w = do focus w windowMenu return True isCommandChecked FocusWindow _ = return False isCommandChecked DwmPromote w = do withWindowSet $ \ws -> return $ Just w == master ws where master ws = case W.integrate' $ W.stack $ W.workspace $ W.current ws of [] -> Nothing (x:_) -> Just x isCommandChecked ToggleSticky w = do ws <- gets windowset let copies = CW.copiesOfOn (Just w) (CW.taggedWindows $ W.hidden ws) return $ not $ null copies isCommandChecked _ _ = return False -- | Generic data type for decoration widgets. data GenericWidget cmd = TitleWidget -- ^ Window title (just text label) | WindowIcon { swCommand :: !cmd } -- ^ Window icon with some associated command -- | Other widgets | GenericWidget { swCheckedText :: !String -- ^ Text for checked widget state , swUncheckedText :: !String -- ^ Text for unchecked widget state , swCommand :: !cmd -- ^ Window command } deriving (Show, Read) -- | Generic widget type specialized for 'StandardCommand' type StandardWidget = GenericWidget StandardCommand instance (Default cmd, Read cmd, Show cmd, WindowCommand cmd) => DecorationWidget (GenericWidget cmd) where type WidgetCommand (GenericWidget cmd) = cmd widgetCommand TitleWidget _ = def widgetCommand w 1 = swCommand w widgetCommand _ _ = def isShrinkable TitleWidget = True isShrinkable _ = False -- | Check if the widget should be displayed in `checked' state. isWidgetChecked :: DecorationWidget widget => widget -> Window -> X Bool isWidgetChecked wdt = isCommandChecked (widgetCommand wdt 1) -- | Type class for widgets that can be displayed as -- text fragments by 'TextDecoration' engine. class DecorationWidget widget => TextWidget widget where widgetString :: DrawData engine widget -> widget -> X String instance TextWidget StandardWidget where widgetString dd TitleWidget = return $ ddWindowTitle dd widgetString _ (WindowIcon {}) = return "[*]" widgetString dd w = do checked <- isWidgetChecked w (ddOrigWindow dd) if checked then return $ swCheckedText w else return $ swUncheckedText w -- | Widget for window title titleW :: StandardWidget titleW = TitleWidget -- | Widget for ToggleSticky command. toggleStickyW :: StandardWidget toggleStickyW = GenericWidget "[S]" "[s]" ToggleSticky -- | Widget for Minimize command minimizeW :: StandardWidget minimizeW = GenericWidget "" "[_]" Minimize -- | Widget for ToggleMaximize command maximizeW :: StandardWidget maximizeW = GenericWidget "" "[O]" ToggleMaximize -- | Widget for CloseWindow command closeW :: StandardWidget closeW = GenericWidget "" "[X]" CloseWindow dwmpromoteW :: StandardWidget dwmpromoteW = GenericWidget "[M]" "[m]" DwmPromote moveToNextGroupW :: StandardWidget moveToNextGroupW = GenericWidget "" "[>]" MoveToNextGroup moveToPrevGroupW :: StandardWidget moveToPrevGroupW = GenericWidget "" "[<]" MoveToPrevGroup