diff --git a/gtk_channels/CMakeLists.txt b/gtk_channels/CMakeLists.txt
index c57fe921f1b61e3413739c395d22f158e5df04e8..532e7b324fd0822f094c1f1dec70f5947d749f84 100644
--- a/gtk_channels/CMakeLists.txt
+++ b/gtk_channels/CMakeLists.txt
@@ -1,22 +1,22 @@
 # Set the minimum version of cmake required to build this project
+cmake_minimum_required(VERSION 3.3)
 
-cmake_minimum_required(VERSION 2.6)
 project(gtk_channels)
 
+#set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "/usr/local/Cellar/include-what-you-use/0.12/bin/include-what-you-use;-Xiwyu;--verbose=3;")
+
 find_package(blc_channel REQUIRED)
-find_package(blc_image REQUIRED)
+find_package(blc_image REQUIRED) #Used to detect image format in channels
 find_package(blc_program REQUIRED)
 find_package(blc_process REQUIRED)
 
 find_package(PkgConfig REQUIRED) 
-pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
-pkg_check_modules(GTK3_SOURCE_VIEW REQUIRED gtksourceview-4)
+#pkg_check_modules(GTK3  gtk+-3.0 REQUIRED)
 pkg_check_modules(GTKMM gtkmm-3.0 REQUIRED)
-pkg_check_modules(VTE3  vte-2.91 REQUIRED) #libvtemm is not yet common
-#pkg_check_modules(GTKMMPLPLOT REQUIRED gtkmm-plplot-2.0)
+pkg_check_modules(VTE3  vte-2.91 REQUIRED) #libvtemm is not yet common and stable we
 
-add_definitions(-std=c++14 ${BL_DEFINITIONS} ${GTK3_CFLAGS_OTHER} )
-include_directories(${BL_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS} ${GTK3_SOURCE_VIEW_INCLUDE_DIRS} ${VTE_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS} ${VTE3_INCLUDE_DIRS})
-link_directories(${GTK3_LIBRARY_DIRS}  ${VTE_LIBRARY_DIRS} /usr/local/lib)
-add_executable(gtk_channels gtk_channels.cpp ChannelWidget.cpp ContextMenu.cpp ChannelColumns.cpp Process.cpp parse_help.cpp)
-target_link_libraries(gtk_channels ${BL_LIBRARIES} ${GTK3_LIBRARIES} ${GTK3_SOURCE_VIEW_LIBRARIES} ${VTE_LIBRARIES} ${GTKMM_LIBRARIES} ${VTE3_LIBRARIES})
+add_definitions(-std=c++17 -pedantic ${BL_DEFINITIONS})
+include_directories(${BL_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS} ${VTE3_INCLUDE_DIRS})
+link_directories(${GTKMM_LIBRARY_DIRS} ${VTE3_LIBRARY_DIRS})
+add_executable(gtk_channels gtk_channels.cpp ChannelWidget.cpp ContextMenu.cpp ChannelColumns.cpp Command.cpp Process.cpp parse_help.cpp)
+target_link_libraries(gtk_channels ${BL_LIBRARIES}  ${GTKMM_LIBRARIES} ${VTE3_LIBRARIES})
diff --git a/gtk_channels/ChannelWidget.cpp b/gtk_channels/ChannelWidget.cpp
index ee4a0286c4ad244631b404529306b540aebd6b80..9d562a14b47d5fd5962631c673447ca571e714bf 100644
--- a/gtk_channels/ChannelWidget.cpp
+++ b/gtk_channels/ChannelWidget.cpp
@@ -5,20 +5,16 @@
 //  Created by Arnaud Blanchard on 29/09/2019.
 //
 
-#include "ChannelColumns.hpp"
-#include "Process.h"
-#include "ChannelWidget.hpp"
 #include "blc_channel.h"
 #include "blc_image.h"
+#include "ChannelColumns.hpp"
+#include "ChannelWidget.hpp"
+#include "Process.h"
+#include "Command.hpp"
 
+#include <numeric> //Accumulate
 #include <string>
 #include <vector>
-#include <forward_list>
-
-#include <vte/vte.h>
-#include <thread>
-#include <iostream>
-#include <numeric>
 
 using namespace Gtk;
 using namespace Glib; //signal_idle,RefPtr
