Correct binary test logic for primary mask.

state & get_primary_mask(another) tested (state & (primary | other)),
which will be true if state matches *either* primary *or* other, but
what is wanted in a not-negated test is state matching all bits of
(primary | other). match_primary_mask does that.

On the other hand there are also cases of "not state & (primary | other)".
no_match_primary_mask handles that, returning true if state matches none
 of the bits in (primary | other).

Fixes #10646.
This commit is contained in:
John Ralls 2018-07-01 14:46:55 -07:00 committed by prculley
parent de31a42fc8
commit 0161c4b917
11 changed files with 43 additions and 35 deletions

View File

@ -57,7 +57,7 @@ from .managedwindow import ManagedWindow
from .glade import Glade from .glade import Glade
from .ddtargets import DdTargets from .ddtargets import DdTargets
from .makefilter import make_filter from .makefilter import make_filter
from .utils import is_right_click, get_primary_mask from .utils import is_right_click, no_match_primary_mask
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext _ = glocale.translation.sgettext
@ -1572,9 +1572,9 @@ class MultiTreeView(Gtk.TreeView):
# otherwise: # otherwise:
if (target and if (target and
event.type == Gdk.EventType.BUTTON_PRESS and event.type == Gdk.EventType.BUTTON_PRESS and
self.get_selection().path_is_selected(target[0]) and not self.get_selection().path_is_selected(target[0]) and
(event.get_state() & no_match_primary_mask(event.get_state(),
get_primary_mask(Gdk.ModifierType.SHIFT_MASK))): Gdk.ModifierType.SHIFT_MASK)):
# disable selection # disable selection
self.get_selection().set_select_function( self.get_selection().set_select_function(
lambda *ignore: False, None) lambda *ignore: False, None)

View File

@ -43,7 +43,7 @@ _ = glocale.translation.gettext
from ...widgets import SimpleButton from ...widgets import SimpleButton
from .grampstab import GrampsTab from .grampstab import GrampsTab
from gramps.gen.errors import WindowActiveError from gramps.gen.errors import WindowActiveError
from ...utils import get_primary_mask from ...utils import match_primary_mask
_KP_ENTER = Gdk.keyval_from_name("KP_Enter") _KP_ENTER = Gdk.keyval_from_name("KP_Enter")
_RETURN = Gdk.keyval_from_name("Return") _RETURN = Gdk.keyval_from_name("Return")
@ -220,7 +220,7 @@ class ButtonTab(GrampsTab):
return return
self.add_button_clicked(obj) self.add_button_clicked(obj)
elif event.keyval in (_OPEN,) and self.share_btn and \ elif event.keyval in (_OPEN,) and self.share_btn and \
(event.get_state() & get_primary_mask()): match_primary_mask(event.get_state()):
self.share_button_clicked(obj) self.share_button_clicked(obj)
elif event.keyval in (_LEFT,) and \ elif event.keyval in (_LEFT,) and \
(event.get_state() & Gdk.ModifierType.MOD1_MASK): (event.get_state() & Gdk.ModifierType.MOD1_MASK):

View File

@ -48,7 +48,7 @@ from .surnamemodel import SurnameModel
from .embeddedlist import EmbeddedList, TEXT_EDIT_COL from .embeddedlist import EmbeddedList, TEXT_EDIT_COL
from ...ddtargets import DdTargets from ...ddtargets import DdTargets
from gramps.gen.lib import Surname, NameOriginType from gramps.gen.lib import Surname, NameOriginType
from ...utils import get_primary_mask from ...utils import match_primary_mask, no_match_primary_mask
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -345,11 +345,10 @@ class SurnameTab(EmbeddedList):
""" """
if not EmbeddedList.key_pressed(self, obj, event): if not EmbeddedList.key_pressed(self, obj, event):
if event.type == Gdk.EventType.KEY_PRESS and event.keyval in (_TAB,): if event.type == Gdk.EventType.KEY_PRESS and event.keyval in (_TAB,):
if not (event.get_state() & if no_match_primary_mask(event.get_state(),
get_primary_mask(Gdk.ModifierType.SHIFT_MASK)): Gdk.ModifierType.SHIFT_MASK):
return self.next_cell() return self.next_cell()
elif (event.get_state() & elif match_primary_mask(event.get_state(), Gdk.ModifierType.SHIFT_MASK):
get_primary_mask(Gdk.ModifierType.SHIFT_MASK)):
return self.prev_cell() return self.prev_cell()
else: else:
return return

View File

