Skip to content
Draft
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
94 changes: 94 additions & 0 deletions daemon/IBus/IBusCandidateWindow.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright 2026 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Authored by: Leonhard Kargl <leo.kargl@proton.me>
*/

public class Gala.Daemon.IBusCandidateWindow : Gtk.Window {
public IBus.PanelService service { get; construct; }

private Gtk.Label preedit_text;
private Gtk.Label auxiliary_text;

public IBusCandidateWindow (IBus.PanelService service) {
Object (service: service);
}

construct {
preedit_text = new Gtk.Label (null) {
visible = false,
};

auxiliary_text = new Gtk.Label (null) {
visible = false,
};

var content_box = new Granite.Box (VERTICAL);
content_box.append (preedit_text);
content_box.append (auxiliary_text);

default_width = 200;
default_height = 200;

child = content_box;
title = "IBUS_CANDIDATE";

service.show_preedit_text.connect (on_show_preedit_text);
service.hide_preedit_text.connect (on_hide_preedit_text);
service.update_preedit_text.connect (on_update_preedit_text);
service.show_auxiliary_text.connect (on_show_auxiliary_text);
service.hide_auxiliary_text.connect (on_hide_auxiliary_text);
service.update_auxiliary_text.connect (on_update_auxiliary_text);
service.set_cursor_location.connect ((x, y, width, height) => {
warning ("Set location: %d, %d, %d, %d", x, y, width, height);
});
service.set_cursor_location_relative.connect ((x, y, width, height) => {
warning ("Set location: %d, %d, %d, %d", x, y, width, height);
});
}

private void update_visibility () {
var is_visible = preedit_text.visible || auxiliary_text.visible;

if (is_visible) {
present ();
} else {
hide ();
}
}

private void on_show_preedit_text () {
preedit_text.visible = true;
update_visibility ();
}

private void on_hide_preedit_text () {
preedit_text.visible = false;
update_visibility ();
}

private void on_update_preedit_text (IBus.Text text, uint cursor_pos, bool visible) {
preedit_text.visible = visible;
preedit_text.label = text.text;

update_visibility ();
}

private void on_show_auxiliary_text () {
auxiliary_text.visible = true;
update_visibility ();
}

private void on_hide_auxiliary_text () {
auxiliary_text.visible = false;
update_visibility ();
}

private void on_update_auxiliary_text (IBus.Text text, bool visible) {
auxiliary_text.visible = visible;
auxiliary_text.label = text.text;

update_visibility ();
}
}
39 changes: 39 additions & 0 deletions daemon/IBus/IBusService.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2026 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Authored by: Leonhard Kargl <leo.kargl@proton.me>
*/

public class Gala.Daemon.IBusService : Object {
private IBus.Bus bus;
private IBus.PanelService service;
private IBusCandidateWindow candidate_window;

construct {
bus = new IBus.Bus.async ();
bus.connected.connect (on_connected);
}

private void on_connected () {
bus.request_name_async.begin (
IBus.SERVICE_PANEL, IBus.BusNameFlag.REPLACE_EXISTING, -1, null,
on_name_acquired
);
}

private void on_name_acquired (Object? obj, AsyncResult res) {
try {
bus.request_name_async_finish (res);
} catch (Error e) {
warning ("Failed to acquire bus name: %s", e.message);
return;
}

/* We need to go over Object.new because we need to pass construct properties */
service = (IBus.PanelService) Object.@new (typeof (IBus.PanelService), "connection", bus.get_connection (), "object-path", IBus.PATH_PANEL);
service.focus_in.connect (() => warning ("Focus in"));
service.update_lookup_table.connect (() => warning ("Update lookup table"));
candidate_window = new IBusCandidateWindow (service);
}
}
6 changes: 6 additions & 0 deletions daemon/Main.vala
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@
*/

public class Gala.Daemon.Application : Gtk.Application {
private IBusService ibus_service;

public Application () {
Object (application_id: "org.pantheon.gala.daemon");
}

construct {
ibus_service = new IBusService ();
}

public override void startup () {
base.startup ();

Expand Down
4 changes: 3 additions & 1 deletion daemon/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ gala_daemon_sources = files(
'MonitorLabel.vala',
'Window.vala',
'WindowMenu.vala',
'IBus' / 'IBusService.vala',
'IBus' / 'IBusCandidateWindow.vala'
)

gtk4_dep = dependency('gtk4')
Expand All @@ -16,6 +18,6 @@ executable(
gala_common_enums,
config_header,
gala_resources,
dependencies: [gtk4_dep, granite7_dep],
dependencies: [gtk4_dep, granite7_dep, ibus_dep],
install: true
)
3 changes: 2 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ gio_unix_dep = dependency('gio-unix-2.0', version: '>= @0@'.format(glib_version_
gmodule_dep = dependency('gmodule-2.0')
gee_dep = dependency('gee-0.8')
gnome_desktop_dep = dependency('gnome-desktop-4')
ibus_dep = dependency('ibus-1.0')
gnome_bg_dep = dependency('gnome-bg-4')
m_dep = cc.find_library('m', required: false)
posix_dep = vala.find_library('posix', required: false)
Expand Down Expand Up @@ -171,7 +172,7 @@ endif
add_project_arguments(vala_flags, language: 'vala')
add_project_link_arguments(['-Wl,-rpath,@0@'.format(mutter_typelib_dir)], language: 'c')

gala_base_dep = [atk_bridge_dep, gdk_pixbuf_def, gtk4_dep, glib_dep, gobject_dep, gio_dep, gio_unix_dep, gmodule_dep, gee_dep, mutter_dep, gnome_desktop_dep, gnome_bg_dep, m_dep, posix_dep, sqlite3_dep, xext_dep]
gala_base_dep = [atk_bridge_dep, gdk_pixbuf_def, gtk4_dep, glib_dep, gobject_dep, gio_dep, gio_unix_dep, gmodule_dep, gee_dep, mutter_dep, gnome_desktop_dep, gnome_bg_dep, ibus_dep, m_dep, posix_dep, sqlite3_dep, xext_dep]

if get_option('systemd')
gala_base_dep += systemd_dep
Expand Down
5 changes: 5 additions & 0 deletions src/DaemonManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class Gala.DaemonManager : GLib.Object {
client = new ManagedClient (display, args);

client.window_created.connect ((window) => {
client.wayland_client.make_dock (window);
window.shown.connect (handle_daemon_window);
});
}
Expand Down Expand Up @@ -71,6 +72,10 @@ public class Gala.DaemonManager : GLib.Object {
window.make_above ();
window.stick ();
break;

case "IBUS_CANDIDATE":
ShellClientsManager.get_instance ().make_ibus_candidate_window (window);
break;
}
}

Expand Down
Loading
Loading