From 020b1b9328239b499ae2ecdbfe8bf1a7e998d3c5 Mon Sep 17 00:00:00 2001 From: ochibani <11yzyv86j@relay.firefox.com> Date: Fri, 20 Dec 2024 15:22:25 +0200 Subject: [PATCH] fix select-window --- Cargo.lock | 1 + Cargo.toml | 6 ++- interfaces/area_selection.ui | 2 +- interfaces/select_window.ui | 29 +++++++++++- locales/ar.ftl | 4 +- locales/ar_YE.ftl | 4 +- locales/en.ftl | 4 +- locales/en_US.ftl | 4 +- src/area_capture.rs | 29 +++++++++++- src/styles/global.css | 7 +++ src/ui.rs | 92 ++++++++++++++++++++++++++---------- 11 files changed, 145 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1efeb11..4fe0dea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -479,6 +479,7 @@ dependencies = [ "regex", "rust-ini 0.16.1", "secfmt", + "winapi", "x-win", ] diff --git a/Cargo.toml b/Cargo.toml index 2c951a7..76150d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ blue-recorder-core = { git = "https://github.com/ochibani/blue-recorder-core.git cpal = "0.15.3" dark-light = "1.0.0" dirs = "4.0.0" -display-info = "0.5.1" fluent-bundle = "0.15.3" glib = "0.10.3" libadwaita = { version = "0.1.1" } @@ -18,4 +17,9 @@ rdev = "0.5" regex = "1.4.3" rust-ini = "0.16" secfmt = "0.1.1" + +# Windows-only dependency +[target.'cfg(windows)'.dependencies] +display-info = "0.5.1" x-win = "2.0.2" +winapi = { version = "0.3", features = ["winuser"] } diff --git a/interfaces/area_selection.ui b/interfaces/area_selection.ui index 8ed9bfb..4ee376c 100644 --- a/interfaces/area_selection.ui +++ b/interfaces/area_selection.ui @@ -25,7 +25,7 @@ True vertical fill - filr + fill True diff --git a/interfaces/select_window.ui b/interfaces/select_window.ui index 99691d5..c73118e 100644 --- a/interfaces/select_window.ui +++ b/interfaces/select_window.ui @@ -1,7 +1,7 @@ - + select_window True True @@ -9,5 +9,32 @@ False False True + + + True + True + vertical + + + True + True + horizontal + center + center + True + + + select_window_label + True + True + label + center + center + + + + + + diff --git a/locales/ar.ftl b/locales/ar.ftl index 8c1ee58..c4a6de7 100644 --- a/locales/ar.ftl +++ b/locales/ar.ftl @@ -61,7 +61,7 @@ wmv-format = WMV (Windows Media Video) blue-recorder = المسجّل الأزرق # Click to select window -click-window = Left click to select a window +click-window = Left click to select window # Close error dialog close = Close @@ -182,4 +182,4 @@ tray-minimize-tooltip = Minimize application to tray icon video-tooltip = يسجل الشاشة wayland-tooltip = غير مدعوم في وايلاند window-tooltip = يحدد نافذة ليسجلها -windows-unsupported-tooltip = Not supported in windows platform +windows-unsupported-tooltip = Not supported on windows platform diff --git a/locales/ar_YE.ftl b/locales/ar_YE.ftl index 8c1ee58..c4a6de7 100644 --- a/locales/ar_YE.ftl +++ b/locales/ar_YE.ftl @@ -61,7 +61,7 @@ wmv-format = WMV (Windows Media Video) blue-recorder = المسجّل الأزرق # Click to select window -click-window = Left click to select a window +click-window = Left click to select window # Close error dialog close = Close @@ -182,4 +182,4 @@ tray-minimize-tooltip = Minimize application to tray icon video-tooltip = يسجل الشاشة wayland-tooltip = غير مدعوم في وايلاند window-tooltip = يحدد نافذة ليسجلها -windows-unsupported-tooltip = Not supported in windows platform +windows-unsupported-tooltip = Not supported on windows platform diff --git a/locales/en.ftl b/locales/en.ftl index 57b2169..223ae86 100644 --- a/locales/en.ftl +++ b/locales/en.ftl @@ -61,7 +61,7 @@ wmv-format = WMV (Windows Media Video) blue-recorder = Blue Recorder # Click to select window -click-window = Left click to select a window +click-window = Left click to select window # Close error dialog close = Close @@ -182,4 +182,4 @@ tray-minimize-tooltip = Minimize application to tray icon video-tooltip = Video recording wayland-tooltip = Not supported in Wayland window-tooltip = Select window to record -windows-unsupported-tooltip = Not supported in windows platform +windows-unsupported-tooltip = Not supported on windows platform diff --git a/locales/en_US.ftl b/locales/en_US.ftl index 57b2169..223ae86 100644 --- a/locales/en_US.ftl +++ b/locales/en_US.ftl @@ -61,7 +61,7 @@ wmv-format = WMV (Windows Media Video) blue-recorder = Blue Recorder # Click to select window -click-window = Left click to select a window +click-window = Left click to select window # Close error dialog close = Close @@ -182,4 +182,4 @@ tray-minimize-tooltip = Minimize application to tray icon video-tooltip = Video recording wayland-tooltip = Not supported in Wayland window-tooltip = Select window to record -windows-unsupported-tooltip = Not supported in windows platform +windows-unsupported-tooltip = Not supported on windows platform diff --git a/src/area_capture.rs b/src/area_capture.rs index 8c72363..9251c96 100644 --- a/src/area_capture.rs +++ b/src/area_capture.rs @@ -1,13 +1,18 @@ extern crate regex; -use anyhow::{anyhow, Result}; +#[cfg(any(target_os = "freebsd", target_os = "linux"))] +use anyhow::anyhow; +use anyhow::Result; +#[cfg(target_os = "windows")] use display_info::DisplayInfo; use glib::Continue; use libadwaita::gtk::Label; use libadwaita::Window; use libadwaita::prelude::*; +#[cfg(any(target_os = "freebsd", target_os = "linux"))] use regex::Regex; use std::cell::RefCell; +#[cfg(any(target_os = "freebsd", target_os = "linux"))] use std::process::Command; use std::rc::Rc; #[cfg(target_os = "windows")] @@ -113,7 +118,7 @@ impl AreaCapture { } Ok(*self) -} + } } #[cfg(any(target_os = "freebsd", target_os = "linux"))] @@ -189,3 +194,23 @@ pub fn show_size(area_chooser_window: Window, area_size_bottom_label: Label, are Ok(()) } + +// Returns `true` if the left mouse button is clicked, and `false` if the `Esc` key is pressed. +#[cfg(target_os = "windows")] +pub fn check_input() -> bool { + use winapi::um::winuser::{GetAsyncKeyState, VK_LBUTTON, VK_ESCAPE}; + loop { + // Check if the left mouse button (VK_LBUTTON) is pressed + if unsafe { GetAsyncKeyState(VK_LBUTTON) } & 0x8000u16 as i16 != 0 { + break true; + } + + // Check if the Esc key is pressed + if unsafe { GetAsyncKeyState(VK_ESCAPE) } & 0x8000u16 as i16 != 0 { + break false; + } + + // Add a small delay to avoid busy-waiting + std::thread::sleep(std::time::Duration::from_millis(10)); + } +} diff --git a/src/styles/global.css b/src/styles/global.css index 77dd96f..77af1ff 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -102,9 +102,16 @@ } #select_window { + background: none; + border: none; + border-radius: 0px; font-weight: bold; } +#select_window_label { + color: @theme_selected_bg_color; +} + #stop_button { background: #ed333b; border: 1px solid #ed333b; diff --git a/src/ui.rs b/src/ui.rs index 7367a63..f458ac4 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -30,7 +30,7 @@ pub fn run_ui(application: &Application) { error_dialog_button.set_label(&get_bundle("close", None)); error_expander_label.set_label(&get_bundle("details-button", None)); let _error_dialog = error_dialog.clone(); - error_dialog_button.connect_clicked(move |_|{ + error_dialog_button.connect_clicked(move |_| { _error_dialog.close(); }); @@ -114,7 +114,8 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag let screen_grab_button: ToggleButton = builder.object("screen_grab_button").unwrap(); let screen_grab_icon: Image = builder.object("screen_grab_icon").unwrap(); let screen_grab_label: Label = builder.object("screen_grab_label").unwrap(); - let select_window: MessageDialog = builder.object("select_window").unwrap(); + let select_window: Window = builder.object("select_window").unwrap(); + let select_window_label: Label = builder.object("select_window_label").unwrap(); let speaker_switch: CheckButton = builder.object("speakerswitch").unwrap(); let stop_button: Button = builder.object("stopbutton").unwrap(); let stop_label: Label = builder.object("stop_label").unwrap(); @@ -130,8 +131,6 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag area_chooser_window.set_title(Some(&get_bundle("area-chooser", None))); // Title is hidden error_dialog.set_transient_for(Some(&main_window)); select_window.set_transient_for(Some(&main_window)); - select_window.set_message_type(libadwaita::gtk::MessageType::Info); - select_window.set_secondary_text(Some(&get_bundle("click-window", None))); main_window.set_application(Some(application)); main_window.set_title(Some(&get_bundle("blue-recorder", None))); @@ -160,6 +159,12 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag area_grab_button.set_sensitive(false); area_grab_button.set_tooltip_text(Some(&get_bundle("wayland-tooltip", None))); } + // Disable follow mouse option + #[cfg(target_os = "windows")] + { + follow_mouse_switch.set_active(false); + follow_mouse_switch.set_sensitive(false); + } // Entries filename_entry.set_placeholder_text(Some(&get_bundle("file-name", None))); @@ -216,6 +221,9 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag video_switch.set_label(Some(&get_bundle("record-video", None))); area_switch.set_tooltip_text(Some(&get_bundle("show-area-tooltip", None))); audio_input_switch.set_tooltip_text(Some(&get_bundle("audio-input-tooltip", None))); + #[cfg(target_os = "windows")] + follow_mouse_switch.set_tooltip_text(Some(&get_bundle("windows-unsupported-tooltip", None))); + #[cfg(any(target_os = "freebsd", target_os = "linux"))] follow_mouse_switch.set_tooltip_text(Some(&get_bundle("follow-mouse-tooltip", None))); hide_switch.set_tooltip_text(Some(&get_bundle("hide-tooltip", None))); mouse_switch.set_tooltip_text(Some(&get_bundle("mouse-tooltip", None))); @@ -546,12 +554,12 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag }); // Buttons - //let area_capture: Rc> = - //Rc::new(RefCell::new(area_capture::AreaCapture::new()?)); + let area_capture: Rc> = + Rc::new(RefCell::new(area_capture::AreaCapture::new()?)); area_grab_label.set_label(&get_bundle("select-area", None)); let _area_chooser_window = area_chooser_window.clone(); - //let mut _area_capture = area_capture.clone(); + let mut _area_capture = area_capture.clone(); let _area_switch = area_switch.clone(); let _error_dialog = error_dialog.clone(); let _error_message = error_message.clone(); @@ -574,23 +582,32 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag area_apply_label.set_label(&get_bundle("apply", None)); let _area_chooser_window = area_chooser_window.clone(); - //let mut _area_capture = area_capture.clone(); + let mut _area_capture = area_capture.clone(); let _error_dialog = error_dialog.clone(); let _error_message = error_message.clone(); area_set_button.connect_clicked(move |_| { let text_buffer = TextBuffer::new(None); - /*if _area_capture + #[cfg(target_os = "windows")] + if _area_capture + .borrow_mut() + .get_active_window().is_err() { + text_buffer.set_text("Failed to get area size value"); + _error_message.set_buffer(Some(&text_buffer)); + _error_dialog.show(); + } + #[cfg(any(target_os = "freebsd", target_os = "linux"))] + if _area_capture .borrow_mut() .get_window_by_name(_area_chooser_window.title().unwrap().as_str()).is_err() { text_buffer.set_text("Failed to get area size value"); _error_message.set_buffer(Some(&text_buffer)); _error_dialog.show(); - }*/ + } _area_chooser_window.hide(); }); let _area_chooser_window = area_chooser_window.clone(); - //let mut _area_capture = area_capture.clone(); + let mut _area_capture = area_capture.clone(); let _area_switch = area_switch.clone(); let _error_dialog = error_dialog.clone(); let _error_message = error_message.clone(); @@ -607,15 +624,15 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag config_management::set("default", "mode", "screen"); screen_grab_button_record_window.replace(false); _area_chooser_window.hide(); - /*if _area_capture.borrow_mut().reset().is_err() { - text_buffer.set_text("Failed to get reset area_capture value"); + if _area_capture.borrow_mut().reset().is_err() { + text_buffer.set_text("Failed to reset area_capture value"); _error_message.set_buffer(Some(&text_buffer)); _error_dialog.show(); - }*/ + } }); let _area_chooser_window: Window = area_chooser_window.clone(); - //let mut _area_capture: Rc> = area_capture.clone(); + let mut _area_capture: Rc> = area_capture.clone(); let _area_switch = area_switch.clone(); let _error_dialog = error_dialog.clone(); let _error_message = error_message.clone(); @@ -631,21 +648,48 @@ fn build_ui(application: &Application, error_dialog: MessageDialog, error_messag if is_wayland() { window_grab_button_record_window.replace(true); } else { - select_window.show(); - select_window.set_hide_on_close(true); - /*if _area_capture.borrow_mut().get_area().is_err() { - text_buffer.set_text("Failed to get window size value"); - _error_message.set_buffer(Some(&text_buffer)); - _error_dialog.show(); - }*/ - } + #[cfg(target_os = "windows")] + { + select_window_label.set_label(&get_bundle("click-window", None)); + select_window.show(); + + let area_capture = _area_capture.clone(); + let error_message = _error_message.clone(); + let error_dialog = error_dialog.clone(); + let _select_window = select_window.clone(); + glib::timeout_add_local(1000, move || { + let clicked = area_capture::check_input(); + if clicked { + _select_window.hide(); + if area_capture.borrow_mut().get_title().is_err() { + text_buffer.set_text("Failed to get window info"); + error_message.set_buffer(Some(&text_buffer)); + error_dialog.show(); + } + return glib::source::Continue(false); + } else if !clicked { + _select_window.hide(); + return glib::source::Continue(false); + } + glib::source::Continue(true) + }); + } + + #[cfg(any(target_os = "freebsd", target_os = "linux"))] + { + if _area_capture.borrow_mut().get_area().is_err() { + text_buffer.set_text("Failed to get window info"); + _error_message.set_buffer(Some(&text_buffer)); + _error_dialog.show(); + } + }} }); let _delay_spin = delay_spin.clone(); //let bundle_msg = get_bundle("already-exist", None); //let main_context = glib::MainContext::default(); //let wayland_record = main_context.block_on(WaylandRecorder::new()); - // Init record struc + // Init record struct /*let ffmpeg_record_interface: Rc> = Rc::new(RefCell::new(Ffmpeg { audio_input_id: String::new(), audio_output_id: String::new(),