Middle mouse down in GWT is being swallowed by Safari - gwt

I've been writing a GWT app that does various simple things with images like pan, zoom, brighten, etc. when you click and drag the mouse. Everything is working really well in all the browsers, except Safari. Well, Chrome 3 was also a problem but my app now works fine in Chrome 4.
The problem is capturing the middle mouse down events. I've added mouse handlers to a widget class like this:
public class InteractiveThingy extends Composite implements
HasMouseDownHandlers, HasMouseMoveHandlers, HasMouseUpHandlers,
HasMouseWheelHandlers
{
#Override
public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) {
return addDomHandler(handler, MouseDownEvent.getType());
}
...
}
and I can subscribe to the mouse events elsewhere and handle them. I can see which button was pressed and apply the appropriate operation.
However, in Safari and Chrome 3, the handlers are never called when I press the middle mouse button. Instead, the multi-way scroll icon pops up. The middle mouse down event comes through on IE, FireFox and Chrome 4 just fine.
Is there some extra event handling (like event preview) needed to stop Safari from handling the middle mouse before my code gets its chance? Or perhaps I need to wait until Safari fixes the issue like Google did with Chrome.

Related

dojox/gesture/swipe prevents the html select to open dropdown

can anyone please explain to me why the html SELECT control (or any other control like BUTTON) placed inside the div (that is registered with dojox/gesture/swipe events) cannot be opened? I'd welcome any workarounds pls
require({
}, [ 'dojo/dom', 'dojox/gesture/swipe', 'dojo/on', 'dojo/_base/event' ], function(dom, swipe, on, event) {
var div = dom.byId('testSwipe');
var isSwipe = false;
on(div, swipe.end, function(e) {
console.log("### SWIPE");
});
});
http://jsfiddle.net/zLyck884/
based on the documentation here, particularly the image : http://dojotoolkit.org/reference-guide/1.10/dojox/gesture.html
the image depicts how the dojo standardizes the events (also for desktops) and how the swipe is just another layer of the touch events. so I reckoned if the mouse events are replaced by touchstart or something, then it most likely blocks the default mouse action...
once I've stopped propagating the event (on the SELECT) further, then it worked ok.
query("select", this.domNode).on(touch.press, function(e){e.stopPropagation()});
where this.domNode is the element on which the swipe is enabled
on(this.domNode, swipe, lang.hitch(this, "_onSwipe"));
Unfortunately the swipe (touch) event overriding the default behaviour is not very handy, I just left dojox/gesture/swipe or touch for now. Seems like I'll rather implement my own touch event handling.

Back and volume buttons not working when app is resumed in certain conditions

I'm starting a new activity to display a leaderboard in my Android App.
When the leaderboard activity is displayed, and the user presses the home key and then resumes the app (so the leaderboard activity comes up again), and then navigates back to the main activity by pressing the back key, the back key and volume keys stop working).
I've attempted to override onBackPressed in my activity class. I can confirm that when this problem occurs, onBackPressed is not called (When back / volume is working, pressing back does trigger onBackPressed).
Normally I get a message in LogCat when I press the back key 'Unimplemented WebView method onKeyDown called from android.webkit.WebView,onKeyDown(WebView.java.2178)' - Again I can confirm that this message doesn't come up when the back key isn't working
Armed with the above information, I can only assume that it's something to do with the View not having focus or something along those lines. I would point out that touch input on the screen itself does work. It just seems to be the back and volume keys/buttons that have no effect.
It's an openGL ES 2.0 app so in my onPause() I'm calling view.onPause(); and in onResume, I'm calling view.onResume();
I really have no idea what's going on and I've been on this for 3 days straight so if anyone can point me in the right direction, that would be great.
If the user comes out of the leaderboard and back into the main app before they press the home key, then everything is OK, it's just if the home key is pressed while the leaderboard activity is displayed as described above.
So when I'm at the point where the back / volume keys aren't working, if I click my scores button and fire up the leaderboard activity again, they work. On returning to my activity, they stop working again.
Not sure if this is relevant at all but the following shows how I'm starting my leaderboard activity:
if (scoresButtonPresses){
displayLeaderBoard();
}
void displayLeaderBoard(){
//Display the leaderboard if already signed in
if (checkSignedIn()){
startActivityForResult(Games.Leaderboards.getLeaderboardIntent(getApiClient(), leaderboardID), 1);
}
//if not already connected, then set flag and connect to play services before displaying leaderbaord
else{
signInAction=SHOW_LEADERBOARD;
getGameHelper().beginUserInitiatedSignIn();
}
}
#Override
public void onSignInSucceeded() {
//If the flag is set, then display the leaderboard
if (signInAction==DISPLAY_LEADERBOARD){
startActivityForResult(Games.Leaderboards.getLeaderboardIntent(getApiClient(), leaderboardID), 1);
}
//Otherwise, reset the flag and take no action
else {signInAction=NO_ACTION;}
}
This is driving me crazy so any help or even a nudge in the right direction would be very much appreciated!!
Edit
After much testing I have learned a couple of things:
If I remove the view.onPause() && view.onResume() the problem seems to go away. So this appears to be something to do with the way key events are captured by the view. Pausing and resuming seems to mess something up.
I have also tried removing the view.onPause() and view.onResume() as above, but instead, putting in View.setVisibility(View.GONE); and then making it visible again in public void onWindowFocusChanged(boolean hasFocus). Again, I get the same problem. Interestingly, when I open the leaderboard, as expected the view's staus is 'gone' then hitting the home key and running the app again, it's set back to 'visible' - I don't understand this behaviour but I'll ask another question for that.
Lastly, and this I find really odd. If I put my app back to as I had it, then after hitting the home key and relaunching the app via Eclipse (and I can do this multiple times) the problem doesn't seem to occur. So in that respect, it appears to be something to do with touching the screen.
Edit
It appears as though this isn't limited to my app. I've tested this on a couple of other apps from the Play store and get the same result.
One app clearly uses a single activity model like mine and the back and volume stop working throughout the app.
The other may use a different activity for it menu and game. When I test on this app, the back/volume breaks but if you start a game (therefore a second activity), the back key starts working again, even when you return to the first activity (recreated this activity?!)
So maybe I can get around this by ensuring the activity is recreated? I thought i was already but maybe I'm not getting something. Maybe it's something to do with the stack.........
I have no solution to your problem but some additional insights since I'm facing the same bug/problem with the leaderboards and the back button (and it's driving me crazy).
I'm using a single activity with fragments from which I login to Google Play, open Leaderboards and Achievements in the exact way you are doing it (startActivityForResult). Always when I come back from any Google Play Service activity my back button is broken. Sometimes it's even enough if I try to login to Google Play for it to break, meaning the login popup sometimes breaks the back button (but not always).
Some more insights which might help to solve the problem:
I'm not using OpenGL, so it's not related to this - I'm just using a single activity and fragments
It's also breaking for me when I just use the back button for going back from any Google Play Activity (I don't even need to go via the home key, just normal back is enough).
When the back button is broken the Activity is not receiving any Key Events (OnKeyDown, OnKeyUp, dispatchKeyEvent) are all not working, although using the activity and touching it fully works. My guess is that some view is catching the events...
Edit:
I also tried checking activity.getCurrentFocus() and activity.hasWindowFocus() as well as the parent and context classes of activity.getCurrentFocus() to see if there is any difference between when it's working and when it's not - and there isn't any difference...
Edit:
It seems that a simple call to View.requestFocus() is fixing the problem. For my single activity (using fragments implementation) I have now added:
#Override
public void onResume(){
super.onResume();
Fragment fragment = getFragmentManager().findFragmentById(R.id.fragmentContainer);
fragment.getView().requestFocus();
}
and this seems to be fixing the problem. Sill have to do long term checking if it's always fixed. In your OpenGL implementation I guess you will have to get the main view of the activity in some other way since you are not using fragments.
I know it's pretty old question, but for clarification: accepted answer is correct, but incomplete. Focus requesting should be done in onResume, onActivityResult, onSignInSucceeded and onSignInFailed. In first two you have! to call super. Some code:
private void requestFocusAfterGooglePlay(){
if(gimmeFocus==null)
return;
View currFocus=getCurrentFocus();
gimmeFocus.setFocusableInTouchMode(true);
gimmeFocus.setFocusable(true);
gimmeFocus.requestFocus();
gimmeFocus.setFocusableInTouchMode(false);
gimmeFocus.setFocusable(false);
if(currFocus!=null)
currFocus.requestFocus();
}
#Override
public void onSignInFailed() {
requestFocusAfterGooglePlay();
}
#Override
public void onSignInSucceeded() {
requestFocusAfterGooglePlay();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
requestFocusAfterGooglePlay();
super.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onResume(){
super.onResume();
requestFocusAfterGooglePlay();
}
in my case gimmeFocus is a dummy View created as below:
<View
android:id="#+id/gimme_focus"
android:layout_width="0px"
android:layout_height="0px"
android:focusable="false"
android:focusableInTouchMode="false"/>
I have dynamic layout so I can't never be sure that any view exists in my layout, so I've created this dummy View, it might be also added programmatically. You might choose your fixed View for gaining focus, but rembember that changing focus might change view's look (drawable state).

Wicket AjaxLink javascript handler shows strange behaviour

I have a ListView that displays a list of Panels, one below the other. Every panel features a button (implemented via AjaxLink) that closes the panel and removes it from the list.
This is how the ListView is initalized and how the panels are created:
panelsList = new ArrayList<MyPanel>();
pnlContainer = new WebMarkupContainer("pnlContainer");
ListView<MyPanel> pnlItems = new ListView<MyPanel>("pnlItems", panelsList) {
#Override
protected void populateItem(final ListItem<MyPanel> item) {
item.add(item.getModelObject());
item.add(new AjaxLink<Void>("pnlClose") {
#Override
public void onClick(AjaxRequestTarget target) {
panelsList.remove(item.getModelObject());
target.add(pnlContainer); // repaint panel container
}
});
}
};
pnlContainer.setOutputMarkupId(true);
pnlContainer.add(pnlItems);
add(pnlContainer);
This works so far - the actions that trigger adding new panels (usually also AjaxLinks) do what they should and the new panel is added and displayed correctly. But I have problems getting the close button to fully work.
Please see the following steps:
1) I start the server and navigate to the main page. The ListView is initially populated with one panel.
Close-button-code of this panel:
<a wicket:id="pnlClose" id="pnlClose7" href="javascript:;">Close</a>
Searching the page code for pnlClose7 finds the following javascript code that makes the button work as expected:
Wicket.Ajax.ajax({"u":"./?0-1.IBehaviorListener.0-pnlContainer-pnlItems-0-pnlClose","e":"click","c":"pnlClose7"});;
Note: I do not press the button now, if i would, it would work as expected (thoroughly tested).
2) I trigger an action that opens a second panel. The panel is displayed below the first one as expected.
Close-button of the first panel:
<a wicket:id="pnlClose" id="pnlClosef" href="javascript:;">X</i></a>
Close-button of the second panel:
<a wicket:id="pnlClose" id="pnlClose10" href="javascript:;">X</i></a>
But now, neither searching for pnlClosef nor pnlClose10 finds some javascript code. The buttons (both!) do not work. I can still find the javascript code for pnlClose7.
3) I reload the page via pressing F5.
The button IDs change to pnlClose1a and pnlClose1b. Both IDs have javascript counterparts and work.
4) I press the first button (upper panel, ID pnlClose1a). The panel is closed as expected.
The remaining button's ID changes to pnlClose1c, again without a javascript counterpart. Javascript code for pnlClose1a and pnlClose1b is still present.
To make a long story short, the javascript handlers for my AjaxLinks seem to have shyness issues and only appear after I press F5 or reload the whole page in any other manner. I guess thats because repainting the pnlContainer changes the IDs of the current panels - but why is the linked javascript not updated at the same time? Is there anything I can change in my code to update the whole page without completely reloading it?
Wierd thing is that I am pretty sure this worked before... But I checked the whole class history and can't find any major change that would have triggered that. The ListView-code is mainly static since I added it.
I was had similiar problem. if you have any hardcoded javascript code in your page or panels html file (using <script> tag) remove it and set that js code in renderHead of your panel.

mouseenter event does not working for gwt celltable

I have one celltable and I need to add handler on its row for "mouseenter" event.
I have tried something like following, but its not working for "mouseenter" althought it works for "mouseover".
cellTable.addCellPreviewHandler(new CellPreviewEvent.Handler<Test>(){
#Override
public void onCellPreview(CellPreviewEvent<Test> event) {
if ("mouseenter".equals(event.getNativeEvent().getType())){
Window.alert("mouse entered");
}
}
});
Is not working properly for mouseenter events because apparently is only implemented by IE and Opera, since you're Chrome, you can just wait until they implement it.
Unfortunately Firefox, Chrome, and Safari still haven’t copied this brilliant Microsoft invention, that has even made it to the spec. Come on, guys!
From this source.

GWT handling onBlur is also stopping the propagation of the event [duplicate]

This question already exists:
Closed 10 years ago.
Possible Duplicate:
in Chrome not getting an onClick() on a FocusPanel when focus was on a TextArea that has registered onChange and onBlur handlers
In my GWT app I register a BlurHandler on a TextArea so that I can save the changes and go from edit mode back to view mode if the focus moves elsewhere. This works, but also seems to defeat the effect of the event that moved the focus, at least on Chrome in devmode. For example, if the user clicks on an Anchor, the TextBox gets the onBlur() and then the Anchor does not get the onClick(); whereas before I registered the onBlur, the Anchor would get the onClick(). This seems to be quite reliable (again, in Chrome in devmode). I am being careful to not call event.stopPropagation() or event.preventDefault(). Any ideas how I can get the onBlur and also the onClick() ?
I had a similar issue. I was not able to track the source problem though. I did enable dev toolbar / firebug and set event breakpoints to test; it does look like the click event was not triggered after the blur action. After playing around for many hours (and I'm not quite sure what inspired me to try this), I dropped the onblur action in a timer with executed delay at about 300ms. That seemed to work for me. I think it might have something to do with the fact that my action slightly modified the page and visibility of items, witch re-rendered the page and I can only guess that the single-threaded browser model killed the click event which was not longer on the right area.
textBox.addBlurHandler(new BlurHandler()
{
#Override
public void onBlur(BlurEvent event)
{
Timer delayTimer = new Timer()
{
#Override
public void run()
{
//do stuff
}
};
delayTimer.schedule(300);
}
});
anchor.addClickHandler(....)