From 10a806e9a98dd90b0b30150a33914d1b9a148566 Mon Sep 17 00:00:00 2001 From: Toby Worland <47527939+tobyWorland@users.noreply.github.com> Date: Sat, 31 Dec 2022 23:41:36 +0000 Subject: [PATCH 1/2] Use chrome in app mode if present, else use the user's default browser --- src/plot/browser.lisp | 23 +++++++++++++++-------- src/plot/plot.lisp | 11 ++++++----- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/plot/browser.lisp b/src/plot/browser.lisp index 09ea1ca..d60d593 100644 --- a/src/plot/browser.lisp +++ b/src/plot/browser.lisp @@ -2,7 +2,7 @@ ;;; Copyright (c) 2021 by Symbolics Pte. Ltd. All rights reserved. (in-package #:plot) -;;; Helper functions to launch browers +;;; Helper functions to launch browsers ;;; Note: This experiment has shown that there is too much variability ;;; in browser behaviour to use the command line switches to control @@ -16,18 +16,24 @@ ;;; specific to each browser that is selected in the arguments to ;;; uiop:launch-program. +(deftype browser-specifier () '(member :chrome-app-mode :chrome :firefox :default)) +(declaim (type browser-specifier *default-browser-command*)) + ;;; ;;; Chrome on Linux ;;; +(defun executable-present-p (potential-executable) + "Return T if POTENTIAL-EXECUTABLE responds to --version argument" + (ignore-errors + (zerop (nth-value 2 (uiop:run-program (list potential-executable "--version")))))) + (defun find-chrome-executable-linux () "Find Chrome's executable for Linux distributions" ;; Linux distributions unfortunately do not all use the same name for chrome, ;; or there may only be chromium installed. ;; Partial list of executables: https://unix.stackexchange.com/questions/436835/universal-path-for-chrome-on-nix-systems - (find-if (lambda (potential-executable) - (ignore-errors - (zerop (nth-value 2 (uiop:run-program (list potential-executable "--version")))))) + (find-if #'executable-present-p (list "google-chrome" "chrome" "google-chrome-stable" "chromium" "chromium-browser"))) ;;; @@ -85,7 +91,7 @@ "Set the windows size in *default-browser-options*" (setf (cdr (assoc "window-size" *default-browser-options* :test 'string=)) size)) -(defparameter *default-chrome-options* +(defparameter *default-chrome-app-options* (list (cons "window-size" "800,600") ; This should probably be set in the plot JavaScript (cons "app" "foo"))) ; Run without tabs, menus, etc. "foo" ignored @@ -96,6 +102,7 @@ ;;; ;;; If passing custom options frequently, set these -(defparameter *default-browser-command* :chrome) -(defparameter *default-browser-options* *default-chrome-options*) - +(defparameter *default-browser-command* (if (executable-present-p (alexandria:assoc-value *browser-commands* :chrome)) + :chrome-app-mode + :default)) +(defparameter *default-browser-options* (when (eq *default-browser-command* :chrome-app-mode) *default-chrome-app-options*)) diff --git a/src/plot/plot.lisp b/src/plot/plot.lisp index 53627b9..020e694 100644 --- a/src/plot/plot.lisp +++ b/src/plot/plot.lisp @@ -34,13 +34,14 @@ A device could be a webserver, where a PUT operation would write the plot, locat ;; General function to open a browser to display a file (defun plot-from-file (filespec &key (browser *default-browser-command*) (browser-options *default-browser-options*)) "Open FILESPEC with browser. FILESPEC must be displayable by the browser, e.g. HTML." + (declare (type browser-specifier browser)) (let ((plot-file (namestring (truename filespec)))) #+win32 (setf plot-file (concatenate 'string "file:///" plot-file)) #+(or macos darwin linux) (setf plot-file (concatenate 'string "file://" plot-file)) - (uiop:launch-program (append (list (alexandria:assoc-value plot:*browser-commands* browser)) - (cl-ppcre:split "\\s+" (case browser - (:chrome (if (assoc "app" browser-options :test 'string=) + (uiop:launch-program (append (list (alexandria:assoc-value plot:*browser-commands* (if (eq browser :chrome-app-mode) :chrome browser))) + (cl-ppcre:split "\\s+" (if (eq browser :chrome-app-mode) + (progn (if (assoc "app" browser-options :test 'string=) (setf (cdr (assoc "app" browser-options :test 'string=)) plot-file)) - (encode-chrome-options browser-options)) - (:default plot-file)))) + (encode-chrome-options browser-options)) + plot-file))) :ignore-error-status t))) From 0c28f26fb8cf095f5a18f5bf77012b75b80f6f89 Mon Sep 17 00:00:00 2001 From: Toby Worland <47527939+tobyWorland@users.noreply.github.com> Date: Sun, 1 Jan 2023 02:07:40 +0000 Subject: [PATCH 2/2] Support selecting Firefox and Chrome in non-app mode --- src/plot/browser.lisp | 22 +++++++++++++++++----- src/plot/plot.lisp | 10 +++++----- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/plot/browser.lisp b/src/plot/browser.lisp index d60d593..72ce9f9 100644 --- a/src/plot/browser.lisp +++ b/src/plot/browser.lisp @@ -65,14 +65,15 @@ ;; Chrome arg-format: "--~A=~A" ;; Firefox: "-~A ~A" (declare (special arg-format)) - (format nil "~{~/plot::%print-alist/~^ ~}" options)) + (when options + (format nil "~{~/plot::%print-alist/~^ ~}" options))) ;;; ;;; Chrome ;;; -(defun encode-chrome-options (options) +(defun encode-chrome-app-options (options app-url) "Encode command line options for Chrome" ;; We want to add a --user-data-directory so that --windows-size is honoured ;; --app, if present, will have been set by the caller @@ -83,19 +84,30 @@ (merge-pathnames "chrome-data" (translate-logical-pathname #P"PLOT:TEMP;"))) (cons "no-default-browser-check" 1) - (cons "no-first-run" 1)) + (cons "no-first-run" 1) + (cons "app" app-url)) ; Run without tabs, menus, etc. options))) (encode-application-options chrome-options "--~A=~A"))) +(defun encode-chrome-options (options url) + "Encode command line options for Chrome" + (concatenate 'string (encode-application-options options "--~A=~A") " " url)) + (defun set-chrome-size (size) "Set the windows size in *default-browser-options*" (setf (cdr (assoc "window-size" *default-browser-options* :test 'string=)) size)) (defparameter *default-chrome-app-options* - (list (cons "window-size" "800,600") ; This should probably be set in the plot JavaScript - (cons "app" "foo"))) ; Run without tabs, menus, etc. "foo" ignored + (list (cons "window-size" "800,600"))) ; This should probably be set in the plot JavaScript +;;; +;;; Firefox +;;; +(defun encode-firefox-options (options url) + "Encode command line options for Firefox" + ;; We have to be careful with large spaces as Firefox seems to misinterpret them as multiple urls + (format nil "~@[~A ~]~A" (encode-application-options options "-~A ~A") url)) ;;; ;;; Set global defaults. diff --git a/src/plot/plot.lisp b/src/plot/plot.lisp index 020e694..2221efc 100644 --- a/src/plot/plot.lisp +++ b/src/plot/plot.lisp @@ -39,9 +39,9 @@ A device could be a webserver, where a PUT operation would write the plot, locat #+win32 (setf plot-file (concatenate 'string "file:///" plot-file)) #+(or macos darwin linux) (setf plot-file (concatenate 'string "file://" plot-file)) (uiop:launch-program (append (list (alexandria:assoc-value plot:*browser-commands* (if (eq browser :chrome-app-mode) :chrome browser))) - (cl-ppcre:split "\\s+" (if (eq browser :chrome-app-mode) - (progn (if (assoc "app" browser-options :test 'string=) - (setf (cdr (assoc "app" browser-options :test 'string=)) plot-file)) - (encode-chrome-options browser-options)) - plot-file))) + (cl-ppcre:split "\\s+" (case browser + (:chrome-app-mode (encode-chrome-app-options browser-options plot-file)) + (:chrome (encode-chrome-options browser-options plot-file)) + (:firefox (encode-firefox-options browser-options plot-file)) + (t plot-file)))) :ignore-error-status t)))