Browse Source

HasFlagCustom made safe and supports all enums

Yoh Deadfall 5 years ago
parent
commit
0a7ca87e3b

+ 26 - 4
src/Avalonia.Base/EnumExtensions.cs

@@ -11,10 +11,32 @@ namespace Avalonia
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static unsafe bool HasFlagCustom<T>(this T value, T flag) where T : unmanaged, Enum
         {
-            var intValue = *(int*)&value;
-            var intFlag = *(int*)&flag;
-
-            return (intValue & intFlag) == intFlag;
+            if (sizeof(T) == 1)
+            {
+                var byteValue = Unsafe.As<T, byte>(ref value);
+                var byteFlag = Unsafe.As<T, byte>(ref flag);
+                return (byteValue & byteFlag) == byteFlag;
+            }
+            else if (sizeof(T) == 2)
+            {
+                var shortValue = Unsafe.As<T, short>(ref value);
+                var shortFlag = Unsafe.As<T, short>(ref flag);
+                return (shortValue & shortFlag) == shortFlag;
+            }
+            else if (sizeof(T) == 4)
+            {
+                var intValue = Unsafe.As<T, int>(ref value);
+                var intFlag = Unsafe.As<T, int>(ref flag);
+                return (intValue & intFlag) == intFlag;
+            }
+            else if (sizeof(T) == 8)
+            {
+                var longValue = Unsafe.As<T, long>(ref value);
+                var longFlag = Unsafe.As<T, long>(ref flag);
+                return (longValue & longFlag) == longFlag;
+            }
+            else
+                throw new NotSupportedException("Enum with size of " + Unsafe.SizeOf<T>() + " are not supported");
         }
     }
 }

+ 2 - 2
src/Avalonia.Base/Utilities/TypeUtilities.cs

@@ -372,8 +372,8 @@ namespace Avalonia.Utilities
             const string implicitName = "op_Implicit";
             const string explicitName = "op_Explicit";
 
-            bool allowImplicit = (operatorType & OperatorType.Implicit) != 0;
-            bool allowExplicit = (operatorType & OperatorType.Explicit) != 0;
+            bool allowImplicit = operatorType.HasFlagCustom(OperatorType.Implicit);
+            bool allowExplicit = operatorType.HasFlagCustom(OperatorType.Explicit);
 
             foreach (MethodInfo method in fromType.GetMethods())
             {

+ 1 - 1
src/Avalonia.Controls.DataGrid/Collections/DataGridCollectionView.cs

@@ -2595,7 +2595,7 @@ namespace Avalonia.Collections
         /// <returns>Whether the specified flag is set</returns>
         private bool CheckFlag(CollectionViewFlags flags)
         {
-            return (_flags & flags) != 0;
+            return _flags.HasFlagCustom(flags);
         }
 
         /// <summary>

+ 1 - 1
src/Avalonia.Controls/ComboBox.cs

@@ -188,7 +188,7 @@ namespace Avalonia.Controls
                 return;
 
             if (e.Key == Key.F4 ||
-                ((e.Key == Key.Down || e.Key == Key.Up) && ((e.KeyModifiers & KeyModifiers.Alt) != 0)))
+                ((e.Key == Key.Down || e.Key == Key.Up) && e.KeyModifiers.HasFlagCustom(KeyModifiers.Alt)))
             {
                 IsDropDownOpen = !IsDropDownOpen;
                 e.Handled = true;

+ 16 - 29
src/Avalonia.Controls/Grid.cs

@@ -637,7 +637,7 @@ namespace Avalonia.Controls
         /// </summary>
         internal bool MeasureOverrideInProgress
         {
-            get { return (CheckFlagsAnd(Flags.MeasureOverrideInProgress)); }
+            get { return CheckFlags(Flags.MeasureOverrideInProgress); }
             set { SetFlags(value, Flags.MeasureOverrideInProgress); }
         }
 
@@ -646,7 +646,7 @@ namespace Avalonia.Controls
         /// </summary>
         internal bool ArrangeOverrideInProgress
         {
-            get { return (CheckFlagsAnd(Flags.ArrangeOverrideInProgress)); }
+            get { return CheckFlags(Flags.ArrangeOverrideInProgress); }
             set { SetFlags(value, Flags.ArrangeOverrideInProgress); }
         }
 
@@ -2350,25 +2350,12 @@ namespace Avalonia.Controls
         }
 
         /// <summary>
-        /// CheckFlagsAnd returns <c>true</c> if all the flags in the
+        /// CheckFlags returns <c>true</c> if all the flags in the
         /// given bitmask are set on the object.
         /// </summary>
-        private bool CheckFlagsAnd(Flags flags)
+        private bool CheckFlags(Flags flags)
         {
-            return ((_flags & flags) == flags);
-        }
-
-        /// <summary>
-        /// CheckFlagsOr returns <c>true</c> if at least one flag in the
-        /// given bitmask is set.
-        /// </summary>
-        /// <remarks>
-        /// If no bits are set in the given bitmask, the method returns
-        /// <c>true</c>.
-        /// </remarks>
-        private bool CheckFlagsOr(Flags flags)
-        {
-            return (flags == 0 || (_flags & flags) != 0);
+            return _flags.HasFlagCustom(flags);
         }
 
         private static void OnShowGridLinesPropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e)
