summaryrefslogtreecommitdiff
path: root/chrome
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2014-02-23 18:32:00 +0100
committerJavier <dev.git@javispedro.com>2014-02-23 18:32:00 +0100
commit1fbcb3f7bf7ddf955193d798837ab88cf2815112 (patch)
tree5c8d4f8c07e61a6ee72a00a2a47e6365f5689b38 /chrome
parentb0f4f142bf7abdcc1a8b9437911b6794a3cb09d2 (diff)
downloadtopmenu-mozilla-1fbcb3f7bf7ddf955193d798837ab88cf2815112.tar.gz
topmenu-mozilla-1fbcb3f7bf7ddf955193d798837ab88cf2815112.zip
convert into a restartless extension
Diffstat (limited to 'chrome')
-rw-r--r--chrome/content/gdk.js20
-rw-r--r--chrome/content/overlay.js52
-rw-r--r--chrome/content/overlay.xul4
-rw-r--r--chrome/content/topmenu-client.js2
-rw-r--r--chrome/content/topmenuservice.js98
-rw-r--r--chrome/content/vkgdkmap.js17
6 files changed, 86 insertions, 107 deletions
diff --git a/chrome/content/gdk.js b/chrome/content/gdk.js
index 25458ef..d70dfc3 100644
--- a/chrome/content/gdk.js
+++ b/chrome/content/gdk.js
@@ -32,6 +32,16 @@ function defines(lib) {
this.GDK_KEY_Return = 0xff0d;
this.GDK_KEY_Escape = 0xff1b;
this.GDK_KEY_Delete = 0xffff;
+ this.GDK_KEY_Home = 0xff50;
+ this.GDK_KEY_Left = 0xff51;
+ this.GDK_KEY_Up = 0xff52;
+ this.GDK_KEY_Right = 0xff53;
+ this.GDK_KEY_Down = 0xff54;
+ this.GDK_KEY_Prior = 0xff55;
+ this.GDK_KEY_Page_Up = 0xff55;
+ this.GDK_KEY_Next = 0xff56;
+ this.GDK_KEY_Page_Down = 0xff56;
+ this.GDK_KEY_End = 0xff57;
this.GDK_KEY_F1 = 0xffbe;
this.GDK_KEY_F2 = 0xffbf;
this.GDK_KEY_F3 = 0xffc0;
@@ -45,16 +55,6 @@ function defines(lib) {
this.GDK_KEY_F11 = 0xffc8;
this.GDK_KEY_L1 = 0xffc8;
this.GDK_KEY_F12 = 0xffc9;
- this.GDK_KEY_Home = 0xff50;
- this.GDK_KEY_Left = 0xff51;
- this.GDK_KEY_Up = 0xff52;
- this.GDK_KEY_Right = 0xff53;
- this.GDK_KEY_Down = 0xff54;
- this.GDK_KEY_Prior = 0xff55;
- this.GDK_KEY_Page_Up = 0xff55;
- this.GDK_KEY_Next = 0xff56;
- this.GDK_KEY_Page_Down = 0xff56;
- this.GDK_KEY_End = 0xff57;
lib.lazy_bind("gdk_window_get_toplevel", this.GdkWindow.ptr, this.GdkWindow.ptr);
diff --git a/chrome/content/overlay.js b/chrome/content/overlay.js
deleted file mode 100644
index 29b9a07..0000000
--- a/chrome/content/overlay.js
+++ /dev/null
@@ -1,52 +0,0 @@
-"use strict";
-
-var topmenu = {
- logger : null,
- proxy : null,
-
- setupLogging: function() {
- Components.utils.import("chrome://topmenu/content/log4moz.js", topmenu);
- var Log4Moz = this.Log4Moz;
- var formatter = new Log4Moz.BasicFormatter();
- var root = Log4Moz.repository.rootLogger;
- root.level = Log4Moz.Level.Warn;
-
- var capp = new Log4Moz.ConsoleAppender(formatter);
- capp.level = Log4Moz.Level.Warn;
- root.addAppender(capp);
-
- /*
- var dapp = new Log4Moz.DumpAppender(formatter);
- dapp.level = Log4Moz.Level.Debug;
- root.addAppender(dapp);
- */
-
- this.logger = Log4Moz.repository.getLogger("topmenu");
- },
-
- setupMenuProxy: function() {
- Components.utils.import("chrome://topmenu/content/topmenuservice.js", topmenu);
- this.proxy = topmenu.TopMenuService.createWindowProxy(window);
- },
-
- dispose: function() {
- if (this.proxy) {
- this.proxy.dispose();
- this.proxy = null;
- }
- },
-
- onLoad: function() {
- window.removeEventListener('load', topmenu.onLoad);
- window.addEventListener('unload', topmenu.onUnload);
- topmenu.setupLogging();
- topmenu.setupMenuProxy();
- },
-
- onUnload: function() {
- window.removeEventListener('unload', topmenu.onUnload);
- topmenu.dispose();
- },
-}
-
-window.addEventListener('load', topmenu.onLoad);
diff --git a/chrome/content/overlay.xul b/chrome/content/overlay.xul
deleted file mode 100644
index 3e61323..0000000
--- a/chrome/content/overlay.xul
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<overlay id="topmenu-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <script type="application/x-javascript" src="chrome://topmenu/content/overlay.js"></script>
-</overlay>
diff --git a/chrome/content/topmenu-client.js b/chrome/content/topmenu-client.js
index a5d7ab2..af8b1d2 100644
--- a/chrome/content/topmenu-client.js
+++ b/chrome/content/topmenu-client.js
@@ -1,3 +1,5 @@
+"use strict";
+
var EXPORTED_SYMBOLS = [ "topmenu_client" ];
const Cu = Components.utils;
diff --git a/chrome/content/topmenuservice.js b/chrome/content/topmenuservice.js
index 494ea3e..96d0e6c 100644
--- a/chrome/content/topmenuservice.js
+++ b/chrome/content/topmenuservice.js
@@ -1,3 +1,5 @@
+"use strict";
+
var EXPORTED_SYMBOLS = ["TopMenuService"];
var Cu = Components.utils;
@@ -42,13 +44,23 @@ function getTopLevelGdkWindow(w) {
function createMutationObserver(window, proxy)
{
return new window.MutationObserver(function(mutations) {
- mutations.forEach(function(mutation) {
- proxy.handleMutation(mutation);
- });
+ try {
+ mutations.forEach(function(mutation) {
+ proxy.handleMutation(mutation);
+ });
+ } catch (ex) {
+ log.warn("Exception processing menubar changes: " + ex);
+ }
});
}
function WindowProxy(window) {
+ var menubars = window.document.getElementsByTagNameNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', 'menubar');
+ if (menubars.length === 0) {
+ // No menubars, give up constructing the object
+ return;
+ }
+
this.srcWindow = window;
this.srcMenuBar = null;
this.observer = null;
@@ -106,6 +118,7 @@ function WindowProxy(window) {
}
}
+ // Initialize the Gtk widgets for this window
this.accelGroup = gobject.ref_sink(gtk.gtk_accel_group_new());
this.appMenuBar = gobject.ref_sink(topmenu_client.topmenu_app_menu_bar_new());
@@ -113,48 +126,57 @@ function WindowProxy(window) {
topmenu_client.topmenu_client_connect_window_widget(this.gdkWindow, this.appMenuBar);
- var menubars = window.document.getElementsByTagNameNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', 'menubar');
- if (menubars.length > 0) {
- this.srcMenuBar = menubars[0];
- this.observer = createMutationObserver(window, this);
- this.observer.observe(this.srcMenuBar, {
- childList: true,
- attributes: true,
- subtree: true
- });
-
- // Let's find currently added menu items and proxy them
- this.srcMenuBar.topmenuData = {
- gtkMenu: this.appMenuBar
- }
+ // Connect to the first available menu bar
+ this.srcMenuBar = menubars[0];
+ this.observer = createMutationObserver(window, this);
+ this.observer.observe(this.srcMenuBar, {
+ childList: true,
+ attributes: true,
+ subtree: true
+ });
- for (var item = this.srcMenuBar.firstChild; item; item = item.nextSibling) {
- this.addItem(item, this.srcMenuBar, -1);
- }
+ // Let's find currently added menu items and proxy them
+ this.srcMenuBar.topmenuData = {
+ gtkMenu: this.appMenuBar
+ }
- this.appMenu = this.buildAppMenu();
- if (this.appMenu) {
- topmenu_client.topmenu_app_menu_bar_set_app_menu(this.appMenuBar, this.appMenu);
- }
+ for (var item = this.srcMenuBar.firstChild; item; item = item.nextSibling) {
+ this.addItem(item, this.srcMenuBar, -1);
+ }
- window.document.addEventListener("keypress", this.callbacks.keypress);
+ this.appMenu = this.buildAppMenu();
+ if (this.appMenu) {
+ topmenu_client.topmenu_app_menu_bar_set_app_menu(this.appMenuBar, this.appMenu);
}
+ window.document.addEventListener("keypress", this.callbacks.keypress);
+
+ // Connect to the appmenu monitor
this.monitor = topmenu_client.topmenu_monitor_get_instance();
this.monitorConnectionId = gobject.signal_connect(this.monitor, "notify::available",
this.callbacks.monitor_available, null);
+
+ // This will hide the source menu bar if everything's OK.
this.updateMenuBarVisibility();
}
-WindowProxy.prototype.updateMenuBarVisibility = function() {
- var topmenuAvailable = topmenu_client.topmenu_monitor_is_topmenu_available(this.monitor);
+WindowProxy.prototype.setMenuBarVisibility = function(visible) {
if (this.srcMenuBar) {
- this.srcMenuBar.parentNode.parentNode.hidden = topmenuAvailable;
+ this.srcMenuBar.hidden = !visible;
+ // A hack for windows containing the menubar in a toolbar.
+ var toolbar = this.srcMenuBar.parentNode.parentNode;
+ if (toolbar && toolbar.tagName === 'toolbar') {
+ toolbar.hidden = !visible;
+ }
}
}
-WindowProxy.prototype.buildAppMenuItem = function(itemId, stockId)
-{
+WindowProxy.prototype.updateMenuBarVisibility = function() {
+ var topmenuAvailable = topmenu_client.topmenu_monitor_is_topmenu_available(this.monitor);
+ this.setMenuBarVisibility(!topmenuAvailable);
+}
+
+WindowProxy.prototype.buildAppMenuItem = function(itemId, stockId) {
var item = this.srcWindow.document.getElementById(itemId);
if (item) {
@@ -377,7 +399,7 @@ WindowProxy.prototype.addAccelerator = function(gtkItem, item) {
if (keyItemMods) {
keyItemMods = keyItemMods.split(/[\s,]+/);
- for (i in keyItemMods) {
+ for (var i in keyItemMods) {
var mod = keyItemMods[i];
if (mod === "accel") {
/* Read platform default accelerator key from prefs */
@@ -496,9 +518,12 @@ WindowProxy.prototype.addItem = function(item, menu, position) {
try {
this.addAccelerator(gtkItem, item);
} catch (ex) {
- log.warn(ex);
+ log.warn("Exception during accelerator computation: " + ex);
}
}
+ } else if (item.tagName === "spacer") {
+ // Nothing to do
+ return;
} else {
log.warn("Unknown tagName: " + item.tagName);
return;
@@ -624,7 +649,7 @@ WindowProxy.prototype.updateItem = function(item, changedAttr) {
}
WindowProxy.prototype.updateMenu = function(menu, prevItem, removedItems, addedItems) {
- var position, i, node;
+ var position, i;
var popup = menu.firstChild;
if (removedItems.length > 0) {
@@ -637,7 +662,7 @@ WindowProxy.prototype.updateMenu = function(menu, prevItem, removedItems, addedI
if (prevItem) {
position = -1;
i = 2;
- for (node = popup.firstChild; node; node = node.nextSibling, i++) {
+ for (var node = popup.firstChild; node; node = node.nextSibling, i++) {
if (node === prevItem) {
position = i;
break;
@@ -753,6 +778,11 @@ WindowProxy.prototype.fakeCommandEvent = function(item) {
item.dispatchEvent(commandEvent);
}
+WindowProxy.prototype.unload = function() {
+ this.setMenuBarVisibility(true);
+ topmenu_client.topmenu_client_disconnect_window(this.gdkWindow);
+}
+
WindowProxy.prototype.dispose = function() {
window.document.removeEventListener("keypress", this.callbacks.keypress);
if (this.monitor) {
diff --git a/chrome/content/vkgdkmap.js b/chrome/content/vkgdkmap.js
index 35a8fc5..088a212 100644
--- a/chrome/content/vkgdkmap.js
+++ b/chrome/content/vkgdkmap.js
@@ -1,13 +1,20 @@
+"use strict";
+
var EXPORTED_SYMBOLS = [ "vkgdkmap" ];
const Cu = Components.utils;
Cu.import("chrome://topmenu/content/gdk.js");
-/* Hardcoding DOM_VK_* constants, how ugly. */
-/* But how to get a window scope from here? Need to access KeyEvent. */
+var vkgdkmap = {
+ VK_TAB : gdk.GDK_KEY_Tab,
+ VK_RETURN : gdk.GDK_KEY_Return,
+
+ VK_HOME : gdk.GDK_KEY_Home,
+ VK_END : gdk.GDK_KEY_End,
+
+ VK_DELETE : gdk.GDK_KEY_Delete,
-vkgdkmap = {
VK_F1 : gdk.GDK_KEY_F1,
VK_F2 : gdk.GDK_KEY_F2,
VK_F3 : gdk.GDK_KEY_F3,
@@ -20,8 +27,4 @@ vkgdkmap = {
VK_F10 : gdk.GDK_KEY_F10,
VK_F11 : gdk.GDK_KEY_F11,
VK_F12 : gdk.GDK_KEY_F12,
-
- VK_TAB : gdk.GDK_KEY_Tab,
- VK_DELETE : gdk.GDK_KEY_Delete
-
}