Skip to content
32 changes: 32 additions & 0 deletions src/Application.vala
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,38 @@ namespace Scratch {
return windows.length () > 0 ? windows.last ().data as MainWindow : null;
}

public async void handle_quit_app () {
unowned List<Gtk.Window> windows;
windows = get_windows ();
//NOTE This yields the last opened window at head of list (may change in future?)
while (windows.length () > 0) {
if (!yield handle_quit_window ((MainWindow) (windows.first ().data))) {
return;
}

windows = get_windows ();
}

return;
}

public async bool handle_quit_window (MainWindow window_to_close) {
unowned List<Gtk.Window> windows = get_windows ();
var n_windows = windows.length ();
if (!yield window_to_close.check_unsaved_changes (n_windows == 1)) {
return false;
}

if (n_windows == 1) {
window_to_close.before_quit (); // Update settings
}
// Just destroy window - we have already checked whether any docs need saving
// When the last window is removed and destroyed the app quits.
remove_window (window_to_close);
window_to_close.destroy ();
return true;
}

public static int main (string[] args) {
// By default, profile whole app when profiling is enabled in meson_options.txt
// These conditional statements can be moved to profile sections of code
Expand Down
38 changes: 20 additions & 18 deletions src/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ namespace Scratch {
public const string ACTION_TO_UPPER_CASE = "action-to-upper-case";
public const string ACTION_DUPLICATE = "action-duplicate";
public const string ACTION_FULLSCREEN = "action-fullscreen";
public const string ACTION_QUIT = "action-quit";
public const string ACTION_QUIT = "action-quit-app";
public const string ACTION_CLOSE_WINDOW = "action-close-window";
public const string ACTION_ZOOM_DEFAULT = "action-zoom-default";
public const string ACTION_ZOOM_IN = "action-zoom-in";
public const string ACTION_ZOOM_OUT = "action-zoom-out";
Expand Down Expand Up @@ -159,7 +160,8 @@ namespace Scratch {
{ ACTION_TO_UPPER_CASE, action_to_upper_case },
{ ACTION_DUPLICATE, action_duplicate },
{ ACTION_FULLSCREEN, action_fullscreen },
{ ACTION_QUIT, action_quit },
{ ACTION_QUIT, action_quit_app },
{ ACTION_CLOSE_WINDOW, action_close_window },
{ ACTION_ZOOM_DEFAULT, action_set_default_zoom },
{ ACTION_ZOOM_IN, action_zoom_in },
{ ACTION_ZOOM_OUT, action_zoom_out},
Expand Down Expand Up @@ -208,7 +210,7 @@ namespace Scratch {
action_accelerators.set (ACTION_FIND_GLOBAL + "::", "<Control><shift>f");
action_accelerators.set (ACTION_OPEN, "<Control>o");
action_accelerators.set (ACTION_OPEN_FOLDER, "<Control><Shift>o");
action_accelerators.set (ACTION_REVERT, "<Control><shift>o");
action_accelerators.set (ACTION_REVERT, "<Control><shift>r");
action_accelerators.set (ACTION_SAVE, "<Control>s");
action_accelerators.set (ACTION_SAVE_AS, "<Control><shift>s");
action_accelerators.set (ACTION_GO_TO, "<Control>i");
Expand All @@ -223,6 +225,7 @@ namespace Scratch {
action_accelerators.set (ACTION_DUPLICATE, "<Control>d");
action_accelerators.set (ACTION_FULLSCREEN, "F11");
action_accelerators.set (ACTION_QUIT, "<Control>q");
action_accelerators.set (ACTION_CLOSE_WINDOW, "<Control>F4");
action_accelerators.set (ACTION_ZOOM_DEFAULT, "<Control>0");
action_accelerators.set (ACTION_ZOOM_DEFAULT, "<Control>KP_0");
action_accelerators.set (ACTION_ZOOM_IN, "<Control>plus");
Expand Down Expand Up @@ -720,7 +723,7 @@ namespace Scratch {
}

protected override bool delete_event (Gdk.EventAny event) {
action_quit ();
action_close_window ();
return true;
}

Expand Down Expand Up @@ -808,10 +811,10 @@ namespace Scratch {
}

// Check that there no unsaved changes and all saves are successful
private async bool check_unsaved_changes () {
public async bool check_unsaved_changes (bool app_closing) {
document_view.is_closing = true;
foreach (var doc in document_view.docs) {
if (!yield (doc.do_close (true))) {
if (!yield (doc.do_close (app_closing))) {
document_view.current_document = doc;
return false;
}
Expand Down Expand Up @@ -845,7 +848,7 @@ namespace Scratch {
}
}

private void update_saved_state () {
private void update_window_state_setting () {
// Save window state
var state = get_window ().get_state ();
if (Gdk.WindowState.MAXIMIZED in state) {
Expand All @@ -867,14 +870,14 @@ namespace Scratch {

// SIGTERM/SIGINT Handling
public bool quit_source_func () {
action_quit ();
action_quit_app ();
return false;
}

// For exit cleanup
private void handle_quit () {
document_view.save_opened_files ();
update_saved_state ();
public void before_quit () {
document_view.update_opened_files_setting ();
update_window_state_setting ();
}

public void set_default_zoom () {
Expand Down Expand Up @@ -961,13 +964,12 @@ namespace Scratch {
preferences_dialog.present ();
}

private void action_quit () {
handle_quit ();
check_unsaved_changes.begin ((obj, res) => {
if (check_unsaved_changes.end (res)) {
app.quit ();
}
});
private void action_close_window () {
app.handle_quit_window.begin (this);
}

private void action_quit_app () {
app.handle_quit_app.begin ();
}

private void action_open () {
Expand Down
10 changes: 5 additions & 5 deletions src/Widgets/DocumentView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
var should_close = doc.do_close.end (res);
// Ensure removed doc is saved by handling this first
if (!is_closing) {
save_opened_files ();
update_opened_files_setting ();
}
//`page-detached` handler will perform rest of necessary cleanup
tab_view.close_page_finish (tab, should_close);
Expand Down Expand Up @@ -337,7 +337,7 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
if (range != SelectionRange.EMPTY) {
Idle.add_full (GLib.Priority.LOW, () => { // This helps ensures new tab is drawn before opening document.
current_document.source_view.select_range (range);
save_opened_files ();
update_opened_files_setting ();

return false;
});
Expand All @@ -364,7 +364,7 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
doc.source_view.cursor_position = cursor_position;
}

save_opened_files ();
update_opened_files_setting ();
}

public void next_document () {
Expand Down Expand Up @@ -399,7 +399,7 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
}
}

public void save_opened_files () {
public void update_opened_files_setting () {
if (privacy_settings.get_boolean ("remember-recent-files")) {
var vb = new VariantBuilder (new VariantType ("a(si)"));
docs.foreach ((doc) => {
Expand Down Expand Up @@ -542,7 +542,7 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
current_document = doc;
}

save_opened_files ();
update_opened_files_setting ();
}

private unowned Hdy.TabView? on_doc_to_new_window (Hdy.TabView tab_view) {
Expand Down