max / shop
1 file changed,
+73 insertions,
-62 deletions
| @@ -23,21 +23,19 @@ | |||
| 23 | 23 | XdgShell, XdgWindow, registry_queue_init, | |
| 24 | 24 | }; | |
| 25 | 25 | use smithay_client_toolkit::{ | |
| 26 | - | delegate_dispatch2, delegate_registry, | |
| 27 | - | registry_handlers, | |
| 26 | + | delegate_dispatch2, delegate_registry, registry_handlers, | |
| 28 | 27 | seat::keyboard::{KeyEvent, KeyboardHandler, Keysym, Modifiers, RawModifiers, RepeatInfo}, | |
| 29 | 28 | }; | |
| 30 | 29 | use std::collections::VecDeque; | |
| 31 | - | use wayland_client::protocol::wl_keyboard; | |
| 32 | 30 | use tracing::{info, warn}; | |
| 31 | + | use wayland_client::protocol::wl_keyboard; | |
| 33 | 32 | use wayland_client::protocol::{wl_callback, wl_output, wl_seat, wl_surface}; | |
| 34 | 33 | ||
| 35 | 34 | const INITIAL: (u32, u32) = (960, 540); | |
| 36 | 35 | /// IosevkaTerm Nerd Font Mono, terminal-optimized variant of Iosevka with | |
| 37 | 36 | /// nerd-font glyphs baked in. Bundled so starship, yazi, helix and friends | |
| 38 | 37 | /// get their icons without a system font install. ~13 MB in the binary. | |
| 39 | - | const FONT_BYTES: &[u8] = | |
| 40 | - | include_bytes!("../../../assets/IosevkaTermNerdFontMono-Regular.ttf"); | |
| 38 | + | const FONT_BYTES: &[u8] = include_bytes!("../../../assets/IosevkaTermNerdFontMono-Regular.ttf"); | |
| 41 | 39 | const FONT_PX: f32 = 14.0; | |
| 42 | 40 | const CELL_ADVANCE: f32 = 8.0; | |
| 43 | 41 | const CELL_HEIGHT: f32 = 17.0; | |
| @@ -120,8 +118,7 @@ | |||
| 120 | 118 | let compositor = CompositorState::bind(&globals, &qh)?; | |
| 121 | 119 | let xdg_shell = XdgShell::bind(&globals, &qh)?; | |
| 122 | 120 | let wl_surface = compositor.create_surface(&qh); | |
| 123 | - | let xdg_window = | |
| 124 | - | xdg_shell.create_window(wl_surface, WindowDecorations::ServerDefault, &qh); | |
| 121 | + | let xdg_window = xdg_shell.create_window(wl_surface, WindowDecorations::ServerDefault, &qh); | |
| 125 | 122 | xdg_window.set_title(spec.title.to_string()); | |
| 126 | 123 | xdg_window.set_app_id(spec.app_id.to_string()); | |
| 127 | 124 | xdg_window.set_min_size(Some(spec.min_size)); | |
| @@ -208,8 +205,11 @@ | |||
| 208 | 205 | awaiting_frame: false, | |
| 209 | 206 | }; | |
| 210 | 207 | app.surface.configure(&app.device, &app.surface_config); | |
| 211 | - | app.text | |
| 212 | - | .resize(&app.queue, app.surface_config.width, app.surface_config.height); | |
| 208 | + | app.text.resize( | |
| 209 | + | &app.queue, | |
| 210 | + | app.surface_config.width, | |
| 211 | + | app.surface_config.height, | |
| 212 | + | ); | |
| 213 | 213 | ||
| 214 | 214 | // calloop event loop with wayland + PTY sources. | |
| 215 | 215 | let mut event_loop: EventLoop<App> = EventLoop::try_new()?; | |
| @@ -297,7 +297,10 @@ | |||
| 297 | 297 | app.text.resize(&app.queue, physical_w, physical_h); | |
| 298 | 298 | app.images.resize(&app.queue, physical_w, physical_h); | |
| 299 | 299 | // Tell the compositor our buffer is N logical px per buffer px. | |
| 300 | - | app.chrome.xdg_window.wl_surface().set_buffer_scale(s as i32); | |
| 300 | + | app.chrome | |
| 301 | + | .xdg_window | |
| 302 | + | .wl_surface() | |
| 303 | + | .set_buffer_scale(s as i32); | |
| 301 | 304 | let cols = grid_cols(logical_w); | |
| 302 | 305 | let rows = grid_rows(logical_h); | |
| 303 | 306 | app.grid.resize(cols, rows); | |
| @@ -354,13 +357,7 @@ | |||
| 354 | 357 | ignore: bool, | |
| 355 | 358 | action: char, | |
| 356 | 359 | ) { | |
| 357 | - | <Grid as shop_vt::Perform>::csi_dispatch( | |
| 358 | - | self.grid, | |
| 359 | - | params, | |
| 360 | - | intermediates, | |
| 361 | - | ignore, | |
| 362 | - | action, | |
| 363 | - | ); | |
| 360 | + | <Grid as shop_vt::Perform>::csi_dispatch(self.grid, params, intermediates, ignore, action); | |
| 364 | 361 | } | |
| 365 | 362 | fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) { | |
| 366 | 363 | <Grid as shop_vt::Perform>::esc_dispatch(self.grid, intermediates, ignore, byte); | |
| @@ -381,23 +378,24 @@ | |||
| 381 | 378 | return; | |
| 382 | 379 | }; | |
| 383 | 380 | let rgba = match format { | |
| 384 | - | kgp::Format::Png => match image::load_from_memory_with_format( | |
| 385 | - | &payload, | |
| 386 | - | image::ImageFormat::Png, | |
| 387 | - | ) { | |
| 388 | - | Ok(img) => { | |
| 389 | - | let rgba = img.to_rgba8(); | |
| 390 | - | let (w, h) = (rgba.width(), rgba.height()); | |
| 391 | - | Some((rgba.into_raw(), w, h)) | |
| 381 | + | kgp::Format::Png => { | |
| 382 | + | match image::load_from_memory_with_format(&payload, image::ImageFormat::Png) { | |
| 383 | + | Ok(img) => { | |
| 384 | + | let rgba = img.to_rgba8(); | |
| 385 | + | let (w, h) = (rgba.width(), rgba.height()); | |
| 386 | + | Some((rgba.into_raw(), w, h)) | |
| 387 | + | } | |
| 388 | + | Err(e) => { | |
| 389 | + | warn!("kitty: png decode: {e}"); | |
| 390 | + | None | |
| 391 | + | } | |
| 392 | 392 | } | |
| 393 | - | Err(e) => { | |
| 394 | - | warn!("kitty: png decode: {e}"); | |
| 395 | - | None | |
| 396 | - | } | |
| 397 | - | }, | |
| 393 | + | } | |
| 398 | 394 | kgp::Format::Rgba => { | |
| 399 | - | let (w, h) = | |
| 400 | - | (control.width_px.unwrap_or(0), control.height_px.unwrap_or(0)); | |
| 395 | + | let (w, h) = ( | |
| 396 | + | control.width_px.unwrap_or(0), | |
| 397 | + | control.height_px.unwrap_or(0), | |
| 398 | + | ); | |
| 401 | 399 | if w == 0 || h == 0 { | |
| 402 | 400 | warn!("kitty: rgba transmit missing s= / v="); | |
| 403 | 401 | None | |
| @@ -406,8 +404,10 @@ | |||
| 406 | 404 | } | |
| 407 | 405 | } | |
| 408 | 406 | kgp::Format::Rgb => { | |
| 409 | - | let (w, h) = | |
| 410 | - | (control.width_px.unwrap_or(0), control.height_px.unwrap_or(0)); | |
| 407 | + | let (w, h) = ( | |
| 408 | + | control.width_px.unwrap_or(0), | |
| 409 | + | control.height_px.unwrap_or(0), | |
| 410 | + | ); | |
| 411 | 411 | if w == 0 || h == 0 { | |
| 412 | 412 | warn!("kitty: rgb transmit missing s= / v="); | |
| 413 | 413 | None | |
| @@ -546,11 +546,11 @@ | |||
| 546 | 546 | let view = frame | |
| 547 | 547 | .texture | |
| 548 | 548 | .create_view(&wgpu::TextureViewDescriptor::default()); | |
| 549 | - | let mut encoder = | |
| 550 | - | app.device | |
| 551 | - | .create_command_encoder(&wgpu::CommandEncoderDescriptor { | |
| 552 | - | label: Some("shop.frame"), | |
| 553 | - | }); | |
| 549 | + | let mut encoder = app | |
| 550 | + | .device | |
| 551 | + | .create_command_encoder(&wgpu::CommandEncoderDescriptor { | |
| 552 | + | label: Some("shop.frame"), | |
| 553 | + | }); | |
| 554 | 554 | { | |
| 555 | 555 | let _clear = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { | |
| 556 | 556 | label: Some("shop.clear"), | |
| @@ -585,19 +585,23 @@ | |||
| 585 | 585 | app.text.update_row( | |
| 586 | 586 | &app.queue, | |
| 587 | 587 | row, | |
| 588 | - | app.grid.row(row).iter().enumerate().filter_map(|(col, cell)| { | |
| 589 | - | let c = cell.c(); | |
| 590 | - | if c == ' ' || c == '\0' { | |
| 591 | - | return None; | |
| 592 | - | } | |
| 593 | - | let mut fg = resolve_color(cell.fg(), DEFAULT_FG); | |
| 594 | - | let mut bg = resolve_color(cell.bg(), DEFAULT_BG); | |
| 595 | - | if cell.reverse() { | |
| 596 | - | std::mem::swap(&mut fg, &mut bg); | |
| 597 | - | } | |
| 598 | - | let _ = bg; | |
| 599 | - | Some((col as u16, c, fg)) | |
| 600 | - | }), | |
| 588 | + | app.grid | |
| 589 | + | .row(row) | |
| 590 | + | .iter() | |
| 591 | + | .enumerate() | |
| 592 | + | .filter_map(|(col, cell)| { | |
| 593 | + | let c = cell.c(); | |
| 594 | + | if c == ' ' || c == '\0' { | |
| 595 | + | return None; | |
| 596 | + | } | |
| 597 | + | let mut fg = resolve_color(cell.fg(), DEFAULT_FG); | |
| 598 | + | let mut bg = resolve_color(cell.bg(), DEFAULT_BG); | |
| 599 | + | if cell.reverse() { | |
| 600 | + | std::mem::swap(&mut fg, &mut bg); | |
| 601 | + | } | |
| 602 | + | let _ = bg; | |
| 603 | + | Some((col as u16, c, fg)) | |
| 604 | + | }), | |
| 601 | 605 | ); | |
| 602 | 606 | } | |
| 603 | 607 | ||
| @@ -622,7 +626,13 @@ | |||
| 622 | 626 | if cell.reverse() { | |
| 623 | 627 | std::mem::swap(&mut fg, &mut bg); | |
| 624 | 628 | } | |
| 625 | - | fills.push(BgFill { x, y, w: cell_w_px, h: cell_h_px, color: bg }); | |
| 629 | + | fills.push(BgFill { | |
| 630 | + | x, | |
| 631 | + | y, | |
| 632 | + | w: cell_w_px, | |
| 633 | + | h: cell_h_px, | |
| 634 | + | color: bg, | |
| 635 | + | }); | |
| 626 | 636 | } | |
| 627 | 637 | if underline { | |
| 628 | 638 | fills.push(BgFill { | |
| @@ -677,8 +687,12 @@ | |||
| 677 | 687 | ); | |
| 678 | 688 | // Draw any live kitty-graphics image on top of the text layer. | |
| 679 | 689 | if let Some(placement) = app.image_placement { | |
| 680 | - | app.images | |
| 681 | - | .draw(&app.queue, &view, &mut encoder, std::slice::from_ref(&placement)); | |
| 690 | + | app.images.draw( | |
| 691 | + | &app.queue, | |
| 692 | + | &view, | |
| 693 | + | &mut encoder, | |
| 694 | + | std::slice::from_ref(&placement), | |
| 695 | + | ); | |
| 682 | 696 | } | |
| 683 | 697 | app.queue.submit(std::iter::once(encoder.finish())); | |
| 684 | 698 | app.queue.present(frame); | |
| @@ -965,12 +979,7 @@ | |||
| 965 | 979 | GridColor::Default => default, | |
| 966 | 980 | GridColor::Named(i) => palette16(i), | |
| 967 | 981 | GridColor::Indexed(i) => palette256(i), | |
| 968 | - | GridColor::Rgb(r, g, b) => [ | |
| 969 | - | r as f32 / 255.0, | |
| 970 | - | g as f32 / 255.0, | |
| 971 | - | b as f32 / 255.0, | |
| 972 | - | 1.0, | |
| 973 | - | ], | |
| 982 | + | GridColor::Rgb(r, g, b) => [r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0, 1.0], | |
| 974 | 983 | } | |
| 975 | 984 | } | |
| 976 | 985 | ||
| @@ -1037,7 +1046,9 @@ | |||
| 1037 | 1046 | let height = new_h.map_or(self.chrome.height, std::num::NonZeroU32::get); | |
| 1038 | 1047 | self.chrome.width = width; | |
| 1039 | 1048 | self.chrome.height = height; | |
| 1040 | - | self.chrome.pending.push_back(Pending::Resized { width, height }); | |
| 1049 | + | self.chrome | |
| 1050 | + | .pending | |
| 1051 | + | .push_back(Pending::Resized { width, height }); | |
| 1041 | 1052 | } | |
| 1042 | 1053 | } | |
| 1043 | 1054 |