Handle multiple pointer events in IE11 Metro/Mobile with pan-x and pan-y touch-action allowed - touch

I have a web application where I want to handle the pinch zooming gesture in javascript rather than allowing the browser to scale all of the UI. In IE11, it's my understanding that you need to specify a touch-action CSS on the element you wish to handle pointer events for.
In my application, I've disabled all touch behavior except for panning (touch-action: pan-x pan-y). I've wired up the pointerdown, pointerup, and pointermove events in javascript and I've added my own calculations to determine the level of zoom to perform based on distance between two active pointers (pinch gesture).
In IE11 on the desktop, this works exactly as I'd expect; however, on the mobile/metro version of IE (I've been testing on surface pro), I can never seem to detect more than one pointer event at a given time. It simply fires a pointercancel on the first captured event and fails to fire the second pointerdown. If I disable all touch gestures (touch-action: none), I'm able to get the multi-touch pointer events in the mobile browser as well, but it no longer allows panning, which is undesirable.
Here's a simple jsfiddle that demonstrates the issue:
http://jsfiddle.net/wqgg0Ly7/22/
$(document).ready(function()
{
var pointers = [];
function pointerDown(e)
{
pointers.push(e);
if (pointers.length >= 2)
alert("multiple pointers detected");
};
function pointerOut(e)
{
for (var i in pointers)
if (pointers[i].pointerId == e.pointerId)
pointers.splice(i, 1);
};
$(".container")
.on("pointerdown", pointerDown)
.on("pointerout", pointerOut)
.on("pointercancel", pointerOut);
});
};
If you test this in the Desktop version of IE11 on a touch-enabled device, you can pinch either one of these DIVs and you'll see the alert that two pointers were detected. Doing this same test in IE11 mobile, and only the first DIV will detect the second pointer; however, it doesn't allow panning like the second DIV.
Is this simply a bug in IE Metro or is there a work-around to allow panning on an element but still capture multiple pointer events?

Related

Firebreath NPAPI plugin rendering video to top level browser window (HWND)

I am working on a audio/video rendering plugin that is using FireBreath and we have a need to get HTML elements to overlay on top of the video. I am aware that to do this I need to use the windowless mode in FireBreath. However since I am using DirectX to render the video I cannot initialize DirectX with the HDC handle (it requires a HWND) that I get when I am instructed to render in windowless mode.
Also for other software security reasons I cannot render the video to an off-screen surface then Blt the bits to the HDC.
The alternative I was trying to accomplish is to use the Hardware Overlay feature in DirectX and use the browser's TOP level HWND to initialize DirectX, then use the HDC and coordinates to tell directX where in the TOP browser window to render the video frame. And render it directly to the top parent browser window.
I have tired a proof of concept, but I am seeing my video frames getting erased quite often after I draw them and thus the video appears to be flickering. I am trying to understand why that might be and I am wondering if this is not a viable solution given my parameters.
Also I am wide open to suggestions on how to accomplish this given my constraints.
Any help would be greatly appreciated!
In the FireBreath-dev group, John Tan wrote:
As what I know, you practically have no control precisely when the screen is going to draw. What can only be done is:
1) Inform the browser to repaint by issuing the windowless invalidatewindow
2) browser draw event arrives with the hdc. Draw on the hdc
John is completely correct. In addition, the HDC could potentially (perhaps likely will) be different each time your draw is called. I don't know of anyone who has successfully gotten directx drawing using windowless mode, and you have absolutely no guarantee that what you are doing will ever work as even if you got it working the browser may change the way or order that it draws in in a way that would break it.
You might want to look at the async surface API; I don't know which browsers this works on but I suspect likely only Firefox and IE. It was implemented in this commit.
I haven't used this at all, so I can't tell you how it works, but it was intended to solve exactly the problem you're describing. Your main issue will be browser support. What documentation there is is here.
Hope this helps

How can I turn off hardware acceleration for certain HTML elements via CSS?

I created a very complex web app using HTML5, CSS3 and jQueryMobile.
It seems like jQueryMobile turns on hardware acceleration here and there via translate3D and/or translateZ.
Now I want to turn this off for certain HTML elements.
This gives me two questions:
Is there a css property/attribute or something that I can use to tell the browser to turn off hardware acceleration for certain elements?
If not: I will have to find the places where either translate3D or translateZ is used and simply remove them, right? How can I do that? The whole markup is very complex with many HTML elements. I can't go through each element in the inspector and search for it.
Update: The reason why I want to fix this
In my web app there are some elements which need to be swipeable (e.g. an image gallery). In this case I need hardware acceleration. Same for div containers that require iScroll and every other element which should be animated (e.g. slide- and fade-animations).
However, there are many parts of the app which are static (not animated). Using a special startup option in Safari, I was able to make the parts which get hardware-accelerated visible. This way I noticed that THE WHOLE app gets hardware-accelerated, not only the necessary parts.
IMHO this is not a good thing because:
Accelerating the whole thing will cause heavy load to the GPU which makes the whole app stutter while scrolling.
AFAIK it's best practice to let the CPU do the static stuff while the GPU only handles all the fancy animated stuff.
When animations have ended, hardware acceleration should be deactived because it's not necessary anymore and would shorten battery lifetime.
After going through thousands of thousands of lines of CSS code, I found this:
.ui-page{-webkit-backface-visibility: hidden !important}
This was active for all pages and caused the problem. Removing that line fixed it for me.

