forked from AuroraMiddleware/gtk
[broadway] Add configure event for browser-side geometry changes
Atm this only works for the useToplevelWindows case, but we can add a browser wm to make use of it inside the browser too.
This commit is contained in:
parent
1365e93fad
commit
adc05ae6b7
@ -88,7 +88,27 @@ function resizeBrowserWindow(window, w, h) {
|
||||
h + outerH - innerH);
|
||||
}
|
||||
|
||||
function resizeCanvas(canvas, w, h)
|
||||
{
|
||||
/* Canvas resize clears the data, so we need to save it first */
|
||||
var tmpCanvas = canvas.ownerDocument.createElement("canvas");
|
||||
tmpCanvas.width = canvas.width;
|
||||
tmpCanvas.height = canvas.height;
|
||||
var tmpContext = tmpCanvas.getContext("2d");
|
||||
tmpContext.globalCompositeOperation = "copy";
|
||||
tmpContext.drawImage(canvas, 0, 0, tmpCanvas.width, tmpCanvas.height);
|
||||
|
||||
canvas.width = w;
|
||||
canvas.height = h;
|
||||
|
||||
var context = canvas.getContext("2d");
|
||||
|
||||
context.globalCompositeOperation = "copy";
|
||||
context.drawImage(tmpCanvas, 0, 0, tmpCanvas.width, tmpCanvas.height);
|
||||
}
|
||||
|
||||
var useToplevelWindows = false;
|
||||
var toplevelWindows = [];
|
||||
var grab = new Object();
|
||||
grab.window = null;
|
||||
grab.ownerEvents = false;
|
||||
@ -103,6 +123,9 @@ var windowWithMouse = 0;
|
||||
var surfaces = {};
|
||||
var outstandingCommands = new Array();
|
||||
var inputSocket = null;
|
||||
var frameSizeX = -1;
|
||||
var frameSizeY = -1;
|
||||
|
||||
|
||||
var GDK_CROSSING_NORMAL = 0;
|
||||
var GDK_CROSSING_GRAB = 1;
|
||||
@ -214,6 +237,67 @@ function ensureSurfaceInDocument(surface, doc)
|
||||
}
|
||||
}
|
||||
|
||||
var windowGeometryTimeout = null;
|
||||
|
||||
function updateBrowserWindowGeometry(win) {
|
||||
if (win.closed)
|
||||
return;
|
||||
|
||||
var surface = win.surface;
|
||||
|
||||
var innerW = win.innerWidth;
|
||||
var innerH = win.innerHeight;
|
||||
|
||||
var x = surface.x;
|
||||
var y = surface.y;
|
||||
if (frameSizeX > 0) {
|
||||
x = win.screenX + frameSizeX;
|
||||
y = win.screenY + frameSizeY;
|
||||
}
|
||||
|
||||
if (x != surface.x || y != surface.y ||
|
||||
innerW != surface.width || innerH != surface.height) {
|
||||
var oldX = surface.x;
|
||||
var oldY = surface.y;
|
||||
surface.x = x;
|
||||
surface.y = y;
|
||||
if (surface.width != innerW || surface.height != innerH)
|
||||
resizeCanvas(surface.canvas, innerW, innerH);
|
||||
surface.width = innerW;
|
||||
surface.height = innerH;
|
||||
sendInput ("w", [surface.id, surface.x, surface.y, surface.width, surface.height]);
|
||||
for (id in surfaces) {
|
||||
if (surfaces[id].transientToplevel != null && surfaces[id].transientToplevel == surface) {
|
||||
var childSurface = surfaces[id];
|
||||
childSurface.x += surface.x - oldX;
|
||||
childSurface.y += surface.y - oldY;
|
||||
sendInput ("w", [childSurface.id, childSurface.x, childSurface.y, childSurface.width, childSurface.height]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function registerWindow(win)
|
||||
{
|
||||
toplevelWindows.push(win);
|
||||
win.onresize = function(ev) { updateBrowserWindowGeometry(ev.target); };
|
||||
if (!windowGeometryTimeout)
|
||||
windowGeometryTimeout = setInterval(function () { toplevelWindows.forEach(updateBrowserWindowGeometry); }, 2000);
|
||||
}
|
||||
|
||||
function unregisterWindow(win)
|
||||
{
|
||||
var i = toplevelWindows.indexOf(win);
|
||||
if (i >= 0)
|
||||
toplevelWindows.splice(i, 1);
|
||||
|
||||
if (windowGeometryTimeout && toplevelWindows.length == 0) {
|
||||
clearInterval(windowGeometryTimeout);
|
||||
windowGeometryTimeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
function getTransientToplevel(surface)
|
||||
{
|
||||
while (surface.transientParent != 0) {
|
||||
@ -232,6 +316,7 @@ function cmdCreateSurface(id, x, y, width, height, isTemp)
|
||||
surface.visible = false;
|
||||
surface.window = null;
|
||||
surface.document = document;
|
||||
surface.transientToplevel = null;
|
||||
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.width = width;
|
||||
@ -269,6 +354,8 @@ function cmdShowSurface(id)
|
||||
'width='+surface.width+',height='+surface.height+
|
||||
',left='+surface.x+',top='+surface.y+',screenX='+surface.x+',screenY='+surface.y+
|
||||
',location=no,menubar=no,scrollbars=no,toolbar=no');
|
||||
win.surface = surface;
|
||||
registerWindow(win);
|
||||
doc = win.document;
|
||||
doc.open();
|
||||
doc.write("<body></body>");
|
||||
@ -278,11 +365,11 @@ function cmdShowSurface(id)
|
||||
xOffset = 0;
|
||||
yOffset = 0;
|
||||
} else {
|
||||
var transientToplevel = getTransientToplevel(surface);
|
||||
if (transientToplevel) {
|
||||
doc = transientToplevel.window.document;
|
||||
xOffset = surface.x - transientToplevel.x;
|
||||
yOffset = surface.y - transientToplevel.y;
|
||||
surface.transientToplevel = getTransientToplevel(surface);
|
||||
if (surface.transientToplevel) {
|
||||
doc = surface.transientToplevel.window.document;
|
||||
xOffset = surface.x - surface.transientToplevel.x;
|
||||
yOffset = surface.y - surface.transientToplevel.y;
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,12 +390,13 @@ function cmdHideSurface(id)
|
||||
return;
|
||||
surface.visible = false;
|
||||
|
||||
surfaces[id].canvas.style["display"] = "none";
|
||||
surface.canvas.style["display"] = "none";
|
||||
|
||||
// Import the canvas into the main document
|
||||
ensureSurfaceInDocument(surface, document);
|
||||
|
||||
if (surface.window) {
|
||||
unregisterWindow(surface.window);
|
||||
surface.window.close();
|
||||
surface.window = null;
|
||||
}
|
||||
@ -346,7 +434,7 @@ function cmdMoveSurface(id, x, y)
|
||||
* However this isn't *strictly* invalid, as any WM could have done whatever it
|
||||
* wanted with the positioning of the window.
|
||||
*/
|
||||
surface.window.moveTo(surface.x, surface.y);
|
||||
//surface.window.moveTo(surface.x, surface.y);
|
||||
} else {
|
||||
var xOffset = surface.x;
|
||||
var yOffset = surface.y;
|
||||
@ -373,19 +461,7 @@ function cmdResizeSurface(id, w, h)
|
||||
/* Flush any outstanding draw ops before changing size */
|
||||
flushSurface(surface);
|
||||
|
||||
/* Canvas resize clears the data, so we need to save it first */
|
||||
var tmpCanvas = surface.document.createElement("canvas");
|
||||
tmpCanvas.width = surface.canvas.width;
|
||||
tmpCanvas.height = surface.canvas.height;
|
||||
var tmpContext = tmpCanvas.getContext("2d");
|
||||
tmpContext.globalCompositeOperation = "copy";
|
||||
tmpContext.drawImage(surface.canvas, 0, 0, tmpCanvas.width, tmpCanvas.height);
|
||||
|
||||
surface.canvas.width = w;
|
||||
surface.canvas.height = h;
|
||||
|
||||
surface.context.globalCompositeOperation = "copy";
|
||||
surface.context.drawImage(tmpCanvas, 0, 0, tmpCanvas.width, tmpCanvas.height);
|
||||
resizeCanvas(surface.canvas, w, h);
|
||||
|
||||
if (surface.window) {
|
||||
resizeBrowserWindow(surface.window, w, h);
|
||||
@ -649,6 +725,19 @@ function getEffectiveEventTarget (id) {
|
||||
|
||||
function updateForEvent(ev) {
|
||||
lastTimeStamp = ev.timeStamp;
|
||||
if (ev.target.surface && ev.target.surface.window) {
|
||||
var win = ev.target.surface.window;
|
||||
if (ev.screenX != undefined && ev.clientX != undefined) {
|
||||
var newFrameSizeX = ev.screenX - ev.clientX - win.screenX;
|
||||
var newFrameSizeY = ev.screenY - ev.clientY - win.screenY;
|
||||
if (newFrameSizeX != frameSizeX || newFrameSizeY != frameSizeY) {
|
||||
frameSizeX = newFrameSizeX;
|
||||
frameSizeY = newFrameSizeY;
|
||||
toplevelWindows.forEach(updateBrowserWindowGeometry);
|
||||
}
|
||||
}
|
||||
updateBrowserWindowGeometry(win);
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseMove (ev) {
|
||||
@ -839,4 +928,8 @@ function connect()
|
||||
alert("WebSocket not supported, input will not work!");
|
||||
}
|
||||
setupDocument(document);
|
||||
window.onunload = function (ev) {
|
||||
for (var i = 0; i < toplevelWindows.length; i++)
|
||||
toplevelWindows[i].close();
|
||||
};
|
||||
}
|
||||
|
@ -248,6 +248,19 @@ parse_input_message (BroadwayInput *input, const char *message)
|
||||
msg.grab_reply.res = strtol(p, &p, 10);
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
msg.configure_notify.id = strtol(p, &p, 10);
|
||||
p++; /* Skip , */
|
||||
msg.configure_notify.x = strtol (p, &p, 10);
|
||||
p++; /* Skip , */
|
||||
msg.configure_notify.y = strtol (p, &p, 10);
|
||||
p++; /* Skip , */
|
||||
msg.configure_notify.width = strtol (p, &p, 10);
|
||||
p++; /* Skip , */
|
||||
msg.configure_notify.height = strtol (p, &p, 10);
|
||||
p++; /* Skip , */
|
||||
break;
|
||||
|
||||
default:
|
||||
g_printerr ("Unknown input command %s\n", message);
|
||||
break;
|
||||
|
@ -87,6 +87,15 @@ typedef struct {
|
||||
int res;
|
||||
} BroadwayInputGrabReply;
|
||||
|
||||
typedef struct {
|
||||
BroadwayInputBaseMsg base;
|
||||
int id;
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
} BroadwayInputConfigureNotify;
|
||||
|
||||
typedef union {
|
||||
BroadwayInputBaseMsg base;
|
||||
BroadwayInputPointerMsg pointer;
|
||||
@ -95,6 +104,7 @@ typedef union {
|
||||
BroadwayInputScrollMsg scroll;
|
||||
BroadwayInputKeyMsg key;
|
||||
BroadwayInputGrabReply grab_reply;
|
||||
BroadwayInputConfigureNotify configure_notify;
|
||||
} BroadwayInputMsg;
|
||||
|
||||
struct _GdkBroadwayDisplay
|
||||
|
@ -270,6 +270,30 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
|
||||
case 'u':
|
||||
_gdk_display_device_grab_update (display, display->core_pointer, NULL, message->base.serial);
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->configure_notify.id));
|
||||
if (window)
|
||||
{
|
||||
window->x = message->configure_notify.x;
|
||||
window->y = message->configure_notify.y;
|
||||
window->width = message->configure_notify.width;
|
||||
window->height = message->configure_notify.height;
|
||||
_gdk_window_update_size (window);
|
||||
_gdk_broadway_window_resize_surface (window);
|
||||
|
||||
event = gdk_event_new (GDK_CONFIGURE);
|
||||
event->configure.window = g_object_ref (window);
|
||||
event->configure.x = message->configure_notify.x;
|
||||
event->configure.y = message->configure_notify.y;
|
||||
event->configure.width = message->configure_notify.width;
|
||||
event->configure.height = message->configure_notify.height;
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event, message->base.serial);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_printerr ("Unknown input command %c\n", message->base.type);
|
||||
break;
|
||||
|
@ -207,6 +207,7 @@ gboolean _gdk_broadway_window_simulate_button (GdkWindow *window,
|
||||
guint button,
|
||||
GdkModifierType modifiers,
|
||||
GdkEventType button_pressrelease);
|
||||
void _gdk_broadway_window_resize_surface (GdkWindow *window);
|
||||
|
||||
void _gdk_broadway_cursor_update_theme (GdkCursor *cursor);
|
||||
void _gdk_broadway_cursor_display_finalize (GdkDisplay *display);
|
||||
|
@ -368,8 +368,8 @@ _gdk_broadway_display_create_window_impl (GdkDisplay *display,
|
||||
window->window_type == GDK_WINDOW_TEMP);
|
||||
}
|
||||
|
||||
static void
|
||||
resize_surface (GdkWindow *window)
|
||||
void
|
||||
_gdk_broadway_window_resize_surface (GdkWindow *window)
|
||||
{
|
||||
GdkWindowImplBroadway *impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
|
||||
cairo_surface_t *old, *last_old;
|
||||
@ -396,6 +396,8 @@ resize_surface (GdkWindow *window)
|
||||
NULL, NULL);
|
||||
impl->ref_surface = NULL;
|
||||
}
|
||||
|
||||
gdk_window_invalidate_rect (window, NULL, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -641,8 +643,7 @@ gdk_window_broadway_move_resize (GdkWindow *window,
|
||||
|
||||
window->width = width;
|
||||
window->height = height;
|
||||
resize_surface (window);
|
||||
gdk_window_invalidate_rect (window, NULL, TRUE);
|
||||
_gdk_broadway_window_resize_surface (window);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user