From 07b10b15b1502becec549ae7ae7ea8ae922f7412 Mon Sep 17 00:00:00 2001 From: Martin Kolman Date: Wed, 12 Jul 2023 13:50:04 +0200 Subject: [PATCH] webui: Add Firefox theme for use on Live media The theme upstream is here: https://github.com/garrett/firefox-theme-frame Its main aim is to shape the Firefox window to the most suitable state on Live images: - has a header bar for window switching - has no tab/status/URL bars - has no browser controls As Firefox needs the profile folder to be writable, we need to copy the profile template to a writable directory & use that as the profile path for Firefox. We also need to make sure profile folders from previous runs (possible on Live) are cleaned up. To simplify things, we also use the same theme on non Live images for now, with the expectation that a tweaked theme will provided later. --- anaconda.spec.in | 9 ++++ pyanaconda/ui/webui/__init__.py | 12 ++++- ui/webui/Makefile.am | 4 +- .../default/chrome/userChrome.css | 16 +++++++ ui/webui/firefox-theme/default/user.js | 47 +++++++++++++++++++ .../firefox-theme/live/chrome/userChrome.css | 16 +++++++ ui/webui/firefox-theme/live/user.js | 47 +++++++++++++++++++ ui/webui/webui-desktop | 23 ++++++++- 8 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 ui/webui/firefox-theme/default/chrome/userChrome.css create mode 100644 ui/webui/firefox-theme/default/user.js create mode 100644 ui/webui/firefox-theme/live/chrome/userChrome.css create mode 100644 ui/webui/firefox-theme/live/user.js diff --git a/anaconda.spec.in b/anaconda.spec.in index b062d841b7a..14a69be9f41 100644 --- a/anaconda.spec.in +++ b/anaconda.spec.in @@ -441,6 +441,15 @@ rm -rf \ %{_datadir}/cockpit/anaconda-webui/manifest.json %{_datadir}/metainfo/org.cockpit-project.anaconda-webui.metainfo.xml %{_datadir}/cockpit/anaconda-webui/po.*.js.gz +%dir %{_datadir}/anaconda/firefox-theme +%dir %{_datadir}/anaconda/firefox-theme/default +%dir %{_datadir}/anaconda/firefox-theme/default/chrome +%{_datadir}/anaconda/firefox-theme/default/user.js +%{_datadir}/anaconda/firefox-theme/default/chrome/userChrome.css +%dir %{_datadir}/anaconda/firefox-theme/live +%dir %{_datadir}/anaconda/firefox-theme/live/chrome +%{_datadir}/anaconda/firefox-theme/live/user.js +%{_datadir}/anaconda/firefox-theme/live/chrome/userChrome.css %{_libexecdir}/webui-desktop %files gui diff --git a/pyanaconda/ui/webui/__init__.py b/pyanaconda/ui/webui/__init__.py index d18dee95fdf..8a32fccc7d5 100644 --- a/pyanaconda/ui/webui/__init__.py +++ b/pyanaconda/ui/webui/__init__.py @@ -23,9 +23,12 @@ from pyanaconda.core.util import startProgram from pyanaconda.anaconda_loggers import get_module_logger from pyanaconda.core.threads import thread_manager +from pyanaconda.core.configuration.anaconda import conf log = get_module_logger(__name__) +FIREFOX_THEME_DEFAULT = "default" +FIREFOX_THEME_LIVE = "live" class CockpitUserInterface(ui.UserInterface): """This is the main class for Cockpit user interface.""" @@ -107,8 +110,15 @@ def run(self): # This is read by cockpit-desktop and makes it launch Firefox in kiosk mode # instead of the GTK WebKit based web view it launches by default. + # FIXME: looks like "type" should not be used and _is_live_os is private ? + if conf.system.provides_liveuser: + profile_name = FIREFOX_THEME_LIVE + else: + profile_name = FIREFOX_THEME_DEFAULT + proc = startProgram(["/usr/libexec/webui-desktop", - "/cockpit/@localhost/anaconda-webui/index.html"], + "/cockpit/@localhost/anaconda-webui/index.html", + profile_name], reset_lang=False) log.debug("cockpit web view has been started") with open("/run/anaconda/webui_script.pid", "w") as f: diff --git a/ui/webui/Makefile.am b/ui/webui/Makefile.am index fa96a421784..df90d6fec38 100644 --- a/ui/webui/Makefile.am +++ b/ui/webui/Makefile.am @@ -56,11 +56,13 @@ rsync: install-data-hook: $(WEBPACK_TEST) mkdir -p $(DESTDIR)/usr/share/cockpit/$(PACKAGE_NAME) cp -r dist/* $(DESTDIR)/usr/share/cockpit/$(PACKAGE_NAME) + mkdir -p $(DESTDIR)/usr/share/anaconda + cp -r firefox-theme $(DESTDIR)/usr/share/anaconda/ mkdir -p $(DESTDIR)/usr/share/metainfo/ cp org.cockpit-project.$(PACKAGE_NAME).metainfo.xml $(DESTDIR)/usr/share/metainfo/ cp webui-desktop $(DESTDIR)/usr/libexec/ -EXTRA_DIST = dist src +EXTRA_DIST = dist src firefox-theme # checkout common files from Cockpit repository required to build this project; # this has no API stability guarantee, so check out a stable tag when you start diff --git a/ui/webui/firefox-theme/default/chrome/userChrome.css b/ui/webui/firefox-theme/default/chrome/userChrome.css new file mode 100644 index 00000000000..1b8eff3ced1 --- /dev/null +++ b/ui/webui/firefox-theme/default/chrome/userChrome.css @@ -0,0 +1,16 @@ +/* Hide things we're not going to use when there's only 1 tab */ +:has(#tabbrowser-tabs tab:only-of-type) :is(#tab-notification-deck, #PersonalToolbar, #statuspanel) { + display: none; +} + +/* When there's 1 tab, ajdust the minimum tab height */ +#tabbrowser-tabs:has(tab:only-of-type) { + --tab-min-height: auto; +} + +/* Hide the tab and unfocused nav bars for 1 tab */ +#tabbrowser-tabs :is(tab:only-of-type, tab:only-of-type ~ *), +#tabbrowser-tabs:has(tab:only-of-type) + #alltabs-button, +#titlebar:has(#tabbrowser-tabs tab:only-of-type) + #nav-bar:not(:focus-within) { + visibility: collapse; +} diff --git a/ui/webui/firefox-theme/default/user.js b/ui/webui/firefox-theme/default/user.js new file mode 100644 index 00000000000..e995bc9e349 --- /dev/null +++ b/ui/webui/firefox-theme/default/user.js @@ -0,0 +1,47 @@ +// Let us use userChrome.css +user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true); + +// We want to use :has() +user_pref("layout.css.has-selector.enabled", true); + +// New windows, not tabs +user_pref("browser.link.open_newwindow", 2); +user_pref("browser.link.open_newwindow.restriction", 1); +user_pref("browser.link.open_newwindow.override.external", 2); + +// Dev stuff (for easier UI adusting with ctrl+shift+alt+i) +user_pref("browser.aboutConfig.showWarning", false); +user_pref("devtools.chrome.enabled", true); +user_pref("devtools.debugger.remote-enabled", true); +user_pref("devtools.inspector.showUserAgentStyles", true); + +// Don't have any startup page +user_pref("browser.startup.page", 0); +user_pref("browser.startup.homepage", "about:blank"); +user_pref("browser.startup.homepage_override.once", {}); + +// Use a window manager titlebar +user_pref("browser.tabs.inTitlebar", 0); + +// Hide the bookmarks +user_pref("browser.toolbars.bookmarks.visibility", "never"); + +// Don't show anything special in the new tab page' +user_pref("browser.newtabpage.activity-stream.default.sites", ""); +user_pref("browser.newtabpage.activity-stream.showSponsored", false); +user_pref("browser.newtabpage.activity-stream.showSponsoredTopSites", false); + +// Remove UI stuff +user_pref("browser.uiCustomization.state", "{\"placements\":{\"widget-overflow-fixed-list\":[],\"unified-extensions-area\":[],\"nav-bar\":[\"back-button\",\"forward-button\",\"stop-reload-button\",\"urlbar-container\",\"downloads-button\",\"unified-extensions-button\"],\"toolbar-menubar\":[\"menubar-items\"],\"TabsToolbar\":[\"tabbrowser-tabs\",\"alltabs-button\"],\"PersonalToolbar\":[\"personal-bookmarks\"]},\"seen\":[\"save-to-pocket-button\",\"developer-button\"],\"dirtyAreaCache\":[\"nav-bar\",\"TabsToolbar\",\"toolbar-menubar\",\"PersonalToolbar\"],\"currentVersion\":19,\"newElementCount\":3}"); + +// Don't set a placeholder for the tab before the page loads and sets title +user_pref("browser.urlbar.placeholderName", ""); + +// Turn off calling home +user_pref("app.normandy.enabled", false); +user_pref("browser.discovery.enabled", false); +user_pref("datareporting.healthreport.uploadEnabled", false); +user_pref("datareporting.policy.dataSubmissionEnabled", false); +user_pref("toolkit.telemetry.unified", false); +user_pref("trailhead.firstrun.didSeeAboutWelcome", true); + diff --git a/ui/webui/firefox-theme/live/chrome/userChrome.css b/ui/webui/firefox-theme/live/chrome/userChrome.css new file mode 100644 index 00000000000..1b8eff3ced1 --- /dev/null +++ b/ui/webui/firefox-theme/live/chrome/userChrome.css @@ -0,0 +1,16 @@ +/* Hide things we're not going to use when there's only 1 tab */ +:has(#tabbrowser-tabs tab:only-of-type) :is(#tab-notification-deck, #PersonalToolbar, #statuspanel) { + display: none; +} + +/* When there's 1 tab, ajdust the minimum tab height */ +#tabbrowser-tabs:has(tab:only-of-type) { + --tab-min-height: auto; +} + +/* Hide the tab and unfocused nav bars for 1 tab */ +#tabbrowser-tabs :is(tab:only-of-type, tab:only-of-type ~ *), +#tabbrowser-tabs:has(tab:only-of-type) + #alltabs-button, +#titlebar:has(#tabbrowser-tabs tab:only-of-type) + #nav-bar:not(:focus-within) { + visibility: collapse; +} diff --git a/ui/webui/firefox-theme/live/user.js b/ui/webui/firefox-theme/live/user.js new file mode 100644 index 00000000000..e995bc9e349 --- /dev/null +++ b/ui/webui/firefox-theme/live/user.js @@ -0,0 +1,47 @@ +// Let us use userChrome.css +user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true); + +// We want to use :has() +user_pref("layout.css.has-selector.enabled", true); + +// New windows, not tabs +user_pref("browser.link.open_newwindow", 2); +user_pref("browser.link.open_newwindow.restriction", 1); +user_pref("browser.link.open_newwindow.override.external", 2); + +// Dev stuff (for easier UI adusting with ctrl+shift+alt+i) +user_pref("browser.aboutConfig.showWarning", false); +user_pref("devtools.chrome.enabled", true); +user_pref("devtools.debugger.remote-enabled", true); +user_pref("devtools.inspector.showUserAgentStyles", true); + +// Don't have any startup page +user_pref("browser.startup.page", 0); +user_pref("browser.startup.homepage", "about:blank"); +user_pref("browser.startup.homepage_override.once", {}); + +// Use a window manager titlebar +user_pref("browser.tabs.inTitlebar", 0); + +// Hide the bookmarks +user_pref("browser.toolbars.bookmarks.visibility", "never"); + +// Don't show anything special in the new tab page' +user_pref("browser.newtabpage.activity-stream.default.sites", ""); +user_pref("browser.newtabpage.activity-stream.showSponsored", false); +user_pref("browser.newtabpage.activity-stream.showSponsoredTopSites", false); + +// Remove UI stuff +user_pref("browser.uiCustomization.state", "{\"placements\":{\"widget-overflow-fixed-list\":[],\"unified-extensions-area\":[],\"nav-bar\":[\"back-button\",\"forward-button\",\"stop-reload-button\",\"urlbar-container\",\"downloads-button\",\"unified-extensions-button\"],\"toolbar-menubar\":[\"menubar-items\"],\"TabsToolbar\":[\"tabbrowser-tabs\",\"alltabs-button\"],\"PersonalToolbar\":[\"personal-bookmarks\"]},\"seen\":[\"save-to-pocket-button\",\"developer-button\"],\"dirtyAreaCache\":[\"nav-bar\",\"TabsToolbar\",\"toolbar-menubar\",\"PersonalToolbar\"],\"currentVersion\":19,\"newElementCount\":3}"); + +// Don't set a placeholder for the tab before the page loads and sets title +user_pref("browser.urlbar.placeholderName", ""); + +// Turn off calling home +user_pref("app.normandy.enabled", false); +user_pref("browser.discovery.enabled", false); +user_pref("datareporting.healthreport.uploadEnabled", false); +user_pref("datareporting.policy.dataSubmissionEnabled", false); +user_pref("toolkit.telemetry.unified", false); +user_pref("trailhead.firstrun.didSeeAboutWelcome", true); + diff --git a/ui/webui/webui-desktop b/ui/webui/webui-desktop index 3df4c8ca462..498b7fc4f76 100755 --- a/ui/webui/webui-desktop +++ b/ui/webui/webui-desktop @@ -39,7 +39,6 @@ set -eu # exec_prefix= is set because the default /usr/libexec contains "${exec_prefix}" exec_prefix="/usr" libexecdir="/usr/libexec" - if [ -z "${1:-}" ]; then echo "Usage: $0 [ssh host]" >&2 exit 1 @@ -61,7 +60,27 @@ case "$1" in ;; esac -BROWSER="/usr/bin/firefox --kiosk" +# prepare empty firefox profile dir with theme based on the passed profile id +FIREFOX_THEME_DIR="/usr/share/anaconda/firefox-theme" +FIREFOX_PROFILE_PATH="/tmp/anaconda-firefox-profile" +THEME_ID=$2 + +# make sure the profile directory exists and is empty +if [ -d ${FIREFOX_PROFILE_PATH} ] +then + echo "Cleaning up existing Anaconda Firefox profile directory." + rm -rf ${FIREFOX_PROFILE_PATH} +fi +mkdir -p ${FIREFOX_PROFILE_PATH} + +# populate the profile directory with our custom Firefox theme +# - theme id is passed as the second argument of this script +THEME_PATH="${FIREFOX_THEME_DIR}/${THEME_ID}" + +cp -a "${THEME_PATH}/." ${FIREFOX_PROFILE_PATH} + +# FIXME: is this hardcoded resolution necessary ? +BROWSER="/usr/bin/firefox --new-instance --window-size 1024,768 --profile ${FIREFOX_PROFILE_PATH}" # start browser in a temporary home dir, so that it does not interfere with your real one BROWSER_HOME=$(mktemp --directory --tmpdir cockpit.desktop.XXXXXX)