diff options
author | Arun Mani J <j.arunmani@proton.me> | 2024-04-06 14:34:03 +0530 |
---|---|---|
committer | Guido Günther <agx@sigxcpu.org> | 2024-04-10 08:39:38 +0200 |
commit | cc3afeceaa6c39240b621d7e00ad45519315b861 (patch) | |
tree | 2bd2d50399c6c1ae8a29eb0824c84843a6b2cb84 | |
parent | 6799c0a64ca00335ef4bbd5e38ef52e0878a01f4 (diff) |
posts: Custom plugins development
-rw-r--r-- | content/posts/custom-plugins-dev/custom-plugins.png | bin | 0 -> 53379 bytes | |||
-rw-r--r-- | content/posts/custom-plugins-dev/heart-beat-monitor-active.png | bin | 0 -> 29459 bytes | |||
-rw-r--r-- | content/posts/custom-plugins-dev/heart-beat-monitor-in-phosh.png | bin | 0 -> 37293 bytes | |||
-rw-r--r-- | content/posts/custom-plugins-dev/heart-beat-monitor-in-standalone.png | bin | 0 -> 11265 bytes | |||
-rw-r--r-- | content/posts/custom-plugins-dev/heart-beat-monitor-inactive.png | bin | 0 -> 29767 bytes | |||
-rw-r--r-- | content/posts/custom-plugins-dev/index.md | 280 | ||||
-rw-r--r-- | content/posts/custom-plugins-dev/lock-screen-plugin.png | bin | 0 -> 23817 bytes | |||
-rw-r--r-- | content/posts/custom-plugins-dev/plugin-prefs-standalone-ticket-box.png | bin | 0 -> 18135 bytes | |||
-rw-r--r-- | content/posts/custom-plugins-dev/plugin-prefs-standalone.png | bin | 0 -> 12092 bytes | |||
-rw-r--r-- | content/posts/custom-plugins-dev/plugin-prefs.png | bin | 0 -> 29131 bytes |
10 files changed, 280 insertions, 0 deletions
diff --git a/content/posts/custom-plugins-dev/custom-plugins.png b/content/posts/custom-plugins-dev/custom-plugins.png Binary files differnew file mode 100644 index 0000000..219fb68 --- /dev/null +++ b/content/posts/custom-plugins-dev/custom-plugins.png diff --git a/content/posts/custom-plugins-dev/heart-beat-monitor-active.png b/content/posts/custom-plugins-dev/heart-beat-monitor-active.png Binary files differnew file mode 100644 index 0000000..2503b65 --- /dev/null +++ b/content/posts/custom-plugins-dev/heart-beat-monitor-active.png diff --git a/content/posts/custom-plugins-dev/heart-beat-monitor-in-phosh.png b/content/posts/custom-plugins-dev/heart-beat-monitor-in-phosh.png Binary files differnew file mode 100644 index 0000000..23c9add --- /dev/null +++ b/content/posts/custom-plugins-dev/heart-beat-monitor-in-phosh.png diff --git a/content/posts/custom-plugins-dev/heart-beat-monitor-in-standalone.png b/content/posts/custom-plugins-dev/heart-beat-monitor-in-standalone.png Binary files differnew file mode 100644 index 0000000..21b12bb --- /dev/null +++ b/content/posts/custom-plugins-dev/heart-beat-monitor-in-standalone.png diff --git a/content/posts/custom-plugins-dev/heart-beat-monitor-inactive.png b/content/posts/custom-plugins-dev/heart-beat-monitor-inactive.png Binary files differnew file mode 100644 index 0000000..2a917e8 --- /dev/null +++ b/content/posts/custom-plugins-dev/heart-beat-monitor-inactive.png diff --git a/content/posts/custom-plugins-dev/index.md b/content/posts/custom-plugins-dev/index.md new file mode 100644 index 0000000..c5ff2b9 --- /dev/null +++ b/content/posts/custom-plugins-dev/index.md @@ -0,0 +1,280 @@ ++++ +authors = ["Arun Mani J"] +title = "Build Your Own Quick-Setting or Lock-Screen Widget" +date = "2024-04-10T08:39:22+02:00" +tags = [ "development", "lock-screen", "phosh", "plugins", "quick-settings" ] +images = ["posts/custom-plugins-dev/custom-plugins.png"] ++++ + +{{< image name="custom-plugins.png" title="Custom plugins in Phosh" >}} + +Phosh has support for plugins which can be used to customize and extend certain +aspects as per your liking without touching the internal source code. + +Currently Phosh supports plugins for lock-screen and quick-settings. Lock-screen +plugins appear when your phone is in locked state. Plugins here can be used to +show information that doesn't need one to unlock the screen. Examples include +emergency information, upcoming events etc. + +Quick-setting plugins are found in the quick-settings box (the one where Wi-Fi, +Bluetooth etc. can be toggled) when you drag the top-panel. Plugins here can be +used to toggle an action like activate caffeine mode. + +Read on to learn how to create a plugin and use it. + +## Plugins, Extensions - What is What? + +People usually confuse between these two words. For our usecase, an extension is +a user interface element that extends the functionality of something. A plugin +is a collection of extensions, like a package. + +As an example, suppose we have a plugin to monitor heart-beats, then it can +provide two extensions - a quick-setting to enable and disable the tracker and a +lock-screen extension to show the analytics collected so far. + +## Prerequisites + +Phosh plugins are usually written in C[^1] and are similar to typical +[Gtk](https://gtk.org) widgets. It means you should be familiar with C, Gtk and +[GLib](https://docs.gtk.org/glib/) based libraries. + +You can read our [Development Guide - Getting +Started](https://gitlab.gnome.org/World/Phosh/phosh/-/wikis/Development-Guide#getting-started) +for more information. Especially the [Running +Phosh](https://gitlab.gnome.org/World/Phosh/phosh/-/wikis/Development-Guide#running-phosh) +section as it is highly useful to test your plugins. + +## Getting Started + +With the requirements set, let us see how to develop a plugin. + +{{< notice note >}} +In this guide we will walk you through how to develop an _in-tree_ plugin. That +is, a plugin that is shipped alongside Phosh. You can also use `phosh-plugin.h` +(can be located via `pkg-config --cflags --libs phosh-plugins`) to develop plugins +without cloning Phosh repository. +{{< /notice >}} + +First you should clone the [Phosh](https://gitlab.gnome.org/World/Phosh/phosh) +repository and get it +[running](https://gitlab.gnome.org/World/Phosh/phosh#running). + +Phosh comes with a sample quick-setting plugin to give an overview of what your +plugin should contain. Head over to +[`plugins/simple-custom-quick-setting`](https://gitlab.gnome.org/World/Phosh/phosh/-/tree/main/plugins/simple-custom-quick-setting?ref_type=heads) +directory and copy it to a new name under the `plugins/` directory. + +{{< notice note >}} +If you want to create a plugin for lock-screen or both, the steps are more or +less the same. +{{< /notice >}} + +For example, if you are creating a new quick-setting plugin named `heart-beat-monitor`, +then you should have copied `plugins/simple-custom-quick-setting` to +`plugins/heart-beat-monitor`. + +Next, you should rename all occurrences of `simple-custom-quick-setting` (and +variations) with your plugin's name in the files inside `plugins/heart-beat-monitor`. + +## Plugin Files + +Let's have a short look at what each file in your plugin does. + +1. [`meson.build`](https://gitlab.gnome.org/World/Phosh/phosh/-/blob/main/plugins/simple-custom-quick-setting/meson.build?ref_type=heads) + - It is a [Meson](https://mesonbuild.com) build file. + - If your plugin has an external dependency apart from what Phosh uses, then + you should set it here. +2. [`simple-custom-quick-setting.desktop.in.in`](https://gitlab.gnome.org/World/Phosh/phosh/-/blob/main/plugins/simple-custom-quick-setting/simple-custom-quick-setting.desktop.in.in?ref_type=heads) + - This file provides the metadata of your plugin. + - You should replace `Name` and `Comment` keys with your plugin details. + - The `Types` key describes what extensions the plugin supports. Example + values are `lock-screen;`, `quick-setting;`, `lock-screen;quick-setting;`. +3. [`qs.ui`](https://gitlab.gnome.org/World/Phosh/phosh/-/blob/main/plugins/simple-custom-quick-setting/qs.ui?ref_type=heads) + - It is a + [UI](https://docs.gtk.org/gtk3/class.Builder.html#gtkbuilder-ui-definitions-builder-ui) + file. + - For a lock-screen extension, it can be any valid Gtk widget. + - However, quick-settings should stick to the structure and modify only the + properties available. +4. [`phosh-plugin-simple-custom-quick-setting.gresources.xml`](https://gitlab.gnome.org/World/Phosh/phosh/-/blob/main/plugins/simple-custom-quick-setting/phosh-plugin-simple-custom-quick-setting.gresources.xml?ref_type=heads) + - This file lists the + [resources](https://docs.gtk.org/gio/struct.Resource.html) used by your + plugin. + - One obvious resource is the UI file described above. + - If your plugin needs other resources like icons, CSS files etc. then it + should be described here. +5. [`phosh-plugin-simple-custom-quick-setting.c`](https://gitlab.gnome.org/World/Phosh/phosh/-/blob/main/plugins/simple-custom-quick-setting/phosh-plugin-simple-custom-quick-setting.c?ref_type=heads) + - This is the entry file used to describe the plugin to the loading mechanisms. + - You should include your plugin headers. + - Change `PHOSH_TYPE_SIMPLE_CUSTOM_QUICK_SETTING` to your plugin's, like `PHOSH_TYPE_HEART_BEAT_MONITOR`. + - Change the extension point to match what extensions your plugin provides. +6. [`simple-custom-quick-setting.h`](https://gitlab.gnome.org/World/Phosh/phosh/-/blob/main/plugins/simple-custom-quick-setting/simple-custom-quick-setting.h?ref_type=heads) +7. [`simple-custom-quick-setting.c`](https://gitlab.gnome.org/World/Phosh/phosh/-/blob/main/plugins/simple-custom-quick-setting/simple-custom-quick-setting.c?ref_type=heads) + - The above two files form the core of your plugin. + - Just like the UI file, if you are making a lock-screen extension, then it + can be any Gtk widget. + - For quick-settings, it should stick to the available properties. + +The above description can be confusing or vague. Worry not, have a look at the +source code of other plugins. It should give you an idea of what to replace, +what to modify etc. If you still have doubts, feel free to reach us using +[Matrix](https://im.puri.sm/#/room/#phosh:talk.puri.sm). + +If you have followed the above steps, then a quick-settings plugin for heart-beat monitoring +would have its `on_clicked` method like the below code. + +```c +static void +on_clicked (PhoshHeartBeatMonitor *self) +{ + gboolean active = phosh_quick_setting_get_active (PHOSH_QUICK_SETTING (self)); + + if (active) { + phosh_status_icon_set_icon_name (self->info, "action-unavailable-symbolic"); + phosh_status_icon_set_info (self->info, _("Heart Beat Monitor Inactive")); + /* Inform the sensor to pause monitoring… */ + } else { + phosh_status_icon_set_icon_name (self->info, "emblem-favorite-symbolic"); + phosh_status_icon_set_info (self->info, _("Heart Beat Monitor Active")); + /* Inform the sensor to start monitoring… */ + } + + phosh_quick_setting_set_active (PHOSH_QUICK_SETTING (self), !active); +} +``` + +## Testing +### Standalone Testing + +In a standalone testing, you only load the set of extensions. It is useful for a +quick testing if your plugin doesn't need Phosh to be running. + +1. Enable tools support. + +```bash +$ meson configure _build -Dtools=true +``` + +2. Compile Phosh and plugins. + +```bash +$ meson compile -C _build +``` + +3. Load the extensions. + +```bash +# For lock-screen extensions +$ G_MESSAGES_DEBUG="phosh-plugin-heart-beat-monitor" _build/tools/run_tool _build/tools/widget-box +# For quick-settings extensions +$ G_MESSAGES_DEBUG="phosh-plugin-heart-beat-monitor" _build/tools/run_tool _build/tools/custom-quick-settings +``` + +Now a window should pop-up where you can test your plugin. + +{{< image name="heart-beat-monitor-in-standalone.png" title="Heart Beat Monitor plugin loaded for standalone testing" >}} + +`G_MESSAGES_DEBUG=phosh-plugin-heart-beat-monitor` shows you the debug messages +logged by your plugin named `heart-beat-monitor`. + +### Testing with Phosh + +You should be able to test your plugin _locally_ without having to mess up your +system configuration. In the following, we locally install Phosh, set the +plugins and then run Phosh. + +1. Change the [installation + prefix](https://mesonbuild.com/Builtin-options.html). + +```bash +$ meson configure _build -Dprefix="/home/user/phosh/install/" +``` + +This asks Meson to use `/home/user/phosh/install/` as the directory to install +Phosh. Feel free to replace it with any absolute path you like. + +2. Compile and install Phosh and the plugins. + +```bash +$ meson compile -C _build +$ meson install -C _build +``` + +3. Set the plugin as enabled. + +```bash +$ GSETTINGS_SCHEMA_DIR=_build/data \ + GSETTINGS_BACKEND=keyfile \ + gsettings set sm.puri.phosh.plugins quick-settings "['heart-beat-monitor']" +``` + +We ask GSettings to enable the quick-settings plugin named `heart-beat-monitor`. +Actually, we are setting `heart-beat-monitor` as the only enabled +quick-settings. It should simplify the testing by loading only your plugin. + +For lock-screen extensions use the `lock-screen` key. + +`GSETTINGS_SCHEMA_DIR=_build/data` asks GSettings to load the schema from +`_build/data` directory. + +`GSETTINGS_BACKEND=keyfile` saves the value to +`$HOME/.config/glib-2.0/settings/keyfile` instead of messing up system settings. + +4. Run Phosh. + +```bash +$ G_MESSAGES_DEBUG=phosh-plugin-heart-beat-monitor \ + GSETTINGS_SCHEMA_DIR=_build/data \ + phoc -C /usr/share/phosh/phoc.ini \ + -E "PREFIXDIR/libexec/phosh -U" +``` + +You might have to replace `phoc -C /usr/share/phosh/phoc.ini` with your local +Phoc executable and configuration. + +`G_MESSAGES_DEBUG=phosh-plugin-heart-beat-monitor` shows you the debug messages logged by +your plugin named `heart-beat-monitor`. + +Change `PREFIXDIR` to the prefix you set in step 1. + +Now Phosh should be launched where you can test your plugin. + +{{< image name="heart-beat-monitor-in-phosh.png" title="Heart Beat Monitor plugin loaded in Phosh" >}} + +## Preferences + +Plugins can have preferences which show up in [Phosh Mobile +Settings](https://gitlab.gnome.org/World/Phosh/phosh-mobile-settings). This has +two benefits. As a plugin developer, you need not worry about making preferences +UI part of any extension (like where to place the settings button, should +preferences be a pop-up or separate application etc.). For a user, they have a +unified, standard portal to browse and configure all their plugins. + +To keep the article concise, we have decided to explain more about preferences +in a future article. But for the curious, have a look at +[`/plugins/ticket-box`](https://gitlab.gnome.org/World/Phosh/phosh/-/tree/main/plugins/ticket-box?ref_type=heads) +to get an idea of how to create preferences for your plugin. + +Similar to how we test plugins, you can test plugins using `plugin-prefs`. + +```bash +$ G_MESSAGES_DEBUG="phosh-plugin-prefs-ticket-box" _build/tools/run_tool _build/tools/plugin-prefs +``` + +This should launch a standalone that can be used to test Ticket Box plugin. + +{{< image name="plugin-prefs.png" title="Phosh plugin preferences" >}} + +## Wrapping Up + +Once your plugin is ready, you can package it and distribute it. If the plugin +is for general users, then you can open up a [merge +request](https://gitlab.gnome.org/World/Phosh/phosh/-/merge_requests) to make it +part of Phosh itself. + +## Footnotes + +[^1]: + Technically speaking, you can write it in any language as long as you can + compile to a form loadable by [GModule](https://docs.gtk.org/gmodule/). + diff --git a/content/posts/custom-plugins-dev/lock-screen-plugin.png b/content/posts/custom-plugins-dev/lock-screen-plugin.png Binary files differnew file mode 100644 index 0000000..0d8fca5 --- /dev/null +++ b/content/posts/custom-plugins-dev/lock-screen-plugin.png diff --git a/content/posts/custom-plugins-dev/plugin-prefs-standalone-ticket-box.png b/content/posts/custom-plugins-dev/plugin-prefs-standalone-ticket-box.png Binary files differnew file mode 100644 index 0000000..911ea78 --- /dev/null +++ b/content/posts/custom-plugins-dev/plugin-prefs-standalone-ticket-box.png diff --git a/content/posts/custom-plugins-dev/plugin-prefs-standalone.png b/content/posts/custom-plugins-dev/plugin-prefs-standalone.png Binary files differnew file mode 100644 index 0000000..94b83c1 --- /dev/null +++ b/content/posts/custom-plugins-dev/plugin-prefs-standalone.png diff --git a/content/posts/custom-plugins-dev/plugin-prefs.png b/content/posts/custom-plugins-dev/plugin-prefs.png Binary files differnew file mode 100644 index 0000000..feb5068 --- /dev/null +++ b/content/posts/custom-plugins-dev/plugin-prefs.png |