[gtk+] [broadway] Add configure event for browser-side geometry changes
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] [broadway] Add configure event for browser-side geometry changes
- Date: Thu, 7 Apr 2011 19:20:41 +0000 (UTC)
commit adc05ae6b7e369d31a052e373b1f08a1928a86bc
Author: Alexander Larsson <alexl redhat com>
Date: Wed Apr 6 16:39:07 2011 +0200
[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.
gdk/broadway/broadway.js | 133 ++++++++++++++++++++++++++++++------
gdk/broadway/gdkdisplay-broadway.c | 13 ++++
gdk/broadway/gdkdisplay-broadway.h | 10 +++
gdk/broadway/gdkeventsource.c | 24 +++++++
gdk/broadway/gdkprivate-broadway.h | 1 +
gdk/broadway/gdkwindow-broadway.c | 9 ++-
6 files changed, 166 insertions(+), 24 deletions(-)
---
diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js
index 8f3e57d..94d9b2e 100644
--- a/gdk/broadway/broadway.js
+++ b/gdk/broadway/broadway.js
@@ -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();
+ };
}
diff --git a/gdk/broadway/gdkdisplay-broadway.c b/gdk/broadway/gdkdisplay-broadway.c
index ae2d964..3ed9a79 100644
--- a/gdk/broadway/gdkdisplay-broadway.c
+++ b/gdk/broadway/gdkdisplay-broadway.c
@@ -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;
diff --git a/gdk/broadway/gdkdisplay-broadway.h b/gdk/broadway/gdkdisplay-broadway.h
index b791579..3e9be85 100644
--- a/gdk/broadway/gdkdisplay-broadway.h
+++ b/gdk/broadway/gdkdisplay-broadway.h
@@ -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
diff --git a/gdk/broadway/gdkeventsource.c b/gdk/broadway/gdkeventsource.c
index c94eb09..a6e47c9 100644
--- a/gdk/broadway/gdkeventsource.c
+++ b/gdk/broadway/gdkeventsource.c
@@ -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;
diff --git a/gdk/broadway/gdkprivate-broadway.h b/gdk/broadway/gdkprivate-broadway.h
index b33dd9c..517977b 100644
--- a/gdk/broadway/gdkprivate-broadway.h
+++ b/gdk/broadway/gdkprivate-broadway.h
@@ -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);
diff --git a/gdk/broadway/gdkwindow-broadway.c b/gdk/broadway/gdkwindow-broadway.c
index 4fd138f..5b67ea9 100644
--- a/gdk/broadway/gdkwindow-broadway.c
+++ b/gdk/broadway/gdkwindow-broadway.c
@@ -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);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]