@@ -2535,7 +2522,7 @@ namespace Avalonia.Controls
         /// </summary>
         private bool CellsStructureDirty
         {
-            get { return (!CheckFlagsAnd(Flags.ValidCellsStructure)); }
+            get { return !CheckFlags(Flags.ValidCellsStructure); }
             set { SetFlags(!value, Flags.ValidCellsStructure); }
         }
 
@@ -2544,7 +2531,7 @@ namespace Avalonia.Controls
         /// </summary>
         private bool ListenToNotifications
         {
-            get { return (CheckFlagsAnd(Flags.ListenToNotifications)); }
+            get { return CheckFlags(Flags.ListenToNotifications); }
             set { SetFlags(value, Flags.ListenToNotifications); }
         }
 
@@ -2553,7 +2540,7 @@ namespace Avalonia.Controls
         /// </summary>
         private bool SizeToContentU
         {
-            get { return (CheckFlagsAnd(Flags.SizeToContentU)); }
+            get { return CheckFlags(Flags.SizeToContentU); }
             set { SetFlags(value, Flags.SizeToContentU); }
         }
 
@@ -2562,7 +2549,7 @@ namespace Avalonia.Controls
         /// </summary>
         private bool SizeToContentV
         {
-            get { return (CheckFlagsAnd(Flags.SizeToContentV)); }
+            get { return CheckFlags(Flags.SizeToContentV); }
             set { SetFlags(value, Flags.SizeToContentV); }
         }
 
@@ -2571,7 +2558,7 @@ namespace Avalonia.Controls
         /// </summary>
         private bool HasStarCellsU
         {
-            get { return (CheckFlagsAnd(Flags.HasStarCellsU)); }
+            get { return CheckFlags(Flags.HasStarCellsU); }
             set { SetFlags(value, Flags.HasStarCellsU); }
         }
 
@@ -2580,7 +2567,7 @@ namespace Avalonia.Controls
         /// </summary>
         private bool HasStarCellsV
         {
-            get { return (CheckFlagsAnd(Flags.HasStarCellsV)); }
+            get { return CheckFlags(Flags.HasStarCellsV); }
             set { SetFlags(value, Flags.HasStarCellsV); }
         }
 
@@ -2589,7 +2576,7 @@ namespace Avalonia.Controls
         /// </summary>
         private bool HasGroup3CellsInAutoRows
         {
-            get { return (CheckFlagsAnd(Flags.HasGroup3CellsInAutoRows)); }
+            get { return CheckFlags(Flags.HasGroup3CellsInAutoRows); }
             set { SetFlags(value, Flags.HasGroup3CellsInAutoRows); }
         }
 
@@ -2803,10 +2790,10 @@ namespace Avalonia.Controls
             internal LayoutTimeSizeType SizeTypeU;
             internal LayoutTimeSizeType SizeTypeV;
             internal int Next;
-            internal bool IsStarU { get { return ((SizeTypeU & LayoutTimeSizeType.Star) != 0); } }
-            internal bool IsAutoU { get { return ((SizeTypeU & LayoutTimeSizeType.Auto) != 0); } }
-            internal bool IsStarV { get { return ((SizeTypeV & LayoutTimeSizeType.Star) != 0); } }
-            internal bool IsAutoV { get { return ((SizeTypeV & LayoutTimeSizeType.Auto) != 0); } }
+            internal bool IsStarU => SizeTypeU.HasFlagCustom(LayoutTimeSizeType.Star);
+            internal bool IsAutoU => SizeTypeU.HasFlagCustom(LayoutTimeSizeType.Auto);
+            internal bool IsStarV => SizeTypeV.HasFlagCustom(LayoutTimeSizeType.Star);
+            internal bool IsAutoV => SizeTypeV.HasFlagCustom(LayoutTimeSizeType.Auto);
         }
 
         /// <summary>

+ 4 - 4
src/Avalonia.Controls/ListBox.cs

@@ -135,8 +135,8 @@ namespace Avalonia.Controls
                 e.Handled = UpdateSelectionFromEventSource(
                     e.Source,
                     true,
-                    (e.KeyModifiers & KeyModifiers.Shift) != 0,
-                    (e.KeyModifiers & KeyModifiers.Control) != 0);
+                    e.KeyModifiers.HasFlagCustom(KeyModifiers.Shift),
+                    e.KeyModifiers.HasFlagCustom(KeyModifiers.Control));
             }
         }
 
@@ -154,8 +154,8 @@ namespace Avalonia.Controls
                     e.Handled = UpdateSelectionFromEventSource(
                         e.Source,
                         true,
-                        (e.KeyModifiers & KeyModifiers.Shift) != 0,
-                        (e.KeyModifiers & KeyModifiers.Control) != 0,
+                        e.KeyModifiers.HasFlagCustom(KeyModifiers.Shift),
+                        e.KeyModifiers.HasFlagCustom(KeyModifiers.Control),
                         point.Properties.IsRightButtonPressed);
                 }
             }

+ 6 - 6
src/Avalonia.Controls/Platform/InProcessDragSource.cs

