SelectColor hangs in Big Sur

… and sometimes I’ve even a crash.

Hope this will be solved soon.

SelectColor is not going to be “fixed”. The modal dialog that was used was deprecated by Apple years ago for a non-modal floating palette. You’re going to need to use the non-visual control in your projects for compatibility with Big Sur and later.

Greg, I understand that the old color selector is gone and we’ve to use the non modal palette.

But something happens selecting a color: there is a noticeable delay between palette closure and color update in the IDE, and if you accidentally select any other method /object in the meanwhile you will probably have a crash.

Are you talking about in the Xojo IDE or within your application? I use an external color picker to get the HEX code and paste that into my code as using insertColor, is a frustrating experience.

In apps you can use Xojo’s colorPicker control to show and handle a color picker dialog, or with some declares or a plugin you can use Apple’s NSColorWell, which presents a button a customer can click to open the color picker.

I’m talking about selecting a color in the IDE using contextual “Insert Color…”. Very, very slow response after closing the palette.

Anyway, I’ve found a workaround that not only bypasses this annoying delay but also provides the old modal “Choose color” palette.

I’ve discovered that even in Big Sur the AppleScript command “choose color” still displays the modal color picker, so I’ve tried to implement it using a IDE script to call an AppleScript file to fire the choose color command.

This is the IDE script:

// Debug mode for print some messages
Const DebugMode as boolean = false

// Path to compiled AppleScript relative to Xojo app folder
Const AppleScriptFile as string = "/Scripts/XojoSelectColor.scpt"


Dim SelectedColor as string
Dim hexR, hexG, hexB, hexA as string
Dim intR, intG, intB, intA as integer
Dim AppleScriptPath, AppleScriptCommand as string
Dim OsascriptResult as string
Dim AppleScriptColors as string


// Get IDE selection, if any
SelectedColor = SelText


If SelectedColor.left(2) = "&c" and (SelectedColor.length = 8 OR SelectedColor.length = 10) then
  
  // Extract individual RGB vales from selection
  
  hexR = SelectedColor.middle(2,2)
  hexG = SelectedColor.middle(4,2)
  hexB = SelectedColor.middle(6,2)
  
  
  // Convert to Apple color values
  
  intR = integer.FromHex(hexR) * 257
  intG = integer.FromHex(hexG) * 257
  intB = integer.FromHex(hexB) * 257
  
end if


// Get the path to AppleScript file and normalize it
AppleScriptPath = DoShellCommand("echo ${IDE_PATH}") + AppleScriptFile
AppleScriptPath = AppleScriptPath.ReplaceAll(EndOfLine, "")
AppleScriptPath = AppleScriptPath.ReplaceAll(" ", "\ ")


// Get the final osascript command 
AppleScriptCommand= "osascript " + AppleScriptPath + " " + str(intR) + " " + str(intG) + " " + str(intB)

If DebugMode then print "AppleScript Command:" + EndOfLine + AppleScriptCommand


// Execute AppleScript
OsascriptResult = DoShellCommand(AppleScriptCommand)

If DebugMode then print "AppleScript Result:" + EndOfLine + OsascriptResult


// Result may include an osascript error alert message at begining, we've to look at last line -1

Dim aResult() as string = OsascriptResult.split(EndOfLine)
AppleScriptColors = aResult(aResult.ubound-1)


// Esc or any other error on AppleScript returns "UserCancelled" (Hard coded on AppleScript) so return
If AppleScriptColors = "UserCancelled" then return


// Extract RGB colors and convert back to hex
intR = val(AppleScriptColors.NthField(",", 1)) / 257
intG = val(AppleScriptColors.NthField(",", 2)) / 257
intB = val(AppleScriptColors.NthField(",", 3)) / 257

hexR = intR.ToHex(2)
hexG = intG.ToHex(2)
hexB = intB.ToHex(2)


// Place hex color on IDE selected text 
SelText = "&c" + hexR + hexG + hexB + "00"

And this is the AppleScript command

on run argv
	
	-- white as default
	set colorR to 255 * 257
	set colorG to 255 * 257
	set colorB to 255 * 257
	
	if (count of argv) = 3 then
		
		-- Passed RGV values
		set colorR to (item 1 of argv)
		set colorG to (item 2 of argv)
		set colorB to (item 3 of argv)
		
	end if
	
	try
		tell current application to set TheColor to choose color default color {colorR, colorG, colorB}
		return TheColor
		
	on error errStr
		return "UserCancelled"
		
	end try
	
end run

The only problem is AppleScript returns before the selected RGB values an alert osascript message that I’ve to filter. I don’t know why, maybe someone with AppleScript skills can help with this.

Now I’ve the old modal Choose Color Palette in Big Sur with Cancel/Select buttons, just calling the IDE script using option+command+1 while coding.

1 Like

Is this code only for you or do you plan to use it in a commercial app? If the latter then it’s a super bad idea to use AppleScript. Your users will get an annoying message because of the Automation security.

Beatrix, it’s only for me, to use on IDE while coding.