@ -32,7 +32,7 @@ from gi.repository import Gdk
from gi.repository import Gtk from gi.repository import Gtk
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext _ = glocale.translation.gettext
from ..utils import get_primary_mask from ..utils import no_match_primary_mask
_RETURN = Gdk.keyval_from_name("Return") _RETURN = Gdk.keyval_from_name("Return")
_KP_ENTER = Gdk.keyval_from_name("KP_Enter") _KP_ENTER = Gdk.keyval_from_name("KP_Enter")
@ -139,7 +139,7 @@ class SearchBar:
self.clear_button.set_sensitive(True) self.clear_button.set_sensitive(True)
def key_press(self, obj, event): def key_press(self, obj, event):
if not (event.get_state() & get_primary_mask()): if no_match_primary_mask(event.get_state()):
if event.keyval in (_RETURN, _KP_ENTER): if event.keyval in (_RETURN, _KP_ENTER):
self.filter_button.set_sensitive(False) self.filter_button.set_sensitive(False)
self.clear_button.set_sensitive(True) self.clear_button.set_sensitive(True)

View File

@ -29,7 +29,7 @@ from gi.repository import Pango
from ... import widgets from ... import widgets
from ...dbguielement import DbGUIElement from ...dbguielement import DbGUIElement
from gramps.gen.config import config from gramps.gen.config import config
from ...utils import get_primary_mask from ...utils import no_match_primary_mask
_RETURN = Gdk.keyval_from_name("Return") _RETURN = Gdk.keyval_from_name("Return")
_KP_ENTER = Gdk.keyval_from_name("KP_Enter") _KP_ENTER = Gdk.keyval_from_name("KP_Enter")
@ -130,7 +130,7 @@ class SidebarFilter(DbGUIElement):
widget.set_tooltip_text(tooltip) widget.set_tooltip_text(tooltip)
def key_press(self, obj, event): def key_press(self, obj, event):
if not (event.get_state() & get_primary_mask()): if no_match_primary_mask(event.get_state()):
if event.keyval in (_RETURN, _KP_ENTER): if event.keyval in (_RETURN, _KP_ENTER):
self.clicked(obj) self.clicked(obj)
return False return False

View File

@ -714,11 +714,22 @@ def text_to_clipboard(text):
Gdk.SELECTION_CLIPBOARD) Gdk.SELECTION_CLIPBOARD)
clipboard.set_text(text, -1) clipboard.set_text(text, -1)
def get_primary_mask(addl_mask=0): def match_primary_mask(test_mask, addl_mask=0):
""" """
Obtain the IntentPrimary mask for the platform bitwise-ored with a Return True if test_mask fully matches all bits of
passed-in additional mask. GdkModifierIntent.PRIMARY_ACCELERATOR and addl_mask, False
otherwise.
""" """
keymap = Gdk.Keymap.get_default() keymap = Gdk.Keymap.get_default()
primary = keymap.get_modifier_mask(Gdk.ModifierIntent.PRIMARY_ACCELERATOR) primary = keymap.get_modifier_mask(Gdk.ModifierIntent.PRIMARY_ACCELERATOR)
return primary | addl_mask return ((test_mask & (primary | addl_mask)) == (primary | addl_mask))
def no_match_primary_mask(test_mask, addl_mask=0):
"""
Return False if test_mask matches any bit of
GdkModifierIntent.PRIMARY_ACCELERATOR or addl_mask, True
otherwise.
"""
keymap = Gdk.Keymap.get_default()
primary = keymap.get_modifier_mask(Gdk.ModifierIntent.PRIMARY_ACCELERATOR)
return (test_mask & (primary | addl_mask)) == 0

View File

@ -52,7 +52,7 @@ from .pageview import PageView
from ..actiongroup import ActionGroup from ..actiongroup import ActionGroup
from gramps.gen.utils.db import navigation_label from gramps.gen.utils.db import navigation_label
from gramps.gen.constfunc import mod_key from gramps.gen.constfunc import mod_key
from ..utils import get_primary_mask from ..utils import match_primary_mask
DISABLED = -1 DISABLED = -1
MRU_SIZE = 10 MRU_SIZE = 10
@ -481,7 +481,7 @@ class NavigationView(PageView):
if self.active: if self.active:
if event.type == Gdk.EventType.KEY_PRESS: if event.type == Gdk.EventType.KEY_PRESS:
if (event.keyval == Gdk.KEY_c and if (event.keyval == Gdk.KEY_c and
(event.get_state() & get_primary_mask())): match_primary_mask(event.get_state())):
self.call_copy() self.call_copy()
return True return True
return super(NavigationView, self).key_press_handler(widget, event) return super(NavigationView, self).key_press_handler(widget, event)

View File

