From 32d76633ca80c0518007c56b2d750451815f06af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Valdelvira?= Date: Mon, 9 Jun 2025 16:16:37 +0200 Subject: [PATCH 1/3] Fix #10: Crash on headless servers: clipboard X11 connection failure The clipboard initialization on TableView::default was calling `unwrap` on the value returned by `Clipboard::new`. On enviroments without a window manager session (e.g. A server accessed via ssh), this would cause the application to panic. Instead, make the `clipboard` field on TableView and Optional, and simply ignore yank actions if no clipboard was available. --- src/ui/talbe_view.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/ui/talbe_view.rs b/src/ui/talbe_view.rs index 1af9f61..8593217 100644 --- a/src/ui/talbe_view.rs +++ b/src/ui/talbe_view.rs @@ -125,7 +125,21 @@ pub struct TableView { pub data: (Vec, Vec>), pub table_state: TableState, table_scroll_height: u16, - clipboard: Clipboard, + clipboard: Option, +} + +fn init_clipboard() -> Option { + let disabled = std::env::var("DISABLE_CLIPBOARD") + .is_ok_and(|val| matches!(&*val, "1" | "true")); + if disabled { return None } + + match Clipboard::new() { + Ok(clip) => Some(clip), + Err(err) => { + eprintln!("INFO: Failed to initialize clipboard: {err}"); + None + } + } } impl Default for TableView { @@ -138,7 +152,7 @@ impl Default for TableView { data: (Vec::default(), Vec::default()), table_state: TableState::default(), table_scroll_height: 0, - clipboard: Clipboard::new().unwrap(), + clipboard: init_clipboard(), } } } @@ -339,14 +353,16 @@ impl TableView { } fn yank_cell(&mut self) -> Result<(), Box> { - Ok(if let Some((x, y)) = self.table_state.selected_cell() { + let Some(clipboard) = &mut self.clipboard else { return Ok(()) }; + if let Some((x, y)) = self.table_state.selected_cell() { if let Some(row) = self.data.1.get(x) { if let Some(val) = row.get(y) { - self.clipboard.set_text(val)?; + clipboard.set_text(val)?; return Ok(()); } } - }) + }; + Ok(()) } fn load_table_data(&mut self, app: &App, db: &Db) -> Result<(), Box> { From afd7d19ef9a522041520995aabd67f58584a2693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Valdelvira?= Date: Mon, 9 Jun 2025 16:16:57 +0200 Subject: [PATCH 2/3] Make the clipboard feature opt-out The arboard dependency pulls a lot of crates to give support for multiple desktop enviroments. This patch puts it behind a "clipboard" feature, which is enabled by default. Wayland support is also behind the "wayland" feature, also enabled by default. The idea is to give more flexibility to the people compiling this app for their personal use. For example: If I'm building JDbrowser for my home server, which I access via ssh, I don't need clipboard support, since I won't be able to use it. And even if I build it for my laptop, I won't need wayland support if I'm on an X11 server. Since the features are enabled by default, nothing breaks. But if someone wants to opt-out of a bunch of crates they won't use, let them! --- Cargo.lock | 237 +++---------------------------------------- Cargo.toml | 7 +- src/ui/help_view.rs | 9 +- src/ui/talbe_view.rs | 88 ++++++++++------ 4 files changed, 85 insertions(+), 256 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d55ef4d..57ed930 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,12 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - [[package]] name = "allocator-api2" version = "0.2.21" @@ -86,14 +80,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df099ccb16cd014ff054ac1bf392c67feeef57164b05c42f037cd40f5d4357f4" dependencies = [ "clipboard-win", - "core-graphics", - "image", "log", "objc2", "objc2-app-kit", "objc2-foundation", "parking_lot", - "windows-sys 0.48.0", "wl-clipboard-rs", "x11rb", ] @@ -114,17 +105,11 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide 0.7.4", + "miniz_oxide", "object", "rustc-demangle", ] -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.8.0" @@ -143,18 +128,6 @@ dependencies = [ "objc2", ] -[[package]] -name = "bytemuck" -version = "1.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" - -[[package]] -name = "byteorder-lite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" - [[package]] name = "cassowary" version = "0.3.0" @@ -288,62 +261,13 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "core-graphics" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-graphics-types", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - [[package]] name = "crossterm" version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.8.0", + "bitflags", "crossterm_winapi", "mio", "parking_lot", @@ -470,31 +394,12 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" -[[package]] -name = "fdeflate" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" -dependencies = [ - "simd-adler32", -] - [[package]] name = "fixedbitset" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" -[[package]] -name = "flate2" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" -dependencies = [ - "crc32fast", - "miniz_oxide 0.8.5", -] - [[package]] name = "fnv" version = "1.0.7" @@ -507,33 +412,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" -[[package]] -name = "foreign-types" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" -dependencies = [ - "foreign-types-macros", - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - [[package]] name = "gethostname" version = "0.4.3" @@ -594,19 +472,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "image" -version = "0.25.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" -dependencies = [ - "bytemuck", - "byteorder-lite", - "num-traits", - "png", - "tiff", -] - [[package]] name = "indenter" version = "0.3.3" @@ -677,12 +542,6 @@ dependencies = [ "strum", ] -[[package]] -name = "jpeg-decoder" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" - [[package]] name = "lazy_static" version = "1.5.0" @@ -757,16 +616,6 @@ dependencies = [ "adler", ] -[[package]] -name = "miniz_oxide" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" -dependencies = [ - "adler2", - "simd-adler32", -] - [[package]] name = "mio" version = "1.0.3" @@ -785,7 +634,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 2.8.0", + "bitflags", "cfg-if", "cfg_aliases", "libc", @@ -801,15 +650,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - [[package]] name = "objc-sys" version = "0.3.5" @@ -832,7 +672,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.8.0", + "bitflags", "block2", "libc", "objc2", @@ -848,7 +688,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.8.0", + "bitflags", "block2", "objc2", "objc2-foundation", @@ -878,7 +718,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.8.0", + "bitflags", "block2", "libc", "objc2", @@ -890,7 +730,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.8.0", + "bitflags", "block2", "objc2", "objc2-foundation", @@ -902,7 +742,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.8.0", + "bitflags", "block2", "objc2", "objc2-foundation", @@ -991,19 +831,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" -[[package]] -name = "png" -version = "0.17.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide 0.8.5", -] - [[package]] name = "proc-macro2" version = "1.0.93" @@ -1046,7 +873,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" dependencies = [ - "bitflags 2.8.0", + "bitflags", "cassowary", "compact_str", "crossterm", @@ -1088,7 +915,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags 2.8.0", + "bitflags", ] [[package]] @@ -1097,7 +924,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c6d5e5acb6f6129fe3f7ba0a7fc77bca1942cb568535e18e7bc40262baf3110" dependencies = [ - "bitflags 2.8.0", + "bitflags", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -1117,7 +944,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.8.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -1207,12 +1034,6 @@ dependencies = [ "libc", ] -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - [[package]] name = "smallvec" version = "1.13.2" @@ -1331,17 +1152,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "tiff" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" -dependencies = [ - "flate2", - "jpeg-decoder", - "weezl", -] - [[package]] name = "tracing" version = "0.1.41" @@ -1483,7 +1293,7 @@ version = "0.31.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2120de3d33638aaef5b9f4472bff75f07c56379cf76ea320bd3a3d65ecaf73f" dependencies = [ - "bitflags 2.8.0", + "bitflags", "rustix", "wayland-backend", "wayland-scanner", @@ -1495,7 +1305,7 @@ version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" dependencies = [ - "bitflags 2.8.0", + "bitflags", "wayland-backend", "wayland-client", "wayland-scanner", @@ -1507,7 +1317,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" dependencies = [ - "bitflags 2.8.0", + "bitflags", "wayland-backend", "wayland-client", "wayland-protocols", @@ -1534,12 +1344,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "weezl" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" - [[package]] name = "winapi" version = "0.3.9" @@ -1562,15 +1366,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -1716,7 +1511,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" dependencies = [ - "bitflags 2.8.0", + "bitflags", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7f6f640..ba862ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["cli", "tui", "sqlite","browser"] categories = ["command-line-utilities"] [dependencies] -arboard = { version = "3.4.1" , features = ["wayland-data-control"]} +arboard = { version = "3.4.1" , default-features = false, optional = true } clap = { version = "4.5.27" , features = ["derive"]} color-eyre = "0.6.3" crossterm = "0.28.1" @@ -18,3 +18,8 @@ ratatui = { version = "0.29.0", features = ["serde"] } rusqlite = "0.33.0" sqlparser = "0.54.0" strum = "0.26.3" + +[features] +default = ["wayland", "clipboard"] +clipboard = ["arboard"] +wayland = ["arboard/wayland-data-control"] diff --git a/src/ui/help_view.rs b/src/ui/help_view.rs index 6483b9e..2d7c39d 100644 --- a/src/ui/help_view.rs +++ b/src/ui/help_view.rs @@ -22,7 +22,13 @@ const NAV_LIST_KEYS: [[&str; 2]; 3] = [ ]; const TABLE_VIEW_TITLE: &str = " Table View "; -const TABLE_KEYS: [[&str; 2]; 8] = [ + +#[cfg(not(feature = "clipboard"))] +const TABLE_KEYS_LEN: usize = 7; +#[cfg(feature = "clipboard")] +const TABLE_KEYS_LEN: usize = 8; + +const TABLE_KEYS: [[&str; 2]; TABLE_KEYS_LEN] = [ ["View Schema - Browse Data", "SHIFT + h - l"], ["Page Up Half", "u"], ["Page Down Half", "d"], @@ -30,6 +36,7 @@ const TABLE_KEYS: [[&str; 2]; 8] = [ ["Move Cell Down", "j"], ["Move Cell Left", "h"], ["Move Cell Right", "l"], + #[cfg(feature = "clipboard")] ["Yank Cell to Clipboard", "y"], ]; diff --git a/src/ui/talbe_view.rs b/src/ui/talbe_view.rs index 8593217..b16a8f2 100644 --- a/src/ui/talbe_view.rs +++ b/src/ui/talbe_view.rs @@ -4,6 +4,7 @@ use super::{ SECONDARY_COLOR, TEXT_COLOR, }; use crate::app::{self, App, Db}; +#[cfg(feature = "clipboard")] use arboard::Clipboard; use crossterm::event::{KeyCode, KeyEvent}; use ratatui::{ @@ -125,9 +126,11 @@ pub struct TableView { pub data: (Vec, Vec>), pub table_state: TableState, table_scroll_height: u16, + #[cfg(feature = "clipboard")] clipboard: Option, } +#[cfg(feature = "clipboard")] fn init_clipboard() -> Option { let disabled = std::env::var("DISABLE_CLIPBOARD") .is_ok_and(|val| matches!(&*val, "1" | "true")); @@ -152,6 +155,7 @@ impl Default for TableView { data: (Vec::default(), Vec::default()), table_state: TableState::default(), table_scroll_height: 0, + #[cfg(feature = "clipboard")] clipboard: init_clipboard(), } } @@ -313,45 +317,63 @@ impl TableView { app: &mut App, ) -> Result<(), Box> { if let Some(db) = &app.current_db { - if key.code == KeyCode::Char('h') { - self.table_state.scroll_left_by(1); - return Ok(()); - } else if key.code == KeyCode::Char('u') { - self.table_state.scroll_up_by(self.table_scroll_height); - return Ok(()); - } else if key.code == KeyCode::Char('d') { - self.table_state.scroll_down_by(self.table_scroll_height); - return Ok(()); - } else if key.code == KeyCode::Char('l') { - self.table_state.scroll_right_by(1); - return Ok(()); - } else if key.code == KeyCode::Char('k') { - self.table_state.scroll_up_by(1); - return Ok(()); - } else if key.code == KeyCode::Char('j') { - self.table_state.scroll_down_by(1); - return Ok(()); - } else if key.code == KeyCode::Char('e') { - self.table_nav_tab = self.table_nav_tab.next(); - } else if key.code == KeyCode::Char('q') { - self.table_nav_tab = self.table_nav_tab.previous(); - } else if key.code == KeyCode::Char('L') { - self.selected_table_tab = self.selected_table_tab.next(); - } else if key.code == KeyCode::Char('H') { - self.selected_table_tab = self.selected_table_tab.previous(); - } else if key.code == KeyCode::Char('K') { - self.tables_list.list_state.select_previous(); - } else if key.code == KeyCode::Char('J') { - self.tables_list.list_state.select_next(); - } else if key.code == KeyCode::Char('y') { - self.yank_cell()?; - return Ok(()); + match key.code { + KeyCode::Char('h') => { + self.table_state.scroll_left_by(1); + return Ok(()); + }, + KeyCode::Char('u') => { + self.table_state.scroll_up_by(self.table_scroll_height); + return Ok(()); + }, + KeyCode::Char('d') => { + self.table_state.scroll_down_by(self.table_scroll_height); + return Ok(()); + }, + KeyCode::Char('l') => { + self.table_state.scroll_right_by(1); + return Ok(()); + }, + KeyCode::Char('k') => { + self.table_state.scroll_up_by(1); + return Ok(()); + }, + KeyCode::Char('j') => { + self.table_state.scroll_down_by(1); + return Ok(()); + }, + KeyCode::Char('e') => { + self.table_nav_tab = self.table_nav_tab.next(); + }, + KeyCode::Char('q') => { + self.table_nav_tab = self.table_nav_tab.previous(); + }, + KeyCode::Char('L') => { + self.selected_table_tab = self.selected_table_tab.next(); + } + KeyCode::Char('H') => { + self.selected_table_tab = self.selected_table_tab.previous(); + } + KeyCode::Char('K') => { + self.tables_list.list_state.select_previous(); + } + KeyCode::Char('J') => { + self.tables_list.list_state.select_next(); + }, + #[cfg(feature = "clipboard")] + KeyCode::Char('y') => { + self.yank_cell()?; + return Ok(()); + } + _ => {} } + self.load_table_data(app, db)?; } Ok(()) } + #[cfg(feature = "clipboard")] fn yank_cell(&mut self) -> Result<(), Box> { let Some(clipboard) = &mut self.clipboard else { return Ok(()) }; if let Some((x, y)) = self.table_state.selected_cell() { From 964f5f2adfa168f08f37ff7f0b3b9c0d7aba7d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Valdelvira?= Date: Mon, 9 Jun 2025 17:01:13 +0200 Subject: [PATCH 3/3] Add "bundled-sqlite" feature The rusqlite crate defines an optional feature "bundled", that uses a bundled sqlite library. Adding an, also optional, feature "bundled-sqlite" to JDbrowser allows the user to benefit from that feature, wich only a single extra line on Cargo.toml --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index ba862ee..f0a8129 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,4 @@ strum = "0.26.3" default = ["wayland", "clipboard"] clipboard = ["arboard"] wayland = ["arboard/wayland-data-control"] +bundled-sqlite = ["rusqlite/bundled"]