don't freeze gui during long makepkg tasks and avoid zombis with pamac-tray
This commit is contained in:
parent
3b4a29bcf9
commit
10c2dfebd5
@ -19,9 +19,10 @@
|
|||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
from gi.repository import Gtk, GObject, Notify
|
from gi.repository import Gtk, GObject, Notify
|
||||||
from subprocess import Popen
|
from subprocess import call
|
||||||
import dbus
|
import dbus
|
||||||
from dbus.mainloop.glib import DBusGMainLoop
|
from dbus.mainloop.glib import DBusGMainLoop
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
from pamac import common
|
from pamac import common
|
||||||
|
|
||||||
@ -64,10 +65,10 @@ class Tray:
|
|||||||
self.update_icon(icon, info)
|
self.update_icon(icon, info)
|
||||||
|
|
||||||
def execute_update(self, widget, event, data = None):
|
def execute_update(self, widget, event, data = None):
|
||||||
Popen(['/usr/bin/pamac-updater'])
|
Thread(target = call, args = (['/usr/bin/pamac-updater'],)).start()
|
||||||
|
|
||||||
def execute_manager(self, widget, event, data = None):
|
def execute_manager(self, widget, event, data = None):
|
||||||
Popen(['/usr/bin/pamac-manager'])
|
Thread(target = call, args = (['/usr/bin/pamac-manager'],)).start()
|
||||||
|
|
||||||
def quit_tray(self, widget, data = None):
|
def quit_tray(self, widget, data = None):
|
||||||
Gtk.main_quit()
|
Gtk.main_quit()
|
||||||
@ -80,7 +81,7 @@ class Tray:
|
|||||||
|
|
||||||
def activate_cb(self, widget, data = None):
|
def activate_cb(self, widget, data = None):
|
||||||
if icon == update_icon:
|
if icon == update_icon:
|
||||||
Popen(['/usr/bin/pamac-updater'])
|
Thread(target = call, args = (['/usr/bin/pamac-updater'],)).start()
|
||||||
|
|
||||||
def update_icon(self, icon, info):
|
def update_icon(self, icon, info):
|
||||||
self.statusIcon.set_from_file(icon)
|
self.statusIcon.set_from_file(icon)
|
||||||
@ -90,7 +91,7 @@ class Tray:
|
|||||||
self.statusIcon.set_visible(boolean)
|
self.statusIcon.set_visible(boolean)
|
||||||
|
|
||||||
def refresh():
|
def refresh():
|
||||||
Popen(['/usr/bin/pamac-refresh'])
|
Thread(target = call, args = (['/usr/bin/pamac-refresh'],)).start()
|
||||||
|
|
||||||
def set_icon(update_data):
|
def set_icon(update_data):
|
||||||
global icon
|
global icon
|
||||||
|
@ -29,6 +29,7 @@ import fnmatch
|
|||||||
#from urllib.parse import urlparse
|
#from urllib.parse import urlparse
|
||||||
import dbus
|
import dbus
|
||||||
from dbus.mainloop.glib import DBusGMainLoop
|
from dbus.mainloop.glib import DBusGMainLoop
|
||||||
|
import signal
|
||||||
|
|
||||||
from pamac import config, common, aur
|
from pamac import config, common, aur
|
||||||
|
|
||||||
@ -134,18 +135,6 @@ def config_dbus_signals():
|
|||||||
bus.add_signal_receiver(log_error, dbus_interface = "org.manjaro.pamac", signal_name = "EmitLogError")
|
bus.add_signal_receiver(log_error, dbus_interface = "org.manjaro.pamac", signal_name = "EmitLogError")
|
||||||
bus.add_signal_receiver(log_warning, dbus_interface = "org.manjaro.pamac", signal_name = "EmitLogWarning")
|
bus.add_signal_receiver(log_warning, dbus_interface = "org.manjaro.pamac", signal_name = "EmitLogWarning")
|
||||||
|
|
||||||
def write_to_buffer(fd, condition):
|
|
||||||
if condition == GObject.IO_IN: # if there's something interesting to read
|
|
||||||
line = fd.readline().decode(encoding='UTF-8')
|
|
||||||
#print(line.rstrip('\n'))
|
|
||||||
progress_buffer.insert_at_cursor(line)
|
|
||||||
progress_bar.pulse()
|
|
||||||
while Gtk.events_pending():
|
|
||||||
Gtk.main_iteration()
|
|
||||||
return True # FUNDAMENTAL, otherwise the callback isn't recalled
|
|
||||||
else:
|
|
||||||
return False # Raised an error: exit
|
|
||||||
|
|
||||||
def action_handler(action):
|
def action_handler(action):
|
||||||
progress_label.set_text(action)
|
progress_label.set_text(action)
|
||||||
|
|
||||||
@ -468,16 +457,34 @@ def prepare(**trans_flags):
|
|||||||
return(error)
|
return(error)
|
||||||
|
|
||||||
def check_finished_build(data):
|
def check_finished_build(data):
|
||||||
|
def handle_timeout(*args):
|
||||||
|
raise Exception('timeout')
|
||||||
|
|
||||||
global to_build
|
global to_build
|
||||||
global build_proc
|
global build_proc
|
||||||
path = data[0]
|
path = data[0]
|
||||||
pkg = data[1]
|
pkg = data[1]
|
||||||
if build_proc.poll() is None:
|
if build_proc.poll() is None:
|
||||||
|
# Build no finished : read stdout to push it to text_buffer
|
||||||
|
# add a timeout to stop reading stdout if too long
|
||||||
|
# so the gui won't freeze
|
||||||
|
signal.signal(signal.SIGALRM, handle_timeout)
|
||||||
|
signal.setitimer(signal.ITIMER_REAL, 0.05) # 50 ms timeout
|
||||||
|
try:
|
||||||
|
line = build_proc.stdout.readline().decode(encoding='UTF-8')
|
||||||
|
#print(line.rstrip('\n'))
|
||||||
|
progress_buffer.insert_at_cursor(line)
|
||||||
progress_bar.pulse()
|
progress_bar.pulse()
|
||||||
while Gtk.events_pending():
|
while Gtk.events_pending():
|
||||||
Gtk.main_iteration()
|
Gtk.main_iteration()
|
||||||
|
except Exception:
|
||||||
|
while Gtk.events_pending():
|
||||||
|
Gtk.main_iteration()
|
||||||
|
finally:
|
||||||
|
signal.alarm(0)
|
||||||
return True
|
return True
|
||||||
elif build_proc.poll() == 0:
|
elif build_proc.poll() == 0:
|
||||||
|
# Build successfully finished
|
||||||
built = []
|
built = []
|
||||||
# parse again PKGBUILD to have new pkg objects in case of a pkgver() function
|
# parse again PKGBUILD to have new pkg objects in case of a pkgver() function
|
||||||
# was used so pkgver was changed during build process
|
# was used so pkgver was changed during build process
|
||||||
@ -525,6 +532,7 @@ def check_finished_build(data):
|
|||||||
action_long_handler(_('Build process failed.'))
|
action_long_handler(_('Build process failed.'))
|
||||||
return False
|
return False
|
||||||
elif build_proc.poll() == 1:
|
elif build_proc.poll() == 1:
|
||||||
|
# Build finish with an error
|
||||||
ProgressCancelButton.set_visible(False)
|
ProgressCancelButton.set_visible(False)
|
||||||
ProgressCloseButton.set_visible(True)
|
ProgressCloseButton.set_visible(True)
|
||||||
action_long_handler(_('Build process failed.'))
|
action_long_handler(_('Build process failed.'))
|
||||||
@ -625,10 +633,9 @@ def build_next():
|
|||||||
progress_expander.set_expanded(True)
|
progress_expander.set_expanded(True)
|
||||||
ProgressWindow.show()
|
ProgressWindow.show()
|
||||||
build_proc = subprocess.Popen(["makepkg", "-cf"], cwd = path, stdout = subprocess.PIPE, stderr=subprocess.STDOUT)
|
build_proc = subprocess.Popen(["makepkg", "-cf"], cwd = path, stdout = subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
GObject.io_add_watch(build_proc.stdout, GObject.IO_IN, write_to_buffer)
|
|
||||||
while Gtk.events_pending():
|
while Gtk.events_pending():
|
||||||
Gtk.main_iteration()
|
Gtk.main_iteration()
|
||||||
GObject.timeout_add(500, check_finished_build, (path, pkg))
|
GObject.timeout_add(100, check_finished_build, (path, pkg))
|
||||||
|
|
||||||
def finalize():
|
def finalize():
|
||||||
if To_Add() or To_Remove():
|
if To_Add() or To_Remove():
|
||||||
|
Loading…
Reference in New Issue
Block a user