@@ -73,20 +73,20 @@ namespace Avalonia.Platform
         {
             if (effect == DragDropEffects.Copy || effect == DragDropEffects.Move || effect == DragDropEffects.Link || effect == DragDropEffects.None)
                 return effect; // No need to check for the modifiers.
-            if (effect.HasFlag(DragDropEffects.Link) && modifiers.HasFlag(RawInputModifiers.Alt))
+            if (effect.HasFlagCustom(DragDropEffects.Link) && modifiers.HasFlagCustom(RawInputModifiers.Alt))
                 return DragDropEffects.Link;
-            if (effect.HasFlag(DragDropEffects.Copy) && modifiers.HasFlag(RawInputModifiers.Control))
+            if (effect.HasFlagCustom(DragDropEffects.Copy) && modifiers.HasFlagCustom(RawInputModifiers.Control))
                 return DragDropEffects.Copy;
             return DragDropEffects.Move;
         }
 
         private StandardCursorType GetCursorForDropEffect(DragDropEffects effects)
         {
-            if (effects.HasFlag(DragDropEffects.Copy))
+            if (effects.HasFlagCustom(DragDropEffects.Copy))
                 return StandardCursorType.DragCopy;
-            if (effects.HasFlag(DragDropEffects.Move))
+            if (effects.HasFlagCustom(DragDropEffects.Move))
                 return StandardCursorType.DragMove;
-            if (effects.HasFlag(DragDropEffects.Link))
+            if (effects.HasFlagCustom(DragDropEffects.Link))
                 return StandardCursorType.DragLink;
             return StandardCursorType.No;
         }
