diff --git a/eek/eek-xml-layout.c b/eek/eek-xml-layout.c index ce1b1936..e4f2eb09 100644 --- a/eek/eek-xml-layout.c +++ b/eek/eek-xml-layout.c @@ -31,9 +31,10 @@ LevelKeyboard * eek_xml_layout_real_create_keyboard (const char *keyboard_type, - EekboardContextService *manager) + EekboardContextService *manager, + enum layout_type t) { - struct squeek_layout *layout = squeek_load_layout(keyboard_type); + struct squeek_layout *layout = squeek_load_layout(keyboard_type, t); squeek_layout_place_contents(layout); return level_keyboard_new(manager, layout); } diff --git a/eek/eek-xml-layout.h b/eek/eek-xml-layout.h index 9f8ceee3..9b96e445 100644 --- a/eek/eek-xml-layout.h +++ b/eek/eek-xml-layout.h @@ -24,10 +24,13 @@ #define EEK_XML_LAYOUT_H 1 #include "eek-types.h" +#include "src/layout.h" G_BEGIN_DECLS + LevelKeyboard * eek_xml_layout_real_create_keyboard (const char *keyboard_type, - EekboardContextService *manager); + EekboardContextService *manager, + enum layout_type t); G_END_DECLS #endif /* EEK_XML_LAYOUT_H */ diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index 746eeb6a..47ac5f9b 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -41,12 +41,10 @@ #include "wayland.h" #include "eek/eek-xml-layout.h" +#include "src/server-context-service.h" #include "eekboard/eekboard-context-service.h" -#define CSW 640 -#define CSH 480 - enum { PROP_0, // Magic: without this, keyboard is not useable in g_object_notify PROP_KEYBOARD, @@ -73,10 +71,6 @@ struct _EekboardContextServicePrivate { LevelKeyboard *keyboard; // currently used keyboard GHashTable *keyboard_hash; // a table of available keyboards, per layout - // TODO: make use of repeating buttons - guint repeat_timeout_id; - gboolean repeat_triggered; - GSettings *settings; uint32_t hint; uint32_t purpose; @@ -86,9 +80,10 @@ G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_ static LevelKeyboard * eekboard_context_service_real_create_keyboard (EekboardContextService *self, - const gchar *keyboard_type) + const gchar *keyboard_type, + enum layout_type t) { - LevelKeyboard *keyboard = eek_xml_layout_real_create_keyboard(keyboard_type, self); + LevelKeyboard *keyboard = eek_xml_layout_real_create_keyboard(keyboard_type, self, t); if (!keyboard) { g_error("Failed to create a keyboard"); } @@ -231,8 +226,8 @@ settings_get_layout(GSettings *settings, char **type, char **layout) g_variant_unref(inputs); } -static void -settings_update_layout(EekboardContextService *context) +void +eekboard_context_service_update_layout(EekboardContextService *context, enum layout_type t) { g_autofree gchar *keyboard_type = NULL; g_autofree gchar *keyboard_layout = NULL; @@ -262,7 +257,7 @@ settings_update_layout(EekboardContextService *context) GUINT_TO_POINTER(keyboard_id)); // create a keyboard if (!keyboard) { - keyboard = eekboard_context_service_real_create_keyboard(context, keyboard_layout); + keyboard = eekboard_context_service_real_create_keyboard(context, keyboard_layout, t); g_hash_table_insert (context->priv->keyboard_hash, GUINT_TO_POINTER(keyboard_id), @@ -272,11 +267,14 @@ settings_update_layout(EekboardContextService *context) } // set as current context->priv->keyboard = keyboard; - // TODO: this used to save the group, why? - //group = eek_element_get_group (EEK_ELEMENT(context->priv->keyboard)); + g_object_notify (G_OBJECT(context), "keyboard"); } +static void update_layout_and_type(EekboardContextService *context) { + eekboard_context_service_update_layout(context, server_context_service_get_layout_type(context)); +} + static gboolean settings_handle_layout_changed(GSettings *s, gpointer keys, gint n_keys, @@ -285,7 +283,7 @@ settings_handle_layout_changed(GSettings *s, (void)keys; (void)n_keys; EekboardContextService *context = user_data; - settings_update_layout(context); + update_layout_and_type(context); return TRUE; } @@ -299,7 +297,7 @@ eekboard_context_service_constructed (GObject *object) if (!context->virtual_keyboard) { g_error("Programmer error: Failed to receive a virtual keyboard instance"); } - settings_update_layout(context); + update_layout_and_type(context); } static void @@ -518,6 +516,6 @@ void eekboard_context_service_set_hint_purpose(EekboardContextService *context, if (priv->hint != hint || priv->purpose != purpose) { priv->hint = hint; priv->purpose = purpose; - settings_update_layout(context); + update_layout_and_type(context); } } diff --git a/eekboard/eekboard-context-service.h b/eekboard/eekboard-context-service.h index b8db74a5..2dccd498 100644 --- a/eekboard/eekboard-context-service.h +++ b/eekboard/eekboard-context-service.h @@ -105,6 +105,7 @@ void eekboard_context_service_set_keymap(EekboardContextService *context, void eekboard_context_service_set_hint_purpose(EekboardContextService *context, uint32_t hint, uint32_t purpose); - +void +eekboard_context_service_update_layout(EekboardContextService *context, enum layout_type t); G_END_DECLS #endif /* EEKBOARD_CONTEXT_SERVICE_H */ diff --git a/src/data.rs b/src/data.rs index 61760799..ab39af47 100644 --- a/src/data.rs +++ b/src/data.rs @@ -33,15 +33,23 @@ use serde::Deserialize; pub mod c { use super::*; use std::os::raw::c_char; - + #[no_mangle] pub extern "C" - fn squeek_load_layout(name: *const c_char) -> *mut ::layout::Layout { + fn squeek_load_layout( + name: *const c_char, + type_: u32, + ) -> *mut ::layout::Layout { + let type_ = match type_ { + 0 => LayoutType::Base, + 1 => LayoutType::Wide, + _ => panic!("Bad enum value"), + }; let name = as_str(&name) .expect("Bad layout name") .expect("Empty layout name"); - let layout = load_layout_with_fallback(name); + let layout = load_layout_with_fallback(&name, type_); Box::into_raw(Box::new(layout)) } } @@ -68,6 +76,20 @@ impl fmt::Display for LoadError { } } +pub enum LayoutType { + Base = 0, + Wide = 1, +} + +impl LayoutType { + fn apply_to_name(&self, name: String) -> String { + match self { + LayoutType::Base => name, + LayoutType::Wide => name + "_wide", + } + } +} + #[derive(Debug, Clone, PartialEq)] enum DataSource { File(PathBuf), @@ -86,22 +108,35 @@ impl fmt::Display for DataSource { /// Lists possible sources, with 0 as the most preferred one fn list_layout_sources( name: &str, - keyboards_path: Option + type_: LayoutType, + keyboards_path: Option, ) -> Vec { let mut ret = Vec::new(); - if let Some(path) = keyboards_path.clone() { - ret.push(DataSource::File(path.join(name).with_extension("yaml"))) - } - - ret.push(DataSource::Resource(name.to_owned())); - if let Some(path) = keyboards_path.clone() { - ret.push(DataSource::File( - path.join(FALLBACK_LAYOUT_NAME).with_extension("yaml") - )) - } - - ret.push(DataSource::Resource(FALLBACK_LAYOUT_NAME.to_owned())); + let mut add_by_name = |name: &str| { + if let Some(path) = keyboards_path.clone() { + ret.push(DataSource::File( + path.join(name.to_owned()).with_extension("yaml") + )) + } + + ret.push(DataSource::Resource(name.into())); + }; + + match &type_ { + LayoutType::Base => {}, + type_ => add_by_name(&type_.apply_to_name(name.into())), + }; + + add_by_name(name); + + match &type_ { + LayoutType::Base => {}, + type_ => add_by_name(&type_.apply_to_name(FALLBACK_LAYOUT_NAME.into())), + }; + + add_by_name(FALLBACK_LAYOUT_NAME); + ret } @@ -124,13 +159,14 @@ fn load_layout(source: DataSource) -> Result<::layout::Layout, LoadError> { } fn load_layout_with_fallback( - name: &str + name: &str, + type_: LayoutType, ) -> ::layout::Layout { let path = env::var_os("SQUEEKBOARD_KEYBOARDSDIR") .map(PathBuf::from) .or_else(|| xdg::data_path("squeekboard/keyboards")); - for source in list_layout_sources(name, path) { + for source in list_layout_sources(name, type_, path) { let layout = load_layout(source.clone()); match layout { Err(e) => match (e, source) { @@ -665,7 +701,7 @@ mod tests { /// First fallback should be to builtin, not to FALLBACK_LAYOUT_NAME #[test] fn fallbacks_order() { - let sources = list_layout_sources("nb", None); + let sources = list_layout_sources("nb", LayoutType::Base, None); assert_eq!( sources, diff --git a/src/layout.h b/src/layout.h index d820d229..ea52abfe 100644 --- a/src/layout.h +++ b/src/layout.h @@ -9,6 +9,11 @@ #include "src/keyboard.h" #include "virtual-keyboard-unstable-v1-client-protocol.h" +enum layout_type { + LAYOUT_TYPE_BASE = 0, + LAYOUT_TYPE_WIDE = 1, +}; + struct squeek_button; struct squeek_row; struct squeek_view; @@ -52,7 +57,7 @@ void squeek_layout_place_contents(struct squeek_layout*); struct squeek_view *squeek_layout_get_current_view(struct squeek_layout*); -struct squeek_layout *squeek_load_layout(const char *type); +struct squeek_layout *squeek_load_layout(const char *name, uint32_t type); const char *squeek_layout_get_keymap(const struct squeek_layout*); void squeek_layout_free(struct squeek_layout*); diff --git a/src/outputs.rs b/src/outputs.rs index 7bdc19d4..38326013 100644 --- a/src/outputs.rs +++ b/src/outputs.rs @@ -210,7 +210,7 @@ pub mod c { match output_state { Some(OutputState { current_mode: Some(super::Mode { width, height: _ } ), - scale: scale, + scale, }) => width / scale, _ => { eprintln!("No width registered on output"); diff --git a/src/server-context-service.c b/src/server-context-service.c index b3302f61..d3bcc3e9 100644 --- a/src/server-context-service.c +++ b/src/server-context-service.c @@ -39,10 +39,11 @@ typedef struct _ServerContextServiceClass ServerContextServiceClass; struct _ServerContextService { EekboardContextService parent; - GtkWidget *window; + PhoshLayerSurface *window; GtkWidget *widget; guint hiding; guint last_requested_height; + enum layout_type last_type; gdouble size_constraint_landscape[2]; gdouble size_constraint_portrait[2]; @@ -59,7 +60,7 @@ on_destroy (GtkWidget *widget, gpointer user_data) { ServerContextService *context = user_data; - g_assert (widget == context->window); + g_assert (widget == GTK_WIDGET(context->window)); context->window = NULL; context->widget = NULL; @@ -127,15 +128,30 @@ calculate_height(int32_t width) return height; } +enum layout_type get_type(uint32_t width, uint32_t height) { + (void)height; + if (width < 540) { + return LAYOUT_TYPE_BASE; + } + return LAYOUT_TYPE_WIDE; +} + static void on_surface_configure(PhoshLayerSurface *surface, ServerContextService *context) { gint width; gint height; g_object_get(G_OBJECT(surface), - "width", &width, - "height", &height, + "configured-width", &width, + "configured-height", &height, NULL); + // check if the change would switch types + enum layout_type new_type = get_type((uint32_t)width, (uint32_t)height); + if (context->last_type != new_type) { + context->last_type = new_type; + eekboard_context_service_update_layout(EEKBOARD_CONTEXT_SERVICE(context), context->last_type); + } + guint desired_height = calculate_height(width); guint configured_height = (guint)height; // if height was already requested once but a different one was given @@ -190,7 +206,7 @@ make_window (ServerContextService *context) // and there's no space in the protocol for others. // Those may still be useful in the future, // or for hacks with regular windows. - gtk_widget_set_can_focus (context->window, FALSE); + gtk_widget_set_can_focus (GTK_WIDGET(context->window), FALSE); g_object_set (G_OBJECT(context->window), "accept_focus", FALSE, NULL); gtk_window_set_title (GTK_WINDOW(context->window), _("Squeekboard")); @@ -239,13 +255,13 @@ server_context_service_real_show_keyboard (EekboardContextService *_context) EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)-> show_keyboard (_context); - gtk_widget_show (context->window); + gtk_widget_show (GTK_WIDGET(context->window)); } static gboolean on_hide (ServerContextService *context) { - gtk_widget_hide (context->window); + gtk_widget_hide (GTK_WIDGET(context->window)); context->hiding = 0; return G_SOURCE_REMOVE; @@ -357,3 +373,8 @@ server_context_service_new () { return EEKBOARD_CONTEXT_SERVICE(g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL)); } + +enum layout_type server_context_service_get_layout_type(EekboardContextService *service) +{ + return SERVER_CONTEXT_SERVICE(service)->last_type; +} diff --git a/src/server-context-service.h b/src/server-context-service.h index 6a20b62c..abaa5428 100644 --- a/src/server-context-service.h +++ b/src/server-context-service.h @@ -19,6 +19,7 @@ #define SERVER_CONTEXT_SERVICE_H 1 #include "eekboard/eekboard-service.h" +#include "src/layout.h" G_BEGIN_DECLS @@ -33,6 +34,7 @@ G_BEGIN_DECLS typedef struct _ServerContextService ServerContextService; EekboardContextService *server_context_service_new (); +enum layout_type server_context_service_get_layout_type(EekboardContextService*); G_END_DECLS #endif /* SERVER_CONTEXT_SERVICE_H */