You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As gnome shell have only one process call spaw sync block the compositor thread. This is ofcurse not a good idea and in some context can freeze the whole shell or make it pretty slower. One way to detect when a compositor is blocked is reproduce a video while the synchronous call is occurring. You will listen the effect of block the compositor.
Here you are calling GLib.spawn_command_line_sync and this is what is not a good idea. Anyway, it's never a good idea in gnome shell whatever this occurs.
Find an asynchronous solution it' s a little hard, to be honest, that's why i make a class to be used in context like that and not need to repeat again that thing anymore. It' s used by some people, so you can read understand the code in a context, if you see that examples.
You sure will need to update it to a new gjs class style if you want to use it:
functionTerminalReader(command,callback){this._init(command,callback);}TerminalReader.prototype={_init: function(command,callback){this._callbackPipe=callback;this._commandPipe=command;this.idle=true;this._childWatch=null;},executeReader: function(){if(this.idle){this.idle=false;try{let[success,argv]=GLib.shell_parse_argv("sh -c '"+this._commandPipe+"'");if(success){let[exit,pid,stdin,stdout,stderr]=GLib.spawn_async_with_pipes(null,/* cwd */argv,/* args */null,/* env */GLib.SpawnFlags.SEARCH_PATH|GLib.SpawnFlags.DO_NOT_REAP_CHILD,/*Use env path and no repet*/null/* child_setup */);this._childPid=pid;this._stdin=newGio.UnixOutputStream({fd: stdin,close_fd: true});this._stdout=newGio.UnixInputStream({fd: stdout,close_fd: true});this._stderr=newGio.UnixInputStream({fd: stderr,close_fd: true});// We need this one too, even if don't actually care of what the process// has to say on stderr, because otherwise the fd opened by g_spawn_async_with_pipes// is kept open indefinitelythis._stderrStream=newGio.DataInputStream({base_stream: this._stderr});this._dataStdout=newGio.DataInputStream({base_stream: this._stdout});this._cancellableStderrStream=newGio.Cancellable();this._cancellableStdout=newGio.Cancellable();this.resOut=1;this._readStdout();this.resErr=1;this._readStderror();this._childWatch=GLib.child_watch_add(GLib.PRIORITY_DEFAULT,pid,Lang.bind(this,function(pid,status,requestObj){GLib.source_remove(this._childWatch);this._childWatch=null;this._stdin.close(null);this.idle=true;}));}//throw}catch(err){if(err.code==GLib.SpawnError.G_SPAWN_ERROR_NOENT){err.message=_("Command not found.");}else{// The exception from gjs contains an error string like:// Error invoking GLib.spawn_command_line_async: Failed to// execute child process "foo" (No such file or directory)// We are only interested in the part in the parentheses. (And// we can't pattern match the text, since it gets localized.)err.message=err.message.replace(/.*\((.+)\)/,'$1');}throwerr;}}},destroy: function(){try{if(this._childWatch){GLib.source_remove(this._childWatch);this._childWatch=null;}if(!this._dataStdout.is_closed()){this._cancellableStdout.cancel();this._stdout.close_async(0,null,Lang.bind(this,this.closeStdout));}if(!this._stderrStream.is_closed()){this._cancellableStderrStream.cancel();this._stderrStream.close_async(0,null,Lang.bind(this,this.closeStderrStream));}this._stdin.close(null);this.idle=true;}catch(e){Main.notify("Error on close"+this._dataStdout.is_closed(),e.message);}},closeStderrStream: function(std,result){try{std.close_finish(result);}catch(e){std.close_async(0,null,Lang.bind(this,this.closeStderrStream));}},closeStdout: function(std,result){try{std.close_finish(result);}catch(e){std.close_async(0,null,Lang.bind(this,this.closeStderrStream));}},_readStdout: function(){this._dataStdout.fill_async(-1,GLib.PRIORITY_DEFAULT,this._cancellableStdout,Lang.bind(this,function(stream,result){try{if(!this._dataStdout.is_closed()){if(this.resOut!=-1)this.resOut=this._dataStdout.fill_finish(result);// end of fileif(this.resOut==0){letval=stream.peek_buffer().toString();if(val!="")this._callbackPipe(this._commandPipe,true,val);this._stdout.close(this._cancellableStdout);}else{// Try to read morethis._dataStdout.set_buffer_size(2*this._dataStdout.get_buffer_size());this._readStdout();}}}catch(e){global.log(e.toString());}}));},_readStderror: function(){this._stderrStream.fill_async(-1,GLib.PRIORITY_DEFAULT,this._cancellableStderrStream,Lang.bind(this,function(stream,result){try{if(!this._stderrStream.is_closed()){if(this.resErr!=-1)this.resErr=this._stderrStream.fill_finish(result);if(this.resErr==0){// end of fileletval=stream.peek_buffer().toString();if(val!="")this._callbackPipe(this._commandPipe,false,val);this._stderr.close(null);}else{this._stderrStream.set_buffer_size(2*this._stderrStream.get_buffer_size());this._readStderror();}}}catch(e){global.log(e.toString());}}));}};
The text was updated successfully, but these errors were encountered:
As gnome shell have only one process call spaw sync block the compositor thread. This is ofcurse not a good idea and in some context can freeze the whole shell or make it pretty slower. One way to detect when a compositor is blocked is reproduce a video while the synchronous call is occurring. You will listen the effect of block the compositor.
Here you are calling
GLib.spawn_command_line_sync
and this is what is not a good idea. Anyway, it's never a good idea in gnome shell whatever this occurs.Find an asynchronous solution it' s a little hard, to be honest, that's why i make a class to be used in context like that and not need to repeat again that thing anymore. It' s used by some people, so you can read understand the code in a context, if you see that examples.
You sure will need to update it to a new gjs class style if you want to use it:
The text was updated successfully, but these errors were encountered: