B4J Tutorial Floating ContextMenu using jNativeHookB4j

This is an example of using @Roycefer 's jNativeHook to monitor all mouse events, even outside of the current app. It uses a ContextMenu to replicate the right click functionality. Default behaviour is overridden by the jNativeHook library and returning false from the relevant event sub.

It uses a dummy form to enable the context menu to be placed anywhere on the screen.

It's not been comprehensively tested and I can't guarantee it will work on Mac or Linux, but would be interested to know if it does.

Get the jNativehook files from here: https://www.b4x.com/android/forum/threads/jnativehookb4j-for-intercepting-system-input-events.55826/

Hope you enjoy it.

V 0.2 Update for Mac - see post #3
V 0.6 implements Tags, css styling of menu, checkmenuitem, submenus and a menutitle
V 0.7 Close all menus correctly
V 0.8 Added :
  • Ignore clicks on window (allows window to operate normally)
  • Multiple Floating Menus (Only one can be active at a time)
This update contains breaking code, MainForm has to be passed to the NativeHook initialization.

No version increment update fixed menu resize issue.
Demo only update to V0.8
V0.8.5 Added
ThRuST's latest css styles
Pause and Restart Mouse Listener
cmenu.css.zip contains the latest css.file
Tags : B4j Native Hook Floating Context Menu
12
 

Attachments

  • FloatingContextMenu-0-7.zip
    7.1 KB · Views: 284
  • cmenu.css.zip
    1 KB · Views: 302
  • FloatingContextMenu-0-8-6.zip
    10.3 KB · Views: 343
  • Test - cmenu.css.zip
    1 KB · Views: 270
  • FCMTest1.zip
    10.3 KB · Views: 272
Last edited:

stevel05

Expert
Licensed User
I don't think you are pushing CSS too far, the base file is huge and does a lot of configuration. Although the local file is overriding some of it, it should be fine. I haven't change Focus on anything.
 

ThRuST

Well-Known Member
Licensed User
I posted a question about this just in case. I think I have a solution to this, it's just to set focus to the contextmenu when the mouse is clicked or keyboard shortcut it pressed. That should solve the problem.
 

stevel05

Expert
Licensed User
Thinking about it, it would be worth checking the CSS for valid data. In the past I've some some web stuff that has worked perfectly on Windows, but failed dismally on Safari. The Mac environment seems to insist more on correct validation than Window.
 

stevel05

Expert
Licensed User
I've added a requestFocus to the context menu immediately after it is show, it doesn't error on window so it must be a valid function but it's not going to make a difference on there. Hopefully it will on Mac. V0.8.6
 

ThRuST

Well-Known Member
Licensed User
That's good, ok I'll try it on my Mac again. Hang on, it's been a long working day again. After this we should better sleep. Do you ever work haha ;)
 

stevel05

Expert
Licensed User
It's a post Christmas lull at the moment. Very busy next 2 weeks though which is unusual for January.
 

ThRuST

Well-Known Member
Licensed User
I tested it and it's still the same. Try to add in jAWTRobot and set robotdelay(10) before you do RequestFocus. I'm able to study from home from the business course, so these three weeks I should focus on learning business but this got me hooked completely. It's nice to get stuff done until the wheel starts to roll again.
 

stevel05

Expert
Licensed User
Added 50 ms delay with CallSubUtils (Silent Update Download 0.8.6)
 

stevel05

Expert
Licensed User
Try the "Test - cmenu.css.zip" file in the first post. There were errors in it (I ran it through an online validator, incorrect comment characters and spaces after ':')
I just changed the errors it showed. Don't overwrite your old one though I think it looks a little different, probably things working now that weren't before.
 

stevel05

Expert
Licensed User
Just tried it again, I think it probably does look the same. It'll be interesting to see if it makes any difference on the Mac.
 

ThRuST

Well-Known Member
Licensed User
I have got a reply from my CSS question that it might help to update Java and so I did. Now I have the latest v8 update 111 on both PC and Mac. I also ran your latest code with the corrected CSS and tested it on Mac OSX El Capitan but it's still the same, the menu selector colors is greyed out. I tested something that might give a clue how to solve this. On Mac you can use CMD+Tab to switch between running applications the same way ALT+Tab works on a PC. It says 'Java' or 'java' in the running B4X application. This can be possibly be changed when using the installer tool by Erel (I think) so that the name can be changed in the top menubar on Mac. So a routine that scans the running application names and sets the focus to it will probably work, I cannot see why it won't. Since I will bake in your code modules into my code it will find Mindcraft, if there's no other solution for this. I have no clue why the contextmenu won't get focus itself. Perhaps it's depending on the running form (pane), I hate to say that :mad: programming pain that is :)
 

ThRuST

Well-Known Member
Licensed User
Is this of any help?
B4X:
 Dim JO As JavaObject = ContextMenuControl
  JO.RunMethod("setFocusTraversable", Array As Object(False))
 

stevel05

Expert
Licensed User
FocusTraversable is only relevant to moving through focusable items with the keys, I suspect that the context menu is not focusable. Rather than uploading another version, can you change the existing code in the FloatingMenu class in the RequestFocusDelayed sub, line 104 or so From Dim JO as JavaObject = CM to Dim JO as JavaObject = FM.RootPane, and see if that makes any difference.
 

ThRuST

Well-Known Member
Licensed User
I'm looking for this code in v0.8.6 but I cannot find Dim JO as JavaObject = CM. Please locate which class and code to change and I'll do it. Is B4J as complete that it has this feature inbuildt or maybe Erel can update B4J to make this work? just a taught. Or maybe this is related to JavaFX. If someone knows how to set focus to the contextmenu it would be great to know, possibly if Erel reads this post in a near future. Until then we have to depend on clever workarounds, as it would be great to make this work also on other platforms than Windows. It should be possible, one way or the other, don't you think so too?
 

stevel05

Expert
Licensed User
OK try FCMTest.zip (Post#1)
 

ThRuST

Well-Known Member
Licensed User
What about this? Please update your code since you know what you're doing. And add in this code. That's my new coding style #:)#

B4X:
' ########## Set Form Always On Top (TopMost) #############
    setAlwaysOnTop(MainForm, True)

    ' ########## Sets Form TopMost #############
Sub setAlwaysOnTop(frm As Object, Value As Boolean)
    Dim frmJO As JavaObject = frm
    Dim stage As JavaObject = frmJO.GetField("stage")
    stage.RunMethod("setAlwaysOnTop", Array(Value))
End Sub
 

stevel05

Expert
Licensed User
It's difficult to say as I can't test it here, but there are always issues when dealing with other OS's even different versions of the same software. In some cases it may work as standard, the functionality in here is non standard so it is our responsibility to get it working. It's not possible to tailor a function in a product like B4X for a case that is an exception to the rule.
 

stevel05

Expert
Licensed User
For a standard implementation it is not appropriate to set the main form always on top, as it will not behave as the user expects it to. The context menu is attached to an invisible form which is already set to always on top. Making the MainForm always on top will not make any difference.
 

ThRuST

Well-Known Member
Licensed User
I couldn't have said it better myself, that's the way it is. B4J is the best and that's a fact :) I am about to try your update on Mac.
 
Top