Detect Touchpad event in C++ Builder

I am writing an API in C++ Builder that collects information for events on the touchpad of a windows laptop.
This is how I was doing it.
I was creating a window
when the touch pad is touched, I simply paint that information on that window in WM_PAINT event.
But now I dont want to create that window (form), i want to catch all the events, even if user is on desktop screen or on another application's window. If an application that is using my API is running in background i want to be able to get that touch even information in the code. How can I do that??
I hope you are getting my point ... actually i want to do it in a seamless way, otherwise that white form window will irritate the user.
I also want to save these events in a link list and want to return that out of the API is it possible??
I will be very thankful for your time. I really need to work it out in next few hours.
The touchpad is just a mouse like any other. It generates standard mouse events. Use a global WH_MOUSE hook via SetWindowsHookEx() to capture mouse events globally. To replay them, use mouse_event(). Alternatively, use WH_JOURNALRECORD and WH_JOURNALPLAYBACK hooks instead for capture and playback, respectively.

How can I detect when a user holds their finger over an image in a UIWebView?

In Mobile Safari, if you hold your finger over an image for a second or two, a little popup appears giving you the option of saving or copying the image.
Is there any way to do this in a UIWebView in an app? Gesture recognizers seem to be ignored and I don't see any way to hook into that behavior.
I am not very strong in web dev, but i am pretty shure you should use custom java script code which will detect the click on image and call the popup to appear.
Here is just an example how simple js injection works in iOS UiWebView.
There are javascript events you can hook into to get the effect you want
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[webView stringByEvaluatingJavaScriptFromString:#"window.ontouchstart=function(/* ... */);"];
}
Put your custom code in ontouchstart. I'd imagine what you want is a timer that checks if the user releases the touch before x milliseconds, and if that doesn't happen, you can call an obj-c function from javascript to activate the popup. Get the coords of the touch event and compare them to the coords of all the images in your page.
I'm hoping someone will know of a native way to do this though; this is a really hackish workaround.

Safari iPhone - How to detect zoom level and offset?

I looking for options on how to track user zooming and panning on a page when viewed in Safari on an iPhone. Safari exposes move and gesture events, so theoretically I can keep a running tally of pan and zoom operations, but that seems like overkill since the browser must track that internally.
Is this information exposed through the Document Object Model?
When you zoom in, window.innerWidth is adjusted, but document.documentElement.clientWidth is not, therefore:
var zoom = document.documentElement.clientWidth / window.innerWidth;
(I've tested iOS4, without viewport <meta>).
However, I wouldn't rely on it for anything important. DOM viewport sizes/pixel sizes in mobile browsers are a complete mess.
On Mobile Safari and Android, here is an accurate way to measure how much the page has been zoomed.
Try it here: http://jsbin.com/cobucu/3 - change zoom then click measure.
Technique is to add a top level div:
<body>
<div id=measurer style="position:absolute;width:100%"></div>
and use the calculation:
function getZoom(){
return document.getElementById('measurer').offsetWidth / window.innerWidth;
}
The only problem is finding a tidy way to detect that the user has changed zoom (pinch, double tap, etc). Options:
webkitRequestAnimationFrame: very reliable, but likely to cause jankiness if using animations (due to performance hit)
setInterval: reliable but very ugly
touch events: look for two fingers or
double tap: ugly and maybe difficult to make 100% reliable
window.onresize + window.onorientationchange + window.onscroll: simple but totally unreliable (Edit: and onscroll can cause performance problems in WKWebView or Mobile Safari 8 or greater).
PS: Windows Phone needs a different solution (pinch-zoom doesn't change the viewport - pinch-zoom on Windows has its own separate viewport that is not visible to javascript).
Edit: Android Visual Viewport resize and scroll events may help? See https://developer.mozilla.org/en-US/docs/Web/API/VisualViewport#Events
According to the Safari Web Content Guide, zoom events (double tap) are not exposed, so I'm not sure how you can track this.
I do not believe this information is exposed through the DOM.
I actually think things might have moved on a little since Steve's answer, as having a look at the content guide link he provided I can see a section on Handling Multi-Touch Events and also Handling Gesture Events.
Haven't tried them yet but they look pretty promising. I'll provide an update once I've checked them out and have a demo link available...
I measure zoom this way (works on iOS only):
screenOrientedWidth = screen.width;
if (window.orientation == 90) {
screenOrientedWidth = screen.height;
}
return screenOrientedWidth / window.innerWidth;
It doesn't depend of how wide content is.
However, in iOS Safari window.innerWidth isn't correct inside a gestureend handler. You should defer such calculation for later execution. In GWT, I use scheduleDeferred, but I can't say how to implement this in pure JavaScript.
If you are using any elements with location:fixed this can get complicated, as the location:fixed coordinates are relative to the unzoomed window, where window coordinates are relative to the zoomed viewport. More info: How to position a fixed-location element on IOS browser when zoomed?