Tool Cursor not Loded on MacOSX

Hi all,

For some tools that I’ve written, I’m loading a specific cursor icon. Everything always runs fine on Windows but some of the tools icons doesn’t load on MacOSX, I just get the bascic arrow icon without any ruby console error message…

Here is the code I’m running in the activate method of the tools:.

def activate
  # Grab tool cursor icon file
  tool_cursor_file = File.dirname(__FILE__) + "/images/cursor_drawing.png"
   
  # Create the cursor if it doesn't exists yet
  if @@cursor_id.nil?
    @@cursor_id = UI.create_cursor(tool_cursor_file, 4, 27)
  end
end

What is really strange is that for the same code on two different tools it works for one and doesn’t for another.

So I’ve started the check the icon file but I can’t find differences, both are 24x24px, are RGB 8bits png files BUT when, for a tool that doesn’t load the icon, I’m switching the images it works. That means the problem is linked to the image use.

So MacOSX seems to be more sensitive than Windows to the file encoding type. Does anyone knows what are the recommanded cursor image settings ?

Is there something else that I’m missing ?

Thanks for your help.

Jérémie

Assorted thoughts:

I have found that SU on the Mac is fussy about the png image files used for cursors. In particular, it will sometimes silently reject a file that was created on Windows. I’ve never figured out why, but the fix can be as simple as opening the image in a Mac image editor and then saving it to a new name. I’ve never found the reverse to be true: a Mac png has always worked on Windows SU.

The preferred file format changed as of SU 2016 when scalable images were enabled, so for 2016 and 2017 on Mac the preferred form is pdf (on Windows it is svg). But for older versions you still need to use png.

I have also found that SU on the Mac sometimes delays showing a Tool’s cursor until the first user-click after the Tool is activated. Some of my Tools do this, and others show the cursor every time, with no pattern that I can find in the Tool code to explain the difference. Typically this happens only the first time the Tool is used in a SU session, so I suspect it has something to do with OS X caching the cursor, but I’ve never found a workaround. I just warn users it may happen…

Finally, in the code snippet you shared you never invoked UI.set_cursor(). I believe that has to be done somewhere in your Tool (typically in the onSetCursor callback), merely calling UI.create_cursor() is not sufficient.

1 Like

Each tool class MUST have this callback (so the SketchUp engine can call it, whenever it thinks the cursor needs to be changed.)

def onSetCursor
  # You would set your cursor here.
  UI.set_cursor(@@cursor_id)
end

You could just go ahead and create the cursor at load time, near the top of your Tool class:

@@cursor_id ||= UI.create_cursor(
  File.join(File.dirname(__FILE__),"/images/cursor_drawing.png"),
  4, 27
)

… and then the cursor will be ready whenever the tool is activated.

(Ie, there will be no delay because there will be no slow string manipulation in the activate() callback.)

As an alternative to what @DanRathbun showed, I usually create the cursor as a class constant at the top of the file (same principle, different mechanism). Here’s a sample with the branching code to handle all releases of SketchUp:

      if(Sketchup.version.to_i >= 16)
        if(RUBY_PLATFORM =~ /darwin/)
          IN_ICON =  File.join(IMGPATH, 'inside.pdf') unless defined? IN_ICON
          OUT_ICON =  File.join(IMGPATH, 'outside.pdf') unless defined? OUT_ICON
        else
          IN_ICON =  File.join(IMGPATH, 'inside.svg') unless defined? IN_ICON
          OUT_ICON =  File.join(IMGPATH, 'outside.svg') unless defined? OUT_ICON
        end
      else
        IN_ICON =  File.join(IMGPATH, 'interior2.png') unless defined? IN_ICON
        OUT_ICON =  File.join(IMGPATH, 'exterior2.png') unless defined? OUT_ICON
      end

      IN_CURSOR = UI::create_cursor(IN_ICON, 0, 31) unless defined? IN_CURSOR
      OUT_CURSOR = UI::create_cursor(OUT_ICON, 0, 31) unless defined? OUT_CURSOR

I have also noticed issues similar to @slbaumgartner. For Sketchup versions needing “png” files, I suggest using a resultion of 32x32 only. At least keep it square, and keep the resolution to an intregral power of 2.

Hi all,

Thanks for your feedbacks.

For sure I’m using the onSetCursor Method either it wouldn’t work anywhere. As I said it’s working on Windows but not on MacOSX. Here is the onSetCursor code I’m using, this is exactly the same that Dan shared :

def onSetCursor
  UI.set_cursor(@@cursor_id)
end

Anyway thanks slbaumgartner for sharing your experience, I’ll try to open and save the icons on MacOSX, either I’ll move to vector cursors.

Again, thank for all the answers.

Jérémie

Hi Bruce,

That what I’m doing recentlty, I’m now much more using 32px images instead of 24px images. I tried that too for my actual problem but it didn’t worked better…

Thanks for your suggestion.

Jérémie

I have no luck on macOS no matter what I try (I haven’t yet tested on Windows). The onSetCursor method is not even getting called… Any reason as to why this is happening? I even shrank the image from 128x128 to 32x32 and still no luck. Even tried a pdf from an existing tool and that doesn’t work either. I’m so disappointed… :frowning:

Update: I’ve tested using the LineTool from Github and the cursor does indeed change according to the image I supply. However, my Tool is activated when opening a HtmlDialog, like this:

UI.menu("Plugins").add_item("My Item") {
  dialog = UI::HtmlDialog.new(...)

  Sketchup.active_model.tools.push_tool(MyTool.new)
  dialog.set_on_closed { Sketchup.active_model.tools.pop_tool }
}

Why is this causing onSetCursor to not get called? Callbacks like onLButtonDown or draw work as expected…

I wonder if the HTMLDialog is getting focus and that is preventing your cursor from being shown? What happens if you click in the model view?

I discovered what was happening: first, I accidentally put 2 versions of onSetCursor inside my Tool class; secondly, the puts instruction I added prevented the cursor from showing up when clicking in the model view (just me trying to debug things). I removed the printing line and everything is now smooth.

Now I hope that my code will also work on Windows :sweat_smile:.

Console IO is slow … ie, using puts. Callbacks for UI like onSetCursor and command validation procs can get called very often. They should have a minimum of statements and code.

It’s a good lesson learned.

You’ll need a SVG cursor for Windows platform.

1 Like