On every Gnome Shell desktop there is a main panel at the top of the screen. Usually, the panel shows the current time, the WiFi signal, the speaker volume, the power button, and the activity startup button. There can be many other things on the panel as individual user penchants. The panel will not be covered by anything, and will be there at all time except when there is a full-screen application running. The Gnome community has decided that the whole humanity needs the panel.
What little things of texts and icons on the panel are called Gnome Shell extensions. Each of them is a kind of a desktop application which always run through out a user session. They can be personalized.
We are going to create a simple and useless application that shows a running counter, something like the one that shows '1473' on the panel image above. It can be a starting point for a bigger and productive application. But before we begin let's get familiar with a collection of handy Gnome tools.
Gnome Command Dialog
On a Gnome Shell desktop, press Alt-F2. A dialog box will appear for us to enter a Gnome command. We can simply press Esc to exit the dialog, or to exit any Gnome dialog for that matter.
Gnome Looking Glass
Press Alt-F2 and key in lg (small L and small G) into the field and press Enter. The Gnome Looking Glass dialog will open. The Evaluator field at the bottom of the dialog will evaluate any Gnome Javascript (gjs) expression.
Click on Extensions at the top right corner of the dialog. It will show the list of existing extensions. We want our application to be in the list.
Restarting Gnome Shell Desktop
During our development we will need to restart the Gnome Shell desktop. Press Alt-F2 and enter r. The desktop will take a moment to restart. Don't worry. All our windows will still be there. We need to restart the desktop every time we make changes so that the desktop will reload our application.
Gnome Tweak Tool
We can tweak Gnome Shell according to our liking. But most importantly we need a tool to enable or disable our application. Press Alt-F2 and enter gnome-tweak-tool. The Gnome Tweak Tool dialog will open. On the left hand side menu, click Extensions. The list of extensions will appear. We can enable or disable any extension, or we can remove any of them.
We may need to install the Gnome Tweak Tool:
$ sudo apt install gnome-tweak-tool
Debugging
Before we start programming we need a method to debug. Gnome Shell keeps activity log including error messages. Messages related to our application will also appear in the log. Gnome Shell log can be monitored from a terminal. Execute the following command. It will print existing messages in the log and wait for new messages:
$ sudo journalctl /usr/bin/gnome-session -f
Our application can post messages into the log with the following command. We can also log debugging messages:
global.log("Application message");
Generate a Hello, world! Extension
Gnome Shell has a tool to create a new extension. Execute the following command:
$ gnome-shell-extension-tool --create-extension
We will be asked to give the new extension a name, description and uuid. Let's assume the details are as follows:
- name : Counter
- description : A useless counter
- uuid : counter@me.useless.com
const St = imports.gi.St;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
let text, button;
function _hideHello() {
Main.uiGroup.remove_actor(text);
text = null;
}
function _showHello() {
if (!text) {
text = new St.Label({ style_class: 'helloworld-label', text: "Hello, world!" });
Main.uiGroup.add_actor(text);
}
text.opacity = 255;
let monitor = Main.layoutManager.primaryMonitor;
text.set_position(monitor.x + Math.floor(monitor.width / 2 - text.width / 2),
monitor.y + Math.floor(monitor.height / 2 - text.height / 2));
Tweener.addTween(text,
{ opacity: 0,
time: 2,
transition: 'easeOutQuad',
onComplete: _hideHello });
}
function init() {
button = new St.Bin({ style_class: 'panel-button',
reactive: true,
can_focus: true,
x_fill: true,
y_fill: false,
track_hover: true });
let icon = new St.Icon({ icon_name: 'system-run-symbolic',
style_class: 'system-status-icon' });
button.set_child(icon);
button.connect('button-press-event', _showHello);
}
function enable() {
Main.panel._rightBox.insert_child_at_index(button, 0);
}
function disable() {
Main.panel._rightBox.remove_child(button);
}
~/.local/share/gnome-shell/extensions/
Useless Counter
let icon = new St.Icon({ icon_name: 'system-run-symbolic',
style_class: 'system-status-icon' });
button.set_child(icon);
button.connect('button-press-event', _showHello);
label = new St.Label({text: "Counter"});
button.set_child(label);
button.connect('button-press-event', _showHello);
let label;
$ sudo apt-get install gtk-3-examples
$ gtk3-icon-browser
function refresh() {
label.set_text(count.toString());
++count;
if (timeout != null)
Mainloop.source_remove(timeout);
timeout = Mainloop.timeout_add_seconds(10, refresh);
return true;
}
let timeout;
const Mainloop = imports.mainloop;
refresh();
if (timeout != null)
Mainloop.source_remove(timeout);
Comments
Post a Comment