Commit 271fd662 authored by louiz’'s avatar louiz’

Entirely remove the g_lock (used to avoid a few race conditions with ncures)

parent ba93f3f2
......@@ -46,7 +46,6 @@ from roster import roster
from size_manager import SizeManager
from text_buffer import TextBuffer
from theming import get_theme
from windows import g_lock
from . import completions
from . import commands
......@@ -1540,41 +1539,39 @@ class Core(object):
"""
Resize the global_information_win only once at each resize.
"""
with g_lock:
if self.information_win_size > tabs.Tab.height - 6:
self.information_win_size = tabs.Tab.height - 6
if tabs.Tab.height < 6:
self.information_win_size = 0
height = (tabs.Tab.height - 1 - self.information_win_size
- tabs.Tab.tab_win_height())
self.information_win.resize(self.information_win_size,
tabs.Tab.width,
height,
0)
if self.information_win_size > tabs.Tab.height - 6:
self.information_win_size = tabs.Tab.height - 6
if tabs.Tab.height < 6:
self.information_win_size = 0
height = (tabs.Tab.height - 1 - self.information_win_size
- tabs.Tab.tab_win_height())
self.information_win.resize(self.information_win_size,
tabs.Tab.width,
height,
0)
def resize_global_info_bar(self):
"""
Resize the GlobalInfoBar only once at each resize
"""
with g_lock:
height, width = self.stdscr.getmaxyx()
if config.get('enable_vertical_tab_list', False):
height, width = self.stdscr.getmaxyx()
if config.get('enable_vertical_tab_list', False):
if self.size.core_degrade_x:
return
try:
height, _ = self.stdscr.getmaxyx()
truncated_win = self.stdscr.subwin(height,
config.get('vertical_tab_list_size', 20),
0, 0)
except:
log.error('Curses error on infobar resize', exc_info=True)
return
self.left_tab_win = windows.VerticalGlobalInfoBar(truncated_win)
elif not self.size.core_degrade_y:
self.tab_win.resize(1, tabs.Tab.width,
tabs.Tab.height - 2, 0)
self.left_tab_win = None
if self.size.core_degrade_x:
return
try:
height, _ = self.stdscr.getmaxyx()
truncated_win = self.stdscr.subwin(height,
config.get('vertical_tab_list_size', 20),
0, 0)
except:
log.error('Curses error on infobar resize', exc_info=True)
return
self.left_tab_win = windows.VerticalGlobalInfoBar(truncated_win)
elif not self.size.core_degrade_y:
self.tab_win.resize(1, tabs.Tab.width,
tabs.Tab.height - 2, 0)
self.left_tab_win = None
def add_message_to_text_buffer(self, buff, txt,
time=None, nickname=None, history=None):
......@@ -1602,30 +1599,27 @@ class Core(object):
# window to each Tab class, so they draw themself in the portion of
# the screen that they can occupy, and we draw the tab list on the
# remaining space, on the left
with g_lock:
height, width = self.stdscr.getmaxyx()
height, width = self.stdscr.getmaxyx()
if (config.get('enable_vertical_tab_list', False) and
not self.size.core_degrade_x):
with g_lock:
try:
scr = self.stdscr.subwin(0,
config.get('vertical_tab_list_size', 20))
except:
log.error('Curses error on resize', exc_info=True)
return
try:
scr = self.stdscr.subwin(0,
config.get('vertical_tab_list_size', 20))
except:
log.error('Curses error on resize', exc_info=True)
return
else:
scr = self.stdscr
tabs.Tab.resize(scr)
self.resize_global_info_bar()
self.resize_global_information_win()
with g_lock:
for tab in self.tabs:
if config.get('lazy_resize', True):
tab.need_resize = True
else:
tab.resize()
if self.tabs:
self.full_screen_redraw()
for tab in self.tabs:
if config.get('lazy_resize', True):
tab.need_resize = True
else:
tab.resize()
if self.tabs:
self.full_screen_redraw()
def read_keyboard(self):
"""
......
......@@ -3,8 +3,6 @@ Size Manager:
used to check size boundaries of the whole window and
specific tabs
"""
from windows import g_lock
THRESHOLD_WIDTH_DEGRADE = 45
THRESHOLD_HEIGHT_DEGRADE = 10
......@@ -27,26 +25,22 @@ class SizeManager(object):
@property
def tab_degrade_x(self):
with g_lock:
_, x = self.tab_scr.getmaxyx()
_, x = self.tab_scr.getmaxyx()
return x < THRESHOLD_WIDTH_DEGRADE
@property
def tab_degrade_y(self):
with g_lock:
y, x = self.tab_scr.getmaxyx()
y, x = self.tab_scr.getmaxyx()
return y < THRESHOLD_HEIGHT_DEGRADE
@property
def core_degrade_x(self):
with g_lock:
y, x = self.core_scr.getmaxyx()
y, x = self.core_scr.getmaxyx()
return x < FULL_WIDTH_DEGRADE
@property
def core_degrade_y(self):
with g_lock:
y, x = self.core_scr.getmaxyx()
y, x = self.core_scr.getmaxyx()
return y < FULL_HEIGHT_DEGRADE
......@@ -35,7 +35,6 @@ from decorators import refresh_wrapper
from logger import logger
from text_buffer import TextBuffer
from theming import get_theme, dump_tuple
from windows import g_lock
# getters for tab colors (lambdas, so that they are dynamic)
......@@ -187,9 +186,8 @@ class Tab(object):
@staticmethod
def resize(scr):
with g_lock:
Tab.height, Tab.width = scr.getmaxyx()
windows.Win._tab_win = scr
Tab.height, Tab.width = scr.getmaxyx()
windows.Win._tab_win = scr
def missing_command_callback(self, command_name):
"""
......
......@@ -2,7 +2,8 @@
Module exporting all the Windows, which are wrappers around curses wins
used to display information on the screen
"""
from . base_wins import Win, g_lock
from . base_wins import Win
from . data_forms import FormWin
from . info_bar import GlobalInfoBar, VerticalGlobalInfoBar
from . info_wins import InfoWin, XMLInfoWin, PrivateInfoWin, MucListInfoWin, \
......
......@@ -32,8 +32,6 @@ allowed_color_digits = ('0', '1', '2', '3', '4', '5', '6', '7')
# text_end are the position delimiting the text in this line.
Line = collections.namedtuple('Line', 'msg start_pos end_pos prepend')
g_lock = RLock()
LINES_NB_LIMIT = 4096
class DummyWin(object):
......@@ -69,8 +67,7 @@ class Win(object):
"""
Override if something has to be done on resize
"""
with g_lock:
self._resize(height, width, y, x)
self._resize(height, width, y, x)
def _refresh(self):
self._win.noutrefresh()
......
......@@ -6,7 +6,7 @@ does not inherit from the Win base class), as it will create the
others when needed.
"""
from . import g_lock, Win
from . import Win
from . inputs import Input
from theming import to_curses_attr, get_theme
......@@ -61,12 +61,11 @@ class ColoredLabel(Win):
self.refresh()
def refresh(self):
with g_lock:
self._win.erase()
self._win.attron(to_curses_attr(self.color))
self.addstr(0, 0, self.text)
self._win.attroff(to_curses_attr(self.color))
self._refresh()
self._win.erase()
self._win.attron(to_curses_attr(self.color))
self.addstr(0, 0, self.text)
self._win.attroff(to_curses_attr(self.color))
self._refresh()
class DummyInput(FieldInput, Win):
......@@ -100,19 +99,18 @@ class BooleanWin(FieldInput, Win):
self.refresh()
def refresh(self):
with g_lock:
self._win.erase()
self._win.attron(to_curses_attr(self.color))
self.addnstr(0, 0, ' '*(8), self.width)
self.addstr(0, 2, "%s"%self.value)
self.addstr(0, 8, '→')
self.addstr(0, 0, '←')
if self.last_key == 'KEY_RIGHT':
self.addstr(0, 8, '')
else:
self.addstr(0, 0, '')
self._win.attroff(to_curses_attr(self.color))
self._refresh()
self._win.erase()
self._win.attron(to_curses_attr(self.color))
self.addnstr(0, 0, ' '*(8), self.width)
self.addstr(0, 2, "%s"%self.value)
self.addstr(0, 8, '→')
self.addstr(0, 0, '←')
if self.last_key == 'KEY_RIGHT':
self.addstr(0, 8, '')
else:
self.addstr(0, 0, '')
self._win.attroff(to_curses_attr(self.color))
self._refresh()
def reply(self):
self._field['label'] = ''
......@@ -166,18 +164,17 @@ class TextMultiWin(FieldInput, Win):
def refresh(self):
if not self.edition_input:
with g_lock:
self._win.erase()
self._win.attron(to_curses_attr(self.color))
self.addnstr(0, 0, ' '*self.width, self.width)
option = self.options[self.val_pos]
self.addstr(0, self.width//2-len(option)//2, option)
if self.val_pos > 0:
self.addstr(0, 0, '←')
if self.val_pos < len(self.options)-1:
self.addstr(0, self.width-1, '→')
self._win.attroff(to_curses_attr(self.color))
self._refresh()
self._win.erase()
self._win.attron(to_curses_attr(self.color))
self.addnstr(0, 0, ' '*self.width, self.width)
option = self.options[self.val_pos]
self.addstr(0, self.width//2-len(option)//2, option)
if self.val_pos > 0:
self.addstr(0, 0, '←')
if self.val_pos < len(self.options)-1:
self.addstr(0, self.width-1, '→')
self._win.attroff(to_curses_attr(self.color))
self._refresh()
else:
self.edition_input.refresh()
......@@ -219,20 +216,19 @@ class ListMultiWin(FieldInput, Win):
self.refresh()
def refresh(self):
with g_lock:
self._win.erase()
self._win.attron(to_curses_attr(self.color))
self.addnstr(0, 0, ' '*self.width, self.width)
if self.val_pos > 0:
self.addstr(0, 0, '←')
if self.val_pos < len(self.options)-1:
self.addstr(0, self.width-1, '→')
if self.options:
option = self.options[self.val_pos]
self.addstr(0, self.width//2-len(option)//2, option[0]['label'])
self.addstr(0, 2, '✔' if option[1] else '☐')
self._win.attroff(to_curses_attr(self.color))
self._refresh()
self._win.erase()
self._win.attron(to_curses_attr(self.color))
self.addnstr(0, 0, ' '*self.width, self.width)
if self.val_pos > 0:
self.addstr(0, 0, '←')
if self.val_pos < len(self.options)-1:
self.addstr(0, self.width-1, '→')
if self.options:
option = self.options[self.val_pos]
self.addstr(0, self.width//2-len(option)//2, option[0]['label'])
self.addstr(0, 2, '✔' if option[1] else '☐')
self._win.attroff(to_curses_attr(self.color))
self._refresh()
def reply(self):
self._field['label'] = ''
......@@ -267,19 +263,18 @@ class ListSingleWin(FieldInput, Win):
self.refresh()
def refresh(self):
with g_lock:
self._win.erase()
self._win.attron(to_curses_attr(self.color))
self.addnstr(0, 0, ' '*self.width, self.width)
if self.val_pos > 0:
self.addstr(0, 0, '←')
if self.val_pos < len(self.options)-1:
self.addstr(0, self.width-1, '→')
if self.options:
option = self.options[self.val_pos]['label']
self.addstr(0, self.width//2-len(option)//2, option)
self._win.attroff(to_curses_attr(self.color))
self._refresh()
self._win.erase()
self._win.attron(to_curses_attr(self.color))
self.addnstr(0, 0, ' '*self.width, self.width)
if self.val_pos > 0:
self.addstr(0, 0, '←')
if self.val_pos < len(self.options)-1:
self.addstr(0, self.width-1, '→')
if self.options:
option = self.options[self.val_pos]['label']
self.addstr(0, self.width//2-len(option)//2, option)
self._win.attroff(to_curses_attr(self.color))
self._refresh()
def reply(self):
self._field['label'] = ''
......@@ -310,19 +305,18 @@ class TextPrivateWin(TextSingleWin):
TextSingleWin.__init__(self, field)
def rewrite_text(self):
with g_lock:
self._win.erase()
if self.color:
self._win.attron(to_curses_attr(self.color))
self.addstr('*'*len(self.text[self.view_pos:self.view_pos+self.width-1]))
if self.color:
(y, x) = self._win.getyx()
size = self.width-x
self.addnstr(' '*size, size, to_curses_attr(self.color))
self.addstr(0, self.pos, '')
if self.color:
self._win.attroff(to_curses_attr(self.color))
self._refresh()
self._win.erase()
if self.color:
self._win.attron(to_curses_attr(self.color))
self.addstr('*'*len(self.text[self.view_pos:self.view_pos+self.width-1]))
if self.color:
(y, x) = self._win.getyx()
size = self.width-x
self.addnstr(' '*size, size, to_curses_attr(self.color))
self.addstr(0, self.pos, '')
if self.color:
self._win.attroff(to_curses_attr(self.color))
self._refresh()
def get_help_message(self):
return 'Edit the secret text'
......@@ -346,8 +340,7 @@ class FormWin(object):
}
def __init__(self, form, height, width, y, x):
self._form = form
with g_lock:
self._win = Win._tab_win.derwin(height, width, y, x)
self._win = Win._tab_win.derwin(height, width, y, x)
self.scroll_pos = 0
self.current_input = 0
self.inputs = [] # dict list
......@@ -370,8 +363,7 @@ class FormWin(object):
def resize(self, height, width, y, x):
self.height = height
self.width = width
with g_lock:
self._win = Win._tab_win.derwin(height, width, y, x)
self._win = Win._tab_win.derwin(height, width, y, x)
# Adjust the scroll position, if resizing made the window too small
# for the cursor to be visible
while self.current_input - self.scroll_pos > self.height-1:
......@@ -443,19 +435,18 @@ class FormWin(object):
self.inputs[self.current_input]['input'].do_command(key)
def refresh(self):
with g_lock:
self._win.erase()
y = -self.scroll_pos
i = 0
for name, field in self._form.getFields().items():
if field['type'] == 'hidden':
continue
self.inputs[i]['label'].resize(1, self.width//2, y + 1, 0)
self.inputs[i]['input'].resize(1, self.width//2, y+1, self.width//2)
# TODO: display the field description
y += 1
i += 1
self._win.refresh()
self._win.erase()
y = -self.scroll_pos
i = 0
for name, field in self._form.getFields().items():
if field['type'] == 'hidden':
continue
self.inputs[i]['label'].resize(1, self.width//2, y + 1, 0)
self.inputs[i]['input'].resize(1, self.width//2, y+1, self.width//2)
# TODO: display the field description
y += 1
i += 1
self._win.refresh()
for i, inp in enumerate(self.inputs):
if i < self.scroll_pos:
continue
......
......@@ -12,7 +12,7 @@ import curses
from config import config
from . import Win, g_lock
from . import Win
from theming import get_theme, to_curses_attr
class GlobalInfoBar(Win):
......@@ -21,39 +21,38 @@ class GlobalInfoBar(Win):
def refresh(self):
log.debug('Refresh: %s', self.__class__.__name__)
with g_lock:
self._win.erase()
self.addstr(0, 0, "[", to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
self._win.erase()
self.addstr(0, 0, "[", to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
create_gaps = config.get('create_gaps', False)
show_names = config.get('show_tab_names', False)
show_nums = config.get('show_tab_numbers', True)
use_nicks = config.get('use_tab_nicks', True)
# ignore any remaining gap tabs if the feature is not enabled
if create_gaps:
sorted_tabs = self.core.tabs[:]
else:
sorted_tabs = [tab for tab in self.core.tabs if tab]
create_gaps = config.get('create_gaps', False)
show_names = config.get('show_tab_names', False)
show_nums = config.get('show_tab_numbers', True)
use_nicks = config.get('use_tab_nicks', True)
# ignore any remaining gap tabs if the feature is not enabled
if create_gaps:
sorted_tabs = self.core.tabs[:]
else:
sorted_tabs = [tab for tab in self.core.tabs if tab]
for nb, tab in enumerate(sorted_tabs):
if not tab: continue
color = tab.color
if not config.get('show_inactive_tabs', True) and\
color is get_theme().COLOR_TAB_NORMAL:
continue
try:
if show_nums or not show_names:
self.addstr("%s" % str(nb), to_curses_attr(color))
if show_names:
self.addstr(' ', to_curses_attr(color))
for nb, tab in enumerate(sorted_tabs):
if not tab: continue
color = tab.color
if not config.get('show_inactive_tabs', True) and\
color is get_theme().COLOR_TAB_NORMAL:
continue
try:
if show_nums or not show_names:
self.addstr("%s" % str(nb), to_curses_attr(color))
if show_names:
if use_nicks:
self.addstr("%s" % str(tab.get_nick()), to_curses_attr(color))
else:
self.addstr("%s" % tab.name, to_curses_attr(color))
self.addstr("|", to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
except: # end of line
break
self.addstr(' ', to_curses_attr(color))
if show_names:
if use_nicks:
self.addstr("%s" % str(tab.get_nick()), to_curses_attr(color))
else:
self.addstr("%s" % tab.name, to_curses_attr(color))
self.addstr("|", to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
except: # end of line
break
(y, x) = self._win.getyx()
self.addstr(y, x-1, '] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
(y, x) = self._win.getyx()
......@@ -68,42 +67,40 @@ class VerticalGlobalInfoBar(Win):
self._win = scr
def refresh(self):
with g_lock:
height, width = self._win.getmaxyx()
self._win.erase()
sorted_tabs = [tab for tab in self.core.tabs if tab]
if not config.get('show_inactive_tabs', True):
sorted_tabs = [tab for tab in sorted_tabs if\
tab.vertical_color != get_theme().COLOR_VERTICAL_TAB_NORMAL]
nb_tabs = len(sorted_tabs)
use_nicks = config.get('use_tab_nicks', True)
if nb_tabs >= height:
for y, tab in enumerate(sorted_tabs):
if tab.vertical_color == get_theme().COLOR_VERTICAL_TAB_CURRENT:
pos = y
break
# center the current tab as much as possible
if pos < height//2:
sorted_tabs = sorted_tabs[:height]
elif nb_tabs - pos <= height//2:
sorted_tabs = sorted_tabs[-height:]
else:
sorted_tabs = sorted_tabs[pos-height//2 : pos+height//2]
height, width = self._win.getmaxyx()
self._win.erase()
sorted_tabs = [tab for tab in self.core.tabs if tab]
if not config.get('show_inactive_tabs', True):
sorted_tabs = [tab for tab in sorted_tabs if\
tab.vertical_color != get_theme().COLOR_VERTICAL_TAB_NORMAL]
nb_tabs = len(sorted_tabs)
use_nicks = config.get('use_tab_nicks', True)
if nb_tabs >= height:
for y, tab in enumerate(sorted_tabs):
color = tab.vertical_color
if not config.get('vertical_tab_list_sort', 'desc') != 'asc':
y = height - y - 1
self.addstr(y, 0, "%2d" % tab.nb,
to_curses_attr(get_theme().COLOR_VERTICAL_TAB_NUMBER))
self.addstr('.')
if use_nicks:
self.addnstr("%s" % tab.get_nick(), width - 4, to_curses_attr(color))
else:
self.addnstr("%s" % tab.name, width - 4, to_curses_attr(color))
separator = to_curses_attr(get_theme().COLOR_VERTICAL_SEPARATOR)
self._win.attron(separator)
self._win.vline(0, width-1, curses.ACS_VLINE, height)
self._win.attroff(separator)
self._refresh()
if tab.vertical_color == get_theme().COLOR_VERTICAL_TAB_CURRENT:
pos = y
break
# center the current tab as much as possible
if pos < height//2:
sorted_tabs = sorted_tabs[:height]
elif nb_tabs - pos <= height//2:
sorted_tabs = sorted_tabs[-height:]
else:
sorted_tabs = sorted_tabs[pos-height//2 : pos+height//2]
for y, tab in enumerate(sorted_tabs):
color = tab.vertical_color
if not config.get('vertical_tab_list_sort', 'desc') != 'asc':
y = height - y - 1
self.addstr(y, 0, "%2d" % tab.nb,
to_curses_attr(get_theme().COLOR_VERTICAL_TAB_NUMBER))
self.addstr('.')
if use_nicks:
self.addnstr("%s" % tab.get_nick(), width - 4, to_curses_attr(color))
else:
self.addnstr("%s" % tab.name, width - 4, to_curses_attr(color))
separator = to_curses_attr(get_theme().COLOR_VERTICAL_SEPARATOR)
self._win.attron(separator)
self._win.vline(0, width-1, curses.ACS_VLINE, height)
self._win.attroff(separator)
self._refresh()
......@@ -8,7 +8,7 @@ log = logging.getLogger(__name__)
from common import safeJID
from . import Win, g_lock
from . import Win
from . funcs import truncate_nick
from theming import get_theme, to_curses_attr
......@@ -39,17 +39,16 @@ class XMLInfoWin(InfoWin):
def refresh(self, filter_t='', filter='', window=None):
log.debug('Refresh: %s', self.__class__.__name__)