portalHelper: Stop using a subtitle
The pattern has become a lot less common, not least indicated by the removal of the HeaderBar:subtitle property. And in this case we are including an icon in the subtitle, which looks completely out of place. Address this by moving the URL/security information into a popover menu, inspired by the similar drop-down in GNOME Web. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2690>
This commit is contained in:
parent
d796244fb1
commit
7a4055ec92
@ -1,10 +1,9 @@
|
|||||||
/* exported main */
|
/* exported main */
|
||||||
imports.gi.versions.Pango = '1.0';
|
|
||||||
imports.gi.versions.Gtk = '4.0';
|
imports.gi.versions.Gtk = '4.0';
|
||||||
imports.gi.versions.WebKit = '6.0';
|
imports.gi.versions.WebKit = '6.0';
|
||||||
|
|
||||||
const Gettext = imports.gettext;
|
const Gettext = imports.gettext;
|
||||||
const {Gio, GLib, GObject, Gtk, Pango, WebKit} = imports.gi;
|
const {Gio, GLib, GObject, Gtk, WebKit} = imports.gi;
|
||||||
|
|
||||||
const _ = Gettext.gettext;
|
const _ = Gettext.gettext;
|
||||||
|
|
||||||
@ -37,72 +36,69 @@ const CONNECTIVITY_RECHECK_RATELIMIT_TIMEOUT = 30 * GLib.USEC_PER_SEC;
|
|||||||
|
|
||||||
const HelperDBusInterface = loadInterfaceXML('org.gnome.Shell.PortalHelper');
|
const HelperDBusInterface = loadInterfaceXML('org.gnome.Shell.PortalHelper');
|
||||||
|
|
||||||
var PortalHeaderBar = GObject.registerClass(
|
var PortalSecurityButton = GObject.registerClass(
|
||||||
class PortalHeaderBar extends Gtk.HeaderBar {
|
class PortalSecurityButton extends Gtk.MenuButton {
|
||||||
_init() {
|
_init() {
|
||||||
super._init();
|
const popover = new Gtk.Popover();
|
||||||
|
|
||||||
|
super._init({
|
||||||
|
popover,
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
|
||||||
// See ephy-title-box.c in epiphany for the layout
|
|
||||||
const vbox = new Gtk.Box({
|
const vbox = new Gtk.Box({
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
valign: Gtk.Align.CENTER,
|
margin_top: 6,
|
||||||
spacing: 0,
|
margin_bottom: 6,
|
||||||
|
margin_start: 6,
|
||||||
|
margin_end: 6,
|
||||||
|
spacing: 6,
|
||||||
});
|
});
|
||||||
this.set_title_widget(vbox);
|
popover.set_child(vbox);
|
||||||
|
|
||||||
/* TRANSLATORS: this is the title of the wifi captive portal login window */
|
|
||||||
const titleLabel = new Gtk.Label({
|
|
||||||
label: _('Hotspot Login'),
|
|
||||||
wrap: false,
|
|
||||||
single_line_mode: true,
|
|
||||||
ellipsize: Pango.EllipsizeMode.END,
|
|
||||||
});
|
|
||||||
titleLabel.add_css_class('title');
|
|
||||||
vbox.append(titleLabel);
|
|
||||||
|
|
||||||
const hbox = new Gtk.Box({
|
const hbox = new Gtk.Box({
|
||||||
orientation: Gtk.Orientation.HORIZONTAL,
|
orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
spacing: 4,
|
|
||||||
halign: Gtk.Align.CENTER,
|
halign: Gtk.Align.CENTER,
|
||||||
valign: Gtk.Align.BASELINE,
|
|
||||||
});
|
});
|
||||||
hbox.add_css_class('subtitle');
|
|
||||||
vbox.append(hbox);
|
vbox.append(hbox);
|
||||||
|
|
||||||
this._lockImage = new Gtk.Image({
|
this._secureIcon = new Gtk.Image();
|
||||||
valign: Gtk.Align.BASELINE,
|
hbox.append(this._secureIcon);
|
||||||
});
|
|
||||||
hbox.append(this._lockImage);
|
|
||||||
|
|
||||||
this.subtitleLabel = new Gtk.Label({
|
this._secureIcon.bind_property('icon-name',
|
||||||
wrap: false,
|
this, 'icon-name',
|
||||||
single_line_mode: true,
|
GObject.BindingFlags.DEFAULT);
|
||||||
ellipsize: Pango.EllipsizeMode.END,
|
|
||||||
valign: Gtk.Align.BASELINE,
|
this._titleLabel = new Gtk.Label();
|
||||||
selectable: true,
|
this._titleLabel.add_css_class('title');
|
||||||
|
hbox.append(this._titleLabel);
|
||||||
|
|
||||||
|
this._descriptionLabel = new Gtk.Label({
|
||||||
|
wrap: true,
|
||||||
|
max_width_chars: 32,
|
||||||
});
|
});
|
||||||
this.subtitleLabel.add_css_class('subtitle');
|
vbox.append(this._descriptionLabel);
|
||||||
hbox.append(this.subtitleLabel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setSubtitle(label) {
|
setPopoverTitle(label) {
|
||||||
this.subtitleLabel.set_text(label);
|
this._titleLabel.set_text(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSecurityIcon(securityLevel) {
|
setSecurityIcon(securityLevel) {
|
||||||
switch (securityLevel) {
|
switch (securityLevel) {
|
||||||
case PortalHelperSecurityLevel.NOT_YET_DETERMINED:
|
case PortalHelperSecurityLevel.NOT_YET_DETERMINED:
|
||||||
this._lockImage.hide();
|
this.hide();
|
||||||
break;
|
break;
|
||||||
case PortalHelperSecurityLevel.SECURE:
|
case PortalHelperSecurityLevel.SECURE:
|
||||||
this._lockImage.show();
|
this.show();
|
||||||
this._lockImage.set_from_icon_name('channel-secure-symbolic');
|
this._secureIcon.icon_name = 'channel-secure-symbolic';
|
||||||
this._lockImage.set_tooltip_text(null);
|
this._descriptionLabel.label = _('Your connection seems to be secure');
|
||||||
break;
|
break;
|
||||||
case PortalHelperSecurityLevel.INSECURE:
|
case PortalHelperSecurityLevel.INSECURE:
|
||||||
this._lockImage.show();
|
this.show();
|
||||||
this._lockImage.set_from_icon_name('channel-insecure-symbolic');
|
this._secureIcon.icon_name = 'channel-insecure-symbolic';
|
||||||
this._lockImage.set_tooltip_text(_('Your connection to this hotspot login is not secure. Passwords or other information you enter on this page can be viewed by people nearby.'));
|
this._descriptionLabel.label =
|
||||||
|
_('Your connection to this hotspot login is not secure. Passwords or other information you enter on this page can be viewed by people nearby.');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,11 +107,16 @@ class PortalHeaderBar extends Gtk.HeaderBar {
|
|||||||
var PortalWindow = GObject.registerClass(
|
var PortalWindow = GObject.registerClass(
|
||||||
class PortalWindow extends Gtk.ApplicationWindow {
|
class PortalWindow extends Gtk.ApplicationWindow {
|
||||||
_init(application, url, timestamp, doneCallback) {
|
_init(application, url, timestamp, doneCallback) {
|
||||||
super._init({application});
|
super._init({
|
||||||
|
application,
|
||||||
|
title: _('Hotspot Login'),
|
||||||
|
});
|
||||||
|
|
||||||
this._headerBar = new PortalHeaderBar();
|
const headerbar = new Gtk.HeaderBar();
|
||||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.NOT_YET_DETERMINED);
|
this._secureMenu = new PortalSecurityButton();
|
||||||
this.set_titlebar(this._headerBar);
|
headerbar.pack_start(this._secureMenu);
|
||||||
|
|
||||||
|
this.set_titlebar(headerbar);
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
url = CONNECTIVITY_CHECK_URI;
|
url = CONNECTIVITY_CHECK_URI;
|
||||||
@ -157,11 +158,16 @@ class PortalWindow extends Gtk.ApplicationWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_syncUri() {
|
_syncUri() {
|
||||||
let uri = this._webView.uri;
|
const {uri} = this._webView;
|
||||||
if (uri)
|
|
||||||
this._headerBar.setSubtitle(GLib.uri_unescape_string(uri, null));
|
try {
|
||||||
else
|
const [, , host] = GLib.Uri.split_network(uri, HTTP_URI_FLAGS);
|
||||||
this._headerBar.setSubtitle('');
|
this._secureMenu.setPopoverTitle(host);
|
||||||
|
} catch (e) {
|
||||||
|
if (uri != null)
|
||||||
|
console.error(`Failed to parse Uri ${uri}: ${e.message}`);
|
||||||
|
this._secureMenu.setPopoverTitle('');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
@ -179,24 +185,24 @@ class PortalWindow extends Gtk.ApplicationWindow {
|
|||||||
|
|
||||||
_onLoadChanged(view, loadEvent) {
|
_onLoadChanged(view, loadEvent) {
|
||||||
if (loadEvent === WebKit.LoadEvent.STARTED) {
|
if (loadEvent === WebKit.LoadEvent.STARTED) {
|
||||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.NOT_YET_DETERMINED);
|
this._secureMenu.setSecurityIcon(PortalHelperSecurityLevel.NOT_YET_DETERMINED);
|
||||||
} else if (loadEvent === WebKit.LoadEvent.COMMITTED) {
|
} else if (loadEvent === WebKit.LoadEvent.COMMITTED) {
|
||||||
let tlsInfo = this._webView.get_tls_info();
|
let tlsInfo = this._webView.get_tls_info();
|
||||||
let ret = tlsInfo[0];
|
let ret = tlsInfo[0];
|
||||||
let flags = tlsInfo[2];
|
let flags = tlsInfo[2];
|
||||||
if (ret && flags === 0)
|
if (ret && flags === 0)
|
||||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.SECURE);
|
this._secureMenu.setSecurityIcon(PortalHelperSecurityLevel.SECURE);
|
||||||
else
|
else
|
||||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
this._secureMenu.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onInsecureContentDetected() {
|
_onInsecureContentDetected() {
|
||||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
this._secureMenu.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onLoadFailedWithTlsErrors(view, failingURI, certificate, _errors) {
|
_onLoadFailedWithTlsErrors(view, failingURI, certificate, _errors) {
|
||||||
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
this._secureMenu.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||||
let uri = GLib.Uri.parse(failingURI, HTTP_URI_FLAGS);
|
let uri = GLib.Uri.parse(failingURI, HTTP_URI_FLAGS);
|
||||||
this._webContext.allow_tls_certificate_for_host(certificate, uri.get_host());
|
this._webContext.allow_tls_certificate_for_host(certificate, uri.get_host());
|
||||||
this._webView.load_uri(failingURI);
|
this._webView.load_uri(failingURI);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user