[broadway] Add some initial work for in-window frames

The css is based on work by Jasper St Pierre:
http://magcius.mecheye.net/vista/
This commit is contained in:
Alexander Larsson 2011-04-08 11:45:51 +02:00
parent 69eafcc3c5
commit 618dc872b0
2 changed files with 196 additions and 19 deletions

View File

@ -107,12 +107,13 @@ function resizeCanvas(canvas, w, h)
context.drawImage(tmpCanvas, 0, 0, tmpCanvas.width, tmpCanvas.height);
}
var useToplevelWindows = true;
var useToplevelWindows = false;
var toplevelWindows = [];
var grab = new Object();
grab.window = null;
grab.ownerEvents = false;
grab.implicit = false;
var localGrab = null;
var lastSerial = 0;
var lastX = 0;
var lastY = 0;
@ -126,7 +127,6 @@ var inputSocket = null;
var frameSizeX = -1;
var frameSizeY = -1;
var GDK_CROSSING_NORMAL = 0;
var GDK_CROSSING_GRAB = 1;
var GDK_CROSSING_UNGRAB = 2;
@ -321,6 +321,18 @@ function getTransientToplevel(surface)
return null;
}
function getFrameOffset(surface) {
var x = 1;
var y = 1;
var el = surface.canvas;
while (el != null && el != surface.frame) {
x += el.offsetLeft;
y += el.offsetTop;
el = el.offsetParent;
}
return {x: x, y: y};
}
function cmdCreateSurface(id, x, y, width, height, isTemp)
{
var surface = { id: id, x: x, y:y, width: width, height: height, isTemp: isTemp };
@ -330,18 +342,49 @@ function cmdCreateSurface(id, x, y, width, height, isTemp)
surface.window = null;
surface.document = document;
surface.transientToplevel = null;
surface.frame = null;
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
canvas.surface = surface;
canvas.style["position"] = "absolute";
canvas.style["left"] = "0px";
canvas.style["top"] = "0px";
canvas.style["display"] = "none";
document.body.appendChild(canvas);
surface.canvas = canvas;
if (useToplevelWindows || isTemp) {
canvas.style["position"] = "absolute";
canvas.style["left"] = "0px";
canvas.style["top"] = "0px";
canvas.style["display"] = "none";
document.body.appendChild(canvas);
} else {
var frame = document.createElement("div");
frame.frameFor = surface;
frame.style["position"] = "absolute";
frame.style["left"] = "0px";
frame.style["top"] = "0px";
frame.style["display"] = "inline";
// We hide the frame with visibility rather than display none
// so getFrameOffset still works with hidden windows
frame.style["visibility"] = "hidden";
frame.className = "frame-window";
var button = document.createElement("center");
var X = document.createTextNode("X");
button.appendChild(X);
button.className = "frame-close";
frame.appendChild(button);
var contents = document.createElement("div");
contents.className = "frame-contents";
frame.appendChild(contents);
document.body.appendChild(frame);
contents.appendChild(canvas);
canvas.style["display"] = "block";
surface.frame = frame;
}
var context = canvas.getContext("2d");
context.globalCompositeOperation = "source-over";
surface.context = context;
@ -357,6 +400,7 @@ function cmdShowSurface(id)
return;
surface.visible = true;
var element = surface.canvas;
var xOffset = surface.x;
var yOffset = surface.y;
@ -387,12 +431,21 @@ function cmdShowSurface(id)
}
ensureSurfaceInDocument(surface, doc);
} else {
if (surface.frame) {
element = surface.frame;
var offset = getFrameOffset(surface);
xOffset -= offset.x;
yOffset -= offset.y;
}
}
surface.canvas.style["position"] = "absolute";
surface.canvas.style["left"] = xOffset + "px";
surface.canvas.style["top"] = yOffset + "px";
surface.canvas.style["display"] = "inline";
element.style["position"] = "absolute";
element.style["left"] = xOffset + "px";
element.style["top"] = yOffset + "px";
element.style["display"] = "inline";
if (surface.frame)
surface.frame.style["visibility"] = "visible";
}
function cmdHideSurface(id)
@ -403,7 +456,14 @@ function cmdHideSurface(id)
return;
surface.visible = false;
surface.canvas.style["display"] = "none";
var element = surface.canvas;
if (surface.frame)
element = surface.frame;
if (surface.frame)
surface.frame.style["visibility"] = "hidden";
else
element.style["display"] = "none";
// Import the canvas into the main document
ensureSurfaceInDocument(surface, document);
@ -458,8 +518,16 @@ function cmdMoveSurface(id, x, y)
yOffset = surface.y - transientToplevel.y;
}
surface.canvas.style["left"] = xOffset + "px";
surface.canvas.style["top"] = yOffset + "px";
var element = surface.canvas;
if (surface.frame) {
element = surface.frame;
var offset = getFrameOffset(surface);
xOffset -= offset.x;
yOffset -= offset.y;
}
element.style["left"] = xOffset + "px";
element.style["top"] = yOffset + "px";
}
}
}
@ -748,6 +816,20 @@ function updateForEvent(ev) {
function onMouseMove (ev) {
updateForEvent(ev);
if (localGrab) {
var dx = ev.pageX - localGrab.lastX;
var dy = ev.pageY - localGrab.lastY;
var surface = localGrab.frame.frameFor;
surface.x += dx;
surface.y += dy;
var offset = getFrameOffset(surface);
localGrab.frame.style["left"] = (surface.x - offset.x) + "px";
localGrab.frame.style["top"] = (surface.y - offset.y) + "px";
sendInput ("w", [surface.id, surface.x, surface.y, surface.width, surface.height]);
localGrab.lastX = ev.pageX;
localGrab.lastY = ev.pageY;
return;
}
var id = getSurfaceId(ev);
id = getEffectiveEventTarget (id);
var pos = getPositionsFromEvent(ev, id);
@ -756,6 +838,8 @@ function onMouseMove (ev) {
function onMouseOver (ev) {
updateForEvent(ev);
if (localGrab)
return;
var id = getSurfaceId(ev);
realWindowWithMouse = id;
id = getEffectiveEventTarget (id);
@ -768,6 +852,8 @@ function onMouseOver (ev) {
function onMouseOut (ev) {
updateForEvent(ev);
if (localGrab)
return;
var id = getSurfaceId(ev);
var origId = id;
id = getEffectiveEventTarget (id);
@ -816,23 +902,48 @@ function doUngrab() {
function onMouseDown (ev) {
updateForEvent(ev);
var button = ev.button + 1;
lastState = lastState | getButtonMask (button);
var id = getSurfaceId(ev);
id = getEffectiveEventTarget (id);
if (id == 0 && ev.target.frameFor) { /* mouse click on frame */
localGrab = new Object();
localGrab.frame = ev.target;
localGrab.lastX = ev.pageX;
localGrab.lastY = ev.pageY;
return;
}
var pos = getPositionsFromEvent(ev, id);
if (grab.window == null)
doGrab (id, false, true);
var button = ev.button + 1;
lastState = lastState | getButtonMask (button);
sendInput ("b", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, button]);
}
function onMouseUp (ev) {
updateForEvent(ev);
var id = getSurfaceId(ev);
id = getEffectiveEventTarget (id);
var pos = getPositionsFromEvent(ev, id);
var button = ev.button + 1;
lastState = lastState & ~getButtonMask (button);
var evId = getSurfaceId(ev);
id = getEffectiveEventTarget (evId);
var pos = getPositionsFromEvent(ev, id);
if (localGrab) {
localGrab = null;
realWindowWithMouse = evId;
if (windowWithMouse != id) {
if (windowWithMouse != 0) {
sendInput ("l", [realWindowWithMouse, windowWithMouse, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_NORMAL]);
}
windowWithMouse = id;
if (windowWithMouse != 0) {
sendInput ("e", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, GDK_CROSSING_NORMAL]);
}
}
return;
}
sendInput ("B", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, button]);
if (grab.window != null && grab.implicit)
@ -842,6 +953,8 @@ function onMouseUp (ev) {
var lastKeyDown = 0;
function onKeyDown (ev) {
updateForEvent(ev);
if (localGrab)
return;
var keyCode = ev.keyCode;
if (keyCode != lastKeyDown) {
sendInput ("k", [keyCode]);
@ -851,6 +964,8 @@ function onKeyDown (ev) {
function onKeyUp (ev) {
updateForEvent(ev);
if (localGrab)
return;
var keyCode = ev.keyCode;
sendInput ("K", [keyCode]);
lastKeyDown = 0;
@ -872,6 +987,8 @@ function cancelEvent(ev)
function onMouseWheel(ev)
{
updateForEvent(ev);
if (localGrab)
return;
ev = ev ? ev : window.event;
var id = getSurfaceId(ev);

View File

@ -4,6 +4,66 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<title>broadway 2.0</title>
<script type="text/javascript" src="broadway.js"></script>
<style type="text/css">
.frame-window {
background-color: rgba(179, 230, 255, 0.35);
background-image: -moz-linear-gradient(rgba(250, 253, 255, 0.1) 0px, rgba(250, 253, 255, 0.65) 40px, rgba(250, 253, 255, 0.75) 50px, rgba(250, 253, 255, 0) 54px);
background-image: -webkit-gradient(linear, left top, left 50, from(rgba(250, 253, 255, 0.9)), to(rgba(250, 253, 255, 0)), color-stop(88%, rgba(250, 253, 255, 0.75)));
border-radius: 6px;
-moz-border-radius: 6px;
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.65) inset, 0 0 0 1px rgba(0, 0, 0, 0.75), 0 1px 10px 2px rgba(0, 0, 0, 0.65);
-webkit-box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.65) inset, 0 0 0 1px rgba(0, 0, 0, 0.75), 0 1px 10px 2px rgba(0, 0, 0, 0.65);
padding: 0 7px 7px 7px;
}
.frame-contents {
border-radius: 3px;
-moz-border-radius: 3px;
border: 1px solid rgba(255, 255, 255, 0.4);
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.9) inset;
-webkit-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.9) inset;
clear: both;
padding: 1px;
position: relative;
}
.frame-close {
margin: 0 2px 3px 2px;
background-color: #CC3333;
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.35) 0%, rgba(255, 255, 255, 0.5) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0.5) 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.35)), to(rgba(255, 255, 255, 0.5)), color-stop(50%, rgba(255, 255, 255, 0.5)), color-stop(50%, rgba(255, 255, 255, 0)));
border-radius: 2px;
border-top-left-radius: 0;
border-top-right-radius: 0;
-moz-border-radius: 2px;
-moz-border-top-left-radius: 0;
-moz-border-top-right-radius: 0;
border: 1px solid #550000;
border-top: none;
float: right;
color: white;
width: 36px;
text-shadow: black -1px 0 0, black 1px 0 0, black 0 1px 0, black 0 -1px 0;
box-shadow: 0 0 2px 1px rgba(255, 255, 255, 0.5) inset;
-webkit-box-shadow: 0 0 2px 1px rgba(255, 255, 255, 0.5) inset;
font-weight: bold;
cursor: pointer;
}
.frame-close:focus {
left: 0;
}
.frame-close:hover {
background-color: #EE4A4A;
}
.frame-close:active {
background-color: #AA2020;
}
</style>
</head>
<body onload="connect()">