Picture-in-Picture video - chromium

So, I have been using Opera as my main browser just because of preference, but I want to come away from it and go to another browser, probably chromium because my job works with websites and Opera isn't the greatest.
My most loved feature of Opera is the pop-out video feature. As seen by the screen shot below of
Opera 65.0.3467.62 on my Arch Linux running suckless DWM.
My problem is the newer versions of chromium use a different method for this video pop-out. Above is Opera 65, but if I update to after, it becomes a new window (screen shot below). You can see that my DWM can see it as a new window seen by a title in top 'Picture-in-Picture'.
Just as another screenshot, here is my Chromium doing the same thing.
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating monitor */
{ "Gimp", NULL, NULL, 0, 1, -1 },
{ "Picture-in-picture", NULL, NULL, 0, 1, -1 },
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
};
I presume there are a couple of ways to fix this, either a patch for the browser to prevent it from becoming a new window, or a new line in my DWM config, possibly in rules. I did try that above, but my problem is, I have no clue how to do this, or revert the pop-out video to an old version. Can anyone help me?

static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating monitor */
{ "Gimp", NULL, NULL, 0, 1, -1 },
{ NULL, NULL, "Picture-in-picture", ~0, 1, -1 },
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
};
So, I did a bit of testing using the rules, the line in the middle is what I used. Title, for the pop-out video title, tag mask ~0 for all the tags and isFloating to 1 to float it.
I think I will stick with this method, and use DWM default keybinds.
MOD+LMB = Move floating window
MOD+RMB = Resize floating window

Related

How to have a pushpin (MapIcon) without the black line and offset

I'm using a XAML-MapControl in a UWP-project.
When you create a MapIcon, the image is floating a fixed offset above the desired location on the map, instead of directly on the map, with a black line connecting the icon with the map, as you can see in this image:
I can't find a way to remove this line, or reduce its size.
And none of the other MapElement-types seem to do what I want, I want the exact behavior of the MapIcon, but without this line.
Is there a way to do that?
Edit:
Here's how I create the MapIcons:
var icon = new MapIcon
{
NormalizedAnchorPoint = new Point(0.5, 1),
Image = image,
Visible = true,
};
MapControl.MapElements.Add(icon);
Edit2:
I tried to set the stylysheet, but it does not work for me, probably because it's only supported in a version newer than the one I target:
MapControl.StyleSheet = MapStyleSheet.ParseFromJson("{ \"version\": \"1.*\", \"settings\": { }, \"elements\": { \"userPoint\": { \"stemAnchorRadiusScale\": 0, \"stemHeightScale\": 0 }}}");
You need to set the stemAnchorRadiusScale and stemHeightScale properties of userPoint to 0 in the map style sheet. See this topic for how to work with style sheets:
https://learn.microsoft.com/en-us/windows/uwp/maps-and-location/elements-of-map-style-sheet.
For example:
{
"version": "1.*",
"settings": {
},
"elements": {
"userPoint": {
"stemAnchorRadiusScale": 0,
"stemHeightScale": 0
}
}
}

How can I screenshot the full height of a mobile form factor?

