From e1a5be735417bbde1c2a5c85a70da7daea032233 Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Thu, 8 Nov 2018 18:07:29 +0100
Subject: [PATCH 1/2] Cleanup IDE quit()

There were two different routines andling more or less the same operations.
Let the IDE call "real" quit when the last Editor windows is being closed.
---
 app/src/processing/app/Base.java | 29 ++---------------------------
 1 file changed, 2 insertions(+), 27 deletions(-)

diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java
index 26c7f67f4c8..33e2d29d6f6 100644
--- a/app/src/processing/app/Base.java
+++ b/app/src/processing/app/Base.java
@@ -925,45 +925,20 @@ public void actionPerformed(ActionEvent actionEvent) {
    */
   public boolean handleClose(Editor editor) {
     // Check if modified
-//    boolean immediate = editors.size() == 1;
     if (!editor.checkModified()) {
       return false;
     }
 
     if (editors.size() == 1) {
-      storeScreenDimensions();
-      storeSketches();
-
-      // This will store the sketch count as zero
-      editors.remove(editor);
-      try {
-        Editor.serialMonitor.close();
-      } catch (Exception e) {
-        //ignore
-      }
-      rebuildRecentSketchesMenuItems();
-
-      // Save out the current prefs state
-      PreferencesData.save();
 
-      // Since this wasn't an actual Quit event, call System.exit()
-      System.exit(0);
+      handleQuit();
 
     } else {
       // More than one editor window open,
       // proceed with closing the current window.
       editor.setVisible(false);
       editor.dispose();
-//      for (int i = 0; i < editorCount; i++) {
-//        if (editor == editors[i]) {
-//          for (int j = i; j < editorCount-1; j++) {
-//            editors[j] = editors[j+1];
-//          }
-//          editorCount--;
-//          // Set to null so that garbage collection occurs
-//          editors[editorCount] = null;
-//        }
-//      }
+
       editors.remove(editor);
     }
     return true;

From b71a4969af16ea24bb313198650ab9965d109062 Mon Sep 17 00:00:00 2001
From: Martino Facchin <m.facchin@arduino.cc>
Date: Thu, 8 Nov 2018 18:08:58 +0100
Subject: [PATCH 2/2] Kill active programmer if still alive after closing last
 IDE window

Fixes https://github.com/arduino/Arduino/issues/7498
---
 app/src/processing/app/Base.java                   | 9 +++++++++
 arduino-core/src/cc/arduino/packages/Uploader.java | 2 +-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java
index 33e2d29d6f6..b118dbae256 100644
--- a/app/src/processing/app/Base.java
+++ b/app/src/processing/app/Base.java
@@ -26,6 +26,7 @@
 import cc.arduino.Constants;
 import cc.arduino.UpdatableBoardsLibsFakeURLsHandler;
 import cc.arduino.UploaderUtils;
+import cc.arduino.packages.Uploader;
 import cc.arduino.contributions.*;
 import cc.arduino.contributions.libraries.*;
 import cc.arduino.contributions.libraries.ui.LibraryManagerUI;
@@ -961,6 +962,14 @@ public boolean handleQuit() {
       // ignore
     }
 
+    // kill uploader (if still alive)
+    UploaderUtils uploaderInstance = new UploaderUtils();
+    Uploader uploader = uploaderInstance.getUploaderByPreferences(false);
+    if (uploader != null && uploader.programmerPid != null && uploader.programmerPid.isAlive()) {
+        // kill the stuck programmer
+        uploader.programmerPid.destroyForcibly();
+    }
+
     if (handleQuitEach()) {
       // Save out the current prefs state
       PreferencesData.save();
diff --git a/arduino-core/src/cc/arduino/packages/Uploader.java b/arduino-core/src/cc/arduino/packages/Uploader.java
index 54b5c7abd1e..f2e2126d54b 100644
--- a/arduino-core/src/cc/arduino/packages/Uploader.java
+++ b/arduino-core/src/cc/arduino/packages/Uploader.java
@@ -106,7 +106,7 @@ public String getAuthorizationKey() {
   }
 
   // static field for last executed programmer process ID
-  static protected Process programmerPid;
+  static public Process programmerPid;
 
   protected boolean executeUploadCommand(Collection<String> command) throws Exception {
     return executeUploadCommand(command.toArray(new String[command.size()]));