Skip to content

Commit bfe98e8

Browse files
committed
Handle CLI args by overriding handle_local_options
This means we get the full Glib help again.
1 parent f1fd4f1 commit bfe98e8

1 file changed

Lines changed: 71 additions & 61 deletions

File tree

src/kcshot.rs

Lines changed: 71 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ impl KCShot {
2525
pub fn new() -> Self {
2626
glib::Object::builder()
2727
.property("application-id", "kc.kcshot")
28-
.property("flags", gio::ApplicationFlags::HANDLES_COMMAND_LINE)
2928
.build()
3029
}
3130

@@ -79,9 +78,7 @@ impl KCShot {
7978
mod underlying {
8079
use std::{
8180
cell::{Cell, OnceCell, RefCell},
82-
ffi::OsString,
8381
ops::ControlFlow,
84-
sync::LazyLock,
8582
};
8683

8784
use diesel::SqliteConnection;
@@ -101,6 +98,9 @@ mod underlying {
10198
systray,
10299
};
103100

101+
const NO_WINDOW_OPTION: &str = "no-window";
102+
const SCREENSHOT_OPTION: &str = "screenshot";
103+
104104
pub struct KCShot {
105105
pub(super) show_main_window: Cell<bool>,
106106
pub(super) take_screenshot: Cell<bool>,
@@ -120,6 +120,46 @@ mod underlying {
120120
pub(super) fn model_notifier(&self) -> ModelNotifier {
121121
self.model_notifier.get().cloned().unwrap()
122122
}
123+
124+
fn add_cli_args(&self) {
125+
let app = self.obj();
126+
127+
app.add_main_option(
128+
NO_WINDOW_OPTION,
129+
glib::Char::from(b'n'),
130+
glib::OptionFlags::NONE,
131+
glib::OptionArg::None,
132+
"Don't show any windows",
133+
None,
134+
);
135+
136+
app.add_main_option(
137+
SCREENSHOT_OPTION,
138+
glib::Char::from(b's'),
139+
glib::OptionFlags::NONE,
140+
glib::OptionArg::None,
141+
&format!("Take a screenshot (mutually exclusive with --{NO_WINDOW_OPTION})"),
142+
None,
143+
);
144+
}
145+
146+
fn setup_actions(&self) {
147+
let show_main_window = gio::ActionEntry::builder("show-main-window")
148+
.activate(|app: &super::KCShot, _, _| app.main_window().present())
149+
.build();
150+
151+
let new_editor_window = gio::ActionEntry::builder("new-editor-window")
152+
.activate(|app: &super::KCShot, _, _| {
153+
let editing_starts_with_cropping =
154+
Settings::open().editing_starts_with_cropping();
155+
156+
EditorWindow::show(app.upcast_ref(), editing_starts_with_cropping);
157+
})
158+
.build();
159+
160+
self.obj()
161+
.add_action_entries([show_main_window, new_editor_window]);
162+
}
123163
}
124164

125165
impl Default for KCShot {
@@ -170,6 +210,8 @@ mod underlying {
170210
fn constructed(&self) {
171211
self.parent_constructed();
172212

213+
self.add_cli_args();
214+
173215
match db::open() {
174216
Ok(conn) => self.database_connection.replace(Some(conn)),
175217
Err(why) => {
@@ -204,15 +246,6 @@ mod underlying {
204246
}
205247
}
206248

207-
const LONG: usize = 1;
208-
209-
static SCREENSHOT_FLAGS_OS: LazyLock<Vec<OsString>> =
210-
LazyLock::new(|| vec!["-s".into(), "--screenshot".into()]);
211-
const SCREENSHOT_FLAGS: &[&str] = &["-s", "--screenshot"];
212-
static NO_WINDOW_FLAGS_OS: LazyLock<Vec<OsString>> =
213-
LazyLock::new(|| vec!["-n".into(), "--no-window".into()]);
214-
const NO_WINDOW_FLAGS: &[&str] = &["-n", "--no-window"];
215-
216249
impl ApplicationImpl for KCShot {
217250
fn activate(&self) {
218251
self.parent_activate();
@@ -240,66 +273,43 @@ mod underlying {
240273
}
241274
}
242275

243-
// This is called in the primary instance
244-
fn command_line(&self, command_line: &gio::ApplicationCommandLine) -> glib::ExitCode {
245-
let mut show_main_window = true;
246-
for argument in command_line.arguments() {
247-
if NO_WINDOW_FLAGS_OS.contains(&argument) {
248-
show_main_window = false;
249-
self.take_screenshot.set(false);
250-
} else if SCREENSHOT_FLAGS_OS.contains(&argument) {
251-
self.take_screenshot.set(true);
252-
show_main_window = false;
253-
}
276+
fn handle_local_options(&self, options: &glib::VariantDict) -> ControlFlow<glib::ExitCode> {
277+
if let Err(err) = self.obj().register(None::<&gio::Cancellable>) {
278+
tracing::error!("Failed to register app: {err}");
279+
return ControlFlow::Break(glib::ExitCode::FAILURE);
254280
}
255-
self.show_main_window.set(show_main_window);
256-
257-
self.obj().activate();
258281

259-
glib::ExitCode::from(0)
260-
}
261-
262-
// This is called in remote instances
263-
fn local_command_line(
264-
&self,
265-
arguments: &mut gio::subclass::ArgumentList,
266-
) -> ControlFlow<glib::ExitCode> {
267-
let prog_name = glib::prgname().unwrap_or_else(|| "kcshot".into());
268-
let usage = format!(
269-
r#"Usage:
270-
{prog_name} [OPTION...]
271-
272-
Help Options:
273-
-h, --help Show help options
274-
275-
Application Options:
276-
-n, --no-window Don't show any windows
277-
-s, --screenshot Take a screenshot (mutually exclusive with -n)
278-
"#
279-
);
282+
match (
283+
options.contains(NO_WINDOW_OPTION),
284+
options.contains(SCREENSHOT_OPTION),
285+
) {
286+
(true, true) => {
287+
let prog_name = glib::prgname().unwrap_or_else(|| "kcshot".into());
280288

281-
if arguments.contains(&"-h".into()) || arguments.contains(&"--help".into()) {
282-
eprintln!("{usage}");
283-
return ControlFlow::Break(glib::ExitCode::SUCCESS);
284-
}
289+
eprintln!(
290+
"{prog_name}: --{NO_WINDOW_OPTION} and --{SCREENSHOT_OPTION} mutually exclusive"
291+
);
285292

286-
let take_screenshot = arguments.iter().any(|os| SCREENSHOT_FLAGS_OS.contains(os));
287-
let no_window = arguments.iter().any(|os| NO_WINDOW_FLAGS_OS.contains(os));
293+
ControlFlow::Break(glib::ExitCode::FAILURE)
294+
}
295+
(true, false) => self.parent_handle_local_options(options),
296+
(false, true) => {
297+
self.obj().activate_action("new-editor-window", None);
288298

289-
if take_screenshot && no_window {
290-
eprintln!(
291-
"{}: {} and {} are mutually exclusive\n{}",
292-
prog_name, SCREENSHOT_FLAGS[LONG], NO_WINDOW_FLAGS[LONG], usage
293-
);
294-
return ControlFlow::Break(glib::ExitCode::FAILURE);
299+
ControlFlow::Break(glib::ExitCode::SUCCESS)
300+
}
301+
(false, false) => {
302+
self.obj().activate_action("show-main-window", None);
303+
ControlFlow::Break(glib::ExitCode::SUCCESS)
304+
}
295305
}
296-
297-
ControlFlow::Continue(())
298306
}
299307

300308
fn startup(&self) {
301309
self.parent_startup();
302310

311+
self.setup_actions();
312+
303313
// This hold has no matching release intentionally so that the application keeps running
304314
// in the background even when no top-level windows are spawned. (This is the case when
305315
// we get started with `--no-window`)

0 commit comments

Comments
 (0)