コンテクストメニューからAppleScriptを実行するツール「Service Station」を連日こづき回していろいろ試しています。
その中で、Service StationではScript実行をGUIなしの補助プログラムからosascriptコマンドを経由してAppleScriptを実行しているために、AppleScript中でNSAlertによるダイアログ表示をおこなった際に、ダイアログが最前面に表示されないという問題が生じていました。
これを見たedama2さんから、強制的にNSAlertダイアログを最前面に表示させるコードを提供していただいたので、実際にテストに用いたAppleScriptに入れたものをご紹介します。
▲そのまま普通にNSAlertダイアログを表示させたところ。Service Stationによるコンテクストメニューから実行すると、最前面に表示されないという問題があった
▲edama2さんからもたらされたコードを追加したNSAlertダイアログ。Service Stationから実行しても、問題なく最前面に表示される
コードは2行、効き目はばっちり!
--Move to frontmost (By edama2) current application's NSApplication's sharedApplication()'s setActivationPolicy:(current application's NSApplicationActivationPolicyRegular) current application's NSApp's activateIgnoringOtherApps:(true)
副作用として、Dockにターミナルのアイコンが表示され、最前面のアプリケーションが「osascript」になってしまいますが、気にならないところでしょう。
Program Name | Name of runtime | Support AppleScript document format | AS Format | NSAlert dialog is displayed in frontmost | Can use GUI Scripting functions | Can call AppleScript Libraries? | Can call AS Library including Frameworks? | Can call Generic Cocoa Functions? | Can use Cocoa system notification functions? |
Service Station | osascript | Script/Text Script/Applet | Script/Text Script | No-> Yes | Yes | Yes | No | Yes | No |
Script Menu | osascript | Script/Scriptd/Applet | Script/Scriptd | Yes | Yes | Yes | No | Yes | Yes |
Shortcuts Events | MacHelper | File Embedded Script | Text | Yes | Yes | Yes | No | Yes | No |
Switch Control | Assistive Control | File Embedded Script | Script (archived) | Yes | Yes | No | No | Yes | No |
FastScript 3 | FastScripts Script Runner | Script/Scriptd/Applet | Script/Scriptd | Yes | Yes | Yes | No | Yes |
あれ? edama2さんのおかげで、Service Stationの弱点が1つなくなりましたよ。Service Stationについては、
(1)「Kind–> Script」「AppleScript」でテキストで書いた「.applescript」しかピックアップできないとかいう気の狂ったようなRulesの仕様は要・修正
(2)実行Scriptにフラットな.scptとテキストの.applescriptしか実行できないのはダメ。バンドル形式の.scptdの実行サポートは必須
(3)大量のAppleScriptをコンテクストメニューに入れると使い勝手が落ちるので、Rulesでもう少しこまかく条件付けできるとよさそう。ただし必須ではない
といったところでしょうか。
AppleScript名:Webダイアログ表示(強制最前面).scpt |
use AppleScript version "2.4" use scripting additions use framework "Foundation" my serviceStationDidSelect("", "", "") on serviceStationDidSelect(targetedURL, selectedItemURLs, menuKind) set aList to {{label:"TEST1", value:403}, {label:"TEST2", value:301}, {label:"TEST3", value:101}, {label:"TEST4", value:65}} set bList to sortRecListByLabel(aList, {"value"}, {false}) of me –降順ソート –https://www.amcharts.com/demos/pie-chart/ set myStr to retHTML() of me set jsonStr to array2DToJSONArray(bList) of me as string set aString to current application’s NSString’s stringWithFormat_(myStr, jsonStr) as string set paramObj to {myMessage:"Simple Pie Chart", mySubMessage:"This is a AMCharts test", htmlStr:aString, viewSize:{1000, 550}} my webD’s displayWebDialog(paramObj) end serviceStationDidSelect on array2DToJSONArray(aList) set anArray to current application’s NSMutableArray’s arrayWithArray:aList set jsonData to current application’s NSJSONSerialization’s dataWithJSONObject:anArray options:(0 as integer) |error|:(missing value) set resString to current application’s NSString’s alloc()’s initWithData:jsonData encoding:(current application’s NSUTF8StringEncoding) return resString end array2DToJSONArray –リストに入れたレコードを、指定の属性ラベルの値でソート on sortRecListByLabel(aRecList as list, aLabelStr as list, ascendF as list) set aArray to current application’s NSArray’s arrayWithArray:aRecList set aCount to length of aLabelStr set sortDescArray to current application’s NSMutableArray’s new() repeat with i from 1 to aCount set aLabel to (item i of aLabelStr) set aKey to (item i of ascendF) set sortDesc to (current application’s NSSortDescriptor’s alloc()’s initWithKey:aLabel ascending:aKey) (sortDescArray’s addObject:sortDesc) end repeat return (aArray’s sortedArrayUsingDescriptors:sortDescArray) as list end sortRecListByLabel script webD — – Created by: Takaaki Naganoya – Created on: 2020/06/20 — – Copyright © 2020 Piyomaru Software, All Rights Reserved — use AppleScript use framework "Foundation" use framework "AppKit" use framework "WebKit" use scripting additions property parent : AppleScript property |NSURL| : a reference to current application’s |NSURL| property NSAlert : a reference to current application’s NSAlert property NSString : a reference to current application’s NSString property NSButton : a reference to current application’s NSButton property WKWebView : a reference to current application’s WKWebView property WKUserScript : a reference to current application’s WKUserScript property NSURLRequest : a reference to current application’s NSURLRequest property NSRunningApplication : a reference to current application’s NSRunningApplication property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding property WKUserContentController : a reference to current application’s WKUserContentController property WKWebViewConfiguration : a reference to current application’s WKWebViewConfiguration property WKUserScriptInjectionTimeAtDocumentEnd : a reference to current application’s WKUserScriptInjectionTimeAtDocumentEnd property returnCode : 0 on displayWebDialog(paramObj) my performSelectorOnMainThread:"browseStrWebContents:" withObject:(paramObj) waitUntilDone:true end displayWebDialog on browseStrWebContents:paramObj set aMainMes to myMessage of paramObj as string set aSubMes to mySubMessage of paramObj as string set htmlString to (htmlStr of paramObj) as string –set jsDelimList to (jsDelimiters of paramObj) as list set webSize to (viewSize of paramObj) as list copy webSize to {aWidth, aHeight} –WebViewをつくる set aConf to WKWebViewConfiguration’s alloc()’s init() set aWebView to WKWebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight)) configuration:aConf aWebView’s setNavigationDelegate:me aWebView’s setUIDelegate:me aWebView’s setTranslatesAutoresizingMaskIntoConstraints:true using terms from scripting additions set bURL to |NSURL|’s fileURLWithPath:(POSIX path of (path to me)) end using terms from aWebView’s loadHTMLString:htmlString baseURL:(bURL) –Move to frontmost (By edama2) current application’s NSApplication’s sharedApplication()’s setActivationPolicy:(current application’s NSApplicationActivationPolicyRegular) current application’s NSApp’s activateIgnoringOtherApps:(true) — set up alert set theAlert to NSAlert’s alloc()’s init() tell theAlert its setMessageText:aMainMes its setInformativeText:aSubMes its addButtonWithTitle:"OK" –its addButtonWithTitle:"Cancel" its setAccessoryView:aWebView set myWindow to its |window| end tell — show alert in modal loop NSRunningApplication’s currentApplication()’s activateWithOptions:0 my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true if (my returnCode as number) = 1001 then error number -128 ##後始末 aWebView’s stopLoading() set js to "window.open(’about:blank’,’_self’).close();" aWebView’s evaluateJavaScript:js completionHandler:(missing value) set aWebView to missing value end browseStrWebContents: on doModal:aParam set (my returnCode) to (aParam’s runModal()) as number end doModal: on viewDidLoad:aNotification return true end viewDidLoad: on fetchJSSourceString(aURL) set jsURL to |NSURL|’s URLWithString:aURL set jsSourceString to NSString’s stringWithContentsOfURL:jsURL encoding:(NSUTF8StringEncoding) |error|:(missing value) return jsSourceString end fetchJSSourceString on pickUpFromToStr(aStr as string, s1Str as string, s2Str as string) using terms from scripting additions set a1Offset to offset of s1Str in aStr if a1Offset = 0 then return false set bStr to text (a1Offset + (length of s1Str)) thru -1 of aStr set a2Offset to offset of s2Str in bStr if a2Offset = 0 then return false set cStr to text 1 thru (a2Offset – (length of s2Str)) of bStr return cStr as string end using terms from end pickUpFromToStr –リストを任意のデリミタ付きでテキストに on retArrowText(aList, aDelim) using terms from scripting additions set aText to "" set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to aDelim set aText to aList as text set AppleScript’s text item delimiters to curDelim return aText end using terms from end retArrowText on array2DToJSONArray(aList) set anArray to current application’s NSMutableArray’s arrayWithArray:aList set jsonData to current application’s NSJSONSerialization’s dataWithJSONObject:anArray options:(0 as integer) |error|:(missing value) –0 is set resString to current application’s NSString’s alloc()’s initWithData:jsonData encoding:(current application’s NSUTF8StringEncoding) return resString end array2DToJSONArray on parseByDelim(aData, aDelim) using terms from scripting additions set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to aDelim set dList to text items of aData set AppleScript’s text item delimiters to curDelim return dList end using terms from end parseByDelim end script on retHTML() return "<!doctype html> <head> <meta charset=\"utf-8\"> <!– Styles –> <style> body { background-color: #000000; color: #ffffff; } #chartdiv { width: 100%; height: 500px; } </style> <!– Resources –> <!– Chart code –> // Themes begin // Create chart instance // Add data // Add and configure Series // This creates initial animation chart.hiddenState.properties.radius = am4core.percent(0); }); // end am4core.ready() <!– HTML –> end retHTML |