diff --git a/mozilla/toolkit/components/alerts/resources/content/alert.js b/mozilla/toolkit/components/alerts/resources/content/alert.js
index b0db1d20b86..5aa42c8c5d0 100644
--- a/mozilla/toolkit/components/alerts/resources/content/alert.js
+++ b/mozilla/toolkit/components/alerts/resources/content/alert.js
@@ -36,10 +36,18 @@
*
* ***** END LICENSE BLOCK ***** */
-var gFinalHeight = 50;
+// Copied from nsILookAndFeel.h, see comments on eMetric_AlertNotificationOrigin
+const NS_ALERT_HORIZONTAL = 1;
+const NS_ALERT_LEFT = 2;
+const NS_ALERT_TOP = 4;
+
+var gFinalSize;
+var gCurrentSize = 1;
+
var gSlideIncrement = 1;
var gSlideTime = 10;
var gOpenTime = 3000; // total time the alert should stay up once we are done animating.
+var gOrigin = 0; // Default value: alert from bottom right, sliding in vertically.
var gAlertListener = null;
var gAlertTextClickable = false;
@@ -53,24 +61,36 @@ function prefillAlertInfo()
// arguments[2] --> the alert text
// arguments[3] --> is the text clickable?
// arguments[4] --> the alert cookie to be passed back to the listener
- // arguments[5] --> an optional callback listener (nsIObserver)
+ // arguments[5] --> the alert origin reported by the look and feel
+ // arguments[6] --> an optional callback listener (nsIObserver)
- document.getElementById('alertImage').setAttribute('src', window.arguments[0]);
- document.getElementById('alertTitleLabel').setAttribute('value', window.arguments[1]);
- document.getElementById('alertTextLabel').setAttribute('value', window.arguments[2]);
- gAlertTextClickable = window.arguments[3];
- gAlertCookie = window.arguments[4];
-
- if (gAlertTextClickable)
- document.getElementById('alertTextLabel').setAttribute('clickable', true);
-
- // the 5th argument is optional
- gAlertListener = window.arguments[5];
+ switch (window.arguments.length)
+ {
+ default:
+ case 7:
+ gAlertListener = window.arguments[6];
+ case 6:
+ gOrigin = window.arguments[5];
+ case 5:
+ gAlertCookie = window.arguments[4];
+ case 4:
+ gAlertTextClickable = window.arguments[3];
+ if (gAlertTextClickable)
+ document.getElementById('alertTextLabel').setAttribute('clickable', true);
+ case 3:
+ document.getElementById('alertTextLabel').setAttribute('value', window.arguments[2]);
+ case 2:
+ document.getElementById('alertTitleLabel').setAttribute('value', window.arguments[1]);
+ case 1:
+ document.getElementById('alertImage').setAttribute('src', window.arguments[0]);
+ case 0:
+ break;
+ }
}
function onAlertLoad()
{
- // read out our initial settings from prefs.
+ // Read out our initial settings from prefs.
try
{
var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService();
@@ -79,32 +99,102 @@ function onAlertLoad()
gSlideIncrement = prefBranch.getIntPref("alerts.slideIncrement");
gSlideTime = prefBranch.getIntPref("alerts.slideIncrementTime");
gOpenTime = prefBranch.getIntPref("alerts.totalOpenTime");
- } catch (ex) {}
+ }
+ catch (ex)
+ {
+ }
+
+ // Make sure that the contents are fixed at the window edge facing the
+ // screen's center so that the window looks like "sliding in" and not
+ // like "unfolding". The default packing of "start" only works for
+ // vertical-bottom and horizontal-right positions, so we change it here.
+ if (gOrigin & NS_ALERT_HORIZONTAL)
+ {
+ if (gOrigin & NS_ALERT_LEFT)
+ document.documentElement.pack = "end";
+
+ // Additionally, change the orientation so the packing works as intended
+ document.documentElement.orient = "horizontal";
+ }
+ else
+ {
+ if (gOrigin & NS_ALERT_TOP)
+ document.documentElement.pack = "end";
+ }
+
+ var alertBox = document.getElementById("alertBox");
+ alertBox.orient = (gOrigin & NS_ALERT_HORIZONTAL) ? "vertical" : "horizontal";
+
+ // The above doesn't cause the labels in alertTextBox to reflow,
+ // see bug 311557. As the theme's -moz-box-align css rule gets ignored,
+ // we work around the bug by setting the align property.
+ if (gOrigin & NS_ALERT_HORIZONTAL)
+ {
+ document.getElementById("alertTextBox").align = "center";
+ }
sizeToContent();
- // work around a bug where sizeToContent() leaves a border outside of the content
+ // Work around a bug where sizeToContent() leaves a border outside of the content
var contentDim = document.getElementById("alertBox").boxObject;
if (window.innerWidth == contentDim.width + 1)
--window.innerWidth;
- gFinalHeight = window.outerHeight;
+ // Start with a 1px width/height, because 0 causes trouble with gtk1/2
+ gCurrentSize = 1;
- // start with a 1px height, because 0 causes trouble with gtk1/2
- window.outerHeight = 1;
+ // Determine final size
+ if (gOrigin & NS_ALERT_HORIZONTAL)
+ {
+ gFinalSize = window.outerWidth;
+ window.outerWidth = gCurrentSize;
+ }
+ else
+ {
+ gFinalSize = window.outerHeight;
+ window.outerHeight = gCurrentSize;
+ }
- // be sure to offset the alert by 10 pixels from the far right edge of the screen
- window.moveTo( (screen.availLeft + screen.availWidth - window.outerWidth) - 10, screen.availTop + screen.availHeight - window.outerHeight);
+ // Determine position
+ var x = gOrigin & NS_ALERT_LEFT ? screen.availLeft :
+ screen.availLeft + screen.availWidth - window.outerWidth;
+ var y = gOrigin & NS_ALERT_TOP ? screen.availTop :
+ screen.availTop + screen.availHeight - window.outerHeight;
+
+ // Offset the alert by 10 pixels from the edge of the screen
+ if (gOrigin & NS_ALERT_HORIZONTAL)
+ y += gOrigin & NS_ALERT_TOP ? 10 : -10;
+ else
+ x += gOrigin & NS_ALERT_LEFT ? 10 : -10;
+
+ window.moveTo(x, y);
setTimeout(animateAlert, gSlideTime);
}
+function animate(step)
+{
+ gCurrentSize += step;
+
+ if (gOrigin & NS_ALERT_HORIZONTAL)
+ {
+ if (!(gOrigin & NS_ALERT_LEFT))
+ window.screenX -= step;
+ window.outerWidth = gCurrentSize;
+ }
+ else
+ {
+ if (!(gOrigin & NS_ALERT_TOP))
+ window.screenY -= step;
+ window.outerHeight = gCurrentSize;
+ }
+}
+
function animateAlert()
{
- if (window.outerHeight < gFinalHeight)
+ if (gCurrentSize < gFinalSize)
{
- window.screenY -= gSlideIncrement;
- window.outerHeight += gSlideIncrement;
+ animate(gSlideIncrement);
setTimeout(animateAlert, gSlideTime);
}
else
@@ -113,10 +203,9 @@ function animateAlert()
function closeAlert()
{
- if (window.outerHeight > 1)
+ if (gCurrentSize > 1)
{
- window.screenY += gSlideIncrement;
- window.outerHeight -= gSlideIncrement;
+ animate(-gSlideIncrement);
setTimeout(closeAlert, gSlideTime);
}
else
diff --git a/mozilla/toolkit/components/alerts/resources/content/alert.xul b/mozilla/toolkit/components/alerts/resources/content/alert.xul
index 57783da070a..65004e1df59 100644
--- a/mozilla/toolkit/components/alerts/resources/content/alert.xul
+++ b/mozilla/toolkit/components/alerts/resources/content/alert.xul
@@ -44,14 +44,14 @@
xmlns:xhtml2="http://www.w3.org/TR/xhtml2"
xmlns:wairole="http://www.w3.org/2005/01/wai-rdf/GUIRoleTaxonomy#"
xhtml2:role="wairole:alert"
- align="start"
+ pack="start"
onload="onAlertLoad()">
-
+
-
+
@@ -60,7 +60,7 @@
-
+
diff --git a/mozilla/toolkit/components/alerts/src/Makefile.in b/mozilla/toolkit/components/alerts/src/Makefile.in
index 1fc07d263b8..85344b4905c 100644
--- a/mozilla/toolkit/components/alerts/src/Makefile.in
+++ b/mozilla/toolkit/components/alerts/src/Makefile.in
@@ -52,6 +52,8 @@ REQUIRES = xpcom \
string \
windowwatcher \
dom \
+ widget \
+ gfx \
$(NULL)
CPPSRCS = \
diff --git a/mozilla/toolkit/components/alerts/src/nsAlertsService.cpp b/mozilla/toolkit/components/alerts/src/nsAlertsService.cpp
index 36eccd0744b..d5e2aedcbc0 100644
--- a/mozilla/toolkit/components/alerts/src/nsAlertsService.cpp
+++ b/mozilla/toolkit/components/alerts/src/nsAlertsService.cpp
@@ -21,6 +21,7 @@
*
* Contributor(s):
* Scott MacGregor
+ * Jens Bannmann
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -44,6 +45,10 @@
#include "nsIDOMWindowInternal.h"
#include "nsIWindowWatcher.h"
#include "nsDependentString.h"
+#include "nsWidgetsCID.h"
+#include "nsILookAndFeel.h"
+
+static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
#define ALERT_CHROME_URL "chrome://global/content/alerts/alert.xul"
@@ -80,31 +85,49 @@ NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl
NS_ENSURE_TRUE(scriptableImageUrl, NS_ERROR_FAILURE);
scriptableImageUrl->SetData(aImageUrl);
- argsArray->AppendElement(scriptableImageUrl);
+ rv = argsArray->AppendElement(scriptableImageUrl);
+ NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr scriptableAlertTitle (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableAlertTitle, NS_ERROR_FAILURE);
scriptableAlertTitle->SetData(aAlertTitle);
- argsArray->AppendElement(scriptableAlertTitle);
+ rv = argsArray->AppendElement(scriptableAlertTitle);
+ NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr scriptableAlertText (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableAlertText, NS_ERROR_FAILURE);
scriptableAlertText->SetData(aAlertText);
- argsArray->AppendElement(scriptableAlertText);
+ rv = argsArray->AppendElement(scriptableAlertText);
+ NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr scriptableIsClickable (do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID));
NS_ENSURE_TRUE(scriptableIsClickable, NS_ERROR_FAILURE);
scriptableIsClickable->SetData(aAlertTextClickable);
- argsArray->AppendElement(scriptableIsClickable);
+ rv = argsArray->AppendElement(scriptableIsClickable);
+ NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr scriptableAlertCookie (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableAlertCookie, NS_ERROR_FAILURE);
scriptableAlertCookie->SetData(aAlertCookie);
- argsArray->AppendElement(scriptableAlertCookie);
+ rv = argsArray->AppendElement(scriptableAlertCookie);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr scriptableOrigin (do_CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID));
+ NS_ENSURE_TRUE(scriptableOrigin, NS_ERROR_FAILURE);
+ nsCOMPtr lookAndFeel = do_GetService("@mozilla.org/widget/lookandfeel;1");
+ if (lookAndFeel)
+ {
+ PRInt32 origin;
+ lookAndFeel->GetMetric(nsILookAndFeel::eMetric_AlertNotificationOrigin,
+ origin);
+ scriptableOrigin->SetData(origin);
+ }
+ rv = argsArray->AppendElement(scriptableOrigin);
+ NS_ENSURE_SUCCESS(rv, rv);
if (aAlertListener)
{
@@ -114,9 +137,10 @@ NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl
nsCOMPtr iSupports (do_QueryInterface(aAlertListener));
ifptr->SetData(iSupports);
ifptr->SetDataIID(&NS_GET_IID(nsIObserver));
- argsArray->AppendElement(ifptr);
+ rv = argsArray->AppendElement(ifptr);
+ NS_ENSURE_SUCCESS(rv, rv);
}
-
+
rv = wwatch->OpenWindow(0, ALERT_CHROME_URL, "_blank",
"chrome,dialog=yes,titlebar=no,popup=yes", argsArray,
getter_AddRefs(newWindow));
diff --git a/mozilla/toolkit/themes/winstripe/global/alerts/alert.css b/mozilla/toolkit/themes/winstripe/global/alerts/alert.css
index a1aa54e6112..1487d426c28 100644
--- a/mozilla/toolkit/themes/winstripe/global/alerts/alert.css
+++ b/mozilla/toolkit/themes/winstripe/global/alerts/alert.css
@@ -52,12 +52,18 @@
min-height: 50px;
}
-.alertImageBox {
+.alertBox[orient="horizontal"] > .alertImageBox {
-moz-margin-start: 4px;
-moz-margin-end: 6px;
min-height: 46px;
}
+.alertBox[orient="vertical"] > .alertImageBox {
+ margin-top: 6px;
+ margin-bottom: 4px;
+ min-width: 46px;
+}
+
.alertTitle {
font-weight: bold;
}
@@ -76,9 +82,14 @@
color: #424F63;
}
-.alertTextBox
-{
+.alertBox[orient="horizontal"] > .alertTextBox {
-moz-padding-end: 10px;
padding-top: 5px;
}
+.alertBox[orient="vertical"] > .alertTextBox {
+ -moz-padding-start: 5px;
+ -moz-padding-end: 5px;
+ margin-bottom: 8px;
+ -moz-box-align: center; /* also hard-coded in alert.js, see bug 311557 */
+}
diff --git a/mozilla/widget/public/nsILookAndFeel.h b/mozilla/widget/public/nsILookAndFeel.h
index dc25a4c4d5e..2eeeec59f53 100644
--- a/mozilla/widget/public/nsILookAndFeel.h
+++ b/mozilla/widget/public/nsILookAndFeel.h
@@ -189,7 +189,24 @@ public:
eMetric_TreeLazyScrollDelay, // delay for triggering the tree scrolling
eMetric_TreeScrollDelay, // delay for scrolling the tree
eMetric_TreeScrollLinesMax, // the maximum number of lines to be scrolled at ones
- eMetric_TabFocusModel // What type of tab-order to use
+ eMetric_TabFocusModel, // What type of tab-order to use
+
+ /*
+ * eMetric_AlertNotificationOrigin indicates from which corner of the
+ * screen alerts slide in, and from which direction (horizontal/vertical).
+ * 0, the default, represents bottom right, sliding vertically.
+ * Use any bitwise combination of the following constants:
+ * NS_ALERT_HORIZONTAL (1), NS_ALERT_LEFT (2), NS_ALERT_TOP (4).
+ *
+ * 6 4
+ * +-----------+
+ * 7| |5
+ * | |
+ * 3| |1
+ * +-----------+
+ * 2 0
+ */
+ eMetric_AlertNotificationOrigin
} nsMetricID;
enum {
@@ -257,4 +274,12 @@ public:
#define NS_DONT_CHANGE_COLOR NS_RGB(0x01, 0x01, 0x01)
+// ------------------------------------------
+// Bits for eMetric_AlertNotificationOrigin
+// ------------------------------------------
+
+#define NS_ALERT_HORIZONTAL 1
+#define NS_ALERT_LEFT 2
+#define NS_ALERT_TOP 4
+
#endif /* __nsILookAndFeel */
diff --git a/mozilla/widget/src/windows/nsLookAndFeel.cpp b/mozilla/widget/src/windows/nsLookAndFeel.cpp
index cb4146df518..c04a9008f12 100644
--- a/mozilla/widget/src/windows/nsLookAndFeel.cpp
+++ b/mozilla/widget/src/windows/nsLookAndFeel.cpp
@@ -21,6 +21,7 @@
*
* Contributor(s):
* Michael Lowe
+ * Jens Bannmann
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -39,14 +40,37 @@
#include "nsLookAndFeel.h"
#include "nsXPLookAndFeel.h"
#include
+#include
#include "nsWindow.h"
+#ifndef WINCE
+typedef UINT (CALLBACK *SHAppBarMessagePtr)(DWORD, PAPPBARDATA);
+SHAppBarMessagePtr gSHAppBarMessage = NULL;
+static HINSTANCE gShell32DLLInst = NULL;
+#endif
+
nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel()
{
+#ifndef WINCE
+ gShell32DLLInst = LoadLibrary("Shell32.dll");
+ if (gShell32DLLInst)
+ {
+ gSHAppBarMessage = (SHAppBarMessagePtr) GetProcAddress(gShell32DLLInst,
+ "SHAppBarMessage");
+ }
+#endif
}
nsLookAndFeel::~nsLookAndFeel()
{
+#ifndef WINCE
+ if (gShell32DLLInst)
+ {
+ FreeLibrary(gShell32DLLInst);
+ gShell32DLLInst = NULL;
+ gSHAppBarMessage = NULL;
+ }
+#endif
}
nsresult nsLookAndFeel::NativeGetColor(const nsColorID aID, nscolor &aColor)
@@ -419,6 +443,43 @@ NS_IMETHODIMP nsLookAndFeel::GetMetric(const nsMetricID aID, PRInt32 & aMetric)
case eMetric_TreeScrollLinesMax:
aMetric = 3;
break;
+#ifndef WINCE
+ case eMetric_AlertNotificationOrigin:
+ aMetric = 0;
+ if (gSHAppBarMessage)
+ {
+ // Get task bar window handle
+ HWND shellWindow = FindWindow("Shell_TrayWnd", NULL);
+
+ if (shellWindow != NULL)
+ {
+ // Determine position
+ APPBARDATA appBarData;
+ appBarData.hWnd = shellWindow;
+ appBarData.cbSize = sizeof(appBarData);
+ if (gSHAppBarMessage(ABM_GETTASKBARPOS, &appBarData))
+ {
+ // Set alert origin as a bit field - see nsILookAndFeel.h
+ // 0 represents bottom right, sliding vertically.
+ switch(appBarData.uEdge)
+ {
+ case ABE_LEFT:
+ aMetric = NS_ALERT_HORIZONTAL | NS_ALERT_LEFT;
+ break;
+ case ABE_RIGHT:
+ aMetric = NS_ALERT_HORIZONTAL;
+ break;
+ case ABE_TOP:
+ aMetric = NS_ALERT_TOP;
+ break;
+ case ABE_BOTTOM:
+ break;
+ }
+ }
+ }
+ }
+ break;
+#endif
default:
aMetric = 0;
diff --git a/mozilla/widget/src/xpwidgets/nsXPLookAndFeel.cpp b/mozilla/widget/src/xpwidgets/nsXPLookAndFeel.cpp
index 72bb602351c..01c749d4c18 100644
--- a/mozilla/widget/src/xpwidgets/nsXPLookAndFeel.cpp
+++ b/mozilla/widget/src/xpwidgets/nsXPLookAndFeel.cpp
@@ -107,6 +107,8 @@ nsLookAndFeelIntPref nsXPLookAndFeel::sIntPrefs[] =
eMetric_TreeScrollLinesMax, PR_FALSE, nsLookAndFeelTypeInt, 0 },
{ "accessibility.tabfocus",
eMetric_TabFocusModel, PR_FALSE, nsLookAndFeelTypeInt, 0 },
+ { "ui.alertNotificationOrigin",
+ eMetric_AlertNotificationOrigin, PR_FALSE, nsLookAndFeelTypeInt, 0 },
};
nsLookAndFeelFloatPref nsXPLookAndFeel::sFloatPrefs[] =