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