When testing mobile form factors, Chrome screenshots just the visible window. I'm fine with that being the standard and expected behaviour. However, I additionally want to capture the full scrolled height of the page so I can inspect the rendering of the entire page.
I thought the simplest solution was to set the chrome window height to be a sufficiently large value, and job done. However, the Chrome window height seems bound by my physical screen height, ie. I set it to 5,000 with browser.manage().window().setSize(375,5000);, but it only resizes to a height of 1,200.
I already know [According to the WebDriver specification][1], the [takeScreenshot() function][2] is not supposed to capture the entire page, but should make a screenshot of the visible area only.
OP EDIT: I went with the final option below which I've labelled "Working solution!!"
Below are the different grouped by type strategies to solve the problem.
Scroll, take screenshot, append
Quoting the author of the screenshot system at the CrossBrowserTesting.com:
As the author of the screenshot system for CrossBrowserTesting.com, I can tell you that the only way we've been able to get full page screenshots consistently and reliably across browsers is to scroll, capture, and append images.
Here is a sample working implementation of scrolling and taking visible area screenshots using cnn.com as an example target. Using scrollHeight, clientHeight and scrollTop to determine where we are on a vertical scroll position and how much more to scroll down. Since we are dealing with promises in a loop, we have to make a recursive function with a "we are at the bottom" base condition:
var fs = require('fs'),
Utils = {
screenShotDirectory: '',
writeScreenShot: function (data, filename) {
var stream = fs.createWriteStream(this.screenShotDirectory + filename);
stream.write(new Buffer(data, 'base64'));
stream.end();
},
getSizes: function () {
return browser.executeScript("return {scrollHeight: document.body.scrollHeight, clientHeight: document.body.clientHeight, scrollTop: document.body.scrollTop};");
},
scrollToBottom: function (height, index) {
var self = this;
self.getSizes().then(function (data) {
// continue only if we are not at the bottom of the page
if (data.scrollTop + data.clientHeight < data.scrollHeight) {
browser.executeScript("window.scrollTo(0, arguments[0]);", height).then(function () {
browser.takeScreenshot().then(function (png) {
self.writeScreenShot(png, "test" + index + ".png");
});
});
self.scrollToBottom(height + data.clientHeight, index + 1);
}
});
}
};
describe("Scrolling and saving screenshots", function () {
beforeEach(function () {
browser.ignoreSynchronization = true;
browser.get("http://www.cnn.com/");
});
it("should capture an entire page", function () {
Utils.getSizes().then(function (data) {
Utils.scrollToBottom(data.clientHeight * 2, 1);
});
});
});
It would produce multiple test<index>.png images that you can then glue together.
To concatenate images in a "single column image", you may, for instance, use the GraphicsMagick Image Processing System through the gm nodejs module. The .montage() method with the concatenate option in the 1x mode would be helpful. Sample code:
var gm = require('gm');
Utils.getSizes().then(function (data) {
var index = Utils.scrollToBottom(data.clientHeight * 2, 1);
var op = gm();
for (var i = 1; i <= index; i++) {
op = op.in("test" + i + ".png");
}
op = op.montage().mode("concatenate").tile("1x");
op.write('output.png', function (err) {
if (err) console.log(err);
});
});
Change the Browser
In Chrome, you would always get only the visible area on the resulting screenshot, here is the relevant chromedriver issue with a lot of information about the issue and multiple workarounds:
ChromeDriver2 take screenshot is not full page
Somewhat surprisingly, it should though work in Firefox - switch to it if possible:
Chrome screenshots that take up the entire screen are not like Firefox's. Firefox will capture the entire screen, even parts of it that are not currently viewable. Chrome will not!
Tweak the Screen Size
Another option would be to use services like BrowserStack or SauceLabs to start your tests on a specific platform in a specific browser and, using a specific large enough resolution. Protractor supports Sauce Labs and BrowserStack out-of-the-box.
Example configuration for BrowserStack:
exports.config: {
browserstackUser: "user",
browserstackKey: "key",
capabilities: {
'browserstack.local': true,
'browserstack.debug': true,
browserName: "Chrome",
os: "Windows",
os_version: "8",
resolution: "2048x1536"
},
}
Then, maximize the browser window (inside onPrepare(), for instance):
browser.driver.manage().window().maximize();
And make a screenshot.
Working solution!!!
Another option could be to run tests in a Virtual Display. I you would follow this blogpost and use Xvfb, when you will run the Xvfb server, you may specify the resolution:
/usr/bin/Xvfb :99 -ac -screen 0 2048x6000x24 &
Also see related information on this topic here:
AngularJS Headless End to End Testing With Protractor and Selenium
What is a good headless browser to run with protractor?
You may also use the docker-selenium solution which allows to configure the screen size.

Animating Hub's scrolling

I've written an Attached Property to be able to bind the index of the displayed HubSection to my ViewModel, so that I can change it within my code.
I'm using the Hub's ScrollTo(section) method but it doesn't animate the scroll, so I decided to use the ScrollViewer inside the Hub with the ChangeView method.
What happens is that, having 4 HubSection, it just scrolls to the second one before hanging.
The viewer.HorizontalOffset stays fixed at 360 (which is the HubSection's ActualWidth) and there's no way to change it!
Here's the code that I'm using to animate the scroll:
async private static Task ScrollHubToSection(Hub hub, HubSection section, int index)
{
var dispatcher = hub.Dispatcher;
var viewer = hub.GetDescendantsOfType<ScrollViewer>().First();
var offset = index*section.ActualWidth;
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => viewer.ChangeView(offset, null, null, false));
}
(GetDescendantsOfType is from WinRTXamlToolkit.Controls.Extensions)
What I'd expect is that calling
ScrollHubSection(myHub, section1, 1)
should scroll the viewer to an HorizontalOffset of 360, while
ScrollHubSection(myHub, section2, 2)
(with offset becomes correctly 720) still leaves HorizontalOffset to 360 which is quite nonsens.
If I manually insert the offset by doing
viewer.ChangeView(1000, null, null, false));
it goes to an HorizontalOffset of 1000, but if I do
viewer.ChangeView(offset, null, null, false));
when offset is 1000 it doesn't work.
This is really driving me mad because I've wasted the whole afternoon trying to fix it without success.
Can you please help me?
You can do it like this.
async private static Task ScrollHubToSection(Hub hub, HubSection section, int index)
{
var dispatcher = hub.Dispatcher;
var viewer = hub.GetDescendantsOfType<ScrollViewer>().First();
double offset = 0;
for (int i = 0; i < index; i++)
{
offset += hub.Sections[i].ActualWidth;
}
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => viewer.ChangeView(offset, null, null, false));
}

