Merge branch 'master' into fix-popup-width
This commit is contained in:
@@ -65,9 +65,8 @@ impl State {
|
||||
fn reset_to(&mut self, phase: AnimPhase) {
|
||||
self.alpha = Alpha(1.0);
|
||||
self.anim_phase = phase;
|
||||
if let Some(timer_id) = self.timer {
|
||||
if let Some(timer_id) = self.timer.take() {
|
||||
glib::source_remove(timer_id);
|
||||
self.timer = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,7 +258,7 @@ fn anim_step(state: &Arc<UiMutex<State>>) -> glib::Continue {
|
||||
|
||||
impl Drop for Cursor {
|
||||
fn drop(&mut self) {
|
||||
if let Some(timer_id) = self.state.borrow().timer {
|
||||
if let Some(timer_id) = self.state.borrow_mut().timer.take() {
|
||||
glib::source_remove(timer_id);
|
||||
}
|
||||
}
|
||||
|
||||
12
src/input.rs
12
src/input.rs
@@ -18,8 +18,8 @@ pub fn keyval_to_input_string(in_str: &str, in_state: gdk::ModifierType) -> Stri
|
||||
debug!("keyval -> {}", in_str);
|
||||
|
||||
// CTRL-^ and CTRL-@ don't work in the normal way.
|
||||
if state.contains(gdk::CONTROL_MASK) && !state.contains(gdk::SHIFT_MASK) &&
|
||||
!state.contains(gdk::MOD1_MASK)
|
||||
if state.contains(gdk::ModifierType::CONTROL_MASK) && !state.contains(gdk::ModifierType::SHIFT_MASK) &&
|
||||
!state.contains(gdk::ModifierType::MOD1_MASK)
|
||||
{
|
||||
if val == "6" {
|
||||
val = "^";
|
||||
@@ -35,7 +35,7 @@ pub fn keyval_to_input_string(in_str: &str, in_state: gdk::ModifierType) -> Stri
|
||||
|
||||
// Remove SHIFT
|
||||
if ch.is_ascii() && !ch.is_alphanumeric() {
|
||||
state.remove(gdk::SHIFT_MASK);
|
||||
state.remove(gdk::ModifierType::SHIFT_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,13 +43,13 @@ pub fn keyval_to_input_string(in_str: &str, in_state: gdk::ModifierType) -> Stri
|
||||
val = "lt";
|
||||
}
|
||||
|
||||
if state.contains(gdk::SHIFT_MASK) {
|
||||
if state.contains(gdk::ModifierType::SHIFT_MASK) {
|
||||
input.push_str("S-");
|
||||
}
|
||||
if state.contains(gdk::CONTROL_MASK) {
|
||||
if state.contains(gdk::ModifierType::CONTROL_MASK) {
|
||||
input.push_str("C-");
|
||||
}
|
||||
if state.contains(gdk::MOD1_MASK) {
|
||||
if state.contains(gdk::ModifierType::MOD1_MASK) {
|
||||
input.push_str("A-");
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ extern crate cairo;
|
||||
extern crate pango;
|
||||
extern crate pango_sys;
|
||||
extern crate pangocairo;
|
||||
extern crate pango_cairo_sys;
|
||||
extern crate neovim_lib;
|
||||
extern crate phf;
|
||||
#[macro_use]
|
||||
@@ -64,7 +65,7 @@ const TIMEOUT_ARG: &str = "--timeout";
|
||||
fn main() {
|
||||
env_logger::init().expect("Can't initialize env_logger");
|
||||
|
||||
let app_flags = gio::APPLICATION_HANDLES_OPEN | gio::APPLICATION_NON_UNIQUE;
|
||||
let app_flags = gio::ApplicationFlags::HANDLES_OPEN | gio::ApplicationFlags::NON_UNIQUE;
|
||||
|
||||
let app = if cfg!(debug_assertions) {
|
||||
gtk::Application::new(Some("org.daa.NeovimGtkDebug"), app_flags)
|
||||
@@ -83,10 +84,10 @@ fn main() {
|
||||
gtk::Window::set_default_icon_name("org.daa.NeovimGtk");
|
||||
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let argv: Vec<&str> = args.iter()
|
||||
let argv: Vec<String> = args.iter()
|
||||
.filter(|a| !a.starts_with(BIN_PATH_ARG))
|
||||
.filter(|a| !a.starts_with(TIMEOUT_ARG))
|
||||
.map(String::as_str)
|
||||
.cloned()
|
||||
.collect();
|
||||
app.run(&argv);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ impl<'a> Builder<'a> {
|
||||
let dlg = gtk::Dialog::new_with_buttons(
|
||||
Some(self.title),
|
||||
Some(parent),
|
||||
gtk::DIALOG_USE_HEADER_BAR | gtk::DIALOG_DESTROY_WITH_PARENT,
|
||||
gtk::DialogFlags::USE_HEADER_BAR | gtk::DialogFlags::DESTROY_WITH_PARENT,
|
||||
&[
|
||||
("Cancel", gtk::ResponseType::Cancel.into()),
|
||||
("Ok", gtk::ResponseType::Ok.into()),
|
||||
|
||||
@@ -30,7 +30,7 @@ impl<'a> Ui<'a> {
|
||||
let dlg = gtk::Dialog::new_with_buttons(
|
||||
Some("Plug"),
|
||||
Some(parent),
|
||||
gtk::DIALOG_DESTROY_WITH_PARENT,
|
||||
gtk::DialogFlags::DESTROY_WITH_PARENT,
|
||||
&[
|
||||
("Cancel", gtk::ResponseType::Cancel.into()),
|
||||
("Ok", gtk::ResponseType::Ok.into()),
|
||||
|
||||
@@ -112,13 +112,13 @@ impl State {
|
||||
let bg = color_model.pmenu_bg_sel();
|
||||
let fg = color_model.pmenu_fg_sel();
|
||||
|
||||
match gtk::CssProviderExtManual::load_from_data(
|
||||
match gtk::CssProviderExt::load_from_data(
|
||||
&self.css_provider,
|
||||
&format!(
|
||||
".view {{ color: {}; background-color: {};}}",
|
||||
fg.to_hex(),
|
||||
bg.to_hex()
|
||||
),
|
||||
).as_bytes(),
|
||||
) {
|
||||
Err(e) => error!("Can't update css {}", e),
|
||||
Ok(_) => (),
|
||||
|
||||
@@ -57,7 +57,7 @@ struct ContextState {
|
||||
|
||||
impl ContextState {
|
||||
pub fn new(font_desc: pango::FontDescription) -> Self {
|
||||
let font_map = FontMap::get_default();
|
||||
let font_map = FontMap::get_default().unwrap();
|
||||
let pango_context = font_map.create_context().unwrap();
|
||||
pango_context.set_font_description(&font_desc);
|
||||
|
||||
|
||||
@@ -9,10 +9,12 @@ use self::model_clip_iterator::{RowView, ModelClipIteratorFactory};
|
||||
use mode;
|
||||
use color;
|
||||
use sys::pango::*;
|
||||
use sys::pangocairo::*;
|
||||
use pango;
|
||||
use cairo;
|
||||
use pangocairo;
|
||||
|
||||
use cursor;
|
||||
use pangocairo::CairoContextExt;
|
||||
use ui_model;
|
||||
|
||||
pub fn render(
|
||||
@@ -104,7 +106,7 @@ fn draw_underline(
|
||||
let undercurl_height = (underline_thickness * 4.0).min(max_undercurl_height);
|
||||
let undercurl_y = line_y + underline_position - undercurl_height / 2.0;
|
||||
|
||||
ctx.show_error_underline(line_x, undercurl_y, char_width, undercurl_height);
|
||||
pangocairo::functions::error_underline_path(ctx, line_x, undercurl_y, char_width, undercurl_height);
|
||||
} else if cell.attrs.underline {
|
||||
let fg = color_model.actual_cell_fg(cell);
|
||||
ctx.set_source_rgb(fg.0, fg.1, fg.2);
|
||||
@@ -183,7 +185,8 @@ fn draw_cell(
|
||||
|
||||
ctx.move_to(line_x, line_y + ascent);
|
||||
ctx.set_source_rgb(fg.0, fg.1, fg.2);
|
||||
ctx.show_glyph_string(item.font(), glyphs);
|
||||
|
||||
show_glyph_string(ctx, item.font(), glyphs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
104
src/shell.rs
104
src/shell.rs
@@ -1,4 +1,4 @@
|
||||
use std::cell::{RefCell, Cell};
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Condvar, Mutex};
|
||||
use std::ops::Deref;
|
||||
@@ -6,7 +6,6 @@ use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use cairo;
|
||||
use pangocairo::CairoContextExt;
|
||||
use pango::{LayoutExt, FontDescription};
|
||||
use gdk;
|
||||
use gdk::{ModifierType, EventButton, EventMotion, EventType, EventScroll};
|
||||
@@ -14,6 +13,7 @@ use gdk_sys;
|
||||
use glib;
|
||||
use gtk;
|
||||
use gtk::prelude::*;
|
||||
use pangocairo;
|
||||
|
||||
use neovim_lib::{Neovim, NeovimApi, Value};
|
||||
use neovim_lib::neovim_api::Tabpage;
|
||||
@@ -50,12 +50,26 @@ macro_rules! idle_cb_call {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum ResizeState {
|
||||
NvimResizeTimer(glib::SourceId, usize, usize),
|
||||
enum ResizeStateEnum {
|
||||
NvimResizeTimer(usize, usize),
|
||||
NvimResizeRequest(usize, usize),
|
||||
Wait,
|
||||
}
|
||||
|
||||
pub struct ResizeState {
|
||||
state: ResizeStateEnum,
|
||||
timer: Option<glib::SourceId>,
|
||||
}
|
||||
|
||||
impl ResizeState {
|
||||
pub fn new() -> Self {
|
||||
ResizeState {
|
||||
state: ResizeStateEnum::Wait,
|
||||
timer: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
pub model: UiModel,
|
||||
pub color_model: ColorModel,
|
||||
@@ -75,7 +89,7 @@ pub struct State {
|
||||
im_context: gtk::IMMulticontext,
|
||||
error_area: error::ErrorArea,
|
||||
|
||||
resize_state: Rc<Cell<ResizeState>>,
|
||||
resize_state: Rc<RefCell<ResizeState>>,
|
||||
|
||||
options: ShellOptions,
|
||||
|
||||
@@ -109,7 +123,7 @@ impl State {
|
||||
im_context: gtk::IMMulticontext::new(),
|
||||
error_area: error::ErrorArea::new(),
|
||||
|
||||
resize_state: Rc::new(Cell::new(ResizeState::Wait)),
|
||||
resize_state: Rc::new(RefCell::new(ResizeState::new())),
|
||||
|
||||
options,
|
||||
|
||||
@@ -269,24 +283,26 @@ impl State {
|
||||
fn try_nvim_resize(&self) {
|
||||
let (columns, rows) = self.calc_nvim_size();
|
||||
|
||||
let mut resize_state = self.resize_state.borrow_mut();
|
||||
|
||||
match self.resize_state.get() {
|
||||
ResizeState::NvimResizeTimer(timer, req_columns, req_rows) => {
|
||||
match resize_state.state {
|
||||
ResizeStateEnum::NvimResizeTimer(req_columns, req_rows) => {
|
||||
if req_columns == columns && req_rows == rows {
|
||||
return;
|
||||
}
|
||||
glib::source_remove(timer);
|
||||
glib::source_remove(resize_state.timer.take().unwrap());
|
||||
resize_state.state = ResizeStateEnum::Wait;
|
||||
}
|
||||
ResizeState::NvimResizeRequest(req_columns, req_rows) => {
|
||||
ResizeStateEnum::NvimResizeRequest(req_columns, req_rows) => {
|
||||
if req_columns == columns && req_rows == rows {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ResizeState::Wait => (),
|
||||
ResizeStateEnum::Wait => (),
|
||||
}
|
||||
|
||||
|
||||
let resize_state = self.resize_state.clone();
|
||||
let resize_state_ref = self.resize_state.clone();
|
||||
let nvim = self.nvim.clone();
|
||||
|
||||
|
||||
@@ -294,21 +310,19 @@ impl State {
|
||||
return;
|
||||
}
|
||||
|
||||
self.resize_state.set(ResizeState::NvimResizeTimer(
|
||||
gtk::timeout_add(250, move || {
|
||||
resize_state.set(ResizeState::NvimResizeRequest(columns, rows));
|
||||
resize_state.state = ResizeStateEnum::NvimResizeTimer(columns, rows);
|
||||
resize_state.timer = Some(gtk::timeout_add(250, move || {
|
||||
let mut resize_state = resize_state_ref.borrow_mut();
|
||||
resize_state.state = ResizeStateEnum::NvimResizeRequest(columns, rows);
|
||||
resize_state.timer = None;
|
||||
|
||||
if let Some(mut nvim) = nvim.nvim().and_then(NeovimRef::non_blocked) {
|
||||
if let Err(err) = nvim.ui_try_resize(columns as u64, rows as u64) {
|
||||
error!("Error trying resize nvim {}", err);
|
||||
}
|
||||
if let Some(mut nvim) = nvim.nvim().and_then(NeovimRef::non_blocked) {
|
||||
if let Err(err) = nvim.ui_try_resize(columns as u64, rows as u64) {
|
||||
error!("Error trying resize nvim {}", err);
|
||||
}
|
||||
Continue(false)
|
||||
}),
|
||||
columns,
|
||||
rows,
|
||||
));
|
||||
|
||||
}
|
||||
Continue(false)
|
||||
}));
|
||||
}
|
||||
|
||||
fn resize_main_window(&mut self) {
|
||||
@@ -508,7 +522,11 @@ impl Shell {
|
||||
let ref_state = self.state.clone();
|
||||
let ref_ui_state = self.ui_state.clone();
|
||||
state.drawing_area.connect_scroll_event(move |_, ev| {
|
||||
gtk_scroll_event(&mut *ref_state.borrow_mut(), &mut *ref_ui_state.borrow_mut(), ev)
|
||||
gtk_scroll_event(
|
||||
&mut *ref_state.borrow_mut(),
|
||||
&mut *ref_ui_state.borrow_mut(),
|
||||
ev,
|
||||
)
|
||||
});
|
||||
|
||||
let ref_state = self.state.clone();
|
||||
@@ -651,20 +669,20 @@ fn gtk_scroll_event(state: &mut State, ui_state: &mut UiState, ev: &EventScroll)
|
||||
|
||||
state.close_popup_menu();
|
||||
|
||||
match ev.as_ref().direction {
|
||||
gdk_sys::GdkScrollDirection::Right => {
|
||||
match ev.get_direction() {
|
||||
gdk::ScrollDirection::Right => {
|
||||
mouse_input(state, "ScrollWheelRight", ev.get_state(), ev.get_position())
|
||||
}
|
||||
gdk_sys::GdkScrollDirection::Left => {
|
||||
gdk::ScrollDirection::Left => {
|
||||
mouse_input(state, "ScrollWheelLeft", ev.get_state(), ev.get_position())
|
||||
}
|
||||
gdk_sys::GdkScrollDirection::Up => {
|
||||
gdk::ScrollDirection::Up => {
|
||||
mouse_input(state, "ScrollWheelUp", ev.get_state(), ev.get_position())
|
||||
}
|
||||
gdk_sys::GdkScrollDirection::Down => {
|
||||
gdk::ScrollDirection::Down => {
|
||||
mouse_input(state, "ScrollWheelDown", ev.get_state(), ev.get_position())
|
||||
}
|
||||
gdk_sys::GdkScrollDirection::Smooth => {
|
||||
gdk::ScrollDirection::Smooth => {
|
||||
// Remember and accumulate scroll deltas, so slow scrolling still
|
||||
// works.
|
||||
ui_state.scroll_delta.0 += ev.as_ref().delta_x;
|
||||
@@ -688,6 +706,7 @@ fn gtk_scroll_event(state: &mut State, ui_state: &mut UiState, ev: &EventScroll)
|
||||
ui_state.scroll_delta.0 -= x as f64;
|
||||
ui_state.scroll_delta.1 -= y as f64;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
Inhibit(false)
|
||||
}
|
||||
@@ -889,7 +908,7 @@ fn set_nvim_initialized(state_arc: Arc<UiMutex<State>>) {
|
||||
}
|
||||
|
||||
fn draw_initializing(state: &State, ctx: &cairo::Context) {
|
||||
let layout = ctx.create_pango_layout();
|
||||
let layout = pangocairo::functions::create_layout(ctx).unwrap();
|
||||
let desc = state.get_font_desc();
|
||||
let alloc = state.drawing_area.get_allocation();
|
||||
|
||||
@@ -913,8 +932,8 @@ fn draw_initializing(state: &State, ctx: &cairo::Context) {
|
||||
state.color_model.fg_color.1,
|
||||
state.color_model.fg_color.2,
|
||||
);
|
||||
ctx.update_pango_layout(&layout);
|
||||
ctx.show_pango_layout(&layout);
|
||||
pangocairo::functions::update_layout(ctx, &layout);
|
||||
pangocairo::functions::show_layout(ctx, &layout);
|
||||
|
||||
|
||||
ctx.move_to(x + width as f64, y);
|
||||
@@ -933,9 +952,7 @@ fn init_nvim(state_ref: &Arc<UiMutex<State>>) {
|
||||
if state.start_nvim_initialization() {
|
||||
let (cols, rows) = state.calc_nvim_size();
|
||||
state.model = UiModel::new(rows as u64, cols as u64);
|
||||
state.resize_state.set(
|
||||
ResizeState::NvimResizeRequest(cols, rows),
|
||||
);
|
||||
state.resize_state.borrow_mut().state = ResizeStateEnum::NvimResizeRequest(cols, rows);
|
||||
|
||||
let state_arc = state_ref.clone();
|
||||
let options = state.options.clone();
|
||||
@@ -965,16 +982,17 @@ impl RedrawEvents for State {
|
||||
}
|
||||
|
||||
fn on_resize(&mut self, columns: u64, rows: u64) -> RepaintMode {
|
||||
match self.resize_state.get() {
|
||||
ResizeState::NvimResizeTimer(..) => {
|
||||
let state = self.resize_state.borrow().state.clone();
|
||||
match state {
|
||||
ResizeStateEnum::NvimResizeTimer(..) => {
|
||||
if self.model.columns != columns as usize || self.model.rows != rows as usize {
|
||||
self.model = UiModel::new(rows, columns);
|
||||
}
|
||||
}
|
||||
ResizeState::Wait |
|
||||
ResizeState::NvimResizeRequest(..) => {
|
||||
ResizeStateEnum::Wait |
|
||||
ResizeStateEnum::NvimResizeRequest(..) => {
|
||||
if self.model.columns != columns as usize || self.model.rows != rows as usize {
|
||||
self.resize_state.set(ResizeState::Wait);
|
||||
self.resize_state.borrow_mut().state = ResizeStateEnum::Wait;
|
||||
self.model = UiModel::new(rows, columns);
|
||||
self.resize_main_window();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ fn show_not_saved_dlg(comps: &UiMutex<Components>, shell: &Shell, changed_bufs:
|
||||
.fold(String::new(), |acc, v| acc + v + "\n");
|
||||
changed_files.pop();
|
||||
|
||||
let flags = gtk::DIALOG_MODAL | gtk::DIALOG_DESTROY_WITH_PARENT;
|
||||
let flags = gtk::DialogFlags::MODAL | gtk::DialogFlags::DESTROY_WITH_PARENT;
|
||||
let dlg = MessageDialog::new(
|
||||
Some(comps.borrow().window()),
|
||||
flags,
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
|
||||
pub mod pango;
|
||||
pub mod pangocairo;
|
||||
|
||||
16
src/sys/pangocairo/mod.rs
Normal file
16
src/sys/pangocairo/mod.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
use pango;
|
||||
use cairo;
|
||||
|
||||
use pango_cairo_sys as ffi;
|
||||
|
||||
use glib::translate::*;
|
||||
|
||||
pub fn show_glyph_string(cr: &cairo::Context, font: &pango::Font, glyphs: &pango::GlyphString) {
|
||||
unsafe {
|
||||
ffi::pango_cairo_show_glyph_string(
|
||||
mut_override(cr.to_glib_none().0),
|
||||
font.to_glib_none().0,
|
||||
mut_override(glyphs.to_glib_none().0),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ use std::cell::RefCell;
|
||||
use gtk;
|
||||
use gtk::prelude::*;
|
||||
|
||||
use glib;
|
||||
use glib::signal;
|
||||
|
||||
use pango;
|
||||
@@ -43,7 +44,7 @@ impl State {
|
||||
pub struct Tabline {
|
||||
tabs: gtk::Notebook,
|
||||
state: Rc<RefCell<State>>,
|
||||
switch_handler_id: u64,
|
||||
switch_handler_id: glib::SignalHandlerId,
|
||||
}
|
||||
|
||||
impl Tabline {
|
||||
@@ -102,7 +103,7 @@ impl Tabline {
|
||||
self.update_state(nvim, selected, tabs);
|
||||
|
||||
|
||||
signal::signal_handler_block(&self.tabs, self.switch_handler_id);
|
||||
signal::signal_handler_block(&self.tabs, &self.switch_handler_id);
|
||||
|
||||
let count = self.tabs.get_n_pages() as usize;
|
||||
if count < tabs.len() {
|
||||
@@ -134,7 +135,7 @@ impl Tabline {
|
||||
}
|
||||
}
|
||||
|
||||
signal::signal_handler_unblock(&self.tabs, self.switch_handler_id);
|
||||
signal::signal_handler_unblock(&self.tabs, &self.switch_handler_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
12
src/theme.rs
12
src/theme.rs
@@ -57,10 +57,14 @@ fn get_hl_colors(nvim: &mut Neovim, hl: &str) -> (Option<Color>, Option<Color>)
|
||||
nvim.get_hl_by_name(hl, true)
|
||||
.ok_and_report()
|
||||
.and_then(|m| if let Some(m) = m.to_attrs_map_report() {
|
||||
Some((
|
||||
get_hl_color(&m, "background"),
|
||||
get_hl_color(&m, "foreground"),
|
||||
))
|
||||
let reverse = m.get("reverse").and_then(|v| v.as_bool()).unwrap_or(false);
|
||||
let bg = get_hl_color(&m, "background");
|
||||
let fg = get_hl_color(&m, "foreground");
|
||||
if reverse {
|
||||
Some((fg, bg))
|
||||
} else {
|
||||
Some((bg, fg))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user