Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fullscreen: Hide HeaderBar, add Toast #1

Merged
merged 3 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
[![Flathub](https://img.shields.io/flathub/v/com.cassidyjames.butler?logo=flathub&logoColor=white&style=for-the-badge)][flathub]
[![Installs](https://img.shields.io/flathub/downloads/com.cassidyjames.butler?label=Installs&logo=flathub&logoColor=white&style=for-the-badge)][flathub]

![Icon](data/icons/app.svg?raw=true)

# Butler for Home Assistant

**Control your smart home**

![Screenshot](https://raw.githubusercontent.com/cassidyjames/butler/1.0.0/data/screenshots/light.png)
![Screenshot](data/screenshots/light.png)

Hybrid native + web app for Home Assistant. Butler wraps your Home Assistant dashboard up in a native UI, integrating better with your OS. Native features include:

Expand All @@ -17,8 +22,21 @@ Other features include:
- Pinch-to-zoom
- Set the scaling with Ctrl+Plus/Minus or Ctrl+0 to reset

## Made for GNOME

Butler is designed and developed on and for GNOME. As such, contributors agree to abide by the [GNOME Code of Conduct](https://wiki.gnome.org/Foundation/CodeOfConduct).

<a href='https://flathub.org/apps/details/com.cassidyjames.butler'><img width='196' alt='Download on Flathub' src='https://flathub.org/assets/badges/flathub-badge-en.svg'/></a>

## Why not a web browser or PWA?

I don't love the state of web apps and PWAs on Linux; I prefer GNOME Web or Firefox, but the former doesn't truly support PWAs (just web apps with not-that-lightweight of a UI) and the latter doesn't support PWAs on the desktop at all. So, I made this dumb little web wrapper to give myself a bit more integrated of an experience.

If there's more interest in making this into a better-integrated companion app for Linux, I welcome contributions!

## Developing and Building

I recommend using GNOME Builder for development.

[flathub]: https://flathub.org/apps/details/com.cassidyjames.butler

1 change: 1 addition & 0 deletions com.cassidyjames.butler.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
{
"name" : "butler",
"buildsystem" : "meson",
"run-tests": true,
"sources" : [
{
"type" : "dir",
Expand Down
5 changes: 5 additions & 0 deletions data/gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
<summary>Home Assistant server URL</summary>
<description>URL for the Home Assistant server; must include protocol and custom ports</description>
</key>
<key name="window-fullscreened" type="b">
<default>false</default>
<summary>Window fullscreened</summary>
<description>Whether the window was fullscreened on last run</description>
</key>
<key name="window-maximized" type="b">
<default>false</default>
<summary>Window maximized</summary>
Expand Down
57 changes: 46 additions & 11 deletions data/metainfo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,90 @@
<!-- Copyright 2024 Cassidy James Blaede <[email protected]> -->
<component type="desktop">
<id>com.cassidyjames.butler</id>
<name>Butler for Home Assistant</name>
<summary>Control your smart home</summary>
<metadata_license>CC-BY-SA-4.0</metadata_license>
<project_license>GPL-3.0-or-later</project_license>

<name>Butler for Home Assistant</name>
<summary>Control your smart home</summary>
<developer_name translatable="no">Cassidy James Blaede</developer_name>
<developer id="cassidyjames.com">
<name translatable="no">Cassidy James Blaede</name>
</developer>
<description>
<p>Hybrid native + web app for Home Assistant. Butler wraps your Home Assistant dashboard up in a native UI, integrating better with your OS. Native features include:</p>
<ul>
<li>Icon in your App Grid, Applications Menu, Dash, Dock, etc.</li>
<li>Native header bar</li>
<li>Save and restore current view and size when closed and re-opened</li>
<li>Two-finger swipe and mouse button support to go back/forward between views</li>
<li>Cross-desktop light/dark style support for GNOME, elementary OS, etc.</li>
<li>Cross-desktop light/dark style support (if supported by your Lovelace theme)</li>
</ul>
<p>Other features include:</p>
<ul>
<li>Pinch-to-zoom</li>
<li>Set the scaling with Ctrl+Plus/Minus or Ctrl+0 to reset</li>
<li>Fullscreen from the menu, a keyboard shortcut, or a GSetting to better support kiosk use cases</li>
</ul>
<p>Note WebRTC camera streams (i.e. used by some newer Nest cameras) are not currently supported.</p>
</description>

<provides>
<binary>com.cassidyjames.butler</binary>
</provides>
<launchable type="desktop-id">com.cassidyjames.butler.desktop</launchable>

<branding>
<color type="primary">#03a9f5</color>
</branding>

<recommends>
<display_length compare="ge">360</display_length>
<display_length compare="ge">300</display_length>
</recommends>
<supports>
<control>pointing</control>
<control>keyboard</control>
<control>touch</control>
</supports>

<screenshots>
<screenshot type="default">
<image>https://raw.githubusercontent.com/cassidyjames/butler/1.0.0/data/screenshots/light.png</image>
<caption>Home Assistant dashboard with many rooms and devices</caption>
</screenshot>
</screenshots>

<releases>
<release version="1.0.0" date="2024-01-03">
<release version="1.0.1" date="2024-01-05">
<description>
<p>Improved accessibility and fullscreen experience</p>
<ul>
<li>Hide header bar when fullscreen</li>
<li>Remember fullscreen state</li>
<li>Remind how to exit fullscreen</li>
<li>Add access keys (mnemonics) for better accessibility</li>
</ul>
</description>
<issues>
<issue url="https://github.com/cassidyjames/butler/issues/12">Hide header bar when fullscreen</issue>
<issue url="https://github.com/cassidyjames/butler/issues/3">Remember fullscreen state</issue>
<issue url="https://github.com/cassidyjames/butler/issues/6">Remind how to exit fullscreen</issue>
<issue url="https://github.com/cassidyjames/butler/issues/7">Add access keys (mnemonics) for better accessibility</issue>
</issues>
</release>
<release version="1.0.0" date="2024-01-04">
<description>
<p>Initial release</p>
</description>
</release>
</releases>
<screenshots>
<screenshot type="default">
<image>https://raw.githubusercontent.com/cassidyjames/butler/1.0.0/data/screenshots/light.png</image>
</screenshot>
</screenshots>

<content_rating type="oars-1.1">
<content_attribute id="social-info">mild</content_attribute>
</content_rating>
<developer_name>Cassidy James Blaede</developer_name>

<url type="homepage">https://cassidyjames.com</url>
<url type="bugtracker">https://github.com/cassidyjames/butler/issues</url>
<url type="vcs-browser">https://github.com/cassidyjames/butler</url>
<url type="donation">https://cassidyjames.com/pay</url>
<url type="help">https://cassidyjames.com/support</url>
</component>
4 changes: 2 additions & 2 deletions data/style.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@define-color headerbar_bg_color #03A9F5;
@define-color headerbar_bg_color #03a9f5;
@define-color headerbar_fg_color #fff;
@define-color headerbar_border_color #fff;
@define-color headerbar_backdrop_color mix(@headerbar_bg_color, @window_bg_color, 0.2);
@define-color headerbar_backdrop_color mix(@headerbar_bg_color, @window_bg_color, 0.1);

@define-color accent_color @headerbar_bg_color;
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
project(
'com.cassidyjames.butler',
'vala', 'c',
version: '1.0.0'
version: '1.0.1'
)

gnome = import('gnome')
Expand Down
51 changes: 38 additions & 13 deletions src/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
*/

public class Butler.MainWindow : Adw.ApplicationWindow {
public Adw.Toast fullscreen_toast;
public Adw.ToastOverlay toast_overlay;
public Gtk.Revealer header_revealer;

private const GLib.ActionEntry[] ACTION_ENTRIES = {
{ "toggle_fullscreen", toggle_fullscreen },
{ "set_server", on_set_server_activate },
Expand All @@ -26,12 +30,15 @@ public class Butler.MainWindow : Adw.ApplicationWindow {
}

construct {
maximized = App.settings.get_boolean ("window-maximized");
fullscreened = App.settings.get_boolean ("window-fullscreened");

var site_menu = new Menu ();
site_menu.append (_("_Log Out…"), "win.log_out");

var app_menu = new Menu ();
// TODO: How do I add shortcuts to the menu?
app_menu.append (_("Toggle _Fullscreen"), "win.toggle_fullscreen");
app_menu.append (_("_Fullscreen"), "win.toggle_fullscreen");
app_menu.append (_("Change _Server…"), "win.set_server");
app_menu.append (_("_About %s").printf (App.NAME), "win.about");

Expand All @@ -48,6 +55,16 @@ public class Butler.MainWindow : Adw.ApplicationWindow {
var header = new Adw.HeaderBar ();
header.pack_end (menu_button);

header_revealer = new Gtk.Revealer () {
child = header,
reveal_child = !fullscreened
};

fullscreen_toast = new Adw.Toast ("Press <b>Ctrl F</b> or <b>F11</b> to toggle fullscreen") {
action_name = "win.toggle_fullscreen",
button_label = _("Exit _Fullscreen")
};

web_view = new Butler.WebView ();

string server = App.settings.get_string ("server");
Expand All @@ -73,11 +90,15 @@ public class Butler.MainWindow : Adw.ApplicationWindow {
stack.add_named (status_page, "loading");
stack.add_named (web_view, "web");

toast_overlay = new Adw.ToastOverlay () {
child = stack
};

var grid = new Gtk.Grid () {
orientation = Gtk.Orientation.VERTICAL
};
grid.attach (header, 0, 0);
grid.attach (stack, 0, 1);
grid.attach (header_revealer, 0, 0);
grid.attach (toast_overlay, 0, 1);

set_content (grid);

Expand All @@ -86,14 +107,11 @@ public class Butler.MainWindow : Adw.ApplicationWindow {

set_default_size (window_width, window_height);

if (App.settings.get_boolean ("window-maximized")) {
maximize ();
}

close_request.connect (() => {
save_window_state ();
return Gdk.EVENT_PROPAGATE;
});
notify["fullscreened"].connect (save_window_state);
notify["maximized"].connect (save_window_state);

web_view.load_changed.connect ((load_event) => {
Expand All @@ -111,9 +129,12 @@ public class Butler.MainWindow : Adw.ApplicationWindow {
}

private void save_window_state () {
if (maximized) {
if (fullscreened) {
App.settings.set_boolean ("window-fullscreened", true);
} else if (maximized) {
App.settings.set_boolean ("window-maximized", true);
} else {
App.settings.set_boolean ("window-fullscreened", false);
App.settings.set_boolean ("window-maximized", false);
App.settings.set (
"window-size", "(ii)",
Expand Down Expand Up @@ -178,8 +199,12 @@ public class Butler.MainWindow : Adw.ApplicationWindow {
public void toggle_fullscreen () {
if (fullscreened) {
unfullscreen ();
header_revealer.set_reveal_child (true);
fullscreen_toast.dismiss ();
} else {
fullscreen ();
header_revealer.set_reveal_child (false);
toast_overlay.add_toast (fullscreen_toast);
}
}

Expand All @@ -202,12 +227,12 @@ public class Butler.MainWindow : Adw.ApplicationWindow {
default_response = "save",
extra_child = server_entry,
};
server_dialog.add_response ("close", "Cancel");
server_dialog.add_response ("close", "_Cancel");

server_dialog.add_response ("demo", _("Reset to Demo"));
server_dialog.add_response ("demo", _("_Reset to Demo"));
server_dialog.set_response_appearance ("demo", Adw.ResponseAppearance.DESTRUCTIVE);

server_dialog.add_response ("save", _("Set Server"));
server_dialog.add_response ("save", _("_Set Server"));
server_dialog.set_response_appearance ("save", Adw.ResponseAppearance.SUGGESTED);

server_dialog.present ();
Expand Down Expand Up @@ -243,8 +268,8 @@ public class Butler.MainWindow : Adw.ApplicationWindow {
body_use_markup = true,
default_response = "log_out"
};
log_out_dialog.add_response ("close", "Stay Logged In");
log_out_dialog.add_response ("log_out", _("Log Out"));
log_out_dialog.add_response ("close", "_Stay Logged In");
log_out_dialog.add_response ("log_out", _("_Log Out"));
log_out_dialog.set_response_appearance ("log_out", Adw.ResponseAppearance.DESTRUCTIVE);

log_out_dialog.present ();
Expand Down
15 changes: 15 additions & 0 deletions src/Widgets/WebView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ public class Butler.WebView : WebKit.WebView {
hardware_acceleration_policy = WebKit.HardwareAccelerationPolicy.ALWAYS
};

var custom_css = new WebKit.UserStyleSheet (
"""
header,
.header {
app-region: drag;
-webkit-app-region: drag;
}
""",
WebKit.UserContentInjectedFrames.TOP_FRAME,
WebKit.UserStyleLevel.AUTHOR,
null,
null
);
user_content_manager.add_style_sheet (custom_css);

settings = webkit_settings;
web_context = new WebKit.WebContext ();

Expand Down
Loading