MorphOS MUI is strange

Posted by ALB42 on 27. Juni 201511 Comments

Playing around with the LCL for MorphOS, seems to work nicely, but (as described last time already) it crashes on Exit. I tried to find the reason for it. It seems that that the MUI Objects are kind of destroyed already, even still visible on the screen. Due to the special way to work in LCL I do not like the automatic destroy function of MUI. If you build up a mui application with application, window, items in there you usually only need to destroy the application and every thing else will just be automatically destroyed. Of course thats not what we want to use for LCL (or it would be impossible to destroy single button/Windows and so on). Long time before at AROS I played around with it and the best solution is to just unlink the item from its parent and destroy it by hand (MUI_DisposeObject) because then it is always in my full control when an object gets destroyed or alive.
Seems thats exactly my problem now. When I begin to destroy my objects at some point it seems that the MUI Objects are already destroyed, so it crashes, but this object (window) is still visible on the screen. I removed all MUI_DisposeObject from my code and still the Window gets destroyed somehow :-O and the mui objects are invalid. Here happens something I do not understand. Really strange thing, maybe its some special “new MUI Version”-thing? I don’t know and not really an idea how to continue here. Maybe I need to write a simple non-LCL program where I do the same and try to find out this strange behaviour.

11 comments to "MorphOS MUI is strange"

  1. Jacek sagt:

    Most of MUI follows the ‘parent owns the child’ policy, so when the parent is disposed, the child gets disposed as well. If you need the child to stay alive for reuse or so, you simply have to OM_REMMEMBER/MUIM_Family_Remove/MUIM_Group_Remove it from the parent. Starting with MorphOS 3.8 you may also send an OM_RETAIN to the object to increase its reference count – just remember to call OM_RELEASE later to dispose it (interchangeable with MUI_DisposeObject as well!).

  2. ALB42 sagt:

    This is exactly what I’m doing, from the text: “unlink the item from its parent” is exactly a “OM_REMMEMBER/MUIM_Family_Remove/MUIM_Group_Remove” and at AROS this works perfectly well.

    How it work currently on create
    – create application
    – create window + group
    – link window to application
    – create Button
    – link button to group
    – show window

    on destroy:
    – unlink button
    – destroy button
    – unlink window <--- crash seems window, group and application are gone already, any access to them will crash even I never Destroy the button still the same problems, I'm rather stuck here.

    • Tcheko sagt:

      If they are gone, then objects were disposed previously. If you’re messing stuff in Dispose method of application for example, be sure to act before DoMethodSuper. Everything done after DoMethodSuper will be on already disposed objects.

      • ALB42 sagt:

        Until now for MorphOS I do not use any Dispatcher, so this are just the plain MUI objects. I removed every MUI_DisposeObject() from the code, but still the same behavior. Maybe some automatics? an application + window + group can not stand on itself without the button so if I remove the button it will dispose itself? (If I create only application + window + group I’m not able to open the window, even the group has a layout hook, so in principle it could open)

        I do not know who destroys my Application but its not me.

        Anyone knows a method to find out who/when it gets destroyed? some enhanced Debug output?

        Ok, maybe I could add a dispatcher to application and let it crash on Dispose and check the Callstack from where it came, but I guess the Callstack will be not long enough to see the real source.

  3. Jacek sagt:

    Rule #1: do not use hooks, ever.

    Do you have a piece of code to illustrate your problem? Otherwise it’ll be hard to help.

  4. ALB42 sagt:

    Is there an other way to force an own placements of items?
    Is there a better way for events, dynamically created?

    Why nit hooks? Hooks are nice and real OOP. This strange way with the MUIM_Application_ReturnID is very bad, if you try to make a dynamically application where you do not know how many and which items and events there are at the end.

    Reminder: What I try to compile is LCL, Lazarus component library, its a GUI library not a single program. So everything have to be highly dynamically created, placed and destroyed.

    The Source is available for all, only AROS atm., the MorphOS is not included there currently:
    https://github.com/alb42/lazarus/tree/lazarus-aros/lcl/interfaces/mui

    but as I wrote in the article, I guess I have to write a simple application which tries the same things as in the LCL.

  5. Jacek sagt:

    The only valid use of hooks may indeed be a layout hook, although you are likely to create a bad looking app if you ignore MUI’s regular layout. Normally you’d have your main dispatcher have a method called when a button is pressed, etc, rather than have a hook called on button press.

    I’ve had a brief look at the code:

    TMuiApplication.AddChild: SetAttribute(MUIA_Application_Window, child.obj); <- while allowed, that is very bad MUI code and it not meant to be used like that – the only real use is in MUI macroed object creation.

    What you should do is to DoMethod(applicationobject, OM_ADDMEMBER, windowobject), and to remove use OM_REMMEMBER. This will likely fix at least some of your issues. At the moment your windows are never removed and when you dispose the application they are disposed along with it.

    • ALB42 sagt:

      Thanks for looking into.
      the OM_ADDMEMBER is done in in the “inherited AddChild(Child);” (which is compareable to an DoSupermethod in MUI) TMUIApplication is inherited from TMUIObject ( TMuiApplication = class(TMUIObject) ) and there in the TMUIObject.AddChild you find the OM_ADDMEMBER. This settings of the MUIA_Application_Window was only to define the default application window, even it gets destroyed and a new one is created. I’m not sure if this is needed at all 😉 I will try to remove it and see if there is any difference, Thanks for that hint.

      About the layout hook, you neglect here that the LCL is a GUI set itself at has its own layouter, which for sure works nicely, not only aligned to the full window/group but also fixed to some position, see entries before especially the MorphOS Layout Entry.

  6. Tcheko sagt:

    > Is there an other way to force an own placements of items?

    No. Unless you write your own group layouter. (I fear the grid placement stuff
    here… which is well. A call for trouble with MUI. Objects can have different size depending of the decoration applied by MUI user settings… It will be really ‘hard’ to make a grid placement working nicely. Depending of the MUI skin settings, objects might overflow each other.)

    > Is there a better way for events, dynamically created?

    See MUIM_Notify.

    > Why not hooks? Hooks are nice and real OOP.

    Really? Hooks suck donkey balls. Use Dispatcher and override methods. That’s *real* OOP.

    > This strange way with the MUIM_Application_ReturnID is very bad

    That’s why you better use Dispatcher way of doing things and stick to the default MUI loop for handling event flowing in the application. You can extend to more signal if needed without problem.

    See SDK examples for more insight on the matter.

    Also, a good starting point for MUI subclassing mastery: http://library.morph.zone/Magic_User_Interface_Programming

    Without proper subclassing, you’ll go anywhere with MUI.

    • ALB42 sagt:

      As I wrote LCL is a GUI library with an own layouter which is able to make the layout. With skinning is a problem but there is a way around because LCL support also minimal sizes and theming and so on there you have the same problems. So it is solvable.

      in your link I also find:
      http://library.morph.zone/Event_Driven_Programming,_Notifications
      where my Hook method gets described MUIM_CallHook(), the Event driven programming fits very nicely to LCL (because its also event driven). About subclassing EVERY class I use, I thought about also, its just a hell of work, because I have to subclass EVERY single MUI class available.

  7. Tcheko sagt:

    No pain, no gain. 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.