feat: add virtual keyboard ui
This commit is contained in:
parent
4da1db3bd4
commit
8020954fed
@ -71,7 +71,7 @@ dm_src = [
|
||||
|
||||
buil_dep = [gtk, gtk_layer_shell, wayland_client, xkbcommon]
|
||||
|
||||
session_resource = gnome.compile_resources('session-resources','resources/session-shell/gresource.xml')
|
||||
session_resource = gnome.compile_resources('session-resources','resources/gresource-session.xml')
|
||||
|
||||
executable(
|
||||
'diya-shell',
|
||||
@ -85,7 +85,7 @@ login_src = [
|
||||
'src/login.c'
|
||||
]
|
||||
|
||||
login_resource = gnome.compile_resources('login-resources','resources/login-shell/gresource.xml')
|
||||
login_resource = gnome.compile_resources('login-resources','resources/gresource-login.xml')
|
||||
|
||||
executable(
|
||||
'diya-login-shell',
|
||||
|
1461
resources/default-full.keymap
Normal file
1461
resources/default-full.keymap
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
9
resources/gresource-login.xml
Normal file
9
resources/gresource-login.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/dev/iohub/diya/shell">
|
||||
<file alias="login-shell.css">resources/login-shell.css</file>
|
||||
<file alias="virtual-keyboard.css">resources/virtual-keyboard.css</file>
|
||||
<file alias="default.keymap">resources/default.keymap</file>
|
||||
<!--file alias="virtuail-keyboard.ui">resources/ui/virtual-keyboard.ui</file-->
|
||||
</gresource>
|
||||
</gresources>
|
11
resources/login-shell.css
Normal file
11
resources/login-shell.css
Normal file
@ -0,0 +1,11 @@
|
||||
@import url("resource:///dev/iohub/diya/shell/virtual-keyboard.css");
|
||||
|
||||
.diya-login-header {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.diya-login-status {
|
||||
font-size: 12px;
|
||||
color: red;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/dev/iohub/diya/shell">
|
||||
<file alias="login-shell.css">resources/login-shell/login-shell.css</file>
|
||||
<file alias="default.keymap">resources/default.keymap</file>
|
||||
</gresource>
|
||||
</gresources>
|
@ -1,9 +0,0 @@
|
||||
.header {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.status {
|
||||
font-size: 12px;
|
||||
color: red;
|
||||
}
|
38
resources/virtual-keyboard.css
Normal file
38
resources/virtual-keyboard.css
Normal file
@ -0,0 +1,38 @@
|
||||
.diya-vkb
|
||||
{
|
||||
background-color: transparent;
|
||||
border: 1px solid orangered;
|
||||
}
|
||||
|
||||
.diya-vkb-btn {
|
||||
background-color: white;
|
||||
border: 1px solid #CDC7C2;
|
||||
border-radius: 3px;
|
||||
min-width: 20px;
|
||||
/*min-height: 30px;*/
|
||||
}
|
||||
|
||||
.diya-vkb-btn:hover
|
||||
{
|
||||
background-color: #E7E6E2;
|
||||
}
|
||||
/*
|
||||
.diya-vkb-btn label {
|
||||
border: 1px solid #b81f2b;
|
||||
}*/
|
||||
|
||||
.diya-vkb-btn-level-1 {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.diya-vkb-btn-level-2 {
|
||||
color: gray;
|
||||
font-size: 10px;
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
||||
.diya-vkb-btn-level-3 {
|
||||
color: gray;
|
||||
font-size: 10px;
|
||||
padding-right: 3px;
|
||||
}
|
@ -37,10 +37,12 @@ static void diya_foreign_window_dispose(GObject* object)
|
||||
if(self->appid)
|
||||
{
|
||||
g_free(self->appid);
|
||||
self->appid = NULL;
|
||||
}
|
||||
if(self->title)
|
||||
{
|
||||
g_free(self->title);
|
||||
self->title = NULL;
|
||||
}
|
||||
G_OBJECT_CLASS(diya_foreign_window_parent_class)->dispose(object);
|
||||
}
|
||||
|
@ -12,12 +12,13 @@
|
||||
struct _DiyaLoginShell
|
||||
{
|
||||
DiyaShell parent_object;
|
||||
GtkApplication *app;
|
||||
GtkSessionLockInstance *lock;
|
||||
GtkWidget *username;
|
||||
GtkWidget *password;
|
||||
GtkWidget *status;
|
||||
guint bus_watch_id;
|
||||
//GtkWindow *window;
|
||||
GList * windows;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE(DiyaLoginShell, diya_login_shell, DIYA_TYPE_SHELL);
|
||||
@ -34,46 +35,37 @@ static void diya_login_shell_dispose(GObject *object)
|
||||
}
|
||||
g_object_unref(self->lock);
|
||||
}
|
||||
if(self->windows)
|
||||
{
|
||||
// destroyed all windows and free list
|
||||
GList * it = NULL;
|
||||
for(it = self->windows; it; it = it->next)
|
||||
{
|
||||
if(it->data)
|
||||
{
|
||||
gtk_window_destroy(GTK_WINDOW(it->data));
|
||||
}
|
||||
}
|
||||
g_list_free(self->windows);
|
||||
}
|
||||
if (self->bus_watch_id > 0)
|
||||
{
|
||||
g_bus_unwatch_name(self->bus_watch_id);
|
||||
}
|
||||
if (self->app)
|
||||
{
|
||||
g_object_unref(self->app);
|
||||
}
|
||||
G_OBJECT_CLASS(diya_login_shell_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void diya_login_shell_init(DiyaLoginShell *self)
|
||||
{
|
||||
self->app = NULL;
|
||||
g_debug("diya_login_shell_init");
|
||||
self->lock = gtk_session_lock_instance_new();
|
||||
self->username = NULL;
|
||||
self->password = NULL;
|
||||
self->status = NULL;
|
||||
self->windows = NULL;
|
||||
self->bus_watch_id = 0;
|
||||
}
|
||||
|
||||
static const gchar *diya_login_shell_to_string(DiyaObject *object)
|
||||
{
|
||||
(void)object;
|
||||
return "Diya Login Shell";
|
||||
}
|
||||
|
||||
static void diya_login_shell_class_init(DiyaLoginShellClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
|
||||
DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class);
|
||||
gobject_class->dispose = diya_login_shell_dispose;
|
||||
// gobject_class->set_property = diya_lock_session_set_property;
|
||||
// gobject_class->get_property = diya_lock_session_get_property;
|
||||
|
||||
|
||||
//DiyaShellClass *base_shell_class = DIYA_SHELL_CLASS(class)
|
||||
//base_shell_class->foreign_register = diya_session_shell_foreign_toplevel_register;
|
||||
|
||||
base_class->to_string = diya_login_shell_to_string;
|
||||
}
|
||||
|
||||
static void on_method_call_return(GObject *source_object, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
@ -103,7 +95,7 @@ static void on_method_call_return(GObject *source_object, GAsyncResult *res, gpo
|
||||
if (success)
|
||||
{
|
||||
gtk_label_set_text(GTK_LABEL(self->status), "Login successful");
|
||||
g_application_quit(G_APPLICATION(self->app));
|
||||
g_object_unref(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -191,101 +183,122 @@ static void open_vkb(GtkButton *button, DiyaLoginShell *self)
|
||||
g_object_unref(vkb);
|
||||
}
|
||||
|
||||
DiyaLoginShell *diya_login_shell_new()
|
||||
|
||||
static void add_new_monitor(DiyaLoginShell* self, GdkMonitor* monitor, gint position)
|
||||
{
|
||||
return g_object_new(DIYA_TYPE_LOGIN_SHELL, NULL);
|
||||
GtkWindow* window = GTK_WINDOW(gtk_application_window_new(diya_shell_get_application(DIYA_SHELL(self))));
|
||||
gtk_session_lock_instance_assign_window_to_monitor(self->lock, window, monitor);
|
||||
|
||||
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_halign(box, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign(box, GTK_ALIGN_CENTER);
|
||||
gtk_box_set_spacing(GTK_BOX(box), 10);
|
||||
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new("Please login");
|
||||
gtk_box_append(GTK_BOX(box), label);
|
||||
gtk_widget_add_css_class(label, "diya-login-header");
|
||||
|
||||
GtkWidget *user_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_valign(user_box, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_halign(user_box, GTK_ALIGN_END);
|
||||
gtk_box_set_spacing(GTK_BOX(user_box), 10);
|
||||
|
||||
label = gtk_label_new("Username");
|
||||
gtk_box_append(GTK_BOX(user_box), label);
|
||||
|
||||
self->username = gtk_entry_new();
|
||||
gtk_box_append(GTK_BOX(user_box), GTK_WIDGET(self->username));
|
||||
|
||||
gtk_box_append(GTK_BOX(box), user_box);
|
||||
|
||||
GtkWidget *password_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_valign(password_box, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_halign(password_box, GTK_ALIGN_END);
|
||||
gtk_box_set_spacing(GTK_BOX(password_box), 10);
|
||||
|
||||
label = gtk_label_new("Password");
|
||||
gtk_box_append(GTK_BOX(password_box), label);
|
||||
|
||||
self->password = gtk_password_entry_new();
|
||||
gtk_box_append(GTK_BOX(password_box), GTK_WIDGET(self->password));
|
||||
|
||||
gtk_box_append(GTK_BOX(box), password_box);
|
||||
|
||||
g_signal_connect(self->username, "activate", G_CALLBACK(do_login), self);
|
||||
g_signal_connect(self->password, "activate", G_CALLBACK(do_login), self);
|
||||
|
||||
GtkWidget *button = gtk_button_new_with_label("Login");
|
||||
g_signal_connect(button, "clicked", G_CALLBACK(do_login), self);
|
||||
//gtk_widget_set_can_focus(GTK_WIDGET(button), false);
|
||||
gtk_box_append(GTK_BOX(box), button);
|
||||
|
||||
// Not displayed, but allows testing that creating popups doesn't crash GTK
|
||||
gtk_widget_set_tooltip_text(button, "Login");
|
||||
|
||||
self->status = gtk_label_new(NULL);
|
||||
gtk_box_append(GTK_BOX(box), self->status);
|
||||
gtk_widget_add_css_class(self->status, "diya-login-status");
|
||||
|
||||
button = gtk_button_new_with_label("Show virtual keyboard");
|
||||
g_signal_connect(button, "clicked", G_CALLBACK(open_vkb), self);
|
||||
gtk_widget_set_can_focus(GTK_WIDGET(button), false);
|
||||
gtk_box_append(GTK_BOX(box), button);
|
||||
|
||||
DiyaVirtualKeyboardWidget* vkb_widget = diya_virtual_keyboard_widget_new();
|
||||
gtk_box_append(GTK_BOX(box), GTK_WIDGET(vkb_widget));
|
||||
|
||||
gtk_window_set_child(GTK_WINDOW(window), box);
|
||||
|
||||
gtk_window_present(window);
|
||||
|
||||
self->windows = g_list_insert(self->windows,window, position);
|
||||
}
|
||||
|
||||
void diya_login_shell_attach(DiyaLoginShell *self, GtkApplication *app)
|
||||
static void on_monitor_changed(GListModel* monitor_lists,guint position, guint removed,guint added, gpointer object)
|
||||
{
|
||||
self->app = app;
|
||||
g_debug("Monitor list changed at %d: added %d, removed %d", position, added, removed);
|
||||
DiyaLoginShell* self = DIYA_LOGIN_SHELL(object);
|
||||
if(removed > 0)
|
||||
{
|
||||
for (guint i = 0; i < removed; i++)
|
||||
{
|
||||
GtkWindow* win = GTK_WINDOW(g_list_nth(self->windows, position));
|
||||
if(win)
|
||||
{
|
||||
gtk_window_destroy(win);
|
||||
self->windows = g_list_remove(self->windows, win);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(added > 0)
|
||||
{
|
||||
for (guint i = 0; i < added; i++)
|
||||
{
|
||||
GdkMonitor * monitor = g_list_model_get_item(monitor_lists,position + i);
|
||||
add_new_monitor(self, monitor, position + i);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void diya_login_shell_startup(DiyaShell* shell)
|
||||
{
|
||||
DiyaLoginShell* self = DIYA_LOGIN_SHELL(shell);
|
||||
if (!gtk_session_lock_instance_lock(self->lock))
|
||||
{
|
||||
g_error("gtk_session_lock_instance_lock: Unable to lock the display");
|
||||
g_object_unref(self);
|
||||
return;
|
||||
}
|
||||
|
||||
GdkDisplay *display = gdk_display_get_default();
|
||||
GListModel *monitors = gdk_display_get_monitors(display);
|
||||
guint n_monitors = g_list_model_get_n_items(monitors);
|
||||
|
||||
for (guint i = 0; i < n_monitors; ++i)
|
||||
{
|
||||
GdkMonitor *monitor = g_list_model_get_item(monitors, i);
|
||||
|
||||
GtkWindow *gtk_window = GTK_WINDOW(gtk_application_window_new(app));
|
||||
gtk_session_lock_instance_assign_window_to_monitor(self->lock, gtk_window, monitor);
|
||||
|
||||
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_halign(box, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign(box, GTK_ALIGN_CENTER);
|
||||
gtk_box_set_spacing(GTK_BOX(box), 10);
|
||||
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new("Please login");
|
||||
gtk_box_append(GTK_BOX(box), label);
|
||||
gtk_widget_add_css_class(label, "header");
|
||||
|
||||
GtkWidget *user_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_valign(user_box, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_halign(user_box, GTK_ALIGN_END);
|
||||
gtk_box_set_spacing(GTK_BOX(user_box), 10);
|
||||
|
||||
label = gtk_label_new("Username");
|
||||
gtk_box_append(GTK_BOX(user_box), label);
|
||||
|
||||
self->username = gtk_entry_new();
|
||||
gtk_box_append(GTK_BOX(user_box), GTK_WIDGET(self->username));
|
||||
|
||||
gtk_box_append(GTK_BOX(box), user_box);
|
||||
|
||||
GtkWidget *password_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_valign(password_box, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_halign(password_box, GTK_ALIGN_END);
|
||||
gtk_box_set_spacing(GTK_BOX(password_box), 10);
|
||||
|
||||
label = gtk_label_new("Password");
|
||||
gtk_box_append(GTK_BOX(password_box), label);
|
||||
|
||||
self->password = gtk_password_entry_new();
|
||||
gtk_box_append(GTK_BOX(password_box), GTK_WIDGET(self->password));
|
||||
|
||||
gtk_box_append(GTK_BOX(box), password_box);
|
||||
|
||||
g_signal_connect(self->username, "activate", G_CALLBACK(do_login), self);
|
||||
g_signal_connect(self->password, "activate", G_CALLBACK(do_login), self);
|
||||
|
||||
GtkWidget *button = gtk_button_new_with_label("Login");
|
||||
g_signal_connect(button, "clicked", G_CALLBACK(do_login), self);
|
||||
//gtk_widget_set_can_focus(GTK_WIDGET(button), false);
|
||||
gtk_box_append(GTK_BOX(box), button);
|
||||
|
||||
// Not displayed, but allows testing that creating popups doesn't crash GTK
|
||||
gtk_widget_set_tooltip_text(button, "Login");
|
||||
|
||||
self->status = gtk_label_new(NULL);
|
||||
gtk_box_append(GTK_BOX(box), self->status);
|
||||
gtk_widget_add_css_class(self->status, "status");
|
||||
|
||||
button = gtk_button_new_with_label("Show virtual keyboard");
|
||||
g_signal_connect(button, "clicked", G_CALLBACK(open_vkb), self);
|
||||
gtk_widget_set_can_focus(GTK_WIDGET(button), false);
|
||||
gtk_box_append(GTK_BOX(box), button);
|
||||
|
||||
gtk_window_set_child(GTK_WINDOW(gtk_window), box);
|
||||
|
||||
gtk_window_present(gtk_window);
|
||||
}
|
||||
// load xml content from gresource
|
||||
GError *err = NULL;
|
||||
GBytes *bytes = g_resources_lookup_data("/dev/iohub/diya/shell/login-shell.css", 0, &err);
|
||||
if (err != NULL)
|
||||
{
|
||||
g_critical("Unable to load CSS resource: %s", err->message);
|
||||
g_error_free(err);
|
||||
return;
|
||||
// continue without stylesheet
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -299,4 +312,24 @@ void diya_login_shell_attach(DiyaLoginShell *self, GtkApplication *app)
|
||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
g_bytes_unref(bytes);
|
||||
}
|
||||
GListModel * list = gdk_display_get_monitors(gdk_display_get_default());
|
||||
for(guint i = 0; i < g_list_model_get_n_items(list); i++)
|
||||
{
|
||||
GdkMonitor * monitor = g_list_model_get_item(list,i);
|
||||
add_new_monitor(self, monitor, -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void diya_login_shell_class_init(DiyaLoginShellClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
|
||||
gobject_class->dispose = diya_login_shell_dispose;
|
||||
// gobject_class->set_property = diya_lock_session_set_property;
|
||||
// gobject_class->get_property = diya_lock_session_get_property;
|
||||
|
||||
DiyaShellClass *base_shell_class = DIYA_SHELL_CLASS(class);
|
||||
base_shell_class->monitor_changed_handle = on_monitor_changed;
|
||||
base_shell_class->startup_handle = diya_login_shell_startup;
|
||||
//base_shell_class->foreign_register = diya_session_shell_foreign_toplevel_register;
|
||||
|
||||
}
|
@ -8,8 +8,4 @@
|
||||
#define DIYA_TYPE_LOGIN_SHELL (diya_login_shell_get_type())
|
||||
G_DECLARE_FINAL_TYPE(DiyaLoginShell, diya_login_shell, DIYA, LOGIN_SHELL, DiyaShell);
|
||||
|
||||
|
||||
DiyaLoginShell *diya_login_shell_new();
|
||||
void diya_login_shell_attach(DiyaLoginShell *self, GtkApplication *app);
|
||||
|
||||
#endif
|
30
src/login.c
30
src/login.c
@ -2,16 +2,9 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "login-shell.h"
|
||||
#include "wayland.h"
|
||||
|
||||
static gchar **g_shell_argv;
|
||||
|
||||
static void activate(GtkApplication *app, void *data)
|
||||
{
|
||||
(void)app;
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static gboolean restart(gpointer d)
|
||||
{
|
||||
(void)d;
|
||||
@ -29,15 +22,6 @@ static gboolean restart(gpointer d)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void startup(GtkApplication *app, DiyaLoginShell* shell)
|
||||
{
|
||||
diya_shell_wayland_init(DIYA_SHELL(shell));
|
||||
g_unix_signal_add(SIGHUP, (GSourceFunc)restart, NULL);
|
||||
g_unix_signal_add(SIGINT,(GSourceFunc)g_application_quit,(void*)app);
|
||||
diya_login_shell_attach(shell, app);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
g_shell_argv = g_malloc0(sizeof(gchar *) * (argc + 1));
|
||||
@ -45,15 +29,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
g_shell_argv[i] = argv[i];
|
||||
}
|
||||
GtkApplication* app = gtk_application_new("dev.iohub.diya.login-shell", G_APPLICATION_DEFAULT_FLAGS);
|
||||
|
||||
DiyaLoginShell* shell = diya_login_shell_new();
|
||||
|
||||
g_signal_connect(app, "startup", G_CALLBACK(startup), shell);
|
||||
g_signal_connect(app, "activate", G_CALLBACK(activate), shell);
|
||||
// g_signal_connect(app, "shutdown", G_CALLBACK(shutdown), (void*)shell);
|
||||
int status = g_application_run(G_APPLICATION(app), argc, argv);
|
||||
g_warning("Exiting SHELL");
|
||||
g_object_unref(shell);
|
||||
return status;
|
||||
g_unix_signal_add(SIGHUP, (GSourceFunc)restart, NULL);
|
||||
DiyaLoginShell* shell = DIYA_LOGIN_SHELL(g_object_new(DIYA_TYPE_LOGIN_SHELL, "name", "dev.iohub.diya.login-shell", NULL));
|
||||
return diya_shell_run(DIYA_SHELL(shell), argc, argv);
|
||||
}
|
||||
|
@ -4,13 +4,13 @@
|
||||
#include <gtk4-session-lock.h>
|
||||
#include "shell.h"
|
||||
#include "foreign.h"
|
||||
|
||||
#define SHELL_DESCRIPTION "Diya GTK shell for wayland (diyac)"
|
||||
#include "background.h"
|
||||
#include "launcher.h"
|
||||
#include "session-lock.h"
|
||||
|
||||
enum
|
||||
{
|
||||
NO_PROP,
|
||||
SHELL_APP,
|
||||
SHELL_BACKGROUND_WIDGET,
|
||||
SHELL_LAUNCHPAD_WIDGET,
|
||||
SHELL_LOCK_SESSION,
|
||||
@ -23,7 +23,6 @@ static GParamSpec *shell_properties[N_PROPERTIES] = {0};
|
||||
struct _DiyaSessionShell
|
||||
{
|
||||
DiyaShell parent;
|
||||
GtkApplication* app;
|
||||
GtkWindow* background;
|
||||
GtkWindow* launcher;
|
||||
GHashTable* windows;
|
||||
@ -35,11 +34,19 @@ static void diya_session_shell_dispose(GObject* object)
|
||||
{
|
||||
DiyaSessionShell * self = DIYA_SESSION_SHELL(object);
|
||||
g_hash_table_destroy(self->windows);
|
||||
g_debug("diya_session_shell_dispose");
|
||||
g_debug("diya_session_shell_dispose: %s", diya_object_to_string(object));
|
||||
if(self->lock)
|
||||
{
|
||||
g_object_unref(self->lock);
|
||||
}
|
||||
if(self->background)
|
||||
{
|
||||
gtk_window_destroy(self->background);
|
||||
}
|
||||
if(self->launcher)
|
||||
{
|
||||
gtk_window_destroy(self->launcher);
|
||||
}
|
||||
G_OBJECT_CLASS(diya_session_shell_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
@ -48,10 +55,6 @@ static void diya_session_shell_set_property(GObject *object, guint property_id,
|
||||
DiyaSessionShell * self = DIYA_SESSION_SHELL(object);
|
||||
switch (property_id)
|
||||
{
|
||||
case SHELL_APP:
|
||||
self->app = g_value_get_pointer(value);
|
||||
assert(self->app);
|
||||
break;
|
||||
case SHELL_BACKGROUND_WIDGET:
|
||||
self->background = g_value_get_pointer(value);
|
||||
break;
|
||||
@ -72,9 +75,6 @@ static void diya_session_shell_get_property(GObject *object, guint property_id,
|
||||
DiyaSessionShell * self = DIYA_SESSION_SHELL(object);
|
||||
switch (property_id)
|
||||
{
|
||||
case SHELL_APP:
|
||||
g_value_set_pointer(value, self->app);
|
||||
break;
|
||||
case SHELL_BACKGROUND_WIDGET:
|
||||
g_value_set_pointer(value, self->background);
|
||||
break;
|
||||
@ -95,26 +95,43 @@ static void diya_session_shell_get_property(GObject *object, guint property_id,
|
||||
}
|
||||
}
|
||||
|
||||
static const gchar* diya_session_shell_to_string(DiyaObject* object)
|
||||
static void diya_session_shell_startup(DiyaShell* shell)
|
||||
{
|
||||
(void) object;
|
||||
return SHELL_DESCRIPTION;
|
||||
diya_session_shell_launcher_init(DIYA_SESSION_SHELL(shell));
|
||||
diya_session_shell_init_background(DIYA_SESSION_SHELL(shell));
|
||||
|
||||
GtkCssProvider *provider = gtk_css_provider_new();
|
||||
const char *css = "#launcher {background-color: red;} #background {background-image:url(\"file:///etc/xdg/labwc/wpp.jpg\");background-size: cover;}";
|
||||
gtk_css_provider_load_from_string(provider, css);
|
||||
gtk_style_context_add_provider_for_display(
|
||||
gdk_display_get_default(), GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
// g_signal_connect (win, "destroy", G_CALLBACK (before_destroy), provider);
|
||||
g_object_unref(provider);
|
||||
// CSS support
|
||||
// set color for it
|
||||
// g_timeout_add (100,(GSourceFunc )shell_timer,NULL);
|
||||
}
|
||||
|
||||
static void diya_session_shell_active(DiyaShell* shell)
|
||||
{
|
||||
diya_session_shell_lock(DIYA_SESSION_SHELL(shell));
|
||||
}
|
||||
|
||||
static void diya_session_shell_class_init(DiyaSessionShellClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
|
||||
DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class);
|
||||
// DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class);
|
||||
|
||||
DiyaShellClass *base_shell_class = DIYA_SHELL_CLASS(class);
|
||||
base_shell_class->foreign_register = diya_session_shell_foreign_toplevel_register;
|
||||
base_shell_class->startup_handle = diya_session_shell_startup;
|
||||
base_shell_class->active_handle = diya_session_shell_active;
|
||||
|
||||
base_class->to_string = diya_session_shell_to_string;
|
||||
///base_class->to_string = diya_session_shell_to_string;
|
||||
gobject_class->dispose = diya_session_shell_dispose;
|
||||
gobject_class->set_property = diya_session_shell_set_property;
|
||||
gobject_class->get_property = diya_session_shell_get_property;
|
||||
|
||||
shell_properties[SHELL_APP] = g_param_spec_pointer("application", NULL, "Shell application", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
shell_properties[SHELL_BACKGROUND_WIDGET] = g_param_spec_pointer("background", NULL, "Shell background widget", G_PARAM_READWRITE );
|
||||
shell_properties[SHELL_LAUNCHPAD_WIDGET] = g_param_spec_pointer("launchpad", NULL, "Shell launchpad", G_PARAM_READWRITE );
|
||||
shell_properties[SHELL_LOCK_SESSION] = g_param_spec_pointer("session-lock", NULL, "Shell lock session", G_PARAM_READABLE );
|
||||
@ -232,10 +249,6 @@ void diya_session_shell_remove_all_windows(DiyaSessionShell * shell)
|
||||
shell->windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
|
||||
}
|
||||
|
||||
DiyaSessionShell * diya_session_shell_new(GtkApplication * app)
|
||||
{
|
||||
return DIYA_SESSION_SHELL(g_object_new(DIYA_TYPE_SESSION_SHELL,"application",app, NULL));
|
||||
}
|
||||
/*
|
||||
static void on_orientation_changed (GtkWindow *window, WindowOrientation orientation, ToplevelData *data)
|
||||
{
|
||||
|
@ -15,6 +15,4 @@ DiyaForeignWindow* diya_session_shell_get_window(DiyaSessionShell * shell, gpoin
|
||||
gboolean diya_session_shell_add_window(DiyaSessionShell * shell, DiyaForeignWindow * win);
|
||||
gboolean diya_session_shell_remove_window(DiyaSessionShell * shell, DiyaForeignWindow * win);
|
||||
void diya_session_shell_remove_all_windows(DiyaSessionShell * shell);
|
||||
|
||||
DiyaSessionShell * diya_session_shell_new(GtkApplication * app);
|
||||
#endif
|
@ -1,23 +1,10 @@
|
||||
#include <glib-unix.h>
|
||||
#include <assert.h>
|
||||
#include "shell.h"
|
||||
#include "background.h"
|
||||
#include "launcher.h"
|
||||
#include "wayland.h"
|
||||
#include "foreign.h"
|
||||
#include "session-lock.h"
|
||||
#include "session-shell.h"
|
||||
|
||||
|
||||
static gchar **g_shell_argv;
|
||||
|
||||
static void activate(GtkApplication *app, void *data)
|
||||
{
|
||||
(void)app;
|
||||
(void)data;
|
||||
|
||||
DiyaSessionShell *shell = data;
|
||||
diya_session_shell_lock(shell);
|
||||
}
|
||||
|
||||
static gboolean restart(gpointer d)
|
||||
{
|
||||
(void)d;
|
||||
@ -35,28 +22,6 @@ static gboolean restart(gpointer d)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void startup(GtkApplication *app, void *data)
|
||||
{
|
||||
DiyaSessionShell *shell = data;
|
||||
|
||||
diya_session_shell_launcher_init(shell);
|
||||
diya_session_shell_init_background(shell);
|
||||
diya_shell_wayland_init(DIYA_SHELL(shell));
|
||||
|
||||
GtkCssProvider *provider = gtk_css_provider_new();
|
||||
const char *css = "#launcher {background-color: red;} #background {background-image:url(\"file:///etc/xdg/labwc/wpp.jpg\");background-size: cover;}";
|
||||
gtk_css_provider_load_from_string(provider, css);
|
||||
gtk_style_context_add_provider_for_display(
|
||||
gdk_display_get_default(), GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
// g_signal_connect (win, "destroy", G_CALLBACK (before_destroy), provider);
|
||||
g_object_unref(provider);
|
||||
// CSS support
|
||||
// set color for it
|
||||
// g_timeout_add (100,(GSourceFunc )shell_timer,NULL);
|
||||
g_unix_signal_add(SIGHUP, (GSourceFunc)restart, NULL);
|
||||
g_unix_signal_add(SIGINT,(GSourceFunc)g_application_quit,(void*)app);
|
||||
}
|
||||
|
||||
static void session_locked(DiyaSessionShell* shell, void* data)
|
||||
{
|
||||
(void)data;
|
||||
@ -78,16 +43,9 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
g_shell_argv[i] = argv[i];
|
||||
}
|
||||
GtkApplication *app = gtk_application_new("dev.iohub.diya.shell", G_APPLICATION_DEFAULT_FLAGS);
|
||||
DiyaSessionShell *shell = diya_session_shell_new(app);
|
||||
g_signal_connect(app, "startup", G_CALLBACK(startup), (void *)shell);
|
||||
g_signal_connect(app, "activate", G_CALLBACK(activate), (void *)shell);
|
||||
g_unix_signal_add(SIGHUP, (GSourceFunc)restart, NULL);
|
||||
DiyaSessionShell *shell = DIYA_SESSION_SHELL(g_object_new(DIYA_TYPE_SESSION_SHELL, "name","dev.iohub.diya.session-shell", NULL));
|
||||
g_signal_connect(shell, "session-locked", G_CALLBACK(session_locked), NULL);
|
||||
g_signal_connect(shell, "session-unlocked", G_CALLBACK(session_unlocked), NULL);
|
||||
// g_signal_connect(app, "shutdown", G_CALLBACK(shutdown), (void*)shell);
|
||||
int status = g_application_run(G_APPLICATION(app), argc, argv);
|
||||
g_warning("Exiting SHELL");
|
||||
g_object_unref(app);
|
||||
g_object_unref(shell);
|
||||
return status;
|
||||
return diya_shell_run(DIYA_SHELL(shell), argc, argv);
|
||||
}
|
||||
|
126
src/shell.c
126
src/shell.c
@ -1,3 +1,4 @@
|
||||
#include <glib-unix.h>
|
||||
#include "shell.h"
|
||||
#include "wayland.h"
|
||||
#include "virtual-keyboard.h"
|
||||
@ -5,6 +6,8 @@ enum
|
||||
{
|
||||
NO_PROP,
|
||||
PROP_SHELL_WAYLAND,
|
||||
PROP_SHELL_APP,
|
||||
PROP_SHELL_NAME,
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
||||
@ -15,7 +18,9 @@ typedef struct _DiyaShellPrivate
|
||||
{
|
||||
DiyaObject parent;
|
||||
DiyaWayland * wayland;
|
||||
GtkApplication* app;
|
||||
DiyaVirtualKeyboard* vkb;
|
||||
gchar* name;
|
||||
} DiyaShellPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE(DiyaShell, diya_shell, DIYA_TYPE_OBJECT);
|
||||
@ -31,7 +36,66 @@ static void diya_shell_dispose(GObject* object)
|
||||
{
|
||||
g_object_unref(priv->wayland);
|
||||
}
|
||||
if(priv->name)
|
||||
{
|
||||
g_free(priv->name);
|
||||
priv->name = NULL;
|
||||
}
|
||||
G_OBJECT_CLASS(diya_shell_parent_class)->dispose(object);
|
||||
if (priv->app)
|
||||
{
|
||||
g_application_quit(G_APPLICATION(priv->app));
|
||||
}
|
||||
}
|
||||
|
||||
static void on_gtk_app_startup(GtkApplication *app, void *data)
|
||||
{
|
||||
(void)app;
|
||||
DiyaShell *shell = data;
|
||||
DiyaShellPrivate* priv = diya_shell_get_instance_private(shell);
|
||||
priv->wayland =diya_wayland_new(DIYA_SHELL(shell));
|
||||
DiyaShellClass* class = DIYA_SHELL_GET_CLASS(shell);
|
||||
if(class->startup_handle)
|
||||
{
|
||||
class->startup_handle(shell);
|
||||
}
|
||||
if(class->monitor_changed_handle)
|
||||
{
|
||||
GListModel* monitor_list = gdk_display_get_monitors(gdk_display_get_default());
|
||||
g_debug("listen to monitor changed");
|
||||
g_signal_connect(monitor_list,"items-changed", G_CALLBACK(class->monitor_changed_handle), shell);
|
||||
}
|
||||
}
|
||||
|
||||
static void on_gtk_app_active(GtkApplication *app, void *data)
|
||||
{
|
||||
(void)app;
|
||||
DiyaShell *shell = data;
|
||||
DiyaShellClass* class = DIYA_SHELL_GET_CLASS(shell);
|
||||
if(class->active_handle)
|
||||
{
|
||||
class->active_handle(shell);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean diya_shell_sigint_handle(gpointer data)
|
||||
{
|
||||
g_object_unref(DIYA_SHELL(data));
|
||||
return true;
|
||||
}
|
||||
|
||||
static void init_gtk_application(DiyaShell* self)
|
||||
{
|
||||
DiyaShellPrivate* priv = diya_shell_get_instance_private(self);
|
||||
if(priv->app)
|
||||
{
|
||||
return;
|
||||
}
|
||||
priv->app = gtk_application_new(priv->name, G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect(priv->app, "startup", G_CALLBACK(on_gtk_app_startup), (void *)self);
|
||||
g_signal_connect(priv->app, "activate", G_CALLBACK(on_gtk_app_active), (void *)self);
|
||||
g_unix_signal_add(SIGINT,(GSourceFunc)diya_shell_sigint_handle,(void*)self);
|
||||
// g_signal_connect(priv->app, "shutdown", G_CALLBACK(shutdown), (void*)shell);
|
||||
}
|
||||
|
||||
static void diya_shell_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
|
||||
@ -41,8 +105,13 @@ static void diya_shell_set_property(GObject *object, guint property_id, const GV
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_SHELL_WAYLAND:
|
||||
priv->wayland = g_value_get_pointer(value);
|
||||
case PROP_SHELL_NAME:
|
||||
if(priv->name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
priv->name = g_strdup(g_value_get_string(value));
|
||||
init_gtk_application(self);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
@ -59,6 +128,12 @@ static void diya_shell_get_property(GObject *object, guint property_id, GValue *
|
||||
case PROP_SHELL_WAYLAND:
|
||||
g_value_set_pointer(value, priv->wayland);
|
||||
break;
|
||||
case PROP_SHELL_APP:
|
||||
g_value_set_pointer(value, priv->app);
|
||||
break;
|
||||
case PROP_SHELL_NAME:
|
||||
g_value_set_string(value, priv->name);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
@ -70,14 +145,33 @@ static void diya_shell_init(DiyaShell *self)
|
||||
{
|
||||
DiyaShellPrivate* priv = diya_shell_get_instance_private(self);
|
||||
priv->wayland = NULL;
|
||||
priv->app = NULL;
|
||||
priv->name = NULL;
|
||||
}
|
||||
|
||||
DiyaWayland * diya_shell_get_wayland(DiyaShell* shell)
|
||||
{
|
||||
DiyaWayland * wayland;
|
||||
g_object_get(shell,"wayland", &wayland, NULL);
|
||||
assert(DIYA_IS_WAYLAND(wayland));
|
||||
return wayland;
|
||||
DiyaShellPrivate* priv = diya_shell_get_instance_private(shell);
|
||||
assert(DIYA_IS_WAYLAND(priv->wayland));
|
||||
return priv->wayland;
|
||||
}
|
||||
|
||||
GtkApplication* diya_shell_get_application(DiyaShell* shell)
|
||||
{
|
||||
DiyaShellPrivate* priv = diya_shell_get_instance_private(shell);
|
||||
assert(GTK_IS_APPLICATION(priv->app));
|
||||
return priv->app;
|
||||
}
|
||||
|
||||
const char* diya_shell_get_name(DiyaShell* shell)
|
||||
{
|
||||
DiyaShellPrivate* priv = diya_shell_get_instance_private(shell);
|
||||
return priv->name;
|
||||
}
|
||||
|
||||
static const gchar *diya_shell_to_string(DiyaObject *object)
|
||||
{
|
||||
return diya_shell_get_name(DIYA_SHELL(object));
|
||||
}
|
||||
|
||||
static void diya_shell_class_init(DiyaShellClass *class)
|
||||
@ -87,9 +181,27 @@ static void diya_shell_class_init(DiyaShellClass *class)
|
||||
gobject_class->set_property = diya_shell_set_property;
|
||||
gobject_class->get_property = diya_shell_get_property;
|
||||
|
||||
DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class);
|
||||
base_class->to_string = diya_shell_to_string;
|
||||
|
||||
class->foreign_register = NULL;
|
||||
class->virtual_keyboard_register = diya_virtual_keyboard_register;
|
||||
class->monitor_changed_handle = NULL;
|
||||
class->startup_handle = NULL;
|
||||
class->active_handle = NULL;
|
||||
|
||||
shell_properties[PROP_SHELL_WAYLAND] = g_param_spec_pointer("wayland", NULL, "Shell wayland", G_PARAM_READWRITE); //
|
||||
shell_properties[PROP_SHELL_WAYLAND] = g_param_spec_pointer("wayland", NULL, "Shell wayland", G_PARAM_READABLE); //
|
||||
shell_properties[PROP_SHELL_NAME] = g_param_spec_string("name", NULL, "Shell name", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
shell_properties[PROP_SHELL_APP] = g_param_spec_pointer("application", NULL, "Shell application", G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPERTIES, shell_properties);
|
||||
}
|
||||
|
||||
int diya_shell_run(DiyaShell* shell, int argc, char **argv)
|
||||
{
|
||||
DiyaShellPrivate* priv = diya_shell_get_instance_private(shell);
|
||||
assert(GTK_IS_APPLICATION(priv->app));
|
||||
int status = g_application_run(G_APPLICATION(priv->app),argc,argv);
|
||||
g_object_unref(priv->app);
|
||||
return status;
|
||||
}
|
10
src/shell.h
10
src/shell.h
@ -1,6 +1,8 @@
|
||||
#ifndef DIYA_SHELL_H
|
||||
#define DIYA_SHELL_H
|
||||
#include <stdint.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "base.h"
|
||||
|
||||
#define DIYA_TYPE_SHELL (diya_shell_get_type())
|
||||
@ -18,10 +20,14 @@ struct _DiyaShellClass
|
||||
DiyaObjectClass parent_class;
|
||||
wl_protocol_manager_register_t foreign_register;
|
||||
wl_protocol_manager_register_t virtual_keyboard_register;
|
||||
void (*monitor_changed_handle)(GListModel* /*list*/,guint /*position*/, guint /*removed*/,guint /*added*/, gpointer);
|
||||
void (*startup_handle)(DiyaShell*);
|
||||
void (*active_handle)(DiyaShell*);
|
||||
};
|
||||
|
||||
void diya_shell_wayland_init(DiyaShell *shell);
|
||||
DiyaWayland * diya_shell_get_wayland(DiyaShell* shell);
|
||||
GtkApplication* diya_shell_get_application(DiyaShell* shell);
|
||||
const char* diya_shell_get_name(DiyaShell* shell);
|
||||
|
||||
|
||||
int diya_shell_run(DiyaShell* shell, int argc, char **argv);
|
||||
#endif
|
@ -13,6 +13,230 @@
|
||||
#include "virtual-keyboard.h"
|
||||
#include "wayland.h"
|
||||
|
||||
/**
|
||||
* @brief DiyaVkbButton: virtual keyboard button
|
||||
*/
|
||||
|
||||
struct _DiyaVkbButton
|
||||
{
|
||||
GtkWidget super;
|
||||
GtkWidget *labels[3];
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE(DiyaVkbButton, diya_vkb_button, GTK_TYPE_WIDGET);
|
||||
|
||||
static void diya_vkb_button_dispose(GObject *object)
|
||||
{
|
||||
DiyaVkbButton *self = DIYA_VKB_BUTTON(object);
|
||||
g_debug("diya_vkb_button_dispose");
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
g_clear_pointer(&self->labels[i], gtk_widget_unparent);
|
||||
}
|
||||
// g_clear_pointer (&demo->label, gtk_widget_unparent);
|
||||
G_OBJECT_CLASS(diya_vkb_button_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void diya_vkb_button_init(DiyaVkbButton *self)
|
||||
{
|
||||
gchar class_name[32]; /*diya-vkb-btn-level-%d */
|
||||
GtkLayoutManager *grid_layout;
|
||||
grid_layout = gtk_widget_get_layout_manager(GTK_WIDGET(self));
|
||||
//gtk_orientable_set_orientation(GTK_ORIENTABLE(box_layout), GTK_ORIENTATION_VERTICAL);
|
||||
// gtk_box_layout_set_spacing (GTK_BOX_LAYOUT (box_layout), 3);
|
||||
gtk_widget_add_css_class(GTK_WIDGET(self),"diya-vkb-btn");
|
||||
gtk_widget_set_can_focus(GTK_WIDGET(self), false);
|
||||
// init labels
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
self->labels[i] = gtk_label_new(i==0?"X":"x");
|
||||
g_snprintf(class_name, sizeof(class_name),"diya-vkb-btn-level-%d",i + 1);
|
||||
gtk_widget_add_css_class(self->labels[i], class_name);
|
||||
gtk_widget_set_hexpand(self->labels[i], true);
|
||||
|
||||
gtk_widget_set_parent(self->labels[i], GTK_WIDGET(self));
|
||||
|
||||
GtkGridLayoutChild *grid_child = GTK_GRID_LAYOUT_CHILD(gtk_layout_manager_get_layout_child(grid_layout,self->labels[i]));
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
/* code */
|
||||
gtk_grid_layout_child_set_row(grid_child,0);
|
||||
gtk_grid_layout_child_set_column(grid_child,0);
|
||||
gtk_grid_layout_child_set_column_span (grid_child,2);
|
||||
break;
|
||||
case 1:
|
||||
gtk_grid_layout_child_set_row(grid_child,1);
|
||||
gtk_grid_layout_child_set_column(grid_child,0);
|
||||
gtk_widget_set_halign(self->labels[i],GTK_ALIGN_START);
|
||||
break;
|
||||
case 2:
|
||||
gtk_grid_layout_child_set_row(grid_child,1);
|
||||
gtk_grid_layout_child_set_column(grid_child,1);
|
||||
gtk_widget_set_halign(self->labels[i],GTK_ALIGN_END);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void diya_vkb_button_class_init(DiyaVkbButtonClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
|
||||
gobject_class->dispose = diya_vkb_button_dispose;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type(GTK_WIDGET_CLASS(class), GTK_TYPE_GRID_LAYOUT);
|
||||
}
|
||||
|
||||
DiyaVkbButton* diya_vkb_button_new(/**with prameter */)
|
||||
{
|
||||
return DIYA_VKB_BUTTON(g_object_new(DIYA_TYPE_VKB_BUTTON, NULL));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief DiyaVirtualKeyboardWidget: Virtual keyboard GTK widget
|
||||
*
|
||||
*/
|
||||
|
||||
#define VKB_N_CELLS 145
|
||||
#define VKB_ROW_NUM(i) (i/29)
|
||||
#define VKB_COL_NUM(i) (i % 29)
|
||||
|
||||
struct _DiyaVirtualKeyboardWidget
|
||||
{
|
||||
GtkWidget super;
|
||||
/**
|
||||
* row 0: 00 - 13
|
||||
* row 1: 14 - 27
|
||||
* row 2: 28 - 40
|
||||
* row 3: 41 - 53
|
||||
* row 4: 54 - 62
|
||||
*/
|
||||
GList *buttons;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE(DiyaVirtualKeyboardWidget, diya_virtual_keyboard_widget, GTK_TYPE_WIDGET);
|
||||
|
||||
static void diya_virtual_keyboard_widget_dispose(GObject *object)
|
||||
{
|
||||
DiyaVirtualKeyboardWidget *self = DIYA_VIRTUAL_KEYBOARD_WIDGET(object);
|
||||
g_debug("diya_virtual_keyboard_widget_dispose");
|
||||
if(self->buttons)
|
||||
{
|
||||
GList * it = NULL;
|
||||
for(it = self->buttons; it; it = it->next)
|
||||
{
|
||||
if(it->data)
|
||||
{
|
||||
g_clear_pointer(&it->data, gtk_widget_unparent);
|
||||
}
|
||||
}
|
||||
}
|
||||
// g_clear_pointer (&demo->label, gtk_widget_unparent);
|
||||
G_OBJECT_CLASS(diya_virtual_keyboard_widget_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void diya_virtual_keyboard_widget_init(DiyaVirtualKeyboardWidget *self)
|
||||
{
|
||||
// gtk_widget_set_size_request(GTK_WIDGET(self), 600, 400);
|
||||
g_debug("diya_virtual_keyboard_widget_init: Create new widget");
|
||||
GtkLayoutManager *grid_layout;
|
||||
gtk_widget_add_css_class(GTK_WIDGET(self),"diya-vkb");
|
||||
grid_layout = gtk_widget_get_layout_manager(GTK_WIDGET(self));
|
||||
// gtk_orientable_set_orientation(GTK_ORIENTABLE(grid_layout), GTK_ORIENTATION_VERTICAL);
|
||||
gtk_grid_layout_set_row_spacing(GTK_GRID_LAYOUT(grid_layout), 2);
|
||||
gtk_grid_layout_set_column_spacing(GTK_GRID_LAYOUT(grid_layout), 2);
|
||||
//gtk_grid_layout_set_baseline_row(GTK_GRID_LAYOUT(grid_layout), 4);
|
||||
// init buttons
|
||||
for (int i = 0; i < VKB_N_CELLS; i++)
|
||||
{
|
||||
gboolean skip = false;
|
||||
int row = VKB_ROW_NUM(i);
|
||||
int col = VKB_COL_NUM(i);
|
||||
switch (row)
|
||||
{
|
||||
case 0:
|
||||
skip = (col %2 != 0) || (col > 26);
|
||||
break;
|
||||
case 1:
|
||||
skip = (col == 1) || (col == 2) || (col != 0 && col % 2 == 0);
|
||||
break;
|
||||
case 2:
|
||||
skip = (col == 1) || (col == 2) || (col != 0 && col%2 == 0) || (col > 25);
|
||||
break;
|
||||
case 3:
|
||||
skip = (col > 0 && col < 5) || (col != 0 && col % 2 == 0);
|
||||
break;
|
||||
case 4:
|
||||
skip = (col > 0 && col < 3) || (col == 4) || (col==6) || (col>7 && col < 19) || (col > 19 && col %2 == 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(skip)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
GtkWidget* button = GTK_WIDGET(diya_vkb_button_new());
|
||||
self->buttons = g_list_append(self->buttons, button);
|
||||
gtk_widget_set_parent(button, GTK_WIDGET(self));
|
||||
gtk_widget_set_hexpand(button, true);
|
||||
GtkGridLayoutChild *grid_child = GTK_GRID_LAYOUT_CHILD(gtk_layout_manager_get_layout_child(grid_layout,button));
|
||||
|
||||
gtk_grid_layout_child_set_row(grid_child,row);
|
||||
gtk_grid_layout_child_set_column(grid_child,col);
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 26:
|
||||
case 29:
|
||||
case 58:
|
||||
case 116:
|
||||
gtk_grid_layout_child_set_column_span (grid_child,3);
|
||||
break;
|
||||
|
||||
case 83:
|
||||
gtk_grid_layout_child_set_column_span (grid_child,4);
|
||||
break;
|
||||
case 87:
|
||||
gtk_grid_layout_child_set_column_span (grid_child,5);
|
||||
break;
|
||||
case 123:
|
||||
gtk_grid_layout_child_set_column_span (grid_child,12);
|
||||
break;
|
||||
|
||||
default:
|
||||
if(i > 0)
|
||||
gtk_grid_layout_child_set_column_span (grid_child,2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void diya_virtual_keyboard_widget_class_init(DiyaVirtualKeyboardWidgetClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
|
||||
gobject_class->dispose = diya_virtual_keyboard_widget_dispose;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type(GTK_WIDGET_CLASS(class), GTK_TYPE_GRID_LAYOUT);
|
||||
}
|
||||
|
||||
DiyaVirtualKeyboardWidget *diya_virtual_keyboard_widget_new()
|
||||
{
|
||||
DiyaVirtualKeyboardWidget *vkb_widget = g_object_new(DIYA_TYPE_VIRTUAL_KEYBOARD_WIDGET, NULL);
|
||||
return vkb_widget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DiyaVirtualKeyboard class: lowlevel wayland virtual keyboard handle
|
||||
*
|
||||
*/
|
||||
|
||||
static struct zwp_virtual_keyboard_manager_v1 *g_virtual_keyboard_manager = NULL;
|
||||
|
||||
struct _DiyaVirtualKeyboard
|
||||
@ -151,7 +375,7 @@ DiyaVirtualKeyboard *diya_virtual_keyboard_new(DiyaShell *shell, const gchar *ke
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning("No keymap file specified.Loading default keymap from resource");
|
||||
g_warning("No keymap file specified. Loading default keymap from resource");
|
||||
GBytes *bytes = g_resources_lookup_data("/dev/iohub/diya/shell/default.keymap", 0, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
@ -159,19 +383,19 @@ DiyaVirtualKeyboard *diya_virtual_keyboard_new(DiyaShell *shell, const gchar *ke
|
||||
g_error_free(error);
|
||||
return NULL;
|
||||
}
|
||||
content = (gchar*)g_bytes_get_data(bytes, &len);
|
||||
content = (gchar *)g_bytes_get_data(bytes, &len);
|
||||
}
|
||||
|
||||
g_debug("Using default keymap configuration: \n%s", content);
|
||||
int fd = create_keymap_fd(len);
|
||||
if (fd == -1)
|
||||
{
|
||||
g_critical("diya_virtual_keyboard_new: create temp file");
|
||||
if(bytes)
|
||||
if (bytes)
|
||||
{
|
||||
g_bytes_unref(bytes);
|
||||
content = NULL;
|
||||
}
|
||||
if(content)
|
||||
if (content)
|
||||
{
|
||||
g_free(content);
|
||||
}
|
||||
@ -182,12 +406,12 @@ DiyaVirtualKeyboard *diya_virtual_keyboard_new(DiyaShell *shell, const gchar *ke
|
||||
{
|
||||
g_critical("diya_virtual_keyboard_new: error mmap: %s", strerror(errno));
|
||||
close(fd);
|
||||
if(bytes)
|
||||
if (bytes)
|
||||
{
|
||||
g_bytes_unref(bytes);
|
||||
content = NULL;
|
||||
}
|
||||
if(content)
|
||||
if (content)
|
||||
{
|
||||
g_free(content);
|
||||
}
|
||||
@ -200,7 +424,6 @@ DiyaVirtualKeyboard *diya_virtual_keyboard_new(DiyaShell *shell, const gchar *ke
|
||||
struct wl_seat *seat = diya_wayland_get_seat(wayland);
|
||||
vkb->keyboard = zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(g_virtual_keyboard_manager, seat);
|
||||
zwp_virtual_keyboard_v1_keymap(vkb->keyboard, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, fd, len);
|
||||
|
||||
|
||||
return vkb;
|
||||
}
|
||||
|
@ -16,4 +16,16 @@ DiyaVirtualKeyboard* diya_virtual_keyboard_new(DiyaShell* shell, const gchar* ke
|
||||
|
||||
void diya_virtual_keyboard_register(struct wl_registry *registry, uint32_t name, DiyaShell *shell);
|
||||
void diya_virtual_keyboard_send_key(DiyaVirtualKeyboard* vkb, uint32_t key, diya_vkb_state_t state);
|
||||
|
||||
#define DIYA_TYPE_VIRTUAL_KEYBOARD_WIDGET (diya_virtual_keyboard_widget_get_type())
|
||||
G_DECLARE_FINAL_TYPE (DiyaVirtualKeyboardWidget, diya_virtual_keyboard_widget, DIYA, VIRTUAL_KEYBOARD_WIDGET, GtkWidget)
|
||||
|
||||
DiyaVirtualKeyboardWidget* diya_virtual_keyboard_widget_new();
|
||||
|
||||
|
||||
#define DIYA_TYPE_VKB_BUTTON (diya_vkb_button_get_type())
|
||||
G_DECLARE_FINAL_TYPE (DiyaVkbButton, diya_vkb_button, DIYA, VKB_BUTTON, GtkWidget)
|
||||
|
||||
DiyaVkbButton* diya_vkb_button_new(/**with prameter */);
|
||||
|
||||
#endif
|
@ -119,7 +119,7 @@ static const struct wl_registry_listener registry_listener =
|
||||
.global_remove = handle_global_remove
|
||||
};
|
||||
|
||||
void diya_shell_wayland_init(DiyaShell *shell)
|
||||
DiyaWayland* diya_wayland_new(DiyaShell *shell)
|
||||
{
|
||||
struct wl_display *display;
|
||||
struct wl_registry *registry;
|
||||
@ -127,20 +127,20 @@ void diya_shell_wayland_init(DiyaShell *shell)
|
||||
if (!display)
|
||||
{
|
||||
g_error("Can't get wayland display");
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
DiyaWayland * wayland = g_object_new(DIYA_TYPE_WAYLAND, "shell", shell, NULL);
|
||||
g_object_set(shell, "wayland", wayland, NULL);
|
||||
//g_object_set(wayland, "shell", shell, NULL);
|
||||
registry = wl_display_get_registry(display);
|
||||
wl_registry_add_listener(registry, ®istry_listener, (void*)shell);
|
||||
wl_display_roundtrip(display);
|
||||
// wl_display_roundtrip(display);
|
||||
// wayland_monitor_probe();
|
||||
// GdkMonitor *mon = wayland_monitor_get_default();
|
||||
// g_info("default output: %s", (gchar *)g_object_get_data(G_OBJECT(mon), "xdg_name"));
|
||||
|
||||
// wl_display_roundtrip(display);
|
||||
// wl_display_roundtrip(display);
|
||||
return wayland;
|
||||
}
|
||||
|
||||
struct wl_surface* diya_wayland_create_surface(DiyaWayland * self)
|
||||
|
@ -7,4 +7,6 @@ struct wl_surface* diya_wayland_create_surface(DiyaWayland * self);
|
||||
struct wl_output* diya_wayland_get_output(DiyaWayland * self, int index);
|
||||
struct wl_shm_pool * diya_wayland_create_shm_pool(DiyaWayland * self, int fd, guint size);
|
||||
struct wl_seat* diya_wayland_get_seat(DiyaWayland* self);
|
||||
|
||||
DiyaWayland* diya_wayland_new(DiyaShell *shell);
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user