@@ -161,7 +161,7 @@ namespace Avalonia.Platform
             
             void CheckDraggingAccepted(RawInputModifiers changedMouseButton)
             {
-                if (_initialInputModifiers.Value.HasFlag(changedMouseButton))
+                if (_initialInputModifiers.Value.HasFlagCustom(changedMouseButton))
                 {
                     var result = RaiseEventAndUpdateCursor(RawDragEventType.Drop, e.Root, e.Position, e.InputModifiers);
                     UpdateCursor(null, DragDropEffects.None);

+ 10 - 11
src/Avalonia.Controls/Primitives/PopupPositioning/IPopupPositioner.cs

@@ -253,9 +253,8 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
     {
         public static void ValidateEdge(this PopupAnchor edge)
         {
-            if (((edge & PopupAnchor.Left) != 0 && (edge & PopupAnchor.Right) != 0)
-                ||
-                ((edge & PopupAnchor.Top) != 0 && (edge & PopupAnchor.Bottom) != 0))
+            if (edge.HasFlagCustom(PopupAnchor.Left) && edge.HasFlagCustom(PopupAnchor.Right) ||
+                edge.HasFlagCustom(PopupAnchor.Top) && edge.HasFlagCustom(PopupAnchor.Bottom))
                 throw new ArgumentException("Opposite edges specified");
         }
 
@@ -266,25 +265,25 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
 
         public static PopupAnchor Flip(this PopupAnchor edge)
         {
-            var hmask = PopupAnchor.Left | PopupAnchor.Right;
-            var vmask = PopupAnchor.Top | PopupAnchor.Bottom;
-            if ((edge & hmask) != 0)
-                edge ^= hmask;
-            if ((edge & vmask) != 0)
-                edge ^= vmask;
+            if (edge.HasFlagCustom(PopupAnchor.HorizontalMask))
+                edge ^= PopupAnchor.HorizontalMask;
+
+            if (edge.HasFlagCustom(PopupAnchor.VerticalMask))
+                edge ^= PopupAnchor.VerticalMask;
+
             return edge;
         }
 
         public static PopupAnchor FlipX(this PopupAnchor edge)
         {
-            if ((edge & PopupAnchor.HorizontalMask) != 0)
+            if (edge.HasFlagCustom(PopupAnchor.HorizontalMask))
                 edge ^= PopupAnchor.HorizontalMask;
             return edge;
         }
         
         public static PopupAnchor FlipY(this PopupAnchor edge)
         {
-            if ((edge & PopupAnchor.VerticalMask) != 0)
+            if (edge.HasFlagCustom(PopupAnchor.VerticalMask))
                 edge ^= PopupAnchor.VerticalMask;
             return edge;
         }

+ 20 - 28
src/Avalonia.Controls/Primitives/PopupPositioning/ManagedPopupPositioner.cs

@@ -42,16 +42,16 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
         private static Point GetAnchorPoint(Rect anchorRect, PopupAnchor edge)
         {
             double x, y;
-            if ((edge & PopupAnchor.Left) != 0)
+            if (edge.HasFlagCustom(PopupAnchor.Left))
                 x = anchorRect.X;
-            else if ((edge & PopupAnchor.Right) != 0)
+            else if (edge.HasFlagCustom(PopupAnchor.Right))
                 x = anchorRect.Right;
             else
                 x = anchorRect.X + anchorRect.Width / 2;
             
-            if ((edge & PopupAnchor.Top) != 0)
+            if (edge.HasFlagCustom(PopupAnchor.Top))
                 y = anchorRect.Y;
-            else if ((edge & PopupAnchor.Bottom) != 0)
+            else if (edge.HasFlagCustom(PopupAnchor.Bottom))
                 y = anchorRect.Bottom;
             else
                 y = anchorRect.Y + anchorRect.Height / 2;
@@ -61,16 +61,16 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
         private static Point Gravitate(Point anchorPoint, Size size, PopupGravity gravity)
         {
             double x, y;
-            if ((gravity & PopupGravity.Left) != 0)
+            if (gravity.HasFlagCustom(PopupGravity.Left))
                 x = -size.Width;
-            else if ((gravity & PopupGravity.Right) != 0)
+            else if (gravity.HasFlagCustom(PopupGravity.Right))
                 x = 0;
             else
                 x = -size.Width / 2;
             
-            if ((gravity & PopupGravity.Top) != 0)
+            if (gravity.HasFlagCustom(PopupGravity.Top))
                 y = -size.Height;
-            else if ((gravity & PopupGravity.Bottom) != 0)
+            else if (gravity.HasFlagCustom(PopupGravity.Bottom))
                 y = 0;
             else
                 y = -size.Height / 2;
@@ -125,21 +125,13 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
 
             bool FitsInBounds(Rect rc, PopupAnchor edge = PopupAnchor.AllMask)
             {
-                if ((edge & PopupAnchor.Left) != 0
-                    && rc.X < bounds.X)
-                    return false;
-
-                if ((edge & PopupAnchor.Top) != 0
-                    && rc.Y < bounds.Y)
-                    return false;
-
-                if ((edge & PopupAnchor.Right) != 0
-                    && rc.Right > bounds.Right)
-                    return false;
-
-                if ((edge & PopupAnchor.Bottom) != 0
-                    && rc.Bottom > bounds.Bottom)
+                if (edge.HasFlagCustom(PopupAnchor.Left) && rc.X < bounds.X ||
+                    edge.HasFlagCustom(PopupAnchor.Top) && rc.Y < bounds.Y ||
+                    edge.HasFlagCustom(PopupAnchor.Right) && rc.Right > bounds.Right ||
+                    edge.HasFlagCustom(PopupAnchor.Bottom) && rc.Bottom > bounds.Bottom)
+                {
                     return false;
+                }
 
                 return true;
             }
@@ -155,7 +147,7 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
             // If flipping geometry and anchor is allowed and helps, use the flipped one,
             // otherwise leave it as is
             if (!FitsInBounds(geo, PopupAnchor.HorizontalMask)
-                && (constraintAdjustment & PopupPositionerConstraintAdjustment.FlipX) != 0)
+                && constraintAdjustment.HasFlagCustom(PopupPositionerConstraintAdjustment.FlipX))
             {
                 var flipped = GetUnconstrained(anchor.FlipX(), gravity.FlipX());
                 if (FitsInBounds(flipped, PopupAnchor.HorizontalMask))
@@ -163,7 +155,7 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
             }
 
             // If sliding is allowed, try moving the rect into the bounds
-            if ((constraintAdjustment & PopupPositionerConstraintAdjustment.SlideX) != 0)
+            if (constraintAdjustment.HasFlagCustom(PopupPositionerConstraintAdjustment.SlideX))
             {
                 geo = geo.WithX(Math.Max(geo.X, bounds.X));
                 if (geo.Right > bounds.Right)
@@ -171,7 +163,7 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
             }
             
             // Resize the rect horizontally if allowed.
-            if ((constraintAdjustment & PopupPositionerConstraintAdjustment.ResizeX) != 0)
+            if (constraintAdjustment.HasFlagCustom(PopupPositionerConstraintAdjustment.ResizeX))
             {
                 var unconstrainedRect = geo;
 
@@ -194,7 +186,7 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
             // If flipping geometry and anchor is allowed and helps, use the flipped one,
             // otherwise leave it as is
             if (!FitsInBounds(geo, PopupAnchor.VerticalMask)
-                && (constraintAdjustment & PopupPositionerConstraintAdjustment.FlipY) != 0)
+                && constraintAdjustment.HasFlagCustom(PopupPositionerConstraintAdjustment.FlipY))
             {
                 var flipped = GetUnconstrained(anchor.FlipY(), gravity.FlipY());
                 if (FitsInBounds(flipped, PopupAnchor.VerticalMask))
@@ -202,7 +194,7 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
             }
 
             // If sliding is allowed, try moving the rect into the bounds
-            if ((constraintAdjustment & PopupPositionerConstraintAdjustment.SlideY) != 0)
+            if (constraintAdjustment.HasFlagCustom(PopupPositionerConstraintAdjustment.SlideY))
             {
                 geo = geo.WithY(Math.Max(geo.Y, bounds.Y));
                 if (geo.Bottom > bounds.Bottom)
@@ -210,7 +202,7 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
             }
 
             // Resize the rect vertically if allowed.
-            if ((constraintAdjustment & PopupPositionerConstraintAdjustment.ResizeY) != 0)
+            if (constraintAdjustment.HasFlagCustom(PopupPositionerConstraintAdjustment.ResizeY))
             {
                 var unconstrainedRect = geo;
 

+ 4 - 4
src/Avalonia.Controls/Primitives/SelectingItemsControl.cs

@@ -321,7 +321,7 @@ namespace Avalonia.Controls.Primitives
         /// <summary>
         /// Gets a value indicating whether <see cref="SelectionMode.AlwaysSelected"/> is set.
         /// </summary>
-        protected bool AlwaysSelected => (SelectionMode & SelectionMode.AlwaysSelected) != 0;
+        protected bool AlwaysSelected => SelectionMode.HasFlagCustom(SelectionMode.AlwaysSelected);
 
         /// <inheritdoc/>
         public override void BeginInit()
@@ -487,7 +487,7 @@ namespace Avalonia.Controls.Primitives
 
                 if (ItemCount > 0 &&
                     Match(keymap.SelectAll) &&
-                    SelectionMode.HasFlag(SelectionMode.Multiple))
+                    SelectionMode.HasFlagCustom(SelectionMode.Multiple))
                 {
                     Selection.SelectAll();
                     e.Handled = true;
@@ -577,8 +577,8 @@ namespace Avalonia.Controls.Primitives
             }
 
             var mode = SelectionMode;
-            var multi = (mode & SelectionMode.Multiple) != 0;
-            var toggle = (toggleModifier || (mode & SelectionMode.Toggle) != 0);
+            var multi = mode.HasFlagCustom(SelectionMode.Multiple);
+            var toggle = toggleModifier || mode.HasFlagCustom(SelectionMode.Toggle);
             var range = multi && rangeModifier;
 
             if (!select)

+ 2 - 2
src/Avalonia.Controls/Repeater/RepeaterLayoutContext.cs

@@ -53,8 +53,8 @@ namespace Avalonia.Controls
         {
             return _owner.GetElementImpl(
                 index,
-                (options & ElementRealizationOptions.ForceCreate) != 0,
-                (options & ElementRealizationOptions.SuppressAutoRecycle) != 0);
+                options.HasFlagCustom(ElementRealizationOptions.ForceCreate),
+                options.HasFlagCustom(ElementRealizationOptions.SuppressAutoRecycle));
         }
 
         protected override object GetItemAtCore(int index) => _owner.ItemsSourceView.GetAt(index);

+ 2 - 2
src/Avalonia.Controls/TextBox.cs

@@ -585,7 +585,7 @@ namespace Avalonia.Controls
             var keymap = AvaloniaLocator.Current.GetService<PlatformHotkeyConfiguration>();
 
             bool Match(List<KeyGesture> gestures) => gestures.Any(g => g.Matches(e));
-            bool DetectSelection() => e.KeyModifiers.HasFlag(keymap.SelectionModifiers);
+            bool DetectSelection() => e.KeyModifiers.HasFlagCustom(keymap.SelectionModifiers);
 
             if (Match(keymap.SelectAll))
             {
@@ -703,7 +703,7 @@ namespace Avalonia.Controls
             }
             else
             {
-                bool hasWholeWordModifiers = modifiers.HasFlag(keymap.WholeWordTextActionModifiers);
+                bool hasWholeWordModifiers = modifiers.HasFlagCustom(keymap.WholeWordTextActionModifiers);
                 switch (e.Key)
                 {
                     case Key.Left:

+ 6 - 6
src/Avalonia.Controls/TreeView.cs

@@ -412,7 +412,7 @@ namespace Avalonia.Controls
                 e.Handled = UpdateSelectionFromEventSource(
                     e.Source,
                     true,
-                    (e.KeyModifiers & KeyModifiers.Shift) != 0);
+                    e.KeyModifiers.HasFlagCustom(KeyModifiers.Shift));
             }
         }
 
@@ -521,8 +521,8 @@ namespace Avalonia.Controls
                     e.Handled = UpdateSelectionFromEventSource(
                         e.Source,
                         true,
-                        (e.KeyModifiers & KeyModifiers.Shift) != 0,
-                        (e.KeyModifiers & KeyModifiers.Control) != 0,
+                        e.KeyModifiers.HasFlagCustom(KeyModifiers.Shift),
+                        e.KeyModifiers.HasFlagCustom(KeyModifiers.Control),
                         point.Properties.IsRightButtonPressed);
                 }
             }
