window de/activation notifications (was Re: inappropriate tool palette activation problem)

  • On Date: Thu, 18 Oct 2007 09:42:24 +0200, Uli Kusterer said:
    > Am 18.10.2007 um 02:53 schrieb John Richetta:
    >> I also don't know why I'm receiving seemingly incorrect, or at
    >> least very unnecessary, extra window activation and deactivation
    >> notifications, via didBecomeMain and didResignMain, but this is a
    >> separate topic, and I can probably get to the bottom of these
    >> issues.
    >
    > The apps that don't have this are probably Carbon, are they? Or
    > maybe they're just using non-activating panels. The new behaviour
    > has two activation states. One is the "main" window, which has the
    > gradient, and the other is a more subtle "frontmost window in its
    > layer" hightlight.
    >
    > This distinction is actually very useful, in particular for
    > controlling an app via keyboard. You can use Cmd-~ (or Cmd-< on some
    > localized keyboards) to make whatever window you want main, floater
    > or document. And then the "Zoom" and "Minimize" menu items will
    > apply to that window. Same goes for the "Close" menu item. Before
    > Apple introduced this behaviour, it was impossible to perform the
    > actions of the window widgets under keyboard control for some
    > windows.

    I tend to be a stickler for UI details, but I admit that I hadn't
    noticed a distinct "frontmost in its layer" highlight.  However, my
    point was a different one (which I again explained inadequately).
    This (second) problem is not about appearance but rather
    notifications.

    For my application to properly load and store object state used by
    its inspector window, I must know about application windows being
    activated and deactivated (this terminology which was previously very
    clear on Mac OS is no longer consistently applied in the
    documentation; often, but not always, the NeXT terminology of
    "ordering front" is used, or the term "main" - which doesn't appear
    to be really precisely defined anywhere).

    The inspector must always synchronize with the frontmost document,
    and save changes made to frontmost document before it loses that
    status.  Although it is in fact rare for changes to be committed
    later rather than at the exact time they are made in the inspector
    window, it is still possible, and so these notifications are
    important.

    It took me a while to determine how to obtain these notifications.
    In older Mac OS, these were events delivered to all apps, without
    requesting them specially, but now, apparently, one must subscribe to
    the didBecomeMain and didResignMain notifications.  I've done this,
    and these notifications are being sent to my documents, which then
    message the inspector appropriately.

    However, either I am getting too many notifications, or I don't
    understand their meaning correctly.  They are sent at times and/or
    for reasons that seem to be more complicated than simple window
    activation and deactivation.  Specifically, here is what happens in
    my application, assuming document A is initially in front of document
    B, and one clicks on document B:

        1. app receives a deactivate (windowDidResignMain) for document A
        2. app receives a deactivate for document B
        3. app receives an activate (windowDidBecomeMain) for document A
        4. app receives an activate for document B

    If one then clicks on document A, one will receive the *exact* same
    sequence all over again!

    I can't fathom why I receive deactivate and activate notifications
    for both windows, every time one window is clicked once.  Further,
    the notification order does not match what I would expect (it seems
    to match temporal order of window *creation*).  This pattern extends
    to the case when many windows are on-screen: all send a notification
    for every window order change, and the order of the notifications
    from specific windows remains constant, regardless of window depth
    order.

    I'm sure I'm misusing something, and the answer is probably staring
    me in the face...

    Thanks for reading, and any further suggestions.  -jar
  • On Oct 19, 2007, at 1:02 PM, John Richetta wrote:

    > 1. app receives a deactivate (windowDidResignMain) for document A
    > 2. app receives a deactivate for document B
    > 3. app receives an activate (windowDidBecomeMain) for document A
    > 4. app receives an activate for document B
    >
    > If one then clicks on document A, one will receive the *exact* same
    > sequence all over again!
    >
    > I can't fathom why I receive deactivate and activate notifications
    > for both windows, every time one window is clicked once.

    I just put together a quick test app and can't reproduce your results.

    I'll bet something's up with how you're registering for
    notifications, maybe you're passing 'nil' for the object parameter?
    If so, your notification handler will get called whenever ANY window
    becomes or resigns main.

    Here's my test app project:<http://www.muratnkonar.com/source-code/
    Windows.zip
    >

    _murat
  • Am 19.10.2007 um 22:02 schrieb John Richetta:
    > I tend to be a stickler for UI details, but I admit that I hadn't
    > noticed a distinct "frontmost in its layer" highlight.

      To see it, open the "Addresses" window in Mail. When it comes up,
    it initially has a black window title, and the widgets have black
    outlines and are opaque, too. However, the title bar background has
    the inactive, striped appearance. If you now explicitly click the
    window, it actually becomes active, and you see that because the
    window widgets actually take on color, and the title bar background
    gets the gradient instead of the pinstripes.

      Once you click the Addresses window, you'll also notice that the
    Mail window itself deactivates half-way. The title bar gets a softer,
    whiter gradient, but the title text stays black. Only if you switch
    out the application, or open a second Mail Viewer main window or a
    message window, you'll get the real inactive appearance with the
    pinstripes, inactive title text and the semi-transparent widgets.

      IIRC floaters only have the two states, because they are either
    available, or hidden when the app is in background, so I guess nobody
    bothered implementing that appearance.

    > (this terminology which was previously very clear on Mac OS is no
    > longer consistently applied in the documentation; often, but not
    > always, the NeXT terminology of "ordering front" is used, or the
    > term "main" - which doesn't appear to be really precisely defined
    > anywhere).

      It is, somewhere, but I don't remember where I read it. Have you
    checked the HIG or Hillegass' book?

    > It took me a while to determine how to obtain these notifications.
    > In older Mac OS, these were events delivered to all apps, without
    > requesting them specially,

      Well, only because all events were delivered to everyone in the
    main event loop. Since in Cocoa the event loop (NSRunLoop) is owned
    by the framework, it gets dispatched differently.

    > but now, apparently, one must subscribe to the didBecomeMain and
    > didResignMain notifications.  I've done this, and these
    > notifications are being sent to my documents, which then message
    > the inspector appropriately.

      Actually, what you really want to do is implement -
    windowDidBecomeMain: etc. in your window delegate (which is usually
    the document class), but you may have to explicitly hook that up in
    the NIB.

    > However, either I am getting too many notifications, or I don't
    > understand their meaning correctly.

      If you're explicitly registering, and your notification method
    happens to be named windowDidBecomeMain:, you could be getting the
    message twice (once via delegation, the second time via your explicit
    request). Also, you have to specify the object for the notification.
    If you specify NIL there, you'll get notifications for every window,
    instead of just for the object you're interested in. Could any of
    these be your problem?

      It may help to re-read Hillegass and the NSNotification(Center)-
    and delegate-related documentation to make sure you understand these
    concepts and how everything is set up to work.

      In general, when in other frameworks you would subclass a framework
    class, in Cocoa you instead use delegation. The advantage of
    delegation is that you aren't forced to have the delegate be a
    distinct object. It could just be an existing other object. I.e. you
    can have one delegate that handles several similar windows, or one
    delegate that handles a window, and also is the delegate of the views
    in that window... everything that makes sense conceptually, and
    within the Model-View-Controller scheme.

    Cheers,
    -- M. Uli Kusterer
    http://www.zathras.de
  • Murat,

    You sure nailed my problem!  Not sure why, but I did indeed pass in
    nil for the sender object parameter when setting up notifications.
    Sheesh!  I never noticed the verbiage about nil arguments.  I was too
    busy looking for more info on these particular notifications...

    Thanks very much for such a helpful reply.  Sorry to waste bandwidth
    on such a dumb mistake.

    -jar

    > On Oct 19, 2007, at 1:02 PM, John Richetta wrote:
    >
    >> 1. app receives a deactivate (windowDidResignMain) for document A
    >> 2. app receives a deactivate for document B
    >> 3. app receives an activate (windowDidBecomeMain) for document A
    >> 4. app receives an activate for document B
    >>
    >> If one then clicks on document A, one will receive the *exact* same
    >> sequence all over again!
    >>
    >> I can't fathom why I receive deactivate and activate notifications
    >> for both windows, every time one window is clicked once.
    >
    >
    > I just put together a quick test app and can't reproduce your results.
    >
    > I'll bet something's up with how you're registering for
    > notifications, maybe you're passing 'nil' for the object parameter?
    > If so, your notification handler will get called whenever ANY window
    > becomes or resigns main.
    >
    > Here's my test app
    > project:< http://www.muratnkonar.com/source-code/Windows.zip >
    >
    > _murat
previous month october 2007 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today