@@ -37,9 +33,7 @@ ChannelColumns ChannelWidget::columns;
 ChannelWidget::ChannelWidget(){
     char const *blaar_dir=getenv("BLAAR_DIR");
     if (blaar_dir==nullptr) EXIT_ON_ERROR("Your environment variable 'BLAAR_DIR' is not defined.");
-    
-    program_dir=blaar_dir;
-    program_dir+="/bin";
+    bin_dir=string(blaar_dir)+"/bin";
     
     append_column("Name", columns.name);
     append_column("Type", columns.type);
@@ -54,29 +48,62 @@ ChannelWidget::ChannelWidget(){
     col->add_attribute(terminal_cell_renderer, "icon-name",  columns.terminal_icon);
     append_column(*col);
     
-    col =  new TreeViewColumn(" ");
-    col->pack_start(play_pause_cell_renderer);
-    col->pack_start(stop_cell_renderer);
-    
+    col =  new TreeViewColumn(" ", play_pause_cell_renderer);
     col->add_attribute(play_pause_cell_renderer, "icon-name",  columns.play_pause_icon);
-    col->add_attribute(stop_cell_renderer, "icon-name",  columns.stop_icon);
     col->add_attribute(play_pause_cell_renderer, "sensitive", columns.play_pause_sensitive);
+    append_column(*col);
+    
+    col =  new TreeViewColumn(" ", stop_cell_renderer);
+    col->add_attribute(stop_cell_renderer, "icon-name",  columns.stop_icon);
     col->add_attribute(stop_cell_renderer, "sensitive", columns.stop_sensitive);
     append_column(*col);
     
+    
+
+    commands.emplace("graph", Command(bin_dir, "o_gnuplot", {}, [](vector<blc_channel const*> channels ){
+        if (channels.size()>1) return false;
+      }));
+    commands.emplace("graph history", Command(bin_dir, "o_gnuplot", {"--history=100"}, [](vector<blc_channel const*> channels ){
+         int total_length=channels[0]->total_length;
+         return all_of(channels.begin()+1,channels.end(),[total_length](blc_channel const *channel){
+             if (channel->dims_nb==1 && channel->total_length!=total_length) return false;
+             else if (channel->dims_nb==2) return false;
+             return true;
+         });
+       }));
+    commands.emplace("keyboard", Command(bin_dir, "i_keyboard", {"--debug"}, [](vector<blc_channel const*> channels ){
+        if (channels.size()==1 && channels[0]->total_length<=64) return true;
+        else return false;
+    }));
+
+    
     signal_row_activated().connect([this](const TreeModel::Path& path, TreeViewColumn* column){
         int x, y;
         TreeIter iter=this->tree_store->get_iter(path);
         TreeModel::Row row = *iter;
-        
         Process *process=row[columns.process];
-        
         if (tree_store->iter_depth(iter) != 0){ //It is a process
             if (column->get_cell_position(terminal_cell_renderer, x, y)){//x, y are not used but it allow to chack the existanace of the cell renderer
                 process->display_terminal();
             }
             else if (column->get_cell_position(play_pause_cell_renderer, x, y)){
-                process->signal(SIGTSTP);
+                switch (process->status){
+                    case Process::running:
+                        process->pause();
+                        row[columns.play_pause_icon]="media-playback-start";
+                        break;
+                    case Process::paused:
+                        process->cont();
+                        row[columns.play_pause_icon]="media-playback-pause";
+                        break;
+                    case Process::stopped:
+                        process->run();
+                        break;
+                }
+            }
+            else if (column->get_cell_position(stop_cell_renderer, x, y)){
+                process->stop();
+                row [columns.stop_sensitive]=false;
             }
         }
     });
@@ -96,8 +123,7 @@ ChannelWidget::ChannelWidget(){
 }
 
 blc_channel *ChannelWidget::find_channel(int  id){
-    blc_channel *channel;
-    channel= lower_bound(channels, channels+channels_nb, id, [](blc_channel const &a, int id){
+    blc_channel *channel= lower_bound(channels, channels+channels_nb, id, [](blc_channel const &a, int id){
         return (a.id < id);
     });
     return channel;
@@ -112,27 +138,21 @@ void ChannelWidget::after_launch(Process *process, std::vector<TreeModel::Path>
     for (auto const &path : rows){
         TreeNodeChildren node = tree_store->get_iter(path)->children();
         TreeIter row_iter=tree_store->append(node);
-         process_rows->emplace_back(row_iter);
+        process_rows->emplace_back(row_iter);
         TreeRow row=*row_iter;
         row[columns.name]=command;
         row[columns.terminal_icon]="utilities-terminal";
         row[columns.play_pause_icon]="media-playback-pause";
         row[columns.play_pause_sensitive]=true;
-
         row[columns.stop_icon]="media-playback-stop";
         row[columns.stop_sensitive]=true;
-
         row[columns.process]= process;
         expand_row(path, true);
-   //     process_rows->push_back(row_iter);
     }
     
     process->on_quit([process_rows](int status){
         for (auto &row_iter : *process_rows){
             TreeRow row=*row_iter;
-
-          //  row[columns.name]=command;
-         //   row[columns.terminal_icon]="utilities-terminal";
             if (status==0)  row[columns.terminal_icon]="process-stop";
             else row[columns.terminal_icon]="dialog-error";
             row[columns.play_pause_icon]="media-playback-start";
@@ -145,31 +165,63 @@ void ChannelWidget::after_launch(Process *process, std::vector<TreeModel::Path>
 void ChannelWidget::on_quit(Process *process, int status, std::vector<TreeModel::Path> rows){
     for (auto const &path : rows){
         TreeRow row = *tree_store->get_iter(path);
-      //  row[columns.name]=command;
-     //   row[columns.terminal_icon]="utilities-terminal";
+        //  row[columns.name]=command;
+        //   row[columns.terminal_icon]="utilities-terminal";
         if (status==0)  row[columns.terminal_icon]="process-stop";
         else  row[columns.terminal_icon]="dialog-error";
         row[columns.stop_icon]="media-playback-start";
         expand_row(path, true);
     }
 }
+/*
+void ChannelWidget::create_and_execute_command(string program_name, initializer_list<const char*> arguments){
+    commands.emplace_back(bin_dir, program_name, arguments));
+    auto command=&commands.back();
+    command->execute();
+}*/
 
-ContextMenu *ChannelWidget::create_menu(){
-    bool only_channels=true, can_keyboard=true, can_image=true,  can_graph=true, can_history_graph=true;
-    menu=new ContextMenu(program_dir);
-
-    menu->row_selection=get_selection();
-    menu->row_selection->selected_foreach_iter ([&](TreeModel::iterator const &iter){
-        if (tree_store->iter_depth(iter)==0){
-            blc_channel *channel=find_channel((*iter)[columns.id]);
-            if (channel->total_length > 64) can_keyboard=false;
-            if (blc_image_get_bytes_per_pixel(channel)==0) can_image=false;
-            if (channel->dims_nb > 1) can_history_graph=false;
-            else if (channel->dims_nb > 2) can_graph=false;
-            menu->selected_channels.emplace_back(channel);
+/*
+void ContextMenu::add_program(char const *menu_name, std::string program_name, initializer_list<const char*> const optional_arguments, function <void(Process *process)> after_launch){
+    auto item=new MenuItem(menu_name);
+    auto args_vec=make_shared<vector<const char*>>(optional_arguments); //This will be destroyed by process
+    append(*item);
+    
+    item->signal_activate().connect([this, args_vec, program_name, after_launch]{
+        args_vec->reserve(args_vec->size()+selected_channels.size());
+        for(auto const &channel:selected_channels){
+            args_vec->push_back(strdup(channel->name));
         }
-        else only_channels=false;
+        auto process = new Process(program_dir, program_name, args_vec);
+        process->run(after_launch);
     });
+}*/
+
+
+/*
+item->signal_activate().connect([this, args_vec, program_name, after_launch]{
+    args_vec->reserve(args_vec->size()+selected_channels.size());
+    for(auto const &channel:selected_channels){
+        args_vec->push_back(strdup(channel->name));
+    }
+    auto process = new Process(program_dir, program_name, args_vec);
+    process->run(after_launch);
+});
+ */
+
+ContextMenu *ChannelWidget::create_menu(){
+    bool only_channels=true;
+    vector<Command*> context_commands;
+    vector<blc_channel const *> selected_channels;
+    menu=new ContextMenu();
+    menu->row_selection=get_selection();
+    
+    get_selection()->selected_foreach_iter ([&](TreeModel::iterator const &iter){
+           if (tree_store->iter_depth(iter)==0){
+               blc_channel *channel=find_channel((*iter)[columns.id]);
+               selected_channels.emplace_back(channel);
+           }
+           else only_channels=false;
+       });
     
     if (only_channels){
         menu->add_item("_Remove", true, [this]{
@@ -179,15 +231,14 @@ ContextMenu *ChannelWidget::create_menu(){
         });
         menu->add_separator();
         
-        Glib::RefPtr<TreeModel> tree_model=tree_store;
-        
-        /* This is the simpler I can do for a callback
-         It means this->after_launch( first_argument (i.e. process)) will be called.*/
-        auto after_launch_callback=bind(&ChannelWidget::after_launch, this, placeholders::_1,  menu->row_selection->get_selected_rows(tree_model));//This is a way to pass the rows, without process needing to know what is row
-        if (can_keyboard) menu->add_program("keyboard", "i_keyboard", {"--display","--output"}, after_launch_callback);
-        if (can_image) menu->add_program("image", "o_gtk_image", {},  after_launch_callback);
-        if (can_graph) menu->add_program("graph", "o_gnuplot", {},  after_launch_callback);
-        if (can_history_graph) menu->add_program("history graph", "o_gnuplot", {"--history=100"},  after_launch_callback);
+        for ( const auto&  [name, command]:commands){
+            Command const *command_ptr=&command; //wihout ptr, command cannot be pass to lambda
+            if (command.valid_channels(selected_channels));
+            menu->add_item(name, false, [this, command_ptr, selected_channels](){
+                auto command =used_commands.emplace_back(*command_ptr, selected_channels);
+                auto process=new Process(command.args.data(), [](Process*){});
+            });
+        }
     }
     menu->show_all();
     return menu;
@@ -201,16 +252,15 @@ void ChannelWidget::refresh_channel_list(){
     ///  We define a functor to compare blc_channel and TreeIter by id
     struct compare_id{
         bool operator()(blc_channel const &a, TreeIter const &b) { return a.id < (*b)[columns.id]; };
-        bool operator()(TreeIter const &a, blc_channel const &b) { return  (*a)[columns.id]< b.id ; };
-    };
-            
-    vector<blc_channel> news_channels;
-    vector<TreeIter> channels_to_remove;
+            bool operator()(TreeIter const &a, blc_channel const &b) { return  (*a)[columns.id]< b.id ; };
+            };
+            vector<blc_channel> news_channels;
+            vector<TreeIter> channels_to_remove;
             
-    FREE(channels);
-    tie(channels, channels_nb)=blc_channel::get_all_infos();
+            FREE(channels);
+            tie(channels, channels_nb)=blc_channel::get_all_infos();
             
-    //We get children to be able to use iterator
+            //We get children to be able to use iterator
             auto children=tree_store->children();
             
             //We get a list of new channels
diff --git a/gtk_channels/ChannelWidget.hpp b/gtk_channels/ChannelWidget.hpp
index 794f8520dcc9774db0106876d5bd4def5f11fb1e..b6b5e8887baa10072eb296475a5938b7b22f2993 100644
--- a/gtk_channels/ChannelWidget.hpp
+++ b/gtk_channels/ChannelWidget.hpp
@@ -12,11 +12,13 @@
 
 #include <gtkmm.h>
 #include <string>
-#include <deque>
-#include <set>
 #include "blc_channel.h"
 #include "ChannelColumns.hpp"
 #include "ContextMenu.hpp"
+#include "Command.hpp"
+#include <unordered_map>
+#include <map>
+
 
 struct ChannelWidget:Gtk::TreeView{
     blc_channel* channels;  //This structure is coherent with blc_channel implementation
@@ -24,13 +26,16 @@ struct ChannelWidget:Gtk::TreeView{
     Gtk::CellRendererPixbuf  terminal_cell_renderer, play_pause_cell_renderer, stop_cell_renderer;
     Glib::RefPtr<Gtk::TreeStore>  tree_store;
     int channels_nb;
-    std::string program_dir;
-    
+    std::string bin_dir;
+    std::map<std::string, Command> commands;
+    std::vector<Command> used_commands;
     static ChannelColumns columns;
 
     ChannelWidget();
     blc_channel *find_channel(int  id);
     ContextMenu *create_menu();
+    void create_and_execute_command(std::string program_name, std::initializer_list<const char*> const optional_arguments);
+
 
     void display_process(Gtk::TreeModel::Row &row);
     void refresh_channel_list();
diff --git a/gtk_channels/Command.cpp b/gtk_channels/Command.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5da5cb07cc80d660d7575d140fc39d6da32e14ee
--- /dev/null
+++ b/gtk_channels/Command.cpp
@@ -0,0 +1,34 @@
+//
+//  Command.cpp
+//  gtk_channels
+//
+//  Created by Arnaud Blanchard on 21/10/2019.
+//
+#include "Command.hpp"
+#include <numeric> //accumulate
+using namespace std;
+
+Command::Command(string const &bin_dir, string program_name, initializer_list<char const*> default_args, function<bool(vector<blc_channel const*>)>valid_channels):binary(bin_dir+"/"+program_name), program_name(move(program_name)), valid_channels(valid_channels){
+    args.emplace_back(binary.data());
+    args.insert(args.end(), default_args);
+}
+
+Command::Command(Command const &command, vector<blc_channel const*> const channels){
+    *this=command;
+    args.reserve(args.size()+channels.size()+1);
+    for (auto const &channel:channels){
+        args.emplace_back(channel->name);
+    }
+    args.emplace_back(nullptr);
+}
+
+void Command::add_args(initializer_list<char const *> optional_args){
+    args.insert(args.end(), optional_args);
+}
+
+unique_ptr<Process> Command::execute(function<void(Process*)> after_launch) const{
+    
+  /*  for (auto &channel:channels){
+        process_args.emplace_back(channel->name);
+    }*/
+}
diff --git a/gtk_channels/Command.hpp b/gtk_channels/Command.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ac6f02f472d8eb9e680c99c416443f4d70f46f0a
--- /dev/null
+++ b/gtk_channels/Command.hpp
@@ -0,0 +1,30 @@
+//
+//  Command.hpp
+//  gtk_channels
+//
+//  Created by Arnaud Blanchard on 21/10/2019.
+//
+
+#ifndef Command_hpp
+#define Command_hpp
+
+#include <string>
+#include <vector>
+#include "Process.h"
+#include "blc_channel.h"
+
+/* One command may have many processes */
+struct Command{
+    std::string binary;
+    std::string program_name;
+    std::function<bool(std::vector<blc_channel const*> &channels)> valid_channels;
+    std::vector<const char *> args;
+    
+    Command(std::string const &bin_dir, std::string program_name, std::initializer_list<char const*> default_args, std::function<bool(std::vector<blc_channel const*>)>validity);
+    Command(Command const &command, std::vector<blc_channel const*> const channel); //Copy command and add arguments
+
+    void add_args(std::initializer_list<char const *> optional_args);
+    std::unique_ptr<Process> execute(std::function<void(Process*)> after_launch) const;
+};
+
+#endif /* Command_hpp */
diff --git a/gtk_channels/ContextMenu.cpp b/gtk_channels/ContextMenu.cpp
index ffa658e4f16f54afa531d335c0a9b2a665013eb3..7a8604a124ead036af2527032a272e097013bd04 100644
--- a/gtk_channels/ContextMenu.cpp
+++ b/gtk_channels/ContextMenu.cpp
@@ -4,15 +4,11 @@
 //
 //  Created by Arnaud Blanchard on 13/10/2019.
 //
-
-#include "ChannelWidget.hpp"
-#include "blc_image.h"
+#include "ContextMenu.hpp"
 
 using namespace Gtk;
 using namespace std;
 
-ContextMenu::ContextMenu(string program_dir):program_dir(move(program_dir)){}
-
 void ContextMenu::add_item(string name, bool shortcut, function <void()> action){
     MenuItem *item=new MenuItem(name, shortcut);
     append(*item);
@@ -23,7 +19,7 @@ void ContextMenu::add_separator(){
     SeparatorMenuItem *separator_item = new SeparatorMenuItem();
     append(*separator_item);
 }
-
+/*
 void ContextMenu::add_program(char const *menu_name, std::string program_name, initializer_list<const char*> const optional_arguments, function <void(Process *process)> after_launch){
     auto item=new MenuItem(menu_name);
     auto args_vec=make_shared<vector<const char*>>(optional_arguments); //This will be destroyed by process
@@ -37,4 +33,4 @@ void ContextMenu::add_program(char const *menu_name, std::string program_name, i
         auto process = new Process(program_dir, program_name, args_vec);
         process->run(after_launch);
     });
-}
+}*/
diff --git a/gtk_channels/ContextMenu.hpp b/gtk_channels/ContextMenu.hpp
index 99815f1c08302e0a58b9b3b38c587455be2fabc3..3033866af9c76597d6fb7afd8619e78085ec0c64 100644
--- a/gtk_channels/ContextMenu.hpp
+++ b/gtk_channels/ContextMenu.hpp
@@ -14,19 +14,13 @@
 #include <string>
 #include <vector>
 
-#include "Process.h"
-
-
 struct ContextMenu:Gtk::Menu{
-    std::string program_dir;
     std::vector<blc_channel*> selected_channels;
     Glib::RefPtr<Gtk::TreeSelection> row_selection;
     
-    ContextMenu(std::string program_dir);
-    void after_launch(Process *process);
     void add_item(std::string name, bool shortcut, std::function<void ()>action);
     void add_separator();
-    void add_program(char const *menu_name, std::string program_name, std::initializer_list<const char*> const optional_args, std::function <void(Process*)> after_launch);
+   // void add_program(char const *menu_name, std::string program_name, std::initializer_list<const char*> const optional_args, std::function <void(Process*)> after_launch);
 };
 
 #endif /* ContextMenu_hpp */
diff --git a/gtk_channels/Process.cpp b/gtk_channels/Process.cpp
index 4bb8bf07c659e6ab95528e71ba1468a002f29125..41832ede7eae0ccf7a4e0fd1062e2cc2dac0b4fd 100644
--- a/gtk_channels/Process.cpp
+++ b/gtk_channels/Process.cpp
@@ -6,16 +6,11 @@
 //
 //
 #include "Process.h"
-#include "blc_core.h"
 #include <errno.h>
-#include <unistd.h> //execve
-#include <thread>
 #include <vte/vte.h>
-#include <sys/pipe.h>
 #include <gtkmm.h>
 #include <signal.h>
 
-
 using namespace std;
 using namespace Gtk;
 
@@ -35,6 +30,7 @@ static void TerminalSpawnAsyncCallback (VteTerminal *terminal, GPid pid, GError
                    fprintf(stderr, "%s ", arg);
                }
                fprintf(stderr, "\n");
+        process->status=Process::running;
         process->after_launch(process);
     }
 };
@@ -50,26 +46,15 @@ void Process::on_quit(function<void(int exit_status)> on_quit){
     g_signal_connect(G_OBJECT(terminal), "child-exited", G_CALLBACK(after_exectution) , this);
 }
 
-
-Process::Process(string const directory, string const program, shared_ptr<vector<const char*>> const optional_arguments):directory(move(directory)),program_name(move(program)){
-    command_path=directory+"/"+program;
-    arg_vector.emplace_back(command_path.data());
+Process::Process(char const * const *argv, function<void(Process *)>after_launch){
+        this->after_launch=after_launch;
+        terminal=VTE_TERMINAL(vte_terminal_new());
+        vte_terminal_spawn_async(terminal, VTE_PTY_DEFAULT , nullptr, (char**)argv, nullptr, G_SPAWN_DEFAULT, nullptr, nullptr, nullptr, 1000, nullptr, TerminalSpawnAsyncCallback, (void*)this);
     
-    for( auto &arg : *optional_arguments){
-        arg_vector.emplace_back(arg);
-    }
 };
 
-Process::~Process(){
-    for (char const *&arg: arg_vector ){
-        free(&arg);
-    }
-};
 
-void Process::run(function <void(Process *process)> after_launch){
-    this->after_launch=after_launch;
-    terminal=VTE_TERMINAL(vte_terminal_new());
-    arg_vector.emplace_back(nullptr); //note the end of the list
+void Process::run(){
     vte_terminal_spawn_async(terminal, VTE_PTY_DEFAULT , nullptr, (char**)arg_vector.data(), nullptr, G_SPAWN_DEFAULT, nullptr, nullptr, nullptr, 1000, nullptr, TerminalSpawnAsyncCallback, (void*)this);
 }
 
@@ -87,6 +72,19 @@ void Process::display_terminal(){
     terminal_window->show_all();
 }
 
+
+void Process::stop(){
+    signal(SIGTERM);
+    status=stopped;
+};
+void Process::pause(){
+    signal(SIGTSTP);
+    status=paused;
+};
+void Process::cont(){
+    signal(SIGCONT);
+    status=running;
+};
 void Process::signal(int signal) const{
     kill(pid, signal);
 }
diff --git a/gtk_channels/Process.h b/gtk_channels/Process.h
index 98b57f86d5b5bb9e132d317155ca4ef58787139a..ef7266c5362e44b42a9cc050e8720edcfe17c2ec 100644
--- a/gtk_channels/Process.h
+++ b/gtk_channels/Process.h
@@ -16,8 +16,8 @@
 #include <vte/vte.h>
 
 struct Process{
+    enum Status{paused, stopped, running} status=stopped;
     pid_t pid;
-
     std::string name;
     std::string directory;
     std::string program_name;
@@ -28,11 +28,16 @@ struct Process{
     std::function<void(Process *)> after_launch;
     std::function<void(int exit_status)> on_quit_callback;
 
-    
-    Process(std::string const directory, std::string const program_name, std::shared_ptr<std::vector<const char*>> const optional_arguments={});
-    ~Process();
+    Process(char const* const* argv, std::function<void(Process*)> on_launch);
     
     void run(std::function<void(Process*)> on_launch);
+    void run();
+
+    void stop();
+    void pause();
+    void cont();
+
+
     void display_terminal();
     void on_quit(std::function<void(int exit_status)> on_quit);
     void signal(int signal) const;
diff --git a/gtk_channels/gtk_channels.cpp b/gtk_channels/gtk_channels.cpp
index 2327f0d54c18f1e29820236b00ee8aa68661a833..ece0ab92258e386ce4fd72879676f45932af74ef 100644
--- a/gtk_channels/gtk_channels.cpp
+++ b/gtk_channels/gtk_channels.cpp
@@ -1,9 +1,6 @@
-
+#include "ChannelWidget.hpp"
 #include "blc_program.h"
-#include "libgen.h"
 #include <gtkmm.h>
-#include "ChannelWidget.hpp"
-#include "thread"
 
 using namespace std;
 using namespace Gtk;
@@ -16,11 +13,10 @@ struct App:Application{
     
     //Overrides of default signal handlers:
     void on_startup() override; //This is called for the first instance of the app
-    void on_activate() override;
+    void on_activate() override; //This is called a new instance of the app is called (i.e already existing)
 };
 
-App::App(int &argc, char **&argv):Application(argc, argv){
-}
+App::App(int &argc, char **&argv):Application(argc, argv){}
 
 void App::on_startup(){
     Application::on_startup();
@@ -30,7 +26,6 @@ void App::on_startup(){
   }
 
 void App::on_activate(){
-    
     Application::on_activate();
     add_window(main_window);
     main_window.add(channel_widget);
@@ -39,7 +34,7 @@ void App::on_activate(){
 
 int main(int argc, char **argv)
 {
-    App app(argc, argv); //AArgc argv allow to interpret option --g-fatal-warnings for debugging
+    App app(argc, argv); //Argc argv allow to interpret option --g-fatal-warnings for debugging
     
     blc_program_set_description("Graphical interface for blaar programs");
     blc_program_init(&argc, &argv, blc_quit);