@@ -558,9 +558,9 @@ namespace Avalonia.Controls
             }
 
             var mode = SelectionMode;
-            var toggle = toggleModifier || (mode & SelectionMode.Toggle) != 0;
-            var multi = (mode & SelectionMode.Multiple) != 0;
-            var range = multi && selectedContainer != null && rangeModifier;
+            var toggle = toggleModifier || mode.HasFlagCustom(SelectionMode.Toggle);
+            var multi = mode.HasFlagCustom(SelectionMode.Multiple);
+            var range = multi && rangeModifier && selectedContainer != null;
 
             if (rightButton)
             {

+ 4 - 4
src/Avalonia.FreeDesktop/DBusMenuExporter.cs

@@ -223,13 +223,13 @@ namespace Avalonia.FreeDesktop
                             return null;
                         var lst = new List<string>();
                         var mod = item.Gesture;
-                        if ((mod.KeyModifiers & KeyModifiers.Control) != 0)
+                        if (mod.KeyModifiers.HasFlagCustom(KeyModifiers.Control))
                             lst.Add("Control");
-                        if ((mod.KeyModifiers & KeyModifiers.Alt) != 0)
+                        if (mod.KeyModifiers.HasFlagCustom(KeyModifiers.Alt))
                             lst.Add("Alt");
-                        if ((mod.KeyModifiers & KeyModifiers.Shift) != 0)
+                        if (mod.KeyModifiers.HasFlagCustom(KeyModifiers.Shift))
                             lst.Add("Shift");
-                        if ((mod.KeyModifiers & KeyModifiers.Meta) != 0)
+                        if (mod.KeyModifiers.HasFlagCustom(KeyModifiers.Meta))
                             lst.Add("Super");
                         lst.Add(item.Gesture.Key.ToString());
                         return new[] { lst.ToArray() };

+ 2 - 2
src/Avalonia.Headless.Vnc/HeadlessVncFramebufferSource.cs

@@ -33,11 +33,11 @@ namespace Avalonia.Headless.Vnc
                 {
                     Window?.MouseMove(pt);
                     foreach (var btn in CheckedButtons)
-                        if (_previousButtons.HasFlag(btn) && !buttons.HasFlag(btn))
+                        if (_previousButtons.HasFlagCustom(btn) && !buttons.HasFlagCustom(btn))
                             Window?.MouseUp(pt, TranslateButton(btn), modifiers);
                     
                     foreach (var btn in CheckedButtons)
-                        if (!_previousButtons.HasFlag(btn) && buttons.HasFlag(btn))
+                        if (!_previousButtons.HasFlagCustom(btn) && buttons.HasFlagCustom(btn))
                             Window?.MouseDown(pt, TranslateButton(btn), modifiers);
                     _previousButtons = buttons;
                 }, DispatcherPriority.Input);

+ 1 - 1
src/Avalonia.Input/AccessKeyHandler.cs

@@ -177,7 +177,7 @@ namespace Avalonia.Input
         {
             bool menuIsOpen = MainMenu?.IsOpen == true;
 
-            if ((e.KeyModifiers & KeyModifiers.Alt) != 0 || menuIsOpen)
+            if (e.KeyModifiers.HasFlagCustom(KeyModifiers.Alt) || menuIsOpen)
             {
                 // If any other key is pressed with the Alt key held down, or the main menu is open,
                 // find all controls who have registered that access key.

+ 2 - 2
src/Avalonia.X11/X11Window.Ime.cs

@@ -96,14 +96,14 @@ namespace Avalonia.X11
 
         void HandleKeyEvent(ref XEvent ev)
         {
-            var index = ev.KeyEvent.state.HasFlag(XModifierMask.ShiftMask);
+            var index = ev.KeyEvent.state.HasFlagCustom(XModifierMask.ShiftMask);
 
             // We need the latin key, since it's mainly used for hotkeys, we use a different API for text anyway
             var key = (X11Key)XKeycodeToKeysym(_x11.Display, ev.KeyEvent.keycode, index ? 1 : 0).ToInt32();
                 
             // Manually switch the Shift index for the keypad,
             // there should be a proper way to do this
-            if (ev.KeyEvent.state.HasFlag(XModifierMask.Mod2Mask)
+            if (ev.KeyEvent.state.HasFlagCustom(XModifierMask.Mod2Mask)
                 && key > X11Key.Num_Lock && key <= X11Key.KP_9)
                 key = (X11Key)XKeycodeToKeysym(_x11.Display, ev.KeyEvent.keycode, index ? 0 : 1).ToInt32();
             

+ 9 - 9
src/Avalonia.X11/X11Window.cs

@@ -639,23 +639,23 @@ namespace Avalonia.X11
         RawInputModifiers TranslateModifiers(XModifierMask state)
         {
             var rv = default(RawInputModifiers);
-            if (state.HasFlag(XModifierMask.Button1Mask))
+            if (state.HasFlagCustom(XModifierMask.Button1Mask))
                 rv |= RawInputModifiers.LeftMouseButton;
-            if (state.HasFlag(XModifierMask.Button2Mask))
+            if (state.HasFlagCustom(XModifierMask.Button2Mask))
                 rv |= RawInputModifiers.RightMouseButton;
-            if (state.HasFlag(XModifierMask.Button3Mask))
+            if (state.HasFlagCustom(XModifierMask.Button3Mask))
                 rv |= RawInputModifiers.MiddleMouseButton;
-            if (state.HasFlag(XModifierMask.Button4Mask))
+            if (state.HasFlagCustom(XModifierMask.Button4Mask))
                 rv |= RawInputModifiers.XButton1MouseButton;
-            if (state.HasFlag(XModifierMask.Button5Mask))
+            if (state.HasFlagCustom(XModifierMask.Button5Mask))
                 rv |= RawInputModifiers.XButton2MouseButton;
-            if (state.HasFlag(XModifierMask.ShiftMask))
+            if (state.HasFlagCustom(XModifierMask.ShiftMask))
                 rv |= RawInputModifiers.Shift;
-            if (state.HasFlag(XModifierMask.ControlMask))
+            if (state.HasFlagCustom(XModifierMask.ControlMask))
                 rv |= RawInputModifiers.Control;
-            if (state.HasFlag(XModifierMask.Mod1Mask))
+            if (state.HasFlagCustom(XModifierMask.Mod1Mask))
                 rv |= RawInputModifiers.Alt;
-            if (state.HasFlag(XModifierMask.Mod4Mask))
+            if (state.HasFlagCustom(XModifierMask.Mod4Mask))
                 rv |= RawInputModifiers.Meta;
             return rv;
         }

+ 5 - 5
src/Avalonia.X11/XI2Manager.cs

@@ -342,13 +342,13 @@ namespace Avalonia.X11
             Type = ev->evtype;
             Timestamp = (ulong)ev->time.ToInt64();
             var state = (XModifierMask)ev->mods.Effective;
-            if (state.HasFlag(XModifierMask.ShiftMask))
+            if (state.HasFlagCustom(XModifierMask.ShiftMask))
                 Modifiers |= RawInputModifiers.Shift;
-            if (state.HasFlag(XModifierMask.ControlMask))
+            if (state.HasFlagCustom(XModifierMask.ControlMask))
                 Modifiers |= RawInputModifiers.Control;
-            if (state.HasFlag(XModifierMask.Mod1Mask))
+            if (state.HasFlagCustom(XModifierMask.Mod1Mask))
                 Modifiers |= RawInputModifiers.Alt;
-            if (state.HasFlag(XModifierMask.Mod4Mask))
+            if (state.HasFlagCustom(XModifierMask.Mod4Mask))
                 Modifiers |= RawInputModifiers.Meta;
 
             Modifiers |= ParseButtonState(ev->buttons.MaskLen, ev->buttons.Mask);
@@ -364,7 +364,7 @@ namespace Avalonia.X11
             if (Type == XiEventType.XI_ButtonPress || Type == XiEventType.XI_ButtonRelease)
                 Button = ev->detail;
             Detail = ev->detail;
-            Emulated = ev->flags.HasFlag(XiDeviceEventFlags.XIPointerEmulated);
+            Emulated = ev->flags.HasFlagCustom(XiDeviceEventFlags.XIPointerEmulated);
         }
     }
     

+ 1 - 1
src/Linux/Avalonia.LinuxFramebuffer/Output/DrmBindings.cs

@@ -54,7 +54,7 @@ namespace Avalonia.LinuxFramebuffer.Output
         }
 
         public PixelSize Resolution => new PixelSize(Mode.hdisplay, Mode.vdisplay);
-        public bool IsPreferred => Mode.type.HasFlag(DrmModeType.DRM_MODE_TYPE_PREFERRED);
+        public bool IsPreferred => Mode.type.HasFlagCustom(DrmModeType.DRM_MODE_TYPE_PREFERRED);
 
         public string Name { get; }
     }

+ 4 - 4
src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs

@@ -147,13 +147,13 @@ namespace Avalonia.Win32.Interop.Wpf
         {
             var state = Keyboard.Modifiers;
             var rv = default(RawInputModifiers);
-            if (state.HasFlag(ModifierKeys.Windows))
+            if (state.HasFlagCustom(ModifierKeys.Windows))
                 rv |= RawInputModifiers.Meta;
-            if (state.HasFlag(ModifierKeys.Alt))
+            if (state.HasFlagCustom(ModifierKeys.Alt))
                 rv |= RawInputModifiers.Alt;
-            if (state.HasFlag(ModifierKeys.Control))
+            if (state.HasFlagCustom(ModifierKeys.Control))
                 rv |= RawInputModifiers.Control;
-            if (state.HasFlag(ModifierKeys.Shift))
+            if (state.HasFlagCustom(ModifierKeys.Shift))
                 rv |= RawInputModifiers.Shift;
             if (e != null)
             {

+ 3 - 3
src/Windows/Avalonia.Win32/DataObject.cs

@@ -181,7 +181,7 @@ namespace Avalonia.Win32
                 ole.GetData(ref format, out medium);
                 return;
             }
-            if(!format.tymed.HasFlag(TYMED.TYMED_HGLOBAL))
+            if(!format.tymed.HasFlagCustom(TYMED.TYMED_HGLOBAL))
                 Marshal.ThrowExceptionForHR(DV_E_TYMED);
 
             if (format.dwAspect != DVASPECT.DVASPECT_CONTENT)
@@ -205,7 +205,7 @@ namespace Avalonia.Win32
                 return;
             }
 
-            if (medium.tymed != TYMED.TYMED_HGLOBAL || !format.tymed.HasFlag(TYMED.TYMED_HGLOBAL))
+            if (medium.tymed != TYMED.TYMED_HGLOBAL || !format.tymed.HasFlagCustom(TYMED.TYMED_HGLOBAL))
                 Marshal.ThrowExceptionForHR(DV_E_TYMED);
 
             if (format.dwAspect != DVASPECT.DVASPECT_CONTENT)
@@ -228,7 +228,7 @@ namespace Avalonia.Win32
                 return ole.QueryGetData(ref format);
             if (format.dwAspect != DVASPECT.DVASPECT_CONTENT)
                 return DV_E_DVASPECT;
-            if (!format.tymed.HasFlag(TYMED.TYMED_HGLOBAL))
+            if (!format.tymed.HasFlagCustom(TYMED.TYMED_HGLOBAL))
                 return DV_E_TYMED;
 
             string dataFormat = ClipboardFormats.GetFormat(format.cfFormat);

+ 12 - 12
src/Windows/Avalonia.Win32/OleDropTarget.cs

@@ -24,11 +24,11 @@ namespace Avalonia.Win32
         public static DropEffect ConvertDropEffect(DragDropEffects operation)
         {
             DropEffect result = DropEffect.None;
-            if (operation.HasFlag(DragDropEffects.Copy))
+            if (operation.HasFlagCustom(DragDropEffects.Copy))
                 result |= DropEffect.Copy;
-            if (operation.HasFlag(DragDropEffects.Move))
+            if (operation.HasFlagCustom(DragDropEffects.Move))
                 result |= DropEffect.Move;
-            if (operation.HasFlag(DragDropEffects.Link))
+            if (operation.HasFlagCustom(DragDropEffects.Link))
                 result |= DropEffect.Link;
             return result;
         }
@@ -36,11 +36,11 @@ namespace Avalonia.Win32
         public static DragDropEffects ConvertDropEffect(DropEffect effect)
         {
             DragDropEffects result = DragDropEffects.None;
-            if (effect.HasFlag(DropEffect.Copy))
+            if (effect.HasFlagCustom(DropEffect.Copy))
                 result |= DragDropEffects.Copy;
-            if (effect.HasFlag(DropEffect.Move))
+            if (effect.HasFlagCustom(DropEffect.Move))
                 result |= DragDropEffects.Move;
-            if (effect.HasFlag(DropEffect.Link))
+            if (effect.HasFlagCustom(DropEffect.Link))
                 result |= DragDropEffects.Link;
             return result;
         }
@@ -50,17 +50,17 @@ namespace Avalonia.Win32
             var modifiers = RawInputModifiers.None;
             var state = (UnmanagedMethods.ModifierKeys)grfKeyState;
 
-            if (state.HasFlag(UnmanagedMethods.ModifierKeys.MK_LBUTTON))
+            if (state.HasFlagCustom(UnmanagedMethods.ModifierKeys.MK_LBUTTON))
                 modifiers |= RawInputModifiers.LeftMouseButton;
-            if (state.HasFlag(UnmanagedMethods.ModifierKeys.MK_MBUTTON))
+            if (state.HasFlagCustom(UnmanagedMethods.ModifierKeys.MK_MBUTTON))
                 modifiers |= RawInputModifiers.MiddleMouseButton;
-            if (state.HasFlag(UnmanagedMethods.ModifierKeys.MK_RBUTTON))
+            if (state.HasFlagCustom(UnmanagedMethods.ModifierKeys.MK_RBUTTON))
                 modifiers |= RawInputModifiers.RightMouseButton;
-            if (state.HasFlag(UnmanagedMethods.ModifierKeys.MK_SHIFT))
+            if (state.HasFlagCustom(UnmanagedMethods.ModifierKeys.MK_SHIFT))
                 modifiers |= RawInputModifiers.Shift;
-            if (state.HasFlag(UnmanagedMethods.ModifierKeys.MK_CONTROL))
+            if (state.HasFlagCustom(UnmanagedMethods.ModifierKeys.MK_CONTROL))
                 modifiers |= RawInputModifiers.Control;
-            if (state.HasFlag(UnmanagedMethods.ModifierKeys.MK_ALT))
+            if (state.HasFlagCustom(UnmanagedMethods.ModifierKeys.MK_ALT))
                 modifiers |= RawInputModifiers.Alt;
             return modifiers;
         }

+ 2 - 2
src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs

@@ -23,13 +23,13 @@ namespace Avalonia.Win32
             AdjustWindowRectEx(ref rcFrame, (uint)(WindowStyles.WS_OVERLAPPEDWINDOW & ~WindowStyles.WS_CAPTION), false, 0);
 
             var borderThickness = new RECT();
-            if (GetStyle().HasFlag(WindowStyles.WS_THICKFRAME))
+            if (GetStyle().HasFlagCustom(WindowStyles.WS_THICKFRAME))
             {
                 AdjustWindowRectEx(ref borderThickness, (uint)(GetStyle()), false, 0);
                 borderThickness.left *= -1;
                 borderThickness.top *= -1;
             }
-            else if (GetStyle().HasFlag(WindowStyles.WS_BORDER))
+            else if (GetStyle().HasFlagCustom(WindowStyles.WS_BORDER))
             {
                 borderThickness = new RECT { bottom = 1, left = 1, right = 1, top = 1 };
             }

+ 5 - 5
src/Windows/Avalonia.Win32/WindowImpl.cs

@@ -836,7 +836,7 @@ namespace Avalonia.Win32
             borderCaptionThickness.left *= -1;
             borderCaptionThickness.top *= -1;
 
-            bool wantsTitleBar = _extendChromeHints.HasFlag(ExtendClientAreaChromeHints.SystemChrome) || _extendTitleBarHint == -1;
+            bool wantsTitleBar = _extendChromeHints.HasFlagCustom(ExtendClientAreaChromeHints.SystemChrome) || _extendTitleBarHint == -1;
 
             if (!wantsTitleBar)
             {
@@ -853,7 +853,7 @@ namespace Avalonia.Win32
                 borderCaptionThickness.top = (int)(_extendTitleBarHint * RenderScaling);                
             }
 
-            margins.cyTopHeight = _extendChromeHints.HasFlag(ExtendClientAreaChromeHints.SystemChrome) && !_extendChromeHints.HasFlag(ExtendClientAreaChromeHints.PreferSystemChrome) ? borderCaptionThickness.top : 1;
+            margins.cyTopHeight = _extendChromeHints.HasFlagCustom(ExtendClientAreaChromeHints.SystemChrome) && !_extendChromeHints.HasFlagCustom(ExtendClientAreaChromeHints.PreferSystemChrome) ? borderCaptionThickness.top : 1;
 
             if (WindowState == WindowState.Maximized)
             {
@@ -901,8 +901,8 @@ namespace Avalonia.Win32
                 _extendedMargins = new Thickness();
             }
 
-            if(!_isClientAreaExtended || (_extendChromeHints.HasFlag(ExtendClientAreaChromeHints.SystemChrome) &&
-                !_extendChromeHints.HasFlag(ExtendClientAreaChromeHints.PreferSystemChrome)))
+            if(!_isClientAreaExtended || (_extendChromeHints.HasFlagCustom(ExtendClientAreaChromeHints.SystemChrome) &&
+                !_extendChromeHints.HasFlagCustom(ExtendClientAreaChromeHints.PreferSystemChrome)))
             {
                 EnableCloseButton(_hwnd);
             }
@@ -1239,7 +1239,7 @@ namespace Avalonia.Win32
         public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; }
         
         /// <inheritdoc/>
-        public bool NeedsManagedDecorations => _isClientAreaExtended && _extendChromeHints.HasFlag(ExtendClientAreaChromeHints.PreferSystemChrome);
+        public bool NeedsManagedDecorations => _isClientAreaExtended && _extendChromeHints.HasFlagCustom(ExtendClientAreaChromeHints.PreferSystemChrome);
 
         /// <inheritdoc/>
         public Thickness ExtendedMargins => _extendedMargins;