@ -48,7 +48,7 @@ from gramps.gen.errors import WindowActiveError
from gramps.gen.const import URL_MANUAL_PAGE, VERSION_DIR, COLON from gramps.gen.const import URL_MANUAL_PAGE, VERSION_DIR, COLON
from ..editors import EditPerson, EditFamily from ..editors import EditPerson, EditFamily
from ..managedwindow import ManagedWindow from ..managedwindow import ManagedWindow
from ..utils import is_right_click, get_primary_mask, get_link_color from ..utils import is_right_click, match_primary_mask, get_link_color
from .menuitem import add_menuitem from .menuitem import add_menuitem
from ..plug import make_gui_option from ..plug import make_gui_option
from ..plug.quick import run_quick_report_by_name from ..plug.quick import run_quick_report_by_name
@ -400,12 +400,11 @@ class GuiGramplet:
""" """
if ((Gdk.keyval_name(event.keyval) == 'Z') and if ((Gdk.keyval_name(event.keyval) == 'Z') and
(event.get_state() & match_primary_mask(event.get_state(), Gdk.ModifierType.SHIFT_MASK)):
get_primary_mask(Gdk.ModifierType.SHIFT_MASK))):
self.redo() self.redo()
return True return True
elif ((Gdk.keyval_name(event.keyval) == 'z') and elif ((Gdk.keyval_name(event.keyval) == 'z') and
(event.get_state() & get_primary_mask())): match_primary_mask(event.get_state())):
self.undo() self.undo()
return True return True

View File

@ -43,7 +43,7 @@ from gi.repository import Gtk, Gdk, GLib
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from ..utils import get_primary_mask from ..utils import match_primary_mask
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# InteractiveSearchBox class # InteractiveSearchBox class
@ -106,7 +106,7 @@ class InteractiveSearchBox:
self._search_entry.disconnect(popup_menu_id) self._search_entry.disconnect(popup_menu_id)
# Intercept CTRL+F keybinding because Gtk do not allow to _replace_ it. # Intercept CTRL+F keybinding because Gtk do not allow to _replace_ it.
if ((event.state & get_primary_mask()) if (match_primary_mask(event.state)
and event.keyval in [Gdk.KEY_f, Gdk.KEY_F]): and event.keyval in [Gdk.KEY_f, Gdk.KEY_F]):
self.__imcontext_changed = True self.__imcontext_changed = True
# self.real_start_interactive_search(event.get_device(), True) # self.real_start_interactive_search(event.get_device(), True)

View File

@ -24,7 +24,7 @@ An override to allow easy multiselections.
from gi.repository import Gdk from gi.repository import Gdk
from gi.repository import Gtk from gi.repository import Gtk
from ..utils import get_primary_mask from ..utils import no_match_primary_mask
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -66,8 +66,8 @@ class MultiTreeView(Gtk.TreeView):
target = self.get_path_at_pos(int(event.x), int(event.y)) target = self.get_path_at_pos(int(event.x), int(event.y))
if (target if (target
and event.type == Gdk.EventType.BUTTON_PRESS and event.type == Gdk.EventType.BUTTON_PRESS
and not (event.get_state() & and no_match_primary_mask(event.get_state(),
get_primary_mask(Gdk.ModifierType.SHIFT_MASK)) Gdk.ModifierType.SHIFT_MASK)
and self.get_selection().path_is_selected(target[0])): and self.get_selection().path_is_selected(target[0])):
# disable selection # disable selection
self.get_selection().set_select_function(lambda *ignore: False, None) self.get_selection().set_select_function(lambda *ignore: False, None)

View File

@ -60,7 +60,7 @@ from .toolcomboentry import ToolComboEntry
from .springseparator import SpringSeparatorAction from .springseparator import SpringSeparatorAction
from ..spell import Spell from ..spell import Spell
from ..display import display_url from ..display import display_url
from ..utils import SystemFonts, get_primary_mask, get_link_color from ..utils import SystemFonts, match_primary_mask, get_link_color
from gramps.gen.config import config from gramps.gen.config import config
from gramps.gen.constfunc import has_display, mac from gramps.gen.constfunc import has_display, mac
from ..actiongroup import ActionGroup from ..actiongroup import ActionGroup
@ -243,12 +243,11 @@ class StyledTextEditor(Gtk.TextView):
""" """
if ((Gdk.keyval_name(event.keyval) == 'Z') and if ((Gdk.keyval_name(event.keyval) == 'Z') and
(event.get_state() & match_primary_mask(event.get_state(), Gdk.ModifierType.SHIFT_MASK)):
get_primary_mask(Gdk.ModifierType.SHIFT_MASK))):
self.redo() self.redo()
return True return True
elif ((Gdk.keyval_name(event.keyval) == 'z') and elif ((Gdk.keyval_name(event.keyval) == 'z') and
(event.get_state() & get_primary_mask())): match_primary_mask(event.get_state())):
self.undo() self.undo()
return True return True
else: else:
@ -342,7 +341,7 @@ class StyledTextEditor(Gtk.TextView):
self.selclick=False self.selclick=False
if ((event.type == Gdk.EventType.BUTTON_PRESS) and if ((event.type == Gdk.EventType.BUTTON_PRESS) and
(event.button == 1) and (self.url_match) and (event.button == 1) and (self.url_match) and
((event.get_state() & get_primary_mask()) or (match_primary_mask(event.get_state()) or
not self.get_editable())): not self.get_editable())):
flavor = self.url_match[MATCH_FLAVOR] flavor = self.url_match[MATCH_FLAVOR]