MacOS opens new window for each SU file I open. Can I close them?

My plugin cycles through all the .skp files in a given folder. On MS Windows, the same window is used for each file, so the previous file gets closed. On MacOS, each new file gets it’s own window. If there are dozens of files, this can be a problem. So I guess I have two questions:

  • How do I detect if I’m on a mac?
  • If I’m on MacOS, is there a way to re-use the window, instead of opening a new one?
  • OR: How can I close a window when I’m done with it, without stopping my script?

Or maybe there’s a different approach I haven’t thought of. Thanks in advance for your advice. CB.

Sketchup platform class method

Not sure about Mac, but I guess you need to close the active model and open that new one:
Model#close instance method

1 Like

I agree. Always use API methods on the active model only.

I believe that on Windows Sketchup#open_file automatically closes the current model and replaces it with the new one in the same GUI edit window because on Windows SketchUp is SDI (single document interface).

But on Mac it does not. On Mac, Sketchup#open_file will load the argument model file and point the GUI edit window at the newly loaded model, that is, make it the active model.

But, because Mac SketchUp is MDI (multiple document interface) previous models will remain in memory. You can make one of them active (switch the GUI edit window to it) either by clicking its tab or via its entry in the Windows menu. Alas, the Ruby API does not provide any method that I know of to tell if there are other models loaded or to switch them to be active. I suspect this is because it could be very confusing to a user if an extension magically changed the active model without any explicit user action.

So, on Mac the right sequence is to loop over your list of files, for each one doing:

  • call Sketchup#open_file to load a model file
  • call Sketchup#active_model to get a handle to the newly loaded model
  • make your changes via that handle
  • save the changed active model
  • invoke model#close on the active model

I think the same sequence should also work on Windows provided model#close does not implicitly shut down SketchUp.

The downside of this sequence on Mac is that each time you close a model, the GUI edit window will either disappear if there are no other open models or will switch to some other already opened model. The flashing on the screen could be annoying to the user.

Thanks, Steve. I’ll give this a try. In my case, I’m not even modifying the SU file - I’m just appending pages to a LO doc. The flashing shouldn’t be too annoying, as it won’t be very fast – the LO API is really slow. CB.

Update:
I’m now doing this:

        filenames.each do |filename|
            puts "filename: #{filename}"
            status = Sketchup.open_file(filename, with_status: true)
            unless (status == Sketchup::Model::LOAD_STATUS_SUCCESS || 
                    status ==  Sketchup::Model::LOAD_STATUS_SUCCESS_MORE_RECENT)
                UI.messagebox("Error loading SU file #{filename}.  Aborting.")
                return
            end
            model = Sketchup.active_model
            result = append_page_to_layout(model, doc, true)
            if result == true
                count +=1
            elsif result == IDCANCEL
                break
            end
            if Sketchup.platform == :platform_osx
                puts "We're on MacOS, so closing the file..."
                model.close
            end
        end

This works sometimes! But other times it closes the wrong window (the one where the script was first executed) and then keeps opening new windows for each file. Any ideas?

Note: If I do model.close in Windows, it behaves like File | New: It opens a blank doc with just a ThomThom. This doesn’t break the script, just slows it down. So I only do model.close if on Mac.

The inconsistency does seem odd. Looking again, I see that the Ruby API docs don’t actually say what will happen to active_model when you invoke open_file. From experience, I thought it would set it to the newly loaded model, but that was likely when the Ruby code exited shortly afterward and I saw the new file active in the GUI. The whole notion of active file is meant to deal with how the Mac GUI manages multiple open models; it is a GUI animal not really a Ruby one.

Perhaps the GUI needs to get control for a moment to change the active_model, and this is not assured when in a Ruby loop such as yours? You might try adding a UI#start_timer call right before accessing Sketchup#active_model to see whether that lets the GUI catch up.

Do you mean insert a delay? Or are you suggesting I place the call to Skethup.active_model in the proc of the start_timer method?

I mean insert a delay in which the GUI might update its state.