Merge branch 'layer-shell' into 'master'
Hide/show window instead of destroying it Closes #42 See merge request Librem5/squeekboard!76
This commit is contained in:
@ -65,9 +65,9 @@ static void layer_surface_configure(void *data,
|
||||
uint32_t height)
|
||||
{
|
||||
PhoshLayerSurface *self = data;
|
||||
|
||||
gtk_window_resize (GTK_WINDOW (self), width, height);
|
||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||
gtk_widget_show_all (GTK_WIDGET (self));
|
||||
|
||||
g_signal_emit (self, signals[CONFIGURED], 0);
|
||||
}
|
||||
@ -180,22 +180,39 @@ phosh_layer_surface_get_property (GObject *object,
|
||||
|
||||
|
||||
static void
|
||||
phosh_layer_surface_constructed (GObject *object)
|
||||
on_phosh_layer_surface_realized (PhoshLayerSurface *self, gpointer unused)
|
||||
{
|
||||
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
||||
PhoshLayerSurfacePrivate *priv = phosh_layer_surface_get_instance_private (self);
|
||||
PhoshLayerSurfacePrivate *priv;
|
||||
GdkWindow *gdk_window;
|
||||
|
||||
G_OBJECT_CLASS (phosh_layer_surface_parent_class)->constructed (object);
|
||||
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
||||
|
||||
gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
|
||||
/* Realize the window so we can get the GDK window */
|
||||
gtk_widget_realize(GTK_WIDGET (self));
|
||||
priv = phosh_layer_surface_get_instance_private (self);
|
||||
|
||||
gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
|
||||
gdk_wayland_window_set_use_custom_surface (gdk_window);
|
||||
priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
|
||||
|
||||
gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
on_phosh_layer_surface_mapped (PhoshLayerSurface *self, gpointer unused)
|
||||
{
|
||||
PhoshLayerSurfacePrivate *priv;
|
||||
GdkWindow *gdk_window;
|
||||
|
||||
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
||||
priv = phosh_layer_surface_get_instance_private (self);
|
||||
|
||||
if (!priv->wl_surface) {
|
||||
gdk_window = gtk_widget_get_window (GTK_WIDGET (self));
|
||||
gdk_wayland_window_set_use_custom_surface (gdk_window);
|
||||
priv->wl_surface = gdk_wayland_window_get_wl_surface (gdk_window);
|
||||
}
|
||||
g_debug ("Mapped %p", priv->wl_surface);
|
||||
|
||||
priv->layer_surface = zwlr_layer_shell_v1_get_layer_surface(priv->layer_shell,
|
||||
priv->wl_surface,
|
||||
priv->wl_output,
|
||||
@ -209,8 +226,45 @@ phosh_layer_surface_constructed (GObject *object)
|
||||
&layer_surface_listener,
|
||||
self);
|
||||
wl_surface_commit(priv->wl_surface);
|
||||
|
||||
/* Process all pending events, otherwise we end up sending ack configure
|
||||
* to a not yet configured surface */
|
||||
wl_display_roundtrip (gdk_wayland_display_get_wl_display (gdk_display_get_default ()));
|
||||
}
|
||||
|
||||
static void
|
||||
on_phosh_layer_surface_unmapped (PhoshLayerSurface *self, gpointer unused)
|
||||
{
|
||||
PhoshLayerSurfacePrivate *priv;
|
||||
|
||||
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
|
||||
priv = phosh_layer_surface_get_instance_private (self);
|
||||
|
||||
priv = phosh_layer_surface_get_instance_private (self);
|
||||
if (priv->layer_surface) {
|
||||
zwlr_layer_surface_v1_destroy(priv->layer_surface);
|
||||
priv->layer_surface = NULL;
|
||||
}
|
||||
priv->wl_surface = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
phosh_layer_surface_constructed (GObject *object)
|
||||
{
|
||||
PhoshLayerSurface *self = PHOSH_LAYER_SURFACE (object);
|
||||
|
||||
g_signal_connect (self, "realize",
|
||||
G_CALLBACK (on_phosh_layer_surface_realized),
|
||||
NULL);
|
||||
g_signal_connect (self, "map",
|
||||
G_CALLBACK (on_phosh_layer_surface_mapped),
|
||||
NULL);
|
||||
g_signal_connect (self, "unmap",
|
||||
G_CALLBACK (on_phosh_layer_surface_unmapped),
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
phosh_layer_surface_dispose (GObject *object)
|
||||
{
|
||||
@ -352,6 +406,12 @@ phosh_layer_surface_new (gpointer layer_shell,
|
||||
"wl-output", wl_output);
|
||||
}
|
||||
|
||||
/**
|
||||
* phosh_layer_surface_get_surface:
|
||||
*
|
||||
* Get the layer layer surface or #NULL if the window
|
||||
* is not yet realized.
|
||||
*/
|
||||
struct zwlr_layer_surface_v1 *
|
||||
phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
|
||||
{
|
||||
@ -363,6 +423,12 @@ phosh_layer_surface_get_layer_surface(PhoshLayerSurface *self)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* phosh_layer_surface_get_wl_surface:
|
||||
*
|
||||
* Get the layer wayland surface or #NULL if the window
|
||||
* is not yet realized.
|
||||
*/
|
||||
struct wl_surface *
|
||||
phosh_layer_surface_get_wl_surface(PhoshLayerSurface *self)
|
||||
{
|
||||
|
||||
@ -212,12 +212,7 @@ eekboard_context_service_set_property (GObject *object,
|
||||
context->priv->keyboard = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_VISIBLE:
|
||||
/*if (context->priv->keyboard) {
|
||||
if (g_value_get_boolean (value))
|
||||
eekboard_context_service_show_keyboard (context);
|
||||
else
|
||||
eekboard_context_service_hide_keyboard (context);
|
||||
}*/
|
||||
context->priv->visible = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_FULLSCREEN:
|
||||
context->priv->fullscreen = g_value_get_boolean (value);
|
||||
|
||||
@ -42,13 +42,9 @@ typedef struct _ServerContextServiceClass ServerContextServiceClass;
|
||||
struct _ServerContextService {
|
||||
EekboardContextService parent;
|
||||
|
||||
gboolean was_visible;
|
||||
|
||||
GtkWidget *window;
|
||||
GtkWidget *widget;
|
||||
|
||||
gulong notify_visible_handler;
|
||||
|
||||
gdouble size_constraint_landscape[2];
|
||||
gdouble size_constraint_portrait[2];
|
||||
};
|
||||
@ -61,8 +57,6 @@ G_DEFINE_TYPE (ServerContextService, server_context_service, EEKBOARD_TYPE_CONTE
|
||||
|
||||
static void update_widget (ServerContextService *context);
|
||||
static void set_geometry (ServerContextService *context);
|
||||
static void set_dock (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
|
||||
static void
|
||||
on_monitors_changed (GdkScreen *screen,
|
||||
@ -103,24 +97,6 @@ on_notify_keyboard (GObject *object,
|
||||
// but simpler than adding a check in the window showing procedure
|
||||
eekboard_context_service_set_keymap(EEKBOARD_CONTEXT_SERVICE(context),
|
||||
keyboard);
|
||||
|
||||
if (context->window) {
|
||||
if (keyboard == NULL) {
|
||||
gtk_widget_hide (context->window);
|
||||
g_clear_pointer (&context->widget, gtk_widget_destroy);
|
||||
} else {
|
||||
gboolean was_visible = gtk_widget_get_visible (context->window);
|
||||
/* avoid to send KeyboardVisibilityChanged */
|
||||
g_signal_handler_block (context->window,
|
||||
context->notify_visible_handler);
|
||||
update_widget (context);
|
||||
if (was_visible) {
|
||||
gtk_widget_show_all (context->window);
|
||||
}
|
||||
g_signal_handler_unblock (context->window,
|
||||
context->notify_visible_handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -133,81 +109,20 @@ on_notify_fullscreen (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
on_notify_visible (GObject *object,
|
||||
GParamSpec *spec,
|
||||
ServerContextService *context)
|
||||
on_notify_map (GObject *object,
|
||||
ServerContextService *context)
|
||||
{
|
||||
gboolean visible;
|
||||
|
||||
g_object_get (object, "visible", &visible, NULL);
|
||||
g_object_set (context, "visible", visible, NULL);
|
||||
g_object_set (context, "visible", TRUE, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_dock (GtkWidget *widget, GtkAllocation *allocation)
|
||||
on_notify_unmap (GObject *object,
|
||||
ServerContextService *context)
|
||||
{
|
||||
#ifdef HAVE_XDOCK
|
||||
GdkWindow *window = gtk_widget_get_window (widget);
|
||||
long vals[12];
|
||||
|
||||
/* set window type to dock */
|
||||
gdk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DOCK);
|
||||
|
||||
vals[0] = 0;
|
||||
vals[1] = 0;
|
||||
vals[2] = 0;
|
||||
vals[3] = allocation->height;
|
||||
vals[4] = 0;
|
||||
vals[5] = 0;
|
||||
vals[6] = 0;
|
||||
vals[7] = 0;
|
||||
vals[8] = 0;
|
||||
vals[9] = 0;
|
||||
vals[10] = allocation->x;
|
||||
vals[11] = allocation->x + allocation->width;
|
||||
|
||||
XChangeProperty (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
XInternAtom (GDK_WINDOW_XDISPLAY (window),
|
||||
"_NET_WM_STRUT_PARTIAL", False),
|
||||
XA_CARDINAL, 32, PropModeReplace,
|
||||
(guchar *)vals, 12);
|
||||
#endif /* HAVE_XDOCK */
|
||||
g_object_set (context, "visible", FALSE, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_realize_set_dock (GtkWidget *widget,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
set_dock (widget, &allocation);
|
||||
}
|
||||
|
||||
static void
|
||||
on_size_allocate_set_dock (GtkWidget *widget,
|
||||
GdkRectangle *allocation,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (gtk_widget_get_realized (widget))
|
||||
set_dock (widget, allocation);
|
||||
}
|
||||
|
||||
static void
|
||||
on_realize_set_non_maximizable (GtkWidget *widget,
|
||||
ServerContextService *context)
|
||||
{
|
||||
|
||||
g_assert (context && context->window == widget);
|
||||
|
||||
/* make the window not maximizable */
|
||||
gdk_window_set_functions (gtk_widget_get_window (widget),
|
||||
GDK_FUNC_RESIZE |
|
||||
GDK_FUNC_MOVE |
|
||||
GDK_FUNC_MINIMIZE |
|
||||
GDK_FUNC_CLOSE);
|
||||
}
|
||||
|
||||
static void
|
||||
set_geometry (ServerContextService *context)
|
||||
@ -224,13 +139,6 @@ set_geometry (ServerContextService *context)
|
||||
gdk_monitor_get_geometry (monitor, &rect);
|
||||
eek_element_get_bounds (EEK_ELEMENT(keyboard), &bounds);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (context->window,
|
||||
on_realize_set_dock,
|
||||
context);
|
||||
g_signal_handlers_disconnect_by_func (context->window,
|
||||
on_realize_set_non_maximizable,
|
||||
context);
|
||||
|
||||
if (eekboard_context_service_get_fullscreen (EEKBOARD_CONTEXT_SERVICE(context))) {
|
||||
gint width = rect.width;
|
||||
gint height = rect.height;
|
||||
@ -256,12 +164,6 @@ set_geometry (ServerContextService *context)
|
||||
|
||||
gtk_window_set_decorated (GTK_WINDOW(context->window), FALSE);
|
||||
gtk_window_set_resizable (GTK_WINDOW(context->window), FALSE);
|
||||
g_signal_connect_after (context->window, "realize",
|
||||
G_CALLBACK(on_realize_set_dock),
|
||||
context);
|
||||
g_signal_connect_after (context->window, "size-allocate",
|
||||
G_CALLBACK(on_size_allocate_set_dock),
|
||||
context);
|
||||
} else {
|
||||
gtk_window_resize (GTK_WINDOW(context->window),
|
||||
bounds.width,
|
||||
@ -269,9 +171,6 @@ set_geometry (ServerContextService *context)
|
||||
gtk_window_move (GTK_WINDOW(context->window),
|
||||
MAX(rect.width - 20 - bounds.width, 0),
|
||||
MAX(rect.height - 40 - bounds.height, 0));
|
||||
g_signal_connect_after (context->window, "realize",
|
||||
G_CALLBACK(on_realize_set_non_maximizable),
|
||||
context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,18 +192,15 @@ make_window (ServerContextService *context)
|
||||
"layer", ZWLR_LAYER_SHELL_V1_LAYER_TOP,
|
||||
"kbd-interactivity", FALSE,
|
||||
"exclusive-zone", KEYBOARD_HEIGHT,
|
||||
//"namespace", "phosh home",
|
||||
"namespace", "osk",
|
||||
NULL
|
||||
);
|
||||
|
||||
g_signal_connect (context->window, "destroy",
|
||||
G_CALLBACK(on_destroy),
|
||||
context);
|
||||
|
||||
context->notify_visible_handler =
|
||||
g_signal_connect (context->window, "notify::visible",
|
||||
G_CALLBACK(on_notify_visible),
|
||||
context);
|
||||
g_object_connect (context->window,
|
||||
"signal::destroy", G_CALLBACK(on_destroy), context,
|
||||
"signal::map", G_CALLBACK(on_notify_map), context,
|
||||
"signal::unmap", G_CALLBACK(on_notify_unmap), context,
|
||||
NULL);
|
||||
|
||||
// The properties below are just to make hacking easier.
|
||||
// The way we use layer-shell overrides some,
|
||||
@ -322,6 +218,7 @@ make_window (ServerContextService *context)
|
||||
static void
|
||||
destroy_window (ServerContextService *context)
|
||||
{
|
||||
gtk_widget_destroy (GTK_WIDGET (context->window));
|
||||
context->window = NULL;
|
||||
}
|
||||
|
||||
@ -357,11 +254,13 @@ server_context_service_real_show_keyboard (EekboardContextService *_context)
|
||||
{
|
||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
||||
|
||||
make_window (context);
|
||||
if (!context->window)
|
||||
make_window (context);
|
||||
update_widget (context);
|
||||
|
||||
EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
|
||||
show_keyboard (_context);
|
||||
gtk_widget_show_all (context->window);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -372,32 +271,10 @@ server_context_service_real_hide_keyboard (EekboardContextService *_context)
|
||||
gtk_widget_hide (context->window);
|
||||
g_clear_pointer (&context->widget, gtk_widget_destroy);
|
||||
|
||||
destroy_window (context);
|
||||
|
||||
EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
|
||||
hide_keyboard (_context);
|
||||
}
|
||||
|
||||
static void
|
||||
server_context_service_real_enabled (EekboardContextService *_context)
|
||||
{
|
||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
||||
|
||||
if (context->was_visible && context->window)
|
||||
gtk_widget_show_all (context->window);
|
||||
}
|
||||
|
||||
static void
|
||||
server_context_service_real_disabled (EekboardContextService *_context)
|
||||
{
|
||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
|
||||
|
||||
if (context->window) {
|
||||
context->was_visible = gtk_widget_get_visible (context->window);
|
||||
gtk_widget_hide (context->window);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
server_context_service_real_destroyed (EekboardContextService *_context)
|
||||
{
|
||||
@ -437,7 +314,7 @@ server_context_service_dispose (GObject *object)
|
||||
{
|
||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(object);
|
||||
|
||||
g_clear_pointer (&context->window, gtk_widget_destroy);
|
||||
destroy_window (context);
|
||||
context->widget = NULL;
|
||||
|
||||
G_OBJECT_CLASS (server_context_service_parent_class)->dispose (object);
|
||||
@ -452,8 +329,6 @@ server_context_service_class_init (ServerContextServiceClass *klass)
|
||||
|
||||
context_class->show_keyboard = server_context_service_real_show_keyboard;
|
||||
context_class->hide_keyboard = server_context_service_real_hide_keyboard;
|
||||
context_class->enabled = server_context_service_real_enabled;
|
||||
context_class->disabled = server_context_service_real_disabled;
|
||||
context_class->destroyed = server_context_service_real_destroyed;
|
||||
|
||||
gobject_class->set_property = server_context_service_set_property;
|
||||
|
||||
Reference in New Issue
Block a user