How to change the "Fullscreen in browser" for the Snapped view (Windows 8 apps - Construct 2)

I'm working on a Windows 8 application using Construct 2.
I set the Fullscreen in browser to Letterbox scale, and I want to change it to Scale for the Snaped view.
I found the Windows8 on view state Snapped event, but I didn't found the action that change the Fullscreen in browser.
I found a solution that works for me.
First I export the windows 8 application from construct 2 without minifying the script (uncheck Minify script), and then under VS2012 I added to the end of c2runtime.js this lines:
window.addEventListener("resize", onResize);
function onResize() {
window.location.reload();
}
and I changed the line 18068, that contains the mode number to :
(Windows.UI.ViewManagement.ApplicationViewState.snapped == Windows.UI.ViewManagement.ApplicationView.value)?2:3
Which means when the state view change, I set the Fullscreen in browser to 2 or 3 depending on Windows.UI.ViewManagement.ApplicationView.value
PS : 0 = off, 1 = crop, 2 = scale, 3 = letterbox scale, 4 = integer letterbox scale
The last part of the c2runtime.js :
"media/",
false,
768,
1366,
(Windows.UI.ViewManagement.ApplicationViewState.snapped == Windows.UI.ViewManagement.ApplicationView.value)?2:3,
true,
true,
true,
"1.0",
2,
false,
0,
false
];
};
window.addEventListener("resize", onResize);
function onResize() {
window.location.reload();
}

youtube API - setShuffle don't work

I added this script in my site to reproduce video playlist.
<script type="text/javascript" src="swfobject.js"></script>
<div id="ytapiplayer">
You need Flash player 8+ and JavaScript enabled to view this video.
</div>
<script type="text/javascript">
var params = { allowScriptAccess: 'always',
allowFullScreen: 'true' };
var atts = { id: 'myytplayer' };
swfobject.embedSWF("https://www.youtube.com/v/videoseries?listType=playlist&list=PLBA9E733B5C8314DE&autoplay=1&modestbranding=1&enablejsapi=1&playerapiid=ytplayer&version=3", "ytapiplayer", "640", "360", "8", null, null, params, atts);
function onYouTubePlayerReady(myytplayer) {
ytSwfPlayer = document.getElementById( 'myytplayer' );
ytSwfPlayer.setShuffle(1);
}
</script>
the setShuffle function don't work!!!
You can suggest me a solution?
This appears to be a bug in the player. I've reported this bug to the team. In the future you can report bugs at https://code.google.com/p/gdata-issues/issues/entry?template=YouTube%20(Defect%20Report)
As a work around you could use the JS api to shuffle it yourself. When a video ends you can call playVideoAt and pass a random number.
The problem is that if you've loaded a playlist queue in the Youtube player, the next track will automatically start at the end of the current playing one.
So you should bind track ended event (which is event.data = 0) and then make the youtube player make two things:
stop playing
play a new track with a random index by calling playVideoAt method.
A simple solution to avoid repeating the same track more times is to store the played idx in a list. Then, you should have a function, like shuffle that generates a random integer between 0 and the queue length:
function getRandomId() {
var random_id = 0
while(played_idx.indexOf(random_id) != -1) {
random_id = Math.floor(Math.random * playlist.length)
}
return random_id
}
Then, simply call playVideoAt(random_id).
I've noticed that setShuffle does work if you launch the command a little later. Something like this:
function onPlayerReady(event) {
event.target.mute();
setTimeout( function() {
event.target.setShuffle(true);
event.target.setLoop(true);
}, 2000);
}
If you launch it directly, it will definitely not work (I have noticed, to my frustration).