From 72bb302eb22c7cd0400683c63f55c134e2bc5867 Mon Sep 17 00:00:00 2001 From: Pablo Castorino Date: Thu, 10 Mar 2016 15:50:18 -0300 Subject: [PATCH 01/19] support notification received vte (2.91) --- altyo_window.vala | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/altyo_window.vala b/altyo_window.vala index b04d327..a0751c7 100644 --- a/altyo_window.vala +++ b/altyo_window.vala @@ -1619,6 +1619,10 @@ public class AYObject :Object{ this.title_changed((Vte.Terminal)vt.vte_term); } ); + #if VTE_2_91 + vt.vte_term.notification_received.connect(notification_received_cb); + #endif + vt.tbutton.button_press_event.connect(tab_button_press_event); this.hvbox.insert( vt.tbutton ,(int) index); @@ -1942,6 +1946,19 @@ public class AYObject :Object{ } + private void notification_received_cb(Vte.Terminal terminal, string summary, string? body) + { + print ("[%s]: %s\n", summary, body); + //FIXME: detect actual tab + if (this.main_window.current_state == WStates.VISIBLE) + return; + + var notification = new GLib.Notification (summary); + notification.set_body (body); + var gicon = GLib.Icon.new_for_string ("altyo"); + notification.set_icon (gicon); + GLib.Application.get_default().send_notification (null, notification); + } public void tab_sort () { bool update_titles=false; From cdeb6bcfa6766f7bd0d0d9663dad4b84fec590c3 Mon Sep 17 00:00:00 2001 From: Pablo Castorino Date: Thu, 10 Mar 2016 15:52:30 -0300 Subject: [PATCH 02/19] use id as filename desktop for gnome-shell support. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 98f8aea..0db0e8d 100644 --- a/Makefile +++ b/Makefile @@ -93,7 +93,7 @@ install: gen_mo test -z "$(DESTDIR)$(PREFIX)/bin" || mkdir -p "$(DESTDIR)$(PREFIX)/bin"; cp -a ./$(PRG_NAME) $(DESTDIR)$(PREFIX)/bin test -z "$(DESTDIR)$(PREFIX)/share/applications" || mkdir -p "$(DESTDIR)$(PREFIX)/share/applications"; - cp -a ./data/altyo.desktop $(DESTDIR)$(PREFIX)/share/applications + cp -a ./data/altyo.desktop $(DESTDIR)$(PREFIX)/share/applications/org.gtk.altyo.desktop cp -a ./data/altyo_standalone.desktop $(DESTDIR)$(PREFIX)/share/applications test -z "$(DESTDIR)$(PREFIX)/share/locale/ru/LC_MESSAGES" || mkdir -p "$(DESTDIR)$(PREFIX)/share/locale/ru/LC_MESSAGES"; cp -a ./po/ru/LC_MESSAGES/altyo.mo $(DESTDIR)$(PREFIX)/share/locale/ru/LC_MESSAGES From 736fe719c291193676dc80604d130d7ee015409b Mon Sep 17 00:00:00 2001 From: denis Date: Sat, 16 Apr 2016 21:13:26 +0300 Subject: [PATCH 03/19] fix #50 --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 98f8aea..395112f 100644 --- a/Makefile +++ b/Makefile @@ -119,6 +119,9 @@ source-package: sed -i -re '1 s/(altyo \(.*)\) .*\;/\1~vivid\) vivid\;/' ./debian/changelog dpkg-buildpackage -S -sa git checkout ./debian/changelog + sed -i -re '1 s/(altyo \(.*)\) .*\;/\1~xenial\) xenial\;/' ./debian/changelog + dpkg-buildpackage -S -sa + git checkout ./debian/changelog gen_changes: git-dch --ignore-branch --debian-branch=master --verbose -a -R From f4321779e51d13573ee175bba5c341510aab1927 Mon Sep 17 00:00:00 2001 From: denis Date: Sat, 16 Apr 2016 21:15:25 +0300 Subject: [PATCH 04/19] new: debian release 0.4_rc18-linvinus1 --- debian/changelog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/debian/changelog b/debian/changelog index 51820e8..0861c07 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +altyo (0.4~rc18-linvinus1) vivid; urgency=medium + + * fix #33 + * improvement: implement feature-request #43, new default behaviour for scrolling + * fix #50, build package for xenial + + -- denis Sat, 16 Apr 2016 21:14:37 +0300 + altyo (0.4~rc17-linvinus1) vivid; urgency=medium * fix: #24 From 45d25aee1b29686f51db7e97cbabeb10c5103e64 Mon Sep 17 00:00:00 2001 From: linvinus Date: Tue, 19 Apr 2016 11:18:16 +0300 Subject: [PATCH 05/19] trying to resolve #25 --- altyo_window.vala | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/altyo_window.vala b/altyo_window.vala index b04d327..9cdc85d 100644 --- a/altyo_window.vala +++ b/altyo_window.vala @@ -427,6 +427,12 @@ public class VTMainWindow : Window{ } } + public void gdk_resize(int width,int height){ + var window = this.get_window(); + if(window!=null) + window.resize(width,height); + } + public bool on_pull_down(){ if(this.pull_stepshould_be_h){ - this.resize(this.ayobject.terminal_width,should_be_h); + //this.resize(this.ayobject.terminal_width,should_be_h); + this.gdk_resize(this.ayobject.terminal_width,should_be_h); + this.update_events(); this.move (this.orig_x,this.orig_y); this.wait_for_window_position_update=5;//wait while movement will be confirmed in configure_event debug("WINDOW update_position_size resize!!! %d",should_be_h); From 3164e70902804033f4fa6f5999eb46723609ecc9 Mon Sep 17 00:00:00 2001 From: linvinus Date: Tue, 19 Apr 2016 11:24:47 +0300 Subject: [PATCH 06/19] replace tabs by whitespace --- altyo_config.vala | 1514 +++++----- altyo_hotkey.vala | 300 +- altyo_settings.vala | 2332 +++++++-------- altyo_terminal.vala | 3350 +++++++++++----------- altyo_window.vala | 6640 +++++++++++++++++++++---------------------- hvbox.vala | 1336 ++++----- main.vala | 874 +++--- 7 files changed, 8173 insertions(+), 8173 deletions(-) diff --git a/altyo_config.vala b/altyo_config.vala index eafe26e..0d7b219 100644 --- a/altyo_config.vala +++ b/altyo_config.vala @@ -20,32 +20,32 @@ using Gtk; #if VALA_0_17 #else - /* VALA_0_16 and older - * quirk for Ubuntu precise (12.04) - * bug 675403. - * https://mail.gnome.org/archives/commits-list/2012-June/msg05401.html - */ - [CCode (cname = "gtk_style_context_lookup_color")] - extern bool vala_016_style_context_lookup_color(Gtk.StyleContext context,string color_name,out Gdk.RGBA color); + /* VALA_0_16 and older + * quirk for Ubuntu precise (12.04) + * bug 675403. + * https://mail.gnome.org/archives/commits-list/2012-June/msg05401.html + */ + [CCode (cname = "gtk_style_context_lookup_color")] + extern bool vala_016_style_context_lookup_color(Gtk.StyleContext context,string color_name,out Gdk.RGBA color); #endif public enum CFG_CHECK{ - OK, - REPLACE, - USE_DEFAULT - } + OK, + REPLACE, + USE_DEFAULT + } public enum VER{ - major, - minor, - rc - } + major, + minor, + rc + } public enum DISTRIB_ID{ - UBUNTU, - OTHER - } - + UBUNTU, + OTHER + } + public delegate CFG_CHECK check_string(ref string s); public delegate CFG_CHECK check_string_list(ref string[] sl); public delegate CFG_CHECK check_integer(ref int i); @@ -55,725 +55,725 @@ public delegate CFG_CHECK check_integer_list(ref int[] il); [SimpleType] public enum CFG_TYPE{ - TYPE_UNKNOWN, - TYPE_BOOLEAN, - TYPE_DOUBLE, - TYPE_INTEGER, - TYPE_STRING, - TYPE_STRING_LIST, - TYPE_ACCEL_STRING, - TYPE_INTEGER_LIST, - } + TYPE_UNKNOWN, + TYPE_BOOLEAN, + TYPE_DOUBLE, + TYPE_INTEGER, + TYPE_STRING, + TYPE_STRING_LIST, + TYPE_ACCEL_STRING, + TYPE_INTEGER_LIST, + } public class MySettings : Object { - private KeyFile kf; - public string conf_file; - private string profile {get;set;default = "profile0";} - private string accel_section {get;set;default = "KeyBindings";} - private string qconnection_section {get;set;default = "QConnections";} - public bool opened {get;set; default = false;} - private bool changed {get;set; default = false;} - private HashTable typemap; - public bool disable_hotkey = false; - public bool standalone_mode = false; - public bool readonly = false; - public string? default_path = null; - public DISTRIB_ID DISTR_ID=DISTRIB_ID.OTHER; - public bool reduce_memory_usage = false; - public bool force_debug = false; - - public signal void on_load(); - - public MySettings(string? cmd_conf_file=null,bool? standalone=false ){ - this.typemap = new HashTable (str_hash, str_equal); - if(standalone!=null) - this.standalone_mode=standalone; - - if(cmd_conf_file!=null) - this.conf_file = cmd_conf_file; - else{ - - if(standalone!=null && this.standalone_mode==true) - this.conf_file = GLib.Environment.get_user_config_dir()+"/altyo"+"/config-standalone.ini"; - else - this.conf_file = GLib.Environment.get_user_config_dir()+"/altyo"+"/config.ini"; - } - kf = new KeyFile(); - this.load_config(); - if(this.opened){ - this.set_integer_list("profile_version",this.check_for_migrate(this.get_integer_list("profile_version", {0,0,0}, (ref new_val)=>{ - if(new_val.length != 3){ - new_val = {0,0,0}; - return CFG_CHECK.REPLACE; - } - return CFG_CHECK.OK; - })) ); - /* some options related only for ubuntu, so to run same binary - * try to guess linux distribution on which we are have runned, - * guess only once, then save in config*/ - string distr=this.get_string("distrib_id",""); - if(distr==""){ - distr=this.check_linux_distribution(); - this.set_string("distrib_id",distr); - } - if(distr=="ubuntu") - this.DISTR_ID=DISTRIB_ID.UBUNTU; - - this.reduce_memory_usage = this.get_boolean("reduce_memory_usage",false); - } - } - - public void load_config(){ - debug("loading config..."); - if(!GLib.FileUtils.test(this.conf_file,GLib.FileTest.EXISTS) ) - GLib.DirUtils.create_with_parents(GLib.Path.get_dirname(this.conf_file),502);//755 - - try { - kf.load_from_file(this.conf_file, KeyFileFlags.KEEP_COMMENTS); - this.opened = true; - this.changed=false; - this.on_load(); - } catch (GLib.KeyFileError.PARSE err) { - this.opened = true; - this.changed=false; - this.on_load(); - } catch (KeyFileError err) { - debug("Filed: kf.load_from_file"); - warning (err.message); - this.opened = false; - } catch (FileError err) { - //create default settings - kf.set_string (this.profile, "custom_command", ""); - /* - * other settings will be filled on reation time - */ - var str = kf.to_data (null); - try { - FileUtils.set_contents (this.conf_file, str, str.length); - this.opened = true; - } catch (FileError err) { - warning (err.message); - } - } - } - - public void reload_config(){ - this.on_load(); - } - - public void save(bool force=false){ - if(this.readonly==false){ - if(this.changed || force){ - var str = kf.to_data (null); - try { - debug("\tsave settings into file=%s\n",this.conf_file); - FileUtils.set_contents (this.conf_file, str, str.length); - } catch (FileError err) { - warning (err.message); - } - } - }else - debug("config is read only, all changes will be lost!\n"); - this.changed=false; - } - - public void reset_to_defaults(){ - var tmp=this.conf_file; - this.conf_file+=".bak"; - this.save(true);//save backup - this.conf_file=tmp; - try { - debug("\treset_to_defaults settings file=%s\n",this.conf_file); - FileUtils.set_contents (this.conf_file, "", 0); - this.load_config(); - } catch (FileError err) { - warning (err.message); - } - } - - private int[] check_for_migrate(int[] version){ - - if(version[VER.major]==0 && version[VER.minor]==0){ - version[VER.minor]=3;//update settings to latest version 0.3 - } - - if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<5){ - /*migrate from 0.3 rc4 to rc5 - * move autostart file*/ - string old_default_desktop_file=GLib.Environment.get_user_config_dir()+"/autostart/altyo.desktop"; - string new_default_desktop_file=GLib.Environment.get_user_config_dir()+"/autostart/org.gtk.altyo.desktop"; - - if(GLib.FileUtils.test(old_default_desktop_file,GLib.FileTest.EXISTS) ) - GLib.FileUtils.rename(old_default_desktop_file,new_default_desktop_file); - - version[VER.rc]=5;//update version - } - - if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<6){ - try { - var old=kf.get_boolean(this.profile,"window_hide_after_close_last_tab"); - if(old) - kf.set_integer(this.profile,"window_action_on_close_last_tab",1);//restart shell and hide - kf.remove_key(this.profile,"window_hide_after_close_last_tab"); - this.changed=true; - }catch (KeyFileError err) {} - - version[VER.rc]=6;//update version - } - - /*if was 0.3.6 - * update program_style option, gtk prior 3.8 have memory leak when text-shadow is used. - * */ - if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<7){ - if(Gtk.get_major_version()>=3 && Gtk.get_minor_version()<7){ - try { - string old=kf.get_string(this.profile,"program_style"); - if(old!=null && old!="" ){ - Regex regex = new Regex ("VTToggleButton\\:active \\{ text-shadow\\: 1px 1px 2px #005555\\;\\}"); - try { - string result = regex.replace(old,-1,0,""); - kf.set_string(this.profile,"program_style",result); - this.changed=true; - }catch (RegexError e) { - stdout.printf ("Error: %s\n", e.message); - } - kf.set_integer(this.profile,"window_action_on_close_last_tab",1);//restart shell and hide - } - }catch (KeyFileError err) {} - } - - version[VER.rc]=7;//update version - } - - /*if was 0.3.7 - * update program_style option, fix background for quick_options_notebook - * */ - if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<8){ - try { - string old=kf.get_string(this.profile,"program_style"); - if(old!=null && old!="" ){ - Regex regex = new Regex ("HVBox,#search_hbox\\{"); - try { - string result = regex.replace(old,-1,0,"HVBox,#quick_options_notebook {"); - kf.set_string(this.profile,"program_style",result); - this.changed=true; - }catch (RegexError e) { - stdout.printf ("Error: %s\n", e.message); - } - } - }catch (KeyFileError err) {} - version[VER.rc]=8;//update version - } - /*if was 0.3.8 - * now window position and size is unique for each monitor - * */ - if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<9){ - try { - string monitor=kf.get_string(this.profile,"window_default_monitor"); - if(monitor!=null && monitor!=""){ - kf.set_integer(this.profile,"terminal_width_%s".printf(monitor),kf.get_integer(this.profile,"terminal_width")); - kf.set_integer(this.profile,"terminal_height_%s".printf(monitor),kf.get_integer(this.profile,"terminal_height")); - kf.set_integer(this.profile,"window_position_y_%s".printf(monitor),kf.get_integer(this.profile,"window_position_y")); - kf.set_integer(this.profile,"window_position_x_%s".printf(monitor),kf.get_integer(this.profile,"position")); - } - - kf.remove_key(this.profile,"terminal_height"); - kf.remove_key(this.profile,"terminal_width"); - kf.remove_key(this.profile,"window_position_y"); - kf.remove_key(this.profile,"position"); - }catch (KeyFileError err) {} - - version[VER.rc]=9;//update version - } - /*if was 0.3.9 - * update program_style option, fix background for settings tab - * */ - if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<10){ - try { - string old=kf.get_string(this.profile,"program_style"); - if(old!=null && old!="" ){ - kf.set_string(this.profile,"program_style",old+" #settings-scrolledwindow{ background-color: @bg_color;} "); - } - }catch (KeyFileError err) {} - version[VER.rc]=10;//update version - } - /*if was 0.3.10 - * update program_style option, remove button shadow, disable animation - * */ - if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<11){ - try { - string old=kf.get_string(this.profile,"program_style"); - if(old!=null && old!="" ){ - Regex regex = new Regex ("#tasks_notebook"); - try { - string result = regex.replace(old,-1,0,".window_multitabs"); - old=result; - }catch (RegexError e) { - stdout.printf ("Error: %s\n", e.message); - } - - kf.set_string(this.profile,"program_style",old+" VTToggleButton{ box-shadow: none;"+((Gtk.get_major_version()>=3 && Gtk.get_minor_version()>4)?"transition-duration: 0s;":"")+"} .window_single_tab {border-width: 2px 2px 2px 2px;border-color: #3C3B37;border-style: solid;}"); - } - }catch (KeyFileError err) {} - version[VER.rc]=11;//update version - } - /*if was 0.3.11 - * update program_style option, new theme handling - * */ - if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<12){ - try { - string old=kf.get_string(this.profile,"program_style"); - if(old!=null && old!="" ){ - kf.remove_key(this.profile,"program_style"); - kf.remove_key(this.profile,"tab_title_format"); - kf.remove_key(this.profile,"tab_title_format_regex"); - } - }catch (KeyFileError err) {} - version[VER.rc]=12;//update version - } - return version; - } - - private string check_linux_distribution(){ - string contents; - size_t length; - if( GLib.FileUtils.test("/etc/lsb-release",GLib.FileTest.EXISTS) ){ - try{ - GLib.FileUtils.get_contents("/etc/lsb-release",out contents,out length); - if(length>1 && Regex.match_simple(".*ubuntu.*",contents,GLib.RegexCompileFlags.CASELESS|GLib.RegexCompileFlags.MULTILINE)){ - return "ubuntu"; - } - } catch (FileError err) { - } - }else - if( GLib.FileUtils.test("/etc/issue",GLib.FileTest.EXISTS) ){ - try{ - GLib.FileUtils.get_contents("/etc/issue",out contents,out length); - if(length>1 && Regex.match_simple(".*ubuntu.*",contents,GLib.RegexCompileFlags.CASELESS|GLib.RegexCompileFlags.MULTILINE)){ - return "ubuntu"; - } - } catch (FileError err) { - } - } - return "other"; - } - - public bool get_boolean (string key,bool? def,check_boolean? check_cb=null){ - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,(int)CFG_TYPE.TYPE_BOOLEAN); - else if(key_type!=CFG_TYPE.TYPE_BOOLEAN) - GLib.assert(key_type==CFG_TYPE.TYPE_BOOLEAN); - - bool ret = def; - try { - ret = kf.get_boolean(this.profile,key); - if(check_cb!=null) - switch(check_cb(ref ret)){ - case CFG_CHECK.REPLACE: - this.changed=true; - kf.set_boolean(this.profile,key,ret); - break; - case CFG_CHECK.USE_DEFAULT: - ret=def; - this.changed=true; - kf.set_boolean(this.profile,key,def); - break; - } - } catch (KeyFileError err) { - warning (err.message); - this.changed=true; - kf.set_boolean(this.profile,key,def); - ret = def; - } - return ret; - } - - public int get_integer (string key,int def,check_integer? check_cb=null){ - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,CFG_TYPE.TYPE_INTEGER); - else if(key_type!=CFG_TYPE.TYPE_INTEGER) - GLib.assert(key_type==CFG_TYPE.TYPE_INTEGER); - - int ret = def; - try { - ret = kf.get_integer(this.profile,key); - if(check_cb!=null) - switch(check_cb(ref ret)){ - case CFG_CHECK.REPLACE: - this.changed=true; - kf.set_integer(this.profile,key,ret); - break; - case CFG_CHECK.USE_DEFAULT: - ret=def; - this.changed=true; - kf.set_integer(this.profile,key,def); - break; - } - } catch (KeyFileError err) { - warning (err.message); - this.changed=true; - kf.set_integer(this.profile,key,def); - ret = def; - } - return ret; - } - - public int[] get_integer_list (string key,int[] def,check_integer_list? check_cb=null){ - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,CFG_TYPE.TYPE_INTEGER_LIST); - else if(key_type!=CFG_TYPE.TYPE_INTEGER_LIST) - GLib.assert(key_type==CFG_TYPE.TYPE_INTEGER_LIST); - - int[] ret = def; - try { - ret = kf.get_integer_list(this.profile,key); - if(check_cb!=null) - switch(check_cb(ref ret)){ - case CFG_CHECK.REPLACE: - this.changed=true; - kf.set_integer_list(this.profile,key,ret); - break; - case CFG_CHECK.USE_DEFAULT: - ret=def; - this.changed=true; - kf.set_integer_list(this.profile,key,def); - break; - } - } catch (KeyFileError err) { - warning (err.message); - this.changed=true; - kf.set_integer_list(this.profile,key,def); - ret = def; - } - return ret; - } - - public double get_double (string key,double def,check_double? check_cb=null){ - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,CFG_TYPE.TYPE_DOUBLE); - else if(key_type!=CFG_TYPE.TYPE_DOUBLE) - GLib.assert(key_type==CFG_TYPE.TYPE_DOUBLE); - - double ret = def; - try { - ret = kf.get_double(this.profile,key); - if(check_cb!=null) - switch(check_cb(ref ret)){ - case CFG_CHECK.REPLACE: - this.changed=true; - kf.set_double(this.profile,key,ret); - break; - case CFG_CHECK.USE_DEFAULT: - ret=def; - this.changed=true; - kf.set_double(this.profile,key,def); - break; - } - } catch (KeyFileError err) { - warning (err.message); - this.changed=true; - kf.set_double(this.profile,key,def); - ret = def; - } - return ret; - } - - public string[] get_string_list (string key, string[] def,check_string_list? check_cb=null) { - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,CFG_TYPE.TYPE_STRING_LIST); - else if(key_type!=CFG_TYPE.TYPE_STRING_LIST) - GLib.assert(key_type==CFG_TYPE.TYPE_STRING_LIST); - - string[] ret = def; - try { - ret = kf.get_string_list(this.profile,key); - if(check_cb!=null) - switch(check_cb(ref ret)){ - case CFG_CHECK.REPLACE: - this.changed=true; - kf.set_string_list(this.profile,key,ret); - break; - case CFG_CHECK.USE_DEFAULT: - ret=def; - this.changed=true; - kf.set_string_list(this.profile,key,def); - break; - } - } catch (KeyFileError err) { - warning (err.message); - this.changed=true; - kf.set_string_list(this.profile,key,def); - ret = def; - } - return ret; - } - - public string? get_string(string key, string def,check_string? check_cb=null) { - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,CFG_TYPE.TYPE_STRING); - else if(key_type!=CFG_TYPE.TYPE_STRING) - GLib.assert(key_type==CFG_TYPE.TYPE_STRING); - - string ret = def; - try { - ret = kf.get_string(this.profile,key); - if(check_cb!=null) - switch(check_cb(ref ret)){ - case CFG_CHECK.REPLACE: - this.changed=true; - kf.set_string(this.profile,key,ret); - break; - case CFG_CHECK.USE_DEFAULT: - ret=def; - this.changed=true; - kf.set_string(this.profile,key,def); - break; - } - } catch (KeyFileError err) { - warning (err.message); - this.changed=true; - kf.set_string(this.profile,key,def); - ret = def; - } - return ret;//can be null - } - - - public bool set_string_list (string key, string[] def) { - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,CFG_TYPE.TYPE_STRING_LIST); - else if(key_type!=CFG_TYPE.TYPE_STRING_LIST) - GLib.assert(key_type==CFG_TYPE.TYPE_STRING_LIST); - - bool ret = true; - try { - this.changed=true; - kf.set_string_list(this.profile,key,def); - } catch (KeyFileError err) { - warning (err.message); - ret = false; - } - return ret; - } - - public bool set_string(string key, string? def) { - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,CFG_TYPE.TYPE_STRING); - else if(key_type!=CFG_TYPE.TYPE_STRING) - GLib.assert(key_type==CFG_TYPE.TYPE_STRING); - - bool ret = true; - try { - this.changed=true; - if(def==null) - kf.set_string(this.profile,key,""); - else - kf.set_string(this.profile,key,def); - } catch (KeyFileError err) { - warning (err.message); - ret = false; - } - return ret; - } - - public bool set_integer (string key,int def){ - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,CFG_TYPE.TYPE_INTEGER); - else if(key_type!=CFG_TYPE.TYPE_INTEGER) - GLib.assert(key_type==CFG_TYPE.TYPE_INTEGER); - - bool ret = true; - try { - this.changed=true; - kf.set_integer(this.profile,key,def); - } catch (KeyFileError err) { - warning (err.message); - ret = false; - } - return ret; - } - - public bool set_integer_list (string key,int[] def){ - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,CFG_TYPE.TYPE_INTEGER_LIST); - else if(key_type!=CFG_TYPE.TYPE_INTEGER_LIST) - GLib.assert(key_type==CFG_TYPE.TYPE_INTEGER_LIST); - - bool ret = true; - try { - this.changed=true; - kf.set_integer_list(this.profile,key,def); - } catch (KeyFileError err) { - warning (err.message); - ret = false; - } - return ret; - } - - public bool set_boolean (string key,bool def){ - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,CFG_TYPE.TYPE_BOOLEAN); - else if(key_type!=CFG_TYPE.TYPE_BOOLEAN) - GLib.assert(key_type==CFG_TYPE.TYPE_BOOLEAN); - - bool ret = true; - try { - this.changed=true; - kf.set_boolean(this.profile,key,def); - } catch (KeyFileError err) { - warning (err.message); - ret = false; - } - return ret; - } - - public bool set_double (string key,double def,uint digits_after_comma){ - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,CFG_TYPE.TYPE_DOUBLE); - else if(key_type!=CFG_TYPE.TYPE_DOUBLE) - GLib.assert(key_type==CFG_TYPE.TYPE_DOUBLE); - - bool ret = true; - try { - this.changed=true; - if(digits_after_comma>0){ - string S="%.2f".printf(round_double(def,digits_after_comma)); - //printf string is localized, but KeyFile allow only - //dot as digits delimeter in double, - //so replace comma with dot - //is there better solution? - S=S.replace(",","."); - debug("set_double=%s",S); - kf.set_string(this.profile,key,S); - }else{ - kf.set_double(this.profile,key,def); - } - } catch (KeyFileError err) { - warning (err.message); - ret = false; - } - return ret; - } - - public string get_accel_string(string key, string def,check_string? check_cb=null) { - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,CFG_TYPE.TYPE_ACCEL_STRING); - else if(key_type!=CFG_TYPE.TYPE_ACCEL_STRING) - GLib.assert(key_type==CFG_TYPE.TYPE_ACCEL_STRING); - - string ret = def; - try { - ret = kf.get_string(this.accel_section,key); - } catch (KeyFileError err) { - warning (err.message); - this.changed=true; - kf.set_string(this.accel_section,key,def); - ret = def; - } - return ret; - } - - public bool set_accel_string(string key, string def) { - int key_type; - if(!this.typemap.lookup_extended(key,null,out key_type)) - this.typemap.insert(key,CFG_TYPE.TYPE_ACCEL_STRING); - else if(key_type!=CFG_TYPE.TYPE_ACCEL_STRING) - GLib.assert(key_type==CFG_TYPE.TYPE_ACCEL_STRING); - - bool ret = true; - try { - this.changed=true; - kf.set_string(this.accel_section,key,def); - } catch (KeyFileError err) { - warning (err.message); - ret = false; - } - return ret; - } - - public string[] get_qconnection_list () { - string[] ret = {}; - if(kf.has_group(this.qconnection_section)){ - try { - ret = kf.get_keys(this.qconnection_section); - } catch (KeyFileError err) { - warning (err.message); - this.changed=true; - //if(err.code == GLib.KeyFileError.GROUP_NOT_FOUND) - kf.set_string(this.qconnection_section,null,""); - ret = {}; - } - } - return ret; - } - - public string[] get_qconnection_data_list (string key) { - string[] ret = {}; - try { - ret = kf.get_string_list(this.qconnection_section,key); - } catch (KeyFileError err) { - warning (err.message); - //kf.set_string_list(this.qconnection_section,key,{}); - ret = {}; - } - return ret; - } - - public string[] get_profile_keys (){ - return this.kf.get_keys (this.profile); - } - - public CFG_TYPE get_key_type(string key){ - int key_type; - if(this.typemap.lookup_extended(key,null,out key_type)){ - return (CFG_TYPE)key_type; - }else{ - debug("get_key_type TYPE_UNKNOWN for key=%s",key); - return CFG_TYPE.TYPE_UNKNOWN; - } - } - - public bool check_markup(string pattern,out string err_text){ - bool ret=true; - Pango.AttrList attr_list; - string text; - unichar accel_char; - try { - Pango.parse_markup(pattern,-1,(unichar)"_",out attr_list, out text, out accel_char); - } catch( Error re ) { - ret=false; - debug("check_markup err:%s",re.message); - err_text=re.message; - } - return ret; - } - - public bool check_regex(string pattern,out string err_text){ - bool ret=true; - try { - var regex = new Regex( pattern, RegexCompileFlags.EXTENDED ); - } catch( RegexError re ) { - ret=false; - debug("check_regex err:%s",re.message); - err_text=re.message; - } - return ret; - } -/* todo + private KeyFile kf; + public string conf_file; + private string profile {get;set;default = "profile0";} + private string accel_section {get;set;default = "KeyBindings";} + private string qconnection_section {get;set;default = "QConnections";} + public bool opened {get;set; default = false;} + private bool changed {get;set; default = false;} + private HashTable typemap; + public bool disable_hotkey = false; + public bool standalone_mode = false; + public bool readonly = false; + public string? default_path = null; + public DISTRIB_ID DISTR_ID=DISTRIB_ID.OTHER; + public bool reduce_memory_usage = false; + public bool force_debug = false; + + public signal void on_load(); + + public MySettings(string? cmd_conf_file=null,bool? standalone=false ){ + this.typemap = new HashTable (str_hash, str_equal); + if(standalone!=null) + this.standalone_mode=standalone; + + if(cmd_conf_file!=null) + this.conf_file = cmd_conf_file; + else{ + + if(standalone!=null && this.standalone_mode==true) + this.conf_file = GLib.Environment.get_user_config_dir()+"/altyo"+"/config-standalone.ini"; + else + this.conf_file = GLib.Environment.get_user_config_dir()+"/altyo"+"/config.ini"; + } + kf = new KeyFile(); + this.load_config(); + if(this.opened){ + this.set_integer_list("profile_version",this.check_for_migrate(this.get_integer_list("profile_version", {0,0,0}, (ref new_val)=>{ + if(new_val.length != 3){ + new_val = {0,0,0}; + return CFG_CHECK.REPLACE; + } + return CFG_CHECK.OK; + })) ); + /* some options related only for ubuntu, so to run same binary + * try to guess linux distribution on which we are have runned, + * guess only once, then save in config*/ + string distr=this.get_string("distrib_id",""); + if(distr==""){ + distr=this.check_linux_distribution(); + this.set_string("distrib_id",distr); + } + if(distr=="ubuntu") + this.DISTR_ID=DISTRIB_ID.UBUNTU; + + this.reduce_memory_usage = this.get_boolean("reduce_memory_usage",false); + } + } + + public void load_config(){ + debug("loading config..."); + if(!GLib.FileUtils.test(this.conf_file,GLib.FileTest.EXISTS) ) + GLib.DirUtils.create_with_parents(GLib.Path.get_dirname(this.conf_file),502);//755 + + try { + kf.load_from_file(this.conf_file, KeyFileFlags.KEEP_COMMENTS); + this.opened = true; + this.changed=false; + this.on_load(); + } catch (GLib.KeyFileError.PARSE err) { + this.opened = true; + this.changed=false; + this.on_load(); + } catch (KeyFileError err) { + debug("Filed: kf.load_from_file"); + warning (err.message); + this.opened = false; + } catch (FileError err) { + //create default settings + kf.set_string (this.profile, "custom_command", ""); + /* + * other settings will be filled on reation time + */ + var str = kf.to_data (null); + try { + FileUtils.set_contents (this.conf_file, str, str.length); + this.opened = true; + } catch (FileError err) { + warning (err.message); + } + } + } + + public void reload_config(){ + this.on_load(); + } + + public void save(bool force=false){ + if(this.readonly==false){ + if(this.changed || force){ + var str = kf.to_data (null); + try { + debug("\tsave settings into file=%s\n",this.conf_file); + FileUtils.set_contents (this.conf_file, str, str.length); + } catch (FileError err) { + warning (err.message); + } + } + }else + debug("config is read only, all changes will be lost!\n"); + this.changed=false; + } + + public void reset_to_defaults(){ + var tmp=this.conf_file; + this.conf_file+=".bak"; + this.save(true);//save backup + this.conf_file=tmp; + try { + debug("\treset_to_defaults settings file=%s\n",this.conf_file); + FileUtils.set_contents (this.conf_file, "", 0); + this.load_config(); + } catch (FileError err) { + warning (err.message); + } + } + + private int[] check_for_migrate(int[] version){ + + if(version[VER.major]==0 && version[VER.minor]==0){ + version[VER.minor]=3;//update settings to latest version 0.3 + } + + if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<5){ + /*migrate from 0.3 rc4 to rc5 + * move autostart file*/ + string old_default_desktop_file=GLib.Environment.get_user_config_dir()+"/autostart/altyo.desktop"; + string new_default_desktop_file=GLib.Environment.get_user_config_dir()+"/autostart/org.gtk.altyo.desktop"; + + if(GLib.FileUtils.test(old_default_desktop_file,GLib.FileTest.EXISTS) ) + GLib.FileUtils.rename(old_default_desktop_file,new_default_desktop_file); + + version[VER.rc]=5;//update version + } + + if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<6){ + try { + var old=kf.get_boolean(this.profile,"window_hide_after_close_last_tab"); + if(old) + kf.set_integer(this.profile,"window_action_on_close_last_tab",1);//restart shell and hide + kf.remove_key(this.profile,"window_hide_after_close_last_tab"); + this.changed=true; + }catch (KeyFileError err) {} + + version[VER.rc]=6;//update version + } + + /*if was 0.3.6 + * update program_style option, gtk prior 3.8 have memory leak when text-shadow is used. + * */ + if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<7){ + if(Gtk.get_major_version()>=3 && Gtk.get_minor_version()<7){ + try { + string old=kf.get_string(this.profile,"program_style"); + if(old!=null && old!="" ){ + Regex regex = new Regex ("VTToggleButton\\:active \\{ text-shadow\\: 1px 1px 2px #005555\\;\\}"); + try { + string result = regex.replace(old,-1,0,""); + kf.set_string(this.profile,"program_style",result); + this.changed=true; + }catch (RegexError e) { + stdout.printf ("Error: %s\n", e.message); + } + kf.set_integer(this.profile,"window_action_on_close_last_tab",1);//restart shell and hide + } + }catch (KeyFileError err) {} + } + + version[VER.rc]=7;//update version + } + + /*if was 0.3.7 + * update program_style option, fix background for quick_options_notebook + * */ + if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<8){ + try { + string old=kf.get_string(this.profile,"program_style"); + if(old!=null && old!="" ){ + Regex regex = new Regex ("HVBox,#search_hbox\\{"); + try { + string result = regex.replace(old,-1,0,"HVBox,#quick_options_notebook {"); + kf.set_string(this.profile,"program_style",result); + this.changed=true; + }catch (RegexError e) { + stdout.printf ("Error: %s\n", e.message); + } + } + }catch (KeyFileError err) {} + version[VER.rc]=8;//update version + } + /*if was 0.3.8 + * now window position and size is unique for each monitor + * */ + if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<9){ + try { + string monitor=kf.get_string(this.profile,"window_default_monitor"); + if(monitor!=null && monitor!=""){ + kf.set_integer(this.profile,"terminal_width_%s".printf(monitor),kf.get_integer(this.profile,"terminal_width")); + kf.set_integer(this.profile,"terminal_height_%s".printf(monitor),kf.get_integer(this.profile,"terminal_height")); + kf.set_integer(this.profile,"window_position_y_%s".printf(monitor),kf.get_integer(this.profile,"window_position_y")); + kf.set_integer(this.profile,"window_position_x_%s".printf(monitor),kf.get_integer(this.profile,"position")); + } + + kf.remove_key(this.profile,"terminal_height"); + kf.remove_key(this.profile,"terminal_width"); + kf.remove_key(this.profile,"window_position_y"); + kf.remove_key(this.profile,"position"); + }catch (KeyFileError err) {} + + version[VER.rc]=9;//update version + } + /*if was 0.3.9 + * update program_style option, fix background for settings tab + * */ + if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<10){ + try { + string old=kf.get_string(this.profile,"program_style"); + if(old!=null && old!="" ){ + kf.set_string(this.profile,"program_style",old+" #settings-scrolledwindow{ background-color: @bg_color;} "); + } + }catch (KeyFileError err) {} + version[VER.rc]=10;//update version + } + /*if was 0.3.10 + * update program_style option, remove button shadow, disable animation + * */ + if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<11){ + try { + string old=kf.get_string(this.profile,"program_style"); + if(old!=null && old!="" ){ + Regex regex = new Regex ("#tasks_notebook"); + try { + string result = regex.replace(old,-1,0,".window_multitabs"); + old=result; + }catch (RegexError e) { + stdout.printf ("Error: %s\n", e.message); + } + + kf.set_string(this.profile,"program_style",old+" VTToggleButton{ box-shadow: none;"+((Gtk.get_major_version()>=3 && Gtk.get_minor_version()>4)?"transition-duration: 0s;":"")+"} .window_single_tab {border-width: 2px 2px 2px 2px;border-color: #3C3B37;border-style: solid;}"); + } + }catch (KeyFileError err) {} + version[VER.rc]=11;//update version + } + /*if was 0.3.11 + * update program_style option, new theme handling + * */ + if(version[VER.major]==0 && version[VER.minor]==3 && version[VER.rc]<12){ + try { + string old=kf.get_string(this.profile,"program_style"); + if(old!=null && old!="" ){ + kf.remove_key(this.profile,"program_style"); + kf.remove_key(this.profile,"tab_title_format"); + kf.remove_key(this.profile,"tab_title_format_regex"); + } + }catch (KeyFileError err) {} + version[VER.rc]=12;//update version + } + return version; + } + + private string check_linux_distribution(){ + string contents; + size_t length; + if( GLib.FileUtils.test("/etc/lsb-release",GLib.FileTest.EXISTS) ){ + try{ + GLib.FileUtils.get_contents("/etc/lsb-release",out contents,out length); + if(length>1 && Regex.match_simple(".*ubuntu.*",contents,GLib.RegexCompileFlags.CASELESS|GLib.RegexCompileFlags.MULTILINE)){ + return "ubuntu"; + } + } catch (FileError err) { + } + }else + if( GLib.FileUtils.test("/etc/issue",GLib.FileTest.EXISTS) ){ + try{ + GLib.FileUtils.get_contents("/etc/issue",out contents,out length); + if(length>1 && Regex.match_simple(".*ubuntu.*",contents,GLib.RegexCompileFlags.CASELESS|GLib.RegexCompileFlags.MULTILINE)){ + return "ubuntu"; + } + } catch (FileError err) { + } + } + return "other"; + } + + public bool get_boolean (string key,bool? def,check_boolean? check_cb=null){ + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,(int)CFG_TYPE.TYPE_BOOLEAN); + else if(key_type!=CFG_TYPE.TYPE_BOOLEAN) + GLib.assert(key_type==CFG_TYPE.TYPE_BOOLEAN); + + bool ret = def; + try { + ret = kf.get_boolean(this.profile,key); + if(check_cb!=null) + switch(check_cb(ref ret)){ + case CFG_CHECK.REPLACE: + this.changed=true; + kf.set_boolean(this.profile,key,ret); + break; + case CFG_CHECK.USE_DEFAULT: + ret=def; + this.changed=true; + kf.set_boolean(this.profile,key,def); + break; + } + } catch (KeyFileError err) { + warning (err.message); + this.changed=true; + kf.set_boolean(this.profile,key,def); + ret = def; + } + return ret; + } + + public int get_integer (string key,int def,check_integer? check_cb=null){ + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,CFG_TYPE.TYPE_INTEGER); + else if(key_type!=CFG_TYPE.TYPE_INTEGER) + GLib.assert(key_type==CFG_TYPE.TYPE_INTEGER); + + int ret = def; + try { + ret = kf.get_integer(this.profile,key); + if(check_cb!=null) + switch(check_cb(ref ret)){ + case CFG_CHECK.REPLACE: + this.changed=true; + kf.set_integer(this.profile,key,ret); + break; + case CFG_CHECK.USE_DEFAULT: + ret=def; + this.changed=true; + kf.set_integer(this.profile,key,def); + break; + } + } catch (KeyFileError err) { + warning (err.message); + this.changed=true; + kf.set_integer(this.profile,key,def); + ret = def; + } + return ret; + } + + public int[] get_integer_list (string key,int[] def,check_integer_list? check_cb=null){ + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,CFG_TYPE.TYPE_INTEGER_LIST); + else if(key_type!=CFG_TYPE.TYPE_INTEGER_LIST) + GLib.assert(key_type==CFG_TYPE.TYPE_INTEGER_LIST); + + int[] ret = def; + try { + ret = kf.get_integer_list(this.profile,key); + if(check_cb!=null) + switch(check_cb(ref ret)){ + case CFG_CHECK.REPLACE: + this.changed=true; + kf.set_integer_list(this.profile,key,ret); + break; + case CFG_CHECK.USE_DEFAULT: + ret=def; + this.changed=true; + kf.set_integer_list(this.profile,key,def); + break; + } + } catch (KeyFileError err) { + warning (err.message); + this.changed=true; + kf.set_integer_list(this.profile,key,def); + ret = def; + } + return ret; + } + + public double get_double (string key,double def,check_double? check_cb=null){ + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,CFG_TYPE.TYPE_DOUBLE); + else if(key_type!=CFG_TYPE.TYPE_DOUBLE) + GLib.assert(key_type==CFG_TYPE.TYPE_DOUBLE); + + double ret = def; + try { + ret = kf.get_double(this.profile,key); + if(check_cb!=null) + switch(check_cb(ref ret)){ + case CFG_CHECK.REPLACE: + this.changed=true; + kf.set_double(this.profile,key,ret); + break; + case CFG_CHECK.USE_DEFAULT: + ret=def; + this.changed=true; + kf.set_double(this.profile,key,def); + break; + } + } catch (KeyFileError err) { + warning (err.message); + this.changed=true; + kf.set_double(this.profile,key,def); + ret = def; + } + return ret; + } + + public string[] get_string_list (string key, string[] def,check_string_list? check_cb=null) { + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,CFG_TYPE.TYPE_STRING_LIST); + else if(key_type!=CFG_TYPE.TYPE_STRING_LIST) + GLib.assert(key_type==CFG_TYPE.TYPE_STRING_LIST); + + string[] ret = def; + try { + ret = kf.get_string_list(this.profile,key); + if(check_cb!=null) + switch(check_cb(ref ret)){ + case CFG_CHECK.REPLACE: + this.changed=true; + kf.set_string_list(this.profile,key,ret); + break; + case CFG_CHECK.USE_DEFAULT: + ret=def; + this.changed=true; + kf.set_string_list(this.profile,key,def); + break; + } + } catch (KeyFileError err) { + warning (err.message); + this.changed=true; + kf.set_string_list(this.profile,key,def); + ret = def; + } + return ret; + } + + public string? get_string(string key, string def,check_string? check_cb=null) { + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,CFG_TYPE.TYPE_STRING); + else if(key_type!=CFG_TYPE.TYPE_STRING) + GLib.assert(key_type==CFG_TYPE.TYPE_STRING); + + string ret = def; + try { + ret = kf.get_string(this.profile,key); + if(check_cb!=null) + switch(check_cb(ref ret)){ + case CFG_CHECK.REPLACE: + this.changed=true; + kf.set_string(this.profile,key,ret); + break; + case CFG_CHECK.USE_DEFAULT: + ret=def; + this.changed=true; + kf.set_string(this.profile,key,def); + break; + } + } catch (KeyFileError err) { + warning (err.message); + this.changed=true; + kf.set_string(this.profile,key,def); + ret = def; + } + return ret;//can be null + } + + + public bool set_string_list (string key, string[] def) { + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,CFG_TYPE.TYPE_STRING_LIST); + else if(key_type!=CFG_TYPE.TYPE_STRING_LIST) + GLib.assert(key_type==CFG_TYPE.TYPE_STRING_LIST); + + bool ret = true; + try { + this.changed=true; + kf.set_string_list(this.profile,key,def); + } catch (KeyFileError err) { + warning (err.message); + ret = false; + } + return ret; + } + + public bool set_string(string key, string? def) { + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,CFG_TYPE.TYPE_STRING); + else if(key_type!=CFG_TYPE.TYPE_STRING) + GLib.assert(key_type==CFG_TYPE.TYPE_STRING); + + bool ret = true; + try { + this.changed=true; + if(def==null) + kf.set_string(this.profile,key,""); + else + kf.set_string(this.profile,key,def); + } catch (KeyFileError err) { + warning (err.message); + ret = false; + } + return ret; + } + + public bool set_integer (string key,int def){ + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,CFG_TYPE.TYPE_INTEGER); + else if(key_type!=CFG_TYPE.TYPE_INTEGER) + GLib.assert(key_type==CFG_TYPE.TYPE_INTEGER); + + bool ret = true; + try { + this.changed=true; + kf.set_integer(this.profile,key,def); + } catch (KeyFileError err) { + warning (err.message); + ret = false; + } + return ret; + } + + public bool set_integer_list (string key,int[] def){ + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,CFG_TYPE.TYPE_INTEGER_LIST); + else if(key_type!=CFG_TYPE.TYPE_INTEGER_LIST) + GLib.assert(key_type==CFG_TYPE.TYPE_INTEGER_LIST); + + bool ret = true; + try { + this.changed=true; + kf.set_integer_list(this.profile,key,def); + } catch (KeyFileError err) { + warning (err.message); + ret = false; + } + return ret; + } + + public bool set_boolean (string key,bool def){ + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,CFG_TYPE.TYPE_BOOLEAN); + else if(key_type!=CFG_TYPE.TYPE_BOOLEAN) + GLib.assert(key_type==CFG_TYPE.TYPE_BOOLEAN); + + bool ret = true; + try { + this.changed=true; + kf.set_boolean(this.profile,key,def); + } catch (KeyFileError err) { + warning (err.message); + ret = false; + } + return ret; + } + + public bool set_double (string key,double def,uint digits_after_comma){ + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,CFG_TYPE.TYPE_DOUBLE); + else if(key_type!=CFG_TYPE.TYPE_DOUBLE) + GLib.assert(key_type==CFG_TYPE.TYPE_DOUBLE); + + bool ret = true; + try { + this.changed=true; + if(digits_after_comma>0){ + string S="%.2f".printf(round_double(def,digits_after_comma)); + //printf string is localized, but KeyFile allow only + //dot as digits delimeter in double, + //so replace comma with dot + //is there better solution? + S=S.replace(",","."); + debug("set_double=%s",S); + kf.set_string(this.profile,key,S); + }else{ + kf.set_double(this.profile,key,def); + } + } catch (KeyFileError err) { + warning (err.message); + ret = false; + } + return ret; + } + + public string get_accel_string(string key, string def,check_string? check_cb=null) { + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,CFG_TYPE.TYPE_ACCEL_STRING); + else if(key_type!=CFG_TYPE.TYPE_ACCEL_STRING) + GLib.assert(key_type==CFG_TYPE.TYPE_ACCEL_STRING); + + string ret = def; + try { + ret = kf.get_string(this.accel_section,key); + } catch (KeyFileError err) { + warning (err.message); + this.changed=true; + kf.set_string(this.accel_section,key,def); + ret = def; + } + return ret; + } + + public bool set_accel_string(string key, string def) { + int key_type; + if(!this.typemap.lookup_extended(key,null,out key_type)) + this.typemap.insert(key,CFG_TYPE.TYPE_ACCEL_STRING); + else if(key_type!=CFG_TYPE.TYPE_ACCEL_STRING) + GLib.assert(key_type==CFG_TYPE.TYPE_ACCEL_STRING); + + bool ret = true; + try { + this.changed=true; + kf.set_string(this.accel_section,key,def); + } catch (KeyFileError err) { + warning (err.message); + ret = false; + } + return ret; + } + + public string[] get_qconnection_list () { + string[] ret = {}; + if(kf.has_group(this.qconnection_section)){ + try { + ret = kf.get_keys(this.qconnection_section); + } catch (KeyFileError err) { + warning (err.message); + this.changed=true; + //if(err.code == GLib.KeyFileError.GROUP_NOT_FOUND) + kf.set_string(this.qconnection_section,null,""); + ret = {}; + } + } + return ret; + } + + public string[] get_qconnection_data_list (string key) { + string[] ret = {}; + try { + ret = kf.get_string_list(this.qconnection_section,key); + } catch (KeyFileError err) { + warning (err.message); + //kf.set_string_list(this.qconnection_section,key,{}); + ret = {}; + } + return ret; + } + + public string[] get_profile_keys (){ + return this.kf.get_keys (this.profile); + } + + public CFG_TYPE get_key_type(string key){ + int key_type; + if(this.typemap.lookup_extended(key,null,out key_type)){ + return (CFG_TYPE)key_type; + }else{ + debug("get_key_type TYPE_UNKNOWN for key=%s",key); + return CFG_TYPE.TYPE_UNKNOWN; + } + } + + public bool check_markup(string pattern,out string err_text){ + bool ret=true; + Pango.AttrList attr_list; + string text; + unichar accel_char; + try { + Pango.parse_markup(pattern,-1,(unichar)"_",out attr_list, out text, out accel_char); + } catch( Error re ) { + ret=false; + debug("check_markup err:%s",re.message); + err_text=re.message; + } + return ret; + } + + public bool check_regex(string pattern,out string err_text){ + bool ret=true; + try { + var regex = new Regex( pattern, RegexCompileFlags.EXTENDED ); + } catch( RegexError re ) { + ret=false; + debug("check_regex err:%s",re.message); + err_text=re.message; + } + return ret; + } +/* todo public get_boolean_list public get_comment public get_double @@ -824,14 +824,14 @@ public string hexRGBA(Gdk.RGBA c){ } public double round_double(double def,uint digits_after_comma){ - uint round=1; - double rest=5.0; - while(digits_after_comma-->0){ - round*=10; - } - rest/=(round*10); - int i=(int)((def+rest) * round);//round - def=(double)((double)(i)/(double)round); + uint round=1; + double rest=5.0; + while(digits_after_comma-->0){ + round*=10; + } + rest/=(round*10); + int i=(int)((def+rest) * round);//round + def=(double)((double)(i)/(double)round); return def; } @@ -860,22 +860,22 @@ public string replace_color_in_markup(Widget w,string markup,StateFlags state=Gt //context.get_style_property(name,val); gtk_style_context_get_style_property(context,name,ref val); if(val.get_boxed()!=null) - color=*(Gdk.RGBA*)val.get_boxed(); + color=*(Gdk.RGBA*)val.get_boxed(); context.set_state(old); //~ w.style_get(name,out tmp); //~ color=tmp; //~ tmp.free(); } - #if VALA_0_17 - if(color!=null || w.get_style_context().lookup_color(name,out color) ){ - #else - if(color!=null || vala_016_style_context_lookup_color(w.get_style_context(),name,out color) ){ - #endif + #if VALA_0_17 + if(color!=null || w.get_style_context().lookup_color(name,out color) ){ + #else + if(color!=null || vala_016_style_context_lookup_color(w.get_style_context(),name,out color) ){ + #endif result.append("foreground='"); result.append(hexRGBA(color)); result.append("'"); }else - debug("markup: wrong color '%s', foreground will be ignored",name); + debug("markup: wrong color '%s', foreground will be ignored",name); }else result.append(match_info.fetch(0)); }else{ @@ -894,22 +894,22 @@ public string replace_color_in_markup(Widget w,string markup,StateFlags state=Gt //context.get_style_property(name,val); gtk_style_context_get_style_property(context,name,ref val); if(val.get_boxed()!=null) - color=*(Gdk.RGBA*)val.get_boxed(); + color=*(Gdk.RGBA*)val.get_boxed(); context.set_state(old); //~ w.style_get(name,out color); //~ color=tmp; //~ tmp.free(); } - #if VALA_0_17 - if(color!=null || w.get_style_context().lookup_color(name,out color) ){ - #else - if(color!=null || vala_016_style_context_lookup_color(w.get_style_context(),name,out color) ){ - #endif + #if VALA_0_17 + if(color!=null || w.get_style_context().lookup_color(name,out color) ){ + #else + if(color!=null || vala_016_style_context_lookup_color(w.get_style_context(),name,out color) ){ + #endif result.append("background='"); result.append(hexRGBA(color)); result.append("'"); }else - debug("markup: wrong color '%s', background will be ignored",name); + debug("markup: wrong color '%s', background will be ignored",name); }else result.append(match_info.fetch(0)); }else diff --git a/altyo_hotkey.vala b/altyo_hotkey.vala index 701919e..5d1ce5a 100644 --- a/altyo_hotkey.vala +++ b/altyo_hotkey.vala @@ -25,22 +25,22 @@ using Gdk; }*/ public class KeyBinding : Object { - public string combination; - public uint key_code; - public uint modifiers; - public bool relesed {get;set;default=true;} - public signal void on_trigged(); - - public KeyBinding (string combination, uint key_code, uint modifiers) { - this.combination = combination; - this.key_code = key_code; - this.modifiers = modifiers; - } - - ~KeyBinding(){ - debug("~KeyBinding"); - //free(this.combination); - } + public string combination; + public uint key_code; + public uint modifiers; + public bool relesed {get;set;default=true;} + public signal void on_trigged(); + + public KeyBinding (string combination, uint key_code, uint modifiers) { + this.combination = combination; + this.key_code = key_code; + this.modifiers = modifiers; + } + + ~KeyBinding(){ + debug("~KeyBinding"); + //free(this.combination); + } } public class PanelHotkey : Object { @@ -53,7 +53,7 @@ public class PanelHotkey : Object { private X.Atom active_window; private bool processing_event = false; public signal void on_active_window_change(); - + private static uint[] lock_modifiers = { 0, Gdk.ModifierType.MOD2_MASK, // NUM_LOCK @@ -79,100 +79,100 @@ public class PanelHotkey : Object { } ~PanelHotkey () { - debug("~PanelHotkey ()"); - this.unbind(); - var root_window = Gdk.get_default_root_window (); - root_window.remove_filter(event_filter); - } + debug("~PanelHotkey ()"); + this.unbind(); + var root_window = Gdk.get_default_root_window (); + root_window.remove_filter(event_filter); + } public Gdk.FilterReturn event_filter (Gdk.XEvent gxevent, Gdk.Event event) { FilterReturn filter = FilterReturn.CONTINUE; - this.processing_event = true; - void* p = gxevent; - X.Event* xevent = (X.Event*) p; - this.last_key_event_time = (uint32)xevent->xkey.time; - - if (xevent->type == X.EventType.KeyPress) { - foreach (var binding in bindings) { - if (binding.relesed == true && xevent->xkey.keycode == binding.key_code && - (xevent->xkey.state & ~ (lock_modifiers[7])) == binding.modifiers) { - binding.relesed=false; - binding.on_trigged(); - } - } - }else if (xevent->type == X.EventType.KeyRelease ){ - foreach (var binding in bindings) { - if (xevent->xkey.keycode == binding.key_code && - (xevent->xkey.state & ~ (lock_modifiers[7])) == binding.modifiers) { - binding.relesed=true;//to ignore AutoRepeat - } - } - } else if (xevent->type == X.EventType.PropertyNotify ) { - X.PropertyEvent* pevent = (X.PropertyEvent*) p; - if(pevent->atom == this.active_window){//_NET_ACTIVE_WINDOW usual come after focus change - this.last_property_event_time=(uint32)pevent->time; - this.on_active_window_change(); - } - //debug("event_filter type=%d state=%d window=%d atom=%s",(int)pevent->type,(int)pevent->state,(int)pevent->window,this.display.get_atom_name(pevent->atom)); - } + this.processing_event = true; + void* p = gxevent; + X.Event* xevent = (X.Event*) p; + this.last_key_event_time = (uint32)xevent->xkey.time; + + if (xevent->type == X.EventType.KeyPress) { + foreach (var binding in bindings) { + if (binding.relesed == true && xevent->xkey.keycode == binding.key_code && + (xevent->xkey.state & ~ (lock_modifiers[7])) == binding.modifiers) { + binding.relesed=false; + binding.on_trigged(); + } + } + }else if (xevent->type == X.EventType.KeyRelease ){ + foreach (var binding in bindings) { + if (xevent->xkey.keycode == binding.key_code && + (xevent->xkey.state & ~ (lock_modifiers[7])) == binding.modifiers) { + binding.relesed=true;//to ignore AutoRepeat + } + } + } else if (xevent->type == X.EventType.PropertyNotify ) { + X.PropertyEvent* pevent = (X.PropertyEvent*) p; + if(pevent->atom == this.active_window){//_NET_ACTIVE_WINDOW usual come after focus change + this.last_property_event_time=(uint32)pevent->time; + this.on_active_window_change(); + } + //debug("event_filter type=%d state=%d window=%d atom=%s",(int)pevent->type,(int)pevent->state,(int)pevent->window,this.display.get_atom_name(pevent->atom)); + } this.processing_event = false; return filter; } public KeyBinding bind (string combination) { - bool error = false; + bool error = false; uint key_sym; ModifierType modifiers; if(this.display==null){ - debug("error: KeyBinding display==null"); - return null; - } + debug("error: KeyBinding display==null"); + return null; + } accelerator_parse (combination, out key_sym, out modifiers); - debug("bind %s display=%d key_sym=%d modifiers=%d",combination,(int)display,(int)key_sym,modifiers); - if(key_sym != 0 && (combination.contains(">") == (modifiers!=0?true:false) ) ){ - var key_code = display.keysym_to_keycode ((ulong)key_sym); - - if (key_code != 0) { - - - foreach (var mod in lock_modifiers){ - error_trap_push (); - this.display.grab_key (key_code, modifiers | mod, x_id, false, X.GrabMode.Async, X.GrabMode.Async); - flush(); - if (error_trap_pop()>0) { - this.display.ungrab_key (key_code, modifiers | mod, x_id); - error=true; - } - } - if(!error){ - var binding = new KeyBinding (combination, key_code, modifiers); - if(bindings.first()!=null) - bindings.append(binding); - else - bindings.prepend(binding); - return binding; - } - } - } + debug("bind %s display=%d key_sym=%d modifiers=%d",combination,(int)display,(int)key_sym,modifiers); + if(key_sym != 0 && (combination.contains(">") == (modifiers!=0?true:false) ) ){ + var key_code = display.keysym_to_keycode ((ulong)key_sym); + + if (key_code != 0) { + + + foreach (var mod in lock_modifiers){ + error_trap_push (); + this.display.grab_key (key_code, modifiers | mod, x_id, false, X.GrabMode.Async, X.GrabMode.Async); + flush(); + if (error_trap_pop()>0) { + this.display.ungrab_key (key_code, modifiers | mod, x_id); + error=true; + } + } + if(!error){ + var binding = new KeyBinding (combination, key_code, modifiers); + if(bindings.first()!=null) + bindings.append(binding); + else + bindings.prepend(binding); + return binding; + } + } + } debug ("Binding '%s' failed!\n", combination); return null; } public void unbind(){ - foreach(unowned KeyBinding bind in bindings){ - foreach (var mod in lock_modifiers){ - this.display.ungrab_key ((int)bind.key_code, bind.modifiers | mod, x_id); - flush(); - } - bindings.remove(bind); - bind.unref();//destroy - } - } - -/* comment from tilda source, key_grabber.c + foreach(unowned KeyBinding bind in bindings){ + foreach (var mod in lock_modifiers){ + this.display.ungrab_key ((int)bind.key_code, bind.modifiers | mod, x_id); + flush(); + } + bindings.remove(bind); + bind.unref();//destroy + } + } + +/* comment from tilda source, key_grabber.c * Shamelessly adapted (read: ripped off) from gdk_window_focus() and * http://code.google.com/p/ttm/ trunk/src/window.c set_active() * @@ -181,64 +181,64 @@ public class PanelHotkey : Object { * * Thank you. And boo to metacity, because they keep breaking us. */ - public void send_net_active_window(Gdk.Window window){ - - if(window==null) - return; - - var t = Gdk.x11_get_server_time(window); - window.focus(t); - -//~ var event = X.ClientMessageEvent (); -//~ event.type = X.EventType.ClientMessage; -//~ event.serial = 0; -//~ event.send_event = true; -//~ event.display = Gdk.x11_get_default_xdisplay (); //this.display; -//~ event.window = Gdk.X11Window.get_xid(window);//send altyo window id -//~ event.message_type = x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW"); -//~ event.format = 32; -//~ event.data.l [0] = 2; -//~ event.data.l [1] = Gtk.get_current_event_time();//(this.processing_event == true ? this.last_event_time : Gdk.CURRENT_TIME); -//~ event.data.l [2] = 0; -//~ event.data.l [3] = 0; -//~ event.data.l [4] = 0; -//~ X.Event e = (X.Event) event; + public void send_net_active_window(Gdk.Window window){ + + if(window==null) + return; + + var t = Gdk.x11_get_server_time(window); + window.focus(t); + +//~ var event = X.ClientMessageEvent (); +//~ event.type = X.EventType.ClientMessage; +//~ event.serial = 0; +//~ event.send_event = true; +//~ event.display = Gdk.x11_get_default_xdisplay (); //this.display; +//~ event.window = Gdk.X11Window.get_xid(window);//send altyo window id +//~ event.message_type = x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW"); +//~ event.format = 32; +//~ event.data.l [0] = 2; +//~ event.data.l [1] = Gtk.get_current_event_time();//(this.processing_event == true ? this.last_event_time : Gdk.CURRENT_TIME); +//~ event.data.l [2] = 0; +//~ event.data.l [3] = 0; +//~ event.data.l [4] = 0; +//~ X.Event e = (X.Event) event; //~ -//~ display.send_event (Gdk.x11_get_default_root_xwindow(), false, X.EventMask.SubstructureRedirectMask|X.EventMask.StructureNotifyMask, ref e); - - } - public X.Window get_input_focus(){ - int revert_to_return; - X.Window w,root_return; - X.Window root_xwin=Gdk.X11Window.get_xid(this.root_window); - - this.display.get_input_focus(out w, out revert_to_return); - //debug("get_input_focus=%x revert_to_return=%d",(int)w,revert_to_return); - if(w>1){//not None, not PointerRoot, see XGetInputFocus - do{ - X.Window parent_return; - X.Window[] children_return; - X.Atom[] protocols=null; - this.display.query_tree (w, out root_return, out parent_return, out children_return); - //debug("get_input_focus=%x",(int)parent_return); - - if(parent_return>1){ - this.display.get_wm_protocols(parent_return,out protocols); - if(parent_return != root_xwin && protocols != null) - w=parent_return; - else - break; - }else - break; - }while(true); - } - return w; - } - - public X.Window get_transient_for_xid(X.Window w){ - X.Window result; - this.display.get_transient_for_hint(w,out result); - return result; - } - +//~ display.send_event (Gdk.x11_get_default_root_xwindow(), false, X.EventMask.SubstructureRedirectMask|X.EventMask.StructureNotifyMask, ref e); + + } + public X.Window get_input_focus(){ + int revert_to_return; + X.Window w,root_return; + X.Window root_xwin=Gdk.X11Window.get_xid(this.root_window); + + this.display.get_input_focus(out w, out revert_to_return); + //debug("get_input_focus=%x revert_to_return=%d",(int)w,revert_to_return); + if(w>1){//not None, not PointerRoot, see XGetInputFocus + do{ + X.Window parent_return; + X.Window[] children_return; + X.Atom[] protocols=null; + this.display.query_tree (w, out root_return, out parent_return, out children_return); + //debug("get_input_focus=%x",(int)parent_return); + + if(parent_return>1){ + this.display.get_wm_protocols(parent_return,out protocols); + if(parent_return != root_xwin && protocols != null) + w=parent_return; + else + break; + }else + break; + }while(true); + } + return w; + } + + public X.Window get_transient_for_xid(X.Window w){ + X.Window result; + this.display.get_transient_for_hint(w,out result); + return result; + } + } diff --git a/altyo_settings.vala b/altyo_settings.vala index 039d7dc..6604044 100644 --- a/altyo_settings.vala +++ b/altyo_settings.vala @@ -243,7 +243,7 @@ const string settings_css_solarized_dark=""" VTToggleButton { -VTToggleButton-tab-index-color:@ayterm-palette-11; -VTToggleButton-username-color:@ayterm-palette-2; - -VTToggleButton-hostname-color:@ayterm-palette-9; + -VTToggleButton-hostname-color:@ayterm-palette-9; background-color: alpha(@ayterm-bg-color,0.0); color: @ayterm-fg-color; } @@ -409,190 +409,190 @@ VTToggleButton{ //terminal_palettes_rxvt; public class point_ActionGroup_store { - public unowned Gtk.ActionGroup action_group; - public unowned Gtk.ListStore store; - public unowned AYSettings yasettings; - public point_ActionGroup_store(Gtk.ActionGroup ag,Gtk.ListStore st,AYSettings yas) { - this.action_group=ag; - this.store=st; - this.yasettings=yas; - } + public unowned Gtk.ActionGroup action_group; + public unowned Gtk.ListStore store; + public unowned AYSettings yasettings; + public point_ActionGroup_store(Gtk.ActionGroup ag,Gtk.ListStore st,AYSettings yas) { + this.action_group=ag; + this.store=st; + this.yasettings=yas; + } } public class AYSettings : AYTab{ - private Gtk.Builder builder; - public AYObject ayobject {get;set;default=null;} - private Gtk.ListStore keybindings_store; - private string autorun_file; - private string monitor_name;/*save monitor name on which settings was opened*/ - private bool ignore_on_loading;/*ignore some events when loading settings from ini file*/ + private Gtk.Builder builder; + public AYObject ayobject {get;set;default=null;} + private Gtk.ListStore keybindings_store; + private string autorun_file; + private string monitor_name;/*save monitor name on which settings was opened*/ + private bool ignore_on_loading;/*ignore some events when loading settings from ini file*/ private VTToggleButton vttbut; - - public AYSettings(MySettings my_conf,Notebook notebook, int tab_index,AYObject ayo) { - base(my_conf, notebook, tab_index); - this.tbutton.set_title(tab_index, _("AYsettings") ); - this.ayobject=ayo; - if(this.ayobject.main_window.application.application_id!=null) - this.autorun_file = GLib.Environment.get_user_config_dir()+"/autostart"+"/"+this.ayobject.main_window.application.application_id+".desktop"; - else{ - if(my_conf.standalone_mode) - this.autorun_file = GLib.Environment.get_user_config_dir()+"/autostart"+"/altyo.standalone.desktop"; - else - this.autorun_file = GLib.Environment.get_user_config_dir()+"/autostart"+"/altyo.none.desktop"; - } - this.builder = new Gtk.Builder (); - try { - this.builder.add_from_resource ("/org/gnome/altyo/preferences.glade"); - this.builder.add_from_resource("/org/gnome/altyo/encodings_list.glade"); - this.keybindings_store = builder.get_object ("keybindings_store") as Gtk.ListStore; - - var encodings_combo = builder.get_object ("terminal_default_encoding") as Gtk.ComboBox; - var encodinsg_store = this.builder.get_object ("encodings_liststore") as Gtk.ListStore; - encodinsg_store.set_sort_column_id(1,Gtk.SortType.ASCENDING); - encodings_combo.model=encodinsg_store; - //connect model from encodings_list.glade to preferences.glade - var del_combo = builder.get_object ("terminal_delete_binding") as Gtk.ComboBox; - del_combo.model= this.builder.get_object ("terminal_delete_binding_liststore") as Gtk.ListStore; - var bps_combo = builder.get_object ("terminal_backspace_binding") as Gtk.ComboBox; - bps_combo.model= this.builder.get_object ("terminal_delete_binding_liststore") as Gtk.ListStore; - - this.builder.connect_signals(this); - var B = builder.get_object ("settings-scrolledwindow") as Gtk.Widget; - B.name="settings-scrolledwindow"; - B.destroy.connect(()=>{debug("~settings-scrolledwindow");}); - this.hbox.add(B); - var L = builder.get_object ("config_path_linkbutton") as Gtk.LinkButton; - L.label=my_conf.conf_file; - L.uri="file://"+my_conf.conf_file; - #if VTE_2_91 - /*hide unavailable options*/ - Gtk.Grid grid; - int r = 0; - Gtk.Widget? child; - - grid = (builder.get_object ("grid9") as Gtk.Grid); - while( (child=grid.get_child_at(1,r)) != null){ - switch(child.get_name()){ - case "terminal_background_image_file": - case "terminal_background_fake_transparent": - case "terminal_background_fake_transparent_scroll": - case "terminal_tint_color": - case "terminal_background_saturation": - grid.remove_row(r); - break; - default: - r++; - break; - } - } - grid = (builder.get_object ("grid1") as Gtk.Grid); - while( (child=grid.get_child_at(1,r)) != null){ - switch(child.get_name()){ - case "terminal_visible_bell": - case "terminal_set_alternate_screen_scroll": - grid.remove_row(r); - break; - default: - r++; - break; - } - } - grid = (builder.get_object ("grid5") as Gtk.Grid); - r = 0; - while( (child=grid.get_child_at(1,r)) != null){ - switch(child.get_name()){ - case "terminal_word_chars": - grid.remove_row(r); - break; - default: - r++; - break; - } - } - #endif + + public AYSettings(MySettings my_conf,Notebook notebook, int tab_index,AYObject ayo) { + base(my_conf, notebook, tab_index); + this.tbutton.set_title(tab_index, _("AYsettings") ); + this.ayobject=ayo; + if(this.ayobject.main_window.application.application_id!=null) + this.autorun_file = GLib.Environment.get_user_config_dir()+"/autostart"+"/"+this.ayobject.main_window.application.application_id+".desktop"; + else{ + if(my_conf.standalone_mode) + this.autorun_file = GLib.Environment.get_user_config_dir()+"/autostart"+"/altyo.standalone.desktop"; + else + this.autorun_file = GLib.Environment.get_user_config_dir()+"/autostart"+"/altyo.none.desktop"; + } + this.builder = new Gtk.Builder (); + try { + this.builder.add_from_resource ("/org/gnome/altyo/preferences.glade"); + this.builder.add_from_resource("/org/gnome/altyo/encodings_list.glade"); + this.keybindings_store = builder.get_object ("keybindings_store") as Gtk.ListStore; + + var encodings_combo = builder.get_object ("terminal_default_encoding") as Gtk.ComboBox; + var encodinsg_store = this.builder.get_object ("encodings_liststore") as Gtk.ListStore; + encodinsg_store.set_sort_column_id(1,Gtk.SortType.ASCENDING); + encodings_combo.model=encodinsg_store; + //connect model from encodings_list.glade to preferences.glade + var del_combo = builder.get_object ("terminal_delete_binding") as Gtk.ComboBox; + del_combo.model= this.builder.get_object ("terminal_delete_binding_liststore") as Gtk.ListStore; + var bps_combo = builder.get_object ("terminal_backspace_binding") as Gtk.ComboBox; + bps_combo.model= this.builder.get_object ("terminal_delete_binding_liststore") as Gtk.ListStore; + + this.builder.connect_signals(this); + var B = builder.get_object ("settings-scrolledwindow") as Gtk.Widget; + B.name="settings-scrolledwindow"; + B.destroy.connect(()=>{debug("~settings-scrolledwindow");}); + this.hbox.add(B); + var L = builder.get_object ("config_path_linkbutton") as Gtk.LinkButton; + L.label=my_conf.conf_file; + L.uri="file://"+my_conf.conf_file; + #if VTE_2_91 + /*hide unavailable options*/ + Gtk.Grid grid; + int r = 0; + Gtk.Widget? child; + + grid = (builder.get_object ("grid9") as Gtk.Grid); + while( (child=grid.get_child_at(1,r)) != null){ + switch(child.get_name()){ + case "terminal_background_image_file": + case "terminal_background_fake_transparent": + case "terminal_background_fake_transparent_scroll": + case "terminal_tint_color": + case "terminal_background_saturation": + grid.remove_row(r); + break; + default: + r++; + break; + } + } + grid = (builder.get_object ("grid1") as Gtk.Grid); + while( (child=grid.get_child_at(1,r)) != null){ + switch(child.get_name()){ + case "terminal_visible_bell": + case "terminal_set_alternate_screen_scroll": + grid.remove_row(r); + break; + default: + r++; + break; + } + } + grid = (builder.get_object ("grid5") as Gtk.Grid); + r = 0; + while( (child=grid.get_child_at(1,r)) != null){ + switch(child.get_name()){ + case "terminal_word_chars": + grid.remove_row(r); + break; + default: + r++; + break; + } + } + #endif this.vttbut = new VTToggleButton(); - this.get_from_conf(); - } catch (Error e) { - error ("loading menu builder file: %s", e.message); - } - if(my_conf.readonly){ - var A = builder.get_object ("apply_button") as Gtk.Button; - A.sensitive=false; - var R = builder.get_object ("restore_button") as Gtk.Button; - R.sensitive=false; - R.tooltip_text=A.tooltip_text=_("Config is read only!"); - } - } - - ~AYSettings(){ - debug("~AYSettings"); - } - - [CCode (instance_pos = -1)] - public void on_font_set (Gtk.FontButton w) { - debug("New font is: %s",w.get_font_name()); - } - - [CCode (instance_pos = -1)] - public void on_animation_enabled_toggled (Gtk.CheckButton w) { - var B = builder.get_object ("animation_pull_steps") as Gtk.SpinButton; - if(B!=null){ - B.sensitive=w.active; - } - } - - [CCode (instance_pos = -1)] - public void on_workaround_if_focuslost_toggled (Gtk.CheckButton w) { - if(!this.ignore_on_loading && w.active){ - string title=_("AltYo attention"); - string msg=_("You must restart altyo for the workaround to take effect."); - this.ayobject.main_window.show_message_box(title,msg); - } - } - - [CCode (instance_pos = -1)] - public void on_size_changed (Gtk.SpinButton w,Gtk.Label L) { - if(L!=null){ - if(w.value>100){ - L.label=_("px"); - }else - if(w.value==100){ - L.label=_("maximize"); - }else{ - L.label=_("%"); - } - } - } - - [CCode (instance_pos = -1)] - public void on_reset_terminal_background_image_file (Gtk.Button w,Gtk.FileChooserButton F) { - if(F!=null){ - F.unselect_all(); - } - } - - [CCode (instance_pos = -1)] - public void on_apply(Gtk.Button w) { - this.apply(); - } - - [CCode (instance_pos = -1)] - public void on_close(Gtk.Button w) { - this.ayobject.action_group.set_sensitive(true);//activate - this.ayobject.action_group.get_action("open_settings").activate(); - } - - [CCode (instance_pos = -1)] - public void on_reset_to_defaults(Gtk.Button w) { - GLib.Timeout.add(50,()=>{this.ayobject.show_reset_to_defaults_dialog();return false;});//async call - } - - [CCode (instance_pos = -1)] + this.get_from_conf(); + } catch (Error e) { + error ("loading menu builder file: %s", e.message); + } + if(my_conf.readonly){ + var A = builder.get_object ("apply_button") as Gtk.Button; + A.sensitive=false; + var R = builder.get_object ("restore_button") as Gtk.Button; + R.sensitive=false; + R.tooltip_text=A.tooltip_text=_("Config is read only!"); + } + } + + ~AYSettings(){ + debug("~AYSettings"); + } + + [CCode (instance_pos = -1)] + public void on_font_set (Gtk.FontButton w) { + debug("New font is: %s",w.get_font_name()); + } + + [CCode (instance_pos = -1)] + public void on_animation_enabled_toggled (Gtk.CheckButton w) { + var B = builder.get_object ("animation_pull_steps") as Gtk.SpinButton; + if(B!=null){ + B.sensitive=w.active; + } + } + + [CCode (instance_pos = -1)] + public void on_workaround_if_focuslost_toggled (Gtk.CheckButton w) { + if(!this.ignore_on_loading && w.active){ + string title=_("AltYo attention"); + string msg=_("You must restart altyo for the workaround to take effect."); + this.ayobject.main_window.show_message_box(title,msg); + } + } + + [CCode (instance_pos = -1)] + public void on_size_changed (Gtk.SpinButton w,Gtk.Label L) { + if(L!=null){ + if(w.value>100){ + L.label=_("px"); + }else + if(w.value==100){ + L.label=_("maximize"); + }else{ + L.label=_("%"); + } + } + } + + [CCode (instance_pos = -1)] + public void on_reset_terminal_background_image_file (Gtk.Button w,Gtk.FileChooserButton F) { + if(F!=null){ + F.unselect_all(); + } + } + + [CCode (instance_pos = -1)] + public void on_apply(Gtk.Button w) { + this.apply(); + } + + [CCode (instance_pos = -1)] + public void on_close(Gtk.Button w) { + this.ayobject.action_group.set_sensitive(true);//activate + this.ayobject.action_group.get_action("open_settings").activate(); + } + + [CCode (instance_pos = -1)] + public void on_reset_to_defaults(Gtk.Button w) { + GLib.Timeout.add(50,()=>{this.ayobject.show_reset_to_defaults_dialog();return false;});//async call + } + + [CCode (instance_pos = -1)] public void accel_edited_cb (Gtk.CellRendererAccel cell, string path_string, uint accel_key, Gdk.ModifierType accel_mods, uint hardware_keycode){ - debug("accel_edited_cb start"); - this.ayobject.action_group.set_sensitive(true); + debug("accel_edited_cb start"); + this.ayobject.action_group.set_sensitive(true); var path = new Gtk.TreePath.from_string (path_string); if (path == null) return; @@ -604,37 +604,37 @@ public class AYSettings : AYTab{ if (accel_path == null) return; - Gtk.Action action=this.ayobject.action_group.get_action(this.get_name_from_path(accel_path)); - - if(this.ayobject.update_action_keybinding(action,accel_key,accel_mods)){ - debug("accel_edited_cb name:%s ",accel_path); - string? name = this.get_name_from_path(accel_path); - if(name!=null){ - var parsed_name=Gtk.accelerator_name (accel_key, accel_mods); - this.my_conf.set_accel_string(name,parsed_name); - if(name=="main_hotkey"){ - this.ayobject.main_window.reconfigure();//check is it was correct, and not busy - var saved_key = this.my_conf.get_accel_string(name,""); - if(parsed_name != saved_key){ - //some thing was wrong,update key value - uint accelerator_key; - Gdk.ModifierType accelerator_mods; - Gtk.accelerator_parse(saved_key,out accelerator_key,out accelerator_mods); - accel_key=accelerator_key; - accel_mods=accelerator_mods; - } - } - this.keybindings_store.set (iter, 2, accel_key); - this.keybindings_store.set (iter, 3, accel_mods); - this.my_conf.save(); - } - } + Gtk.Action action=this.ayobject.action_group.get_action(this.get_name_from_path(accel_path)); + + if(this.ayobject.update_action_keybinding(action,accel_key,accel_mods)){ + debug("accel_edited_cb name:%s ",accel_path); + string? name = this.get_name_from_path(accel_path); + if(name!=null){ + var parsed_name=Gtk.accelerator_name (accel_key, accel_mods); + this.my_conf.set_accel_string(name,parsed_name); + if(name=="main_hotkey"){ + this.ayobject.main_window.reconfigure();//check is it was correct, and not busy + var saved_key = this.my_conf.get_accel_string(name,""); + if(parsed_name != saved_key){ + //some thing was wrong,update key value + uint accelerator_key; + Gdk.ModifierType accelerator_mods; + Gtk.accelerator_parse(saved_key,out accelerator_key,out accelerator_mods); + accel_key=accelerator_key; + accel_mods=accelerator_mods; + } + } + this.keybindings_store.set (iter, 2, accel_key); + this.keybindings_store.set (iter, 3, accel_mods); + this.my_conf.save(); + } + } } [CCode (instance_pos = -1)] public void accel_cleared_cb (Gtk.CellRendererAccel cell,string path_string){ - debug("accel_cleared_cb start"); - this.ayobject.action_group.set_sensitive(true); + debug("accel_cleared_cb start"); + this.ayobject.action_group.set_sensitive(true); var path = new Gtk.TreePath.from_string (path_string); if (path == null) return; @@ -645,157 +645,157 @@ public class AYSettings : AYTab{ this.keybindings_store.get (iter, 0, out accel_path); if (accel_path == null) return; - if(Gtk.AccelMap.change_entry(accel_path,0,0,false)){ - string? name = get_name_from_path(accel_path); - if(name!=null){ - this.my_conf.set_accel_string(name,"");//clear in config - this.keybindings_store.set (iter, 2, 0); - this.my_conf.save(); - } - } + if(Gtk.AccelMap.change_entry(accel_path,0,0,false)){ + string? name = get_name_from_path(accel_path); + if(name!=null){ + this.my_conf.set_accel_string(name,"");//clear in config + this.keybindings_store.set (iter, 2, 0); + this.my_conf.save(); + } + } //~ settings.set_int (key, 0); } - [CCode (instance_pos = -1)] - public void accel_editing_started_cb (Gtk.CellRenderer cell, - Gtk.CellEditable editable, - string path_string){ - debug("accel_editing_started_cb"); - this.ayobject.action_group.set_sensitive(false); - var tree = builder.get_object ("keybindings_treeview") as Gtk.TreeView; - tree.grab_focus();//so Gtk.CellRendererAccel will have a focus - } + [CCode (instance_pos = -1)] + public void accel_editing_started_cb (Gtk.CellRenderer cell, + Gtk.CellEditable editable, + string path_string){ + debug("accel_editing_started_cb"); + this.ayobject.action_group.set_sensitive(false); + var tree = builder.get_object ("keybindings_treeview") as Gtk.TreeView; + tree.grab_focus();//so Gtk.CellRendererAccel will have a focus + } [CCode (instance_pos = -1)] public bool on_list_button_press_event(Gtk.Widget w,Gdk.EventButton event){ - debug("command_list_button_press_event %s",w.name); - if((int)event.button == 3){//right mouse button - if(((Gtk.Buildable)w).get_name()=="terminal_autostart_session_treeview"){ - var popup_menu = builder.get_object ("popup_command_list") as Gtk.Menu; - popup_menu.popup(null, null, null, event.button, event.time); - }else - if(((Gtk.Buildable)w).get_name()=="tab_title_format_regex_treeview"){ - var popup_menu = builder.get_object ("popup_tab_title_format_regex") as Gtk.Menu; - popup_menu.popup(null, null, null, event.button, event.time); - }else - if(((Gtk.Buildable)w).get_name()=="terminal_url_regexps_treeview"){ - var popup_menu = builder.get_object ("popup_terminal_url_regexps") as Gtk.Menu; - popup_menu.popup(null, null, null, event.button, event.time); - } - return true; - } - return false; - } - - [CCode (instance_pos = -1)] - public void on_popup_command_list_add(Gtk.MenuItem item){ - var store = builder.get_object ("terminal_autostart_session") as Gtk.ListStore; - TreeIter? data_iter = this.list_store_add_after_selected("terminal_autostart_session_treeview",store); - if(data_iter!=null){ - store.set (data_iter, - 0, "/bin/sh", - -1); - } - } - - [CCode (instance_pos = -1)] - public void on_popup_command_list_remove(Gtk.MenuItem item){ - var store = builder.get_object ("terminal_autostart_session") as Gtk.ListStore; - var view = builder.get_object ("terminal_autostart_session_treeview") as Gtk.TreeView; - if(store!=null && view!=null){ - TreePath path; - TreeViewColumn s_column; - TreeIter? iter=null; - view.get_cursor(out path,out s_column); - if(store.get_iter(out iter,path)) - if(!store.iter_has_child(iter)){ - store.remove(iter); - if(store.get_iter(out iter,path)) - view.set_cursor(path,null,false); - else if(path.prev()) - view.set_cursor(path,null,false); - else if(path.up()) - view.set_cursor(path,null,false); - } - } - } - - [CCode (instance_pos = -1)] - public void on_popup_tab_title_format_regex_add(Gtk.MenuItem item){ - var store = builder.get_object ("tab_title_format_regex") as Gtk.ListStore; - TreeIter? data_iter = this.list_store_add_after_selected("tab_title_format_regex_treeview",store); - if(data_iter!=null){ - store.set (data_iter, - 0, "", - 1, "", - -1); - } - } - - [CCode (instance_pos = -1)] - public void on_popup_tab_title_format_regex_remove(Gtk.MenuItem item){ - var store = builder.get_object ("tab_title_format_regex") as Gtk.ListStore; - var view = builder.get_object ("tab_title_format_regex_treeview") as Gtk.TreeView; - if(store!=null && view!=null){ - TreePath path; - TreeViewColumn s_column; - TreeIter? iter=null; - view.get_cursor(out path,out s_column); - if(store.get_iter(out iter,path)) - if(!store.iter_has_child(iter)){ - store.remove(iter); - if(store.get_iter(out iter,path)) - view.set_cursor(path,null,false); - else if(path.prev()) - view.set_cursor(path,null,false); - else if(path.up()) - view.set_cursor(path,null,false); - } - } - } - - [CCode (instance_pos = -1)] - public void on_popup_terminal_url_regexps_add(Gtk.MenuItem item){ - var store = builder.get_object ("terminal_url_regexps") as Gtk.ListStore; - TreeIter? data_iter = this.list_store_add_after_selected("terminal_url_regexps_treeview",store); - if(data_iter!=null){ - store.set (data_iter, - 0, "", - 1, "", - -1); - } - } - - [CCode (instance_pos = -1)] - public void on_popup_terminal_url_regexps_remove(Gtk.MenuItem item){ - var store = builder.get_object ("terminal_url_regexps") as Gtk.ListStore; - var view = builder.get_object ("terminal_url_regexps_treeview") as Gtk.TreeView; - if(store!=null && view!=null){ - TreePath path; - TreeViewColumn s_column; - TreeIter? iter=null; - view.get_cursor(out path,out s_column); - if(store.get_iter(out iter,path)) - if(!store.iter_has_child(iter)){ - store.remove(iter); - if(store.get_iter(out iter,path)) - view.set_cursor(path,null,false); - else if(path.prev()) - view.set_cursor(path,null,false); - else if(path.up()) - view.set_cursor(path,null,false); - } - } - } - - [CCode (instance_pos = -1)] - public void on_terminal_autostart_session_cellrenderertext_edited (Gtk.CellRendererText renderer, string path_string, string new_text){ - debug("on_terminal_autostart_session_cellrenderertext_edited start %s",path_string); - - Gtk.ListStore? store=null; - - store = builder.get_object("terminal_autostart_session") as Gtk.ListStore; - - if(store == null) return; + debug("command_list_button_press_event %s",w.name); + if((int)event.button == 3){//right mouse button + if(((Gtk.Buildable)w).get_name()=="terminal_autostart_session_treeview"){ + var popup_menu = builder.get_object ("popup_command_list") as Gtk.Menu; + popup_menu.popup(null, null, null, event.button, event.time); + }else + if(((Gtk.Buildable)w).get_name()=="tab_title_format_regex_treeview"){ + var popup_menu = builder.get_object ("popup_tab_title_format_regex") as Gtk.Menu; + popup_menu.popup(null, null, null, event.button, event.time); + }else + if(((Gtk.Buildable)w).get_name()=="terminal_url_regexps_treeview"){ + var popup_menu = builder.get_object ("popup_terminal_url_regexps") as Gtk.Menu; + popup_menu.popup(null, null, null, event.button, event.time); + } + return true; + } + return false; + } + + [CCode (instance_pos = -1)] + public void on_popup_command_list_add(Gtk.MenuItem item){ + var store = builder.get_object ("terminal_autostart_session") as Gtk.ListStore; + TreeIter? data_iter = this.list_store_add_after_selected("terminal_autostart_session_treeview",store); + if(data_iter!=null){ + store.set (data_iter, + 0, "/bin/sh", + -1); + } + } + + [CCode (instance_pos = -1)] + public void on_popup_command_list_remove(Gtk.MenuItem item){ + var store = builder.get_object ("terminal_autostart_session") as Gtk.ListStore; + var view = builder.get_object ("terminal_autostart_session_treeview") as Gtk.TreeView; + if(store!=null && view!=null){ + TreePath path; + TreeViewColumn s_column; + TreeIter? iter=null; + view.get_cursor(out path,out s_column); + if(store.get_iter(out iter,path)) + if(!store.iter_has_child(iter)){ + store.remove(iter); + if(store.get_iter(out iter,path)) + view.set_cursor(path,null,false); + else if(path.prev()) + view.set_cursor(path,null,false); + else if(path.up()) + view.set_cursor(path,null,false); + } + } + } + + [CCode (instance_pos = -1)] + public void on_popup_tab_title_format_regex_add(Gtk.MenuItem item){ + var store = builder.get_object ("tab_title_format_regex") as Gtk.ListStore; + TreeIter? data_iter = this.list_store_add_after_selected("tab_title_format_regex_treeview",store); + if(data_iter!=null){ + store.set (data_iter, + 0, "", + 1, "", + -1); + } + } + + [CCode (instance_pos = -1)] + public void on_popup_tab_title_format_regex_remove(Gtk.MenuItem item){ + var store = builder.get_object ("tab_title_format_regex") as Gtk.ListStore; + var view = builder.get_object ("tab_title_format_regex_treeview") as Gtk.TreeView; + if(store!=null && view!=null){ + TreePath path; + TreeViewColumn s_column; + TreeIter? iter=null; + view.get_cursor(out path,out s_column); + if(store.get_iter(out iter,path)) + if(!store.iter_has_child(iter)){ + store.remove(iter); + if(store.get_iter(out iter,path)) + view.set_cursor(path,null,false); + else if(path.prev()) + view.set_cursor(path,null,false); + else if(path.up()) + view.set_cursor(path,null,false); + } + } + } + + [CCode (instance_pos = -1)] + public void on_popup_terminal_url_regexps_add(Gtk.MenuItem item){ + var store = builder.get_object ("terminal_url_regexps") as Gtk.ListStore; + TreeIter? data_iter = this.list_store_add_after_selected("terminal_url_regexps_treeview",store); + if(data_iter!=null){ + store.set (data_iter, + 0, "", + 1, "", + -1); + } + } + + [CCode (instance_pos = -1)] + public void on_popup_terminal_url_regexps_remove(Gtk.MenuItem item){ + var store = builder.get_object ("terminal_url_regexps") as Gtk.ListStore; + var view = builder.get_object ("terminal_url_regexps_treeview") as Gtk.TreeView; + if(store!=null && view!=null){ + TreePath path; + TreeViewColumn s_column; + TreeIter? iter=null; + view.get_cursor(out path,out s_column); + if(store.get_iter(out iter,path)) + if(!store.iter_has_child(iter)){ + store.remove(iter); + if(store.get_iter(out iter,path)) + view.set_cursor(path,null,false); + else if(path.prev()) + view.set_cursor(path,null,false); + else if(path.up()) + view.set_cursor(path,null,false); + } + } + } + + [CCode (instance_pos = -1)] + public void on_terminal_autostart_session_cellrenderertext_edited (Gtk.CellRendererText renderer, string path_string, string new_text){ + debug("on_terminal_autostart_session_cellrenderertext_edited start %s",path_string); + + Gtk.ListStore? store=null; + + store = builder.get_object("terminal_autostart_session") as Gtk.ListStore; + + if(store == null) return; var path = new Gtk.TreePath.from_string (path_string); @@ -804,20 +804,20 @@ public class AYSettings : AYTab{ Gtk.TreeIter iter; if (!store.get_iter (out iter, path)) return; - store.set (iter, - 0, new_text, - -1); - } + store.set (iter, + 0, new_text, + -1); + } - [CCode (instance_pos = -1)] - public void on_tab_title_format_regex_cellrenderertext_pattern_edited (Gtk.CellRendererText renderer, string path_string, string new_text){ - debug("on_tab_title_format_regex_cellrenderertext_pattern_edited start %s",path_string); + [CCode (instance_pos = -1)] + public void on_tab_title_format_regex_cellrenderertext_pattern_edited (Gtk.CellRendererText renderer, string path_string, string new_text){ + debug("on_tab_title_format_regex_cellrenderertext_pattern_edited start %s",path_string); - Gtk.ListStore? store=null; + Gtk.ListStore? store=null; - store = builder.get_object ("tab_title_format_regex") as Gtk.ListStore; + store = builder.get_object ("tab_title_format_regex") as Gtk.ListStore; - if(store == null) return; + if(store == null) return; var path = new Gtk.TreePath.from_string (path_string); @@ -826,35 +826,35 @@ public class AYSettings : AYTab{ Gtk.TreeIter iter; if (!store.get_iter (out iter, path)) return; - string err; - if(!this.my_conf.check_regex(new_text,out err)){ - var bg=new Gdk.RGBA(); - bg.parse("#FF0000"); - store.set (iter, - 0, new_text, - 2, GLib.Markup.escape_text(err,-1), /*tooltip*/ - 3, bg, - 5, true,/*strikethrough*/ - -1); - }else{ - store.set (iter, - 0, new_text, - 2, null, - 3, null, - 5, false,/*strikethrough*/ - -1); - } - } - - [CCode (instance_pos = -1)] - public void on_tab_title_format_regex_cellrenderertext_replace_edited (Gtk.CellRendererText renderer, string path_string, string new_text){ - debug("on_tab_title_format_regex_cellrenderertext_replace_edited start %s",path_string); - - Gtk.ListStore? store=null; - - store = builder.get_object ("tab_title_format_regex") as Gtk.ListStore; - - if(store == null) return; + string err; + if(!this.my_conf.check_regex(new_text,out err)){ + var bg=new Gdk.RGBA(); + bg.parse("#FF0000"); + store.set (iter, + 0, new_text, + 2, GLib.Markup.escape_text(err,-1), /*tooltip*/ + 3, bg, + 5, true,/*strikethrough*/ + -1); + }else{ + store.set (iter, + 0, new_text, + 2, null, + 3, null, + 5, false,/*strikethrough*/ + -1); + } + } + + [CCode (instance_pos = -1)] + public void on_tab_title_format_regex_cellrenderertext_replace_edited (Gtk.CellRendererText renderer, string path_string, string new_text){ + debug("on_tab_title_format_regex_cellrenderertext_replace_edited start %s",path_string); + + Gtk.ListStore? store=null; + + store = builder.get_object ("tab_title_format_regex") as Gtk.ListStore; + + if(store == null) return; var path = new Gtk.TreePath.from_string (path_string); @@ -864,37 +864,37 @@ public class AYSettings : AYTab{ if (!store.get_iter (out iter, path)) return; - string err; + string err; var s = replace_color_in_markup(this.vttbut,new_text); - if(!this.my_conf.check_markup(s,out err)){ - var bg=new Gdk.RGBA(); - bg.parse("#FF0000"); - store.set (iter, - 1, new_text, - 2, GLib.Markup.escape_text(err,-1), /*tooltip*/ - 4, bg, - 6, true,/*strikethrough*/ - -1); - }else{ - store.set (iter, - 1, new_text, - 2, null, - 4, null, - 6, false,/*strikethrough*/ - -1); - } - } - - [CCode (instance_pos = -1)] - public void on_terminal_url_regexps_match_cellrenderertext_pattern_edited (Gtk.CellRendererText renderer, string path_string, string new_text){ - debug("on_terminal_url_regexps_match_cellrenderertext_pattern_edited start %s",path_string); - - Gtk.ListStore? store=null; - - store = builder.get_object ("terminal_url_regexps") as Gtk.ListStore; - - if(store == null) return; + if(!this.my_conf.check_markup(s,out err)){ + var bg=new Gdk.RGBA(); + bg.parse("#FF0000"); + store.set (iter, + 1, new_text, + 2, GLib.Markup.escape_text(err,-1), /*tooltip*/ + 4, bg, + 6, true,/*strikethrough*/ + -1); + }else{ + store.set (iter, + 1, new_text, + 2, null, + 4, null, + 6, false,/*strikethrough*/ + -1); + } + } + + [CCode (instance_pos = -1)] + public void on_terminal_url_regexps_match_cellrenderertext_pattern_edited (Gtk.CellRendererText renderer, string path_string, string new_text){ + debug("on_terminal_url_regexps_match_cellrenderertext_pattern_edited start %s",path_string); + + Gtk.ListStore? store=null; + + store = builder.get_object ("terminal_url_regexps") as Gtk.ListStore; + + if(store == null) return; var path = new Gtk.TreePath.from_string (path_string); @@ -903,35 +903,35 @@ public class AYSettings : AYTab{ Gtk.TreeIter iter; if (!store.get_iter (out iter, path)) return; - string err; - if(!this.my_conf.check_regex(new_text,out err)){ - var bg=new Gdk.RGBA(); - bg.parse("#FF0000"); - store.set (iter, - 0, new_text, - 2, GLib.Markup.escape_text(err,-1), /*tooltip*/ - 3, bg, - 4, true,/*strikethrough*/ - -1); - }else{ - store.set (iter, - 0, new_text, - 2, null, - 3, null, - 4, false,/*strikethrough*/ - -1); - } - - } - [CCode (instance_pos = -1)] - public void on_terminal_url_regexps_run_cellrenderertext_pattern_edited (Gtk.CellRendererText renderer, string path_string, string new_text){ - debug("on_terminal_url_regexps_run_cellrenderertext_pattern_edited start %s",path_string); - - Gtk.ListStore? store=null; - - store = builder.get_object ("terminal_url_regexps") as Gtk.ListStore; - - if(store == null) return; + string err; + if(!this.my_conf.check_regex(new_text,out err)){ + var bg=new Gdk.RGBA(); + bg.parse("#FF0000"); + store.set (iter, + 0, new_text, + 2, GLib.Markup.escape_text(err,-1), /*tooltip*/ + 3, bg, + 4, true,/*strikethrough*/ + -1); + }else{ + store.set (iter, + 0, new_text, + 2, null, + 3, null, + 4, false,/*strikethrough*/ + -1); + } + + } + [CCode (instance_pos = -1)] + public void on_terminal_url_regexps_run_cellrenderertext_pattern_edited (Gtk.CellRendererText renderer, string path_string, string new_text){ + debug("on_terminal_url_regexps_run_cellrenderertext_pattern_edited start %s",path_string); + + Gtk.ListStore? store=null; + + store = builder.get_object ("terminal_url_regexps") as Gtk.ListStore; + + if(store == null) return; var path = new Gtk.TreePath.from_string (path_string); @@ -940,169 +940,169 @@ public class AYSettings : AYTab{ Gtk.TreeIter iter; if (!store.get_iter (out iter, path)) return; - store.set (iter, - 1, new_text, - -1); - } + store.set (iter, + 1, new_text, + -1); + } private string? get_name_from_path(string accel_path){ - string[] regs; - regs=GLib.Regex.split_simple("^.*/(.*)$",accel_path,RegexCompileFlags.CASELESS,0); - if(regs!=null && regs[1]!=null){ - return regs[1]; - } - return null; - } - - [CCode (instance_pos = -1)] - public void on_check_css_button_activate(Gtk.Button w) { - debug("on_check_css_button_activate"); - var B = builder.get_object ("program_style") as Gtk.TextView; - var L = builder.get_object ("check_css_label") as Gtk.Label; - string S=""; - string msg=""; - uint line,pos; - if(!this.check_css(B.buffer.text,ref S,out line,out pos)){ - msg=_("in line %d at position %d error:%s").printf(line,pos,S); - debug("on_check_css_button_activate %s",msg); - TextIter where; - B.buffer.get_iter_at_line_offset(out where,(int)line,(int)pos); - B.buffer.place_cursor(where); - B.grab_focus(); - }else - msg=_("Looks good"); - L.label=msg; - } - - private bool check_css(string css_text,ref string msg,out uint line,out uint pos){ - bool ret=true; - string S=""; - uint L=0,P=0; - var css_main = new CssProvider (); - css_main.parsing_error.connect((section,error)=>{ - if(ret){ - debug("css_main.parsing_error %s",error.message); - L=section.get_end_line(); - P=section.get_end_position(); - S=error.message; - ret=false; - } - }); - - try{ - css_main.load_from_data (css_text,-1); - }catch (Error e) { - //debug("Theme error! loading default.."); - } - msg=S; - line=L; - pos=P; - return ret; - } - - [CCode (instance_pos = -1)] - public void on_terminal_prevent_close_regex_changed(Gtk.Editable editable) { - var E = builder.get_object ("terminal_prevent_close_regex") as Gtk.Entry; - this.check_entry_regex(E); - } - - [CCode (instance_pos = -1)] - public void on_terminal_session_exclude_regex(Gtk.Editable editable) { - var E = builder.get_object ("terminal_session_exclude_regex") as Gtk.Entry; - this.check_entry_regex(E); - } - - [CCode (instance_pos = -1)] - public void on_terminal_terminal_exclude_variables(Gtk.Editable editable) { - var E = builder.get_object ("terminal_exclude_variables") as Gtk.Entry; - this.check_entry_regex(E); + string[] regs; + regs=GLib.Regex.split_simple("^.*/(.*)$",accel_path,RegexCompileFlags.CASELESS,0); + if(regs!=null && regs[1]!=null){ + return regs[1]; + } + return null; + } + + [CCode (instance_pos = -1)] + public void on_check_css_button_activate(Gtk.Button w) { + debug("on_check_css_button_activate"); + var B = builder.get_object ("program_style") as Gtk.TextView; + var L = builder.get_object ("check_css_label") as Gtk.Label; + string S=""; + string msg=""; + uint line,pos; + if(!this.check_css(B.buffer.text,ref S,out line,out pos)){ + msg=_("in line %d at position %d error:%s").printf(line,pos,S); + debug("on_check_css_button_activate %s",msg); + TextIter where; + B.buffer.get_iter_at_line_offset(out where,(int)line,(int)pos); + B.buffer.place_cursor(where); + B.grab_focus(); + }else + msg=_("Looks good"); + L.label=msg; + } + + private bool check_css(string css_text,ref string msg,out uint line,out uint pos){ + bool ret=true; + string S=""; + uint L=0,P=0; + var css_main = new CssProvider (); + css_main.parsing_error.connect((section,error)=>{ + if(ret){ + debug("css_main.parsing_error %s",error.message); + L=section.get_end_line(); + P=section.get_end_position(); + S=error.message; + ret=false; + } + }); + + try{ + css_main.load_from_data (css_text,-1); + }catch (Error e) { + //debug("Theme error! loading default.."); + } + msg=S; + line=L; + pos=P; + return ret; + } + + [CCode (instance_pos = -1)] + public void on_terminal_prevent_close_regex_changed(Gtk.Editable editable) { + var E = builder.get_object ("terminal_prevent_close_regex") as Gtk.Entry; + this.check_entry_regex(E); + } + + [CCode (instance_pos = -1)] + public void on_terminal_session_exclude_regex(Gtk.Editable editable) { + var E = builder.get_object ("terminal_session_exclude_regex") as Gtk.Entry; + this.check_entry_regex(E); + } + + [CCode (instance_pos = -1)] + public void on_terminal_terminal_exclude_variables(Gtk.Editable editable) { + var E = builder.get_object ("terminal_exclude_variables") as Gtk.Entry; + this.check_entry_regex(E); //prevent empty regexp issue #36 if(E.text.strip() == ""){ E.text="^()$"; } - } - - [CCode (instance_pos = -1)] - public void on_tab_format_markup(Gtk.Editable editable) { - var E = builder.get_object ("tab_format") as Gtk.Entry; - this.check_entry_markup(E); - } - - [CCode (instance_pos = -1)] - public void on_tab_title_format_markup(Gtk.Editable editable) { - var E = builder.get_object ("tab_title_format") as Gtk.Entry; - this.check_entry_markup(E); - } - - private void check_entry_regex(Gtk.Entry E) { - if( E != null){ - string err; - if(!this.my_conf.check_regex(replace_color_in_markup(this.vttbut,E.text),out err)){ - E.set_tooltip_text (err); - var bg=new Gdk.RGBA(); - bg.parse("#FF0000"); - E.override_color(Gtk.StateFlags.NORMAL,bg); - }else{ - E.set_tooltip_text (err); - E.override_color(Gtk.StateFlags.NORMAL,null); - } - } - } - - private void check_entry_markup(Gtk.Entry E) { - if( E != null){ - string err; - if(!this.my_conf.check_markup(replace_color_in_markup(this.vttbut,E.text),out err)){ - E.set_tooltip_text (err); - var bg=new Gdk.RGBA(); - bg.parse("#FF0000"); - E.override_color(Gtk.StateFlags.NORMAL,bg); - }else{ - E.set_tooltip_text (err); - E.override_color(Gtk.StateFlags.NORMAL,null); - } - } - } - - private TreeIter? list_store_add_after_selected(string key,Gtk.ListStore store){ - TreeIter? data_iter=null; - var view = builder.get_object (key) as Gtk.TreeView; - - if(store!=null && view!=null){ - TreeModel model; - TreeIter selected_iter; - var selection = view.get_selection(); - if(selection.get_selected(out model,out selected_iter)){ - store.insert_after (out data_iter, selected_iter); - }else{ - store.append (out data_iter); - } - } - return data_iter; - } - - [CCode (instance_pos = -1)] - public void on_terminal_background_image_file_file_set (Gtk.FileChooserButton w) { - string? S=null; - S=w.get_filename(); - var B = builder.get_object ("terminal_background_fake_transparent_scroll") as Gtk.CheckButton; - if(B!=null){ - if(S!=null && S!="") - B.sensitive=true; - else - B.sensitive=true; - } - } - - [CCode (instance_pos = -1)] - public void on_terminal_notify_level_changed(Gtk.ComboBox w){ - var B = builder.get_object ("terminal_timeout_before_notify") as Gtk.SpinButton; - if(B!=null){ - B.sensitive=( (w.active==1 || w.active==3) ?true:false); - } - } + } + + [CCode (instance_pos = -1)] + public void on_tab_format_markup(Gtk.Editable editable) { + var E = builder.get_object ("tab_format") as Gtk.Entry; + this.check_entry_markup(E); + } + + [CCode (instance_pos = -1)] + public void on_tab_title_format_markup(Gtk.Editable editable) { + var E = builder.get_object ("tab_title_format") as Gtk.Entry; + this.check_entry_markup(E); + } + + private void check_entry_regex(Gtk.Entry E) { + if( E != null){ + string err; + if(!this.my_conf.check_regex(replace_color_in_markup(this.vttbut,E.text),out err)){ + E.set_tooltip_text (err); + var bg=new Gdk.RGBA(); + bg.parse("#FF0000"); + E.override_color(Gtk.StateFlags.NORMAL,bg); + }else{ + E.set_tooltip_text (err); + E.override_color(Gtk.StateFlags.NORMAL,null); + } + } + } + + private void check_entry_markup(Gtk.Entry E) { + if( E != null){ + string err; + if(!this.my_conf.check_markup(replace_color_in_markup(this.vttbut,E.text),out err)){ + E.set_tooltip_text (err); + var bg=new Gdk.RGBA(); + bg.parse("#FF0000"); + E.override_color(Gtk.StateFlags.NORMAL,bg); + }else{ + E.set_tooltip_text (err); + E.override_color(Gtk.StateFlags.NORMAL,null); + } + } + } + + private TreeIter? list_store_add_after_selected(string key,Gtk.ListStore store){ + TreeIter? data_iter=null; + var view = builder.get_object (key) as Gtk.TreeView; + + if(store!=null && view!=null){ + TreeModel model; + TreeIter selected_iter; + var selection = view.get_selection(); + if(selection.get_selected(out model,out selected_iter)){ + store.insert_after (out data_iter, selected_iter); + }else{ + store.append (out data_iter); + } + } + return data_iter; + } + + [CCode (instance_pos = -1)] + public void on_terminal_background_image_file_file_set (Gtk.FileChooserButton w) { + string? S=null; + S=w.get_filename(); + var B = builder.get_object ("terminal_background_fake_transparent_scroll") as Gtk.CheckButton; + if(B!=null){ + if(S!=null && S!="") + B.sensitive=true; + else + B.sensitive=true; + } + } + + [CCode (instance_pos = -1)] + public void on_terminal_notify_level_changed(Gtk.ComboBox w){ + var B = builder.get_object ("terminal_timeout_before_notify") as Gtk.SpinButton; + if(B!=null){ + B.sensitive=( (w.active==1 || w.active==3) ?true:false); + } + } /*multidimensional array, hahaha*/ - private Gdk.RGBA? get_color_from_array(int theme,int x){ + private Gdk.RGBA? get_color_from_array(int theme,int x){ switch(theme){ case 0 : return terminal_palettes_tango[x]; case 1 : return terminal_palettes_linux[x]; @@ -1113,7 +1113,7 @@ public class AYSettings : AYTab{ return null; } [CCode (instance_pos = -1)] - public void on_opacity_changed (Gtk.SpinButton opacity_w) {//ay_settings_on_opacity_changed + public void on_opacity_changed (Gtk.SpinButton opacity_w) {//ay_settings_on_opacity_changed var CB = builder.get_object ("terminal_color_bg") as Gtk.ColorButton; var bg = CB.get_rgba(); bg.alpha=opacity_w.get_value(); @@ -1123,11 +1123,11 @@ public class AYSettings : AYTab{ string alpha="%1.2f".printf(round_double(bg.alpha,2)); alpha=alpha.replace(",","."); update_css_global_color(ref css_inner,"ayterm-bg-color","alpha(%s,%s)".printf(hexRGBA(bg),alpha) ); - + B.buffer.text=css_inner;//done } [CCode (instance_pos = -1)] - public void on_theme_changed (Gtk.ComboBox w) {//ay_settings_on_theme_changed + public void on_theme_changed (Gtk.ComboBox w) {//ay_settings_on_theme_changed Gtk.ColorButton CB; int theme_index=w.get_active(); var B = builder.get_object ("program_style") as Gtk.TextView; @@ -1140,7 +1140,7 @@ public class AYSettings : AYTab{ case 3 : css_inner=settings_css_linux; break; case 4 : css_inner=settings_css_solarized_dark; break; }; - + for(int i=1; i<17;i++){ CB = builder.get_object ("terminal_palette_colorbutton"+i.to_string()) as Gtk.ColorButton; if(CB!=null){ @@ -1152,7 +1152,7 @@ public class AYSettings : AYTab{ CB = builder.get_object ("terminal_color_fg") as Gtk.ColorButton; CB.set_rgba(get_color_from_array(theme_index,7)); update_css_global_color(ref css_inner,"ayterm-fg-color",hexRGBA(CB.rgba) ); - + CB = builder.get_object ("terminal_color_bg") as Gtk.ColorButton; var bg = get_color_from_array(theme_index,0); var opacity_w = builder.get_object ("terminal_opacity") as Gtk.SpinButton; @@ -1162,32 +1162,32 @@ public class AYSettings : AYTab{ string alpha="%1.2f".printf(round_double(bg.alpha,2)); alpha=alpha.replace(",","."); update_css_global_color(ref css_inner,"ayterm-bg-color","alpha(%s,%s)".printf(hexRGBA(bg),alpha) ); - + B.buffer.text=css_inner;//done - + //string css = "AYTerm { %s } ".printf(css_inner); //debug(css); - + //https://regex101.com/r/iT2eR5/9 //~ Regex css_regex = new Regex ("""((^\s*)|(\}\s*))(?PAYTerm\s*\{\s*(([\/\*].*[\*\/])?[^}]+?)+\s*\})"""); //~ MatchInfo match_info; -//~ var css_result = new StringBuilder(s); +//~ var css_result = new StringBuilder(s); //~ if(css_regex.match(s,0, out match_info) ){ //~ debug(" RegexEvalCallback match_info "); //~ int start_pos, end_pos; //~ if(match_info.fetch_named_pos("AYTerm_css",out start_pos, out end_pos) ){ //~ debug(" RegexEvalCallback %d %d ",start_pos,end_pos); -//~ +//~ //~ css_result.erase(start_pos,end_pos-start_pos); //~ css_result.insert(start_pos,css); //~ } //~ }else{ //~ css_result.prepend(css); -//~ } - } +//~ } + } [CCode (instance_pos = -1)] - public void on_pallette_color_changed (Gtk.ColorButton CB) {//ay_settings_on_pallette_color_changed + public void on_pallette_color_changed (Gtk.ColorButton CB) {//ay_settings_on_pallette_color_changed var fg = CB.get_rgba(); CB.set_rgba(fg); var B = builder.get_object ("program_style") as Gtk.TextView; @@ -1197,7 +1197,7 @@ public class AYSettings : AYTab{ } [CCode (instance_pos = -1)] - public void on_terminal_color_fg_changed (Gtk.ColorButton CB) {//ay_settings_on_terminal_color_fg_changed + public void on_terminal_color_fg_changed (Gtk.ColorButton CB) {//ay_settings_on_terminal_color_fg_changed var fg = CB.get_rgba(); CB.set_rgba(fg); var B = builder.get_object ("program_style") as Gtk.TextView; @@ -1207,7 +1207,7 @@ public class AYSettings : AYTab{ } [CCode (instance_pos = -1)] - public void on_terminal_color_bg_changed (Gtk.ColorButton CB) {//ay_settings_on_terminal_color_bg_changed + public void on_terminal_color_bg_changed (Gtk.ColorButton CB) {//ay_settings_on_terminal_color_bg_changed var opacity_w = builder.get_object ("terminal_opacity") as Gtk.SpinButton; var bg = CB.get_rgba(); bg.alpha=opacity_w.get_value(); @@ -1220,7 +1220,7 @@ public class AYSettings : AYTab{ B.buffer.text=css_inner;//done } - private string css_ini_to_human(string s){ + private string css_ini_to_human(string s){ Regex regex = new Regex ("[{};]"); string result = regex.replace_eval(s, s.length,0,0, (match_info, result)=>{ result.append(match_info.fetch(match_info.get_match_count()-1)+"\n"); @@ -1229,12 +1229,12 @@ public class AYSettings : AYTab{ return result; } private void load_css(){ - //load css colors + //load css colors var test_term =new AYTerm();//will be destroyed automatically var tct = new term_colors_t(); test_term.gen_colors(tct); - + Gtk.ColorButton CB; CB = builder.get_object ("terminal_color_fg") as Gtk.ColorButton; if(tct.fg!=null) @@ -1257,7 +1257,7 @@ public class AYSettings : AYTab{ } } - + private void update_css_global_color(ref string where,string name, string val){ bool done=false; Regex regex = new Regex ("""\@define\-color\s+"""+GLib.Regex.escape_string(name)+"""\s+(?P[^\;]+);"""); @@ -1282,487 +1282,487 @@ public class AYSettings : AYTab{ where=result; } - public void get_from_conf() { - unowned Gdk.Screen gscreen = this.ayobject.main_window.get_screen (); + public void get_from_conf() { + unowned Gdk.Screen gscreen = this.ayobject.main_window.get_screen (); int win_x,win_y; - this.ayobject.main_window.get_position (out win_x, out win_y); - this.monitor_name = gscreen.get_monitor_plug_name(gscreen.get_monitor_at_point (win_x,win_y)); - this.ignore_on_loading = true; - - var keys = this.my_conf.get_profile_keys(); - foreach(var key in keys){ - switch(this.my_conf.get_key_type(key)){ - case CFG_TYPE.TYPE_UNKNOWN: - continue; - break; - case CFG_TYPE.TYPE_BOOLEAN: - var B = builder.get_object (key) as Gtk.CheckButton; - if(B!=null){ - B.active=this.my_conf.get_boolean(key,false); - }else debug(" no gui for key %s",key); - break; - case CFG_TYPE.TYPE_DOUBLE: - var B = builder.get_object (key) as Gtk.SpinButton; - if(B!=null){ - B.value=this.my_conf.get_double(key,0); - }else debug(" no gui for key %s",key); - break; - case CFG_TYPE.TYPE_INTEGER: - if(key=="terminal_cursorshape" || - key=="terminal_cursor_blinkmode" || - key=="terminal_delete_binding" || - key=="terminal_backspace_binding" || - key=="terminal_notify_level" || - key=="window_action_on_close_last_tab" || - key=="window_new_tab_position" || - key=="window_hvbox_display_mode"){ - var B = builder.get_object (key) as Gtk.ComboBox; - B.active=this.my_conf.get_integer(key,0); - }else if(key=="window_position_x_%s".printf(this.monitor_name) ){ - string unikey = key.substring(0,key.index_of (this.monitor_name)-1);//window_position_x_VGA-0 -> window_position_x - var B = builder.get_object (unikey) as Gtk.ComboBox; - B.active=this.my_conf.get_integer(key,0); - }else if(key=="terminal_width_%s".printf(this.monitor_name) || - key=="terminal_height_%s".printf(this.monitor_name) || - key=="window_position_y_%s".printf(this.monitor_name) ) { - string unikey = key.substring(0,key.index_of (this.monitor_name)-1);//terminal_width_VGA-0 -> terminal_width - var B = builder.get_object (unikey) as Gtk.SpinButton; - if(B!=null){ - B.value=this.my_conf.get_integer(key,0); - }else debug(" no gui for key %s",key); - }else{ - var B = builder.get_object (key) as Gtk.SpinButton; - if(B!=null){ - B.value=this.my_conf.get_integer(key,0); - }else debug(" no gui for key %s",key); - } - break; - case CFG_TYPE.TYPE_STRING: - if(key=="window_default_monitor"){ - var store = builder.get_object (key+"_liststore") as Gtk.ListStore; - - for(var i=0;i{ - string? val=null; - store.get (iter,1, out val, -1);//get combobox item value - if(val!=null && val==ret){ - B.active=path.get_indices()[0]; - return true;//stop - } - return false;//continue - }); - - }else - if(key=="terminal_default_encoding"){ - unowned TreeIter iter; - string term_encoding = this.my_conf.get_string(key,""); - var encodings_combo = builder.get_object ("terminal_default_encoding") as Gtk.ComboBox; - bool found=false; - //try to find encoding in a list - if(encodings_combo.model.get_iter_first(out iter)) - do{ - string s; - encodings_combo.model.get(iter,0,out s); - if(s == term_encoding){ - found=true; - break; - } - }while(encodings_combo.model.iter_next(ref iter)); - - if(found) - encodings_combo.set_active_iter(iter); - else - ((Entry)encodings_combo.get_child()).set_text(term_encoding); - }else{ - var B = builder.get_object (key) as Gtk.Entry; - if(B!=null){ - B.text=this.my_conf.get_string(key,""); - }else - debug(" no gui for key %s",key); - } - break; - case CFG_TYPE.TYPE_STRING_LIST: - var store = builder.get_object (key) as Gtk.ListStore; - if(store!=null){ - string[] sl=this.my_conf.get_string_list(key,null); - if(key=="tab_title_format_regex" || key=="terminal_url_regexps"){ - for(int i=0; i{ - unowned Gtk.ListStore p_store=(Gtk.ListStore)((point_ActionGroup_store)pvoid).store; - unowned Gtk.ActionGroup ag=(Gtk.ActionGroup)((point_ActionGroup_store)pvoid).action_group; - unowned AYSettings yasettings=(AYSettings)((point_ActionGroup_store)pvoid).yasettings; - - string? s = yasettings.get_name_from_path(accel_path); - - if(s!=null && ag.get_action(s)!=null){ - TreeIter? data_iter=null; - p_store.append (out data_iter); - p_store.set (data_iter, - 0, accel_path, - 1, ag.get_action(s).get_label(), - 2, accel_key, - 3, accel_mods, - 4, true,/*editable*/ - 5, ag.get_action(s).get_tooltip(), - -1); - } - }); - this.keybindings_store.set_sort_column_id(0,Gtk.SortType.ASCENDING); - - if(GLib.FileUtils.test(this.autorun_file,GLib.FileTest.EXISTS)){ - - if(!this.get_autostart_hidden()){ - var B = builder.get_object ("window_autostart_with_desktop") as Gtk.CheckButton; - if(B!=null){ - B.active=true; - }else debug(" no gui for window_autostart_with_desktop"); - } - } - #if !ALTERNATE_SCREEN_SCROLL - if(my_conf.DISTR_ID!=DISTRIB_ID.UBUNTU){ - //debian patch vte_terminal_set_alternate_screen_scroll - var ASS = builder.get_object ("terminal_set_alternate_screen_scroll") as Gtk.CheckButton; - ASS.sensitive=false; - } - #endif - + this.ayobject.main_window.get_position (out win_x, out win_y); + this.monitor_name = gscreen.get_monitor_plug_name(gscreen.get_monitor_at_point (win_x,win_y)); + this.ignore_on_loading = true; + + var keys = this.my_conf.get_profile_keys(); + foreach(var key in keys){ + switch(this.my_conf.get_key_type(key)){ + case CFG_TYPE.TYPE_UNKNOWN: + continue; + break; + case CFG_TYPE.TYPE_BOOLEAN: + var B = builder.get_object (key) as Gtk.CheckButton; + if(B!=null){ + B.active=this.my_conf.get_boolean(key,false); + }else debug(" no gui for key %s",key); + break; + case CFG_TYPE.TYPE_DOUBLE: + var B = builder.get_object (key) as Gtk.SpinButton; + if(B!=null){ + B.value=this.my_conf.get_double(key,0); + }else debug(" no gui for key %s",key); + break; + case CFG_TYPE.TYPE_INTEGER: + if(key=="terminal_cursorshape" || + key=="terminal_cursor_blinkmode" || + key=="terminal_delete_binding" || + key=="terminal_backspace_binding" || + key=="terminal_notify_level" || + key=="window_action_on_close_last_tab" || + key=="window_new_tab_position" || + key=="window_hvbox_display_mode"){ + var B = builder.get_object (key) as Gtk.ComboBox; + B.active=this.my_conf.get_integer(key,0); + }else if(key=="window_position_x_%s".printf(this.monitor_name) ){ + string unikey = key.substring(0,key.index_of (this.monitor_name)-1);//window_position_x_VGA-0 -> window_position_x + var B = builder.get_object (unikey) as Gtk.ComboBox; + B.active=this.my_conf.get_integer(key,0); + }else if(key=="terminal_width_%s".printf(this.monitor_name) || + key=="terminal_height_%s".printf(this.monitor_name) || + key=="window_position_y_%s".printf(this.monitor_name) ) { + string unikey = key.substring(0,key.index_of (this.monitor_name)-1);//terminal_width_VGA-0 -> terminal_width + var B = builder.get_object (unikey) as Gtk.SpinButton; + if(B!=null){ + B.value=this.my_conf.get_integer(key,0); + }else debug(" no gui for key %s",key); + }else{ + var B = builder.get_object (key) as Gtk.SpinButton; + if(B!=null){ + B.value=this.my_conf.get_integer(key,0); + }else debug(" no gui for key %s",key); + } + break; + case CFG_TYPE.TYPE_STRING: + if(key=="window_default_monitor"){ + var store = builder.get_object (key+"_liststore") as Gtk.ListStore; + + for(var i=0;i{ + string? val=null; + store.get (iter,1, out val, -1);//get combobox item value + if(val!=null && val==ret){ + B.active=path.get_indices()[0]; + return true;//stop + } + return false;//continue + }); + + }else + if(key=="terminal_default_encoding"){ + unowned TreeIter iter; + string term_encoding = this.my_conf.get_string(key,""); + var encodings_combo = builder.get_object ("terminal_default_encoding") as Gtk.ComboBox; + bool found=false; + //try to find encoding in a list + if(encodings_combo.model.get_iter_first(out iter)) + do{ + string s; + encodings_combo.model.get(iter,0,out s); + if(s == term_encoding){ + found=true; + break; + } + }while(encodings_combo.model.iter_next(ref iter)); + + if(found) + encodings_combo.set_active_iter(iter); + else + ((Entry)encodings_combo.get_child()).set_text(term_encoding); + }else{ + var B = builder.get_object (key) as Gtk.Entry; + if(B!=null){ + B.text=this.my_conf.get_string(key,""); + }else + debug(" no gui for key %s",key); + } + break; + case CFG_TYPE.TYPE_STRING_LIST: + var store = builder.get_object (key) as Gtk.ListStore; + if(store!=null){ + string[] sl=this.my_conf.get_string_list(key,null); + if(key=="tab_title_format_regex" || key=="terminal_url_regexps"){ + for(int i=0; i{ + unowned Gtk.ListStore p_store=(Gtk.ListStore)((point_ActionGroup_store)pvoid).store; + unowned Gtk.ActionGroup ag=(Gtk.ActionGroup)((point_ActionGroup_store)pvoid).action_group; + unowned AYSettings yasettings=(AYSettings)((point_ActionGroup_store)pvoid).yasettings; + + string? s = yasettings.get_name_from_path(accel_path); + + if(s!=null && ag.get_action(s)!=null){ + TreeIter? data_iter=null; + p_store.append (out data_iter); + p_store.set (data_iter, + 0, accel_path, + 1, ag.get_action(s).get_label(), + 2, accel_key, + 3, accel_mods, + 4, true,/*editable*/ + 5, ag.get_action(s).get_tooltip(), + -1); + } + }); + this.keybindings_store.set_sort_column_id(0,Gtk.SortType.ASCENDING); + + if(GLib.FileUtils.test(this.autorun_file,GLib.FileTest.EXISTS)){ + + if(!this.get_autostart_hidden()){ + var B = builder.get_object ("window_autostart_with_desktop") as Gtk.CheckButton; + if(B!=null){ + B.active=true; + }else debug(" no gui for window_autostart_with_desktop"); + } + } + #if !ALTERNATE_SCREEN_SCROLL + if(my_conf.DISTR_ID!=DISTRIB_ID.UBUNTU){ + //debian patch vte_terminal_set_alternate_screen_scroll + var ASS = builder.get_object ("terminal_set_alternate_screen_scroll") as Gtk.CheckButton; + ASS.sensitive=false; + } + #endif + this.load_css(); - - this.ignore_on_loading = false; - }//get_from_conf - - public void apply() { - var keys = this.my_conf.get_profile_keys(); - foreach(var key_bug in keys){ - var key=key_bug;//bug in UBUNTU precise - switch(this.my_conf.get_key_type(key)){ - case CFG_TYPE.TYPE_UNKNOWN: - continue; - break; - case CFG_TYPE.TYPE_BOOLEAN: - var B = builder.get_object (key) as Gtk.CheckButton; - if(B!=null){ - if(B.active!=this.my_conf.get_boolean(key,false)) - this.my_conf.set_boolean(key,B.active); - }else debug(" no gui for key %s",key); - break; - case CFG_TYPE.TYPE_DOUBLE: - var B = builder.get_object (key) as Gtk.SpinButton; - if(B!=null){ - /***** WARNING! ******************* - * accuracy, two sign after comma*/ - int r_val=(int)((B.value+0.005) * 100);//round - B.value=(double)((double)(r_val)/(double)100); - //debug("CFG_TYPE.TYPE_DOUBLE=%.2f",B.value); - if(B.value!=this.my_conf.get_double(key,0)) - this.my_conf.set_double(key, B.value, 2);//two sign after comma - }else debug(" no gui for key %s",key); - break; - case CFG_TYPE.TYPE_INTEGER: - if(key=="terminal_cursorshape" || - key=="terminal_cursor_blinkmode" || - key=="terminal_delete_binding" || - key=="terminal_backspace_binding" || - key=="terminal_notify_level" || - key=="window_action_on_close_last_tab" || - key=="window_new_tab_position" || - key=="window_hvbox_display_mode"){ - var B = builder.get_object (key) as Gtk.ComboBox; - if(B.active!=this.my_conf.get_integer(key,0)) - this.my_conf.set_integer(key,B.active); - }else if(key=="window_position_x_%s".printf(this.monitor_name) ){ - string unikey = key.substring(0,key.index_of (this.monitor_name)-1);//window_position_x_VGA-0 -> window_position_x - var B = builder.get_object (unikey) as Gtk.ComboBox; - if(B.active!=this.my_conf.get_integer(key,0)) - this.my_conf.set_integer(key,B.active); - }else if(key=="terminal_width_%s".printf(this.monitor_name) || - key=="terminal_height_%s".printf(this.monitor_name) || - key=="window_position_y_%s".printf(this.monitor_name) ) { - string unikey = key.substring(0,key.index_of (this.monitor_name)-1);//terminal_width_VGA-0 -> terminal_width - var B = builder.get_object (unikey) as Gtk.SpinButton; - if(B!=null){ - if(B.value!=this.my_conf.get_integer(key,0)) - this.my_conf.set_integer(key,(int)B.value); - }else debug(" no gui for key %s",key); - }else{ - var B = builder.get_object (key) as Gtk.SpinButton; - if(B!=null){ - if(B.value!=this.my_conf.get_integer(key,0)) - this.my_conf.set_integer(key,(int)B.value); - }else debug(" no gui for key %s",key); - } - break; - case CFG_TYPE.TYPE_STRING: - if(key=="window_default_monitor"){ - var combo = builder.get_object (key) as Gtk.ComboBox; - var entry = combo.get_child() as Gtk.Entry; - if(entry.text!=this.my_conf.get_string(key,"")){ - this.my_conf.set_string(key,entry.text); - } - }else - if(key=="terminal_font"){ - var B = builder.get_object (key) as Gtk.FontButton; - if(B.font_name!=this.my_conf.get_string(key,"")) - this.my_conf.set_string(key,B.font_name); - }else - if(/*key=="terminal_color_fg" || key=="terminal_color_bg" ||*/ key=="terminal_tint_color"){ - var B = builder.get_object (key) as Gtk.ColorButton; - var color=B.get_rgba(); - var S = color.to_string(); - if(S!=null && S != this.my_conf.get_string(key,"")){ - this.my_conf.set_string(key,S); - } - - }else - if(key=="terminal_background_image_file"){ - string? S=null; - var B = builder.get_object (key) as Gtk.FileChooserButton; - S=B.get_filename(); - if(S!=this.my_conf.get_string(key,"")){ - debug("terminal_background_image_file=%s",S); - this.my_conf.set_string(key,S); - } - }else - if(key=="program_style"){ - var B = builder.get_object (key) as Gtk.TextView; - var s=B.buffer.text; - string S=""; - uint line,pos; - if(!this.check_css(s,ref S,out line,out pos)){ - string msg=_("New style will not be saved!\nin line %d at position %d\nerror:%s").printf(line,pos,S); - debug("on config apply css error %s",msg); - this.ayobject.main_window.show_message_box(_("AltYo CSS style error"),msg); - }else{//looks good - Regex regex = new Regex ("\n"); - string result = regex.replace (s,-1, 0, ""); - if(result!=this.my_conf.get_string(key,"")){ - this.my_conf.set_string(key,result); - B.buffer.text=this.css_ini_to_human(result);//update - } - } - }else - if(key=="tab_sort_order"){ - var B = builder.get_object (key) as Gtk.ComboBox; - var store = builder.get_object (key+"_liststore") as Gtk.ListStore; - string ret = this.my_conf.get_string(key,"none"); - var path = new TreePath.from_indices(B.active); - TreeIter? iter=null; - string? val=null; - if(path!=null && store.get_iter (out iter, path)){ - store.get (iter, 1, out val); - if(val!=ret){ - this.my_conf.set_string(key,val); - if(val!="none") - this.ayobject.tab_sort(); - } - } - }else - if(key=="terminal_default_encoding"){ - unowned TreeIter iter; - var encodings_combo = builder.get_object ("terminal_default_encoding") as Gtk.ComboBox; - var new_encoding = ((Entry)encodings_combo.get_child()).get_text(); - if(new_encoding==""){ - if(this.my_conf.get_string(key,new_encoding)!="default"){ - this.my_conf.set_string(key,"default"); - ((Entry)encodings_combo.get_child()).set_text("default"); - } - }else if(new_encoding!="default"){ - this.my_conf.set_string(key,new_encoding); - } - }else{ - var B = builder.get_object (key) as Gtk.Entry; - if(B!=null){ - if(B.text!=this.my_conf.get_string(key,"")){ - if(key=="terminal_prevent_close_regex" || key=="terminal_session_exclude_regex" || key =="terminal_exclude_variables"){ - string err; + + this.ignore_on_loading = false; + }//get_from_conf + + public void apply() { + var keys = this.my_conf.get_profile_keys(); + foreach(var key_bug in keys){ + var key=key_bug;//bug in UBUNTU precise + switch(this.my_conf.get_key_type(key)){ + case CFG_TYPE.TYPE_UNKNOWN: + continue; + break; + case CFG_TYPE.TYPE_BOOLEAN: + var B = builder.get_object (key) as Gtk.CheckButton; + if(B!=null){ + if(B.active!=this.my_conf.get_boolean(key,false)) + this.my_conf.set_boolean(key,B.active); + }else debug(" no gui for key %s",key); + break; + case CFG_TYPE.TYPE_DOUBLE: + var B = builder.get_object (key) as Gtk.SpinButton; + if(B!=null){ + /***** WARNING! ******************* + * accuracy, two sign after comma*/ + int r_val=(int)((B.value+0.005) * 100);//round + B.value=(double)((double)(r_val)/(double)100); + //debug("CFG_TYPE.TYPE_DOUBLE=%.2f",B.value); + if(B.value!=this.my_conf.get_double(key,0)) + this.my_conf.set_double(key, B.value, 2);//two sign after comma + }else debug(" no gui for key %s",key); + break; + case CFG_TYPE.TYPE_INTEGER: + if(key=="terminal_cursorshape" || + key=="terminal_cursor_blinkmode" || + key=="terminal_delete_binding" || + key=="terminal_backspace_binding" || + key=="terminal_notify_level" || + key=="window_action_on_close_last_tab" || + key=="window_new_tab_position" || + key=="window_hvbox_display_mode"){ + var B = builder.get_object (key) as Gtk.ComboBox; + if(B.active!=this.my_conf.get_integer(key,0)) + this.my_conf.set_integer(key,B.active); + }else if(key=="window_position_x_%s".printf(this.monitor_name) ){ + string unikey = key.substring(0,key.index_of (this.monitor_name)-1);//window_position_x_VGA-0 -> window_position_x + var B = builder.get_object (unikey) as Gtk.ComboBox; + if(B.active!=this.my_conf.get_integer(key,0)) + this.my_conf.set_integer(key,B.active); + }else if(key=="terminal_width_%s".printf(this.monitor_name) || + key=="terminal_height_%s".printf(this.monitor_name) || + key=="window_position_y_%s".printf(this.monitor_name) ) { + string unikey = key.substring(0,key.index_of (this.monitor_name)-1);//terminal_width_VGA-0 -> terminal_width + var B = builder.get_object (unikey) as Gtk.SpinButton; + if(B!=null){ + if(B.value!=this.my_conf.get_integer(key,0)) + this.my_conf.set_integer(key,(int)B.value); + }else debug(" no gui for key %s",key); + }else{ + var B = builder.get_object (key) as Gtk.SpinButton; + if(B!=null){ + if(B.value!=this.my_conf.get_integer(key,0)) + this.my_conf.set_integer(key,(int)B.value); + }else debug(" no gui for key %s",key); + } + break; + case CFG_TYPE.TYPE_STRING: + if(key=="window_default_monitor"){ + var combo = builder.get_object (key) as Gtk.ComboBox; + var entry = combo.get_child() as Gtk.Entry; + if(entry.text!=this.my_conf.get_string(key,"")){ + this.my_conf.set_string(key,entry.text); + } + }else + if(key=="terminal_font"){ + var B = builder.get_object (key) as Gtk.FontButton; + if(B.font_name!=this.my_conf.get_string(key,"")) + this.my_conf.set_string(key,B.font_name); + }else + if(/*key=="terminal_color_fg" || key=="terminal_color_bg" ||*/ key=="terminal_tint_color"){ + var B = builder.get_object (key) as Gtk.ColorButton; + var color=B.get_rgba(); + var S = color.to_string(); + if(S!=null && S != this.my_conf.get_string(key,"")){ + this.my_conf.set_string(key,S); + } + + }else + if(key=="terminal_background_image_file"){ + string? S=null; + var B = builder.get_object (key) as Gtk.FileChooserButton; + S=B.get_filename(); + if(S!=this.my_conf.get_string(key,"")){ + debug("terminal_background_image_file=%s",S); + this.my_conf.set_string(key,S); + } + }else + if(key=="program_style"){ + var B = builder.get_object (key) as Gtk.TextView; + var s=B.buffer.text; + string S=""; + uint line,pos; + if(!this.check_css(s,ref S,out line,out pos)){ + string msg=_("New style will not be saved!\nin line %d at position %d\nerror:%s").printf(line,pos,S); + debug("on config apply css error %s",msg); + this.ayobject.main_window.show_message_box(_("AltYo CSS style error"),msg); + }else{//looks good + Regex regex = new Regex ("\n"); + string result = regex.replace (s,-1, 0, ""); + if(result!=this.my_conf.get_string(key,"")){ + this.my_conf.set_string(key,result); + B.buffer.text=this.css_ini_to_human(result);//update + } + } + }else + if(key=="tab_sort_order"){ + var B = builder.get_object (key) as Gtk.ComboBox; + var store = builder.get_object (key+"_liststore") as Gtk.ListStore; + string ret = this.my_conf.get_string(key,"none"); + var path = new TreePath.from_indices(B.active); + TreeIter? iter=null; + string? val=null; + if(path!=null && store.get_iter (out iter, path)){ + store.get (iter, 1, out val); + if(val!=ret){ + this.my_conf.set_string(key,val); + if(val!="none") + this.ayobject.tab_sort(); + } + } + }else + if(key=="terminal_default_encoding"){ + unowned TreeIter iter; + var encodings_combo = builder.get_object ("terminal_default_encoding") as Gtk.ComboBox; + var new_encoding = ((Entry)encodings_combo.get_child()).get_text(); + if(new_encoding==""){ + if(this.my_conf.get_string(key,new_encoding)!="default"){ + this.my_conf.set_string(key,"default"); + ((Entry)encodings_combo.get_child()).set_text("default"); + } + }else if(new_encoding!="default"){ + this.my_conf.set_string(key,new_encoding); + } + }else{ + var B = builder.get_object (key) as Gtk.Entry; + if(B!=null){ + if(B.text!=this.my_conf.get_string(key,"")){ + if(key=="terminal_prevent_close_regex" || key=="terminal_session_exclude_regex" || key =="terminal_exclude_variables"){ + string err; var s = replace_color_in_markup(this.vttbut,B.text); - if(this.my_conf.check_regex(s,out err)){ - this.my_conf.set_string(key,B.text);//save unchanged markup - }else{ - string title=_("AltYo %s error").printf(key); - string msg=_("New value of %s will not be saved!\n%s").printf(key,err); - this.ayobject.main_window.show_message_box(title,msg); - } - }else - if(key=="tab_format" || key=="tab_title_format"){ - string err; + if(this.my_conf.check_regex(s,out err)){ + this.my_conf.set_string(key,B.text);//save unchanged markup + }else{ + string title=_("AltYo %s error").printf(key); + string msg=_("New value of %s will not be saved!\n%s").printf(key,err); + this.ayobject.main_window.show_message_box(title,msg); + } + }else + if(key=="tab_format" || key=="tab_title_format"){ + string err; var s = replace_color_in_markup(this.vttbut,B.text); - if(this.my_conf.check_markup(s,out err)){ - this.my_conf.set_string(key,B.text);//save unchanged markup - }else{ - string title=_("AltYo %s error").printf(key); - string msg=_("New value of %s will not be saved!\n%s").printf(key,err); - this.ayobject.main_window.show_message_box(title,msg); - } - }else - this.my_conf.set_string(key,B.text); - } - }else - debug(" no gui for key %s",key); - } - break; - case CFG_TYPE.TYPE_STRING_LIST: - var store = builder.get_object (key) as Gtk.ListStore; - if(store!=null){ - - if(key=="tab_title_format_regex" || key=="terminal_url_regexps"){ - string[] sl = {}; - bool ignore_changes=false; - string err=""; - store.foreach((model, path, iter) =>{ - string? s1=null,s2=null; - store.get (iter, - 0, out s1, - 1, out s2, - -1); - if(s1!=null && s2!=null){ + if(this.my_conf.check_markup(s,out err)){ + this.my_conf.set_string(key,B.text);//save unchanged markup + }else{ + string title=_("AltYo %s error").printf(key); + string msg=_("New value of %s will not be saved!\n%s").printf(key,err); + this.ayobject.main_window.show_message_box(title,msg); + } + }else + this.my_conf.set_string(key,B.text); + } + }else + debug(" no gui for key %s",key); + } + break; + case CFG_TYPE.TYPE_STRING_LIST: + var store = builder.get_object (key) as Gtk.ListStore; + if(store!=null){ + + if(key=="tab_title_format_regex" || key=="terminal_url_regexps"){ + string[] sl = {}; + bool ignore_changes=false; + string err=""; + store.foreach((model, path, iter) =>{ + string? s1=null,s2=null; + store.get (iter, + 0, out s1, + 1, out s2, + -1); + if(s1!=null && s2!=null){ var smark = replace_color_in_markup(this.vttbut,s2); - if(this.my_conf.check_regex(s1,out err) && - ((key=="tab_title_format_regex" && this.my_conf.check_markup(smark,out err)) || - key!="tab_title_format_regex" - )){ - sl+=s1; - sl+=s2; - debug("s1=%s s2=%s",s1,s2); - return false;//continue - }else{ - ignore_changes=true; - return true;//stop - } - }else - return false;//continue, skip empty - }); - if(!ignore_changes) - this.my_conf.set_string_list(key,sl); - else{ - string title=_("AltYo %s error").printf(key); - string msg=_("New value of %s will not be saved!\n%s").printf(key,err); - this.ayobject.main_window.show_message_box(title,msg); - } - }else - if(key=="terminal_autostart_session"){ - string[] sl = {}; - store.foreach((model, path, iter) =>{ - string? s1=null; - store.get (iter, - 0, out s1, - -1); - if(s1!=null) - sl+=s1; - debug("s1=%s",s1); - return false;//continue - }); - this.my_conf.set_string_list(key,sl); - } - }else - if(key=="terminal_palette"){ - string[] sl = {}; - for(int i=1; i<17;i++){ - var B = builder.get_object ("terminal_palette_colorbutton"+i.to_string()) as Gtk.ColorButton; - if(B!=null){ - sl+=B.rgba.to_string(); - } - } - this.my_conf.set_string_list(key,sl); - }else - debug(" no gui for key %s",key); - break; - case CFG_TYPE.TYPE_ACCEL_STRING: - break; - } - } - - var B = builder.get_object ("window_autostart_with_desktop") as Gtk.CheckButton; - if(B!=null){ - if(B.active){ - if(!GLib.FileUtils.test(this.autorun_file,GLib.FileTest.EXISTS)){ - GLib.DirUtils.create_with_parents(GLib.Path.get_dirname(this.autorun_file),502);//755 create autostart dir if not exist - try{ - string autorun_content = """ + if(this.my_conf.check_regex(s1,out err) && + ((key=="tab_title_format_regex" && this.my_conf.check_markup(smark,out err)) || + key!="tab_title_format_regex" + )){ + sl+=s1; + sl+=s2; + debug("s1=%s s2=%s",s1,s2); + return false;//continue + }else{ + ignore_changes=true; + return true;//stop + } + }else + return false;//continue, skip empty + }); + if(!ignore_changes) + this.my_conf.set_string_list(key,sl); + else{ + string title=_("AltYo %s error").printf(key); + string msg=_("New value of %s will not be saved!\n%s").printf(key,err); + this.ayobject.main_window.show_message_box(title,msg); + } + }else + if(key=="terminal_autostart_session"){ + string[] sl = {}; + store.foreach((model, path, iter) =>{ + string? s1=null; + store.get (iter, + 0, out s1, + -1); + if(s1!=null) + sl+=s1; + debug("s1=%s",s1); + return false;//continue + }); + this.my_conf.set_string_list(key,sl); + } + }else + if(key=="terminal_palette"){ + string[] sl = {}; + for(int i=1; i<17;i++){ + var B = builder.get_object ("terminal_palette_colorbutton"+i.to_string()) as Gtk.ColorButton; + if(B!=null){ + sl+=B.rgba.to_string(); + } + } + this.my_conf.set_string_list(key,sl); + }else + debug(" no gui for key %s",key); + break; + case CFG_TYPE.TYPE_ACCEL_STRING: + break; + } + } + + var B = builder.get_object ("window_autostart_with_desktop") as Gtk.CheckButton; + if(B!=null){ + if(B.active){ + if(!GLib.FileUtils.test(this.autorun_file,GLib.FileTest.EXISTS)){ + GLib.DirUtils.create_with_parents(GLib.Path.get_dirname(this.autorun_file),502);//755 create autostart dir if not exist + try{ + string autorun_content = """ [Desktop Entry] Type=Application Encoding=UTF-8 @@ -1772,73 +1772,73 @@ Name[ru_RU]=АльтЁ Comment[ru_RU]=АльтЁ терминал Comment=AltYo terminal Exec=altyo"""; - if(my_conf.standalone_mode) - autorun_content += " --standalone"; - - if(this.ayobject.main_window.application.application_id!=null) - autorun_content += " --id="+this.ayobject.main_window.application.application_id+"\n"; - else - autorun_content += " --id=none\n"; - - if(!GLib.FileUtils.set_contents (this.autorun_file, autorun_content)){ - debug(" unable to save altyo.desktop file"); - } - } catch (GLib.FileError err) { - warning (err.message); - } - }else{//file exist, set hidden false - this.set_autostart_hidden(false); - } - }else{//disable autrun - if(GLib.FileUtils.test(this.autorun_file,GLib.FileTest.EXISTS)){ - //GLib.FileUtils.remove(this.autorun_file); - this.set_autostart_hidden(true); - } - } - } - this.my_conf.reload_config(); - this.my_conf.save(); - this.load_css();//reload - }//apply - - - private void set_autostart_hidden(bool newstate){ - var kf = new KeyFile(); - try { - kf.load_from_file(this.autorun_file, KeyFileFlags.KEEP_COMMENTS); - } catch (GLib.KeyFileError err) { - warning (err.message); - return; - } - bool ret=false; - try{ - ret=kf.get_boolean(GLib.KeyFileDesktop.GROUP,GLib.KeyFileDesktop.KEY_HIDDEN); - } catch (GLib.KeyFileError err) { - } - if(ret!=newstate){ - kf.set_boolean(GLib.KeyFileDesktop.GROUP,GLib.KeyFileDesktop.KEY_HIDDEN,newstate);//enable - var str = kf.to_data (null); - try{ - FileUtils.set_contents (this.autorun_file, str, str.length); - } catch (FileError err) { - warning (err.message); - } - } - }//set_autostart_hidden - - private bool get_autostart_hidden(){ - bool ret=false; - var kf = new KeyFile(); - try { - kf.load_from_file(this.autorun_file, KeyFileFlags.KEEP_COMMENTS); - } catch (GLib.KeyFileError err) { - warning (err.message); - } - try{ - ret=kf.get_boolean(GLib.KeyFileDesktop.GROUP,GLib.KeyFileDesktop.KEY_HIDDEN); - } catch (GLib.KeyFileError err) { - } - return ret; - }//get_autostart_hidden + if(my_conf.standalone_mode) + autorun_content += " --standalone"; + + if(this.ayobject.main_window.application.application_id!=null) + autorun_content += " --id="+this.ayobject.main_window.application.application_id+"\n"; + else + autorun_content += " --id=none\n"; + + if(!GLib.FileUtils.set_contents (this.autorun_file, autorun_content)){ + debug(" unable to save altyo.desktop file"); + } + } catch (GLib.FileError err) { + warning (err.message); + } + }else{//file exist, set hidden false + this.set_autostart_hidden(false); + } + }else{//disable autrun + if(GLib.FileUtils.test(this.autorun_file,GLib.FileTest.EXISTS)){ + //GLib.FileUtils.remove(this.autorun_file); + this.set_autostart_hidden(true); + } + } + } + this.my_conf.reload_config(); + this.my_conf.save(); + this.load_css();//reload + }//apply + + + private void set_autostart_hidden(bool newstate){ + var kf = new KeyFile(); + try { + kf.load_from_file(this.autorun_file, KeyFileFlags.KEEP_COMMENTS); + } catch (GLib.KeyFileError err) { + warning (err.message); + return; + } + bool ret=false; + try{ + ret=kf.get_boolean(GLib.KeyFileDesktop.GROUP,GLib.KeyFileDesktop.KEY_HIDDEN); + } catch (GLib.KeyFileError err) { + } + if(ret!=newstate){ + kf.set_boolean(GLib.KeyFileDesktop.GROUP,GLib.KeyFileDesktop.KEY_HIDDEN,newstate);//enable + var str = kf.to_data (null); + try{ + FileUtils.set_contents (this.autorun_file, str, str.length); + } catch (FileError err) { + warning (err.message); + } + } + }//set_autostart_hidden + + private bool get_autostart_hidden(){ + bool ret=false; + var kf = new KeyFile(); + try { + kf.load_from_file(this.autorun_file, KeyFileFlags.KEEP_COMMENTS); + } catch (GLib.KeyFileError err) { + warning (err.message); + } + try{ + ret=kf.get_boolean(GLib.KeyFileDesktop.GROUP,GLib.KeyFileDesktop.KEY_HIDDEN); + } catch (GLib.KeyFileError err) { + } + return ret; + }//get_autostart_hidden }//class AYSettings diff --git a/altyo_terminal.vala b/altyo_terminal.vala index 03352d5..747c84f 100644 --- a/altyo_terminal.vala +++ b/altyo_terminal.vala @@ -23,506 +23,506 @@ using GnomeKeyring; public enum FIND_TTY{ - CMDLINE, - CWD, - PID - } + CMDLINE, + CWD, + PID + } public enum VTT_LOCK_SETTING{ - ENCODING, - DELETE_BINDING, - BACKSPACE_BINDING - } - + ENCODING, + DELETE_BINDING, + BACKSPACE_BINDING + } + public delegate void OnChildExitCallBack(VTTerminal vt); public class TildaAuth:Object{ - public string? user; - public string? password; - public string? host; - public string? command; - public string? type; - - public TildaAuth(string? user,string? password,string? host,string? command){ - this.user=user; - this.password=password; - this.host=host; - //string[] commands={}; - //commands=command.split(","); - this.command=command; - if( GLib.Regex.match_simple("^ *ssh *(,.*)?$",this.command,RegexCompileFlags.CASELESS,0) ) - this.type="ssh"; - else - this.type="unknown"; - debug("TildaAuth this.type=%s",this.type); - } + public string? user; + public string? password; + public string? host; + public string? command; + public string? type; + + public TildaAuth(string? user,string? password,string? host,string? command){ + this.user=user; + this.password=password; + this.host=host; + //string[] commands={}; + //commands=command.split(","); + this.command=command; + if( GLib.Regex.match_simple("^ *ssh *(,.*)?$",this.command,RegexCompileFlags.CASELESS,0) ) + this.type="ssh"; + else + this.type="unknown"; + debug("TildaAuth this.type=%s",this.type); + } }//class TildaAuth public class VTToggleButton : Gtk.Button{ - static construct { - install_style_property (param_spec_boxed ("tab-index-color", - null, null, - typeof(Gdk.RGBA), - GLib.ParamFlags.READABLE)); - install_style_property (param_spec_boxed ("username-color", - null, null, - typeof(Gdk.RGBA), - GLib.ParamFlags.READABLE)); - install_style_property (param_spec_boxed ("hostname-color", - null, null, - typeof(Gdk.RGBA), - GLib.ParamFlags.READABLE)); + static construct { + install_style_property (param_spec_boxed ("tab-index-color", + null, null, + typeof(Gdk.RGBA), + GLib.ParamFlags.READABLE)); + install_style_property (param_spec_boxed ("username-color", + null, null, + typeof(Gdk.RGBA), + GLib.ParamFlags.READABLE)); + install_style_property (param_spec_boxed ("hostname-color", + null, null, + typeof(Gdk.RGBA), + GLib.ParamFlags.READABLE)); + } + bool _active = false; + public bool active {get{ return _active;} + set{ + if(this._active != value){ + this._active=value; + this.update_state(); + } + //debug ("toggled = %s , %s ",this._active.to_string(),this.label.get_text()); + } + } + private Gtk.Label label; + public unowned Object object; + public string tab_format {get;set;} + public string tab_title_format {get;set;} + public string[] tab_title_regex {get;set;} + public string host_name {get;set;default = null;} + public bool do_not_sort {get;set;default = false;} + public int conf_max_width {get;set;default = -1;} + public bool prevent_close=false; + + public string tab_title {get;set;default = null;} + private string? _tab_custom_title = null; + public string? tab_custom_title { + get { return _tab_custom_title;} + set{ + _tab_custom_title=value; + this.force_update_tab_title = true; + this.set_title(this.tab_index,null); + this.user_notify=false; + } + } + public bool tab_custom_title_enabled { + get{ return _tab_custom_title!=null; } + } + public uint tab_index; /*tab position starting from 0*/ + private string markup_normal {get;set;} + private string markup_active {get;set;} + private string markup_prelight {get;set;} + public bool force_update_tab_title {get;set;default = false;} + private bool _user_notify=false; + public bool user_notify { + get{ + return _user_notify; + } + set{ + if(value && !_user_notify && !this.active){ + var flags = this.get_state_flags(); + this.set_state_flags(Gtk.StateFlags.SELECTED,true); + _user_notify=true; + }else{ + if(!value){ + var flags = this.get_state_flags(); + this.set_state_flags(flags&~Gtk.StateFlags.SELECTED,true); + _user_notify=false; + if(this.terminal_contents_changed_timer!=0){ + GLib.Source.remove(this.terminal_contents_changed_timer); + this.terminal_contents_changed_timer=0;//stop timer if active + } + } + } + }//set } - bool _active = false; - public bool active {get{ return _active;} - set{ - if(this._active != value){ - this._active=value; - this.update_state(); - } - //debug ("toggled = %s , %s ",this._active.to_string(),this.label.get_text()); - } - } - private Gtk.Label label; - public unowned Object object; - public string tab_format {get;set;} - public string tab_title_format {get;set;} - public string[] tab_title_regex {get;set;} - public string host_name {get;set;default = null;} - public bool do_not_sort {get;set;default = false;} - public int conf_max_width {get;set;default = -1;} - public bool prevent_close=false; - - public string tab_title {get;set;default = null;} - private string? _tab_custom_title = null; - public string? tab_custom_title { - get { return _tab_custom_title;} - set{ - _tab_custom_title=value; - this.force_update_tab_title = true; - this.set_title(this.tab_index,null); - this.user_notify=false; - } - } - public bool tab_custom_title_enabled { - get{ return _tab_custom_title!=null; } - } - public uint tab_index; /*tab position starting from 0*/ - private string markup_normal {get;set;} - private string markup_active {get;set;} - private string markup_prelight {get;set;} - public bool force_update_tab_title {get;set;default = false;} - private bool _user_notify=false; - public bool user_notify { - get{ - return _user_notify; - } - set{ - if(value && !_user_notify && !this.active){ - var flags = this.get_state_flags(); - this.set_state_flags(Gtk.StateFlags.SELECTED,true); - _user_notify=true; - }else{ - if(!value){ - var flags = this.get_state_flags(); - this.set_state_flags(flags&~Gtk.StateFlags.SELECTED,true); - _user_notify=false; - if(this.terminal_contents_changed_timer!=0){ - GLib.Source.remove(this.terminal_contents_changed_timer); - this.terminal_contents_changed_timer=0;//stop timer if active - } - } - } - }//set - } - public bool notify_on_title_change=false; - private uint terminal_contents_changed_timer = 0; - public uint notify_timeout = 1; - - //private string label_text; - - public VTToggleButton() { - Object(); - } - /*public VTToggleButton.with_label (string label) { - this.label_text = label; - Object(); - }*/ - ~VTToggleButton() { - debug("~VTToggleButton"); - } - - construct { - this.label = new Gtk.Label(null); - this.label.use_underline=false; - this.label.show(); - this.add(this.label); - this.label.mnemonic_widget=null; - this.user_notify=false; - unowned Gtk.StyleContext context = this.get_style_context(); -//~ context.remove_class("button");//don't use default button theme - context.add_class("aytab"); - } - - public override void state_flags_changed (StateFlags previous_state_flags) { + public bool notify_on_title_change=false; + private uint terminal_contents_changed_timer = 0; + public uint notify_timeout = 1; + + //private string label_text; + + public VTToggleButton() { + Object(); + } + /*public VTToggleButton.with_label (string label) { + this.label_text = label; + Object(); + }*/ + ~VTToggleButton() { + debug("~VTToggleButton"); + } + + construct { + this.label = new Gtk.Label(null); + this.label.use_underline=false; + this.label.show(); + this.add(this.label); + this.label.mnemonic_widget=null; + this.user_notify=false; + unowned Gtk.StyleContext context = this.get_style_context(); +//~ context.remove_class("button");//don't use default button theme + context.add_class("aytab"); + } + + public override void state_flags_changed (StateFlags previous_state_flags) { var flags = this.get_state_flags(); if(this.active && (flags & Gtk.StateFlags.ACTIVE)!=Gtk.StateFlags.ACTIVE){ this.set_state_flags(flags|Gtk.StateFlags.ACTIVE,false);//force state active return; } base.state_flags_changed(previous_state_flags); - } - - public override bool enter_notify_event (Gdk.EventCrossing event) { - if( event.type == Gdk.EventType.ENTER_NOTIFY){ - this.set_state_flags(Gtk.StateFlags.PRELIGHT,true); - this.label.set_markup(this.markup_prelight); - } - return true;//stop - } - public override bool leave_notify_event (Gdk.EventCrossing event) { - if(event.type == Gdk.EventType.LEAVE_NOTIFY){ - this.update_state(); - } - return true;//stop - } - - public void update_state(){ - if(this._active){ - this.user_notify=false; - this.set_state_flags(Gtk.StateFlags.ACTIVE,true); - this.label.set_markup(this.markup_active); - }else{ - this.set_state_flags((this._user_notify?Gtk.StateFlags.NORMAL|Gtk.StateFlags.SELECTED:Gtk.StateFlags.NORMAL),true); - this.label.set_markup(this.markup_normal); - } - } - - - public bool set_title(uint tab_index /*starting from 0*/,string? title){ - debug("set_title start"); - if( ((this.tab_title != null && this.tab_title == title && this.tab_index == tab_index )|| - (title == null && this.tab_index == tab_index )) && this.force_update_tab_title==false ) - return false; //prevent unneccesary redraw - debug("set_title(%u,%s)",tab_index,title); - - - - if(!this.active && - this.notify_on_title_change && - this.tab_title != null && - this.tab_title != title && - this.tab_custom_title_enabled == false && - this.user_notify == false && - this.tab_index == tab_index)//ignore DnD index change - this.user_notify=true; - - string? new_title=null; - - if((title!=null && title!="") || this.force_update_tab_title) - this.tab_title = title; - - this.force_update_tab_title=false; - - if(this.tab_custom_title_enabled) - new_title = this.tab_custom_title; - else - new_title = this.tab_title; - - this.tab_index = tab_index; - - tab_index++;//convert index from 0 to 1 - - string result2=""; - if((new_title!=null && new_title!="") ){ - try{ - GLib.Regex grx_arr; - string reg_title=GLib.Markup.escape_text(new_title,-1);//replace < > with < > - bool done[4]={false,false,false,false}; - for(int i=0; i{ - debug(" RegexEvalCallback %s %s %d",result.str,match_info.fetch(0),match_info.get_match_count()); - GLib.Regex grx; - - if(!done[0] && Regex.match_simple(".*_REPLACE_.*",this.tab_title_regex[i+1])){ - //done[0]=true;//replace is allowed repeatedly - grx = new GLib.Regex(GLib.Regex.escape_string("_REPLACE_")); - result.append(grx.replace_literal(this.tab_title_regex[i+1],-1, 0, match_info.fetch(match_info.get_match_count()-1)) ); - return true;//stop - }else - if(!done[1] && Regex.match_simple(".*_USER_.*",this.tab_title_regex[i+1])){ - done[1]=true; - grx = new GLib.Regex(GLib.Regex.escape_string("_USER_")); - result.append(grx.replace_literal(this.tab_title_regex[i+1],-1, 0, match_info.fetch(match_info.get_match_count()-1)) ); - return true;//stop - }else - if(!done[2] && Regex.match_simple(".*_HOSTNAME_.*",this.tab_title_regex[i+1])){ - done[2]=true; - grx = new GLib.Regex(GLib.Regex.escape_string("_HOSTNAME_")); - result.append(grx.replace_literal(this.tab_title_regex[i+1],-1, 0, match_info.fetch(match_info.get_match_count()-1)) ); - this.host_name=match_info.fetch(match_info.get_match_count()-1); - return true;//stop - }else - if(!done[3] && Regex.match_simple(".*_PATH_.*",this.tab_title_regex[i+1])){ - done[3]=true; - grx = new GLib.Regex(GLib.Regex.escape_string("_PATH_")); - result.append(grx.replace_literal(this.tab_title_regex[i+1],-1, 0, match_info.fetch(match_info.get_match_count()-1)) ); - return true;//stop - } - return false;//continue - } ); - //g_free(grx_arr); - } - - var grx_index = new GLib.Regex(GLib.Regex.escape_string("_INDEX_")); - var grx_title = new GLib.Regex(GLib.Regex.escape_string("_TITLE_")); + } + + public override bool enter_notify_event (Gdk.EventCrossing event) { + if( event.type == Gdk.EventType.ENTER_NOTIFY){ + this.set_state_flags(Gtk.StateFlags.PRELIGHT,true); + this.label.set_markup(this.markup_prelight); + } + return true;//stop + } + public override bool leave_notify_event (Gdk.EventCrossing event) { + if(event.type == Gdk.EventType.LEAVE_NOTIFY){ + this.update_state(); + } + return true;//stop + } + + public void update_state(){ + if(this._active){ + this.user_notify=false; + this.set_state_flags(Gtk.StateFlags.ACTIVE,true); + this.label.set_markup(this.markup_active); + }else{ + this.set_state_flags((this._user_notify?Gtk.StateFlags.NORMAL|Gtk.StateFlags.SELECTED:Gtk.StateFlags.NORMAL),true); + this.label.set_markup(this.markup_normal); + } + } + + + public bool set_title(uint tab_index /*starting from 0*/,string? title){ + debug("set_title start"); + if( ((this.tab_title != null && this.tab_title == title && this.tab_index == tab_index )|| + (title == null && this.tab_index == tab_index )) && this.force_update_tab_title==false ) + return false; //prevent unneccesary redraw + debug("set_title(%u,%s)",tab_index,title); + + + + if(!this.active && + this.notify_on_title_change && + this.tab_title != null && + this.tab_title != title && + this.tab_custom_title_enabled == false && + this.user_notify == false && + this.tab_index == tab_index)//ignore DnD index change + this.user_notify=true; + + string? new_title=null; + + if((title!=null && title!="") || this.force_update_tab_title) + this.tab_title = title; + + this.force_update_tab_title=false; + + if(this.tab_custom_title_enabled) + new_title = this.tab_custom_title; + else + new_title = this.tab_title; + + this.tab_index = tab_index; + + tab_index++;//convert index from 0 to 1 + + string result2=""; + if((new_title!=null && new_title!="") ){ + try{ + GLib.Regex grx_arr; + string reg_title=GLib.Markup.escape_text(new_title,-1);//replace < > with < > + bool done[4]={false,false,false,false}; + for(int i=0; i{ + debug(" RegexEvalCallback %s %s %d",result.str,match_info.fetch(0),match_info.get_match_count()); + GLib.Regex grx; + + if(!done[0] && Regex.match_simple(".*_REPLACE_.*",this.tab_title_regex[i+1])){ + //done[0]=true;//replace is allowed repeatedly + grx = new GLib.Regex(GLib.Regex.escape_string("_REPLACE_")); + result.append(grx.replace_literal(this.tab_title_regex[i+1],-1, 0, match_info.fetch(match_info.get_match_count()-1)) ); + return true;//stop + }else + if(!done[1] && Regex.match_simple(".*_USER_.*",this.tab_title_regex[i+1])){ + done[1]=true; + grx = new GLib.Regex(GLib.Regex.escape_string("_USER_")); + result.append(grx.replace_literal(this.tab_title_regex[i+1],-1, 0, match_info.fetch(match_info.get_match_count()-1)) ); + return true;//stop + }else + if(!done[2] && Regex.match_simple(".*_HOSTNAME_.*",this.tab_title_regex[i+1])){ + done[2]=true; + grx = new GLib.Regex(GLib.Regex.escape_string("_HOSTNAME_")); + result.append(grx.replace_literal(this.tab_title_regex[i+1],-1, 0, match_info.fetch(match_info.get_match_count()-1)) ); + this.host_name=match_info.fetch(match_info.get_match_count()-1); + return true;//stop + }else + if(!done[3] && Regex.match_simple(".*_PATH_.*",this.tab_title_regex[i+1])){ + done[3]=true; + grx = new GLib.Regex(GLib.Regex.escape_string("_PATH_")); + result.append(grx.replace_literal(this.tab_title_regex[i+1],-1, 0, match_info.fetch(match_info.get_match_count()-1)) ); + return true;//stop + } + return false;//continue + } ); + //g_free(grx_arr); + } + + var grx_index = new GLib.Regex(GLib.Regex.escape_string("_INDEX_")); + var grx_title = new GLib.Regex(GLib.Regex.escape_string("_TITLE_")); result2 = grx_index.replace_literal(this.tab_title_format,-1, 0, tab_index.to_string() ); result2 = grx_title.replace_literal(result2,(ssize_t) result2.size(), 0, reg_title); - }catch(GLib.RegexError e){ - this.label.set_markup("TAB: Error in regexp"); - } - }else{ - try{ - var grx_index = new GLib.Regex(GLib.Regex.escape_string("_INDEX_")); + }catch(GLib.RegexError e){ + this.label.set_markup("TAB: Error in regexp"); + } + }else{ + try{ + var grx_index = new GLib.Regex(GLib.Regex.escape_string("_INDEX_")); result2 = grx_index.replace_literal(this.tab_format,-1, 0, tab_index.to_string() ); - }catch(GLib.RegexError e){ - this.label.set_markup("TAB: Error in regexp"); - } - } - - unowned Gtk.StyleContext context = this.get_style_context(); //todo: use this.label instead - context.invalidate();//fix wrong colors - + }catch(GLib.RegexError e){ + this.label.set_markup("TAB: Error in regexp"); + } + } + + unowned Gtk.StyleContext context = this.get_style_context(); //todo: use this.label instead + context.invalidate();//fix wrong colors + Gdk.RGBA color_f = context.get_color(StateFlags.NORMAL); Gdk.RGBA color_b = context.get_background_color(StateFlags.NORMAL); - this.markup_normal=replace_color_in_markup(this,(this.prevent_close ? "[!] " : "")+""+result2+""); - //this.label.set_markup(this.markup_normal); - this.tooltip_markup=this.markup_normal; - //var grx_prelight = new GLib.Regex(GLib.Regex.escape_string("foreground")); - //result = grx_prelight.replace_literal(result,(ssize_t) result.size(), 0, "background" ); + this.markup_normal=replace_color_in_markup(this,(this.prevent_close ? "[!] " : "")+""+result2+""); + //this.label.set_markup(this.markup_normal); + this.tooltip_markup=this.markup_normal; + //var grx_prelight = new GLib.Regex(GLib.Regex.escape_string("foreground")); + //result = grx_prelight.replace_literal(result,(ssize_t) result.size(), 0, "background" ); color_f = context.get_color(StateFlags.ACTIVE); color_b = context.get_background_color(StateFlags.ACTIVE); - this.markup_active=replace_color_in_markup(this,(this.prevent_close ? "[!] " : "")+""+result2+"",StateFlags.ACTIVE); + this.markup_active=replace_color_in_markup(this,(this.prevent_close ? "[!] " : "")+""+result2+"",StateFlags.ACTIVE); color_f = context.get_color(StateFlags.PRELIGHT); color_b = context.get_background_color(StateFlags.PRELIGHT); - this.markup_prelight=replace_color_in_markup(this,(this.prevent_close ? "[!] " : "")+""+result2+"",StateFlags.PRELIGHT); - //this.markup_prelight = result;//""+result+""; - - if(this.active) - this.label.set_markup(this.markup_active); - else - this.label.set_markup(this.markup_normal); - - return true; - } - - public override void get_preferred_width (out int minimum_width, out int natural_width) { - int max_width=-1; - /* if label ellipsized, then normal size will be in natural_width - * but because we use this.width_request as maximum width, - * natural_width will be equal to width_request - * */ - base.get_preferred_width (out minimum_width, out natural_width); - - //set limit if configured - if(this.conf_max_width>0) - max_width=this.conf_max_width; - //use this.width_request as limiting size from hvbox - if( (this.width_request>0 && - this.conf_max_width>0 && - this.width_request0 && this.conf_max_width<1) ){ - max_width=this.width_request; - } - //debug("VTToggleButton1 max_width=%d minimum_width=%d,natural_width=%d ele=%d width_request=%d",max_width,minimum_width,natural_width,this.label.ellipsize,this.width_request); - /*limit width if necessary*/ - if(max_width>0 && natural_width>max_width){ - if(this.label.ellipsize != Pango.EllipsizeMode.MIDDLE) - this.label.ellipsize = Pango.EllipsizeMode.MIDDLE;//limit label size,queue resize (hardcoded in label) - natural_width=minimum_width=max_width;//return limited size - this.has_tooltip=true; - }else{ - if(this.label.ellipsize != Pango.EllipsizeMode.NONE) - this.label.ellipsize = Pango.EllipsizeMode.NONE;//reset limit,queue resize (hardcoded in label) - minimum_width = natural_width; - this.has_tooltip=false; - if(this.width_request>0) - this.width_request=-1;//reset it if size is ok - } - //debug("VTToggleButton2 max_width=%d minimum_width=%d,natural_width=%d ele=%d width_request=%d",max_width,minimum_width,natural_width,this.label.ellipsize,this.width_request); - } - - public override void get_preferred_height (out int minimum_height, out int natural_height) { - var tmp = this.label.ellipsize; - this.label.ellipsize = Pango.EllipsizeMode.NONE; - base.get_preferred_height (out minimum_height, out natural_height); - this.label.ellipsize = tmp; - } - - public void reconfigure(){ - unowned Gtk.StyleContext context = this.get_style_context(); - context.invalidate(); - this.force_update_tab_title=true; - this.set_title(this.tab_index,this.tab_title);//force update title - } - - public void check_for_notify(){ - if(!this.active && !this.user_notify){ - debug("terminal_contents_changed"); - if(this.terminal_contents_changed_timer!=0) - GLib.Source.remove(this.terminal_contents_changed_timer); - this.terminal_contents_changed_timer=GLib.Timeout.add_seconds(this.notify_timeout,this.on_terminal_contents_changed_timeout); - } - } - - public bool on_terminal_contents_changed_timeout(){ - debug("on_terminal_contents_changed_timeout"); - if(this.terminal_contents_changed_timer!=0){ - this.terminal_contents_changed_timer=0; - this.user_notify=true; - } - return false;//stop timer - } + this.markup_prelight=replace_color_in_markup(this,(this.prevent_close ? "[!] " : "")+""+result2+"",StateFlags.PRELIGHT); + //this.markup_prelight = result;//""+result+""; + + if(this.active) + this.label.set_markup(this.markup_active); + else + this.label.set_markup(this.markup_normal); + + return true; + } + + public override void get_preferred_width (out int minimum_width, out int natural_width) { + int max_width=-1; + /* if label ellipsized, then normal size will be in natural_width + * but because we use this.width_request as maximum width, + * natural_width will be equal to width_request + * */ + base.get_preferred_width (out minimum_width, out natural_width); + + //set limit if configured + if(this.conf_max_width>0) + max_width=this.conf_max_width; + //use this.width_request as limiting size from hvbox + if( (this.width_request>0 && + this.conf_max_width>0 && + this.width_request0 && this.conf_max_width<1) ){ + max_width=this.width_request; + } + //debug("VTToggleButton1 max_width=%d minimum_width=%d,natural_width=%d ele=%d width_request=%d",max_width,minimum_width,natural_width,this.label.ellipsize,this.width_request); + /*limit width if necessary*/ + if(max_width>0 && natural_width>max_width){ + if(this.label.ellipsize != Pango.EllipsizeMode.MIDDLE) + this.label.ellipsize = Pango.EllipsizeMode.MIDDLE;//limit label size,queue resize (hardcoded in label) + natural_width=minimum_width=max_width;//return limited size + this.has_tooltip=true; + }else{ + if(this.label.ellipsize != Pango.EllipsizeMode.NONE) + this.label.ellipsize = Pango.EllipsizeMode.NONE;//reset limit,queue resize (hardcoded in label) + minimum_width = natural_width; + this.has_tooltip=false; + if(this.width_request>0) + this.width_request=-1;//reset it if size is ok + } + //debug("VTToggleButton2 max_width=%d minimum_width=%d,natural_width=%d ele=%d width_request=%d",max_width,minimum_width,natural_width,this.label.ellipsize,this.width_request); + } + + public override void get_preferred_height (out int minimum_height, out int natural_height) { + var tmp = this.label.ellipsize; + this.label.ellipsize = Pango.EllipsizeMode.NONE; + base.get_preferred_height (out minimum_height, out natural_height); + this.label.ellipsize = tmp; + } + + public void reconfigure(){ + unowned Gtk.StyleContext context = this.get_style_context(); + context.invalidate(); + this.force_update_tab_title=true; + this.set_title(this.tab_index,this.tab_title);//force update title + } + + public void check_for_notify(){ + if(!this.active && !this.user_notify){ + debug("terminal_contents_changed"); + if(this.terminal_contents_changed_timer!=0) + GLib.Source.remove(this.terminal_contents_changed_timer); + this.terminal_contents_changed_timer=GLib.Timeout.add_seconds(this.notify_timeout,this.on_terminal_contents_changed_timeout); + } + } + + public bool on_terminal_contents_changed_timeout(){ + debug("on_terminal_contents_changed_timeout"); + if(this.terminal_contents_changed_timer!=0){ + this.terminal_contents_changed_timer=0; + this.user_notify=true; + } + return false;//stop timer + } }//private class VTToggleButton public class AYTab : Object{ - public HBox hbox; - public Scrollbar scrollbar; - public VTToggleButton tbutton; - public int page_index = -1; - public Notebook notebook; - public unowned MySettings my_conf; - private uint remove_timer = 0; - public signal void on_remove_timeout(AYTab self); - public uint destroe_delay = 0; - public signal void on_destroy (); - - public AYTab(MySettings my_conf,Notebook notebook, uint tab_index /*starting from 0*/) { - this.my_conf=my_conf; - this.notebook=notebook; - this.tbutton = new VTToggleButton(); - - - this.tbutton.can_focus=false;//vte shoud have focus - this.tbutton.can_default = false; //encrease size - this.tbutton.has_focus = false; //encrease size - this.tbutton.set_use_underline(false); - this.tbutton.set_focus_on_click(false); - this.tbutton.set_has_window (false); - this.tbutton.tab_index=tab_index; - this.tbutton.show(); - this.configure(my_conf); - //this.tbutton.set_title(tab_index,null); - - - this.hbox = new HBox(false, 0); - this.hbox.halign=Gtk.Align.FILL; - this.hbox.valign=Gtk.Align.FILL; - this.hbox.expand=false; - //this.hbox.pack_start(this.vte_term,true,true,0); - //this.vte_term.grab_focus(); - //this.vte_term.can_default=true; - this.hbox.show(); -//~ this.scrollbar = new VScrollbar(((Scrollable)this.vte_term).get_vadjustment()); -//~ hbox.pack_start(scrollbar,false,false,0); - page_index = this.notebook.insert_page (hbox,null,(int)tab_index); - - this.tbutton.object = this; - - this.my_conf.on_load.connect(()=>{ - this.configure(this.my_conf); - }); - - this.hbox.destroy.connect(()=>{ debug("AYTab hbox destroyed"); }); - } - - public void destroy(){ - this.on_destroy();//emit signal - this.hbox.hide(); - this.notebook.remove_page(this.notebook.page_num(this.hbox)); - this.hbox.destroy();//destroy all widgets and unref self - } - -//~ public override void dispose(){ debug("AYTab dispose"); } - - private void configure(MySettings my_conf){ - this.tbutton.tab_format = my_conf.get_string("tab_format","[ _INDEX_ ]",(ref new_val)=>{ - string err; - if(!my_conf.check_markup(replace_color_in_markup(this.tbutton,new_val),out err)){ - debug(_("tab_format wrong value! will be used default value. err:%s"),err); - return CFG_CHECK.USE_DEFAULT; - } - - return CFG_CHECK.OK; - }); - - this.tbutton.tab_title_format = my_conf.get_string("tab_title_format","_INDEX_/_TITLE_|",(ref new_val)=>{ - string err; - if(!my_conf.check_markup(replace_color_in_markup(this.tbutton,new_val),out err)){ - debug(_("tab_title_format wrong value! will be used default value. err:%s"),err); - return CFG_CHECK.USE_DEFAULT; - } - - return CFG_CHECK.OK; - }); - this.tbutton.tab_title_regex = my_conf.get_string_list("tab_title_format_regex",{"^(mc) \\[","_REPLACE_ ","([\\w\\.]+)@","_USER_@","@([\\w\\.\\-]+)\\]?:(?!/{2})","@_HOSTNAME_:","([^:]*)$","_PATH_"},(ref new_val)=>{ - if(new_val!=null && (new_val.length % 2)!=0){ - debug(_("tab_title_format_regex odd value of array length! will be used default value.")); - return CFG_CHECK.USE_DEFAULT; - } - for(int i=0; i{ - if(new_val<-1){new_val=-1;return CFG_CHECK.REPLACE;} - return CFG_CHECK.OK; - }); - - this.destroe_delay = my_conf.get_integer("window_tab_destroy_delay",10,(ref new_val)=>{ - if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} - return CFG_CHECK.OK; - }); - - this.tbutton.reconfigure(); - } - - public bool timer_on_remove_timeout(){ - debug("tab will be destroyed"); - this.on_remove_timeout(this); - this.destroy(); - return false;//stop timer - } - - public void start_remove_timer(){ - if(this.remove_timer!=0) - GLib.Source.remove(this.remove_timer); - this.remove_timer=GLib.Timeout.add_seconds(this.destroe_delay,this.timer_on_remove_timeout); - }//start_remove_timer - - public void stop_remove_timer(){ - if(this.remove_timer!=0) - GLib.Source.remove(this.remove_timer); - this.remove_timer=0; - } + public HBox hbox; + public Scrollbar scrollbar; + public VTToggleButton tbutton; + public int page_index = -1; + public Notebook notebook; + public unowned MySettings my_conf; + private uint remove_timer = 0; + public signal void on_remove_timeout(AYTab self); + public uint destroe_delay = 0; + public signal void on_destroy (); + + public AYTab(MySettings my_conf,Notebook notebook, uint tab_index /*starting from 0*/) { + this.my_conf=my_conf; + this.notebook=notebook; + this.tbutton = new VTToggleButton(); + + + this.tbutton.can_focus=false;//vte shoud have focus + this.tbutton.can_default = false; //encrease size + this.tbutton.has_focus = false; //encrease size + this.tbutton.set_use_underline(false); + this.tbutton.set_focus_on_click(false); + this.tbutton.set_has_window (false); + this.tbutton.tab_index=tab_index; + this.tbutton.show(); + this.configure(my_conf); + //this.tbutton.set_title(tab_index,null); + + + this.hbox = new HBox(false, 0); + this.hbox.halign=Gtk.Align.FILL; + this.hbox.valign=Gtk.Align.FILL; + this.hbox.expand=false; + //this.hbox.pack_start(this.vte_term,true,true,0); + //this.vte_term.grab_focus(); + //this.vte_term.can_default=true; + this.hbox.show(); +//~ this.scrollbar = new VScrollbar(((Scrollable)this.vte_term).get_vadjustment()); +//~ hbox.pack_start(scrollbar,false,false,0); + page_index = this.notebook.insert_page (hbox,null,(int)tab_index); + + this.tbutton.object = this; + + this.my_conf.on_load.connect(()=>{ + this.configure(this.my_conf); + }); + + this.hbox.destroy.connect(()=>{ debug("AYTab hbox destroyed"); }); + } + + public void destroy(){ + this.on_destroy();//emit signal + this.hbox.hide(); + this.notebook.remove_page(this.notebook.page_num(this.hbox)); + this.hbox.destroy();//destroy all widgets and unref self + } + +//~ public override void dispose(){ debug("AYTab dispose"); } + + private void configure(MySettings my_conf){ + this.tbutton.tab_format = my_conf.get_string("tab_format","[ _INDEX_ ]",(ref new_val)=>{ + string err; + if(!my_conf.check_markup(replace_color_in_markup(this.tbutton,new_val),out err)){ + debug(_("tab_format wrong value! will be used default value. err:%s"),err); + return CFG_CHECK.USE_DEFAULT; + } + + return CFG_CHECK.OK; + }); + + this.tbutton.tab_title_format = my_conf.get_string("tab_title_format","_INDEX_/_TITLE_|",(ref new_val)=>{ + string err; + if(!my_conf.check_markup(replace_color_in_markup(this.tbutton,new_val),out err)){ + debug(_("tab_title_format wrong value! will be used default value. err:%s"),err); + return CFG_CHECK.USE_DEFAULT; + } + + return CFG_CHECK.OK; + }); + this.tbutton.tab_title_regex = my_conf.get_string_list("tab_title_format_regex",{"^(mc) \\[","_REPLACE_ ","([\\w\\.]+)@","_USER_@","@([\\w\\.\\-]+)\\]?:(?!/{2})","@_HOSTNAME_:","([^:]*)$","_PATH_"},(ref new_val)=>{ + if(new_val!=null && (new_val.length % 2)!=0){ + debug(_("tab_title_format_regex odd value of array length! will be used default value.")); + return CFG_CHECK.USE_DEFAULT; + } + for(int i=0; i{ + if(new_val<-1){new_val=-1;return CFG_CHECK.REPLACE;} + return CFG_CHECK.OK; + }); + + this.destroe_delay = my_conf.get_integer("window_tab_destroy_delay",10,(ref new_val)=>{ + if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} + return CFG_CHECK.OK; + }); + + this.tbutton.reconfigure(); + } + + public bool timer_on_remove_timeout(){ + debug("tab will be destroyed"); + this.on_remove_timeout(this); + this.destroy(); + return false;//stop timer + } + + public void start_remove_timer(){ + if(this.remove_timer!=0) + GLib.Source.remove(this.remove_timer); + this.remove_timer=GLib.Timeout.add_seconds(this.destroe_delay,this.timer_on_remove_timeout); + }//start_remove_timer + + public void stop_remove_timer(){ + if(this.remove_timer!=0) + GLib.Source.remove(this.remove_timer); + this.remove_timer=0; + } } public class term_colors_t { @@ -540,69 +540,69 @@ extern unowned GLib.ParamSpec param_spec_boxed(string name,string nick,string bl public class AYTerm : Vte.Terminal{ - static construct { - int i=0; - for(i=0;i<16;i++){ - install_style_property (param_spec_boxed ("palette-%0d".printf(i), - null, null, - typeof(Gdk.RGBA), - GLib.ParamFlags.READABLE)); - } - install_style_property (param_spec_boxed ("fg-color", - null, null, - typeof(Gdk.RGBA), - GLib.ParamFlags.READABLE)); - install_style_property (param_spec_boxed ("bg-color", - null, null, - typeof(Gdk.RGBA), - GLib.ParamFlags.READABLE)); - }//construct - -//~ public override void style_updated (){ -//~ base.style_updated (); -//~ this.update_style(); -//~ } - - private bool get_style_color(string name,ref Gdk.RGBA color){ - unowned Gdk.RGBA? tmp; - this.style_get(name,out tmp); - if(tmp!=null){ - color=tmp; - debug("AYTerm: %s:%s",name,color.to_string()); - tmp.free(); - return true; - }else - debug("AYTerm: css color \"%s\" not found ",name); - return false; - } + static construct { + int i=0; + for(i=0;i<16;i++){ + install_style_property (param_spec_boxed ("palette-%0d".printf(i), + null, null, + typeof(Gdk.RGBA), + GLib.ParamFlags.READABLE)); + } + install_style_property (param_spec_boxed ("fg-color", + null, null, + typeof(Gdk.RGBA), + GLib.ParamFlags.READABLE)); + install_style_property (param_spec_boxed ("bg-color", + null, null, + typeof(Gdk.RGBA), + GLib.ParamFlags.READABLE)); + }//construct + +//~ public override void style_updated (){ +//~ base.style_updated (); +//~ this.update_style(); +//~ } + + private bool get_style_color(string name,ref Gdk.RGBA color){ + unowned Gdk.RGBA? tmp; + this.style_get(name,out tmp); + if(tmp!=null){ + color=tmp; + debug("AYTerm: %s:%s",name,color.to_string()); + tmp.free(); + return true; + }else + debug("AYTerm: css color \"%s\" not found ",name); + return false; + } public void gen_colors(term_colors_t tct){ - int i; - Gdk.RGBA c={0}; - for(i=0;i{ -//~ this.update_style(); -//~ }); - } + }//update_style + + public AYTerm(){ +//~ this.update_style(); +//~ var context = this.get_style_context (); +//~ context.changed.connect(()=>{ +//~ this.update_style(); +//~ }); + } } public class VTTerminal : AYTab{ - public AYTerm vte_term {get; set; default = null;} - public Pid pid {get; set; default = -1;} - public bool auto_restart {get; set; default = true;} - public bool match_case {get; set; default = false;} - private OnChildExitCallBack on_child_exit {get; set; default = null;} - private HashTable match_tags; - public string session_command {get;set;default=null;} - public string session_path {get;set;default=null;} - private string? last_link; - private int? last_tag; - private bool disable_terminal_popup=false; - private Array lock_settings; - - - public VTTerminal(MySettings my_conf,Notebook notebook, uint tab_index/*starting from 0*/,string? session_command=null,string? session_path=null,OnChildExitCallBack? on_child_exit=null) { - base(my_conf, notebook, tab_index); - this.my_conf=my_conf; - this.notebook=notebook; - this.session_command=session_command; - this.session_path=session_path; - this.lock_settings = new Array (); - - if(on_child_exit!=null) - this.on_child_exit=on_child_exit; - - this.match_tags = new HashTable (direct_hash, direct_equal); - this.vte_term = new AYTerm(); - this.vte_term.halign=Gtk.Align.FILL; - this.vte_term.valign=Gtk.Align.FILL; - this.vte_term.expand=false; - /*this.vte_term.size_allocate.connect((allocation)=>{ - debug("[screen %p] size-alloc %d : %d at (%d, %d)\n", + public AYTerm vte_term {get; set; default = null;} + public Pid pid {get; set; default = -1;} + public bool auto_restart {get; set; default = true;} + public bool match_case {get; set; default = false;} + private OnChildExitCallBack on_child_exit {get; set; default = null;} + private HashTable match_tags; + public string session_command {get;set;default=null;} + public string session_path {get;set;default=null;} + private string? last_link; + private int? last_tag; + private bool disable_terminal_popup=false; + private Array lock_settings; + + + public VTTerminal(MySettings my_conf,Notebook notebook, uint tab_index/*starting from 0*/,string? session_command=null,string? session_path=null,OnChildExitCallBack? on_child_exit=null) { + base(my_conf, notebook, tab_index); + this.my_conf=my_conf; + this.notebook=notebook; + this.session_command=session_command; + this.session_path=session_path; + this.lock_settings = new Array (); + + if(on_child_exit!=null) + this.on_child_exit=on_child_exit; + + this.match_tags = new HashTable (direct_hash, direct_equal); + this.vte_term = new AYTerm(); + this.vte_term.halign=Gtk.Align.FILL; + this.vte_term.valign=Gtk.Align.FILL; + this.vte_term.expand=false; + /*this.vte_term.size_allocate.connect((allocation)=>{ + debug("[screen %p] size-alloc %d : %d at (%d, %d)\n", this.vte_term, allocation.width, allocation.height, allocation.x, allocation.y); - });*/ + });*/ - /*this.vte_term.size_request.connect((req)=>{ - debug("[window %p] size-request result %d : %d\n", + /*this.vte_term.size_request.connect((req)=>{ + debug("[window %p] size-request result %d : %d\n", this.vte_term, req.width, req.height); - });*/ - - - this.vte_term.child_exited.connect(this.child_exited); - - this.hbox.pack_start(this.vte_term,true,true,0); - //this.vte_term.grab_focus(); - //this.vte_term.can_default=true; - this.scrollbar = new VScrollbar(((Scrollable)this.vte_term).get_vadjustment()); - hbox.pack_start(scrollbar,false,false,0); - this.vte_term.search_set_wrap_around(my_conf.get_boolean("search_wrap_around",true)); - this.match_case =my_conf.get_boolean("search_match_case",this.match_case); - this.my_conf.on_load.connect(()=>{ - this.configure(this.my_conf); - }); - - this.vte_term.button_press_event.connect(vte_button_press_event); - this.tbutton.button_press_event.connect(vttoggle_button_press_event); - this.configure(my_conf); - //GLib.Idle.add(call); - - this.start_shell(); - - this.hbox.show(); - this.vte_term.destroy.connect(()=>{ debug("VTTerminal vte_term destroyed"); }); - this.on_destroy.connect(()=>{ - this.vte_term.child_exited.disconnect(this.child_exited); - debug("VTTerminal destroyed"); - }); - } - - public void start_shell(){ - if(!this.start_command(this.session_command,this.session_path)){ - if(!this.start_command()){//try without session - this.my_conf.set_string("custom_command",""); - if(!this.start_command()){//try without custom_command - debug("Unable to run shell command!"); - Gtk.main_quit(); - } - } - } - } - - - public bool start_command(string? session_command = null,string? session_path=null){ - PtyFlags pty_flags = PtyFlags.DEFAULT; - GLib.SpawnFlags spawn_flags = 0; - string? command = null; - string[] argvp; - - bool run_as_login_shell = this.my_conf.get_boolean("terminal_run_as_login_shell",false); - - if(!run_as_login_shell){ - pty_flags |= PtyFlags.NO_LASTLOG; - } - - if(!this.my_conf.get_boolean("terminal_update_login_records",false)){ - pty_flags |= PtyFlags.NO_UTMP | PtyFlags.NO_WTMP; - } - - if(session_command != null && session_command != ""){ - command = session_command; - spawn_flags |= GLib.SpawnFlags.SEARCH_PATH; - try { - GLib.Shell.parse_argv(command,out argvp); - }catch (ShellError e) { - error("Error: %s", e.message); - } - }else{ - command = this.my_conf.get_string("custom_command",""); - if(command == null || command == "") - command = GLib.Environment.get_variable ("SHELL"); - - if(command==null) - command = "/bin/sh"; - - try { - GLib.Shell.parse_argv(command,out argvp); - }catch (ShellError e) { - error("Error: %s", e.message); - } - - if(run_as_login_shell){ - spawn_flags |= GLib.SpawnFlags.FILE_AND_ARGV_ZERO; - argvp+="-%s".printf(GLib.Path.get_basename(command)); - }else - spawn_flags |= GLib.SpawnFlags.SEARCH_PATH; - } - - debug("run command:%s",command); - - string path=""; - if(session_path==null || session_path==""){ - path = GLib.Environment.get_current_dir(); - }else{ - path = session_path; - } - if(path==null) - path="/"; - - - /*(Vte.PtyFlags pty_flags, - * string? working_directory, - * string[] argv, - * string[]? envv, - * GLib.SpawnFlags spawn_flags, - * GLib.SpawnChildSetupFunc? child_setup, - * out GLib.Pid child_pid)*/ - Pid child_pid; - string?[] envv = {}; - string[] args = GLib.Environment.list_variables (); - string term_var = this.my_conf.get_string("terminal_term_variable","xterm",(ref new_val)=>{ - if(new_val==""){new_val="xterm";return CFG_CHECK.REPLACE;} - return CFG_CHECK.OK; - }); - string term_exclude_vars = this.my_conf.get_string("terminal_exclude_variables","^(COLUMNS|LINES|GNOME_DESKTOP_ICON|COLORTERM|WINDOWID)$",(ref new_val)=>{ - string err; - if(!this.my_conf.check_regex(new_val,out err) || new_val.strip() == ""){ //prevent empty regexp issue #36 - debug(_("terminal_exclude_variables wrong value! will be used default value. err:%s"),err); - return CFG_CHECK.USE_DEFAULT; - } - - return CFG_CHECK.OK; - }); - foreach(string arg in args){ - if(arg == "TERM" || - (arg == "GDK_CORE_DEVICE_EVENTS" && this.my_conf.get_boolean("workaround_if_focuslost",false) ) ){ - continue;//skip - }else - if( !GLib.Regex.match_simple(term_exclude_vars,arg,RegexCompileFlags.CASELESS,0) ){ - unowned string val=GLib.Environment.get_variable(arg); - string s="%s=%s".printf(arg,(val!=null?val:"")); - envv+=s; - }else{ - debug("exclude:%s",arg); - } - } - envv+="TERM="+term_var; - envv+="COLORTERM="+GLib.Environment.get_prgname(); - envv+=null; - bool ret=false; - //var ret = this.vte_term.fork_command_full(pty_flags ,path,argvp,envv,spawn_flags,null,out p); - //don't use fork_command_full because with it, is not possible to set up TERM variable - #if ! VTE_2_91 - Vte.Pty pty = this.vte_term.pty_new(pty_flags); - #else - Vte.Pty pty = new Vte.Pty.sync(pty_flags); - #endif - spawn_flags |= GLib.SpawnFlags.CHILD_INHERITS_STDIN; - spawn_flags |= GLib.SpawnFlags.DO_NOT_REAP_CHILD; - try{ + });*/ + + + this.vte_term.child_exited.connect(this.child_exited); + + this.hbox.pack_start(this.vte_term,true,true,0); + //this.vte_term.grab_focus(); + //this.vte_term.can_default=true; + this.scrollbar = new VScrollbar(((Scrollable)this.vte_term).get_vadjustment()); + hbox.pack_start(scrollbar,false,false,0); + this.vte_term.search_set_wrap_around(my_conf.get_boolean("search_wrap_around",true)); + this.match_case =my_conf.get_boolean("search_match_case",this.match_case); + this.my_conf.on_load.connect(()=>{ + this.configure(this.my_conf); + }); + + this.vte_term.button_press_event.connect(vte_button_press_event); + this.tbutton.button_press_event.connect(vttoggle_button_press_event); + this.configure(my_conf); + //GLib.Idle.add(call); + + this.start_shell(); + + this.hbox.show(); + this.vte_term.destroy.connect(()=>{ debug("VTTerminal vte_term destroyed"); }); + this.on_destroy.connect(()=>{ + this.vte_term.child_exited.disconnect(this.child_exited); + debug("VTTerminal destroyed"); + }); + } + + public void start_shell(){ + if(!this.start_command(this.session_command,this.session_path)){ + if(!this.start_command()){//try without session + this.my_conf.set_string("custom_command",""); + if(!this.start_command()){//try without custom_command + debug("Unable to run shell command!"); + Gtk.main_quit(); + } + } + } + } + + + public bool start_command(string? session_command = null,string? session_path=null){ + PtyFlags pty_flags = PtyFlags.DEFAULT; + GLib.SpawnFlags spawn_flags = 0; + string? command = null; + string[] argvp; + + bool run_as_login_shell = this.my_conf.get_boolean("terminal_run_as_login_shell",false); + + if(!run_as_login_shell){ + pty_flags |= PtyFlags.NO_LASTLOG; + } + + if(!this.my_conf.get_boolean("terminal_update_login_records",false)){ + pty_flags |= PtyFlags.NO_UTMP | PtyFlags.NO_WTMP; + } + + if(session_command != null && session_command != ""){ + command = session_command; + spawn_flags |= GLib.SpawnFlags.SEARCH_PATH; + try { + GLib.Shell.parse_argv(command,out argvp); + }catch (ShellError e) { + error("Error: %s", e.message); + } + }else{ + command = this.my_conf.get_string("custom_command",""); + if(command == null || command == "") + command = GLib.Environment.get_variable ("SHELL"); + + if(command==null) + command = "/bin/sh"; + + try { + GLib.Shell.parse_argv(command,out argvp); + }catch (ShellError e) { + error("Error: %s", e.message); + } + + if(run_as_login_shell){ + spawn_flags |= GLib.SpawnFlags.FILE_AND_ARGV_ZERO; + argvp+="-%s".printf(GLib.Path.get_basename(command)); + }else + spawn_flags |= GLib.SpawnFlags.SEARCH_PATH; + } + + debug("run command:%s",command); + + string path=""; + if(session_path==null || session_path==""){ + path = GLib.Environment.get_current_dir(); + }else{ + path = session_path; + } + if(path==null) + path="/"; + + + /*(Vte.PtyFlags pty_flags, + * string? working_directory, + * string[] argv, + * string[]? envv, + * GLib.SpawnFlags spawn_flags, + * GLib.SpawnChildSetupFunc? child_setup, + * out GLib.Pid child_pid)*/ + Pid child_pid; + string?[] envv = {}; + string[] args = GLib.Environment.list_variables (); + string term_var = this.my_conf.get_string("terminal_term_variable","xterm",(ref new_val)=>{ + if(new_val==""){new_val="xterm";return CFG_CHECK.REPLACE;} + return CFG_CHECK.OK; + }); + string term_exclude_vars = this.my_conf.get_string("terminal_exclude_variables","^(COLUMNS|LINES|GNOME_DESKTOP_ICON|COLORTERM|WINDOWID)$",(ref new_val)=>{ + string err; + if(!this.my_conf.check_regex(new_val,out err) || new_val.strip() == ""){ //prevent empty regexp issue #36 + debug(_("terminal_exclude_variables wrong value! will be used default value. err:%s"),err); + return CFG_CHECK.USE_DEFAULT; + } + + return CFG_CHECK.OK; + }); + foreach(string arg in args){ + if(arg == "TERM" || + (arg == "GDK_CORE_DEVICE_EVENTS" && this.my_conf.get_boolean("workaround_if_focuslost",false) ) ){ + continue;//skip + }else + if( !GLib.Regex.match_simple(term_exclude_vars,arg,RegexCompileFlags.CASELESS,0) ){ + unowned string val=GLib.Environment.get_variable(arg); + string s="%s=%s".printf(arg,(val!=null?val:"")); + envv+=s; + }else{ + debug("exclude:%s",arg); + } + } + envv+="TERM="+term_var; + envv+="COLORTERM="+GLib.Environment.get_prgname(); + envv+=null; + bool ret=false; + //var ret = this.vte_term.fork_command_full(pty_flags ,path,argvp,envv,spawn_flags,null,out p); + //don't use fork_command_full because with it, is not possible to set up TERM variable + #if ! VTE_2_91 + Vte.Pty pty = this.vte_term.pty_new(pty_flags); + #else + Vte.Pty pty = new Vte.Pty.sync(pty_flags); + #endif + spawn_flags |= GLib.SpawnFlags.CHILD_INHERITS_STDIN; + spawn_flags |= GLib.SpawnFlags.DO_NOT_REAP_CHILD; + try{ ret = GLib.Process.spawn_async_with_pipes(path, argvp, envv, spawn_flags, (GLib.SpawnChildSetupFunc) pty.child_setup, out child_pid, null, null, null); - }catch(GLib.SpawnError.CHDIR err){ - /* try spawning in our working directory */ - if(path!=null) - ret = GLib.Process.spawn_async_with_pipes(null, - argvp, envv, - spawn_flags, - (GLib.SpawnChildSetupFunc) pty.child_setup, - out child_pid, - null, null, null); - } - - if(ret==true){ - #if ! VTE_2_91 - this.vte_term.set_pty_object(pty); - #else - this.vte_term.pty = pty; - #endif - this.vte_term.watch_child(child_pid); - this.pid=child_pid; - } - - return ret; - } - - public void child_exited(){ - if(this.on_child_exit!=null) - this.on_child_exit(this); - } - - private void configure(MySettings my_conf){ - uint path_length=0; - string spath = ""; - string spath_reversed = ""; - - if(my_conf.get_boolean("terminal_show_scrollbar",true)) - this.scrollbar.show(); - else - this.scrollbar.hide(); - - -//~ StyleContext style = this.tbutton.get_style_context ();//new StyleContext ();// -//~ var css = new CssProvider (); - -// "HVBox {border-radius: 0 0 4 4; background-image: none; margin:0; padding:0 ; border-width: 0 ;}"+ -// "VTToggleButton:active {-border-gradient: none; -outer-inner-width: 0; -outer-stroke-width: 0; background-image: none; margin:0; padding:5; background-color: @bg_color; border-color: #00DD00; border-width: 0 0 0 0;}"+ -// "* {color: #0000FF; border-radius: 0 0 4 4; background-image: none; margin:0; padding:0 ; border-width: 0 ;}"+ + }catch(GLib.SpawnError.CHDIR err){ + /* try spawning in our working directory */ + if(path!=null) + ret = GLib.Process.spawn_async_with_pipes(null, + argvp, envv, + spawn_flags, + (GLib.SpawnChildSetupFunc) pty.child_setup, + out child_pid, + null, null, null); + } + + if(ret==true){ + #if ! VTE_2_91 + this.vte_term.set_pty_object(pty); + #else + this.vte_term.pty = pty; + #endif + this.vte_term.watch_child(child_pid); + this.pid=child_pid; + } + + return ret; + } + + public void child_exited(){ + if(this.on_child_exit!=null) + this.on_child_exit(this); + } + + private void configure(MySettings my_conf){ + uint path_length=0; + string spath = ""; + string spath_reversed = ""; + + if(my_conf.get_boolean("terminal_show_scrollbar",true)) + this.scrollbar.show(); + else + this.scrollbar.hide(); + + +//~ StyleContext style = this.tbutton.get_style_context ();//new StyleContext ();// +//~ var css = new CssProvider (); + +// "HVBox {border-radius: 0 0 4 4; background-image: none; margin:0; padding:0 ; border-width: 0 ;}"+ +// "VTToggleButton:active {-border-gradient: none; -outer-inner-width: 0; -outer-stroke-width: 0; background-image: none; margin:0; padding:5; background-color: @bg_color; border-color: #00DD00; border-width: 0 0 0 0;}"+ +// "* {color: #0000FF; border-radius: 0 0 4 4; background-image: none; margin:0; padding:0 ; border-width: 0 ;}"+ //font:Ubuntu Mono 10; -//~ string style_str="VTToggleButton {font: \"Ubuntu Mono 8\"; -GtkWidget-focus-padding: 0px; -GtkButton-default-border:0px; -GtkButton-default-outside-border:0px; -GtkButton-inner-border:0px; border-width: 0px 0px 0px 0px; -outer-stroke-width: 0px; border-radius: 0px 0px 0px 0px; border-style: solid; background-image: none; margin:0px; padding:0px 3px 3px 3px; background-color: #000000; color: #AAAAAA; transition: 0ms ease-in-out;}"+ -//~ "VTToggleButton:active {font: \"Ubuntu Mono 8\"; -GtkWidget-focus-padding: 0px; -GtkButton-default-border:0px; -GtkButton-default-outside-border:0px; -GtkButton-inner-border:0px; border-width: 0px 0px 0px 0px; -outer-stroke-width: 0px; border-radius: 0px 0px 0px 0px; border-style: solid; background-image: none; margin:0px; padding:0px 3px 3px 3px; background-color: #00AAAA; color: #000000; transition: 0ms ease-in-out;}"+ -//~ "VTToggleButton:prelight {font: \"Ubuntu Mono 8\"; -GtkWidget-focus-padding: 0px; -GtkButton-default-border:0px; -GtkButton-default-outside-border:0px; -GtkButton-inner-border:0px; border-width: 0px 0px 0px 0px; -outer-stroke-width: 0px; border-radius: 0px 0px 0px 0px; border-style: solid; background-image: none; margin:0px; padding:0px 3px 3px 3px; background-color: #AAAAAA; color: #000000; transition: 0ms ease-in-out;}"+ -//~ ""; -//~ css.load_from_data (this.my_conf.get_string("tbutton_style",style_str),-1); +//~ string style_str="VTToggleButton {font: \"Ubuntu Mono 8\"; -GtkWidget-focus-padding: 0px; -GtkButton-default-border:0px; -GtkButton-default-outside-border:0px; -GtkButton-inner-border:0px; border-width: 0px 0px 0px 0px; -outer-stroke-width: 0px; border-radius: 0px 0px 0px 0px; border-style: solid; background-image: none; margin:0px; padding:0px 3px 3px 3px; background-color: #000000; color: #AAAAAA; transition: 0ms ease-in-out;}"+ +//~ "VTToggleButton:active {font: \"Ubuntu Mono 8\"; -GtkWidget-focus-padding: 0px; -GtkButton-default-border:0px; -GtkButton-default-outside-border:0px; -GtkButton-inner-border:0px; border-width: 0px 0px 0px 0px; -outer-stroke-width: 0px; border-radius: 0px 0px 0px 0px; border-style: solid; background-image: none; margin:0px; padding:0px 3px 3px 3px; background-color: #00AAAA; color: #000000; transition: 0ms ease-in-out;}"+ +//~ "VTToggleButton:prelight {font: \"Ubuntu Mono 8\"; -GtkWidget-focus-padding: 0px; -GtkButton-default-border:0px; -GtkButton-default-outside-border:0px; -GtkButton-inner-border:0px; border-width: 0px 0px 0px 0px; -outer-stroke-width: 0px; border-radius: 0px 0px 0px 0px; border-style: solid; background-image: none; margin:0px; padding:0px 3px 3px 3px; background-color: #AAAAAA; color: #000000; transition: 0ms ease-in-out;}"+ +//~ ""; +//~ css.load_from_data (this.my_conf.get_string("tbutton_style",style_str),-1); /* ".background {"+ "background-color: #FF0000;"+ @@ -895,905 +895,905 @@ public class VTTerminal : AYTab{ "VTToggleButton:active:hover{background-color: #00FF00;}"+ */ - //style.remove_class ("*"); - - //style.add_class("GtkToolbarButton"); - - //style.add_provider(css,900); - - //var wpath = new WidgetPath(); - //wpath.append_type(typeof(Gtk.Window)); - //wpath.append_type(typeof(Gtk.MenuItem)); - //wpath.iter_add_region (0, "tab", RegionFlags.FIRST|RegionFlags.EVEN) ; - //style.set_path(wpath); - //tbutton.reset_style();//set_style(style); - - //this.tbutton.path(out path_length,out spath,out spath_reversed); - //debug("\t tbutton.path=%s",spath); - //new Pango.FontDescription(); - - Pango.FontDescription font_description = Pango.FontDescription.from_string (my_conf.get_string("terminal_font","Mono 12")) ; - - this.vte_term.set_font(font_description);//same color for terminal - this.auto_restart=my_conf.get_boolean("terminal_auto_restart_shell",true); - - #if ALTERNATE_SCREEN_SCROLL && ! VTE_2_91 - if(my_conf.DISTR_ID==DISTRIB_ID.UBUNTU){ - //debian patch vte_terminal_set_alternate_screen_scroll - this.vte_term.set_alternate_screen_scroll(my_conf.get_boolean("terminal_set_alternate_screen_scroll",true)); - } - #endif - - this.vte_term.set_scrollback_lines (my_conf.get_integer("terminal_scrollback_lines",512,(ref new_val)=>{ - if(new_val<-1){new_val=-1;return CFG_CHECK.REPLACE;}//infinite scrollback - return CFG_CHECK.OK; - })); - - #if ! VTE_2_91 - var bg_img_file = my_conf.get_string("terminal_background_image_file",""); - if(bg_img_file!=null && bg_img_file!="" && GLib.FileUtils.test(bg_img_file,GLib.FileTest.EXISTS)){ - message("set_background_image_file=%s",bg_img_file); - this.vte_term.set_background_image_file (bg_img_file); - }else - this.vte_term.set_background_image_file ("/dev/null"); - - var bg_faket = my_conf.get_boolean("terminal_background_fake_transparent",false); - - this.vte_term.set_scroll_background(my_conf.get_boolean("terminal_background_fake_transparent_scroll",false)); - Gdk.Color? tint;//currently libvte don't support rgba tint - if(Gdk.Color.parse(my_conf.get_string("terminal_tint_color","#000000"),out tint)) - this.vte_term.set_background_tint_color(tint); - - var sat = my_conf.get_double("terminal_background_saturation",0.5,(ref new_val)=>{ - if(new_val>1){ new_val=1; return CFG_CHECK.REPLACE;} - if(new_val<0){ new_val=0; return CFG_CHECK.REPLACE;} - return CFG_CHECK.OK; - }); - this.vte_term.set_background_saturation(sat); - //if(bg_faket){ - this.vte_term.set_background_transparent(bg_faket);//fake transparent - //}//else{//moved -> this.vte_term.update_style(); - //set_background_transparent call vte_terminal_queue_background_update - //this.vte_term.set_background_transparent(true);//but only when changes - //this.vte_term.set_background_transparent(false);//but only when changes - //} - #endif - /*0-BLOCK,1-IBEAM,2-UNDERLINE*/ - var cursorshape = my_conf.get_integer("terminal_cursorshape",0,(ref new_val)=>{ - if(new_val>2){new_val=0;return CFG_CHECK.REPLACE;} - if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} - return CFG_CHECK.OK; - }); - #if ! VTE_2_91 - this.vte_term.set_cursor_shape((Vte.TerminalCursorShape)cursorshape); - #else - this.vte_term.set_cursor_shape((Vte.CursorShape)cursorshape); - #endif - /*0-SYSTEM,1-ON,2-OFF*/ - var cursor_blinkmode = my_conf.get_integer("terminal_cursor_blinkmode",0,(ref new_val)=>{ - if(new_val>2){new_val=0;return CFG_CHECK.REPLACE;} - if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} - return CFG_CHECK.OK; - }); - #if ! VTE_2_91 - this.vte_term.set_cursor_blink_mode ((Vte.TerminalCursorBlinkMode)cursor_blinkmode); - #else - this.vte_term.set_cursor_blink_mode ((Vte.CursorBlinkMode)cursor_blinkmode); - #endif - - if(!this.is_locked(VTT_LOCK_SETTING.DELETE_BINDING)){ - /*0-AUTO,1-BACKSPACE,2-DELETE,3-SEQUENCE,4-TTY*/ - var delbinding = my_conf.get_integer("terminal_delete_binding",0,(ref new_val)=>{ - if(new_val>4){new_val=0;return CFG_CHECK.REPLACE;} - if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} - return CFG_CHECK.OK; - }); - #if ! VTE_2_91 - this.vte_term.set_delete_binding ((Vte.TerminalEraseBinding)delbinding); - #else - this.vte_term.set_delete_binding ((Vte.EraseBinding)delbinding); - #endif - } - - if(!this.is_locked(VTT_LOCK_SETTING.BACKSPACE_BINDING)){ - /*0-AUTO,1-BACKSPACE,2-DELETE,3-SEQUENCE,4-TTY*/ - var backspace = my_conf.get_integer("terminal_backspace_binding",0,(ref new_val)=>{ - if(new_val>4){new_val=0;return CFG_CHECK.REPLACE;} - if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} - return CFG_CHECK.OK; - }); - #if ! VTE_2_91 - this.vte_term.set_backspace_binding ((Vte.TerminalEraseBinding)backspace); - #else - this.vte_term.set_backspace_binding ((Vte.EraseBinding)backspace); - #endif - } - - if(!this.is_locked(VTT_LOCK_SETTING.ENCODING)){ - /* default - is special value - * */ - var s = my_conf.get_string("terminal_default_encoding","default"); - if(s!="default"){ - #if ! VTE_2_91 - this.vte_term.set_encoding (s); - #else - this.vte_term.encoding=s; - #endif - }else - #if ! VTE_2_91 - this.vte_term.set_encoding (null);//reset to default - #else - this.vte_term.encoding=null; - #endif - } - - string[] url_regexps = my_conf.get_string_list("terminal_url_regexps",{"(\\\"\\s*)?((?i)http|https|ftp|sftp)\\://([a-zA-Z0-9\\-]+(\\.)?)+(:[0-9]+)?(/([a-zA-Z0-9\\(\\)\\[\\]\\{\\};\\!\\*'\"`\\:@&=\\+\\$\\,/\\?#\\-\\_\\.\\~%\\^<>\\|\\\\])*)?","xdg-open"},(ref new_val)=>{ - if(new_val!=null && (new_val.length % 2)!=0){ - debug(_("terminal_url_regexps odd value of array length! will be used default value.")); - return CFG_CHECK.USE_DEFAULT; - } - for(int j=0; j { - free(val); - }); - this.match_tags.steal_all(); - debug("url_regexps=%d",url_regexps.length); - for(int j=0;j{ - if(new_val>3){new_val=0;return CFG_CHECK.REPLACE;} - if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} - return CFG_CHECK.OK; - }); - this.vte_term.contents_changed.disconnect(this.tbutton.check_for_notify); - - if((notify & 1)==1) - this.vte_term.contents_changed.connect(this.tbutton.check_for_notify); - if((notify & 2)==2) - this.tbutton.notify_on_title_change=true; - else - this.tbutton.notify_on_title_change=false; - - this.tbutton.notify_timeout = my_conf.get_integer("terminal_timeout_before_notify",5,(ref new_val)=>{ - if(new_val>1440){new_val=1440;return CFG_CHECK.REPLACE;} - if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} - return CFG_CHECK.OK; - }); - this.disable_terminal_popup=my_conf.get_boolean("terminal_disable_popup_menu",false); - this.vte_term.update_style(); - - this.scrollbar.get_settings().gtk_primary_button_warps_slider=!my_conf.get_boolean("terminal_scroll_by_page",true); - }//configure - - public bool vte_button_press_event(Widget widget,Gdk.EventButton event) { - if(event.type==Gdk.EventType.BUTTON_PRESS){ - if(event.button==1 && (event.state & Gdk.ModifierType.CONTROL_MASK)==Gdk.ModifierType.CONTROL_MASK){ - this.check_match(event); - }else - if(event.button== 3 && !this.disable_terminal_popup){//right mouse button - this.popup_menu(event); - return true; - } - } - return false; //true == ignore event - } - - public bool vttoggle_button_press_event(Widget widget,Gdk.EventButton event) { - if(event.type==Gdk.EventType.BUTTON_PRESS){ -//~ if(event.button==1 && (event.state & Gdk.ModifierType.CONTROL_MASK)==Gdk.ModifierType.CONTROL_MASK){ -//~ this.check_match(event); -//~ }else - if(event.button== 3){//right mouse button - this.popup_tab_menu(event); - return true; - } - } - return false; //true == ignore event - } - - public void on_copy_link_activate(){ - Gtk.Clipboard clipboard = Gtk.Clipboard.get_for_display (Gdk.Display.get_default (), Gdk.SELECTION_CLIPBOARD); - clipboard.set_text (this.last_link, -1); - this.last_link=null; - } - - public void on_run_link_activate(){ - string tag_value=""; - if(last_tag!=null && this.match_tags.lookup_extended(this.last_tag,null,out tag_value) ){ - if( (this.last_link.get_char (0).to_string ()=="\"" && this.last_link.get_char (this.last_link.length-1).to_string ()=="\"") - || (this.last_link.get_char (0).to_string ()=="'" && this.last_link.get_char (this.last_link.length-1).to_string ()=="'" ) ){ - /*remove quotes if present at beggining and at the end - * example: " http://www.google.com/?q="denis"" - * */ - this.last_link=this.last_link.slice(1,this.last_link.length-1); - this.last_link=this.last_link.strip(); - } - debug("check_match run=%s params=%s",tag_value,this.last_link); - Posix.system(tag_value+" '"+this.last_link+"' &"); - } - this.last_tag=null; - } - - public void create_popup_menu(Gtk.Menu menu){ - //debug("popup_menu ref_count=%d",(int)menu.ref_count); - unowned Gtk.Widget parent; - parent = this.vte_term; - while(parent.parent!=null ){parent = parent.parent;} //find VTMainWindow - VTMainWindow vtw=(VTMainWindow)parent; - menu.set_accel_group(vtw.ayobject.accel_group); - Gtk.ActionGroup acg=vtw.ayobject.action_group; - - Gtk.MenuItem menuitem; - - menuitem = (Gtk.MenuItem)acg.get_action("terminal_copy_text").create_menu_item(); - menu.append(menuitem); - menuitem = (Gtk.MenuItem)acg.get_action("terminal_paste_text").create_menu_item(); - menu.append(menuitem); - - menuitem = new Gtk.SeparatorMenuItem(); - menu.append(menuitem); - - menuitem = (Gtk.MenuItem)acg.get_action("terminal_add_tab").create_menu_item(); - menu.append(menuitem); - menuitem = (Gtk.MenuItem)acg.get_action("terminal_close_tab").create_menu_item(); - menu.append(menuitem); - if(this.my_conf.standalone_mode){ - menuitem = (Gtk.MenuItem)acg.get_action("window_open_new_window").create_menu_item(); - menu.append(menuitem); - } - - vtw.ayobject.create_popup_menu_for_removed_tabs(menu); - - menuitem = (Gtk.MenuItem)acg.get_action("terminal_search_dialog").create_menu_item(); - menu.append(menuitem); - - menuitem = new Gtk.SeparatorMenuItem(); - menu.append(menuitem); - menuitem = (Gtk.MenuItem)acg.get_action("open_settings").create_menu_item(); - menu.append(menuitem); - - /**************************************************************/ - var submenu = new Gtk.Menu (); - - menuitem = (Gtk.MenuItem)acg.get_action("window_terminal_quick_settings").create_menu_item(); - submenu.append(menuitem); - - if(!this.my_conf.standalone_mode){ - menuitem = (Gtk.MenuItem)acg.get_action("follow_the_mouse").create_menu_item(); - submenu.append(menuitem); - - var action_keepabove = acg.get_action("keep_above") as ToggleAction; - action_keepabove.set_active(vtw.keep_above); - menuitem = (Gtk.MenuItem)action_keepabove.create_menu_item(); - submenu.append(menuitem); - - var action_stick = acg.get_action("window_toggle_stick") as ToggleAction; - action_stick.set_active(vtw.orig_stick); - menuitem = (Gtk.MenuItem)action_stick.create_menu_item(); - submenu.append(menuitem); - - var action_autohide = acg.get_action("window_toggle_autohide") as ToggleAction; - action_autohide.set_active(vtw.autohide); - menuitem = (Gtk.MenuItem)action_autohide.create_menu_item(); - submenu.append(menuitem); - - } - if(!this.my_conf.standalone_mode){ - menuitem = (Gtk.MenuItem)acg.get_action("window_open_new_window").create_menu_item(); - submenu.append(menuitem); - } - - menuitem = (Gtk.MenuItem)acg.get_action("terminal_copy_all_text").create_menu_item(); - submenu.append(menuitem); - - menuitem = new Gtk.MenuItem.with_label (_("Quick settings")); - menuitem.set_submenu(submenu); - menu.append(menuitem); - - menuitem = (Gtk.MenuItem)acg.get_action("altyo_about").create_menu_item(); - menu.append(menuitem); - - menuitem = new Gtk.SeparatorMenuItem(); - menu.append(menuitem); - - if(!this.my_conf.standalone_mode){ - menuitem = (Gtk.MenuItem)acg.get_action("main_hotkey").create_menu_item(); - menu.append(menuitem); - } - menuitem = (Gtk.MenuItem)acg.get_action("altyo_exit").create_menu_item(); - menu.append(menuitem); - } - - public void popup_menu(Gdk.EventButton event){ - //debug("terminal popup_menu"); - var menu = new Gtk.Menu(); - - Gtk.MenuItem menuitem; - - this.last_link=null; - this.last_tag=null; - string? match=this.get_match((int)event.x,(int)event.y,out this.last_tag); - if(match!=null){ - this.last_link=match; - menuitem = new Gtk.MenuItem.with_label (_("Copy link")); - menuitem.activate.connect(this.on_copy_link_activate); - menu.append(menuitem); - menuitem = new Gtk.MenuItem.with_label (_("Run link Ctrl+left mouse button")); - menuitem.activate.connect(this.on_run_link_activate); -//~ var label=menuitem.get_child() as Gtk.Label; -//~ label.set_justify( Gtk.Justification.RIGHT); -//~ label.set_pattern( "___ ___"); -//~ ((Gtk.Widget)menuitem).add_accelerator( "activate", vtw.ayobject.accel_group, + //style.remove_class ("*"); + + //style.add_class("GtkToolbarButton"); + + //style.add_provider(css,900); + + //var wpath = new WidgetPath(); + //wpath.append_type(typeof(Gtk.Window)); + //wpath.append_type(typeof(Gtk.MenuItem)); + //wpath.iter_add_region (0, "tab", RegionFlags.FIRST|RegionFlags.EVEN) ; + //style.set_path(wpath); + //tbutton.reset_style();//set_style(style); + + //this.tbutton.path(out path_length,out spath,out spath_reversed); + //debug("\t tbutton.path=%s",spath); + //new Pango.FontDescription(); + + Pango.FontDescription font_description = Pango.FontDescription.from_string (my_conf.get_string("terminal_font","Mono 12")) ; + + this.vte_term.set_font(font_description);//same color for terminal + this.auto_restart=my_conf.get_boolean("terminal_auto_restart_shell",true); + + #if ALTERNATE_SCREEN_SCROLL && ! VTE_2_91 + if(my_conf.DISTR_ID==DISTRIB_ID.UBUNTU){ + //debian patch vte_terminal_set_alternate_screen_scroll + this.vte_term.set_alternate_screen_scroll(my_conf.get_boolean("terminal_set_alternate_screen_scroll",true)); + } + #endif + + this.vte_term.set_scrollback_lines (my_conf.get_integer("terminal_scrollback_lines",512,(ref new_val)=>{ + if(new_val<-1){new_val=-1;return CFG_CHECK.REPLACE;}//infinite scrollback + return CFG_CHECK.OK; + })); + + #if ! VTE_2_91 + var bg_img_file = my_conf.get_string("terminal_background_image_file",""); + if(bg_img_file!=null && bg_img_file!="" && GLib.FileUtils.test(bg_img_file,GLib.FileTest.EXISTS)){ + message("set_background_image_file=%s",bg_img_file); + this.vte_term.set_background_image_file (bg_img_file); + }else + this.vte_term.set_background_image_file ("/dev/null"); + + var bg_faket = my_conf.get_boolean("terminal_background_fake_transparent",false); + + this.vte_term.set_scroll_background(my_conf.get_boolean("terminal_background_fake_transparent_scroll",false)); + Gdk.Color? tint;//currently libvte don't support rgba tint + if(Gdk.Color.parse(my_conf.get_string("terminal_tint_color","#000000"),out tint)) + this.vte_term.set_background_tint_color(tint); + + var sat = my_conf.get_double("terminal_background_saturation",0.5,(ref new_val)=>{ + if(new_val>1){ new_val=1; return CFG_CHECK.REPLACE;} + if(new_val<0){ new_val=0; return CFG_CHECK.REPLACE;} + return CFG_CHECK.OK; + }); + this.vte_term.set_background_saturation(sat); + //if(bg_faket){ + this.vte_term.set_background_transparent(bg_faket);//fake transparent + //}//else{//moved -> this.vte_term.update_style(); + //set_background_transparent call vte_terminal_queue_background_update + //this.vte_term.set_background_transparent(true);//but only when changes + //this.vte_term.set_background_transparent(false);//but only when changes + //} + #endif + /*0-BLOCK,1-IBEAM,2-UNDERLINE*/ + var cursorshape = my_conf.get_integer("terminal_cursorshape",0,(ref new_val)=>{ + if(new_val>2){new_val=0;return CFG_CHECK.REPLACE;} + if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} + return CFG_CHECK.OK; + }); + #if ! VTE_2_91 + this.vte_term.set_cursor_shape((Vte.TerminalCursorShape)cursorshape); + #else + this.vte_term.set_cursor_shape((Vte.CursorShape)cursorshape); + #endif + /*0-SYSTEM,1-ON,2-OFF*/ + var cursor_blinkmode = my_conf.get_integer("terminal_cursor_blinkmode",0,(ref new_val)=>{ + if(new_val>2){new_val=0;return CFG_CHECK.REPLACE;} + if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} + return CFG_CHECK.OK; + }); + #if ! VTE_2_91 + this.vte_term.set_cursor_blink_mode ((Vte.TerminalCursorBlinkMode)cursor_blinkmode); + #else + this.vte_term.set_cursor_blink_mode ((Vte.CursorBlinkMode)cursor_blinkmode); + #endif + + if(!this.is_locked(VTT_LOCK_SETTING.DELETE_BINDING)){ + /*0-AUTO,1-BACKSPACE,2-DELETE,3-SEQUENCE,4-TTY*/ + var delbinding = my_conf.get_integer("terminal_delete_binding",0,(ref new_val)=>{ + if(new_val>4){new_val=0;return CFG_CHECK.REPLACE;} + if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} + return CFG_CHECK.OK; + }); + #if ! VTE_2_91 + this.vte_term.set_delete_binding ((Vte.TerminalEraseBinding)delbinding); + #else + this.vte_term.set_delete_binding ((Vte.EraseBinding)delbinding); + #endif + } + + if(!this.is_locked(VTT_LOCK_SETTING.BACKSPACE_BINDING)){ + /*0-AUTO,1-BACKSPACE,2-DELETE,3-SEQUENCE,4-TTY*/ + var backspace = my_conf.get_integer("terminal_backspace_binding",0,(ref new_val)=>{ + if(new_val>4){new_val=0;return CFG_CHECK.REPLACE;} + if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} + return CFG_CHECK.OK; + }); + #if ! VTE_2_91 + this.vte_term.set_backspace_binding ((Vte.TerminalEraseBinding)backspace); + #else + this.vte_term.set_backspace_binding ((Vte.EraseBinding)backspace); + #endif + } + + if(!this.is_locked(VTT_LOCK_SETTING.ENCODING)){ + /* default - is special value + * */ + var s = my_conf.get_string("terminal_default_encoding","default"); + if(s!="default"){ + #if ! VTE_2_91 + this.vte_term.set_encoding (s); + #else + this.vte_term.encoding=s; + #endif + }else + #if ! VTE_2_91 + this.vte_term.set_encoding (null);//reset to default + #else + this.vte_term.encoding=null; + #endif + } + + string[] url_regexps = my_conf.get_string_list("terminal_url_regexps",{"(\\\"\\s*)?((?i)http|https|ftp|sftp)\\://([a-zA-Z0-9\\-]+(\\.)?)+(:[0-9]+)?(/([a-zA-Z0-9\\(\\)\\[\\]\\{\\};\\!\\*'\"`\\:@&=\\+\\$\\,/\\?#\\-\\_\\.\\~%\\^<>\\|\\\\])*)?","xdg-open"},(ref new_val)=>{ + if(new_val!=null && (new_val.length % 2)!=0){ + debug(_("terminal_url_regexps odd value of array length! will be used default value.")); + return CFG_CHECK.USE_DEFAULT; + } + for(int j=0; j { + free(val); + }); + this.match_tags.steal_all(); + debug("url_regexps=%d",url_regexps.length); + for(int j=0;j{ + if(new_val>3){new_val=0;return CFG_CHECK.REPLACE;} + if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} + return CFG_CHECK.OK; + }); + this.vte_term.contents_changed.disconnect(this.tbutton.check_for_notify); + + if((notify & 1)==1) + this.vte_term.contents_changed.connect(this.tbutton.check_for_notify); + if((notify & 2)==2) + this.tbutton.notify_on_title_change=true; + else + this.tbutton.notify_on_title_change=false; + + this.tbutton.notify_timeout = my_conf.get_integer("terminal_timeout_before_notify",5,(ref new_val)=>{ + if(new_val>1440){new_val=1440;return CFG_CHECK.REPLACE;} + if(new_val<0){new_val=0;return CFG_CHECK.REPLACE;} + return CFG_CHECK.OK; + }); + this.disable_terminal_popup=my_conf.get_boolean("terminal_disable_popup_menu",false); + this.vte_term.update_style(); + + this.scrollbar.get_settings().gtk_primary_button_warps_slider=!my_conf.get_boolean("terminal_scroll_by_page",true); + }//configure + + public bool vte_button_press_event(Widget widget,Gdk.EventButton event) { + if(event.type==Gdk.EventType.BUTTON_PRESS){ + if(event.button==1 && (event.state & Gdk.ModifierType.CONTROL_MASK)==Gdk.ModifierType.CONTROL_MASK){ + this.check_match(event); + }else + if(event.button== 3 && !this.disable_terminal_popup){//right mouse button + this.popup_menu(event); + return true; + } + } + return false; //true == ignore event + } + + public bool vttoggle_button_press_event(Widget widget,Gdk.EventButton event) { + if(event.type==Gdk.EventType.BUTTON_PRESS){ +//~ if(event.button==1 && (event.state & Gdk.ModifierType.CONTROL_MASK)==Gdk.ModifierType.CONTROL_MASK){ +//~ this.check_match(event); +//~ }else + if(event.button== 3){//right mouse button + this.popup_tab_menu(event); + return true; + } + } + return false; //true == ignore event + } + + public void on_copy_link_activate(){ + Gtk.Clipboard clipboard = Gtk.Clipboard.get_for_display (Gdk.Display.get_default (), Gdk.SELECTION_CLIPBOARD); + clipboard.set_text (this.last_link, -1); + this.last_link=null; + } + + public void on_run_link_activate(){ + string tag_value=""; + if(last_tag!=null && this.match_tags.lookup_extended(this.last_tag,null,out tag_value) ){ + if( (this.last_link.get_char (0).to_string ()=="\"" && this.last_link.get_char (this.last_link.length-1).to_string ()=="\"") + || (this.last_link.get_char (0).to_string ()=="'" && this.last_link.get_char (this.last_link.length-1).to_string ()=="'" ) ){ + /*remove quotes if present at beggining and at the end + * example: " http://www.google.com/?q="denis"" + * */ + this.last_link=this.last_link.slice(1,this.last_link.length-1); + this.last_link=this.last_link.strip(); + } + debug("check_match run=%s params=%s",tag_value,this.last_link); + Posix.system(tag_value+" '"+this.last_link+"' &"); + } + this.last_tag=null; + } + + public void create_popup_menu(Gtk.Menu menu){ + //debug("popup_menu ref_count=%d",(int)menu.ref_count); + unowned Gtk.Widget parent; + parent = this.vte_term; + while(parent.parent!=null ){parent = parent.parent;} //find VTMainWindow + VTMainWindow vtw=(VTMainWindow)parent; + menu.set_accel_group(vtw.ayobject.accel_group); + Gtk.ActionGroup acg=vtw.ayobject.action_group; + + Gtk.MenuItem menuitem; + + menuitem = (Gtk.MenuItem)acg.get_action("terminal_copy_text").create_menu_item(); + menu.append(menuitem); + menuitem = (Gtk.MenuItem)acg.get_action("terminal_paste_text").create_menu_item(); + menu.append(menuitem); + + menuitem = new Gtk.SeparatorMenuItem(); + menu.append(menuitem); + + menuitem = (Gtk.MenuItem)acg.get_action("terminal_add_tab").create_menu_item(); + menu.append(menuitem); + menuitem = (Gtk.MenuItem)acg.get_action("terminal_close_tab").create_menu_item(); + menu.append(menuitem); + if(this.my_conf.standalone_mode){ + menuitem = (Gtk.MenuItem)acg.get_action("window_open_new_window").create_menu_item(); + menu.append(menuitem); + } + + vtw.ayobject.create_popup_menu_for_removed_tabs(menu); + + menuitem = (Gtk.MenuItem)acg.get_action("terminal_search_dialog").create_menu_item(); + menu.append(menuitem); + + menuitem = new Gtk.SeparatorMenuItem(); + menu.append(menuitem); + menuitem = (Gtk.MenuItem)acg.get_action("open_settings").create_menu_item(); + menu.append(menuitem); + + /**************************************************************/ + var submenu = new Gtk.Menu (); + + menuitem = (Gtk.MenuItem)acg.get_action("window_terminal_quick_settings").create_menu_item(); + submenu.append(menuitem); + + if(!this.my_conf.standalone_mode){ + menuitem = (Gtk.MenuItem)acg.get_action("follow_the_mouse").create_menu_item(); + submenu.append(menuitem); + + var action_keepabove = acg.get_action("keep_above") as ToggleAction; + action_keepabove.set_active(vtw.keep_above); + menuitem = (Gtk.MenuItem)action_keepabove.create_menu_item(); + submenu.append(menuitem); + + var action_stick = acg.get_action("window_toggle_stick") as ToggleAction; + action_stick.set_active(vtw.orig_stick); + menuitem = (Gtk.MenuItem)action_stick.create_menu_item(); + submenu.append(menuitem); + + var action_autohide = acg.get_action("window_toggle_autohide") as ToggleAction; + action_autohide.set_active(vtw.autohide); + menuitem = (Gtk.MenuItem)action_autohide.create_menu_item(); + submenu.append(menuitem); + + } + if(!this.my_conf.standalone_mode){ + menuitem = (Gtk.MenuItem)acg.get_action("window_open_new_window").create_menu_item(); + submenu.append(menuitem); + } + + menuitem = (Gtk.MenuItem)acg.get_action("terminal_copy_all_text").create_menu_item(); + submenu.append(menuitem); + + menuitem = new Gtk.MenuItem.with_label (_("Quick settings")); + menuitem.set_submenu(submenu); + menu.append(menuitem); + + menuitem = (Gtk.MenuItem)acg.get_action("altyo_about").create_menu_item(); + menu.append(menuitem); + + menuitem = new Gtk.SeparatorMenuItem(); + menu.append(menuitem); + + if(!this.my_conf.standalone_mode){ + menuitem = (Gtk.MenuItem)acg.get_action("main_hotkey").create_menu_item(); + menu.append(menuitem); + } + menuitem = (Gtk.MenuItem)acg.get_action("altyo_exit").create_menu_item(); + menu.append(menuitem); + } + + public void popup_menu(Gdk.EventButton event){ + //debug("terminal popup_menu"); + var menu = new Gtk.Menu(); + + Gtk.MenuItem menuitem; + + this.last_link=null; + this.last_tag=null; + string? match=this.get_match((int)event.x,(int)event.y,out this.last_tag); + if(match!=null){ + this.last_link=match; + menuitem = new Gtk.MenuItem.with_label (_("Copy link")); + menuitem.activate.connect(this.on_copy_link_activate); + menu.append(menuitem); + menuitem = new Gtk.MenuItem.with_label (_("Run link Ctrl+left mouse button")); + menuitem.activate.connect(this.on_run_link_activate); +//~ var label=menuitem.get_child() as Gtk.Label; +//~ label.set_justify( Gtk.Justification.RIGHT); +//~ label.set_pattern( "___ ___"); +//~ ((Gtk.Widget)menuitem).add_accelerator( "activate", vtw.ayobject.accel_group, //~ 0xfee9, Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE); - menu.append(menuitem); - } - - this.create_popup_menu(menu); + menu.append(menuitem); + } + + this.create_popup_menu(menu); - menu.deactivate.connect (this.on_deactivate); - menu.show_all(); + menu.deactivate.connect (this.on_deactivate); + menu.show_all(); //menu.attach_to_widget (this.vte_term, null); - menu.popup(null, null, null, event.button, event.time); - menu.ref();//no one own menu,emulate owners,uref will be on_deactivate - //debug("popup_menu ref_count=%d",(int)menu.ref_count); - } - - private void force_action_state(Gtk.ToggleAction action, bool new_state){ - Type type = action.get_type(); - uint sig_id=GLib.Signal.lookup("activate",type); - var handler_id = GLib.SignalHandler.find(action,GLib.SignalMatchType.ID,sig_id,0,null,null,null); - GLib.SignalHandler.block(action,handler_id);//prevent emit signal - action.set_active(new_state); - GLib.SignalHandler.unblock(action,handler_id); - } - - private void stop_signal_emission(Gtk.Action action){ - Type type = action.get_type(); - uint sig_id=GLib.Signal.lookup("activate",type); - GLib.Signal.stop_emission(action,sig_id,0); - } - - public void popup_tab_menu(Gdk.EventButton event){ - //debug("terminal popup_menu"); - var menu = new Gtk.Menu(); - //debug("popup_menu ref_count=%d",(int)menu.ref_count); - unowned Gtk.Widget parent; - parent = this.vte_term; - while(parent.parent!=null ){parent = parent.parent;} //find VTMainWindow - VTMainWindow vtw=(VTMainWindow)parent; - menu.set_accel_group(vtw.ayobject.accel_group); - Gtk.ActionGroup acg=vtw.ayobject.action_group; - - Gtk.MenuItem menuitem; - - menuitem = (Gtk.MenuItem)acg.get_action("terminal_sort_by_hostname").create_menu_item(); - menu.append(menuitem); - menuitem = (Gtk.MenuItem)acg.get_action("terminal_search_in_tab_title").create_menu_item(); - menu.append(menuitem); - - if(vtw.ayobject.tab_sort_order==TAB_SORT_ORDER.HOSTNAME ){ - var action_sort=acg.get_action("disable_sort_tab") as ToggleAction; - - this.force_action_state(action_sort,this.tbutton.do_not_sort); - - //override default action handler - var action_sort_activate_id = action_sort.activate.connect(()=>{ - debug("disable_sort_tab.activate"); - this.tbutton.do_not_sort=!this.tbutton.do_not_sort; - this.stop_signal_emission(action_sort); - }); - //restore default action handler - menu.destroy.connect(()=>{ - GLib.SignalHandler.disconnect(action_sort,action_sort_activate_id); - }); - - menuitem = (Gtk.MenuItem)action_sort.create_menu_item(); - menu.append(menuitem); - } - Gtk.Settings settings = Gtk.Settings.get_default(); - - Gtk.ImageMenuItem image_menuitem; - Gtk.Image image; - image_menuitem = new Gtk.ImageMenuItem.with_label (_("Copy terminal name")); - if(settings.gtk_menu_images){ - //show images only if it not disabled globally - image = new Gtk.Image.from_icon_name ("gtk-copy", Gtk.IconSize.MENU); - image_menuitem.set_image(image); - } - image_menuitem.activate.connect(()=>{ - Gdk.Display display = vtw.get_display (); - Gtk.Clipboard clipboard = Gtk.Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD); - clipboard.set_text(this.tbutton.tab_title,-1); - }); - menu.append(image_menuitem); - - if(this.tbutton.host_name!=null && this.tbutton.host_name!=""){ - image_menuitem = new Gtk.ImageMenuItem.with_label (_("Copy terminal host name")); - if(settings.gtk_menu_images){ - //show images only if it not disabled globally - image = new Gtk.Image.from_icon_name ("gtk-copy", Gtk.IconSize.MENU); - image_menuitem.set_image(image); - } - image_menuitem.activate.connect(()=>{ - Gdk.Display display = vtw.get_display (); - Gtk.Clipboard clipboard = Gtk.Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD); - clipboard.set_text(this.tbutton.host_name,-1); - }); - menu.append(image_menuitem); - } - - image_menuitem = new Gtk.ImageMenuItem.with_label (_("Copy running command")); - if(settings.gtk_menu_images){ - //show images only if it not disabled globally - image = new Gtk.Image.from_icon_name ("gtk-copy", Gtk.IconSize.MENU); - image_menuitem.set_image(image); - } - image_menuitem.activate.connect(()=>{ - Gdk.Display display = vtw.get_display (); - Gtk.Clipboard clipboard = Gtk.Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD); - clipboard.set_text(this.find_tty_pgrp(this.pid,FIND_TTY.CMDLINE),-1); - }); - menu.append(image_menuitem); - - Gtk.CheckMenuItem chmenuitem; - - chmenuitem = new Gtk.CheckMenuItem.with_label (_("Disable key bindings")); - chmenuitem.set_active (!acg.get_sensitive()); - chmenuitem.activate.connect(()=>{ - acg.set_sensitive(!acg.get_sensitive()); - }); - menu.append(chmenuitem); - - chmenuitem = new Gtk.CheckMenuItem.with_label (_("Disable terminal menu")); - chmenuitem.set_active (this.disable_terminal_popup); - chmenuitem.activate.connect(()=>{ - this.disable_terminal_popup=chmenuitem.get_active(); - }); - menu.append(chmenuitem); - - var lock_tab=acg.get_action("lock_tab") as ToggleAction; - this.force_action_state(lock_tab,this.tbutton.prevent_close); - //override default action handler - var lock_tab_activate_id = lock_tab.activate.connect(()=>{ - debug("lock_tab.activate"); - this.tbutton.prevent_close=!this.tbutton.prevent_close; - this.tbutton.reconfigure(); - vtw.ayobject.hvbox.queue_draw();//redraw border - this.stop_signal_emission(lock_tab); - }); - //restore default action handler - menu.destroy.connect(()=>{ - GLib.SignalHandler.disconnect(lock_tab,lock_tab_activate_id); - }); - menuitem = (Gtk.MenuItem)lock_tab.create_menu_item(); - menu.append(menuitem); - - var custom_title=acg.get_action("tab_custom_title") as ToggleAction; - this.force_action_state(custom_title,this.tbutton.tab_custom_title_enabled); - //override default action handler - var custom_title_activate_id = custom_title.activate.connect(()=>{ - debug("custom_title.activate"); - vtw.ayobject.set_custom_title_dialog(this.tbutton); - this.stop_signal_emission(custom_title); - }); - //restore default action handler - menu.destroy.connect(()=>{ - GLib.SignalHandler.disconnect(custom_title,custom_title_activate_id); - }); - - menuitem = (Gtk.MenuItem)custom_title.create_menu_item(); - menu.append(menuitem); - - - if(this.disable_terminal_popup){ - var submenu = new Gtk.Menu (); - menuitem = new Gtk.MenuItem.with_label (_("Terminal menu")); - menuitem.set_submenu(submenu); - menu.append(menuitem); - this.create_popup_menu(submenu); - } - - - menu.deactivate.connect (this.on_deactivate); - menu.show_all(); + menu.popup(null, null, null, event.button, event.time); + menu.ref();//no one own menu,emulate owners,uref will be on_deactivate + //debug("popup_menu ref_count=%d",(int)menu.ref_count); + } + + private void force_action_state(Gtk.ToggleAction action, bool new_state){ + Type type = action.get_type(); + uint sig_id=GLib.Signal.lookup("activate",type); + var handler_id = GLib.SignalHandler.find(action,GLib.SignalMatchType.ID,sig_id,0,null,null,null); + GLib.SignalHandler.block(action,handler_id);//prevent emit signal + action.set_active(new_state); + GLib.SignalHandler.unblock(action,handler_id); + } + + private void stop_signal_emission(Gtk.Action action){ + Type type = action.get_type(); + uint sig_id=GLib.Signal.lookup("activate",type); + GLib.Signal.stop_emission(action,sig_id,0); + } + + public void popup_tab_menu(Gdk.EventButton event){ + //debug("terminal popup_menu"); + var menu = new Gtk.Menu(); + //debug("popup_menu ref_count=%d",(int)menu.ref_count); + unowned Gtk.Widget parent; + parent = this.vte_term; + while(parent.parent!=null ){parent = parent.parent;} //find VTMainWindow + VTMainWindow vtw=(VTMainWindow)parent; + menu.set_accel_group(vtw.ayobject.accel_group); + Gtk.ActionGroup acg=vtw.ayobject.action_group; + + Gtk.MenuItem menuitem; + + menuitem = (Gtk.MenuItem)acg.get_action("terminal_sort_by_hostname").create_menu_item(); + menu.append(menuitem); + menuitem = (Gtk.MenuItem)acg.get_action("terminal_search_in_tab_title").create_menu_item(); + menu.append(menuitem); + + if(vtw.ayobject.tab_sort_order==TAB_SORT_ORDER.HOSTNAME ){ + var action_sort=acg.get_action("disable_sort_tab") as ToggleAction; + + this.force_action_state(action_sort,this.tbutton.do_not_sort); + + //override default action handler + var action_sort_activate_id = action_sort.activate.connect(()=>{ + debug("disable_sort_tab.activate"); + this.tbutton.do_not_sort=!this.tbutton.do_not_sort; + this.stop_signal_emission(action_sort); + }); + //restore default action handler + menu.destroy.connect(()=>{ + GLib.SignalHandler.disconnect(action_sort,action_sort_activate_id); + }); + + menuitem = (Gtk.MenuItem)action_sort.create_menu_item(); + menu.append(menuitem); + } + Gtk.Settings settings = Gtk.Settings.get_default(); + + Gtk.ImageMenuItem image_menuitem; + Gtk.Image image; + image_menuitem = new Gtk.ImageMenuItem.with_label (_("Copy terminal name")); + if(settings.gtk_menu_images){ + //show images only if it not disabled globally + image = new Gtk.Image.from_icon_name ("gtk-copy", Gtk.IconSize.MENU); + image_menuitem.set_image(image); + } + image_menuitem.activate.connect(()=>{ + Gdk.Display display = vtw.get_display (); + Gtk.Clipboard clipboard = Gtk.Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD); + clipboard.set_text(this.tbutton.tab_title,-1); + }); + menu.append(image_menuitem); + + if(this.tbutton.host_name!=null && this.tbutton.host_name!=""){ + image_menuitem = new Gtk.ImageMenuItem.with_label (_("Copy terminal host name")); + if(settings.gtk_menu_images){ + //show images only if it not disabled globally + image = new Gtk.Image.from_icon_name ("gtk-copy", Gtk.IconSize.MENU); + image_menuitem.set_image(image); + } + image_menuitem.activate.connect(()=>{ + Gdk.Display display = vtw.get_display (); + Gtk.Clipboard clipboard = Gtk.Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD); + clipboard.set_text(this.tbutton.host_name,-1); + }); + menu.append(image_menuitem); + } + + image_menuitem = new Gtk.ImageMenuItem.with_label (_("Copy running command")); + if(settings.gtk_menu_images){ + //show images only if it not disabled globally + image = new Gtk.Image.from_icon_name ("gtk-copy", Gtk.IconSize.MENU); + image_menuitem.set_image(image); + } + image_menuitem.activate.connect(()=>{ + Gdk.Display display = vtw.get_display (); + Gtk.Clipboard clipboard = Gtk.Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD); + clipboard.set_text(this.find_tty_pgrp(this.pid,FIND_TTY.CMDLINE),-1); + }); + menu.append(image_menuitem); + + Gtk.CheckMenuItem chmenuitem; + + chmenuitem = new Gtk.CheckMenuItem.with_label (_("Disable key bindings")); + chmenuitem.set_active (!acg.get_sensitive()); + chmenuitem.activate.connect(()=>{ + acg.set_sensitive(!acg.get_sensitive()); + }); + menu.append(chmenuitem); + + chmenuitem = new Gtk.CheckMenuItem.with_label (_("Disable terminal menu")); + chmenuitem.set_active (this.disable_terminal_popup); + chmenuitem.activate.connect(()=>{ + this.disable_terminal_popup=chmenuitem.get_active(); + }); + menu.append(chmenuitem); + + var lock_tab=acg.get_action("lock_tab") as ToggleAction; + this.force_action_state(lock_tab,this.tbutton.prevent_close); + //override default action handler + var lock_tab_activate_id = lock_tab.activate.connect(()=>{ + debug("lock_tab.activate"); + this.tbutton.prevent_close=!this.tbutton.prevent_close; + this.tbutton.reconfigure(); + vtw.ayobject.hvbox.queue_draw();//redraw border + this.stop_signal_emission(lock_tab); + }); + //restore default action handler + menu.destroy.connect(()=>{ + GLib.SignalHandler.disconnect(lock_tab,lock_tab_activate_id); + }); + menuitem = (Gtk.MenuItem)lock_tab.create_menu_item(); + menu.append(menuitem); + + var custom_title=acg.get_action("tab_custom_title") as ToggleAction; + this.force_action_state(custom_title,this.tbutton.tab_custom_title_enabled); + //override default action handler + var custom_title_activate_id = custom_title.activate.connect(()=>{ + debug("custom_title.activate"); + vtw.ayobject.set_custom_title_dialog(this.tbutton); + this.stop_signal_emission(custom_title); + }); + //restore default action handler + menu.destroy.connect(()=>{ + GLib.SignalHandler.disconnect(custom_title,custom_title_activate_id); + }); + + menuitem = (Gtk.MenuItem)custom_title.create_menu_item(); + menu.append(menuitem); + + + if(this.disable_terminal_popup){ + var submenu = new Gtk.Menu (); + menuitem = new Gtk.MenuItem.with_label (_("Terminal menu")); + menuitem.set_submenu(submenu); + menu.append(menuitem); + this.create_popup_menu(submenu); + } + + + menu.deactivate.connect (this.on_deactivate); + menu.show_all(); //menu.attach_to_widget (this.vte_term, null); - menu.popup(null, null, null, event.button, event.time); - menu.ref();//no one own menu,emulate owners,uref will be on_deactivate - //debug("popup_menu ref_count=%d",(int)menu.ref_count); - }//popup_tab_menu - - private string? get_match(int x,int y ,out int? tag){ - int char_width=(int)this.vte_term.get_char_width(); - int char_height=(int)this.vte_term.get_char_height(); - unowned Gtk.Border? inner_border=null; - #if ! VTE_2_91 - this.vte_term.style_get("inner-border", out inner_border, null); - #else - unowned Gtk.StyleContext context = this.vte_term.get_style_context(); - inner_border=context.get_padding(this.vte_term.get_state_flags()); - #endif - int col = ((int)x - (inner_border!=null ? inner_border.left : 0)) / char_width; - int row = ((int)y - (inner_border!=null ? inner_border.top : 0)) / char_height; - return this.vte_term.match_check (col, row, out tag); - } - - private void check_match (Gdk.EventButton event){ - string tag_value=""; - int? tag=null; - string? match=this.get_match((int)event.x,(int)event.y,out tag); - if(tag!=null && this.match_tags.lookup_extended(tag,null,out tag_value) ){ - if( (match.get_char (0).to_string ()=="\"" && match.get_char (match.length-1).to_string ()=="\"") - || (match.get_char (0).to_string ()=="'" && match.get_char (match.length-1).to_string ()=="'" ) ){ - /*remove quotes if present at beggining and at the end - * example: " http://www.google.com/?q="denis"" - * */ - match=match.slice(1,match.length-1); - match=match.strip(); - } - debug("check_match run: \"%s '%s' &\"",tag_value,match); - Posix.system(tag_value+" '"+match+"' &"); - } - } - - private void on_deactivate(Widget m) { - ((Gtk.Menu)m).deactivate.disconnect(on_deactivate); - m.unref();//menu will be destroyed after end of deactivate event - //debug("popup_menu ref_count=%d",(int)m.ref_count);//normal count 4 - } - - private int find_other_pgrp(int pid){ - GLib.Dir dir = GLib.Dir.open("/proc/"); - unowned string filename; - /* scan whole proc, for another last-child - * there is no other way to do that, ps do the same - * * * * * * * * * * * * * * * * * * * * * * * * */ - while ( (filename = dir.read_name())!=null ) - if(int.parse(filename)>0){ //is it pid number? =) - - var parent_stat = "/proc/"+filename+"/stat"; - - if(GLib.FileUtils.test(parent_stat,GLib.FileTest.EXISTS) ){ - string contents = ""; - size_t length = -1; - if(GLib.FileUtils.get_contents (parent_stat,out contents,out length) ){ - //< skip > [ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] < skip ... > - //31266 (mc) S 31253 31266 31253 34817 31266 4202496 ... - contents=contents.substring(contents.last_index_of(")")+4,-1); - var stat_cont=contents.split(" "); - //debug("pid=%d parse=%d stat_cont0=%s",pid,int.parse(stat_cont[1]),stat_cont[0]); - //we found another last child, probably from subshell - if(pid==int.parse(stat_cont[0]) ){ - return int.parse(stat_cont[4]); - //"/proc/"+stat_cont[4]+"/cmdline"; - } - } - } - } - return -1; - } - - public string?[] find_all_suspended_pgrp(int pid){ - GLib.Dir dir = GLib.Dir.open("/proc/"); - unowned string filename; - string?[] result=null; - /* scan whole proc, for another last-child - * there is no other way to do that, ps do the same - * * * * * * * * * * * * * * * * * * * * * * * * */ - while ( (filename = dir.read_name())!=null ) - if(int.parse(filename)>0){ //is it pid number? =) - - var parent_stat = "/proc/"+filename+"/stat"; - - if(GLib.FileUtils.test(parent_stat,GLib.FileTest.EXISTS) ){ - string contents = ""; - size_t length = -1; - if(GLib.FileUtils.get_contents (parent_stat,out contents,out length) ){ - //< skip > [ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] < skip ... > - //31266 (mc) S 31253 31266 31253 34817 31266 4202496 ... - contents=contents.substring(contents.last_index_of(")")+4,-1); - var stat_cont=contents.split(" "); - //debug("pid=%d parse=%d stat_cont0=%s",pid,int.parse(stat_cont[1]),stat_cont[0]); - //we found another last child, probably from subshell - if(pid==int.parse(stat_cont[0]) ){ - - //return int.parse(stat_cont[4]); - //"/proc/"+stat_cont[4]+"/cmdline"; - var tty_pgrp="/proc/"+filename+"/cmdline"; - if(GLib.FileUtils.test(tty_pgrp,GLib.FileTest.EXISTS) ){ - uint8[] data; - if(GLib.FileUtils.get_data(tty_pgrp,out data) ){ - for(var i=0;i0){ - s_pid=((int)other).to_string(); - tty_pgrp="/proc/"+s_pid; - } - //debug("find_others_pgrp=%s",other); - switch(f_type){ - case FIND_TTY.CMDLINE: - tty_pgrp+="/cmdline"; - if(GLib.FileUtils.test(tty_pgrp,GLib.FileTest.EXISTS) ){ - uint8[] data; - if(GLib.FileUtils.get_data(tty_pgrp,out data) ){ - for(var i=0;i{ - long column, row; - this.vte_term.get_cursor_position(out column,out row); - string vte_text=this.vte_term.get_text_range(row,0,row,column,null,null); - //Password: - vte_text=vte_text.strip(); - debug("expect=%s get '%s'",expect_string,vte_text); - if(GLib.Regex.match_simple(".*"+expect_string+".*",vte_text,RegexCompileFlags.CASELESS,0)){ - this.vte_term.feed_child(paste,paste.length); - if(cb!=null) cb(); - return false; - }else - if(count>0){ - count--; - return true; - }else - return false; - }); - } - - private string parse_port(ref string host_name){ - string port=""; - if(host_name!=null && host_name.contains(":")){ - port=host_name.substring(host_name.index_of_char(':',1)+1,host_name.length-1); - if(int.parse(port)<=0){//is it number? - port="";//port is not number - error("port parse problem"); - }else{ - host_name=host_name.substring(0,host_name.index_of_char(':',1)-1); - } - } - return port; - } - - public void try_run_command(owned TildaAuth tauth){ - #if HAVE_QLIST - if(tauth.password=="!"){ - debug("find_network_password"); - //GnomeKeyring.is_available() + menu.popup(null, null, null, event.button, event.time); + menu.ref();//no one own menu,emulate owners,uref will be on_deactivate + //debug("popup_menu ref_count=%d",(int)menu.ref_count); + }//popup_tab_menu + + private string? get_match(int x,int y ,out int? tag){ + int char_width=(int)this.vte_term.get_char_width(); + int char_height=(int)this.vte_term.get_char_height(); + unowned Gtk.Border? inner_border=null; + #if ! VTE_2_91 + this.vte_term.style_get("inner-border", out inner_border, null); + #else + unowned Gtk.StyleContext context = this.vte_term.get_style_context(); + inner_border=context.get_padding(this.vte_term.get_state_flags()); + #endif + int col = ((int)x - (inner_border!=null ? inner_border.left : 0)) / char_width; + int row = ((int)y - (inner_border!=null ? inner_border.top : 0)) / char_height; + return this.vte_term.match_check (col, row, out tag); + } + + private void check_match (Gdk.EventButton event){ + string tag_value=""; + int? tag=null; + string? match=this.get_match((int)event.x,(int)event.y,out tag); + if(tag!=null && this.match_tags.lookup_extended(tag,null,out tag_value) ){ + if( (match.get_char (0).to_string ()=="\"" && match.get_char (match.length-1).to_string ()=="\"") + || (match.get_char (0).to_string ()=="'" && match.get_char (match.length-1).to_string ()=="'" ) ){ + /*remove quotes if present at beggining and at the end + * example: " http://www.google.com/?q="denis"" + * */ + match=match.slice(1,match.length-1); + match=match.strip(); + } + debug("check_match run: \"%s '%s' &\"",tag_value,match); + Posix.system(tag_value+" '"+match+"' &"); + } + } + + private void on_deactivate(Widget m) { + ((Gtk.Menu)m).deactivate.disconnect(on_deactivate); + m.unref();//menu will be destroyed after end of deactivate event + //debug("popup_menu ref_count=%d",(int)m.ref_count);//normal count 4 + } + + private int find_other_pgrp(int pid){ + GLib.Dir dir = GLib.Dir.open("/proc/"); + unowned string filename; + /* scan whole proc, for another last-child + * there is no other way to do that, ps do the same + * * * * * * * * * * * * * * * * * * * * * * * * */ + while ( (filename = dir.read_name())!=null ) + if(int.parse(filename)>0){ //is it pid number? =) + + var parent_stat = "/proc/"+filename+"/stat"; + + if(GLib.FileUtils.test(parent_stat,GLib.FileTest.EXISTS) ){ + string contents = ""; + size_t length = -1; + if(GLib.FileUtils.get_contents (parent_stat,out contents,out length) ){ + //< skip > [ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] < skip ... > + //31266 (mc) S 31253 31266 31253 34817 31266 4202496 ... + contents=contents.substring(contents.last_index_of(")")+4,-1); + var stat_cont=contents.split(" "); + //debug("pid=%d parse=%d stat_cont0=%s",pid,int.parse(stat_cont[1]),stat_cont[0]); + //we found another last child, probably from subshell + if(pid==int.parse(stat_cont[0]) ){ + return int.parse(stat_cont[4]); + //"/proc/"+stat_cont[4]+"/cmdline"; + } + } + } + } + return -1; + } + + public string?[] find_all_suspended_pgrp(int pid){ + GLib.Dir dir = GLib.Dir.open("/proc/"); + unowned string filename; + string?[] result=null; + /* scan whole proc, for another last-child + * there is no other way to do that, ps do the same + * * * * * * * * * * * * * * * * * * * * * * * * */ + while ( (filename = dir.read_name())!=null ) + if(int.parse(filename)>0){ //is it pid number? =) + + var parent_stat = "/proc/"+filename+"/stat"; + + if(GLib.FileUtils.test(parent_stat,GLib.FileTest.EXISTS) ){ + string contents = ""; + size_t length = -1; + if(GLib.FileUtils.get_contents (parent_stat,out contents,out length) ){ + //< skip > [ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] < skip ... > + //31266 (mc) S 31253 31266 31253 34817 31266 4202496 ... + contents=contents.substring(contents.last_index_of(")")+4,-1); + var stat_cont=contents.split(" "); + //debug("pid=%d parse=%d stat_cont0=%s",pid,int.parse(stat_cont[1]),stat_cont[0]); + //we found another last child, probably from subshell + if(pid==int.parse(stat_cont[0]) ){ + + //return int.parse(stat_cont[4]); + //"/proc/"+stat_cont[4]+"/cmdline"; + var tty_pgrp="/proc/"+filename+"/cmdline"; + if(GLib.FileUtils.test(tty_pgrp,GLib.FileTest.EXISTS) ){ + uint8[] data; + if(GLib.FileUtils.get_data(tty_pgrp,out data) ){ + for(var i=0;i0){ + s_pid=((int)other).to_string(); + tty_pgrp="/proc/"+s_pid; + } + //debug("find_others_pgrp=%s",other); + switch(f_type){ + case FIND_TTY.CMDLINE: + tty_pgrp+="/cmdline"; + if(GLib.FileUtils.test(tty_pgrp,GLib.FileTest.EXISTS) ){ + uint8[] data; + if(GLib.FileUtils.get_data(tty_pgrp,out data) ){ + for(var i=0;i{ + long column, row; + this.vte_term.get_cursor_position(out column,out row); + string vte_text=this.vte_term.get_text_range(row,0,row,column,null,null); + //Password: + vte_text=vte_text.strip(); + debug("expect=%s get '%s'",expect_string,vte_text); + if(GLib.Regex.match_simple(".*"+expect_string+".*",vte_text,RegexCompileFlags.CASELESS,0)){ + this.vte_term.feed_child(paste,paste.length); + if(cb!=null) cb(); + return false; + }else + if(count>0){ + count--; + return true; + }else + return false; + }); + } + + private string parse_port(ref string host_name){ + string port=""; + if(host_name!=null && host_name.contains(":")){ + port=host_name.substring(host_name.index_of_char(':',1)+1,host_name.length-1); + if(int.parse(port)<=0){//is it number? + port="";//port is not number + error("port parse problem"); + }else{ + host_name=host_name.substring(0,host_name.index_of_char(':',1)-1); + } + } + return port; + } + + public void try_run_command(owned TildaAuth tauth){ + #if HAVE_QLIST + if(tauth.password=="!"){ + debug("find_network_password"); + //GnomeKeyring.is_available() /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ - unowned Gtk.Widget parent; - parent = this.vte_term; - while(parent.parent!=null ){parent = parent.parent;} //find VTMainWindow - VTMainWindow vtw=(VTMainWindow)parent; + unowned Gtk.Widget parent; + parent = this.vte_term; + while(parent.parent!=null ){parent = parent.parent;} //find VTMainWindow + VTMainWindow vtw=(VTMainWindow)parent; /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ - var res=GnomeKeyring.set_default_keyring_sync (vtw.conf.get_string("terminal_default_keyring","altyo")); - if(res!=Result.OK) - debug("GnomeKeyring.set_default_keyring_sync error"); - else{ - //unowned - Info info=null; - GnomeKeyring.get_info_sync (vtw.conf.get_string("terminal_default_keyring","altyo"), out info) ; - if(info!=null){ - debug("Update keyring info..."); - info.set_lock_timeout(60*3);//lock after 3 min - info.set_lock_on_idle(true); - GnomeKeyring.set_info_sync (vtw.conf.get_string("terminal_default_keyring","altyo"), info) ; - } - - GnomeKeyring.find_network_password (tauth.user, null, tauth.host, null, tauth.type, "auth", 0, (result, list)=>{ - - debug("find_network_password done=%d",result); - if (result == Result.OK && list.length () > 0) { - weak NetworkPasswordData npd = (NetworkPasswordData) list.first().data; - if (npd.authtype == "auth") { - tauth.password=npd.password; - this.run_command(tauth); - } - }else{ - var dialog = new MessageDialog (null, (DialogFlags.DESTROY_WITH_PARENT | DialogFlags.MODAL), MessageType.QUESTION, ButtonsType.OK_CANCEL, "Password not foud!\n create new one?"); - var ent=new Entry(); - ent.invisible_char='~'; - ent.invisible_char_set=true; - ent.visibility=false; - ent.show(); - var dialog_box = ((Gtk.Box)dialog.get_content_area ()); - dialog_box.pack_start(ent,false,false,0); - uint32 item_id=0; - dialog.response.connect ((response_id) => { - if(response_id == Gtk.ResponseType.OK){ - tauth.password=ent.text; - Result r=GnomeKeyring.set_network_password_sync(null, - tauth.user , - null /*string? domain*/, - tauth.host, - null /*string? object*/, - tauth.type /*string? protocol*/, - "auth" /*string? authtype*/, - 22 /*uint32 port*/, - tauth.password /*string? password*/, - out item_id); - this.run_command(tauth); - dialog.destroy (); - }else{ - //this.window_set_active(); - dialog.destroy (); - } - }); - - dialog.focus_out_event.connect (() => { - return true; //same bug as discribed in this.focus_out_event - }); - - dialog.show (); - //disable close by window manager - Gdk.Window w = dialog.get_window(); - w.set_functions((Gdk.WMFunction.ALL|Gdk.WMFunction.CLOSE)); - dialog.grab_focus(); - dialog.set_transient_for(vtw); - vtw.hotkey.send_net_active_window(dialog.get_window ()); - dialog.run(); - } - }); - }//if GnomeKeyring.set_default_keyring_sync - }else - run_command(tauth); - #endif - }//try_run_command - - public void run_command(TildaAuth tauth){ - string host_name=tauth.host; - string user_password=tauth.password; - string user_name=tauth.user; - string command=tauth.command; - if(command=="ssh"){ - string port=this.parse_port(ref host_name); - if(port!="") port=" -p "+port; - string cmd="ssh %s@%s %s\n".printf(user_name,host_name,port); - debug("ssh = %s",cmd); - this.vte_term.feed_child(cmd,cmd.length); - }else if(tauth.type=="ssh"){ - string[] commands=command.split(","); - if(commands.length==3 && commands[0]=="ssh" && commands[1].contains("expect-user=") && commands[2].contains("expect-password=")){ - string port=this.parse_port(ref host_name); - if(port!="") port=" -p "+port; - string cmd="ssh %s@%s %s\n".printf(user_name,host_name,port); - debug("ssh = %s",cmd); - this.vte_term.feed_child(cmd,cmd.length); - string tmp=commands[1]; - var idx=tmp.index_of_char('=',0)+1; - string expect_name=tmp.substring(idx,tmp.length-idx); - tmp=commands[2]; - idx=tmp.index_of_char('=',0)+1; - string expect_password=tmp.substring(idx,tmp.length-idx); - user_name+="\n"; - user_password+="\n"; - debug("expect_name=%s expect_password=%s",expect_name,expect_password); - this.expect_and_paste(expect_name,user_name,()=>{ - this.expect_and_paste(expect_password,user_password,()=>{}); - }); - - }else - if(commands.length==2 && commands[0]=="ssh" && commands[1].contains("expect-password=")){ - string port=this.parse_port(ref host_name); - if(port!="") port=" -p "+port; - string cmd="ssh %s@%s %s\n".printf(user_name,host_name,port); - debug("ssh = %s",cmd); - this.vte_term.feed_child(cmd,cmd.length); - string tmp=commands[1]; - var idx=tmp.index_of_char('=',0)+1; - string expect_password=tmp.substring(idx,tmp.length-idx); - user_name+="\n"; - user_password+="\n"; - debug(" expect_password=%s",expect_password); - this.expect_and_paste(expect_password,user_password,()=>{}); - } - else - if(commands.length==2 && commands[0]=="ssh" && commands[1].contains("paste-password")){ - debug(" paste-password=%s",user_password); - user_password+="\n"; - this.vte_term.feed_child(user_password,user_password.length); - } - }/*else if(){ - }*/ - //tauth.unref();//not needed - }//run_command - - public void lock_setting(VTT_LOCK_SETTING l){ - if(!this.is_locked(l)) - this.lock_settings.append_val(l); - } - - public bool is_locked(VTT_LOCK_SETTING locked_s){ - bool ret=false; - //foreach(var l in this.lock_settings){ - for (int i = 0; i < this.lock_settings.length ; i++) { - if( locked_s == this.lock_settings.index(i) ){ - ret=true; - } - } - return ret; - } + var res=GnomeKeyring.set_default_keyring_sync (vtw.conf.get_string("terminal_default_keyring","altyo")); + if(res!=Result.OK) + debug("GnomeKeyring.set_default_keyring_sync error"); + else{ + //unowned + Info info=null; + GnomeKeyring.get_info_sync (vtw.conf.get_string("terminal_default_keyring","altyo"), out info) ; + if(info!=null){ + debug("Update keyring info..."); + info.set_lock_timeout(60*3);//lock after 3 min + info.set_lock_on_idle(true); + GnomeKeyring.set_info_sync (vtw.conf.get_string("terminal_default_keyring","altyo"), info) ; + } + + GnomeKeyring.find_network_password (tauth.user, null, tauth.host, null, tauth.type, "auth", 0, (result, list)=>{ + + debug("find_network_password done=%d",result); + if (result == Result.OK && list.length () > 0) { + weak NetworkPasswordData npd = (NetworkPasswordData) list.first().data; + if (npd.authtype == "auth") { + tauth.password=npd.password; + this.run_command(tauth); + } + }else{ + var dialog = new MessageDialog (null, (DialogFlags.DESTROY_WITH_PARENT | DialogFlags.MODAL), MessageType.QUESTION, ButtonsType.OK_CANCEL, "Password not foud!\n create new one?"); + var ent=new Entry(); + ent.invisible_char='~'; + ent.invisible_char_set=true; + ent.visibility=false; + ent.show(); + var dialog_box = ((Gtk.Box)dialog.get_content_area ()); + dialog_box.pack_start(ent,false,false,0); + uint32 item_id=0; + dialog.response.connect ((response_id) => { + if(response_id == Gtk.ResponseType.OK){ + tauth.password=ent.text; + Result r=GnomeKeyring.set_network_password_sync(null, + tauth.user , + null /*string? domain*/, + tauth.host, + null /*string? object*/, + tauth.type /*string? protocol*/, + "auth" /*string? authtype*/, + 22 /*uint32 port*/, + tauth.password /*string? password*/, + out item_id); + this.run_command(tauth); + dialog.destroy (); + }else{ + //this.window_set_active(); + dialog.destroy (); + } + }); + + dialog.focus_out_event.connect (() => { + return true; //same bug as discribed in this.focus_out_event + }); + + dialog.show (); + //disable close by window manager + Gdk.Window w = dialog.get_window(); + w.set_functions((Gdk.WMFunction.ALL|Gdk.WMFunction.CLOSE)); + dialog.grab_focus(); + dialog.set_transient_for(vtw); + vtw.hotkey.send_net_active_window(dialog.get_window ()); + dialog.run(); + } + }); + }//if GnomeKeyring.set_default_keyring_sync + }else + run_command(tauth); + #endif + }//try_run_command + + public void run_command(TildaAuth tauth){ + string host_name=tauth.host; + string user_password=tauth.password; + string user_name=tauth.user; + string command=tauth.command; + if(command=="ssh"){ + string port=this.parse_port(ref host_name); + if(port!="") port=" -p "+port; + string cmd="ssh %s@%s %s\n".printf(user_name,host_name,port); + debug("ssh = %s",cmd); + this.vte_term.feed_child(cmd,cmd.length); + }else if(tauth.type=="ssh"){ + string[] commands=command.split(","); + if(commands.length==3 && commands[0]=="ssh" && commands[1].contains("expect-user=") && commands[2].contains("expect-password=")){ + string port=this.parse_port(ref host_name); + if(port!="") port=" -p "+port; + string cmd="ssh %s@%s %s\n".printf(user_name,host_name,port); + debug("ssh = %s",cmd); + this.vte_term.feed_child(cmd,cmd.length); + string tmp=commands[1]; + var idx=tmp.index_of_char('=',0)+1; + string expect_name=tmp.substring(idx,tmp.length-idx); + tmp=commands[2]; + idx=tmp.index_of_char('=',0)+1; + string expect_password=tmp.substring(idx,tmp.length-idx); + user_name+="\n"; + user_password+="\n"; + debug("expect_name=%s expect_password=%s",expect_name,expect_password); + this.expect_and_paste(expect_name,user_name,()=>{ + this.expect_and_paste(expect_password,user_password,()=>{}); + }); + + }else + if(commands.length==2 && commands[0]=="ssh" && commands[1].contains("expect-password=")){ + string port=this.parse_port(ref host_name); + if(port!="") port=" -p "+port; + string cmd="ssh %s@%s %s\n".printf(user_name,host_name,port); + debug("ssh = %s",cmd); + this.vte_term.feed_child(cmd,cmd.length); + string tmp=commands[1]; + var idx=tmp.index_of_char('=',0)+1; + string expect_password=tmp.substring(idx,tmp.length-idx); + user_name+="\n"; + user_password+="\n"; + debug(" expect_password=%s",expect_password); + this.expect_and_paste(expect_password,user_password,()=>{}); + } + else + if(commands.length==2 && commands[0]=="ssh" && commands[1].contains("paste-password")){ + debug(" paste-password=%s",user_password); + user_password+="\n"; + this.vte_term.feed_child(user_password,user_password.length); + } + }/*else if(){ + }*/ + //tauth.unref();//not needed + }//run_command + + public void lock_setting(VTT_LOCK_SETTING l){ + if(!this.is_locked(l)) + this.lock_settings.append_val(l); + } + + public bool is_locked(VTT_LOCK_SETTING locked_s){ + bool ret=false; + //foreach(var l in this.lock_settings){ + for (int i = 0; i < this.lock_settings.length ; i++) { + if( locked_s == this.lock_settings.index(i) ){ + ret=true; + } + } + return ret; + } } diff --git a/altyo_window.vala b/altyo_window.vala index 9cdc85d..8c30592 100644 --- a/altyo_window.vala +++ b/altyo_window.vala @@ -19,74 +19,74 @@ using Gtk; using Cairo; public class point_a { - public unowned Gtk.ActionGroup ag; - public StringBuilder sb; - public point_a(Gtk.ActionGroup ag) { - this.ag=ag; - this.sb=new StringBuilder(); - } + public unowned Gtk.ActionGroup ag; + public StringBuilder sb; + public point_a(Gtk.ActionGroup ag) { + this.ag=ag; + this.sb=new StringBuilder(); + } } public enum WStates{ - VISIBLE, - HIDDEN - } + VISIBLE, + HIDDEN + } public enum TASKS{ - TERMINALS, - QLIST - } + TERMINALS, + QLIST + } public enum TAB_SORT_ORDER{ - NONE, - HOSTNAME - } + NONE, + HOSTNAME + } public enum SEARCH_MODE{ - SEARCH_IN_TEXT, - SEARCH_IN_NAME - } + SEARCH_IN_TEXT, + SEARCH_IN_NAME + } public enum NEW_TAB_MODE{ - RIGHT_NEXT, - FAR_RIGHT - } + RIGHT_NEXT, + FAR_RIGHT + } public enum OPTIONS_TAB{ - SEARCH, - ENCODINGS - } + SEARCH, + ENCODINGS + } public enum MYWINStates{ - NULL, - MAXIMIZED, - FULLSCREEN - } + NULL, + MAXIMIZED, + FULLSCREEN + } public enum HVBOXDISPLAY{ - VISIBLE, - HIDDEN, - HIDEIFONETAB - } + VISIBLE, + HIDDEN, + HIDEIFONETAB + } public delegate void MyCallBack(Gtk.Action a); public class VTMainWindow : Window{ - public OffscreenWindow pixwin; - public AYObject ayobject; - - private int my_window_state; - private bool wait_window_manager=false; - private bool not_configured=true;//prevent some errors while starting - private uint wait_for_window_position_update=0; - private uint on_monitor_changed_force_new_position_glib_timer_id=0; - private uint update_position_size_for_glib_timer_id=0; - private bool _maximized=false;//cached value - public bool maximized { + public OffscreenWindow pixwin; + public AYObject ayobject; + + private int my_window_state; + private bool wait_window_manager=false; + private bool not_configured=true;//prevent some errors while starting + private uint wait_for_window_position_update=0; + private uint on_monitor_changed_force_new_position_glib_timer_id=0; + private uint update_position_size_for_glib_timer_id=0; + private bool _maximized=false;//cached value + public bool maximized { get { var win = this.get_window(); if( win!=null ){ if( (win.get_state() & Gdk.WindowState.MAXIMIZED) == Gdk.WindowState.MAXIMIZED){ _maximized=true; this.get_style_context().add_class("window_maximized"); - return true; + return true; }else{ _maximized=false; this.get_style_context().remove_class("window_maximized"); @@ -119,313 +119,313 @@ public class VTMainWindow : Window{ } } }//set - }//public bool maximized - - private bool _fullscreened=false; - public bool fullscreened { - get{ - var win = this.get_window(); - if( win!=null ){ - if( (win.get_state() & Gdk.WindowState.FULLSCREEN) == Gdk.WindowState.FULLSCREEN ){ - _fullscreened=true; - return true; - }else{ - _fullscreened=false; - return false; - } - }else - return _fullscreened; - } - set{ - if(value == true){ - this.my_window_state |= MYWINStates.FULLSCREEN; - this.fullscreen(); - }else{ - this.my_window_state &= ~MYWINStates.FULLSCREEN; - - if(this.fullscreened){ - this.unfullscreen(); - } - } - } - }//public bool fullscreen - - public bool allow_update_size { - get{ -//~ debug("maximized=%d fullscreened=%d update_maximized_size=%d update_minimized_size=%d pull_animation_active=%d pull_active=%d standalone_mode=%d wait_window_manager=%d" , -//~ (int)this.maximized, -//~ (int)this.fullscreened, -//~ (int)this.update_maximized_size, -//~ (int)this.update_minimized_size, -//~ (int)this.pull_animation_active, -//~ (int)this.pull_active, -//~ (int)this.conf.standalone_mode, -//~ (int)this.wait_window_manager); - - if(!this.conf.standalone_mode && - !this.maximized && - !this.fullscreened && - !this.pull_animation_active && - !this.pull_active && - !this.not_configured && - !this.wait_window_manager) - return true; - else - return false; - - } - } - public bool fullscreen_on_maximize=false; - public bool animation_enabled = true; - public int animation_speed=20;//50hz - public int pull_steps=20; - public bool pull_animation_active = false; - public bool pull_active = false; - public bool pull_update_maximize_size = false; /*used to update size on pull down*/ - public WStates current_state {get;set; default = WStates.VISIBLE;} - public unowned MySettings conf {get;set; default = null;} - public bool keep_above=true; - public bool orig_stick=true; - - public PanelHotkey hotkey; - public bool mouse_follow=false; - public unowned Widget prev_focus=null; - - private int pull_step = 0; - public int orig_x = 0; - public int orig_y = 0; - private int pull_w = 0; - private int pull_h = 0; - private int pull_x = 0; - private int pull_y = 0; - private int orig_h_tasks_notebook=0; - private int orig_w_tasks_notebook=0; - private int orig_h_main_vbox=0; - private int orig_w_main_vbox=0; - private int orig_monitor=-1; + }//public bool maximized + + private bool _fullscreened=false; + public bool fullscreened { + get{ + var win = this.get_window(); + if( win!=null ){ + if( (win.get_state() & Gdk.WindowState.FULLSCREEN) == Gdk.WindowState.FULLSCREEN ){ + _fullscreened=true; + return true; + }else{ + _fullscreened=false; + return false; + } + }else + return _fullscreened; + } + set{ + if(value == true){ + this.my_window_state |= MYWINStates.FULLSCREEN; + this.fullscreen(); + }else{ + this.my_window_state &= ~MYWINStates.FULLSCREEN; + + if(this.fullscreened){ + this.unfullscreen(); + } + } + } + }//public bool fullscreen + + public bool allow_update_size { + get{ +//~ debug("maximized=%d fullscreened=%d update_maximized_size=%d update_minimized_size=%d pull_animation_active=%d pull_active=%d standalone_mode=%d wait_window_manager=%d" , +//~ (int)this.maximized, +//~ (int)this.fullscreened, +//~ (int)this.update_maximized_size, +//~ (int)this.update_minimized_size, +//~ (int)this.pull_animation_active, +//~ (int)this.pull_active, +//~ (int)this.conf.standalone_mode, +//~ (int)this.wait_window_manager); + + if(!this.conf.standalone_mode && + !this.maximized && + !this.fullscreened && + !this.pull_animation_active && + !this.pull_active && + !this.not_configured && + !this.wait_window_manager) + return true; + else + return false; + + } + } + public bool fullscreen_on_maximize=false; + public bool animation_enabled = true; + public int animation_speed=20;//50hz + public int pull_steps=20; + public bool pull_animation_active = false; + public bool pull_active = false; + public bool pull_update_maximize_size = false; /*used to update size on pull down*/ + public WStates current_state {get;set; default = WStates.VISIBLE;} + public unowned MySettings conf {get;set; default = null;} + public bool keep_above=true; + public bool orig_stick=true; + + public PanelHotkey hotkey; + public bool mouse_follow=false; + public unowned Widget prev_focus=null; + + private int pull_step = 0; + public int orig_x = 0; + public int orig_y = 0; + private int pull_w = 0; + private int pull_h = 0; + private int pull_x = 0; + private int pull_y = 0; + private int orig_h_tasks_notebook=0; + private int orig_w_tasks_notebook=0; + private int orig_h_main_vbox=0; + private int orig_w_main_vbox=0; + private int orig_monitor=-1; private Xkb.State xkbstate; - public int position = 1; - public bool config_maximized=false; - public bool start_maximized=false; - public bool pull_maximized=false; - public bool temporary_maximized=false; - public bool allow_close=false; - public bool gravity_north_west=true; - public bool autohide=false; - - private uint32 last_focus_out_event_time; - private unowned Gdk.Window ignore_last_active_window = null; - private DateTime on_monitors_changed_start_time = null; - - public VTMainWindow(WindowType type) { - Object(type:type); - } - - construct { - this.title = "AltYo"; - //this.border_width = 0; - this.skip_taskbar_hint = true; - this.urgency_hint = true; - this.set_decorated (false); - this.resizable = true;//we need resize! - this.set_has_resize_grip(false);//but hide grip - //this.set_focus_on_map (true); - //this.set_accept_focus (true); - //this.set_keep_above(true); - //this.stick (); - this.pixwin = new OffscreenWindow (); - this.pixwin.name="OffscreenWindow"; - this.pixwin.show(); - this.pixwin.damage_event.connect((event)=>{ - if(this.visible && (this.pull_animation_active || this.pull_active)){ - debug("pixwin.damage_event"); - var w = this.get_window(); + public int position = 1; + public bool config_maximized=false; + public bool start_maximized=false; + public bool pull_maximized=false; + public bool temporary_maximized=false; + public bool allow_close=false; + public bool gravity_north_west=true; + public bool autohide=false; + + private uint32 last_focus_out_event_time; + private unowned Gdk.Window ignore_last_active_window = null; + private DateTime on_monitors_changed_start_time = null; + + public VTMainWindow(WindowType type) { + Object(type:type); + } + + construct { + this.title = "AltYo"; + //this.border_width = 0; + this.skip_taskbar_hint = true; + this.urgency_hint = true; + this.set_decorated (false); + this.resizable = true;//we need resize! + this.set_has_resize_grip(false);//but hide grip + //this.set_focus_on_map (true); + //this.set_accept_focus (true); + //this.set_keep_above(true); + //this.stick (); + this.pixwin = new OffscreenWindow (); + this.pixwin.name="OffscreenWindow"; + this.pixwin.show(); + this.pixwin.damage_event.connect((event)=>{ + if(this.visible && (this.pull_animation_active || this.pull_active)){ + debug("pixwin.damage_event"); + var w = this.get_window(); if(w!=null) w.invalidate_rect(null,false); - - } - }); - //this.set_app_paintable(true); - //this.set_double_buffered(false); - -//~ Gdk.RGBA c = Gdk.RGBA(); -//~ c.parse("#000000");//black todo: make same color as vte -//~ c.alpha = 0.0;//transparency - - this.set_visual (this.screen.get_rgba_visual ());//transparancy - this.set_app_paintable(true);//do not draw backgroud -//~ this.override_background_color(StateFlags.NORMAL, c); - //this.pixwin.set_visual (this.screen.get_rgba_visual ());//transparancy - //this.pixwin.set_app_paintable(true);//do not draw backgroud - } - - public void CreateVTWindow(MySettings conf) { - this.conf=conf; - - Image img = new Image.from_resource ("/org/gnome/altyo/altyo.svg"); - this.set_icon(img.pixbuf); - - this.keep_above=conf.get_boolean("keep_above_at_startup",this.keep_above); - if(!this.keep_above){ - this.skip_taskbar_hint = false; - this.set_keep_above(false); - } - /* since VTE 2.91, - * needed for PanelHotkey to receive X.EventType.PropertyNotify events - * */ - var gdkwin = this.get_screen().get_root_window(); - gdkwin.set_events(gdkwin.get_events()|Gdk.EventMask.PROPERTY_CHANGE_MASK); - - this.hotkey = new PanelHotkey (); - this.hotkey.on_active_window_change.connect(this.check_focusout); - this.reconfigure();//window - this.not_configured=false; - - this.ayobject= new AYObject(this,conf); - this.add(this.ayobject.main_vbox); - - - this.delete_event.connect (()=>{ - if(this.allow_close==false){ - this.ayobject.ShowQuitDialog(); - return true;//prevent close - } - return false;//default is allow - }); - - this.destroy.connect (()=>{ - this.hide(); - this.hotkey.on_active_window_change.disconnect(this.check_focusout); - this.hotkey.unref();//destroy - this.ayobject.save_configuration(); - this.conf.save(); - unowned Gtk.Widget ch=this.pixwin.get_child(); - if(ch is Gtk.Widget) - ch.destroy(); - Gtk.main_quit(); - }); - - this.conf.on_load.connect(()=>{ - this.reconfigure(); - if(this.current_state==WStates.VISIBLE){ - this.configure_position(); - this.update_position_size(); - /*update maximize state according to config_maximized*/ - if(!this.config_maximized && this.maximized){ - this.maximized=false; - }else - if(this.config_maximized && !this.maximized){ - this.maximized=true; - } - } - }); - - this.check_monitor_and_configure_position(); - - if(this.config_maximized && conf.get_boolean("start_hidden",false)){ - this.ayobject.on_maximize(false); - this.maximized=true; - this.update_position_size(false); - }else{ - this.update_position_size(false); - } - debug("CreateVTWindow end"); - - if(!this.conf.standalone_mode){ - if ( conf.get_boolean("start_hidden",false) ){ - this.pull_up();//all workarounds is inside pull_up,pull_down,update_position_size - this.pull_maximized=this.start_maximized; - }else{ - this.show(); - if(!this.start_maximized){ - this.update_position_size(); - }else{ - this.maximized=true; - this.update_events();//process maximize event - } - this.window_set_active(); - } - }else{ - this.set_wmclass("altyo-tiling","Altyo"); - this.set_decorated (true); - this.ayobject.on_maximize(false); - this.ayobject.on_maximize(true); - //this.update_position_size(false); - var should_be_h = this.ayobject.get_altyo_height(this.conf.standalone_mode); - this.set_default_size(this.ayobject.terminal_width,should_be_h); - this.show(); - - - this.window_set_active(); - } - GLib.Idle.add(this.ayobject.create_tabs); - if(!this.conf.standalone_mode){ - unowned Gdk.Screen gscreen = this.get_screen (); - gscreen.monitors_changed.connect (()=>{ - GLib.Timeout.add(1000,this.on_monitors_changed);//wait for some time until the monitor is configured - }); - } - debug("end win show"); - - } - - public bool on_monitors_changed(){ - debug("gscreen.monitors_changed"); - if(this.current_state == WStates.VISIBLE){ - this.check_monitor_and_configure_position();//check if was attached window_default_monitor - if( this.configure_position() ) - this.update_position_size(); - } - return false; //stop the timer - } - - private void check_monitor_and_configure_position(){ - /* move window to appropriate monitor - * */ - string? cfg_monitor = this.conf.get_string("window_default_monitor",""); - if(cfg_monitor!=null && cfg_monitor!=""){ - int x,y; - this.get_position (out x, out y); - unowned Gdk.Screen gscreen = this.get_screen (); - - var current_monitor = gscreen.get_monitor_at_point (this.orig_x,this.orig_y); - var current_monitor_name = gscreen.get_monitor_plug_name (current_monitor); - if(current_monitor_name!=null && current_monitor_name!=cfg_monitor){ - for(var i=0;i{ + if(this.allow_close==false){ + this.ayobject.ShowQuitDialog(); + return true;//prevent close + } + return false;//default is allow + }); + + this.destroy.connect (()=>{ + this.hide(); + this.hotkey.on_active_window_change.disconnect(this.check_focusout); + this.hotkey.unref();//destroy + this.ayobject.save_configuration(); + this.conf.save(); + unowned Gtk.Widget ch=this.pixwin.get_child(); + if(ch is Gtk.Widget) + ch.destroy(); + Gtk.main_quit(); + }); + + this.conf.on_load.connect(()=>{ + this.reconfigure(); + if(this.current_state==WStates.VISIBLE){ + this.configure_position(); + this.update_position_size(); + /*update maximize state according to config_maximized*/ + if(!this.config_maximized && this.maximized){ + this.maximized=false; + }else + if(this.config_maximized && !this.maximized){ + this.maximized=true; + } + } + }); + + this.check_monitor_and_configure_position(); + + if(this.config_maximized && conf.get_boolean("start_hidden",false)){ + this.ayobject.on_maximize(false); + this.maximized=true; + this.update_position_size(false); + }else{ + this.update_position_size(false); + } + debug("CreateVTWindow end"); + + if(!this.conf.standalone_mode){ + if ( conf.get_boolean("start_hidden",false) ){ + this.pull_up();//all workarounds is inside pull_up,pull_down,update_position_size + this.pull_maximized=this.start_maximized; + }else{ + this.show(); + if(!this.start_maximized){ + this.update_position_size(); + }else{ + this.maximized=true; + this.update_events();//process maximize event + } + this.window_set_active(); + } + }else{ + this.set_wmclass("altyo-tiling","Altyo"); + this.set_decorated (true); + this.ayobject.on_maximize(false); + this.ayobject.on_maximize(true); + //this.update_position_size(false); + var should_be_h = this.ayobject.get_altyo_height(this.conf.standalone_mode); + this.set_default_size(this.ayobject.terminal_width,should_be_h); + this.show(); + + + this.window_set_active(); + } + GLib.Idle.add(this.ayobject.create_tabs); + if(!this.conf.standalone_mode){ + unowned Gdk.Screen gscreen = this.get_screen (); + gscreen.monitors_changed.connect (()=>{ + GLib.Timeout.add(1000,this.on_monitors_changed);//wait for some time until the monitor is configured + }); + } + debug("end win show"); + + } + + public bool on_monitors_changed(){ + debug("gscreen.monitors_changed"); + if(this.current_state == WStates.VISIBLE){ + this.check_monitor_and_configure_position();//check if was attached window_default_monitor + if( this.configure_position() ) + this.update_position_size(); + } + return false; //stop the timer + } + + private void check_monitor_and_configure_position(){ + /* move window to appropriate monitor + * */ + string? cfg_monitor = this.conf.get_string("window_default_monitor",""); + if(cfg_monitor!=null && cfg_monitor!=""){ + int x,y; + this.get_position (out x, out y); + unowned Gdk.Screen gscreen = this.get_screen (); + + var current_monitor = gscreen.get_monitor_at_point (this.orig_x,this.orig_y); + var current_monitor_name = gscreen.get_monitor_plug_name (current_monitor); + if(current_monitor_name!=null && current_monitor_name!=cfg_monitor){ + for(var i=0;i