Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wishlist: Prevent exiting fullscreen mode when pointer exits window #5

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
@@ -0,0 +1,3 @@
*.o
*.so
tester
5 changes: 4 additions & 1 deletion Makefile
@@ -1,4 +1,4 @@
BITS=32
BITS=64

all: tester libfullscreenhack.so

Expand All @@ -15,6 +15,9 @@ test: all
echo running with the hack...
LD_PRELOAD=./libfullscreenhack.so ./tester

fftest: all
LD_PRELOAD=`pwd`/libfullscreenhack.so firefox 'http://www.youtube.com'

clean:
rm -f *.o *.so tester

Expand Down
12 changes: 11 additions & 1 deletion README
Expand Up @@ -8,7 +8,9 @@ Why
Flash plugin incorrectly determines the fullscreen resolution when
using nvidia twinview. The result is that fullscreen windows fill
the primary monitor, but the video gets scaled as if the primary
monitor had the resolution of the total display area.
monitor had the resolution of the total display area. Even worse,
Flash has a nasty habit of dropping out of fullscreen mode when
you try to do anything on the other monitor.

How
---
Expand All @@ -20,6 +22,10 @@ causes it to instead return the size of a single monitor.

The monitor sizes sent are now based on Xinerama.

Fullscreen mode is no longer dropped when Flash loses focus by
simply masking out PropertyChange X events, stopping the
behaviour entirely.


Config
------
Expand Down Expand Up @@ -47,6 +53,10 @@ make test

This runs the tester app with and without the patch to verify that it works.

make fftest

This runs Firefox with the patch enabled so Flash can be tested directly.

Install it:

sudo make install
Expand Down
48 changes: 31 additions & 17 deletions fullscreenhack.c
@@ -1,16 +1,20 @@
// fullscreenhack.c
// Alistair Buxton <a.j.buxton@gmail.com>
// extended by Steve Purchase <steve@t220.com>

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xinerama.h>

typedef Status (*xgg_func)(Display *, Drawable, Window *,
int *, int *, unsigned int *,
unsigned int *, unsigned int *,
typedef Status (*xgg_func)(Display *, Drawable, Window *,
int *, int *, unsigned int *,
unsigned int *, unsigned int *,
unsigned int *);

typedef int (*xselectinput_func)(Display*, Window, long);

typedef XineramaScreenInfo * (*xsi_func)(Display*,int*);

typedef int (*xfree_func) (void *);
Expand All @@ -28,7 +32,7 @@ void load(void)
fprintf(stderr, "fullscreen hack loaded...\n");
}

int choose_screen(Display *display, XineramaScreenInfo *screens,
int choose_screen(Display *display, XineramaScreenInfo *screens,
int n_screens, void *xlib_handle)
{
const char *s = getenv("FLASH_FULLSCREEN_DISPLAY");
Expand All @@ -37,21 +41,20 @@ int choose_screen(Display *display, XineramaScreenInfo *screens,
Window root = RootWindow(display, DefaultScreen(display));
int x, y, wx, wy, n;
unsigned int mask;
Bool result;
if (s != NULL) {
int w = strtol(s, &e, 0);
if (e != NULL && *e == 0 && w >= 0 && w < n_screens)
return w;
}
xqp_func xqp = dlsym(xlib_handle, "XQueryPointer");
result = xqp(display, root, &a, &b, &x, &y, &wx, &wy, &mask);
xqp(display, root, &a, &b, &x, &y, &wx, &wy, &mask);
fprintf(stderr, "pointer: %dx%d\n", x, y);
for(n=0;n<n_screens;n++) {
fprintf(stderr, "screen %d, %dx%d+%d+%d\n", n, screens[n].width,
fprintf(stderr, "screen %d, %dx%d+%d+%d\n", n, screens[n].width,
screens[n].height, screens[n].x_org, screens[n].y_org);
if (x >= screens[n].x_org &&
if (x >= screens[n].x_org &&
x < (screens[n].x_org + screens[n].width) &&
y >= screens[n].y_org &&
y >= screens[n].y_org &&
y < (screens[n].y_org + screens[n].height)) {
fprintf(stderr, "match found\n");
return n;
Expand All @@ -60,20 +63,20 @@ int choose_screen(Display *display, XineramaScreenInfo *screens,
return 0;
}

Status XGetGeometry(Display *display, Drawable d, Window *root_return,
int *x_return, int *y_return,
unsigned int *width_return,
unsigned int *height_return,
unsigned int *border_width_return,
Status XGetGeometry(Display *display, Drawable d, Window *root_return,
int *x_return, int *y_return,
unsigned int *width_return,
unsigned int *height_return,
unsigned int *border_width_return,
unsigned int *depth_return)
{
void *xlib_handle;
Status s;
xlib_handle = dlopen("libX11.so", RTLD_LAZY);
xgg_func xgg = dlsym(xlib_handle, "XGetGeometry");
s = xgg(display, d, root_return,
x_return, y_return,
width_return, height_return,
s = xgg(display, d, root_return,
x_return, y_return,
width_return, height_return,
border_width_return, depth_return);

if (d == RootWindow(display, DefaultScreen(display))) {
Expand All @@ -96,4 +99,15 @@ Status XGetGeometry(Display *display, Drawable d, Window *root_return,

}

int XSelectInput(Display* display, Window window, long event_mask)
{
void *xlib_handle;
xlib_handle = dlopen("libX11.so", RTLD_LAZY);
xselectinput_func fn = dlsym(xlib_handle, "XSelectInput");

// Mask out PropertyChange events so Flash doesn't realise
// the pointer/focus has left the window.
event_mask &= ~PropertyChangeMask;

return fn(display, window, event_mask);
}