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 Nick Hall
parent efb2a63492
commit c558b8530b
11 changed files with 43 additions and 35 deletions

View File

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

View File

@ -43,7 +43,7 @@ _ = glocale.translation.gettext
from ...widgets import SimpleButton
from .grampstab import GrampsTab
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")
_RETURN = Gdk.keyval_from_name("Return")
@ -220,7 +220,7 @@ class ButtonTab(GrampsTab):
return
self.add_button_clicked(obj)
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)
elif event.keyval in (_LEFT,) and \
(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 ...ddtargets import DdTargets
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 event.type == Gdk.EventType.KEY_PRESS and event.keyval in (_TAB,):
if not (event.get_state() &
get_primary_mask(Gdk.ModifierType.SHIFT_MASK)):
if no_match_primary_mask(event.get_state(),
Gdk.ModifierType.SHIFT_MASK):
return self.next_cell()
elif (event.get_state() &
get_primary_mask(Gdk.ModifierType.SHIFT_MASK)):
elif match_primary_mask(event.get_state(), Gdk.ModifierType.SHIFT_MASK):
return self.prev_cell()
else:
return

View File

@ -32,7 +32,7 @@ from gi.repository import Gdk
from gi.repository import Gtk
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from ..utils import get_primary_mask
from ..utils import no_match_primary_mask
_RETURN = Gdk.keyval_from_name("Return")
_KP_ENTER = Gdk.keyval_from_name("KP_Enter")
@ -139,7 +139,7 @@ class SearchBar:
self.clear_button.set_sensitive(True)
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):
self.filter_button.set_sensitive(False)
self.clear_button.set_sensitive(True)

View File

@ -29,7 +29,7 @@ from gi.repository import Pango
from ... import widgets
from ...dbguielement import DbGUIElement
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")
_KP_ENTER = Gdk.keyval_from_name("KP_Enter")
@ -130,7 +130,7 @@ class SidebarFilter(DbGUIElement):
widget.set_tooltip_text(tooltip)
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):
self.clicked(obj)
return False

View File

@ -714,11 +714,22 @@ def text_to_clipboard(text):
Gdk.SELECTION_CLIPBOARD)
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
passed-in additional mask.
Return True if test_mask fully matches all bits of
GdkModifierIntent.PRIMARY_ACCELERATOR and addl_mask, False
otherwise.
"""
keymap = Gdk.Keymap.get_default()
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 gramps.gen.utils.db import navigation_label
from gramps.gen.constfunc import mod_key
from ..utils import get_primary_mask
from ..utils import match_primary_mask
DISABLED = -1
MRU_SIZE = 10
@ -481,7 +481,7 @@ class NavigationView(PageView):
if self.active:
if event.type == Gdk.EventType.KEY_PRESS:
if (event.keyval == Gdk.KEY_c and
(event.get_state() & get_primary_mask())):
match_primary_mask(event.get_state())):
self.call_copy()
return True
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 ..editors import EditPerson, EditFamily
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 ..plug import make_gui_option
from ..plug.quick import run_quick_report_by_name
@ -400,12 +400,11 @@ class GuiGramplet:
"""
if ((Gdk.keyval_name(event.keyval) == 'Z') and
(event.get_state() &
get_primary_mask(Gdk.ModifierType.SHIFT_MASK))):
match_primary_mask(event.get_state(), Gdk.ModifierType.SHIFT_MASK)):
self.redo()
return True
elif ((Gdk.keyval_name(event.keyval) == 'z') and
(event.get_state() & get_primary_mask())):
match_primary_mask(event.get_state())):
self.undo()
return True

View File

@ -43,7 +43,7 @@ from gi.repository import Gtk, Gdk, GLib
# Gramps modules
#
#-------------------------------------------------------------------------
from ..utils import get_primary_mask
from ..utils import match_primary_mask
#-------------------------------------------------------------------------
#
# InteractiveSearchBox class
@ -106,7 +106,7 @@ class InteractiveSearchBox:
self._search_entry.disconnect(popup_menu_id)
# 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]):
self.__imcontext_changed = 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 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))
if (target
and event.type == Gdk.EventType.BUTTON_PRESS
and not (event.get_state() &
get_primary_mask(Gdk.ModifierType.SHIFT_MASK))
and no_match_primary_mask(event.get_state(),
Gdk.ModifierType.SHIFT_MASK)
and self.get_selection().path_is_selected(target[0])):
# disable selection
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 ..spell import Spell
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.constfunc import has_display, mac
from ..actiongroup import ActionGroup
@ -243,12 +243,11 @@ class StyledTextEditor(Gtk.TextView):
"""
if ((Gdk.keyval_name(event.keyval) == 'Z') and
(event.get_state() &
get_primary_mask(Gdk.ModifierType.SHIFT_MASK))):
match_primary_mask(event.get_state(), Gdk.ModifierType.SHIFT_MASK)):
self.redo()
return True
elif ((Gdk.keyval_name(event.keyval) == 'z') and
(event.get_state() & get_primary_mask())):
match_primary_mask(event.get_state())):
self.undo()
return True
else:
@ -342,7 +341,7 @@ class StyledTextEditor(Gtk.TextView):
self.selclick=False
if ((event.type == Gdk.EventType.BUTTON_PRESS) 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())):
flavor = self.url_match[MATCH_FLAVOR]