You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
(I abandoned this as it's all clunkier than expected, even once set up properly. And, crucially, I couldn't get openDisplay to return anything other than null for a Gloss window, probably because Gloss is using an OpenGL that targets Quartz, rather than X11.)
Cabal is being weird about not propagating lib and include dirs.
nix-shell -p xorg.libX11 -p xorg.libXext -p xorg.libXrender -p xorg.libXrandr -p xorg.libXScrnSaver
#TODO this errors out for some (error: path '/nix/store/m76c8x2qxc42vc9g9gmbi5vh3kqq2lj1-libX11-1.7.0-man' is not valid)
# so we've hardcoded Church paths below (12/12/21), rather than using e.g. `$X11`
#TODO also for some of these, there are multiple paths
X11=$(nix path-info $(nix-instantiate '<nixpkgs>' -A xorg.libX11))
Xrandr=$(nix path-info $(nix-instantiate '<nixpkgs>' -A xorg.libXrandr))
# ...
rm cabal.project.local
echo '
package X11
extra-lib-dirs:
/nix/store/gfipvaizlslshnphk65582pcv2mqqj2v-libX11-1.7.0/lib
/nix/store/lh8s4vv95dirn11fj89ax2x6w9sqk9d5-libXrandr-1.5.2/lib
/nix/store/pl0f3wanll5phixlxm011ql1rrzdj2xk-libXScrnSaver-1.2.3/lib
/nix/store/bpvrd298qm3dvvzclav8hb39394i4c0x-libXext-1.3.4/lib
' > cabal.project.local
CPPFLAGS=" \
-I/nix/store/kp8lx4z07lhwffr6dr0gz6x7v3cdbi7i-xorgproto-2020.1/include \
-I/nix/store/5czbg1s55qy00ia03xpjgx2r3h88z21x-libX11-1.7.0-dev/include \
-I/nix/store/731lhdqg9vs44ikzhl3kwg44zz808pdd-libXrandr-1.5.2-dev/include \
-I/nix/store/gq4v0d7wvbzqxm28zjf8ci26m463x1lm-libXrender-0.9.10-dev/include \
-I/nix/store/pl0f3wanll5phixlxm011ql1rrzdj2xk-libXScrnSaver-1.2.3/include \
" \
LDFLAGS=" \
-L/nix/store/gfipvaizlslshnphk65582pcv2mqqj2v-libX11-1.7.0/lib \
-L/nix/store/lh8s4vv95dirn11fj89ax2x6w9sqk9d5-libXrandr-1.5.2/lib \
-L/nix/store/pl0f3wanll5phixlxm011ql1rrzdj2xk-libXScrnSaver-1.2.3/lib \
-L/nix/store/bpvrd298qm3dvvzclav8hb39394i4c0x-libXext-1.3.4/lib \
" \
cabb
Quartz API via macos-corelibs ^>= 0.0.1.0
This library is unmaintained and the API messy (plus no Hackage docs), but it actually seems pretty solid. I sense the author really knows what they're doing, and has thought through a lot of the hard problems involved in building a Haskell wrapper for Quartz. Unfortunately, it seems that Quartz doesn't allow for arbitrarily setting window title and icon like X11 and Win32 do. Very possibly for security reasons (it actually surprises me a little that the other two are so cavalier). I only realised this restriction after spending a few hours fiddling, and writing the exploratory code below.
{-# OPTIONS_GHC -Wno-unused-top-binds #-}
module Util.Window.Quartz (
Window,
findByName,
setTitle,
setIcon,
) where
import Data.ByteString (ByteString)
import Data.Text (Text)
import MacSdk
test = do
Just widsArray <- windowListCopyWindowInfo [] Nothing
wids <- arrayValues $ getDictionary <$> widsArray
traverse mkWID wids
data WID = WID
{ kCGWindowNumber :: Int
, kCGWindowStoreType :: Int
, kCGWindowLayer :: Int
-- , kCGWindowBounds :: Dictionary
, kCGWindowSharingState :: Int
-- , kCGWindowAlpha :: Float
, kCGWindowOwnerPID :: Int
, kCGWindowMemoryUsage :: Int
, kCGWindowOwnerName :: Maybe String
, kCGWindowName :: Maybe String
, kCGWindowIsOnscreen :: Maybe Bool
, kCGWindowBackingLocationVideoMemory :: Maybe Bool
}
deriving (Show)
-- mkWID :: WindowInfoDictionary -> IO WID
-- mkWID (getDictionary -> wid) = do
mkWID :: Dictionary -> IO WID
mkWID wid = do
kCGWindowNumber <- int =<< dictLookup "kCGWindowNumber"
kCGWindowStoreType <- int =<< dictLookup "kCGWindowStoreType"
kCGWindowLayer <- int =<< dictLookup "kCGWindowLayer"
-- kCGWindowBounds <- fromString CFStringEncodingUTF8 "kCGWindowBounds"
kCGWindowSharingState <- int =<< dictLookup "kCGWindowSharingState"
-- kCGWindowAlpha <- float =<< dictLookup "kCGWindowAlpha"
kCGWindowOwnerPID <- int =<< dictLookup "kCGWindowOwnerPID"
kCGWindowMemoryUsage <- int =<< dictLookup "kCGWindowMemoryUsage"
kCGWindowOwnerName <- traverse string =<< dictLookup' "kCGWindowOwnerName"
kCGWindowName <- traverse string =<< dictLookup' "kCGWindowName"
kCGWindowIsOnscreen <- traverse bool =<< dictLookup' "kCGWindowIsOnscreen"
kCGWindowBackingLocationVideoMemory <- traverse bool =<< dictLookup' "kCGWindowBackingLocationVideoMemory"
pure $ WID{..}
where
dictLookup s = getDictValue wid =<< fromString CFStringEncodingUTF8 s
dictLookup' s = do
s' <- fromString CFStringEncodingUTF8 s
withCFPtr s' $ getDictValueSafe wid
int x = do
Just n <- numberGetValue x NumberIntType
pure $ fromIntegral n
string s = do
Just r <- toString CFStringEncodingUTF8 s
pure r
bool x = withCFPtr x refToBool
data Window = Window
deriving (Eq, Ord)
findByName ::
-- | substring which must appear in the window title
Text ->
IO Window
findByName name = do
undefined
setTitle :: Window -> Text -> IO ()
setTitle (Window) t = do
undefined
setIcon ::
Window ->
-- | PNG image
ByteString ->
IO ()
setIcon (Window) img = do
undefined
AppKit?
I don't know much about it, but it looks like this may be the way.
How easy is it to bind Haskell to Objective-C? I think it uses the C calling convention.
I should check this will work (and that Quartz API is a dead end) by asking at e.g. https://www.reddit.com/r/MacOS/ (or r/macosprogramming).
The complexity of this is another reason why I don't really like this library, and feel it may be better to just use proper packaging where possible. See #2 (comment).
We need a Mac version of
Util.Window
(introduced in georgefst/lifx-manager#8)XQuartz
(I abandoned this as it's all clunkier than expected, even once set up properly. And, crucially, I couldn't get
openDisplay
to return anything other than null for a Gloss window, probably because Gloss is using an OpenGL that targets Quartz, rather than X11.)None/little of the below should be necessary:
Quartz API via
macos-corelibs ^>= 0.0.1.0
This library is unmaintained and the API messy (plus no Hackage docs), but it actually seems pretty solid. I sense the author really knows what they're doing, and has thought through a lot of the hard problems involved in building a Haskell wrapper for Quartz. Unfortunately, it seems that Quartz doesn't allow for arbitrarily setting window title and icon like X11 and Win32 do. Very possibly for security reasons (it actually surprises me a little that the other two are so cavalier). I only realised this restriction after spending a few hours fiddling, and writing the exploratory code below.
AppKit?
I don't know much about it, but it looks like this may be the way.
The text was updated successfully, but these errors were encountered: