When should Canvas.ConstructContextualMenu fire?

On Win32 right-clicking a canvas and returning True from the mouseDown event gives the following sequence of events:

MouseDown
MouseUp
ConstructContextualMenu 

On Cocoa right-clicking a canvas and returning True from the mouseDown event gives the following sequence of events:

MouseDown
MouseUp

(ConstructContextualMenu never fires)

On Cocoa right-clicking a canvas and returning False from the mouseDown event gives the following sequence of events:

MouseDown
ConstructContextualMenu

(MouseUp never fires)

Is this an OS-level behavioral difference or a bug in the Xojo framework?

If you return True from MouseDown, you shouldn’t get a ConstructContextualMenu event on any platform.

Michael,

You need to return True on your canvas’ “ConstructContextualMenu” for you code in your canvas’ ContextualMenuAction. Here is sample code.

ConstructContextualMenu Code (Canvas Event Handler)

    base.append(New MenuItem(MenuItem.TextSeparator))
    base.append(New MenuItem("Cut"))
    base.append(New MenuItem("Copy"))
    base.append(New MenuItem("Paste"))

Return True

ContextualMenuAction Code (Canvas Event Handler)

  if hitItem <> nil then
    if hitItem.Text = "Cut" then
      // do something
      
    elseif hitItem.Text = "Copy" then
      //do something

    elseif hitItem.Text = "Paste" then
      // 275% Zoom
      // do something
  end if

end if

HTH.

Also On Mouse Down if you do not return True then Mouse Drag will not fire for example.

Xojo Doc for Mouse Drag

“NOTE: This event will not occur unless you return True in the MouseDown event first.”

Mike - Thanks, but I think you are missing the issue, which is that there’s a non-trivial difference in framework behavior between Win32 and Cocoa. My hunch is that the Cocoa behavior is different (e.g., code that I wrote that used to work in Win32 and Carbon is now behaving differently). Or it could simply be one of those “Different OSs are Different” situation.

Yet, one does.

Also: in MouseUp on Cocoa, IsContextualClick() works, but in MouseUp on Win32, it’s always False.

Seems buggy to me, but I wanted to solicit other opinions on what the actual bug is.

My Workaround so far:

  • Subclass the canvas
  • Add an ConstructContextualMenu handler:
  return ConstructContextualMenu(base,x,y)
  • Add a new event
ConstructContextualMenu(base as MenuItem, x as integer, y as integer) as boolean
  • add a boolean flag bIgnoreMouseUp
  • In Canvas.MouseDown:
  if IsContextualClick then
    #if TargetWin32
      bIgnoreMouseUp = true
      dim base as new menuItem
      if ConstructContextualMenu(base,x,y) then
        call base.PopUp
      end if
      return True 
    #else
      return false
    #endif
  • In canvas.MouseUp:
  #if TargetWin32
    ' on win32 we get these events when we shouldn't 
    if bIgnoreMouseUP then
      bIgnoreMouseUp = false
      return
    end if
  #endif

With these changes, the behavior becomes identical between Cocoa and Win32.

I was wrong earlier. It looks like ConstructContextualMenu has always fired on Windows, even when you return true.

… ummm hhmm clears throat…
recall the documentation where it says “Don’t rely on event order”

Except the question is not when, but whether the event will/should fire, and the difference between platforms. It really seems like it should be consistent.

Michael sorry about that :slight_smile:

I’ve submitted a couple bug reports:

Also, this is probably a related issue: