From 4512be22b6ca9a67f343cec58359f4465bcf9461 Mon Sep 17 00:00:00 2001
From: Gwenael Casaccio <mrgwen@gmail.com>
Date: Fri, 15 Nov 2013 12:28:11 +0100
Subject: [PATCH] Add KeySnooper handle the ctrl + . and flush the task queue.
 When the user presses the ctrl + . key the currrent process in the task queue
 is terminated, the task queue is stopped too and a new one is created.

---
 packages/visualgst/ChangeLog          |  6 +++
 packages/visualgst/GtkLauncher.st     |  1 +
 packages/visualgst/Misc/KeySnooper.st | 92 +++++++++++++++++++++++++++++++++++
 packages/visualgst/Misc/TaskQueue.st  | 10 ++++
 packages/visualgst/package.xml        |  1 +
 5 files changed, 110 insertions(+)
 create mode 100644 packages/visualgst/Misc/KeySnooper.st

diff --git a/packages/visualgst/ChangeLog b/packages/visualgst/ChangeLog
index f8d4fab..e6907d1 100644
--- a/packages/visualgst/ChangeLog
+++ b/packages/visualgst/ChangeLog
@@ -1,3 +1,9 @@
+2013-11-13  Gwenael Casaccio  <gwenael.casaccio@gmail.com>
+ 
+	* GtkLauncher.st: Initialize KeySnooper.
+	* Misc/TaskQueue.st: Flush task queue.
+	* Misc/KeySnooper.st: Add key snooper and handle the ctrl + . shortcut
+
 2013-10-21  Gwenael Casaccio  <gwenael.casaccio@gmail.com>
 
 	* Debugger/GtkDebugger.st: If stepping while the last context is not
diff --git a/packages/visualgst/GtkLauncher.st b/packages/visualgst/GtkLauncher.st
index 8b7de66..5383b34 100644
--- a/packages/visualgst/GtkLauncher.st
+++ b/packages/visualgst/GtkLauncher.st
@@ -299,6 +299,7 @@ GtkVisualGSTTool subclass: GtkLauncher [
 	imageName := File image asString.
         systemChangeNotifier := SystemChangeNotifier new.
         SystemChangeNotifier root add: systemChangeNotifier.
+        KeySnooper uniqueInstance.
 	self clearGlobalState.
 	super initialize.
 	window maximize.
diff --git a/packages/visualgst/Misc/KeySnooper.st b/packages/visualgst/Misc/KeySnooper.st
new file mode 100644
index 0000000..1fa0d8f
--- /dev/null
+++ b/packages/visualgst/Misc/KeySnooper.st
@@ -0,0 +1,92 @@
+"======================================================================
+| 
+| KeySnooper class definition
+| 
+======================================================================"
+  
+"======================================================================
+| 
+| Copyright (c) 2013
+| Gwenael Casaccio <gwenael.casaccio@gmail.com>,
+| 
+| 
+| This file is part of VisualGST.
+| 
+| Permission is hereby granted, free of charge, to any person obtaining
+| a copy of this software and associated documentation files (the
+| 'Software'), to deal in the Software without restriction, including
+| without limitation the rights to use, copy, modify, merge, publish,
+| distribute, sublicense, and/or sell copies of the Software, and to
+| permit persons to whom the Software is furnished to do so, subject to
+| the following conditions:
+| 
+| The above copyright notice and this permission notice shall be
+| included in all copies or substantial portions of the Software.
+| 
+| THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+| 
+======================================================================"
+
+Object subclass: KeySnooper [
+
+    KeySnooper class [ | uniqueInstance | ]
+
+    KeySnooper class >> initialize [
+        <category: 'initialization'>
+
+        ObjectMemory addDependent: self.
+    ]
+
+    KeySnooper class >> uniqueInstance [
+        <category: 'instance creation'>
+
+        ^ uniqueInstance ifNil: [ uniqueInstance := self new ]
+    ]
+
+    KeySnooper class >> new [
+        <category: 'instance creation'>
+
+        ^ super new
+            initialize;
+            yourself
+    ]
+
+    KeySnooper class >> update: aSymbol [
+        <category: 'initialize'>
+
+        aSymbol == #returnFromSnapshot ifTrue: [ uniqueInstance := nil ].
+    ]
+
+    | callback |
+
+    initialize [
+        <category: 'initialization'>
+
+        callback := CCallbackDescriptor 
+                            for: [ :aWidget :aGdkEventKey :aPointer |
+                                   [ self keyHandling: (GTK.GdkEventKey address: aGdkEventKey) ] on: Exception do: [ :ex | ex context backtrace.
+                                                                                                                           false ] ]
+                            returning: #boolean
+                            withArgs: #(#long #long #long).
+        GTK.Gtk keySnooperInstall: callback funcData: nil.
+    ]
+
+    keyHandling: aGdkEventKey [
+
+        ^ ((aGdkEventKey state value bitAnd: 4) = 4 and: [ aGdkEventKey keyval value = GTK.Gdk gdkPeriod ])
+                                                            ifTrue: [ VisualGST.TaskQueue uniqueInstance flush.
+                                                                      true ]
+                                                            ifFalse: [ false ]
+    ]
+]
+
+Eval [
+    KeySnooper initialize.
+]
+
diff --git a/packages/visualgst/Misc/TaskQueue.st b/packages/visualgst/Misc/TaskQueue.st
index 5922309..78555ae 100644
--- a/packages/visualgst/Misc/TaskQueue.st
+++ b/packages/visualgst/Misc/TaskQueue.st
@@ -77,5 +77,15 @@ Object subclass: TaskQueue [
             sem wait.
             currentProcess := nil ] repeat ] fork
     ]
+
+    flush [
+        <category: 'accessing'>
+
+        queueHandler ifNotNil: [ :p | p terminate ].
+        currentProcess ifNotNil: [ :p | p terminate ].
+        self 
+            initialize;
+            run.
+    ]
 ]
 
diff --git a/packages/visualgst/package.xml b/packages/visualgst/package.xml
index 52e7a31..8cd2db1 100644
--- a/packages/visualgst/package.xml
+++ b/packages/visualgst/package.xml
@@ -72,6 +72,7 @@
   <filein>Gtk/GtkEntryBuffer.st</filein>
   <filein>Extensions.st</filein>
   <filein>Misc/TaskQueue.st</filein>
+  <filein>Misc/KeySnooper.st</filein>
   <filein>Notification/AbstractEvent.st</filein>
   <filein>Notification/AddedEvent.st</filein>
   <filein>Notification/CommentedEvent.st</filein>
-- 
1.8.3.2

