Merge branch 'themes' into 'master'
Use appropriate styling for layouts See merge request Librem5/squeekboard!253
This commit is contained in:
@ -2,6 +2,7 @@
|
|||||||
<gresources>
|
<gresources>
|
||||||
<gresource prefix="/sm/puri/squeekboard">
|
<gresource prefix="/sm/puri/squeekboard">
|
||||||
<file compressed="true">style.css</file>
|
<file compressed="true">style.css</file>
|
||||||
|
<file compressed="true">style-Adwaita:dark.css</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">popup.ui</file>
|
<file compressed="true" preprocess="xml-stripblanks">popup.ui</file>
|
||||||
<file>icons/key-enter.svg</file>
|
<file>icons/key-enter.svg</file>
|
||||||
<file>icons/key-shift.svg</file>
|
<file>icons/key-shift.svg</file>
|
||||||
|
|||||||
46
data/style-Adwaita:dark.css
Normal file
46
data/style-Adwaita:dark.css
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
sq_view {
|
||||||
|
background-color: rgba(0, 0, 0, 255);
|
||||||
|
color: #ffffff;
|
||||||
|
font-family: cantarell, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
sq_view sq_button {
|
||||||
|
color: #deddda;
|
||||||
|
background: #464448;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color: #5e5c64;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin: 4px 2px 4px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
sq_view.wide sq_button {
|
||||||
|
margin: 1px 1px 1px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
sq_button:active {
|
||||||
|
background: #747077;
|
||||||
|
border-color: #96949d;
|
||||||
|
}
|
||||||
|
|
||||||
|
sq_button.altline,
|
||||||
|
sq_button.special,
|
||||||
|
sq_button.wide {
|
||||||
|
background: #2b292f;
|
||||||
|
border-color: #3e3a44;
|
||||||
|
}
|
||||||
|
|
||||||
|
sq_button.locked {
|
||||||
|
background: #ffffff;
|
||||||
|
color: #2b292f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#Return {
|
||||||
|
background: #1c71d8;
|
||||||
|
border-color: #1a5fb4;
|
||||||
|
}
|
||||||
|
|
||||||
|
#Return:active {
|
||||||
|
background: #1c71d8;
|
||||||
|
border-color: #3584e4;
|
||||||
|
}
|
||||||
@ -1,15 +1,15 @@
|
|||||||
sq_view {
|
sq_view {
|
||||||
background-color: rgba(0, 0, 0, 255);
|
background-color: @theme_base_color; /*rgba(0, 0, 0, 255);*/
|
||||||
color: #ffffff;
|
color: @theme_text_color; /*#ffffff;*/
|
||||||
font-family: cantarell, sans-serif;
|
font-family: cantarell, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
sq_view sq_button {
|
sq_view sq_button {
|
||||||
color: #deddda;
|
color: @theme_fg_color; /*#deddda;*/
|
||||||
background: #464448;
|
background: mix(@theme_bg_color, @theme_base_color, -0.5); /* #464448; */
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-color: #5e5c64;
|
border-color: @borders; /* #5e5c64;*/
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
margin: 4px 2px 4px 2px;
|
margin: 4px 2px 4px 2px;
|
||||||
}
|
}
|
||||||
@ -18,29 +18,32 @@ sq_view.wide sq_button {
|
|||||||
margin: 1px 1px 1px 1px;
|
margin: 1px 1px 1px 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
sq_button:active {
|
sq_button:active,
|
||||||
background: #747077;
|
sq_button.altline:active,
|
||||||
border-color: #96949d;
|
sq_button.special:active,
|
||||||
|
sq_button.wide:active {
|
||||||
|
background: mix(@theme_bg_color, @theme_selected_bg_color, 0.4);/* #747077; */
|
||||||
|
border-color: mix(@borders, @theme_selected_fg_color, 0.5);/* #96949d; */
|
||||||
}
|
}
|
||||||
|
|
||||||
sq_button.altline,
|
sq_button.altline,
|
||||||
sq_button.special,
|
sq_button.special,
|
||||||
sq_button.wide {
|
sq_button.wide {
|
||||||
background: #2b292f;
|
background: mix(@theme_bg_color, @theme_base_color, 0.5); /*#2b292f;*/
|
||||||
border-color: #3e3a44;
|
border-color: @borders; /* #3e3a44; */
|
||||||
}
|
}
|
||||||
|
|
||||||
sq_button.locked {
|
sq_button.locked {
|
||||||
background: #ffffff;
|
background: @theme_fg_color; /*#ffffff;*/
|
||||||
color: #2b292f;
|
color: @theme_bg_color; /*#2b292f;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#Return {
|
#Return {
|
||||||
background: #1c71d8;
|
background: @theme_selected_bg_color; /* #1c71d8; */
|
||||||
border-color: #1a5fb4;
|
border-color: @borders; /*#1a5fb4;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#Return:active {
|
#Return:active {
|
||||||
background: #1c71d8;
|
background: mix(@theme_selected_bg_color, @theme_bg_color, 0.4); /*#1c71d8;*/
|
||||||
border-color: #3584e4;
|
border-color: @borders; /*#3584e4;*/
|
||||||
}
|
}
|
||||||
|
|||||||
2
debian/squeekboard.install
vendored
2
debian/squeekboard.install
vendored
@ -1,2 +1,2 @@
|
|||||||
usr/bin/squeekboard-real /usr/bin
|
tools/squeekboard-restyled usr/bin
|
||||||
usr/bin/squeekboard /usr/bin
|
usr/bin/squeekboard /usr/bin
|
||||||
|
|||||||
2
debian/squeekboard.lintian-overrides
vendored
2
debian/squeekboard.lintian-overrides
vendored
@ -1,2 +1,2 @@
|
|||||||
# yaml-rust 0.4.3 shares some roots with libyaml, including the string which lintian checks, creating a false positive
|
# yaml-rust 0.4.3 shares some roots with libyaml, including the string which lintian checks, creating a false positive
|
||||||
squeekboard binary: embedded-library usr/bin/squeekboard-real: libyaml
|
squeekboard binary: embedded-library usr/bin/squeekboard: libyaml
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "eek-keyboard.h"
|
#include "eek-keyboard.h"
|
||||||
#include "eek-renderer.h"
|
#include "eek-renderer.h"
|
||||||
|
#include "src/style.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
@ -623,10 +624,7 @@ eek_renderer_init (EekRenderer *self)
|
|||||||
|
|
||||||
gtk_icon_theme_add_resource_path (theme, "/sm/puri/squeekboard/icons");
|
gtk_icon_theme_add_resource_path (theme, "/sm/puri/squeekboard/icons");
|
||||||
|
|
||||||
/* Create a default CSS provider and load a style sheet */
|
priv->css_provider = squeek_load_style();
|
||||||
priv->css_provider = gtk_css_provider_new ();
|
|
||||||
gtk_css_provider_load_from_resource (priv->css_provider,
|
|
||||||
"/sm/puri/squeekboard/style.css");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@ -24,6 +24,7 @@ mod outputs;
|
|||||||
mod popover;
|
mod popover;
|
||||||
mod resources;
|
mod resources;
|
||||||
mod submission;
|
mod submission;
|
||||||
|
mod style;
|
||||||
pub mod tests;
|
pub mod tests;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
mod xdg;
|
mod xdg;
|
||||||
|
|||||||
@ -97,20 +97,7 @@ libsqueekboard = static_library('libsqueekboard',
|
|||||||
'-DEEK_COMPILATION=1'],
|
'-DEEK_COMPILATION=1'],
|
||||||
)
|
)
|
||||||
|
|
||||||
# the straight binary needs to be demoted in favor of the wrapper script
|
squeekboard = executable('squeekboard',
|
||||||
# due to styling being inconsistent
|
|
||||||
bindir = join_paths(prefix, get_option('bindir'))
|
|
||||||
wrapper_conf = configuration_data()
|
|
||||||
wrapper_conf.set('bindir', bindir)
|
|
||||||
configure_file(
|
|
||||||
input: '../tools/squeekboard.in',
|
|
||||||
output: 'squeekboard',
|
|
||||||
install_dir: bindir,
|
|
||||||
configuration: wrapper_conf,
|
|
||||||
install: true,
|
|
||||||
)
|
|
||||||
|
|
||||||
squeekboard = executable('squeekboard-real',
|
|
||||||
'server-main.c',
|
'server-main.c',
|
||||||
wl_proto_sources,
|
wl_proto_sources,
|
||||||
squeekboard_resources,
|
squeekboard_resources,
|
||||||
@ -125,6 +112,8 @@ squeekboard = executable('squeekboard-real',
|
|||||||
'-DEEK_COMPILATION=1'],
|
'-DEEK_COMPILATION=1'],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
bindir = join_paths(prefix, get_option('bindir'))
|
||||||
|
|
||||||
test_layout = custom_target('squeekboard-test-layout',
|
test_layout = custom_target('squeekboard-test-layout',
|
||||||
build_by_default: true,
|
build_by_default: true,
|
||||||
# meson doesn't track all inputs, cargo does
|
# meson doesn't track all inputs, cargo does
|
||||||
|
|||||||
7
src/style.h
Normal file
7
src/style.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef __STYLE_H
|
||||||
|
#define __STYLE_H
|
||||||
|
#include "gtk/gtk.h"
|
||||||
|
|
||||||
|
GtkCssProvider *squeek_load_style();
|
||||||
|
|
||||||
|
#endif
|
||||||
124
src/style.rs
Normal file
124
src/style.rs
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2000 Red Hat, Inc.
|
||||||
|
* Copyright (C) 2019 Purism, SPC
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.Free
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! CSS data loading */
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
use glib::object::ObjectExt;
|
||||||
|
use util::Warn;
|
||||||
|
|
||||||
|
/// Gathers stuff defined in C or called by C
|
||||||
|
pub mod c {
|
||||||
|
use super::*;
|
||||||
|
use gio;
|
||||||
|
use gtk;
|
||||||
|
use gtk_sys;
|
||||||
|
|
||||||
|
use gtk::CssProviderExt;
|
||||||
|
use glib::translate::ToGlibPtr;
|
||||||
|
|
||||||
|
/// Loads the layout style based on current theme
|
||||||
|
/// without having to worry about string allocation
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C"
|
||||||
|
fn squeek_load_style() -> *const gtk_sys::GtkCssProvider {
|
||||||
|
unsafe { gtk::set_initialized() };
|
||||||
|
let theme = gtk::Settings::get_default()
|
||||||
|
.map(|settings| get_theme_name(&settings));
|
||||||
|
|
||||||
|
let css_name = path_from_theme(theme);
|
||||||
|
|
||||||
|
let resource_name = if gio::resources_get_info(
|
||||||
|
&css_name,
|
||||||
|
gio::ResourceLookupFlags::NONE
|
||||||
|
).is_ok() {
|
||||||
|
css_name
|
||||||
|
} else { // use default if this path doesn't exist
|
||||||
|
path_from_theme(None)
|
||||||
|
};
|
||||||
|
|
||||||
|
let provider = gtk::CssProvider::new();
|
||||||
|
provider.load_from_resource(&resource_name);
|
||||||
|
provider.to_glib_full()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// not Adwaita, but rather fall back to default
|
||||||
|
const DEFAULT_THEME_NAME: &str = "";
|
||||||
|
|
||||||
|
struct GtkTheme {
|
||||||
|
name: String,
|
||||||
|
variant: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets theme as determined by the toolkit
|
||||||
|
/// Ported from GTK's gtksettings.c
|
||||||
|
fn get_theme_name(settings: >k::Settings) -> GtkTheme {
|
||||||
|
let env_theme = env::var("GTK_THEME")
|
||||||
|
.map(|theme| {
|
||||||
|
let mut parts = theme.splitn(2, ":");
|
||||||
|
GtkTheme {
|
||||||
|
// guaranteed at least empty string
|
||||||
|
// as the first result from splitting a string
|
||||||
|
name: parts.next().unwrap().into(),
|
||||||
|
variant: parts.next().map(String::from)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map_err(|e| {
|
||||||
|
match &e {
|
||||||
|
env::VarError::NotPresent => {},
|
||||||
|
e => eprintln!("GTK_THEME variable invalid: {}", e),
|
||||||
|
};
|
||||||
|
e
|
||||||
|
}).ok();
|
||||||
|
|
||||||
|
match env_theme {
|
||||||
|
Some(theme) => theme,
|
||||||
|
None => GtkTheme {
|
||||||
|
name: {
|
||||||
|
settings.get_property("gtk-theme-name")
|
||||||
|
.ok_warn("No theme name")
|
||||||
|
.and_then(|value| value.get::<String>())
|
||||||
|
.unwrap_or(DEFAULT_THEME_NAME.into())
|
||||||
|
},
|
||||||
|
variant: {
|
||||||
|
settings.get_property("gtk-application-prefer-dark-theme")
|
||||||
|
.ok_warn("No settings key")
|
||||||
|
.and_then(|value| value.get::<bool>())
|
||||||
|
.and_then(|dark_preferred| match dark_preferred {
|
||||||
|
true => Some("dark".into()),
|
||||||
|
false => None,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path_from_theme(theme: Option<GtkTheme>) -> String {
|
||||||
|
format!(
|
||||||
|
"/sm/puri/squeekboard/style{}.css",
|
||||||
|
match theme {
|
||||||
|
Some(GtkTheme { name, variant: Some(variant) }) => {
|
||||||
|
format!("-{}:{}", name, variant)
|
||||||
|
},
|
||||||
|
Some(GtkTheme { name, variant: None }) => format!("-{}", name),
|
||||||
|
None => "".into(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
16
src/util.rs
16
src/util.rs
@ -177,6 +177,22 @@ impl<T> Borrow<Rc<T>> for Pointer<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sugar for logging errors in results
|
||||||
|
pub trait Warn {
|
||||||
|
type Value;
|
||||||
|
fn ok_warn(self, msg: &str) -> Option<Self::Value>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, E: std::error::Error> Warn for Result<T, E> {
|
||||||
|
type Value = T;
|
||||||
|
fn ok_warn(self, msg: &str) -> Option<T> {
|
||||||
|
self.map_err(|e| {
|
||||||
|
eprintln!("{}: {}", msg, e);
|
||||||
|
e
|
||||||
|
}).ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait WarningHandler {
|
pub trait WarningHandler {
|
||||||
/// Handle a warning
|
/// Handle a warning
|
||||||
fn handle(&mut self, warning: &str);
|
fn handle(&mut self, warning: &str);
|
||||||
|
|||||||
@ -12,4 +12,4 @@ for DIR in ${DIRS}; do
|
|||||||
fi;
|
fi;
|
||||||
done;
|
done;
|
||||||
|
|
||||||
exec @bindir@/squeekboard-real
|
exec $(which squeekboard)
|
||||||
Reference in New Issue
Block a user