The AppState type gets generated by the viewable macro. It is a ref-type Strictly speaking 2 ref-types, one representing the state of the GTKWidget (AppState) and one representing the "new" state within owlkettle with all the values it got from elsewhere (App).
For those curious, this is the type it generates from one of the examples: type App = ref object of Widget hasBuffer*: bool valBuffer*: TextBuffer hasMonospace*: bool valMonospace*: bool hasCursorVisible*: bool valCursorVisible*: bool hasEditable*: bool valEditable*: bool hasAcceptsTab*: bool valAcceptsTab*: bool hasIndent*: bool valIndent*: int hasSensitive*: bool valSensitive*: bool hasSizeRequest*: bool valSizeRequest*: tuple[x, y: int] hasTooltip*: bool valTooltip*: string AppState = ref object of Viewable buffer*: TextBuffer monospace*: bool cursorVisible*: bool editable*: bool acceptsTab*: bool indent*: int sensitive*: bool sizeRequest*: tuple[x, y: int] tooltip*: string Run And afaik yes, threads:on is mostly looked at combined with arc/orc, I'm not aware of any looking too much on the "nim 1.6 with refc" case, though note that I don't speak all that much for the project, I just contribute. As for the thread assumptions GTK makes (to keep the info level here the same as in discord): > GTK requires that all GTK API calls are made from the same thread in which > the GtkApplication was created, or gtk_init() was called (the main thread). A quote from a user from GTK's discourse forum: > Your second example is actually calling update_rows in another thread, but in > GTK you should never try to do that. GTK is not thread safe, it is only safe > to call GTK functions from the main thread. What this mostly made me wonder is how a server-client style architecture with owlkettle could look like, with the backend being just a separately running process.