Flasks
- 19 Devlogs
- 53 Total hours
A FOSS MacOS Wine Frontend mainly intended for testing/development
A FOSS MacOS Wine Frontend mainly intended for testing/development
We are nearing the end now so you might notice there are actual releases on github now
idk why i thought it’s a good idea to add sort of a crappy sidebar you can do things like change flask settings and whatnot from but it happened so no time to complain now
all the buttons on it work using the alr bundled tools with wine (taskmgr, winecfg, wineserver, etc)
except winetricks which i am still figuring out
Made GPTK downloadable finally, also included some checks cuz wine is called wine64 sometimes
hopefully that doesn’t infringe on apple’s license?? (they did say they forbid bundling i am pretty sure not downloading)
lot of rapid fire small changes/features, gonna possibly continue like that till the end of stardance cuz the next step is to make a good enough wine runner, which is gonna need a stupid amount of time that is mostly not tracked by hackatime
So it sucks a bit cuz i am terrible at art but it’s fine, it’s modeled after my irl water “flask” funnily enough, don’t ask why, idk either
ye it just sets the environment variable for each, not working in upstream wine since you need a custom patched version of wine to use it which i don’t have rn
Made A Flask and want to change its settings? now you can do that (it’s literally just the OptionView wrapped in another sheet)
so instead of making a whole PE Parser, i learned of this tool called “wrestool” it’s a part of something called Icoutils so what if……we just bundle wrestool and then use it to extract raw ICO data from an exe file? and since NSImage supports ico
this worked perfectly!!
I struggled a bit with byte encoding but eventually realized we want raw bytes (not a string lol) and found the correct option and that was it
UI was getting too messy so had to intervene
So in all most other Wine Frontends, you typically have 1 app per wine prefix
In Flasks, I want to give the user the ability to add however apps they like to a flask
This was a bit annoying with the “InstallAppWizard” handling both flask creation and adding apps to a flask
So….
It was fairly trivial there is nothing to talk about as the views were alr made i just needed to restructure things a bit
also that create flask button being at the bottom of the sidebar may haunt me later…….
finally…. this is taking so long
so i found out i was an idiot for not realizing that i could actually bundle everything i need in the app bundle instead of pulling the entire universe on first launch
so i bundled DXVK, DXMT (likely a wrong version of dxmt but whatever, will fix)
I still need to figure out a way of doing this instead of hosting random dlls on the repo (xcode build scripts maybe?)
I made Flasks put symlinks to the bundled DXVK in System32 and SysWoW64 and used wine dll overrides and that was it
tho i did spend like half a day trying to figure why was wine not detecting my dxvk dlls and it turned out i was using a “builtin” version of dxvk that needs to be put in the lib folder of wine itself but oh well
also made a quick ui for it (which is getting completely overhauled next devlog cuz this is a mess)
still a WIP, DXMT is considerably more complex cuz apparently i need another wine version that exposes some APIs in winemac.drv or something?
i really wish once stardance ends i would just fork some WineCX version and maintain it myself cuz this is dumb
also Apple dropping support for Rosetta in MacOS 28 is worrying cuz now someone needs to port fex to mac (codeweavers doing this but i don’t think they are ever open sourcing it)
I wanted to finally tackle something i have been avoiding for a while now, Enabling tweaks like DXVK/DXMT/D3DMetal
in the case of D3DMetal and DXMT, i learned it’s a bit more involved unfortunately so i decided to focus on the easiest one DXVK for now
It turns out I have no idea where to get DXVK from, where to put it, when to download, how to use it seamlessly, etc so i decided to tackle some other things first b4 doing this
I made the class WineDownloader more general purpose because we need to make it work for DXVK too
I made a new window design using Table and it looks kinda cool tbh
why, onboarding ofc
I am now thinking of two main options for downloading things (DXVK, Winetricks, etc)
Some enhancements here and there
yes, you can do that now (see image #2), while the code structure is a bit ugly it does work beautifully, maybe there are still bugs but ig that’s true for the whole app
I added a small button in the console to copy all console logs to clipboard, nothing much to be said here i just used NSPasteboard
mostly code maintenance if iam gonna be honest, anyways…..
So yeah we now have a context menu that shows 2 options
“Show in finder” -> does what it says on the tin lol, it just needed me to fix my poor URL instantiation
“Remove app from the Flask” -> again pretty straightforward, removes the reference to the app from the Flask
now we GPL 3.0, so that’s cool :>
While i was trying to refine the Grid View we made in the last devlog (handling selection, keyboard events, animations, etc), i learned about this AppKit view called NSCollectionView that does precisely what i wanted, it is even used in Finder’s grid view
For those of you who don’t know AppKit, it is an imperative UI framework made originally for NeXTSTEP (NS for NeXTSTEP btw) in 1988 but later became MacOS’s main UI framework
Now to use an AppKit View in SwiftUI you need something called NSViewRepresentable
Using this thing on its own is somewhat complex but to use it with NSCollectionView (which is alr a very involved AppKit view) proved to be a monumental task especially for me who had never touched AppKit before
So after wasting a lot of time trying to figure this out i just went back to the LazyVGrid approach and hopefully we can come back to this later
I started by adding a selection effect to the grid, meaning that if you click on a program once a background appears behind it (look at the screenshot lol i can’t explain :<)
at first it was terribly slow to activate cuz we effectively had 2 .onTapGesture but then i found this solution on stackoverflow
.gesture(
TapGesture(count: 2).onEnded {
isRunning = true
Task.detached {
try await flask.runApp(programPath)
DispatchQueue.main.async {
isRunning = false
}
}
}
)
.simultaneousGesture(
TapGesture().onEnded {
selectedProgram = programPath
}
)
as for animation it was relatively easy, I just used PhaseAnimator to replicate the MacOS app jump effect
I made this small grid view thing using LazyVGrid to represent each program registered in a flask’s flask.json file, tried to make it a blend between crossover’s and whisky’s approach and actually made it launch programs
Naturally as an avid undertale fan, i knew i had to try undertale yellow first (which is windows-only), at first with upstream wine it just showed a black screen (with sound) but when i did some patches to be able to use Gcenx’s gptk builds (specifically GPTK 3.0) it worked!!
the only sad part is that it appears that to get the icon from a windows executable you need to make some sort of PE header parser (which whisky has made) for now i just use the generic icon that MacOS gives us (which is a whisky icon rn bec i had whisky installed)
I can’t seem to ignore just how ugly this Install App thing looks, so i searched a bit for swiftui views that could help and even referenced Whisky’s (the now deprecated MacOS FOSS wine frontend) BottleCreationView.swift to make something a little less heinous (still heinous but a bit less) using the Form view and in the end i settled on this (look at the attached screenshots -_-)
I really should find something more important to work on lol because this InstallAppWizard view is not that important for now
Devlog #?? (idk, who’s keeping track atp)
The picker which lets you pick the wine/runner version for the flask bothered me bec it always kept refreshing whenever you changed views in the Install App wizard thing
so i made it that the install app wizard owned the runner library and just passed it down using @Binding to the CreateFlaskView then it would be updated only when the sheet appeared
So finally got around to making the sidebar display the actual list of created flasks (aka wine prefixes), it took a while cuz there was a nasty bug in the json decoding function i used to create flask entries, quickly patched it and everything worked as expected :>
Hi, been a while since the last one
mostly struggling to do idiomatic swift/swiftUI error handling :<
anyways……
idk why (ig for testing or something) but i found out Singletons are an anti-pattern so i removed them in favor of just using @Observable and @Environment the way it’s done rn is kinda dumb but “will fix later”™
I’ve added proper error handling for once, everyone online seemed to recommend you create your own custom error type and i did that with the new FlaskError enum and made all functions which should throw (and not just print a stupid message to the console :-< ) throw a FlaskError
still i need to hook it up to the UI which is more easier said then done, i have no clue what is the cleanest way to do that in SwiftUI and am kinda just freestyling it rn and I know it still looks ugly rn cuz still prototyping
yeah so i wanted to they async/await on the processes i was spawning (e.g: to get wine version, to make wine prefix, to run a program in wine prefix, etc) but learned you have to make an extension to the Process class so i just used the cross platform newer first-party Subprocess library instead, probably for the best anyways
Now Hopefully we can stop working on UI for a bit bec UI is boring imo
yeah that’s about it.
I was kinda feeling frustrated that the only good option to run Windows apps and games on MacOS was crossover (which is paid) so i decided i would try making an alternative for it (that doesn’t suck + is user friendly)