Skip to content

Commit

Permalink
Merge pull request #1 from cassidyjames/fullscreen
Browse files Browse the repository at this point in the history
Fullscreen: Hide HeaderBar, add Toast
  • Loading branch information
cassidyjames authored Jan 5, 2024
2 parents 786900c + 3aa964b commit aebe43a
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 28 deletions.
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

0 comments on commit aebe43a

Please sign in to comment.