NSOpenPanel trouble with leopard

  • Hello,

    I'm getting some trouble to make my cocoa app work with leopard : I
    converted it to Objective C 2.0, it compiles fine, great. However one
    critical part don't work as expected at runtime : it's impossible to
    make appear any open file dialog.
    I changed my code to use one of the leopard samples, so it's very
    simple :

    - (IBAction) loadConduite:(id)sender
    {
    NSLog(@"load conduite");
    NSString *conduiteFilename;

    NSArray *fileTypes = [NSArray arrayWithObjects:@"xml", nil];

            NSOpenPanel *oPanel = [NSOpenPanel openPanel];

    NSLog(@"after openPanel");

        int result = [oPanel runModalForTypes:fileTypes];

        if (result == NSOKButton) {
      conduiteFilename = [oPanel filename];
      NSLog(@"load conduite2b");

      //[renderWindow setLevel:2];
      [self loadConduiteAtPath:conduiteFilename];
      conduiteFilePath = conduiteFilename;
      [conduiteFilePath retain];
      NSLog(@"load conduite3");
    }
    else return;
    NSLog(@"load conduite4");
    }

    at runtime the line after NSOpenPanel *oPanel = [NSOpenPanel
    openPanel]; is never executed and the program continue normally, like
    if the thread for opening just stoped.

    Another simple program wih the same code is working properly.

    Does someone as any clue or idea of where the problem is ?

    Thanks
    Adrien
    _________________
    www.adrienm.net/emotion/
  • You can only execute that code on the main thread. The open panel is
    not thread safe.

    On Dec 3, 2007, at 2:01 AM, Adrien Mondot wrote:

    > Hello,
    >
    > I'm getting some trouble to make my cocoa app work with leopard : I
    > converted it to Objective C 2.0, it compiles fine, great. However
    > one critical part don't work as expected at runtime : it's
    > impossible to make appear any open file dialog.
    > I changed my code to use one of the leopard samples, so it's very
    > simple :
    >
    >
    > - (IBAction) loadConduite:(id)sender
    > {
    > NSLog(@"load conduite");
    > NSString *conduiteFilename;
    >
    > NSArray *fileTypes = [NSArray arrayWithObjects:@"xml", nil];
    >
    > NSOpenPanel *oPanel = [NSOpenPanel openPanel];
    >
    > NSLog(@"after openPanel");
    >
    > int result = [oPanel runModalForTypes:fileTypes];
    >
    > if (result == NSOKButton) {
    > conduiteFilename = [oPanel filename];
    > NSLog(@"load conduite2b");
    >
    > //[renderWindow setLevel:2];
    > [self loadConduiteAtPath:conduiteFilename];
    > conduiteFilePath = conduiteFilename;
    > [conduiteFilePath retain];
    > NSLog(@"load conduite3");
    > }
    > else return;
    > NSLog(@"load conduite4");
    > }
    >
    > at runtime the line after NSOpenPanel *oPanel = [NSOpenPanel
    > openPanel]; is never executed and the program continue normally,
    > like if the thread for opening just stoped.
    >
    > Another simple program wih the same code is working properly.
    >
    > Does someone as any clue or idea of where the problem is ?
    >
    > Thanks
    > Adrien
    > _________________
    > www.adrienm.net/emotion/
  • Hi and thanks for your answer...

    maybe it's a newbie question but :
    This function is called via a connection made in Interface Builder,
    isn't it supposed to be executed in the main thread ?

    In my app, I use a displayLink thread for rendering, so I changed the
    code for something like this (adding CVDisplayLinkStop)

    - (IBAction) loadConduite:(id)sender
    {
        CVDisplayLinkStop(_displayLink);

        NSString *conduiteFilename;
        NSArray *fileTypes = [NSArray arrayWithObjects:@"xml", nil];

        NSOpenPanel *oPanel = [NSOpenPanel openPanel];

        int result = [oPanel runModalForTypes:fileTypes];

        if (result == NSOKButton) {
      conduiteFilename = [oPanel filename];
      [self loadConduiteAtPath:conduiteFilename];
    }
    else return;
    CVDisplayLinkStart(_displayLink);
    }

    However it still doesn't work.

    During the call to the
    NSOpenPanel *oPanel = [NSOpenPanel openPanel];
    the console start to dump some errors :
    2007-12-03 18:32:07.155 eMotion[1724:10b] NSOutlineView Warning:
    reloadData called while in the middle of doing a reloadData!
    and continue to dump this line at each rendering loop (60 times/s)

    But I really don't understand why a request for openPanel can make
    some error in other objects of my app ?!?

    Anyway thanks again for your help,

    Adrien

    Le 3 déc. 07 à 16:29, John Stiles a écrit :

    > You can only execute that code on the main thread. The open panel is
    > not thread safe.
  • On Dec 3, 2007, at 9:45 AM, Adrien Mondot wrote:

    > Hi and thanks for your answer...
    >
    > maybe it's a newbie question but :
    > This function is called via a connection made in Interface Builder,
    > isn't it supposed to be executed in the main thread ?
    >
    > In my app, I use a displayLink thread for rendering, so I changed
    > the code for something like this (adding CVDisplayLinkStop)
    >
    >
    > - (IBAction) loadConduite:(id)sender
    > {
    > CVDisplayLinkStop(_displayLink);
    >
    > NSString *conduiteFilename;
    > NSArray *fileTypes = [NSArray arrayWithObjects:@"xml", nil];
    >
    > NSOpenPanel *oPanel = [NSOpenPanel openPanel];
    >
    > int result = [oPanel runModalForTypes:fileTypes];
    >
    > if (result == NSOKButton) {
    > conduiteFilename = [oPanel filename];
    > [self loadConduiteAtPath:conduiteFilename];
    > }
    > else return;
    > CVDisplayLinkStart(_displayLink);
    > }
    >
    > However it still doesn't work.
    >
    > During the call to the
    > NSOpenPanel *oPanel = [NSOpenPanel openPanel];
    > the console start to dump some errors :
    > 2007-12-03 18:32:07.155 eMotion[1724:10b] NSOutlineView Warning:
    > reloadData called while in the middle of doing a reloadData!
    > and continue to dump this line at each rendering loop (60 times/s)
    >
    > But I really don't understand why a request for openPanel can make
    > some error in other objects of my app ?!?

    It sounds like something is causing a bug in the open panel, for some
    reason.

    Can you:

    1. Launch your app in GDB, or the debugger in Xcode.
    2. Reproduce the problem, and as soon as it starts happening, "break"
    in gdb (ctrl-c at the command line, or "pause" in xcode).

    After you do that, please reply back with the backtrace. This will
    help me pinpoint what the problem is, and I may be able to offer a
    work around.

    corbin
  • I think I found one of the side effect that caused the problem : it
    was a NSOutlineView that was raising an error when updated, I don't
    understand why it was updating when calling NSOpenPanel, neither why
    it raise an error...
    I removed the notification I was using, and now it's working (almost)
    normally

    [[NSNotificationCenter defaultCenter] addObserver: self
                           selector: @selector(forceSelectionDidChange:)
                           name: NSOutlineViewSelectionDidChangeNotification
                                          object: forceView];

    However may my code was poorly designed to make the transition from
    ObjC to ObjC 2.0 easely : I still have some serious bug of the same
    kind in the rest of the app :-(

    Adrien

    Le 3 déc. 07 à 21:46, Corbin Dunn a écrit :
    >
    > It sounds like something is causing a bug in the open panel, for
    > some reason.
    >
    > Can you:
    >
    > 1. Launch your app in GDB, or the debugger in Xcode.
    > 2. Reproduce the problem, and as soon as it starts happening,
    > "break" in gdb (ctrl-c at the command line, or "pause" in xcode).
    >
    > After you do that, please reply back with the backtrace. This will
    > help me pinpoint what the problem is, and I may be able to offer a
    > work around.
    >
    > corbin

    _________________
    www.adrienm.net/emotion/
  • On Dec 3, 2007, at 4:11 PM, Adrien Mondot wrote:

    > I think I found one of the side effect that caused the problem : it
    > was a NSOutlineView that was raising an error when updated, I don't
    > understand why it was updating when calling NSOpenPanel, neither
    > why it raise an error...
    > I removed the notification I was using, and now it's working
    > (almost) normally
    >
    > [[NSNotificationCenter defaultCenter] addObserver: self
    > selector: @selector(forceSelectionDidChange:)
    > name: NSOutlineViewSelectionDidChangeNotification
    > object: forceView];

    Was forceView nil at the time you registered for the notification? If
    so, you will get a notification for *every* outline view.

    Jim
  • On Dec 3, 2007, at 1:24 PM, Jim Correia wrote:

    > On Dec 3, 2007, at 4:11 PM, Adrien Mondot wrote:
    >
    >> I think I found one of the side effect that caused the problem : it
    >> was a NSOutlineView that was raising an error when updated, I don't
    >> understand why it was updating when calling NSOpenPanel, neither
    >> why it raise an error...
    >> I removed the notification I was using, and now it's working
    >> (almost) normally
    >>
    >> [[NSNotificationCenter defaultCenter] addObserver: self
    >> selector: @selector(forceSelectionDidChange:)
    >> name: NSOutlineViewSelectionDidChangeNotification
    >> object: forceView];
    >
    > Was forceView nil at the time you registered for the notification?
    > If so, you will get a notification for *every* outline view.
    >

    Yup; I was guessing the same thing. I've seen this type of problem
    before.

    --corbin
previous month december 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