Add base support to virtual keyboard wayland extension protocol
This commit is contained in:
parent
0e8bb9027f
commit
4da1db3bd4
24
meson.build
24
meson.build
@ -17,6 +17,7 @@ add_project_arguments(
|
||||
|
||||
gtk = dependency('gtk4')
|
||||
wayland_client = dependency('wayland-client', version: '>=1.10.0')
|
||||
xkbcommon = dependency('xkbcommon')
|
||||
|
||||
# wayland_scanner is required, but we can find it without pkg-config
|
||||
wayland_scanner = find_program('wayland-scanner')
|
||||
@ -52,24 +53,31 @@ endforeach
|
||||
gnome=import('gnome')
|
||||
|
||||
base = [
|
||||
'src/base.c'
|
||||
'src/base.c',
|
||||
'src/shell.c',
|
||||
'src/wayland.c',
|
||||
'src/virtual-keyboard.c',
|
||||
wayland_targets
|
||||
]
|
||||
|
||||
dm_src = [
|
||||
base,
|
||||
'src/launcher.c',
|
||||
'src/background.c',
|
||||
'src/shell.c',
|
||||
'src/session-shell.c',
|
||||
'src/foreign.c',
|
||||
'src/session-lock.c',
|
||||
'src/wayland.c',
|
||||
'src/session.c',
|
||||
wayland_targets]
|
||||
'src/session.c']
|
||||
|
||||
buil_dep = [gtk, gtk_layer_shell, wayland_client, xkbcommon]
|
||||
|
||||
session_resource = gnome.compile_resources('session-resources','resources/session-shell/gresource.xml')
|
||||
|
||||
executable(
|
||||
'diya-shell',
|
||||
dm_src,
|
||||
dependencies: [gtk, gtk_layer_shell, wayland_client])
|
||||
session_resource,
|
||||
dependencies: buil_dep)
|
||||
|
||||
login_src = [
|
||||
base,
|
||||
@ -77,10 +85,10 @@ login_src = [
|
||||
'src/login.c'
|
||||
]
|
||||
|
||||
login_resource = gnome.compile_resources('resources','resources/login-shell/gresource.xml')
|
||||
login_resource = gnome.compile_resources('login-resources','resources/login-shell/gresource.xml')
|
||||
|
||||
executable(
|
||||
'diya-login-shell',
|
||||
login_src,
|
||||
login_resource,
|
||||
dependencies: [gtk, gtk_layer_shell, wayland_client])
|
||||
dependencies: buil_dep)
|
113
protocols/virtual-keyboard-unstable-v1.xml
Normal file
113
protocols/virtual-keyboard-unstable-v1.xml
Normal file
@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="virtual_keyboard_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2008-2011 Kristian Høgsberg
|
||||
Copyright © 2010-2013 Intel Corporation
|
||||
Copyright © 2012-2013 Collabora, Ltd.
|
||||
Copyright © 2018 Purism SPC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zwp_virtual_keyboard_v1" version="1">
|
||||
<description summary="virtual keyboard">
|
||||
The virtual keyboard provides an application with requests which emulate
|
||||
the behaviour of a physical keyboard.
|
||||
|
||||
This interface can be used by clients on its own to provide raw input
|
||||
events, or it can accompany the input method protocol.
|
||||
</description>
|
||||
|
||||
<request name="keymap">
|
||||
<description summary="keyboard mapping">
|
||||
Provide a file descriptor to the compositor which can be
|
||||
memory-mapped to provide a keyboard mapping description.
|
||||
|
||||
Format carries a value from the keymap_format enumeration.
|
||||
</description>
|
||||
<arg name="format" type="uint" summary="keymap format"/>
|
||||
<arg name="fd" type="fd" summary="keymap file descriptor"/>
|
||||
<arg name="size" type="uint" summary="keymap size, in bytes"/>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="no_keymap" value="0" summary="No keymap was set"/>
|
||||
</enum>
|
||||
|
||||
<request name="key">
|
||||
<description summary="key event">
|
||||
A key was pressed or released.
|
||||
The time argument is a timestamp with millisecond granularity, with an
|
||||
undefined base. All requests regarding a single object must share the
|
||||
same clock.
|
||||
|
||||
Keymap must be set before issuing this request.
|
||||
|
||||
State carries a value from the key_state enumeration.
|
||||
</description>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="key" type="uint" summary="key that produced the event"/>
|
||||
<arg name="state" type="uint" summary="physical state of the key"/>
|
||||
</request>
|
||||
|
||||
<request name="modifiers">
|
||||
<description summary="modifier and group state">
|
||||
Notifies the compositor that the modifier and/or group state has
|
||||
changed, and it should update state.
|
||||
|
||||
The client should use wl_keyboard.modifiers event to synchronize its
|
||||
internal state with seat state.
|
||||
|
||||
Keymap must be set before issuing this request.
|
||||
</description>
|
||||
<arg name="mods_depressed" type="uint" summary="depressed modifiers"/>
|
||||
<arg name="mods_latched" type="uint" summary="latched modifiers"/>
|
||||
<arg name="mods_locked" type="uint" summary="locked modifiers"/>
|
||||
<arg name="group" type="uint" summary="keyboard layout"/>
|
||||
</request>
|
||||
|
||||
<request name="destroy" type="destructor" since="1">
|
||||
<description summary="destroy the virtual keyboard keyboard object"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwp_virtual_keyboard_manager_v1" version="1">
|
||||
<description summary="virtual keyboard manager">
|
||||
A virtual keyboard manager allows an application to provide keyboard
|
||||
input events as if they came from a physical keyboard.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="unauthorized" value="0" summary="client not authorized to use the interface"/>
|
||||
</enum>
|
||||
|
||||
<request name="create_virtual_keyboard">
|
||||
<description summary="Create a new virtual keyboard">
|
||||
Creates a new virtual keyboard associated to a seat.
|
||||
|
||||
If the compositor enables a keyboard to perform arbitrary actions, it
|
||||
should present an error when an untrusted client requests a new
|
||||
keyboard.
|
||||
</description>
|
||||
<arg name="seat" type="object" interface="wl_seat"/>
|
||||
<arg name="id" type="new_id" interface="zwp_virtual_keyboard_v1"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
1461
resources/default.keymap
Normal file
1461
resources/default.keymap
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,5 +2,6 @@
|
||||
<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>
|
6
resources/session-shell/gresource.xml
Normal file
6
resources/session-shell/gresource.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/dev/iohub/diya/shell">
|
||||
<file alias="default.keymap">resources/default.keymap</file>
|
||||
</gresource>
|
||||
</gresources>
|
@ -9,7 +9,7 @@ static void on_background_destroy(GtkWindow *window, GApplication *_data)
|
||||
//g_application_quit (G_APPLICATION (gtk_window_get_application (window)));
|
||||
}
|
||||
|
||||
void diya_shell_init_background(DiyaShell * shell)
|
||||
void diya_session_shell_init_background(DiyaSessionShell * shell)
|
||||
{
|
||||
GtkApplication * app;
|
||||
g_object_get(shell, "application", &app, NULL);
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef DIYA_SHELL_BACKGROUND_H
|
||||
#define DIYA_SHELL_BACKGROUND_H
|
||||
|
||||
#include "shell.h"
|
||||
#include "session-shell.h"
|
||||
|
||||
void diya_shell_init_background(DiyaShell * shell);
|
||||
void diya_session_shell_init_background(DiyaSessionShell * shell);
|
||||
|
||||
#endif
|
@ -2,6 +2,7 @@
|
||||
#define DIYA_OBJECT_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* Base class object
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include "wlr-foreign-toplevel-management-unstable-v1.h"
|
||||
#include "foreign.h"
|
||||
|
||||
/**
|
||||
@ -19,7 +20,7 @@ enum
|
||||
static GParamSpec *win_properties[N_PROPERTIES] = {0};
|
||||
struct _DiyaForeignWindow
|
||||
{
|
||||
DiyaObject parent;
|
||||
DiyaShellObject parent;
|
||||
gchar * appid;
|
||||
gpointer handle;
|
||||
gchar* title;
|
||||
@ -155,9 +156,9 @@ static void toplevel_handle_title(void *data,
|
||||
struct zwlr_foreign_toplevel_handle_v1 *handle,
|
||||
const char *title)
|
||||
{
|
||||
DiyaShell *shell = (DiyaShell *)data;
|
||||
DiyaSessionShell *shell = (DiyaSessionShell *)data;
|
||||
assert(shell);
|
||||
DiyaForeignWindow *win = diya_shell_get_window(shell, handle);
|
||||
DiyaForeignWindow *win = diya_session_shell_get_window(shell, handle);
|
||||
assert(win);
|
||||
g_object_set(win, "title", title, NULL);
|
||||
g_debug("New title for: %s", diya_object_to_string(win));
|
||||
@ -166,9 +167,9 @@ static void toplevel_handle_app_id(void *data,
|
||||
struct zwlr_foreign_toplevel_handle_v1 *handle,
|
||||
const char *app_id)
|
||||
{
|
||||
DiyaShell *shell = (DiyaShell *)data;
|
||||
DiyaSessionShell *shell = (DiyaSessionShell *)data;
|
||||
assert(shell);
|
||||
DiyaForeignWindow *win = diya_shell_get_window(shell, handle);
|
||||
DiyaForeignWindow *win = diya_session_shell_get_window(shell, handle);
|
||||
assert(win);
|
||||
g_object_set(win, "appid", app_id, NULL);
|
||||
g_debug("New appid for: %s", diya_object_to_string(win));
|
||||
@ -186,9 +187,9 @@ static void toplevel_handle_state(void *data,
|
||||
struct wl_array *state)
|
||||
{
|
||||
uint32_t *entry;
|
||||
DiyaShell *shell = (DiyaShell *)data;
|
||||
DiyaSessionShell *shell = (DiyaSessionShell *)data;
|
||||
assert(shell);
|
||||
DiyaForeignWindow *win = diya_shell_get_window(shell, handle);
|
||||
DiyaForeignWindow *win = diya_session_shell_get_window(shell, handle);
|
||||
assert(win);
|
||||
enum diya_win_state wstate = DIYA_WIN_STATE_NONE;
|
||||
wl_array_for_each(entry, state) switch (*entry)
|
||||
@ -211,21 +212,21 @@ static void toplevel_handle_state(void *data,
|
||||
static void toplevel_handle_done(void *data,
|
||||
struct zwlr_foreign_toplevel_handle_v1 *handle)
|
||||
{
|
||||
DiyaShell *shell = (DiyaShell *)data;
|
||||
DiyaSessionShell *shell = (DiyaSessionShell *)data;
|
||||
assert(shell);
|
||||
DiyaForeignWindow *win = diya_shell_get_window(shell, handle);
|
||||
DiyaForeignWindow *win = diya_session_shell_get_window(shell, handle);
|
||||
assert(win);
|
||||
g_signal_emit_by_name(shell, "foreign-window-changed", (void *)win);
|
||||
}
|
||||
static void toplevel_handle_closed(void *data,
|
||||
struct zwlr_foreign_toplevel_handle_v1 *handle)
|
||||
{
|
||||
DiyaShell *shell = (DiyaShell *)data;
|
||||
DiyaSessionShell *shell = (DiyaSessionShell *)data;
|
||||
assert(shell);
|
||||
DiyaForeignWindow *win = diya_shell_get_window(shell, handle);
|
||||
DiyaForeignWindow *win = diya_session_shell_get_window(shell, handle);
|
||||
assert(win);
|
||||
g_signal_emit_by_name(shell, "foreign-window-removed", (void *)win);
|
||||
diya_shell_remove_window(shell, win);
|
||||
diya_session_shell_remove_window(shell, win);
|
||||
zwlr_foreign_toplevel_handle_v1_destroy(handle);
|
||||
}
|
||||
static void toplevel_handle_parent(void *data,
|
||||
@ -237,10 +238,10 @@ static void toplevel_handle_parent(void *data,
|
||||
return;
|
||||
}
|
||||
assert(handle != parent);
|
||||
DiyaShell *shell = (DiyaShell *)data;
|
||||
DiyaSessionShell *shell = (DiyaSessionShell *)data;
|
||||
assert(shell);
|
||||
DiyaForeignWindow *child_win = diya_shell_get_window(shell, handle);
|
||||
DiyaForeignWindow *parent_win = diya_shell_get_window(shell, parent);
|
||||
DiyaForeignWindow *child_win = diya_session_shell_get_window(shell, handle);
|
||||
DiyaForeignWindow *parent_win = diya_session_shell_get_window(shell, parent);
|
||||
assert(child_win);
|
||||
assert(parent_win);
|
||||
assert(child_win != parent_win);
|
||||
@ -260,11 +261,11 @@ static const struct zwlr_foreign_toplevel_handle_v1_listener g_toplevel_impl = {
|
||||
.parent = toplevel_handle_parent
|
||||
};
|
||||
|
||||
static DiyaForeignWindow * diya_shell_foreign_window_new(DiyaShell* shell, gpointer handle)
|
||||
static DiyaForeignWindow * diya_session_shell_foreign_window_new(DiyaSessionShell* shell, gpointer handle)
|
||||
{
|
||||
DiyaForeignWindow *win = DIYA_FOREIGN_WINDOW(g_object_new(DIYA_TYPE_FOREIGN_WINDOW,"handle", handle, "shell", shell, NULL));
|
||||
//g_object_set(win, "shell", shell, NULL);
|
||||
diya_shell_add_window(shell, win);
|
||||
diya_session_shell_add_window(shell, win);
|
||||
g_debug("Add new window 0x%" PRIXPTR, (uintptr_t)handle);
|
||||
return win;
|
||||
}
|
||||
@ -272,9 +273,9 @@ static DiyaForeignWindow * diya_shell_foreign_window_new(DiyaShell* shell, gpoin
|
||||
static void toplevel_manager_handle_toplevel(void *data, struct zwlr_foreign_toplevel_manager_v1 *toplevel_manager, struct zwlr_foreign_toplevel_handle_v1 *tl)
|
||||
{
|
||||
(void) toplevel_manager;
|
||||
DiyaShell *shell = (DiyaShell *)data;
|
||||
DiyaSessionShell *shell = (DiyaSessionShell *)data;
|
||||
assert(shell);
|
||||
DiyaForeignWindow *win = diya_shell_get_window(shell, tl);
|
||||
DiyaForeignWindow *win = diya_session_shell_get_window(shell, tl);
|
||||
|
||||
if (win)
|
||||
{
|
||||
@ -282,15 +283,15 @@ static void toplevel_manager_handle_toplevel(void *data, struct zwlr_foreign_top
|
||||
return;
|
||||
}
|
||||
// TODO: different between windows
|
||||
win = diya_shell_foreign_window_new(shell, tl);
|
||||
win = diya_session_shell_foreign_window_new(shell, tl);
|
||||
zwlr_foreign_toplevel_handle_v1_add_listener(tl, &g_toplevel_impl, data);
|
||||
}
|
||||
|
||||
static void toplevel_manager_handle_finished(void *data,
|
||||
struct zwlr_foreign_toplevel_manager_v1 *toplevel_manager)
|
||||
{
|
||||
DiyaShell *shell = (DiyaShell *)data;
|
||||
diya_shell_remove_all_windows(shell);
|
||||
DiyaSessionShell *shell = (DiyaSessionShell *)data;
|
||||
diya_session_shell_remove_all_windows(shell);
|
||||
// remove table entry
|
||||
zwlr_foreign_toplevel_manager_v1_destroy(toplevel_manager);
|
||||
}
|
||||
@ -301,8 +302,9 @@ static const struct zwlr_foreign_toplevel_manager_v1_listener g_toplevel_manager
|
||||
.finished = toplevel_manager_handle_finished,
|
||||
};
|
||||
|
||||
void diya_shell_foreign_toplevel_register(struct wl_registry *registry, uint32_t name, DiyaShell *shell)
|
||||
void diya_session_shell_foreign_toplevel_register(struct wl_registry *registry, uint32_t name, DiyaShell *shell)
|
||||
{
|
||||
DiyaSessionShell* session_shell = DIYA_SESSION_SHELL(shell);
|
||||
g_toplevel_manager = wl_registry_bind(registry, name, &zwlr_foreign_toplevel_manager_v1_interface, 3);
|
||||
zwlr_foreign_toplevel_manager_v1_add_listener(g_toplevel_manager, &g_toplevel_manager_impl, (void *)shell);
|
||||
zwlr_foreign_toplevel_manager_v1_add_listener(g_toplevel_manager, &g_toplevel_manager_impl, (void *)session_shell);
|
||||
}
|
@ -1,7 +1,16 @@
|
||||
#ifndef DIYA_SHELL_FOREIGN_H
|
||||
#define DIYA_SHELL_FOREIGN_H
|
||||
#include "wlr-foreign-toplevel-management-unstable-v1.h"
|
||||
#include "shell.h"
|
||||
#include "session-shell.h"
|
||||
|
||||
enum diya_win_state
|
||||
{
|
||||
DIYA_WIN_STATE_NONE = 0,
|
||||
DIYA_WIN_STATE_MINIMIZE = 1 << 0,
|
||||
DIYA_WIN_STATE_MAXIMIZE = 1 << 1,
|
||||
DIYA_WIN_STATE_FULLSCREEN = 1 << 2,
|
||||
DIYA_WIN_STATE_FOCUS = 1 << 3,
|
||||
};
|
||||
|
||||
void diya_session_shell_foreign_toplevel_register(struct wl_registry *registry, uint32_t name, DiyaShell * shell);
|
||||
|
||||
void diya_shell_foreign_toplevel_register(struct wl_registry *registry, uint32_t name, DiyaShell * shell);
|
||||
#endif
|
@ -12,7 +12,7 @@ static void on_launcher_destroy(GtkWindow *window, GApplication *_data)
|
||||
//g_application_quit (G_APPLICATION (gtk_window_get_application (window)));
|
||||
}
|
||||
|
||||
static void on_foreign_window_change(DiyaShell* shell, DiyaForeignWindow * win, gpointer data)
|
||||
static void on_foreign_window_change(DiyaSessionShell* shell, DiyaForeignWindow * win, gpointer data)
|
||||
{
|
||||
(void) data;
|
||||
assert(win);
|
||||
@ -20,7 +20,7 @@ static void on_foreign_window_change(DiyaShell* shell, DiyaForeignWindow * win,
|
||||
g_warning("on_foreign_window_change: WINDOW CHANGE %s, shell %s", diya_object_to_string(DIYA_OBJECT(win)), diya_object_to_string(DIYA_OBJECT(shell)));
|
||||
}
|
||||
|
||||
static void on_foreign_window_removed(DiyaShell* shell, DiyaForeignWindow * win, gpointer data)
|
||||
static void on_foreign_window_removed(DiyaSessionShell* shell, DiyaForeignWindow * win, gpointer data)
|
||||
{
|
||||
(void) data;
|
||||
assert(win);
|
||||
@ -32,10 +32,10 @@ static void session_lock(GtkWidget *widget,gpointer data)
|
||||
{
|
||||
(void) widget;
|
||||
g_warning("Enter session lock");
|
||||
diya_shell_lock(data);
|
||||
diya_session_shell_lock(data);
|
||||
}
|
||||
|
||||
void diya_shell_launcher_init(DiyaShell * shell)
|
||||
void diya_session_shell_launcher_init(DiyaSessionShell * shell)
|
||||
{
|
||||
assert(shell);
|
||||
GtkApplication * app;
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef DIYA_SHELL_LAUNCHER_H
|
||||
#define DIYA_SHELL_LAUNCHER_H
|
||||
|
||||
#include "shell.h"
|
||||
#include "session-shell.h"
|
||||
|
||||
|
||||
void diya_shell_launcher_init(DiyaShell * shell);
|
||||
void diya_session_shell_launcher_init(DiyaSessionShell * shell);
|
||||
|
||||
#endif
|
@ -1,17 +1,17 @@
|
||||
#include "login-shell.h"
|
||||
|
||||
#include <gtk4-layer-shell.h>
|
||||
#include <gtk4-session-lock.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "login-shell.h"
|
||||
#include "virtual-keyboard.h"
|
||||
|
||||
#define DBUS_SERVER_NAME "dev.iohub.diya.SessionManager"
|
||||
#define DBUS_SERVER_PATH "/dev/iohub/diya/SessionManager"
|
||||
#define DBUS_SERVER_ERROR_NAME "dev.iohub.diya.SessionManager.Error"
|
||||
|
||||
struct _DiyaLoginShell
|
||||
{
|
||||
DiyaObject parent_object;
|
||||
DiyaShell parent_object;
|
||||
GtkApplication *app;
|
||||
GtkSessionLockInstance *lock;
|
||||
GtkWidget *username;
|
||||
@ -20,7 +20,7 @@ struct _DiyaLoginShell
|
||||
guint bus_watch_id;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE(DiyaLoginShell, diya_login_shell, DIYA_TYPE_OBJECT);
|
||||
G_DEFINE_FINAL_TYPE(DiyaLoginShell, diya_login_shell, DIYA_TYPE_SHELL);
|
||||
|
||||
static void diya_login_shell_dispose(GObject *object)
|
||||
{
|
||||
@ -67,6 +67,11 @@ static void diya_login_shell_class_init(DiyaLoginShellClass *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;
|
||||
}
|
||||
|
||||
@ -169,6 +174,23 @@ static void do_login(GtkButton *button, DiyaLoginShell *self)
|
||||
// g_application_quit(G_APPLICATION(self->app));
|
||||
}
|
||||
|
||||
static void open_vkb(GtkButton *button, DiyaLoginShell *self)
|
||||
{
|
||||
(void) button;
|
||||
DiyaVirtualKeyboard* vkb = diya_virtual_keyboard_new(DIYA_SHELL(self), NULL);
|
||||
if(!vkb)
|
||||
{
|
||||
return;
|
||||
}
|
||||
g_warning("Sending A to: %s", diya_object_to_string(DIYA_OBJECT(vkb)));
|
||||
diya_virtual_keyboard_send_key(vkb,30, VKB_KEY_STATE_PRESSED);
|
||||
g_usleep(10000);
|
||||
diya_virtual_keyboard_send_key(vkb,30, VKB_KEY_STATE_RELEASED);
|
||||
g_usleep(10000);
|
||||
// send example key
|
||||
g_object_unref(vkb);
|
||||
}
|
||||
|
||||
DiyaLoginShell *diya_login_shell_new()
|
||||
{
|
||||
return g_object_new(DIYA_TYPE_LOGIN_SHELL, NULL);
|
||||
@ -232,10 +254,12 @@ void diya_login_shell_attach(DiyaLoginShell *self, GtkApplication *app)
|
||||
|
||||
gtk_box_append(GTK_BOX(box), password_box);
|
||||
|
||||
GtkWidget *button = gtk_button_new_with_label("Login");
|
||||
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
|
||||
@ -245,6 +269,11 @@ void diya_login_shell_attach(DiyaLoginShell *self, GtkApplication *app)
|
||||
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);
|
||||
|
@ -3,9 +3,10 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "base.h"
|
||||
#include "shell.h"
|
||||
|
||||
#define DIYA_TYPE_LOGIN_SHELL (diya_login_shell_get_type())
|
||||
G_DECLARE_FINAL_TYPE(DiyaLoginShell, diya_login_shell, DIYA, LOGIN_SHELL, DiyaObject);
|
||||
G_DECLARE_FINAL_TYPE(DiyaLoginShell, diya_login_shell, DIYA, LOGIN_SHELL, DiyaShell);
|
||||
|
||||
|
||||
DiyaLoginShell *diya_login_shell_new();
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "login-shell.h"
|
||||
#include "wayland.h"
|
||||
|
||||
static gchar **g_shell_argv;
|
||||
|
||||
@ -31,6 +32,7 @@ static gboolean restart(gpointer d)
|
||||
|
||||
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);
|
||||
|
@ -3,14 +3,14 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include "session-lock.h"
|
||||
|
||||
static void unlock_session(GtkButton *button, DiyaShell *shell)
|
||||
static void unlock_session(GtkButton *button, DiyaSessionShell *shell)
|
||||
{
|
||||
(void)button;
|
||||
assert(shell);
|
||||
diya_shell_unlock(shell);
|
||||
diya_session_shell_unlock(shell);
|
||||
}
|
||||
|
||||
void diya_shell_lock(DiyaShell* shell)
|
||||
void diya_session_shell_lock(DiyaSessionShell* shell)
|
||||
{
|
||||
assert(shell);
|
||||
GtkSessionLockInstance * lock;
|
||||
@ -60,7 +60,7 @@ void diya_shell_lock(DiyaShell* shell)
|
||||
gtk_window_present(gtk_window);
|
||||
}
|
||||
}
|
||||
void diya_shell_unlock(DiyaShell* shell)
|
||||
void diya_session_shell_unlock(DiyaSessionShell* shell)
|
||||
{
|
||||
assert(shell);
|
||||
GtkSessionLockInstance * lock;
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef DIYA_SESSION_LOCK_H
|
||||
#define DIYA_SESSION_LOCK_H
|
||||
|
||||
#include "shell.h"
|
||||
#include "session-shell.h"
|
||||
|
||||
void diya_shell_lock(DiyaShell* shell);
|
||||
void diya_shell_unlock(DiyaShell* shell);
|
||||
void diya_session_shell_lock(DiyaSessionShell* shell);
|
||||
void diya_session_shell_unlock(DiyaSessionShell* shell);
|
||||
|
||||
#endif
|
273
src/session-shell.c
Normal file
273
src/session-shell.c
Normal file
@ -0,0 +1,273 @@
|
||||
#include "session-shell.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <gtk4-session-lock.h>
|
||||
#include "shell.h"
|
||||
#include "foreign.h"
|
||||
|
||||
#define SHELL_DESCRIPTION "Diya GTK shell for wayland (diyac)"
|
||||
|
||||
enum
|
||||
{
|
||||
NO_PROP,
|
||||
SHELL_APP,
|
||||
SHELL_BACKGROUND_WIDGET,
|
||||
SHELL_LAUNCHPAD_WIDGET,
|
||||
SHELL_LOCK_SESSION,
|
||||
SHELL_WINDOWS,
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *shell_properties[N_PROPERTIES] = {0};
|
||||
|
||||
struct _DiyaSessionShell
|
||||
{
|
||||
DiyaShell parent;
|
||||
GtkApplication* app;
|
||||
GtkWindow* background;
|
||||
GtkWindow* launcher;
|
||||
GHashTable* windows;
|
||||
GtkSessionLockInstance* lock;
|
||||
};
|
||||
G_DEFINE_FINAL_TYPE(DiyaSessionShell, diya_session_shell, DIYA_TYPE_SHELL)
|
||||
|
||||
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");
|
||||
if(self->lock)
|
||||
{
|
||||
g_object_unref(self->lock);
|
||||
}
|
||||
G_OBJECT_CLASS(diya_session_shell_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void diya_session_shell_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
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;
|
||||
case SHELL_LAUNCHPAD_WIDGET:
|
||||
self->launcher = g_value_get_pointer(value);
|
||||
break;
|
||||
case SHELL_WINDOWS:
|
||||
//self->windows = g_value_get_pointer(value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void diya_session_shell_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
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;
|
||||
case SHELL_LAUNCHPAD_WIDGET:
|
||||
assert(self->launcher);
|
||||
g_value_set_pointer(value, self->launcher);
|
||||
break;
|
||||
case SHELL_LOCK_SESSION:
|
||||
assert(self->lock);
|
||||
g_value_set_pointer(value, self->lock);
|
||||
break;
|
||||
case SHELL_WINDOWS:
|
||||
g_value_set_pointer(value, self->windows);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const gchar* diya_session_shell_to_string(DiyaObject* object)
|
||||
{
|
||||
(void) object;
|
||||
return SHELL_DESCRIPTION;
|
||||
}
|
||||
|
||||
static void diya_session_shell_class_init(DiyaSessionShellClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_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_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 );
|
||||
shell_properties[SHELL_WINDOWS] = g_param_spec_pointer("windows", NULL, "Shell foreign windows", G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPERTIES, shell_properties);
|
||||
|
||||
g_signal_new("foreign-window-changed",
|
||||
DIYA_TYPE_SESSION_SHELL,
|
||||
G_SIGNAL_DETAILED |
|
||||
G_SIGNAL_ACTION |
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_POINTER);
|
||||
g_signal_new("foreign-window-removed",
|
||||
DIYA_TYPE_SESSION_SHELL,
|
||||
G_SIGNAL_DETAILED |
|
||||
G_SIGNAL_ACTION |
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_POINTER);
|
||||
g_signal_new("session-locked",
|
||||
DIYA_TYPE_SESSION_SHELL,
|
||||
G_SIGNAL_DETAILED |
|
||||
G_SIGNAL_ACTION |
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
g_signal_new("session-unlocked",
|
||||
DIYA_TYPE_SESSION_SHELL,
|
||||
G_SIGNAL_DETAILED |
|
||||
G_SIGNAL_ACTION |
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
}
|
||||
|
||||
static void on_session_locked(GtkSessionLockInstance *lock, DiyaSessionShell *shell) {
|
||||
(void)lock;
|
||||
assert(shell);
|
||||
g_message("Session locked successfully");
|
||||
g_signal_emit_by_name(shell, "session-locked");
|
||||
}
|
||||
|
||||
/*
|
||||
static void failed(GtkSessionLockInstance *lock, void *data) {
|
||||
(void)lock;
|
||||
(void)data;
|
||||
|
||||
g_critical("The session could not be locked");
|
||||
g_application_quit(G_APPLICATION(app));
|
||||
}
|
||||
*/
|
||||
|
||||
static void on_session_unlocked(GtkSessionLockInstance *lock, DiyaSessionShell *shell) {
|
||||
(void)lock;
|
||||
assert(shell);
|
||||
g_message("Session unlocked");
|
||||
g_signal_emit_by_name(shell, "session-unlocked");
|
||||
}
|
||||
|
||||
static void diya_session_shell_init(DiyaSessionShell *self)
|
||||
{
|
||||
//self->app = NULL;
|
||||
self->background = NULL;
|
||||
self->launcher = NULL;
|
||||
self->lock = gtk_session_lock_instance_new();
|
||||
g_signal_connect(self->lock, "locked", G_CALLBACK(on_session_locked), self);
|
||||
// g_signal_connect(lock, "failed", G_CALLBACK(failed), NULL);
|
||||
g_signal_connect(self->lock, "unlocked", G_CALLBACK(on_session_unlocked), self);
|
||||
self->windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
|
||||
}
|
||||
|
||||
DiyaForeignWindow* diya_session_shell_get_window(DiyaSessionShell * shell, gpointer handle)
|
||||
{
|
||||
return g_hash_table_lookup(shell->windows, handle);
|
||||
}
|
||||
gboolean diya_session_shell_add_window(DiyaSessionShell * shell, DiyaForeignWindow * win)
|
||||
{
|
||||
gpointer handle;
|
||||
g_object_get(win, "handle", &handle, NULL);
|
||||
assert(handle);
|
||||
return g_hash_table_insert(shell->windows,handle, win);
|
||||
}
|
||||
|
||||
gboolean diya_session_shell_remove_window(DiyaSessionShell * shell, DiyaForeignWindow * win)
|
||||
{
|
||||
gpointer handle;
|
||||
g_object_get(win, "handle", &handle, NULL);
|
||||
assert(handle);
|
||||
return g_hash_table_remove(shell->windows,handle);
|
||||
}
|
||||
|
||||
void diya_session_shell_remove_all_windows(DiyaSessionShell * shell)
|
||||
{
|
||||
g_hash_table_destroy(shell->windows);
|
||||
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)
|
||||
{
|
||||
(void)window;
|
||||
GtkOrientation orient_toplevel, orient_sub;
|
||||
orient_toplevel = GTK_ORIENTATION_HORIZONTAL;
|
||||
orient_sub = GTK_ORIENTATION_VERTICAL;
|
||||
|
||||
switch (orientation) {
|
||||
case WINDOW_ORIENTATION_HORIZONTAL:
|
||||
orient_toplevel = GTK_ORIENTATION_HORIZONTAL;
|
||||
orient_sub = GTK_ORIENTATION_HORIZONTAL;
|
||||
break;
|
||||
case WINDOW_ORIENTATION_VERTICAL:
|
||||
orient_toplevel = GTK_ORIENTATION_VERTICAL;
|
||||
orient_sub = GTK_ORIENTATION_VERTICAL;
|
||||
break;
|
||||
case WINDOW_ORIENTATION_NONE:
|
||||
orient_toplevel = GTK_ORIENTATION_HORIZONTAL;
|
||||
orient_sub = GTK_ORIENTATION_VERTICAL;
|
||||
break;
|
||||
}
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (data->toplevel_box), orient_toplevel);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (data->first_box), orient_sub);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (data->second_box), orient_sub);
|
||||
//gtk_window_resize (window, 1, 1); // force the window to shrink to the smallest size it can
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
static void before_destroy (GtkWidget *win, GtkCssProvider *provider) {
|
||||
GdkDisplay *display = gdk_display_get_default ();
|
||||
gtk_style_context_remove_provider_for_display (display, GTK_STYLE_PROVIDER (provider));
|
||||
}
|
||||
*/
|
20
src/session-shell.h
Normal file
20
src/session-shell.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef DIYA_SESSION_SHELL_H
|
||||
#define DIYA_SESSION_SHELL_H
|
||||
|
||||
#include <gtk4-layer-shell.h>
|
||||
#include "shell.h"
|
||||
#include "base.h"
|
||||
|
||||
#define DIYA_TYPE_SESSION_SHELL (diya_session_shell_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DiyaSessionShell, diya_session_shell, DIYA, SESSION_SHELL, DiyaShell)
|
||||
|
||||
#define DIYA_TYPE_FOREIGN_WINDOW (diya_foreign_window_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DiyaForeignWindow, diya_foreign_window, DIYA, FOREIGN_WINDOW, DiyaShellObject)
|
||||
|
||||
DiyaForeignWindow* diya_session_shell_get_window(DiyaSessionShell * shell, gpointer handle);
|
||||
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
|
@ -14,8 +14,8 @@ static void activate(GtkApplication *app, void *data)
|
||||
(void)app;
|
||||
(void)data;
|
||||
|
||||
DiyaShell *shell = data;
|
||||
diya_shell_lock(shell);
|
||||
DiyaSessionShell *shell = data;
|
||||
diya_session_shell_lock(shell);
|
||||
}
|
||||
|
||||
static gboolean restart(gpointer d)
|
||||
@ -37,11 +37,11 @@ static gboolean restart(gpointer d)
|
||||
|
||||
static void startup(GtkApplication *app, void *data)
|
||||
{
|
||||
DiyaShell *shell = data;
|
||||
DiyaSessionShell *shell = data;
|
||||
|
||||
diya_shell_launcher_init(shell);
|
||||
diya_shell_wayland_init(shell);
|
||||
diya_shell_init_background(shell);
|
||||
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;}";
|
||||
@ -57,14 +57,14 @@ static void startup(GtkApplication *app, void *data)
|
||||
g_unix_signal_add(SIGINT,(GSourceFunc)g_application_quit,(void*)app);
|
||||
}
|
||||
|
||||
static void session_locked(DiyaShell* shell, void* data)
|
||||
static void session_locked(DiyaSessionShell* shell, void* data)
|
||||
{
|
||||
(void)data;
|
||||
assert(shell);
|
||||
g_warning("session_locked callback triggered");
|
||||
}
|
||||
|
||||
static void session_unlocked(DiyaShell* shell, void* data)
|
||||
static void session_unlocked(DiyaSessionShell* shell, void* data)
|
||||
{
|
||||
(void)data;
|
||||
assert(shell);
|
||||
@ -79,7 +79,7 @@ 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);
|
||||
DiyaShell *shell = diya_shell_new(app);
|
||||
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_signal_connect(shell, "session-locked", G_CALLBACK(session_locked), NULL);
|
||||
|
262
src/shell.c
262
src/shell.c
@ -1,47 +1,35 @@
|
||||
#include <assert.h>
|
||||
#include <gtk4-session-lock.h>
|
||||
#include "shell.h"
|
||||
|
||||
#define SHELL_DESCRIPTION "Diya GTK shell for wayland (diyac)"
|
||||
|
||||
#include "wayland.h"
|
||||
#include "virtual-keyboard.h"
|
||||
enum
|
||||
{
|
||||
NO_PROP,
|
||||
SHELL_APP,
|
||||
SHELL_BACKGROUND_WIDGET,
|
||||
SHELL_LAUNCHPAD_WIDGET,
|
||||
SHELL_LOCK_SESSION,
|
||||
SHELL_WINDOWS,
|
||||
SHELL_WAYLAND,
|
||||
PROP_SHELL_WAYLAND,
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *shell_properties[N_PROPERTIES] = {0};
|
||||
|
||||
struct _DiyaShell
|
||||
|
||||
typedef struct _DiyaShellPrivate
|
||||
{
|
||||
DiyaObject parent;
|
||||
GtkApplication* app;
|
||||
GtkWindow* background;
|
||||
GtkWindow* launcher;
|
||||
GHashTable* windows;
|
||||
GtkSessionLockInstance* lock;
|
||||
DiyaWayland * wayland;
|
||||
};
|
||||
G_DEFINE_FINAL_TYPE(DiyaShell, diya_shell, DIYA_TYPE_OBJECT)
|
||||
DiyaVirtualKeyboard* vkb;
|
||||
} DiyaShellPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE(DiyaShell, diya_shell, DIYA_TYPE_OBJECT);
|
||||
|
||||
|
||||
|
||||
static void diya_shell_dispose(GObject* object)
|
||||
{
|
||||
g_debug("diya_shell_dispose: %s", diya_object_to_string(object));
|
||||
DiyaShell * self = DIYA_SHELL(object);
|
||||
g_hash_table_destroy(self->windows);
|
||||
g_debug("diya_shell_dispose");
|
||||
if(self->wayland)
|
||||
DiyaShellPrivate* priv = diya_shell_get_instance_private(self);
|
||||
if(priv->wayland)
|
||||
{
|
||||
g_object_unref(self->wayland);
|
||||
}
|
||||
if(self->lock)
|
||||
{
|
||||
g_object_unref(self->lock);
|
||||
g_object_unref(priv->wayland);
|
||||
}
|
||||
G_OBJECT_CLASS(diya_shell_parent_class)->dispose(object);
|
||||
}
|
||||
@ -49,23 +37,12 @@ static void diya_shell_dispose(GObject* object)
|
||||
static void diya_shell_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
DiyaShell * self = DIYA_SHELL(object);
|
||||
DiyaShellPrivate* priv = diya_shell_get_instance_private(self);
|
||||
|
||||
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;
|
||||
case SHELL_LAUNCHPAD_WIDGET:
|
||||
self->launcher = g_value_get_pointer(value);
|
||||
break;
|
||||
case SHELL_WAYLAND:
|
||||
self->wayland = g_value_get_pointer(value);
|
||||
break;
|
||||
case SHELL_WINDOWS:
|
||||
//self->windows = g_value_get_pointer(value);
|
||||
case PROP_SHELL_WAYLAND:
|
||||
priv->wayland = g_value_get_pointer(value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
@ -76,27 +53,11 @@ static void diya_shell_set_property(GObject *object, guint property_id, const GV
|
||||
static void diya_shell_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
DiyaShell * self = DIYA_SHELL(object);
|
||||
DiyaShellPrivate* priv = diya_shell_get_instance_private(self);
|
||||
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;
|
||||
case SHELL_LAUNCHPAD_WIDGET:
|
||||
assert(self->launcher);
|
||||
g_value_set_pointer(value, self->launcher);
|
||||
break;
|
||||
case SHELL_LOCK_SESSION:
|
||||
assert(self->lock);
|
||||
g_value_set_pointer(value, self->lock);
|
||||
break;
|
||||
case SHELL_WAYLAND:
|
||||
g_value_set_pointer(value, self->wayland);
|
||||
break;
|
||||
case SHELL_WINDOWS:
|
||||
g_value_set_pointer(value, self->windows);
|
||||
case PROP_SHELL_WAYLAND:
|
||||
g_value_set_pointer(value, priv->wayland);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
@ -104,145 +65,11 @@ static void diya_shell_get_property(GObject *object, guint property_id, GValue *
|
||||
}
|
||||
}
|
||||
|
||||
static const gchar* diya_shell_to_string(DiyaObject* object)
|
||||
{
|
||||
(void) object;
|
||||
return SHELL_DESCRIPTION;
|
||||
}
|
||||
|
||||
static void diya_shell_class_init(DiyaShellClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
|
||||
DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class);
|
||||
|
||||
base_class->to_string = diya_shell_to_string;
|
||||
gobject_class->dispose = diya_shell_dispose;
|
||||
gobject_class->set_property = diya_shell_set_property;
|
||||
gobject_class->get_property = diya_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 );
|
||||
shell_properties[SHELL_WINDOWS] = g_param_spec_pointer("windows", NULL, "Shell foreign windows", G_PARAM_READABLE);
|
||||
shell_properties[SHELL_WAYLAND] = g_param_spec_pointer("wayland", NULL, "Shell wayland", G_PARAM_READWRITE );
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPERTIES, shell_properties);
|
||||
|
||||
g_signal_new("foreign-window-changed",
|
||||
DIYA_TYPE_SHELL,
|
||||
G_SIGNAL_DETAILED |
|
||||
G_SIGNAL_ACTION |
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_POINTER);
|
||||
g_signal_new("foreign-window-removed",
|
||||
DIYA_TYPE_SHELL,
|
||||
G_SIGNAL_DETAILED |
|
||||
G_SIGNAL_ACTION |
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_POINTER);
|
||||
g_signal_new("session-locked",
|
||||
DIYA_TYPE_SHELL,
|
||||
G_SIGNAL_DETAILED |
|
||||
G_SIGNAL_ACTION |
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
g_signal_new("session-unlocked",
|
||||
DIYA_TYPE_SHELL,
|
||||
G_SIGNAL_DETAILED |
|
||||
G_SIGNAL_ACTION |
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
}
|
||||
|
||||
static void on_session_locked(GtkSessionLockInstance *lock, DiyaShell *shell) {
|
||||
(void)lock;
|
||||
assert(shell);
|
||||
g_message("Session locked successfully");
|
||||
g_signal_emit_by_name(shell, "session-locked");
|
||||
}
|
||||
|
||||
/*
|
||||
static void failed(GtkSessionLockInstance *lock, void *data) {
|
||||
(void)lock;
|
||||
(void)data;
|
||||
|
||||
g_critical("The session could not be locked");
|
||||
g_application_quit(G_APPLICATION(app));
|
||||
}
|
||||
*/
|
||||
|
||||
static void on_session_unlocked(GtkSessionLockInstance *lock, DiyaShell *shell) {
|
||||
(void)lock;
|
||||
assert(shell);
|
||||
g_message("Session unlocked");
|
||||
g_signal_emit_by_name(shell, "session-unlocked");
|
||||
}
|
||||
|
||||
static void diya_shell_init(DiyaShell *self)
|
||||
{
|
||||
//self->app = NULL;
|
||||
self->background = NULL;
|
||||
self->launcher = NULL;
|
||||
self->wayland = NULL;
|
||||
self->lock = gtk_session_lock_instance_new();
|
||||
g_signal_connect(self->lock, "locked", G_CALLBACK(on_session_locked), self);
|
||||
// g_signal_connect(lock, "failed", G_CALLBACK(failed), NULL);
|
||||
g_signal_connect(self->lock, "unlocked", G_CALLBACK(on_session_unlocked), self);
|
||||
self->windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
|
||||
}
|
||||
|
||||
DiyaForeignWindow* diya_shell_get_window(DiyaShell * shell, gpointer handle)
|
||||
{
|
||||
return g_hash_table_lookup(shell->windows, handle);
|
||||
}
|
||||
gboolean diya_shell_add_window(DiyaShell * shell, DiyaForeignWindow * win)
|
||||
{
|
||||
gpointer handle;
|
||||
g_object_get(win, "handle", &handle, NULL);
|
||||
assert(handle);
|
||||
return g_hash_table_insert(shell->windows,handle, win);
|
||||
}
|
||||
|
||||
gboolean diya_shell_remove_window(DiyaShell * shell, DiyaForeignWindow * win)
|
||||
{
|
||||
gpointer handle;
|
||||
g_object_get(win, "handle", &handle, NULL);
|
||||
assert(handle);
|
||||
return g_hash_table_remove(shell->windows,handle);
|
||||
}
|
||||
|
||||
void diya_shell_remove_all_windows(DiyaShell * shell)
|
||||
{
|
||||
g_hash_table_destroy(shell->windows);
|
||||
shell->windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
|
||||
}
|
||||
|
||||
DiyaShell * diya_shell_new(GtkApplication * app)
|
||||
{
|
||||
return DIYA_SHELL(g_object_new(DIYA_TYPE_SHELL,"application",app, NULL));
|
||||
DiyaShellPrivate* priv = diya_shell_get_instance_private(self);
|
||||
priv->wayland = NULL;
|
||||
}
|
||||
|
||||
DiyaWayland * diya_shell_get_wayland(DiyaShell* shell)
|
||||
@ -252,38 +79,17 @@ DiyaWayland * diya_shell_get_wayland(DiyaShell* shell)
|
||||
assert(DIYA_IS_WAYLAND(wayland));
|
||||
return wayland;
|
||||
}
|
||||
/*
|
||||
static void on_orientation_changed (GtkWindow *window, WindowOrientation orientation, ToplevelData *data)
|
||||
|
||||
static void diya_shell_class_init(DiyaShellClass *class)
|
||||
{
|
||||
(void)window;
|
||||
GtkOrientation orient_toplevel, orient_sub;
|
||||
orient_toplevel = GTK_ORIENTATION_HORIZONTAL;
|
||||
orient_sub = GTK_ORIENTATION_VERTICAL;
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
|
||||
gobject_class->dispose = diya_shell_dispose;
|
||||
gobject_class->set_property = diya_shell_set_property;
|
||||
gobject_class->get_property = diya_shell_get_property;
|
||||
|
||||
switch (orientation) {
|
||||
case WINDOW_ORIENTATION_HORIZONTAL:
|
||||
orient_toplevel = GTK_ORIENTATION_HORIZONTAL;
|
||||
orient_sub = GTK_ORIENTATION_HORIZONTAL;
|
||||
break;
|
||||
case WINDOW_ORIENTATION_VERTICAL:
|
||||
orient_toplevel = GTK_ORIENTATION_VERTICAL;
|
||||
orient_sub = GTK_ORIENTATION_VERTICAL;
|
||||
break;
|
||||
case WINDOW_ORIENTATION_NONE:
|
||||
orient_toplevel = GTK_ORIENTATION_HORIZONTAL;
|
||||
orient_sub = GTK_ORIENTATION_VERTICAL;
|
||||
break;
|
||||
}
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (data->toplevel_box), orient_toplevel);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (data->first_box), orient_sub);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (data->second_box), orient_sub);
|
||||
//gtk_window_resize (window, 1, 1); // force the window to shrink to the smallest size it can
|
||||
}
|
||||
*/
|
||||
class->foreign_register = NULL;
|
||||
class->virtual_keyboard_register = diya_virtual_keyboard_register;
|
||||
|
||||
/*
|
||||
static void before_destroy (GtkWidget *win, GtkCssProvider *provider) {
|
||||
GdkDisplay *display = gdk_display_get_default ();
|
||||
gtk_style_context_remove_provider_for_display (display, GTK_STYLE_PROVIDER (provider));
|
||||
shell_properties[PROP_SHELL_WAYLAND] = g_param_spec_pointer("wayland", NULL, "Shell wayland", G_PARAM_READWRITE); //
|
||||
g_object_class_install_properties (gobject_class, N_PROPERTIES, shell_properties);
|
||||
}
|
||||
*/
|
||||
|
32
src/shell.h
32
src/shell.h
@ -1,31 +1,27 @@
|
||||
#ifndef DIYA_SHELL_H
|
||||
#define DIYA_SHELL_H
|
||||
#include <gtk4-layer-shell.h>
|
||||
#include <stdint.h>
|
||||
#include "base.h"
|
||||
|
||||
enum diya_win_state
|
||||
{
|
||||
DIYA_WIN_STATE_NONE = 0,
|
||||
DIYA_WIN_STATE_MINIMIZE = 1 << 0,
|
||||
DIYA_WIN_STATE_MAXIMIZE = 1 << 1,
|
||||
DIYA_WIN_STATE_FULLSCREEN = 1 << 2,
|
||||
DIYA_WIN_STATE_FOCUS = 1 << 3,
|
||||
};
|
||||
|
||||
#define DIYA_TYPE_SHELL (diya_shell_get_type())
|
||||
G_DECLARE_FINAL_TYPE (DiyaShell, diya_shell, DIYA, SHELL, DiyaObject)
|
||||
G_DECLARE_DERIVABLE_TYPE(DiyaShell, diya_shell, DIYA, SHELL, DiyaObject)
|
||||
|
||||
#define DIYA_TYPE_WAYLAND (diya_wayland_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DiyaWayland, diya_wayland, DIYA, WAYLAND, DiyaShellObject)
|
||||
|
||||
#define DIYA_TYPE_FOREIGN_WINDOW (diya_foreign_window_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DiyaForeignWindow, diya_foreign_window, DIYA, FOREIGN_WINDOW, DiyaShellObject)
|
||||
struct wl_registry;
|
||||
|
||||
DiyaForeignWindow* diya_shell_get_window(DiyaShell * shell, gpointer handle);
|
||||
gboolean diya_shell_add_window(DiyaShell * shell, DiyaForeignWindow * win);
|
||||
gboolean diya_shell_remove_window(DiyaShell * shell, DiyaForeignWindow * win);
|
||||
void diya_shell_remove_all_windows(DiyaShell * shell);
|
||||
typedef void (*wl_protocol_manager_register_t)(struct wl_registry*, uint32_t,DiyaShell*);
|
||||
|
||||
DiyaShell * diya_shell_new(GtkApplication * app);
|
||||
struct _DiyaShellClass
|
||||
{
|
||||
DiyaObjectClass parent_class;
|
||||
wl_protocol_manager_register_t foreign_register;
|
||||
wl_protocol_manager_register_t virtual_keyboard_register;
|
||||
};
|
||||
|
||||
void diya_shell_wayland_init(DiyaShell *shell);
|
||||
DiyaWayland * diya_shell_get_wayland(DiyaShell* shell);
|
||||
|
||||
|
||||
#endif
|
@ -0,0 +1,220 @@
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <gio/gio.h>
|
||||
#include "virtual-keyboard-unstable-v1.h"
|
||||
#include "virtual-keyboard.h"
|
||||
#include "wayland.h"
|
||||
|
||||
static struct zwp_virtual_keyboard_manager_v1 *g_virtual_keyboard_manager = NULL;
|
||||
|
||||
struct _DiyaVirtualKeyboard
|
||||
{
|
||||
DiyaShellObject parent;
|
||||
struct zwp_virtual_keyboard_v1 *keyboard;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE(DiyaVirtualKeyboard, diya_virtual_keyboard, DIYA_TYPE_SHELL_OBJECT);
|
||||
|
||||
static void diya_virtual_keyboard_dispose(GObject *object)
|
||||
{
|
||||
DiyaVirtualKeyboard *self = DIYA_VIRTUAL_KEYBOARD(object);
|
||||
g_debug("diya_virtual_keyboard_dispose");
|
||||
if (self->keyboard)
|
||||
{
|
||||
zwp_virtual_keyboard_v1_destroy(self->keyboard);
|
||||
}
|
||||
G_OBJECT_CLASS(diya_virtual_keyboard_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void diya_virtual_keyboard_init(DiyaVirtualKeyboard *self)
|
||||
{
|
||||
self->keyboard = NULL;
|
||||
}
|
||||
|
||||
static const gchar *diya_virtual_keyboard_to_string(DiyaObject *object)
|
||||
{
|
||||
(void)object;
|
||||
return "Diya virtual keyboard instance";
|
||||
}
|
||||
|
||||
static void diya_virtual_keyboard_class_init(DiyaVirtualKeyboardClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
|
||||
DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class);
|
||||
|
||||
gobject_class->dispose = diya_virtual_keyboard_dispose;
|
||||
// gobject_class->set_property = diya_lock_session_set_property;
|
||||
// gobject_class->get_property = diya_lock_session_get_property;
|
||||
base_class->to_string = diya_virtual_keyboard_to_string;
|
||||
}
|
||||
|
||||
/*
|
||||
static void randname(char *buf)
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
long r = ts.tv_nsec;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
buf[i] = 'A' + (r & 15) + (r & 16) * 2;
|
||||
r >>= 5;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static int create_keymap_fd(off_t size)
|
||||
{
|
||||
static const char name[] = "/diya-shell-keymap-XXXXXX";
|
||||
const char *base;
|
||||
char *path;
|
||||
int fd;
|
||||
int ret;
|
||||
// randname(name + sizeof(name) - 7);
|
||||
base = getenv("XDG_RUNTIME_DIR");
|
||||
if (!base)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
path = malloc(strlen(base) + sizeof(name) + 1);
|
||||
if (!path)
|
||||
return -1;
|
||||
|
||||
strcpy(path, base);
|
||||
strcat(path, name);
|
||||
g_debug("Create temp file for keymap: %s", path);
|
||||
|
||||
fd = mkstemp(path);
|
||||
if (fd >= 0)
|
||||
{
|
||||
long flags;
|
||||
flags = fcntl(fd, F_GETFD);
|
||||
if (flags == -1)
|
||||
{
|
||||
g_critical("fcntl Unable to F_GETFD: %s", strerror(errno));
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
else if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
|
||||
{
|
||||
g_critical("fcntl Unable to F_SETFD(FD_CLOEXEC): %s", strerror(errno));
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
unlink(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_critical("mkstemp Unable to create temp file %s: %s", path, strerror(errno));
|
||||
}
|
||||
free(path);
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
do
|
||||
{
|
||||
ret = ftruncate(fd, size);
|
||||
} while (ret < 0 && errno == EINTR);
|
||||
if (ret < 0)
|
||||
{
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
DiyaVirtualKeyboard *diya_virtual_keyboard_new(DiyaShell *shell, const gchar *keymap_file)
|
||||
{
|
||||
gchar *content = NULL;
|
||||
GError *error = NULL;
|
||||
GBytes *bytes = NULL;
|
||||
gsize len = 0;
|
||||
|
||||
if (keymap_file)
|
||||
{
|
||||
g_file_get_contents(keymap_file, &content, &len, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_critical("diya_virtual_keyboard_new: Unable to read file %s: %s", keymap_file, error->message);
|
||||
g_error_free(error);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
g_critical("Unable to read keymap file from resource %s", error->message);
|
||||
g_error_free(error);
|
||||
return NULL;
|
||||
}
|
||||
content = (gchar*)g_bytes_get_data(bytes, &len);
|
||||
}
|
||||
|
||||
int fd = create_keymap_fd(len);
|
||||
if (fd == -1)
|
||||
{
|
||||
g_critical("diya_virtual_keyboard_new: create temp file");
|
||||
if(bytes)
|
||||
{
|
||||
g_bytes_unref(bytes);
|
||||
content = NULL;
|
||||
}
|
||||
if(content)
|
||||
{
|
||||
g_free(content);
|
||||
}
|
||||
}
|
||||
|
||||
void *ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (ptr == (void *)-1)
|
||||
{
|
||||
g_critical("diya_virtual_keyboard_new: error mmap: %s", strerror(errno));
|
||||
close(fd);
|
||||
if(bytes)
|
||||
{
|
||||
g_bytes_unref(bytes);
|
||||
content = NULL;
|
||||
}
|
||||
if(content)
|
||||
{
|
||||
g_free(content);
|
||||
}
|
||||
}
|
||||
|
||||
strcpy((char *)ptr, content);
|
||||
|
||||
DiyaVirtualKeyboard *vkb = g_object_new(DIYA_TYPE_VIRTUAL_KEYBOARD, "shell", shell, NULL);
|
||||
DiyaWayland *wayland = diya_shell_get_wayland(shell);
|
||||
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;
|
||||
}
|
||||
|
||||
void diya_virtual_keyboard_register(struct wl_registry *registry, uint32_t name, DiyaShell *shell)
|
||||
{
|
||||
(void)shell;
|
||||
g_virtual_keyboard_manager = wl_registry_bind(registry, name, &zwp_virtual_keyboard_manager_v1_interface, 1);
|
||||
}
|
||||
|
||||
void diya_virtual_keyboard_send_key(DiyaVirtualKeyboard *self, uint32_t key, diya_vkb_state_t state)
|
||||
{
|
||||
GDateTime *now = g_date_time_new_now_local();
|
||||
uint32_t current_time_ms = g_date_time_get_microsecond(now) / 1000;
|
||||
g_date_time_unref(now);
|
||||
zwp_virtual_keyboard_v1_key(self->keyboard, current_time_ms, key, (uint32_t)state);
|
||||
}
|
@ -1,8 +1,19 @@
|
||||
#ifndef DIYA_VIRTUAL_KEYBOARD_H
|
||||
#define DIYA_VIRTUAL_KEYBOARD_H
|
||||
|
||||
#include "virtual-keyboard-unstable-v1.h"
|
||||
#include "shell.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VKB_KEY_STATE_RELEASED = 0 /*WL_KEYBOARD_KEY_STATE_RELEASED*/,
|
||||
VKB_KEY_STATE_PRESSED = 1 /*WL_KEYBOARD_KEY_STATE_PRESSED*/,
|
||||
} diya_vkb_state_t;
|
||||
|
||||
#define DIYA_TYPE_VIRTUAL_KEYBOARD (diya_virtual_keyboard_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DiyaVirtualKeyboard, diya_virtual_keyboard, DIYA, VIRTUAL_KEYBOARD, DiyaShellObject)
|
||||
|
||||
DiyaVirtualKeyboard* diya_virtual_keyboard_new(DiyaShell* shell, const gchar* keymap_file);
|
||||
|
||||
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);
|
||||
#endif
|
@ -1,15 +1,17 @@
|
||||
#include <wayland-client-protocol.h>
|
||||
#include <gdk/wayland/gdkwayland.h>
|
||||
#include <assert.h>
|
||||
#include "wlr-foreign-toplevel-management-unstable-v1.h"
|
||||
#include "virtual-keyboard-unstable-v1.h"
|
||||
#include "wayland.h"
|
||||
#include "foreign.h"
|
||||
|
||||
|
||||
struct _DiyaWayland
|
||||
{
|
||||
DiyaObject parent;
|
||||
DiyaShellObject parent;
|
||||
struct wl_compositor * compositor;
|
||||
struct wl_shm * shm;
|
||||
struct wl_seat * seat;
|
||||
};
|
||||
G_DEFINE_FINAL_TYPE(DiyaWayland, diya_wayland, DIYA_TYPE_SHELL_OBJECT)
|
||||
|
||||
@ -17,7 +19,7 @@ static void diya_wayland_dispose(GObject* object)
|
||||
{
|
||||
(void) object;
|
||||
//DiyaWayland * self = DIYA_WAYLAND(object);
|
||||
g_debug("diya_wayland_dispose");
|
||||
g_debug("diya_wayland_dispose: %s", diya_object_to_string(object));
|
||||
G_OBJECT_CLASS(diya_wayland_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
@ -25,17 +27,24 @@ static void diya_wayland_init(DiyaWayland * self)
|
||||
{
|
||||
self->compositor = NULL;
|
||||
self->shm = NULL;
|
||||
self->seat = NULL;
|
||||
}
|
||||
|
||||
static const gchar* diya_wayland_to_string(DiyaObject* object)
|
||||
{
|
||||
(void) object;
|
||||
return "DiyaWayland - wayland client handle object";
|
||||
}
|
||||
|
||||
static void diya_wayland_class_init(DiyaWaylandClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
|
||||
//DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class);
|
||||
DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class);
|
||||
|
||||
gobject_class->dispose = diya_wayland_dispose;
|
||||
//gobject_class->set_property = diya_lock_session_set_property;
|
||||
//gobject_class->get_property = diya_lock_session_get_property;
|
||||
//base_class->to_string = diya_lock_session_to_string;
|
||||
base_class->to_string = diya_wayland_to_string;
|
||||
}
|
||||
|
||||
|
||||
@ -52,18 +61,34 @@ static void handle_global(void *data, struct wl_registry *registry, uint32_t nam
|
||||
*/
|
||||
(void) version;
|
||||
DiyaShell * shell = data;
|
||||
DiyaShellClass * class = DIYA_SHELL_GET_CLASS(shell);
|
||||
DiyaWayland * wayland;
|
||||
g_object_get(shell, "wayland", &wayland, NULL);
|
||||
assert(DIYA_IS_WAYLAND(wayland));
|
||||
g_debug("WAYLAND GLOBAL: %s", interface);
|
||||
|
||||
if (g_strcmp0(interface, zwlr_foreign_toplevel_manager_v1_interface.name) == 0)
|
||||
{
|
||||
diya_shell_foreign_toplevel_register(registry, name, data);
|
||||
if(class->foreign_register)
|
||||
{
|
||||
//diya_session_shell_foreign_toplevel_register(registry, name, data);
|
||||
g_debug("Wayland: register shell foreign top level manager");
|
||||
class->foreign_register(registry, name, data);
|
||||
}
|
||||
}
|
||||
if (g_strcmp0(interface, zwp_virtual_keyboard_manager_v1_interface.name) == 0)
|
||||
{
|
||||
if(class->virtual_keyboard_register)
|
||||
{
|
||||
//diya_session_shell_foreign_toplevel_register(registry, name, data);
|
||||
g_debug("Wayland: register virtual keyboard manager");
|
||||
class->virtual_keyboard_register(registry, name, data);
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if(!g_strcmp0(interface, ext_session_lock_manager_v1_interface.name))
|
||||
{
|
||||
diya_shell_session_lock_register(registry, name);
|
||||
diya_session_shell_session_lock_register(registry, name);
|
||||
}
|
||||
*/
|
||||
else if (strcmp(interface, wl_compositor_interface.name) == 0)
|
||||
@ -74,6 +99,10 @@ static void handle_global(void *data, struct wl_registry *registry, uint32_t nam
|
||||
{
|
||||
wayland->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
|
||||
}
|
||||
else if (strcmp(interface, wl_seat_interface.name) == 0)
|
||||
{
|
||||
wayland->seat = wl_registry_bind(registry, name, &wl_seat_interface, 7);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_global_remove(void *data, struct wl_registry *registry,
|
||||
@ -143,3 +172,9 @@ struct wl_shm_pool * diya_wayland_create_shm_pool(DiyaWayland * self, int fd, gu
|
||||
assert(self->shm);
|
||||
return wl_shm_create_pool(self->shm, fd, size);
|
||||
}
|
||||
|
||||
struct wl_seat* diya_wayland_get_seat(DiyaWayland* self)
|
||||
{
|
||||
assert(self->seat);
|
||||
return self->seat;
|
||||
}
|
@ -3,8 +3,8 @@
|
||||
|
||||
#include "shell.h"
|
||||
|
||||
void diya_shell_wayland_init(DiyaShell *shell);
|
||||
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);
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user