Compare commits
230 Commits
Author | SHA1 | Date | |
---|---|---|---|
e9282c3987 | |||
ed1f8ed339 | |||
5d0d637eb8 | |||
7e70dfdf4c | |||
3f61f39ae3 | |||
371f623a3e | |||
566d566f26 | |||
fb30822860 | |||
526a53bdd4 | |||
3833124d66 | |||
e5e1b52abf | |||
82fc66305d | |||
05e0d5066f | |||
ce2dc84e49 | |||
eb14ed32ea | |||
f97987d0d8 | |||
d23d9c3b05 | |||
3ebf6e3bea | |||
9f41f5c740 | |||
ae00f86887 | |||
ab67c0f8b0 | |||
ed7d4928e5 | |||
f23239a923 | |||
d949920e68 | |||
a1def85c18 | |||
dc624f65e4 | |||
361652d028 | |||
92024b7e54 | |||
4e4ce0dd21 | |||
bc0c490ec3 | |||
6d92af17fd | |||
2140a498a2 | |||
28349d362c | |||
e7af9f98e3 | |||
dd6053c5e1 | |||
37726a4cb6 | |||
4352cc231e | |||
824220356f | |||
247ad9d7ab | |||
09fe12d0c1 | |||
127ef8383b | |||
82eccb566c | |||
543b29efe7 | |||
0f4ce5dd4e | |||
c23919df15 | |||
2b2a8b4747 | |||
2e48dbf6ee | |||
207917ba45 | |||
f824b97f3a | |||
a5ff2fc68f | |||
4906806c0b | |||
d98336a906 | |||
9ddd11cdb8 | |||
554ad4ef05 | |||
45d8550044 | |||
f2b44c1494 | |||
bdb28e87a9 | |||
8b9592e53e | |||
84f89648a6 | |||
1174992099 | |||
391a220dc1 | |||
43f1d0578b | |||
d3e35028ca | |||
61c7d87003 | |||
20f2fa84a4 | |||
17e269b96c | |||
6a57ac92ba | |||
07ad03556f | |||
04c33230c8 | |||
083dac630f | |||
6375724196 | |||
922957c1ae | |||
cbf7d0e738 | |||
fb81efeecf | |||
8466198626 | |||
33718ef7a5 | |||
a94a62764d | |||
12c98df3db | |||
81909a406f | |||
d291aaa4f2 | |||
da36d87e46 | |||
42bc09a7ef | |||
d0defc592e | |||
700f7fbaf3 | |||
74f2d02ac3 | |||
c865d96f4b | |||
cd7b9e108c | |||
f54b82f64c | |||
36bfe8c533 | |||
a40d063cb8 | |||
ac88a88bfb | |||
d89c9b4556 | |||
a07056f5e2 | |||
f91bea3ea5 | |||
9fbd79316a | |||
6d89d0b02a | |||
0febcbfa2a | |||
f2f2898fe3 | |||
f65826b3ba | |||
a869007180 | |||
b5fa48f485 | |||
36d564526c | |||
063f34b5d3 | |||
9486ca5975 | |||
63ead272a9 | |||
9dfa2ad84e | |||
523e431ece | |||
768c4a0dd5 | |||
fd25cf30ff | |||
1d14488a4f | |||
6e32c97c43 | |||
020fe35d98 | |||
e0cf946611 | |||
a42ae6fe3a | |||
196ab6a7c3 | |||
f3235882f3 | |||
0518d69b72 | |||
c9ba94d4d8 | |||
50e4a40bb2 | |||
351421c158 | |||
c3ac2df9ca | |||
7c4f632e06 | |||
a4eb3c17eb | |||
e81cee3949 | |||
e943dcafa4 | |||
a324c390f0 | |||
1cf64b5471 | |||
234a4f3a1b | |||
e69d561e8e | |||
b8f2abcbfa | |||
189617dfb2 | |||
c4bfb1e400 | |||
7db92ad5d9 | |||
fa593a3e15 | |||
8424236daa | |||
5c14be28f3 | |||
9ef80f6ac6 | |||
daf81b5cae | |||
7b407dda91 | |||
4c50293f06 | |||
02b8804b96 | |||
7928f90cf6 | |||
d5e6ea6ebd | |||
52273b6c03 | |||
b3d663b758 | |||
c0028694d4 | |||
3b0110849c | |||
7b1deba590 | |||
7a91f318f0 | |||
2dfde89008 | |||
23146c00ba | |||
cdd95fbbdc | |||
01064af20e | |||
01a9c3fc8e | |||
c1734b279b | |||
b00dc31b55 | |||
c5f8c8c77b | |||
9361c7223d | |||
b43cc22704 | |||
8af4fd64c1 | |||
5b39b87199 | |||
092338a4c7 | |||
7907b19e28 | |||
5790309e88 | |||
9496b64c86 | |||
f7fb6b2160 | |||
98649f9397 | |||
45a1ceaa54 | |||
6496205081 | |||
e2898bea5c | |||
563221698c | |||
92a85071bc | |||
9ae8d90be4 | |||
caade78e79 | |||
4f22c61b16 | |||
5e220e9e47 | |||
857cb9c501 | |||
09fa5d98c2 | |||
268fe464de | |||
27095d1a02 | |||
dd061fed38 | |||
7ddaa8968a | |||
cec1557d04 | |||
84a49a5eef | |||
06ea16bdbf | |||
361d38f93b | |||
016e384fa1 | |||
ef57c9ff83 | |||
627fff967f | |||
e79c093d80 | |||
cbb3831c7b | |||
9752fda1f6 | |||
d99f08b9c4 | |||
bf0bcaa306 | |||
a199c1290b | |||
28bb0c1fb2 | |||
49259b3d19 | |||
a5d0ac7955 | |||
f326dde09c | |||
3b6d907577 | |||
0af108211c | |||
902e78d910 | |||
885e194c25 | |||
d99a2f19a5 | |||
152a7fd1ef | |||
6ceb6545ee | |||
a167b16860 | |||
595be5083c | |||
8b796e745d | |||
d5314736de | |||
a517ab964e | |||
b6c0a2c197 | |||
0151c92a92 | |||
a39440fff5 | |||
5af7e9f6fe | |||
b8d9273a7c | |||
77c4cbb974 | |||
8adc193d73 | |||
86aa4fe0a9 | |||
8c9eb6702d | |||
b245ee6212 | |||
98fa71ba18 | |||
22dcb46bff | |||
3aa904da0a | |||
794f773620 | |||
bbba77c275 | |||
88f2bbba61 | |||
cc8d4e4ab3 | |||
32a11bd8c7 | |||
55c82a389c |
@ -1,7 +1,7 @@
|
||||
# Point to our macro directory and pick up user flags from the environment
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
|
||||
SUBDIRS = data js src tests po man
|
||||
SUBDIRS = data js src browser-plugin tests po man
|
||||
|
||||
EXTRA_DIST = \
|
||||
.project \
|
||||
|
115
NEWS
115
NEWS
@ -1,3 +1,118 @@
|
||||
3.1.92
|
||||
======
|
||||
|
||||
* Login screen
|
||||
- Add the ability to set a logo at the top of the user list [Ray; #658062]
|
||||
- Add fingerprint reader support [Ray; #657823]
|
||||
- Add a power button offering the choice of Suspend/Restart/Power off
|
||||
[Ray; #657822]
|
||||
- Remove the option to view the current keyboad layout [Matthias; #659164]
|
||||
- Make Control-Alt-Tab work for full keyboard access [Ray; #659177]
|
||||
* Frequently initiate a full garbage collection; Spidermonkey isn't very good
|
||||
at tracking the amount of resources we have allocated so this hopefully will
|
||||
improve memory usage without affecting performance too much [Colin; #659254]
|
||||
* Stop adding a notification when the network connection is lost
|
||||
[Colin; #658954]
|
||||
* When disabling notifications; display a notification
|
||||
"Your chat status will be set to busy" [Florian; #652718]
|
||||
* Fix keynav in network dialogs [Florian; #659133]
|
||||
* Improve calendar styling [Sean; #641135, #651299]
|
||||
* Shrink padding around panel buttons for narrow screens [Dan; #651299]
|
||||
* Allow enabling the onscreen keyboard through the accessibility menu
|
||||
[Dan; #612662]
|
||||
* Fix problem that was causing VPN secret dialogs to be delayed before showing
|
||||
[Florian; #658484]
|
||||
* Make custom-keybindings for the window switcher that don't use alt
|
||||
work correctly [Florian; #645200]
|
||||
* Fix duplicate application icons in the Activities Overview [Colin; #659351]
|
||||
* Bug fixes for dimming windows with attached modal dialogs
|
||||
[Jasper, Owen; #659302, 659634]
|
||||
* Add build-time support for BROWSER_PLUGIN_DIR environment variable
|
||||
[Vincent; #659123]
|
||||
* Build fixes [Vincent; #659194]
|
||||
* Code cleanups and test cases
|
||||
[Adel, Dan, Florian, Jasper; #651299, #658092, #658939]
|
||||
* Misc bug fixes
|
||||
[Adel, Colin, Cosimo, Dan, Florian, Giovanni, Jasper, Ray, Xavier;
|
||||
#651299, #652837, #657249, #658004, #658150, #658239, #658469, #658598,
|
||||
#658605, #659050, #659159, #659210, #659270, #659370, #659633]
|
||||
|
||||
Contributors:
|
||||
Giovanni Campagna, Cosimo Cecchi, Xavier Claessens, Matthias Clasen,
|
||||
Rui Matos, Florian Müllner, Jasper St. Pierre, Owen Taylor,
|
||||
Vincent Untz, Colin Walters, Sean Wilson, Dan Winship
|
||||
|
||||
Translations:
|
||||
Ihar Hrachyshka [be], Alexander Shopov, Ivaylo Valkov [bg],
|
||||
Mario Blättermann [de], Jorge González, Daniel Mustieles [es],
|
||||
Arash Mousavi [fa], Ville-Pekka Vainio [fi], Fran Dieguez [gl],
|
||||
Sweta Kothari [gu], Gabor Kelemen [hu], Jiro Matsuzawa [ja],
|
||||
Luca Ferretti [it], Rudolfs Mazurs [lv], Kjartan Maraas [nb], A S Alam [pa],
|
||||
Piotr Drąg [pl], Duarte Loreto [pt], Yuri Myasoedov [ru],
|
||||
Daniel Nylander [se], Matej Urbančič [sl], Miroslav Nikolić [sr, sr@latin],
|
||||
Michal Štrba [sv], Tirumurti Vasudevan [ta], Phương Lê Hoàng [vi],
|
||||
Aron Xu [zh_CN], Chao-Hsiung Liao [zh_HK, zh_TW]
|
||||
|
||||
3.1.91.1
|
||||
========
|
||||
|
||||
* Add a browser plugin - this plugin, tied to extensions.gnome.org,
|
||||
allows users to download and install shell extensions, and enable,
|
||||
disable, and uninstall extensions they already have installed.
|
||||
[Jasper; #658070, #658612]
|
||||
* Improve adding links to URLs in notifications [Dan; #636252]
|
||||
* Remove "connection lost" notifications after reconnecting [Giovanni; #658049]
|
||||
* Hide the onscreen keyboard when leaving a text entry [Dan; #658591]
|
||||
* Fixes for translated strings [Florian; #639987, #644097, #645037]
|
||||
* Bug fixes for network menu [Florian; #658492]
|
||||
* Code cleanup [Dan; #646934]
|
||||
* Build fixes [Javier, Rico]
|
||||
* Misc bug fixes [Emmanuele, Florian, Jasper, Marina, Matthias, Ray;
|
||||
#652837, #658423, #658503, #658525, #658562, #658624, #658640, #658983]
|
||||
|
||||
Conributors:
|
||||
Emmanuele Bassi, Giovanni Campagna, Matthias Clasen, Javier Jardón,
|
||||
Florian Muellner, Jasper St. Pierre, Ray Strode, Rico Tzschichholz,
|
||||
Dan Winship, Marina Zhurakhinskaya
|
||||
|
||||
Translations:
|
||||
Ihar Hrachyshka [be], Bruce Cowan [en_GB], Jorge González,
|
||||
Daniel Mustieles [es], Timo Jyrinki [fi], Bruno Brouard, Luc Guillemin,
|
||||
Claude Paroz, Luc Pionchon [fr], Fran Dieguez [gl], Rajesh Ranjan [hi],
|
||||
Andika Triwidada [id], Luca Ferretti [it], Changwoo Ryu [ko],
|
||||
Rudolfs Mazurs [lt], Kjartan Maraas [nb], Manoj Kumar Giri [or],
|
||||
A S Alam [pa], Piotr Drąg [pl], Duarte Loreto [pt], Henrique P. Machado,
|
||||
Gabriel F. Vilar [pt_BR], Daniel Nylander [se], Matej Urbančič [sl],
|
||||
Tirumurti Vasudevan [ta], Yinghua Wang [zh_CN],
|
||||
Chao-Hsiung Liao [zh_HK, zh_TW]
|
||||
|
||||
3.1.91
|
||||
======
|
||||
|
||||
* Fix problem with applications vanishing from alt-Tab when
|
||||
desktop files change. [Colin; #657990]
|
||||
* Fix interaction of on-screen keyboard with run-dialog and
|
||||
Looking Glass console [Dan; #657986]
|
||||
* Add public API for adding and removing search providers
|
||||
[Philippe; #657548, #658113]
|
||||
* Allow changing IM status with scroll wheel [Florian; #657973]
|
||||
* Limit volume slider to 100% [Bastien; #657607]
|
||||
* Change "Do Not Disturb" to "Notifications" in user menu [Florian; #652718]
|
||||
* Switch browser in default favorites to Epiphany [Colin; #650616]
|
||||
* Misc bug fixes [Dan, Florian, Jasper, Marc-Antoine, Rui;
|
||||
#649631, #655069, #656142, #657703, #657759, #658007, #658065, #658176]
|
||||
|
||||
Contributors:
|
||||
Rui Matos, Florian Müllner, Philippe Normand, Marc-Antoine Perennou,
|
||||
Jasper St. Pierre, Colin Walters, Dan Winship
|
||||
|
||||
Translations:
|
||||
Ihar Hrachyshka [be], Mario Blättermann [de], Kris Thomsen [da],
|
||||
Jorge González [es], Arash Mousavi [fa], Fran Dieguez [gl],
|
||||
Takayuki Kusano [ja],Aurimas Černius [lt], Kjartan Maraas [nb], A S Alam [pa],
|
||||
Stas Solovey [ru], Daniel Nylander [se], Tirumurti Vasudevan [ta],
|
||||
Chao-Hsiung Liao [zh_HK, zh_TW]
|
||||
|
||||
3.1.90.1
|
||||
========
|
||||
|
||||
|
21
browser-plugin/Makefile.am
Normal file
21
browser-plugin/Makefile.am
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
mozillalibdir = $(BROWSER_PLUGIN_DIR)
|
||||
|
||||
mozillalib_LTLIBRARIES = libgnome-shell-browser-plugin.la
|
||||
|
||||
libgnome_shell_browser_plugin_la_LDFLAGS = -module -avoid-version -no-undefined
|
||||
|
||||
libgnome_shell_browser_plugin_la_LIBADD = \
|
||||
$(BROWSER_PLUGIN_LIBS)
|
||||
|
||||
libgnome_shell_browser_plugin_la_SOURCES = \
|
||||
browser-plugin.c \
|
||||
npapi/npapi.h \
|
||||
npapi/npfunctions.h \
|
||||
npapi/npruntime.h \
|
||||
npapi/nptypes.h
|
||||
|
||||
libgnome_shell_browser_plugin_la_CFLAGS = \
|
||||
$(BROWSER_PLUGIN_CFLAGS) \
|
||||
-DG_DISABLE_DEPRECATED \
|
||||
-DG_LOG_DOMAIN=\"GnomeShellBrowserPlugin\"
|
17
browser-plugin/README
Normal file
17
browser-plugin/README
Normal file
@ -0,0 +1,17 @@
|
||||
The GNOME Shell Browser Plugin provides integration with gnome-shell and the
|
||||
corresponding extensions repository, codenamed "SweetTooth". The plugin allows
|
||||
the extensions repository to provide good integration, letting the website
|
||||
know which extensions are enabled and disabled, and allowing the website to
|
||||
enable, disable and install them.
|
||||
|
||||
Bugs should be reported at http://bugzilla.gnome.org against the 'gnome-shell'
|
||||
product.
|
||||
|
||||
License
|
||||
=======
|
||||
The GNOME Shell Browser Plugin, like GNOME Shell itself is distributed under
|
||||
the GNU General Public License, version 2 or later. The plugin also contains
|
||||
header files from the "NPAPI SDK" project, tri-licensed under MPL 1.1, GPL 2.0
|
||||
and LGPL 2.1. These headers are third-party sources and can be retrieved from:
|
||||
|
||||
http://code.google.com/p/npapi-sdk/
|
824
browser-plugin/browser-plugin.c
Normal file
824
browser-plugin/browser-plugin.c
Normal file
@ -0,0 +1,824 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Copyright (C) 2011 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Authors:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
* Giovanni Campagna <scampa.giovanni@gmail.com>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define XP_UNIX 1
|
||||
|
||||
#include "npapi/npapi.h"
|
||||
#include "npapi/npruntime.h"
|
||||
#include "npapi/npfunctions.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
#define ORIGIN "extensions.gnome.org"
|
||||
#define PLUGIN_NAME "Gnome Shell Integration"
|
||||
#define PLUGIN_DESCRIPTION "This plugin provides integration with Gnome Shell " \
|
||||
"for live extension enabling and disabling. " \
|
||||
"It can be used only by extensions.gnome.org"
|
||||
#define PLUGIN_MIME_STRING "application/x-gnome-shell-integration::Gnome Shell Integration Dummy Content-Type";
|
||||
|
||||
#define PLUGIN_API_VERSION 1
|
||||
|
||||
typedef struct {
|
||||
GDBusProxy *proxy;
|
||||
} PluginData;
|
||||
|
||||
/* =============== public entry points =================== */
|
||||
|
||||
static NPNetscapeFuncs funcs;
|
||||
|
||||
static inline gchar *
|
||||
get_string_property (NPP instance,
|
||||
NPObject *obj,
|
||||
const char *name)
|
||||
{
|
||||
NPVariant result = { NPVariantType_Void };
|
||||
NPString result_str;
|
||||
gchar *result_copy;
|
||||
|
||||
result_copy = NULL;
|
||||
|
||||
if (!funcs.getproperty (instance, obj,
|
||||
funcs.getstringidentifier (name),
|
||||
&result))
|
||||
goto out;
|
||||
|
||||
if (!NPVARIANT_IS_STRING (result))
|
||||
goto out;
|
||||
|
||||
result_str = NPVARIANT_TO_STRING (result);
|
||||
if (strlen (result_str.UTF8Characters) != result_str.UTF8Length)
|
||||
goto out;
|
||||
|
||||
result_copy = g_strdup (result_str.UTF8Characters);
|
||||
|
||||
out:
|
||||
funcs.releasevariantvalue (&result);
|
||||
return result_copy;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_origin_and_protocol (NPP instance)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
NPError error;
|
||||
NPObject *window = NULL;
|
||||
NPVariant document = { NPVariantType_Void };
|
||||
NPVariant location = { NPVariantType_Void };
|
||||
gchar *hostname = NULL;
|
||||
gchar *protocol = NULL;
|
||||
|
||||
error = funcs.getvalue (instance, NPNVWindowNPObject, &window);
|
||||
if (error != NPERR_NO_ERROR)
|
||||
goto out;
|
||||
|
||||
if (!funcs.getproperty (instance, window,
|
||||
funcs.getstringidentifier ("document"),
|
||||
&document))
|
||||
goto out;
|
||||
|
||||
if (!NPVARIANT_IS_OBJECT (document))
|
||||
goto out;
|
||||
|
||||
if (!funcs.getproperty (instance, NPVARIANT_TO_OBJECT (document),
|
||||
funcs.getstringidentifier ("location"),
|
||||
&location))
|
||||
goto out;
|
||||
|
||||
if (!NPVARIANT_IS_OBJECT (document))
|
||||
goto out;
|
||||
|
||||
hostname = get_string_property (instance,
|
||||
NPVARIANT_TO_OBJECT (location),
|
||||
"hostname");
|
||||
|
||||
if (g_strcmp0 (hostname, ORIGIN))
|
||||
{
|
||||
g_debug ("origin does not match, is %s",
|
||||
hostname);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
protocol = get_string_property (instance,
|
||||
NPVARIANT_TO_OBJECT (location),
|
||||
"protocol");
|
||||
|
||||
if (g_strcmp0 (protocol, "https:") != 0)
|
||||
{
|
||||
g_debug ("protocol does not match, is %s",
|
||||
protocol);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
g_free (protocol);
|
||||
g_free (hostname);
|
||||
|
||||
funcs.releasevariantvalue (&location);
|
||||
funcs.releasevariantvalue (&document);
|
||||
|
||||
if (window != NULL)
|
||||
funcs.releaseobject (window);
|
||||
return ret;
|
||||
}
|
||||
|
||||
NPError
|
||||
NP_Initialize(NPNetscapeFuncs *pfuncs, NPPluginFuncs *plugin)
|
||||
{
|
||||
/* global initialization routine, called once when plugin
|
||||
is loaded */
|
||||
|
||||
g_debug ("plugin loaded");
|
||||
|
||||
memcpy (&funcs, pfuncs, sizeof (funcs));
|
||||
|
||||
plugin->size = sizeof(NPPluginFuncs);
|
||||
plugin->newp = NPP_New;
|
||||
plugin->destroy = NPP_Destroy;
|
||||
plugin->getvalue = NPP_GetValue;
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
NPError
|
||||
NP_Shutdown(void)
|
||||
{
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
const char*
|
||||
NP_GetMIMEDescription(void)
|
||||
{
|
||||
return PLUGIN_MIME_STRING;
|
||||
}
|
||||
|
||||
NPError
|
||||
NP_GetValue(void *instance,
|
||||
NPPVariable variable,
|
||||
void *value)
|
||||
{
|
||||
switch (variable) {
|
||||
case NPPVpluginNameString:
|
||||
*(char**)value = PLUGIN_NAME;
|
||||
break;
|
||||
case NPPVpluginDescriptionString:
|
||||
*(char**)value = PLUGIN_DESCRIPTION;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
NPError
|
||||
NPP_New(NPMIMEType mimetype,
|
||||
NPP instance,
|
||||
uint16_t mode,
|
||||
int16_t argc,
|
||||
char **argn,
|
||||
char **argv,
|
||||
NPSavedData *saved)
|
||||
{
|
||||
/* instance initialization function */
|
||||
PluginData *data;
|
||||
GError *error = NULL;
|
||||
|
||||
g_debug ("plugin created");
|
||||
|
||||
if (!check_origin_and_protocol (instance))
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
data = g_slice_new (PluginData);
|
||||
instance->pdata = data;
|
||||
|
||||
data->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
NULL, /* interface info */
|
||||
"org.gnome.Shell",
|
||||
"/org/gnome/Shell",
|
||||
"org.gnome.Shell",
|
||||
NULL, /* GCancellable */
|
||||
&error);
|
||||
if (!data->proxy)
|
||||
{
|
||||
/* ignore error if the shell is not running, otherwise warn */
|
||||
if (error->domain != G_DBUS_ERROR ||
|
||||
error->code != G_DBUS_ERROR_NAME_HAS_NO_OWNER)
|
||||
{
|
||||
g_warning ("Failed to set up Shell proxy: %s", error->message);
|
||||
}
|
||||
g_clear_error (&error);
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
g_debug ("plugin created successfully");
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
NPError
|
||||
NPP_Destroy(NPP instance,
|
||||
NPSavedData **saved)
|
||||
{
|
||||
/* instance finalization function */
|
||||
|
||||
PluginData *data = instance->pdata;
|
||||
|
||||
g_debug ("plugin destroyed");
|
||||
|
||||
g_object_unref (data->proxy);
|
||||
|
||||
g_slice_free (PluginData, data);
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
/* =================== scripting interface =================== */
|
||||
|
||||
typedef struct {
|
||||
NPObject parent;
|
||||
NPP instance;
|
||||
GDBusProxy *proxy;
|
||||
NPObject *listener;
|
||||
gint signal_id;
|
||||
} PluginObject;
|
||||
|
||||
static void
|
||||
on_shell_signal (GDBusProxy *proxy,
|
||||
gchar *sender_name,
|
||||
gchar *signal_name,
|
||||
GVariant *parameters,
|
||||
gpointer user_data)
|
||||
{
|
||||
PluginObject *obj = user_data;
|
||||
|
||||
if (strcmp (signal_name, "ExtensionStatusChanged") == 0)
|
||||
{
|
||||
gchar *uuid;
|
||||
gint32 status;
|
||||
gchar *error;
|
||||
NPVariant args[3];
|
||||
NPVariant result;
|
||||
|
||||
g_variant_get (parameters, "(sis)", &uuid, &status, &error);
|
||||
STRINGZ_TO_NPVARIANT (uuid, args[0]);
|
||||
INT32_TO_NPVARIANT (status, args[1]);
|
||||
STRINGZ_TO_NPVARIANT (error, args[2]);
|
||||
|
||||
funcs.invokeDefault (obj->instance, obj->listener,
|
||||
args, 3, &result);
|
||||
|
||||
funcs.releasevariantvalue (&result);
|
||||
g_free (uuid);
|
||||
g_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static NPObject *
|
||||
plugin_object_allocate (NPP instance,
|
||||
NPClass *klass)
|
||||
{
|
||||
PluginData *data = instance->pdata;
|
||||
PluginObject *obj = g_slice_new0 (PluginObject);
|
||||
|
||||
obj->instance = instance;
|
||||
obj->proxy = g_object_ref (data->proxy);
|
||||
obj->signal_id = g_signal_connect (obj->proxy, "g-signal",
|
||||
G_CALLBACK (on_shell_signal), obj);
|
||||
|
||||
g_debug ("plugin object created");
|
||||
|
||||
return (NPObject*)obj;
|
||||
}
|
||||
|
||||
static void
|
||||
plugin_object_deallocate (NPObject *npobj)
|
||||
{
|
||||
PluginObject *obj = (PluginObject*)npobj;
|
||||
|
||||
g_signal_handler_disconnect (obj->proxy, obj->signal_id);
|
||||
g_object_unref (obj->proxy);
|
||||
|
||||
if (obj->listener)
|
||||
funcs.releaseobject (obj->listener);
|
||||
|
||||
g_debug ("plugin object destroyed");
|
||||
|
||||
g_slice_free (PluginObject, obj);
|
||||
}
|
||||
|
||||
static NPIdentifier api_version_id;
|
||||
static NPIdentifier shell_version_id;
|
||||
static NPIdentifier get_info_id;
|
||||
static NPIdentifier list_extensions_id;
|
||||
static NPIdentifier enable_extension_id;
|
||||
static NPIdentifier install_extension_id;
|
||||
static NPIdentifier uninstall_extension_id;
|
||||
static NPIdentifier onextension_changed_id;
|
||||
static NPIdentifier get_errors_id;
|
||||
|
||||
static bool
|
||||
plugin_object_has_method (NPObject *npobj,
|
||||
NPIdentifier name)
|
||||
{
|
||||
return (name == get_info_id ||
|
||||
name == list_extensions_id ||
|
||||
name == enable_extension_id ||
|
||||
name == install_extension_id ||
|
||||
name == uninstall_extension_id ||
|
||||
name == get_errors_id);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
uuid_is_valid (const gchar *uuid)
|
||||
{
|
||||
gsize i;
|
||||
|
||||
for (i = 0; uuid[i]; i ++)
|
||||
{
|
||||
gchar c = uuid[i];
|
||||
if (c < 32 || c >= 127)
|
||||
return FALSE;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '&':
|
||||
case '<':
|
||||
case '>':
|
||||
case '/':
|
||||
case '\\':
|
||||
return FALSE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
jsonify_variant (GVariant *variant,
|
||||
NPVariant *result)
|
||||
{
|
||||
gboolean ret;
|
||||
GVariant *real_value;
|
||||
JsonNode *root;
|
||||
JsonGenerator *generator;
|
||||
gsize json_length;
|
||||
gchar *json;
|
||||
gchar *buffer;
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
/* DBus methods can return multiple values,
|
||||
* but we're only interested in the first. */
|
||||
g_variant_get (variant, "(@*)", &real_value);
|
||||
|
||||
root = json_gvariant_serialize (real_value);
|
||||
|
||||
generator = json_generator_new ();
|
||||
json_generator_set_root (generator, root);
|
||||
json = json_generator_to_data (generator, &json_length);
|
||||
|
||||
buffer = funcs.memalloc (json_length + 1);
|
||||
if (!buffer)
|
||||
{
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
strcpy (buffer, json);
|
||||
|
||||
STRINGN_TO_NPVARIANT (buffer, json_length, *result);
|
||||
|
||||
out:
|
||||
g_variant_unref (variant);
|
||||
g_variant_unref (real_value);
|
||||
json_node_free (root);
|
||||
g_free (json);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_list_extensions (PluginObject *obj,
|
||||
NPVariant *result)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GVariant *res;
|
||||
|
||||
res = g_dbus_proxy_call_sync (obj->proxy,
|
||||
"ListExtensions",
|
||||
NULL, /* parameters */
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, /* timeout */
|
||||
NULL, /* cancellable */
|
||||
&error);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
g_warning ("Failed to retrieve extension list: %s", error->message);
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return jsonify_variant (res, result);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_enable_extension (PluginObject *obj,
|
||||
NPString uuid,
|
||||
gboolean enabled)
|
||||
{
|
||||
const gchar *uuid_str = uuid.UTF8Characters;
|
||||
if (!uuid_is_valid (uuid_str))
|
||||
return FALSE;
|
||||
|
||||
g_dbus_proxy_call (obj->proxy,
|
||||
(enabled ? "EnableExtension" : "DisableExtension"),
|
||||
g_variant_new ("(s)", uuid_str),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, /* timeout */
|
||||
NULL, /* cancellable */
|
||||
NULL, /* callback */
|
||||
NULL /* user_data */);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_install_extension (PluginObject *obj,
|
||||
NPString uuid,
|
||||
NPString version_tag)
|
||||
{
|
||||
const gchar *uuid_str = uuid.UTF8Characters;
|
||||
if (!uuid_is_valid (uuid_str))
|
||||
return FALSE;
|
||||
|
||||
g_dbus_proxy_call (obj->proxy,
|
||||
"InstallRemoteExtension",
|
||||
g_variant_new ("(ss)",
|
||||
uuid_str,
|
||||
version_tag.UTF8Characters),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, /* timeout */
|
||||
NULL, /* cancellable */
|
||||
NULL, /* callback */
|
||||
NULL /* user_data */);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_uninstall_extension (PluginObject *obj,
|
||||
NPString uuid,
|
||||
NPVariant *result)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GVariant *res;
|
||||
const gchar *uuid_str;
|
||||
|
||||
uuid_str = uuid.UTF8Characters;
|
||||
if (!uuid_is_valid (uuid_str))
|
||||
return FALSE;
|
||||
|
||||
res = g_dbus_proxy_call_sync (obj->proxy,
|
||||
"UninstallExtension",
|
||||
g_variant_new ("(s)",
|
||||
uuid_str),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, /* timeout */
|
||||
NULL, /* cancellable */
|
||||
&error);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
g_warning ("Failed to uninstall extension: %s", error->message);
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return jsonify_variant (res, result);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_get_info (PluginObject *obj,
|
||||
NPString uuid,
|
||||
NPVariant *result)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GVariant *res;
|
||||
const gchar *uuid_str;
|
||||
|
||||
uuid_str = uuid.UTF8Characters;
|
||||
if (!uuid_is_valid (uuid_str))
|
||||
return FALSE;
|
||||
|
||||
res = g_dbus_proxy_call_sync (obj->proxy,
|
||||
"GetExtensionInfo",
|
||||
g_variant_new ("(s)", uuid_str),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, /* timeout */
|
||||
NULL, /* cancellable */
|
||||
&error);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
g_warning ("Failed to retrieve extension metadata: %s", error->message);
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return jsonify_variant (res, result);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_get_errors (PluginObject *obj,
|
||||
NPString uuid,
|
||||
NPVariant *result)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GVariant *res;
|
||||
const gchar *uuid_str;
|
||||
|
||||
uuid_str = uuid.UTF8Characters;
|
||||
if (!uuid_is_valid (uuid_str))
|
||||
return FALSE;
|
||||
|
||||
res = g_dbus_proxy_call_sync (obj->proxy,
|
||||
"GetExtensionErrors",
|
||||
g_variant_new ("(s)", uuid_str),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, /* timeout */
|
||||
NULL, /* cancellable */
|
||||
&error);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
g_warning ("Failed to retrieve errors: %s", error->message);
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return jsonify_variant (res, result);
|
||||
}
|
||||
|
||||
static int
|
||||
plugin_get_api_version (PluginObject *obj,
|
||||
NPVariant *result)
|
||||
{
|
||||
INT32_TO_NPVARIANT (PLUGIN_API_VERSION, *result);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
plugin_get_shell_version (PluginObject *obj,
|
||||
NPVariant *result)
|
||||
{
|
||||
GVariant *res;
|
||||
const gchar *version;
|
||||
gsize length;
|
||||
gchar *buffer;
|
||||
gboolean ret;
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
res = g_dbus_proxy_get_cached_property (obj->proxy,
|
||||
"ShellVersion");
|
||||
|
||||
if (res == NULL)
|
||||
{
|
||||
g_warning ("Failed to grab shell version.");
|
||||
version = "-1";
|
||||
}
|
||||
else
|
||||
{
|
||||
g_variant_get (res, "&s", &version);
|
||||
}
|
||||
|
||||
length = strlen (version);
|
||||
buffer = funcs.memalloc (length + 1);
|
||||
if (!buffer)
|
||||
{
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
strcpy (buffer, version);
|
||||
|
||||
STRINGN_TO_NPVARIANT (buffer, length, *result);
|
||||
|
||||
out:
|
||||
g_variant_unref (res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
plugin_object_invoke (NPObject *npobj,
|
||||
NPIdentifier name,
|
||||
const NPVariant *args,
|
||||
uint32_t argc,
|
||||
NPVariant *result)
|
||||
{
|
||||
PluginObject *obj;
|
||||
|
||||
g_debug ("invoking plugin object method");
|
||||
|
||||
obj = (PluginObject*) npobj;
|
||||
|
||||
VOID_TO_NPVARIANT (*result);
|
||||
|
||||
if (!plugin_object_has_method (npobj, name))
|
||||
return FALSE;
|
||||
|
||||
if (name == list_extensions_id)
|
||||
return plugin_list_extensions (obj, result);
|
||||
else if (name == get_info_id)
|
||||
{
|
||||
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
||||
|
||||
return plugin_get_info (obj, NPVARIANT_TO_STRING(args[0]), result);
|
||||
}
|
||||
else if (name == enable_extension_id)
|
||||
{
|
||||
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
||||
if (!NPVARIANT_IS_BOOLEAN(args[1])) return FALSE;
|
||||
|
||||
return plugin_enable_extension (obj,
|
||||
NPVARIANT_TO_STRING(args[0]),
|
||||
NPVARIANT_TO_BOOLEAN(args[1]));
|
||||
}
|
||||
else if (name == install_extension_id)
|
||||
{
|
||||
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
||||
if (!NPVARIANT_IS_STRING(args[1])) return FALSE;
|
||||
|
||||
return plugin_install_extension (obj,
|
||||
NPVARIANT_TO_STRING(args[0]),
|
||||
NPVARIANT_TO_STRING(args[1]));
|
||||
}
|
||||
else if (name == uninstall_extension_id)
|
||||
{
|
||||
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
||||
|
||||
return plugin_uninstall_extension (obj,
|
||||
NPVARIANT_TO_STRING(args[0]),
|
||||
result);
|
||||
}
|
||||
else if (name == get_errors_id)
|
||||
{
|
||||
if (!NPVARIANT_IS_STRING(args[0])) return FALSE;
|
||||
|
||||
return plugin_get_errors (obj,
|
||||
NPVARIANT_TO_STRING(args[0]),
|
||||
result);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool
|
||||
plugin_object_has_property (NPObject *npobj,
|
||||
NPIdentifier name)
|
||||
{
|
||||
return (name == onextension_changed_id ||
|
||||
name == api_version_id ||
|
||||
name == shell_version_id);
|
||||
}
|
||||
|
||||
static bool
|
||||
plugin_object_get_property (NPObject *npobj,
|
||||
NPIdentifier name,
|
||||
NPVariant *result)
|
||||
{
|
||||
PluginObject *obj;
|
||||
|
||||
if (!plugin_object_has_property (npobj, name))
|
||||
return FALSE;
|
||||
|
||||
obj = (PluginObject*) npobj;
|
||||
if (name == api_version_id)
|
||||
return plugin_get_api_version (obj, result);
|
||||
else if (name == shell_version_id)
|
||||
return plugin_get_shell_version (obj, result);
|
||||
else if (name == onextension_changed_id)
|
||||
{
|
||||
if (obj->listener)
|
||||
OBJECT_TO_NPVARIANT (obj->listener, *result);
|
||||
else
|
||||
NULL_TO_NPVARIANT (*result);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool
|
||||
plugin_object_set_property (NPObject *npobj,
|
||||
NPIdentifier name,
|
||||
const NPVariant *value)
|
||||
{
|
||||
PluginObject *obj;
|
||||
|
||||
if (!plugin_object_has_property (npobj, name))
|
||||
return FALSE;
|
||||
|
||||
if (name == onextension_changed_id)
|
||||
{
|
||||
obj = (PluginObject*) npobj;
|
||||
if (obj->listener)
|
||||
funcs.releaseobject (obj->listener);
|
||||
|
||||
obj->listener = NULL;
|
||||
if (NPVARIANT_IS_OBJECT (*value))
|
||||
{
|
||||
obj->listener = NPVARIANT_TO_OBJECT (*value);
|
||||
funcs.retainobject (obj->listener);
|
||||
return TRUE;
|
||||
}
|
||||
else if (NPVARIANT_IS_NULL (*value))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static NPClass plugin_class = {
|
||||
NP_CLASS_STRUCT_VERSION,
|
||||
plugin_object_allocate,
|
||||
plugin_object_deallocate,
|
||||
NULL, /* invalidate */
|
||||
plugin_object_has_method,
|
||||
plugin_object_invoke,
|
||||
NULL, /* invoke default */
|
||||
plugin_object_has_property,
|
||||
plugin_object_get_property,
|
||||
plugin_object_set_property,
|
||||
NULL, /* remove property */
|
||||
NULL, /* enumerate */
|
||||
NULL, /* construct */
|
||||
};
|
||||
|
||||
static void
|
||||
init_methods_and_properties (void)
|
||||
{
|
||||
/* this is the JS public API; it is manipulated through NPIdentifiers for speed */
|
||||
api_version_id = funcs.getstringidentifier ("apiVersion");
|
||||
shell_version_id = funcs.getstringidentifier ("shellVersion");
|
||||
|
||||
get_info_id = funcs.getstringidentifier ("getExtensionInfo");
|
||||
list_extensions_id = funcs.getstringidentifier ("listExtensions");
|
||||
enable_extension_id = funcs.getstringidentifier ("setExtensionEnabled");
|
||||
install_extension_id = funcs.getstringidentifier ("installExtension");
|
||||
uninstall_extension_id = funcs.getstringidentifier ("uninstallExtension");
|
||||
get_errors_id = funcs.getstringidentifier ("getExtensionErrors");
|
||||
|
||||
onextension_changed_id = funcs.getstringidentifier ("onchange");
|
||||
}
|
||||
|
||||
NPError
|
||||
NPP_GetValue(NPP instance,
|
||||
NPPVariable variable,
|
||||
void *value)
|
||||
{
|
||||
g_debug ("NPP_GetValue called");
|
||||
|
||||
switch (variable) {
|
||||
case NPPVpluginScriptableNPObject:
|
||||
g_debug ("creating scriptable object");
|
||||
init_methods_and_properties ();
|
||||
|
||||
*(NPObject**)value = funcs.createobject (instance, &plugin_class);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
893
browser-plugin/npapi/npapi.h
Normal file
893
browser-plugin/npapi/npapi.h
Normal file
@ -0,0 +1,893 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef npapi_h_
|
||||
#define npapi_h_
|
||||
|
||||
#if defined(__OS2__)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
#include "nptypes.h"
|
||||
|
||||
#if defined(__OS2__) || defined(OS2)
|
||||
#ifndef XP_OS2
|
||||
#define XP_OS2 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(__SYMBIAN32__)
|
||||
#include <windef.h>
|
||||
#ifndef XP_WIN
|
||||
#define XP_WIN 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__SYMBIAN32__)
|
||||
#ifndef XP_SYMBIAN
|
||||
#define XP_SYMBIAN 1
|
||||
#undef XP_WIN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE_CC__) && !defined(XP_UNIX)
|
||||
#ifndef XP_MACOSX
|
||||
#define XP_MACOSX 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX) && defined(__LP64__)
|
||||
#define NP_NO_QUICKDRAW
|
||||
#define NP_NO_CARBON
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#ifndef NP_NO_CARBON
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
#include <stdio.h>
|
||||
#if defined(MOZ_X11)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(XP_SYMBIAN)
|
||||
#include <QEvent>
|
||||
#include <QRegion>
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Plugin Version Constants */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#define NP_VERSION_MAJOR 0
|
||||
#define NP_VERSION_MINOR 27
|
||||
|
||||
|
||||
/* The OS/2 version of Netscape uses RC_DATA to define the
|
||||
mime types, file extensions, etc that are required.
|
||||
Use a vertical bar to separate types, end types with \0.
|
||||
FileVersion and ProductVersion are 32bit ints, all other
|
||||
entries are strings that MUST be terminated with a \0.
|
||||
|
||||
AN EXAMPLE:
|
||||
|
||||
RCDATA NP_INFO_ProductVersion { 1,0,0,1,}
|
||||
|
||||
RCDATA NP_INFO_MIMEType { "video/x-video|",
|
||||
"video/x-flick\0" }
|
||||
RCDATA NP_INFO_FileExtents { "avi|",
|
||||
"flc\0" }
|
||||
RCDATA NP_INFO_FileOpenName{ "MMOS2 video player(*.avi)|",
|
||||
"MMOS2 Flc/Fli player(*.flc)\0" }
|
||||
|
||||
RCDATA NP_INFO_FileVersion { 1,0,0,1 }
|
||||
RCDATA NP_INFO_CompanyName { "Netscape Communications\0" }
|
||||
RCDATA NP_INFO_FileDescription { "NPAVI32 Extension DLL\0"
|
||||
RCDATA NP_INFO_InternalName { "NPAVI32\0" )
|
||||
RCDATA NP_INFO_LegalCopyright { "Copyright Netscape Communications \251 1996\0"
|
||||
RCDATA NP_INFO_OriginalFilename { "NVAPI32.DLL" }
|
||||
RCDATA NP_INFO_ProductName { "NPAVI32 Dynamic Link Library\0" }
|
||||
*/
|
||||
/* RC_DATA types for version info - required */
|
||||
#define NP_INFO_ProductVersion 1
|
||||
#define NP_INFO_MIMEType 2
|
||||
#define NP_INFO_FileOpenName 3
|
||||
#define NP_INFO_FileExtents 4
|
||||
/* RC_DATA types for version info - used if found */
|
||||
#define NP_INFO_FileDescription 5
|
||||
#define NP_INFO_ProductName 6
|
||||
/* RC_DATA types for version info - optional */
|
||||
#define NP_INFO_CompanyName 7
|
||||
#define NP_INFO_FileVersion 8
|
||||
#define NP_INFO_InternalName 9
|
||||
#define NP_INFO_LegalCopyright 10
|
||||
#define NP_INFO_OriginalFilename 11
|
||||
|
||||
#ifndef RC_INVOKED
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Definition of Basic Types */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
typedef unsigned char NPBool;
|
||||
typedef int16_t NPError;
|
||||
typedef int16_t NPReason;
|
||||
typedef char* NPMIMEType;
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Structures and definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#if !defined(__LP64__)
|
||||
#if defined(XP_MACOSX)
|
||||
#pragma options align=mac68k
|
||||
#endif
|
||||
#endif /* __LP64__ */
|
||||
|
||||
/*
|
||||
* NPP is a plug-in's opaque instance handle
|
||||
*/
|
||||
typedef struct _NPP
|
||||
{
|
||||
void* pdata; /* plug-in private data */
|
||||
void* ndata; /* netscape private data */
|
||||
} NPP_t;
|
||||
|
||||
typedef NPP_t* NPP;
|
||||
|
||||
typedef struct _NPStream
|
||||
{
|
||||
void* pdata; /* plug-in private data */
|
||||
void* ndata; /* netscape private data */
|
||||
const char* url;
|
||||
uint32_t end;
|
||||
uint32_t lastmodified;
|
||||
void* notifyData;
|
||||
const char* headers; /* Response headers from host.
|
||||
* Exists only for >= NPVERS_HAS_RESPONSE_HEADERS.
|
||||
* Used for HTTP only; NULL for non-HTTP.
|
||||
* Available from NPP_NewStream onwards.
|
||||
* Plugin should copy this data before storing it.
|
||||
* Includes HTTP status line and all headers,
|
||||
* preferably verbatim as received from server,
|
||||
* headers formatted as in HTTP ("Header: Value"),
|
||||
* and newlines (\n, NOT \r\n) separating lines.
|
||||
* Terminated by \n\0 (NOT \n\n\0). */
|
||||
} NPStream;
|
||||
|
||||
typedef struct _NPByteRange
|
||||
{
|
||||
int32_t offset; /* negative offset means from the end */
|
||||
uint32_t length;
|
||||
struct _NPByteRange* next;
|
||||
} NPByteRange;
|
||||
|
||||
typedef struct _NPSavedData
|
||||
{
|
||||
int32_t len;
|
||||
void* buf;
|
||||
} NPSavedData;
|
||||
|
||||
typedef struct _NPRect
|
||||
{
|
||||
uint16_t top;
|
||||
uint16_t left;
|
||||
uint16_t bottom;
|
||||
uint16_t right;
|
||||
} NPRect;
|
||||
|
||||
typedef struct _NPSize
|
||||
{
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
} NPSize;
|
||||
|
||||
typedef enum {
|
||||
NPFocusNext = 0,
|
||||
NPFocusPrevious = 1
|
||||
} NPFocusDirection;
|
||||
|
||||
/* Return values for NPP_HandleEvent */
|
||||
#define kNPEventNotHandled 0
|
||||
#define kNPEventHandled 1
|
||||
/* Exact meaning must be spec'd in event model. */
|
||||
#define kNPEventStartIME 2
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
/*
|
||||
* Unix specific structures and definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Callback Structures.
|
||||
*
|
||||
* These are used to pass additional platform specific information.
|
||||
*/
|
||||
enum {
|
||||
NP_SETWINDOW = 1,
|
||||
NP_PRINT
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t type;
|
||||
} NPAnyCallbackStruct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t type;
|
||||
#if defined(MOZ_X11)
|
||||
Display* display;
|
||||
Visual* visual;
|
||||
Colormap colormap;
|
||||
unsigned int depth;
|
||||
#endif
|
||||
} NPSetWindowCallbackStruct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t type;
|
||||
FILE* fp;
|
||||
} NPPrintCallbackStruct;
|
||||
|
||||
#endif /* XP_UNIX */
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
typedef enum {
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
NPDrawingModelQuickDraw = 0,
|
||||
#endif
|
||||
NPDrawingModelCoreGraphics = 1,
|
||||
NPDrawingModelOpenGL = 2,
|
||||
NPDrawingModelCoreAnimation = 3,
|
||||
NPDrawingModelInvalidatingCoreAnimation = 4
|
||||
} NPDrawingModel;
|
||||
|
||||
typedef enum {
|
||||
#ifndef NP_NO_CARBON
|
||||
NPEventModelCarbon = 0,
|
||||
#endif
|
||||
NPEventModelCocoa = 1
|
||||
} NPEventModel;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following masks are applied on certain platforms to NPNV and
|
||||
* NPPV selectors that pass around pointers to COM interfaces. Newer
|
||||
* compilers on some platforms may generate vtables that are not
|
||||
* compatible with older compilers. To prevent older plugins from
|
||||
* not understanding a new browser's ABI, these masks change the
|
||||
* values of those selectors on those platforms. To remain backwards
|
||||
* compatible with different versions of the browser, plugins can
|
||||
* use these masks to dynamically determine and use the correct C++
|
||||
* ABI that the browser is expecting. This does not apply to Windows
|
||||
* as Microsoft's COM ABI will likely not change.
|
||||
*/
|
||||
|
||||
#define NP_ABI_GCC3_MASK 0x10000000
|
||||
/*
|
||||
* gcc 3.x generated vtables on UNIX and OSX are incompatible with
|
||||
* previous compilers.
|
||||
*/
|
||||
#if (defined(XP_UNIX) && defined(__GNUC__) && (__GNUC__ >= 3))
|
||||
#define _NP_ABI_MIXIN_FOR_GCC3 NP_ABI_GCC3_MASK
|
||||
#else
|
||||
#define _NP_ABI_MIXIN_FOR_GCC3 0
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#define NP_ABI_MACHO_MASK 0x01000000
|
||||
#define _NP_ABI_MIXIN_FOR_MACHO NP_ABI_MACHO_MASK
|
||||
#else
|
||||
#define _NP_ABI_MIXIN_FOR_MACHO 0
|
||||
#endif
|
||||
|
||||
#define NP_ABI_MASK (_NP_ABI_MIXIN_FOR_GCC3 | _NP_ABI_MIXIN_FOR_MACHO)
|
||||
|
||||
/*
|
||||
* List of variable names for which NPP_GetValue shall be implemented
|
||||
*/
|
||||
typedef enum {
|
||||
NPPVpluginNameString = 1,
|
||||
NPPVpluginDescriptionString,
|
||||
NPPVpluginWindowBool,
|
||||
NPPVpluginTransparentBool,
|
||||
NPPVjavaClass,
|
||||
NPPVpluginWindowSize,
|
||||
NPPVpluginTimerInterval,
|
||||
NPPVpluginScriptableInstance = (10 | NP_ABI_MASK),
|
||||
NPPVpluginScriptableIID = 11,
|
||||
NPPVjavascriptPushCallerBool = 12,
|
||||
NPPVpluginKeepLibraryInMemory = 13,
|
||||
NPPVpluginNeedsXEmbed = 14,
|
||||
|
||||
/* Get the NPObject for scripting the plugin. Introduced in NPAPI minor version 14.
|
||||
*/
|
||||
NPPVpluginScriptableNPObject = 15,
|
||||
|
||||
/* Get the plugin value (as \0-terminated UTF-8 string data) for
|
||||
* form submission if the plugin is part of a form. Use
|
||||
* NPN_MemAlloc() to allocate memory for the string data. Introduced
|
||||
* in NPAPI minor version 15.
|
||||
*/
|
||||
NPPVformValue = 16,
|
||||
|
||||
NPPVpluginUrlRequestsDisplayedBool = 17,
|
||||
|
||||
/* Checks if the plugin is interested in receiving the http body of
|
||||
* all http requests (including failed ones, http status != 200).
|
||||
*/
|
||||
NPPVpluginWantsAllNetworkStreams = 18,
|
||||
|
||||
/* Browsers can retrieve a native ATK accessibility plug ID via this variable. */
|
||||
NPPVpluginNativeAccessibleAtkPlugId = 19,
|
||||
|
||||
/* Checks to see if the plug-in would like the browser to load the "src" attribute. */
|
||||
NPPVpluginCancelSrcStream = 20,
|
||||
|
||||
NPPVsupportsAdvancedKeyHandling = 21,
|
||||
|
||||
NPPVpluginUsesDOMForCursorBool = 22
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
/* Used for negotiating drawing models */
|
||||
, NPPVpluginDrawingModel = 1000
|
||||
/* Used for negotiating event models */
|
||||
, NPPVpluginEventModel = 1001
|
||||
/* In the NPDrawingModelCoreAnimation drawing model, the browser asks the plug-in for a Core Animation layer. */
|
||||
, NPPVpluginCoreAnimationLayer = 1003
|
||||
#endif
|
||||
|
||||
#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
|
||||
, NPPVpluginWindowlessLocalBool = 2002
|
||||
#endif
|
||||
} NPPVariable;
|
||||
|
||||
/*
|
||||
* List of variable names for which NPN_GetValue should be implemented.
|
||||
*/
|
||||
typedef enum {
|
||||
NPNVxDisplay = 1,
|
||||
NPNVxtAppContext,
|
||||
NPNVnetscapeWindow,
|
||||
NPNVjavascriptEnabledBool,
|
||||
NPNVasdEnabledBool,
|
||||
NPNVisOfflineBool,
|
||||
|
||||
NPNVserviceManager = (10 | NP_ABI_MASK),
|
||||
NPNVDOMElement = (11 | NP_ABI_MASK),
|
||||
NPNVDOMWindow = (12 | NP_ABI_MASK),
|
||||
NPNVToolkit = (13 | NP_ABI_MASK),
|
||||
NPNVSupportsXEmbedBool = 14,
|
||||
|
||||
/* Get the NPObject wrapper for the browser window. */
|
||||
NPNVWindowNPObject = 15,
|
||||
|
||||
/* Get the NPObject wrapper for the plugins DOM element. */
|
||||
NPNVPluginElementNPObject = 16,
|
||||
|
||||
NPNVSupportsWindowless = 17,
|
||||
|
||||
NPNVprivateModeBool = 18,
|
||||
|
||||
NPNVsupportsAdvancedKeyHandling = 21
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
/* Used for negotiating drawing models */
|
||||
, NPNVpluginDrawingModel = 1000
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
, NPNVsupportsQuickDrawBool = 2000
|
||||
#endif
|
||||
, NPNVsupportsCoreGraphicsBool = 2001
|
||||
, NPNVsupportsOpenGLBool = 2002
|
||||
, NPNVsupportsCoreAnimationBool = 2003
|
||||
, NPNVsupportsInvalidatingCoreAnimationBool = 2004
|
||||
#ifndef NP_NO_CARBON
|
||||
, NPNVsupportsCarbonBool = 3000 /* TRUE if the browser supports the Carbon event model */
|
||||
#endif
|
||||
, NPNVsupportsCocoaBool = 3001 /* TRUE if the browser supports the Cocoa event model */
|
||||
, NPNVsupportsUpdatedCocoaTextInputBool = 3002 /* TRUE if the browser supports the updated
|
||||
Cocoa text input specification. */
|
||||
, NPNVsupportsCompositingCoreAnimationPluginsBool = 74656 /* TRUE if the browser supports
|
||||
CA model compositing */
|
||||
#endif
|
||||
#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)
|
||||
, NPNVSupportsWindowlessLocal = 2002
|
||||
#endif
|
||||
} NPNVariable;
|
||||
|
||||
typedef enum {
|
||||
NPNURLVCookie = 501,
|
||||
NPNURLVProxy
|
||||
} NPNURLVariable;
|
||||
|
||||
/*
|
||||
* The type of Toolkit the widgets use
|
||||
*/
|
||||
typedef enum {
|
||||
NPNVGtk12 = 1,
|
||||
NPNVGtk2
|
||||
} NPNToolkitType;
|
||||
|
||||
/*
|
||||
* The type of a NPWindow - it specifies the type of the data structure
|
||||
* returned in the window field.
|
||||
*/
|
||||
typedef enum {
|
||||
NPWindowTypeWindow = 1,
|
||||
NPWindowTypeDrawable
|
||||
} NPWindowType;
|
||||
|
||||
typedef struct _NPWindow
|
||||
{
|
||||
void* window; /* Platform specific window handle */
|
||||
/* OS/2: x - Position of bottom left corner */
|
||||
/* OS/2: y - relative to visible netscape window */
|
||||
int32_t x; /* Position of top left corner relative */
|
||||
int32_t y; /* to a netscape page. */
|
||||
uint32_t width; /* Maximum window size */
|
||||
uint32_t height;
|
||||
NPRect clipRect; /* Clipping rectangle in port coordinates */
|
||||
#if (defined(XP_UNIX) || defined(XP_SYMBIAN)) && !defined(XP_MACOSX)
|
||||
void * ws_info; /* Platform-dependent additional data */
|
||||
#endif /* XP_UNIX */
|
||||
NPWindowType type; /* Is this a window or a drawable? */
|
||||
} NPWindow;
|
||||
|
||||
typedef struct _NPImageExpose
|
||||
{
|
||||
char* data; /* image pointer */
|
||||
int32_t stride; /* Stride of data image pointer */
|
||||
int32_t depth; /* Depth of image pointer */
|
||||
int32_t x; /* Expose x */
|
||||
int32_t y; /* Expose y */
|
||||
uint32_t width; /* Expose width */
|
||||
uint32_t height; /* Expose height */
|
||||
NPSize dataSize; /* Data buffer size */
|
||||
float translateX; /* translate X matrix value */
|
||||
float translateY; /* translate Y matrix value */
|
||||
float scaleX; /* scale X matrix value */
|
||||
float scaleY; /* scale Y matrix value */
|
||||
} NPImageExpose;
|
||||
|
||||
typedef struct _NPFullPrint
|
||||
{
|
||||
NPBool pluginPrinted;/* Set TRUE if plugin handled fullscreen printing */
|
||||
NPBool printOne; /* TRUE if plugin should print one copy to default
|
||||
printer */
|
||||
void* platformPrint; /* Platform-specific printing info */
|
||||
} NPFullPrint;
|
||||
|
||||
typedef struct _NPEmbedPrint
|
||||
{
|
||||
NPWindow window;
|
||||
void* platformPrint; /* Platform-specific printing info */
|
||||
} NPEmbedPrint;
|
||||
|
||||
typedef struct _NPPrint
|
||||
{
|
||||
uint16_t mode; /* NP_FULL or NP_EMBED */
|
||||
union
|
||||
{
|
||||
NPFullPrint fullPrint; /* if mode is NP_FULL */
|
||||
NPEmbedPrint embedPrint; /* if mode is NP_EMBED */
|
||||
} print;
|
||||
} NPPrint;
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#ifndef NP_NO_CARBON
|
||||
typedef EventRecord NPEvent;
|
||||
#endif
|
||||
#elif defined(XP_SYMBIAN)
|
||||
typedef QEvent NPEvent;
|
||||
#elif defined(XP_WIN)
|
||||
typedef struct _NPEvent
|
||||
{
|
||||
uint16_t event;
|
||||
uintptr_t wParam;
|
||||
uintptr_t lParam;
|
||||
} NPEvent;
|
||||
#elif defined(XP_OS2)
|
||||
typedef struct _NPEvent
|
||||
{
|
||||
uint32_t event;
|
||||
uint32_t wParam;
|
||||
uint32_t lParam;
|
||||
} NPEvent;
|
||||
#elif defined(XP_UNIX) && defined(MOZ_X11)
|
||||
typedef XEvent NPEvent;
|
||||
#else
|
||||
typedef void* NPEvent;
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
typedef void* NPRegion;
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
typedef RgnHandle NPQDRegion;
|
||||
#endif
|
||||
typedef CGPathRef NPCGRegion;
|
||||
#elif defined(XP_WIN)
|
||||
typedef HRGN NPRegion;
|
||||
#elif defined(XP_UNIX) && defined(MOZ_X11)
|
||||
typedef Region NPRegion;
|
||||
#elif defined(XP_SYMBIAN)
|
||||
typedef QRegion* NPRegion;
|
||||
#else
|
||||
typedef void *NPRegion;
|
||||
#endif
|
||||
|
||||
typedef struct _NPNSString NPNSString;
|
||||
typedef struct _NPNSWindow NPNSWindow;
|
||||
typedef struct _NPNSMenu NPNSMenu;
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
typedef NPNSMenu NPMenu;
|
||||
#else
|
||||
typedef void *NPMenu;
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
NPCoordinateSpacePlugin = 1,
|
||||
NPCoordinateSpaceWindow,
|
||||
NPCoordinateSpaceFlippedWindow,
|
||||
NPCoordinateSpaceScreen,
|
||||
NPCoordinateSpaceFlippedScreen
|
||||
} NPCoordinateSpace;
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
typedef struct NP_Port
|
||||
{
|
||||
CGrafPtr port;
|
||||
int32_t portx; /* position inside the topmost window */
|
||||
int32_t porty;
|
||||
} NP_Port;
|
||||
#endif /* NP_NO_QUICKDRAW */
|
||||
|
||||
/*
|
||||
* NP_CGContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelCoreGraphics
|
||||
* as its drawing model.
|
||||
*/
|
||||
|
||||
typedef struct NP_CGContext
|
||||
{
|
||||
CGContextRef context;
|
||||
void *window; /* A WindowRef under the Carbon event model. */
|
||||
} NP_CGContext;
|
||||
|
||||
/*
|
||||
* NP_GLContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelOpenGL as its
|
||||
* drawing model.
|
||||
*/
|
||||
|
||||
typedef struct NP_GLContext
|
||||
{
|
||||
CGLContextObj context;
|
||||
#ifdef NP_NO_CARBON
|
||||
NPNSWindow *window;
|
||||
#else
|
||||
void *window; /* Can be either an NSWindow or a WindowRef depending on the event model */
|
||||
#endif
|
||||
} NP_GLContext;
|
||||
|
||||
typedef enum {
|
||||
NPCocoaEventDrawRect = 1,
|
||||
NPCocoaEventMouseDown,
|
||||
NPCocoaEventMouseUp,
|
||||
NPCocoaEventMouseMoved,
|
||||
NPCocoaEventMouseEntered,
|
||||
NPCocoaEventMouseExited,
|
||||
NPCocoaEventMouseDragged,
|
||||
NPCocoaEventKeyDown,
|
||||
NPCocoaEventKeyUp,
|
||||
NPCocoaEventFlagsChanged,
|
||||
NPCocoaEventFocusChanged,
|
||||
NPCocoaEventWindowFocusChanged,
|
||||
NPCocoaEventScrollWheel,
|
||||
NPCocoaEventTextInput
|
||||
} NPCocoaEventType;
|
||||
|
||||
typedef struct _NPCocoaEvent {
|
||||
NPCocoaEventType type;
|
||||
uint32_t version;
|
||||
union {
|
||||
struct {
|
||||
uint32_t modifierFlags;
|
||||
double pluginX;
|
||||
double pluginY;
|
||||
int32_t buttonNumber;
|
||||
int32_t clickCount;
|
||||
double deltaX;
|
||||
double deltaY;
|
||||
double deltaZ;
|
||||
} mouse;
|
||||
struct {
|
||||
uint32_t modifierFlags;
|
||||
NPNSString *characters;
|
||||
NPNSString *charactersIgnoringModifiers;
|
||||
NPBool isARepeat;
|
||||
uint16_t keyCode;
|
||||
} key;
|
||||
struct {
|
||||
CGContextRef context;
|
||||
double x;
|
||||
double y;
|
||||
double width;
|
||||
double height;
|
||||
} draw;
|
||||
struct {
|
||||
NPBool hasFocus;
|
||||
} focus;
|
||||
struct {
|
||||
NPNSString *text;
|
||||
} text;
|
||||
} data;
|
||||
} NPCocoaEvent;
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
/* Non-standard event types that can be passed to HandleEvent */
|
||||
enum NPEventType {
|
||||
NPEventType_GetFocusEvent = (osEvt + 16),
|
||||
NPEventType_LoseFocusEvent,
|
||||
NPEventType_AdjustCursorEvent,
|
||||
NPEventType_MenuCommandEvent,
|
||||
NPEventType_ClippingChangedEvent,
|
||||
NPEventType_ScrollingBeginsEvent = 1000,
|
||||
NPEventType_ScrollingEndsEvent
|
||||
};
|
||||
#endif /* NP_NO_CARBON */
|
||||
|
||||
#endif /* XP_MACOSX */
|
||||
|
||||
/*
|
||||
* Values for mode passed to NPP_New:
|
||||
*/
|
||||
#define NP_EMBED 1
|
||||
#define NP_FULL 2
|
||||
|
||||
/*
|
||||
* Values for stream type passed to NPP_NewStream:
|
||||
*/
|
||||
#define NP_NORMAL 1
|
||||
#define NP_SEEK 2
|
||||
#define NP_ASFILE 3
|
||||
#define NP_ASFILEONLY 4
|
||||
|
||||
#define NP_MAXREADY (((unsigned)(~0)<<1)>>1)
|
||||
|
||||
/*
|
||||
* Flags for NPP_ClearSiteData.
|
||||
*/
|
||||
#define NP_CLEAR_ALL 0
|
||||
#define NP_CLEAR_CACHE (1 << 0)
|
||||
|
||||
#if !defined(__LP64__)
|
||||
#if defined(XP_MACOSX)
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
#endif /* __LP64__ */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Error and Reason Code definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Values of type NPError:
|
||||
*/
|
||||
#define NPERR_BASE 0
|
||||
#define NPERR_NO_ERROR (NPERR_BASE + 0)
|
||||
#define NPERR_GENERIC_ERROR (NPERR_BASE + 1)
|
||||
#define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2)
|
||||
#define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3)
|
||||
#define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4)
|
||||
#define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5)
|
||||
#define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6)
|
||||
#define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7)
|
||||
#define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8)
|
||||
#define NPERR_INVALID_PARAM (NPERR_BASE + 9)
|
||||
#define NPERR_INVALID_URL (NPERR_BASE + 10)
|
||||
#define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11)
|
||||
#define NPERR_NO_DATA (NPERR_BASE + 12)
|
||||
#define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13)
|
||||
#define NPERR_TIME_RANGE_NOT_SUPPORTED (NPERR_BASE + 14)
|
||||
#define NPERR_MALFORMED_SITE (NPERR_BASE + 15)
|
||||
|
||||
/*
|
||||
* Values of type NPReason:
|
||||
*/
|
||||
#define NPRES_BASE 0
|
||||
#define NPRES_DONE (NPRES_BASE + 0)
|
||||
#define NPRES_NETWORK_ERR (NPRES_BASE + 1)
|
||||
#define NPRES_USER_BREAK (NPRES_BASE + 2)
|
||||
|
||||
/*
|
||||
* Don't use these obsolete error codes any more.
|
||||
*/
|
||||
#define NP_NOERR NP_NOERR_is_obsolete_use_NPERR_NO_ERROR
|
||||
#define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR
|
||||
#define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK
|
||||
|
||||
/*
|
||||
* Version feature information
|
||||
*/
|
||||
#define NPVERS_HAS_STREAMOUTPUT 8
|
||||
#define NPVERS_HAS_NOTIFICATION 9
|
||||
#define NPVERS_HAS_LIVECONNECT 9
|
||||
#define NPVERS_68K_HAS_LIVECONNECT 11
|
||||
#define NPVERS_HAS_WINDOWLESS 11
|
||||
#define NPVERS_HAS_XPCONNECT_SCRIPTING 13
|
||||
#define NPVERS_HAS_NPRUNTIME_SCRIPTING 14
|
||||
#define NPVERS_HAS_FORM_VALUES 15
|
||||
#define NPVERS_HAS_POPUPS_ENABLED_STATE 16
|
||||
#define NPVERS_HAS_RESPONSE_HEADERS 17
|
||||
#define NPVERS_HAS_NPOBJECT_ENUM 18
|
||||
#define NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL 19
|
||||
#define NPVERS_HAS_ALL_NETWORK_STREAMS 20
|
||||
#define NPVERS_HAS_URL_AND_AUTH_INFO 21
|
||||
#define NPVERS_HAS_PRIVATE_MODE 22
|
||||
#define NPVERS_MACOSX_HAS_COCOA_EVENTS 23
|
||||
#define NPVERS_HAS_ADVANCED_KEY_HANDLING 25
|
||||
#define NPVERS_HAS_URL_REDIRECT_HANDLING 26
|
||||
#define NPVERS_HAS_CLEAR_SITE_DATA 27
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Function Prototypes */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#if defined(__OS2__)
|
||||
#define NP_LOADDS _System
|
||||
#else
|
||||
#define NP_LOADDS
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* NPP_* functions are provided by the plugin and called by the navigator. */
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
const char* NPP_GetMIMEDescription(void);
|
||||
#endif
|
||||
|
||||
NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance,
|
||||
uint16_t mode, int16_t argc, char* argn[],
|
||||
char* argv[], NPSavedData* saved);
|
||||
NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save);
|
||||
NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window);
|
||||
NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type,
|
||||
NPStream* stream, NPBool seekable,
|
||||
uint16_t* stype);
|
||||
NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream,
|
||||
NPReason reason);
|
||||
int32_t NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream);
|
||||
int32_t NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32_t offset,
|
||||
int32_t len, void* buffer);
|
||||
void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream,
|
||||
const char* fname);
|
||||
void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint);
|
||||
int16_t NP_LOADDS NPP_HandleEvent(NPP instance, void* event);
|
||||
void NP_LOADDS NPP_URLNotify(NPP instance, const char* url,
|
||||
NPReason reason, void* notifyData);
|
||||
NPError NP_LOADDS NPP_GetValue(NPP instance, NPPVariable variable, void *value);
|
||||
NPError NP_LOADDS NPP_SetValue(NPP instance, NPNVariable variable, void *value);
|
||||
NPBool NP_LOADDS NPP_GotFocus(NPP instance, NPFocusDirection direction);
|
||||
void NP_LOADDS NPP_LostFocus(NPP instance);
|
||||
void NP_LOADDS NPP_URLRedirectNotify(NPP instance, const char* url, int32_t status, void* notifyData);
|
||||
NPError NP_LOADDS NPP_ClearSiteData(const char* site, uint64_t flags, uint64_t maxAge);
|
||||
char** NP_LOADDS NPP_GetSitesWithData(void);
|
||||
|
||||
/* NPN_* functions are provided by the navigator and called by the plugin. */
|
||||
void NP_LOADDS NPN_Version(int* plugin_major, int* plugin_minor,
|
||||
int* netscape_major, int* netscape_minor);
|
||||
NPError NP_LOADDS NPN_GetURLNotify(NPP instance, const char* url,
|
||||
const char* target, void* notifyData);
|
||||
NPError NP_LOADDS NPN_GetURL(NPP instance, const char* url,
|
||||
const char* target);
|
||||
NPError NP_LOADDS NPN_PostURLNotify(NPP instance, const char* url,
|
||||
const char* target, uint32_t len,
|
||||
const char* buf, NPBool file,
|
||||
void* notifyData);
|
||||
NPError NP_LOADDS NPN_PostURL(NPP instance, const char* url,
|
||||
const char* target, uint32_t len,
|
||||
const char* buf, NPBool file);
|
||||
NPError NP_LOADDS NPN_RequestRead(NPStream* stream, NPByteRange* rangeList);
|
||||
NPError NP_LOADDS NPN_NewStream(NPP instance, NPMIMEType type,
|
||||
const char* target, NPStream** stream);
|
||||
int32_t NP_LOADDS NPN_Write(NPP instance, NPStream* stream, int32_t len,
|
||||
void* buffer);
|
||||
NPError NP_LOADDS NPN_DestroyStream(NPP instance, NPStream* stream,
|
||||
NPReason reason);
|
||||
void NP_LOADDS NPN_Status(NPP instance, const char* message);
|
||||
const char* NP_LOADDS NPN_UserAgent(NPP instance);
|
||||
void* NP_LOADDS NPN_MemAlloc(uint32_t size);
|
||||
void NP_LOADDS NPN_MemFree(void* ptr);
|
||||
uint32_t NP_LOADDS NPN_MemFlush(uint32_t size);
|
||||
void NP_LOADDS NPN_ReloadPlugins(NPBool reloadPages);
|
||||
NPError NP_LOADDS NPN_GetValue(NPP instance, NPNVariable variable,
|
||||
void *value);
|
||||
NPError NP_LOADDS NPN_SetValue(NPP instance, NPPVariable variable,
|
||||
void *value);
|
||||
void NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect *invalidRect);
|
||||
void NP_LOADDS NPN_InvalidateRegion(NPP instance,
|
||||
NPRegion invalidRegion);
|
||||
void NP_LOADDS NPN_ForceRedraw(NPP instance);
|
||||
void NP_LOADDS NPN_PushPopupsEnabledState(NPP instance, NPBool enabled);
|
||||
void NP_LOADDS NPN_PopPopupsEnabledState(NPP instance);
|
||||
void NP_LOADDS NPN_PluginThreadAsyncCall(NPP instance,
|
||||
void (*func) (void *),
|
||||
void *userData);
|
||||
NPError NP_LOADDS NPN_GetValueForURL(NPP instance, NPNURLVariable variable,
|
||||
const char *url, char **value,
|
||||
uint32_t *len);
|
||||
NPError NP_LOADDS NPN_SetValueForURL(NPP instance, NPNURLVariable variable,
|
||||
const char *url, const char *value,
|
||||
uint32_t len);
|
||||
NPError NP_LOADDS NPN_GetAuthenticationInfo(NPP instance,
|
||||
const char *protocol,
|
||||
const char *host, int32_t port,
|
||||
const char *scheme,
|
||||
const char *realm,
|
||||
char **username, uint32_t *ulen,
|
||||
char **password,
|
||||
uint32_t *plen);
|
||||
uint32_t NP_LOADDS NPN_ScheduleTimer(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID));
|
||||
void NP_LOADDS NPN_UnscheduleTimer(NPP instance, uint32_t timerID);
|
||||
NPError NP_LOADDS NPN_PopUpContextMenu(NPP instance, NPMenu* menu);
|
||||
NPBool NP_LOADDS NPN_ConvertPoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
|
||||
NPBool NP_LOADDS NPN_HandleEvent(NPP instance, void *event, NPBool handled);
|
||||
NPBool NP_LOADDS NPN_UnfocusInstance(NPP instance, NPFocusDirection direction);
|
||||
void NP_LOADDS NPN_URLRedirectResponse(NPP instance, void* notifyData, NPBool allow);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* RC_INVOKED */
|
||||
#if defined(__OS2__)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#endif /* npapi_h_ */
|
322
browser-plugin/npapi/npfunctions.h
Normal file
322
browser-plugin/npapi/npfunctions.h
Normal file
@ -0,0 +1,322 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef npfunctions_h_
|
||||
#define npfunctions_h_
|
||||
|
||||
#ifdef __OS2__
|
||||
#pragma pack(1)
|
||||
#define NP_LOADDS _System
|
||||
#else
|
||||
#define NP_LOADDS
|
||||
#endif
|
||||
|
||||
#include "npapi.h"
|
||||
#include "npruntime.h"
|
||||
|
||||
typedef NPError (* NP_LOADDS NPP_NewProcPtr)(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved);
|
||||
typedef NPError (* NP_LOADDS NPP_DestroyProcPtr)(NPP instance, NPSavedData** save);
|
||||
typedef NPError (* NP_LOADDS NPP_SetWindowProcPtr)(NPP instance, NPWindow* window);
|
||||
typedef NPError (* NP_LOADDS NPP_NewStreamProcPtr)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype);
|
||||
typedef NPError (* NP_LOADDS NPP_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason);
|
||||
typedef int32_t (* NP_LOADDS NPP_WriteReadyProcPtr)(NPP instance, NPStream* stream);
|
||||
typedef int32_t (* NP_LOADDS NPP_WriteProcPtr)(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer);
|
||||
typedef void (* NP_LOADDS NPP_StreamAsFileProcPtr)(NPP instance, NPStream* stream, const char* fname);
|
||||
typedef void (* NP_LOADDS NPP_PrintProcPtr)(NPP instance, NPPrint* platformPrint);
|
||||
typedef int16_t (* NP_LOADDS NPP_HandleEventProcPtr)(NPP instance, void* event);
|
||||
typedef void (* NP_LOADDS NPP_URLNotifyProcPtr)(NPP instance, const char* url, NPReason reason, void* notifyData);
|
||||
/* Any NPObjects returned to the browser via NPP_GetValue should be retained
|
||||
by the plugin on the way out. The browser is responsible for releasing. */
|
||||
typedef NPError (* NP_LOADDS NPP_GetValueProcPtr)(NPP instance, NPPVariable variable, void *ret_value);
|
||||
typedef NPError (* NP_LOADDS NPP_SetValueProcPtr)(NPP instance, NPNVariable variable, void *value);
|
||||
typedef NPBool (* NP_LOADDS NPP_GotFocusPtr)(NPP instance, NPFocusDirection direction);
|
||||
typedef void (* NP_LOADDS NPP_LostFocusPtr)(NPP instance);
|
||||
typedef void (* NP_LOADDS NPP_URLRedirectNotifyPtr)(NPP instance, const char* url, int32_t status, void* notifyData);
|
||||
typedef NPError (* NP_LOADDS NPP_ClearSiteDataPtr)(const char* site, uint64_t flags, uint64_t maxAge);
|
||||
typedef char** (* NP_LOADDS NPP_GetSitesWithDataPtr)(void);
|
||||
|
||||
typedef NPError (*NPN_GetValueProcPtr)(NPP instance, NPNVariable variable, void *ret_value);
|
||||
typedef NPError (*NPN_SetValueProcPtr)(NPP instance, NPPVariable variable, void *value);
|
||||
typedef NPError (*NPN_GetURLNotifyProcPtr)(NPP instance, const char* url, const char* window, void* notifyData);
|
||||
typedef NPError (*NPN_PostURLNotifyProcPtr)(NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file, void* notifyData);
|
||||
typedef NPError (*NPN_GetURLProcPtr)(NPP instance, const char* url, const char* window);
|
||||
typedef NPError (*NPN_PostURLProcPtr)(NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file);
|
||||
typedef NPError (*NPN_RequestReadProcPtr)(NPStream* stream, NPByteRange* rangeList);
|
||||
typedef NPError (*NPN_NewStreamProcPtr)(NPP instance, NPMIMEType type, const char* window, NPStream** stream);
|
||||
typedef int32_t (*NPN_WriteProcPtr)(NPP instance, NPStream* stream, int32_t len, void* buffer);
|
||||
typedef NPError (*NPN_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason);
|
||||
typedef void (*NPN_StatusProcPtr)(NPP instance, const char* message);
|
||||
/* Browser manages the lifetime of the buffer returned by NPN_UserAgent, don't
|
||||
depend on it sticking around and don't free it. */
|
||||
typedef const char* (*NPN_UserAgentProcPtr)(NPP instance);
|
||||
typedef void* (*NPN_MemAllocProcPtr)(uint32_t size);
|
||||
typedef void (*NPN_MemFreeProcPtr)(void* ptr);
|
||||
typedef uint32_t (*NPN_MemFlushProcPtr)(uint32_t size);
|
||||
typedef void (*NPN_ReloadPluginsProcPtr)(NPBool reloadPages);
|
||||
typedef void* (*NPN_GetJavaEnvProcPtr)(void);
|
||||
typedef void* (*NPN_GetJavaPeerProcPtr)(NPP instance);
|
||||
typedef void (*NPN_InvalidateRectProcPtr)(NPP instance, NPRect *rect);
|
||||
typedef void (*NPN_InvalidateRegionProcPtr)(NPP instance, NPRegion region);
|
||||
typedef void (*NPN_ForceRedrawProcPtr)(NPP instance);
|
||||
typedef NPIdentifier (*NPN_GetStringIdentifierProcPtr)(const NPUTF8* name);
|
||||
typedef void (*NPN_GetStringIdentifiersProcPtr)(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers);
|
||||
typedef NPIdentifier (*NPN_GetIntIdentifierProcPtr)(int32_t intid);
|
||||
typedef bool (*NPN_IdentifierIsStringProcPtr)(NPIdentifier identifier);
|
||||
typedef NPUTF8* (*NPN_UTF8FromIdentifierProcPtr)(NPIdentifier identifier);
|
||||
typedef int32_t (*NPN_IntFromIdentifierProcPtr)(NPIdentifier identifier);
|
||||
typedef NPObject* (*NPN_CreateObjectProcPtr)(NPP npp, NPClass *aClass);
|
||||
typedef NPObject* (*NPN_RetainObjectProcPtr)(NPObject *obj);
|
||||
typedef void (*NPN_ReleaseObjectProcPtr)(NPObject *obj);
|
||||
typedef bool (*NPN_InvokeProcPtr)(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result);
|
||||
typedef bool (*NPN_InvokeDefaultProcPtr)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
|
||||
typedef bool (*NPN_EvaluateProcPtr)(NPP npp, NPObject *obj, NPString *script, NPVariant *result);
|
||||
typedef bool (*NPN_GetPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result);
|
||||
typedef bool (*NPN_SetPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName, const NPVariant *value);
|
||||
typedef bool (*NPN_RemovePropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName);
|
||||
typedef bool (*NPN_HasPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName);
|
||||
typedef bool (*NPN_HasMethodProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName);
|
||||
typedef void (*NPN_ReleaseVariantValueProcPtr)(NPVariant *variant);
|
||||
typedef void (*NPN_SetExceptionProcPtr)(NPObject *obj, const NPUTF8 *message);
|
||||
typedef void (*NPN_PushPopupsEnabledStateProcPtr)(NPP npp, NPBool enabled);
|
||||
typedef void (*NPN_PopPopupsEnabledStateProcPtr)(NPP npp);
|
||||
typedef bool (*NPN_EnumerateProcPtr)(NPP npp, NPObject *obj, NPIdentifier **identifier, uint32_t *count);
|
||||
typedef void (*NPN_PluginThreadAsyncCallProcPtr)(NPP instance, void (*func)(void *), void *userData);
|
||||
typedef bool (*NPN_ConstructProcPtr)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
|
||||
typedef NPError (*NPN_GetValueForURLPtr)(NPP npp, NPNURLVariable variable, const char *url, char **value, uint32_t *len);
|
||||
typedef NPError (*NPN_SetValueForURLPtr)(NPP npp, NPNURLVariable variable, const char *url, const char *value, uint32_t len);
|
||||
typedef NPError (*NPN_GetAuthenticationInfoPtr)(NPP npp, const char *protocol, const char *host, int32_t port, const char *scheme, const char *realm, char **username, uint32_t *ulen, char **password, uint32_t *plen);
|
||||
typedef uint32_t (*NPN_ScheduleTimerPtr)(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID));
|
||||
typedef void (*NPN_UnscheduleTimerPtr)(NPP instance, uint32_t timerID);
|
||||
typedef NPError (*NPN_PopUpContextMenuPtr)(NPP instance, NPMenu* menu);
|
||||
typedef NPBool (*NPN_ConvertPointPtr)(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
|
||||
typedef NPBool (*NPN_HandleEventPtr)(NPP instance, void *event, NPBool handled);
|
||||
typedef NPBool (*NPN_UnfocusInstancePtr)(NPP instance, NPFocusDirection direction);
|
||||
typedef void (*NPN_URLRedirectResponsePtr)(NPP instance, void* notifyData, NPBool allow);
|
||||
|
||||
typedef struct _NPPluginFuncs {
|
||||
uint16_t size;
|
||||
uint16_t version;
|
||||
NPP_NewProcPtr newp;
|
||||
NPP_DestroyProcPtr destroy;
|
||||
NPP_SetWindowProcPtr setwindow;
|
||||
NPP_NewStreamProcPtr newstream;
|
||||
NPP_DestroyStreamProcPtr destroystream;
|
||||
NPP_StreamAsFileProcPtr asfile;
|
||||
NPP_WriteReadyProcPtr writeready;
|
||||
NPP_WriteProcPtr write;
|
||||
NPP_PrintProcPtr print;
|
||||
NPP_HandleEventProcPtr event;
|
||||
NPP_URLNotifyProcPtr urlnotify;
|
||||
void* javaClass;
|
||||
NPP_GetValueProcPtr getvalue;
|
||||
NPP_SetValueProcPtr setvalue;
|
||||
NPP_GotFocusPtr gotfocus;
|
||||
NPP_LostFocusPtr lostfocus;
|
||||
NPP_URLRedirectNotifyPtr urlredirectnotify;
|
||||
NPP_ClearSiteDataPtr clearsitedata;
|
||||
NPP_GetSitesWithDataPtr getsiteswithdata;
|
||||
} NPPluginFuncs;
|
||||
|
||||
typedef struct _NPNetscapeFuncs {
|
||||
uint16_t size;
|
||||
uint16_t version;
|
||||
NPN_GetURLProcPtr geturl;
|
||||
NPN_PostURLProcPtr posturl;
|
||||
NPN_RequestReadProcPtr requestread;
|
||||
NPN_NewStreamProcPtr newstream;
|
||||
NPN_WriteProcPtr write;
|
||||
NPN_DestroyStreamProcPtr destroystream;
|
||||
NPN_StatusProcPtr status;
|
||||
NPN_UserAgentProcPtr uagent;
|
||||
NPN_MemAllocProcPtr memalloc;
|
||||
NPN_MemFreeProcPtr memfree;
|
||||
NPN_MemFlushProcPtr memflush;
|
||||
NPN_ReloadPluginsProcPtr reloadplugins;
|
||||
NPN_GetJavaEnvProcPtr getJavaEnv;
|
||||
NPN_GetJavaPeerProcPtr getJavaPeer;
|
||||
NPN_GetURLNotifyProcPtr geturlnotify;
|
||||
NPN_PostURLNotifyProcPtr posturlnotify;
|
||||
NPN_GetValueProcPtr getvalue;
|
||||
NPN_SetValueProcPtr setvalue;
|
||||
NPN_InvalidateRectProcPtr invalidaterect;
|
||||
NPN_InvalidateRegionProcPtr invalidateregion;
|
||||
NPN_ForceRedrawProcPtr forceredraw;
|
||||
NPN_GetStringIdentifierProcPtr getstringidentifier;
|
||||
NPN_GetStringIdentifiersProcPtr getstringidentifiers;
|
||||
NPN_GetIntIdentifierProcPtr getintidentifier;
|
||||
NPN_IdentifierIsStringProcPtr identifierisstring;
|
||||
NPN_UTF8FromIdentifierProcPtr utf8fromidentifier;
|
||||
NPN_IntFromIdentifierProcPtr intfromidentifier;
|
||||
NPN_CreateObjectProcPtr createobject;
|
||||
NPN_RetainObjectProcPtr retainobject;
|
||||
NPN_ReleaseObjectProcPtr releaseobject;
|
||||
NPN_InvokeProcPtr invoke;
|
||||
NPN_InvokeDefaultProcPtr invokeDefault;
|
||||
NPN_EvaluateProcPtr evaluate;
|
||||
NPN_GetPropertyProcPtr getproperty;
|
||||
NPN_SetPropertyProcPtr setproperty;
|
||||
NPN_RemovePropertyProcPtr removeproperty;
|
||||
NPN_HasPropertyProcPtr hasproperty;
|
||||
NPN_HasMethodProcPtr hasmethod;
|
||||
NPN_ReleaseVariantValueProcPtr releasevariantvalue;
|
||||
NPN_SetExceptionProcPtr setexception;
|
||||
NPN_PushPopupsEnabledStateProcPtr pushpopupsenabledstate;
|
||||
NPN_PopPopupsEnabledStateProcPtr poppopupsenabledstate;
|
||||
NPN_EnumerateProcPtr enumerate;
|
||||
NPN_PluginThreadAsyncCallProcPtr pluginthreadasynccall;
|
||||
NPN_ConstructProcPtr construct;
|
||||
NPN_GetValueForURLPtr getvalueforurl;
|
||||
NPN_SetValueForURLPtr setvalueforurl;
|
||||
NPN_GetAuthenticationInfoPtr getauthenticationinfo;
|
||||
NPN_ScheduleTimerPtr scheduletimer;
|
||||
NPN_UnscheduleTimerPtr unscheduletimer;
|
||||
NPN_PopUpContextMenuPtr popupcontextmenu;
|
||||
NPN_ConvertPointPtr convertpoint;
|
||||
NPN_HandleEventPtr handleevent;
|
||||
NPN_UnfocusInstancePtr unfocusinstance;
|
||||
NPN_URLRedirectResponsePtr urlredirectresponse;
|
||||
} NPNetscapeFuncs;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
/*
|
||||
* Mac OS X version(s) of NP_GetMIMEDescription(const char *)
|
||||
* These can be called to retreive MIME information from the plugin dynamically
|
||||
*
|
||||
* Note: For compatibility with Quicktime, BPSupportedMIMEtypes is another way
|
||||
* to get mime info from the plugin only on OSX and may not be supported
|
||||
* in furture version -- use NP_GetMIMEDescription instead
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kBPSupportedMIMETypesStructVers_1 = 1
|
||||
};
|
||||
typedef struct _BPSupportedMIMETypes
|
||||
{
|
||||
SInt32 structVersion; /* struct version */
|
||||
Handle typeStrings; /* STR# formated handle, allocated by plug-in */
|
||||
Handle infoStrings; /* STR# formated handle, allocated by plug-in */
|
||||
} BPSupportedMIMETypes;
|
||||
OSErr BP_GetSupportedMIMETypes(BPSupportedMIMETypes *mimeInfo, UInt32 flags);
|
||||
#define NP_GETMIMEDESCRIPTION_NAME "NP_GetMIMEDescription"
|
||||
typedef const char* (*NP_GetMIMEDescriptionProcPtr)(void);
|
||||
typedef OSErr (*BP_GetSupportedMIMETypesProcPtr)(BPSupportedMIMETypes*, UInt32);
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define OSCALL WINAPI
|
||||
#else
|
||||
#if defined(__OS2__)
|
||||
#define OSCALL _System
|
||||
#else
|
||||
#define OSCALL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
/* GCC 3.3 and later support the visibility attribute. */
|
||||
#if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3))
|
||||
#define NP_VISIBILITY_DEFAULT __attribute__((visibility("default")))
|
||||
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
#define NP_VISIBILITY_DEFAULT __global
|
||||
#else
|
||||
#define NP_VISIBILITY_DEFAULT
|
||||
#endif
|
||||
#define NP_EXPORT(__type) NP_VISIBILITY_DEFAULT __type
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined (__OS2__)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* plugin meta member functions */
|
||||
#if defined(__OS2__)
|
||||
typedef struct _NPPluginData { /* Alternate OS2 Plugin interface */
|
||||
char *pMimeTypes;
|
||||
char *pFileExtents;
|
||||
char *pFileOpenTemplate;
|
||||
char *pProductName;
|
||||
char *pProductDescription;
|
||||
unsigned long dwProductVersionMS;
|
||||
unsigned long dwProductVersionLS;
|
||||
} NPPluginData;
|
||||
typedef NPError (*NP_GetPluginDataFunc)(NPPluginData*);
|
||||
NPError OSCALL NP_GetPluginData(NPPluginData * pPluginData);
|
||||
#endif
|
||||
typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*);
|
||||
NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs);
|
||||
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*);
|
||||
NPError OSCALL NP_Initialize(NPNetscapeFuncs* bFuncs);
|
||||
typedef NPError (*NP_ShutdownFunc)(void);
|
||||
NPError OSCALL NP_Shutdown(void);
|
||||
typedef const char* (*NP_GetMIMEDescriptionFunc)(void);
|
||||
const char* NP_GetMIMEDescription(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__OS2__)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef char* (*NP_GetPluginVersionFunc)(void);
|
||||
NP_EXPORT(char*) NP_GetPluginVersion(void);
|
||||
typedef const char* (*NP_GetMIMEDescriptionFunc)(void);
|
||||
NP_EXPORT(const char*) NP_GetMIMEDescription(void);
|
||||
#ifdef XP_MACOSX
|
||||
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*);
|
||||
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs);
|
||||
typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*);
|
||||
NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs);
|
||||
#else
|
||||
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*, NPPluginFuncs*);
|
||||
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs);
|
||||
#endif
|
||||
typedef NPError (*NP_ShutdownFunc)(void);
|
||||
NP_EXPORT(NPError) NP_Shutdown(void);
|
||||
typedef NPError (*NP_GetValueFunc)(void *, NPPVariable, void *);
|
||||
NP_EXPORT(NPError) NP_GetValue(void *future, NPPVariable aVariable, void *aValue);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* npfunctions_h_ */
|
393
browser-plugin/npapi/npruntime.h
Normal file
393
browser-plugin/npapi/npruntime.h
Normal file
@ -0,0 +1,393 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* Copyright (c) 2004, Apple Computer, Inc. and The Mozilla Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of Apple Computer, Inc. ("Apple") or The Mozilla
|
||||
* Foundation ("Mozilla") nor the names of their contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR
|
||||
* THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef _NP_RUNTIME_H_
|
||||
#define _NP_RUNTIME_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "nptypes.h"
|
||||
|
||||
/*
|
||||
This API is used to facilitate binding code written in C to script
|
||||
objects. The API in this header does not assume the presence of a
|
||||
user agent. That is, it can be used to bind C code to scripting
|
||||
environments outside of the context of a user agent.
|
||||
|
||||
However, the normal use of the this API is in the context of a
|
||||
scripting environment running in a browser or other user agent.
|
||||
In particular it is used to support the extended Netscape
|
||||
script-ability API for plugins (NP-SAP). NP-SAP is an extension
|
||||
of the Netscape plugin API. As such we have adopted the use of
|
||||
the "NP" prefix for this API.
|
||||
|
||||
The following NP{N|P}Variables were added to the Netscape plugin
|
||||
API (in npapi.h):
|
||||
|
||||
NPNVWindowNPObject
|
||||
NPNVPluginElementNPObject
|
||||
NPPVpluginScriptableNPObject
|
||||
|
||||
These variables are exposed through NPN_GetValue() and
|
||||
NPP_GetValue() (respectively) and are used to establish the
|
||||
initial binding between the user agent and native code. The DOM
|
||||
objects in the user agent can be examined and manipulated using
|
||||
the NPN_ functions that operate on NPObjects described in this
|
||||
header.
|
||||
|
||||
To the extent possible the assumptions about the scripting
|
||||
language used by the scripting environment have been minimized.
|
||||
*/
|
||||
|
||||
#define NP_BEGIN_MACRO do {
|
||||
#define NP_END_MACRO } while (0)
|
||||
|
||||
/*
|
||||
Objects (non-primitive data) passed between 'C' and script is
|
||||
always wrapped in an NPObject. The 'interface' of an NPObject is
|
||||
described by an NPClass.
|
||||
*/
|
||||
typedef struct NPObject NPObject;
|
||||
typedef struct NPClass NPClass;
|
||||
|
||||
typedef char NPUTF8;
|
||||
typedef struct _NPString {
|
||||
const NPUTF8 *UTF8Characters;
|
||||
uint32_t UTF8Length;
|
||||
} NPString;
|
||||
|
||||
typedef enum {
|
||||
NPVariantType_Void,
|
||||
NPVariantType_Null,
|
||||
NPVariantType_Bool,
|
||||
NPVariantType_Int32,
|
||||
NPVariantType_Double,
|
||||
NPVariantType_String,
|
||||
NPVariantType_Object
|
||||
} NPVariantType;
|
||||
|
||||
typedef struct _NPVariant {
|
||||
NPVariantType type;
|
||||
union {
|
||||
bool boolValue;
|
||||
int32_t intValue;
|
||||
double doubleValue;
|
||||
NPString stringValue;
|
||||
NPObject *objectValue;
|
||||
} value;
|
||||
} NPVariant;
|
||||
|
||||
/*
|
||||
NPN_ReleaseVariantValue is called on all 'out' parameters
|
||||
references. Specifically it is to be called on variants that own
|
||||
their value, as is the case with all non-const NPVariant*
|
||||
arguments after a successful call to any methods (except this one)
|
||||
in this API.
|
||||
|
||||
After calling NPN_ReleaseVariantValue, the type of the variant
|
||||
will be NPVariantType_Void.
|
||||
*/
|
||||
void NPN_ReleaseVariantValue(NPVariant *variant);
|
||||
|
||||
#define NPVARIANT_IS_VOID(_v) ((_v).type == NPVariantType_Void)
|
||||
#define NPVARIANT_IS_NULL(_v) ((_v).type == NPVariantType_Null)
|
||||
#define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool)
|
||||
#define NPVARIANT_IS_INT32(_v) ((_v).type == NPVariantType_Int32)
|
||||
#define NPVARIANT_IS_DOUBLE(_v) ((_v).type == NPVariantType_Double)
|
||||
#define NPVARIANT_IS_STRING(_v) ((_v).type == NPVariantType_String)
|
||||
#define NPVARIANT_IS_OBJECT(_v) ((_v).type == NPVariantType_Object)
|
||||
|
||||
#define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue)
|
||||
#define NPVARIANT_TO_INT32(_v) ((_v).value.intValue)
|
||||
#define NPVARIANT_TO_DOUBLE(_v) ((_v).value.doubleValue)
|
||||
#define NPVARIANT_TO_STRING(_v) ((_v).value.stringValue)
|
||||
#define NPVARIANT_TO_OBJECT(_v) ((_v).value.objectValue)
|
||||
|
||||
#define VOID_TO_NPVARIANT(_v) \
|
||||
NP_BEGIN_MACRO \
|
||||
(_v).type = NPVariantType_Void; \
|
||||
(_v).value.objectValue = NULL; \
|
||||
NP_END_MACRO
|
||||
|
||||
#define NULL_TO_NPVARIANT(_v) \
|
||||
NP_BEGIN_MACRO \
|
||||
(_v).type = NPVariantType_Null; \
|
||||
(_v).value.objectValue = NULL; \
|
||||
NP_END_MACRO
|
||||
|
||||
#define BOOLEAN_TO_NPVARIANT(_val, _v) \
|
||||
NP_BEGIN_MACRO \
|
||||
(_v).type = NPVariantType_Bool; \
|
||||
(_v).value.boolValue = !!(_val); \
|
||||
NP_END_MACRO
|
||||
|
||||
#define INT32_TO_NPVARIANT(_val, _v) \
|
||||
NP_BEGIN_MACRO \
|
||||
(_v).type = NPVariantType_Int32; \
|
||||
(_v).value.intValue = _val; \
|
||||
NP_END_MACRO
|
||||
|
||||
#define DOUBLE_TO_NPVARIANT(_val, _v) \
|
||||
NP_BEGIN_MACRO \
|
||||
(_v).type = NPVariantType_Double; \
|
||||
(_v).value.doubleValue = _val; \
|
||||
NP_END_MACRO
|
||||
|
||||
#define STRINGZ_TO_NPVARIANT(_val, _v) \
|
||||
NP_BEGIN_MACRO \
|
||||
(_v).type = NPVariantType_String; \
|
||||
NPString str = { _val, (uint32_t)(strlen(_val)) }; \
|
||||
(_v).value.stringValue = str; \
|
||||
NP_END_MACRO
|
||||
|
||||
#define STRINGN_TO_NPVARIANT(_val, _len, _v) \
|
||||
NP_BEGIN_MACRO \
|
||||
(_v).type = NPVariantType_String; \
|
||||
NPString str = { _val, (uint32_t)(_len) }; \
|
||||
(_v).value.stringValue = str; \
|
||||
NP_END_MACRO
|
||||
|
||||
#define OBJECT_TO_NPVARIANT(_val, _v) \
|
||||
NP_BEGIN_MACRO \
|
||||
(_v).type = NPVariantType_Object; \
|
||||
(_v).value.objectValue = _val; \
|
||||
NP_END_MACRO
|
||||
|
||||
|
||||
/*
|
||||
Type mappings (JavaScript types have been used for illustration
|
||||
purposes):
|
||||
|
||||
JavaScript to C (NPVariant with type:)
|
||||
undefined NPVariantType_Void
|
||||
null NPVariantType_Null
|
||||
Boolean NPVariantType_Bool
|
||||
Number NPVariantType_Double or NPVariantType_Int32
|
||||
String NPVariantType_String
|
||||
Object NPVariantType_Object
|
||||
|
||||
C (NPVariant with type:) to JavaScript
|
||||
NPVariantType_Void undefined
|
||||
NPVariantType_Null null
|
||||
NPVariantType_Bool Boolean
|
||||
NPVariantType_Int32 Number
|
||||
NPVariantType_Double Number
|
||||
NPVariantType_String String
|
||||
NPVariantType_Object Object
|
||||
*/
|
||||
|
||||
typedef void *NPIdentifier;
|
||||
|
||||
/*
|
||||
NPObjects have methods and properties. Methods and properties are
|
||||
identified with NPIdentifiers. These identifiers may be reflected
|
||||
in script. NPIdentifiers can be either strings or integers, IOW,
|
||||
methods and properties can be identified by either strings or
|
||||
integers (i.e. foo["bar"] vs foo[1]). NPIdentifiers can be
|
||||
compared using ==. In case of any errors, the requested
|
||||
NPIdentifier(s) will be NULL. NPIdentifier lifetime is controlled
|
||||
by the browser. Plugins do not need to worry about memory management
|
||||
with regards to NPIdentifiers.
|
||||
*/
|
||||
NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name);
|
||||
void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount,
|
||||
NPIdentifier *identifiers);
|
||||
NPIdentifier NPN_GetIntIdentifier(int32_t intid);
|
||||
bool NPN_IdentifierIsString(NPIdentifier identifier);
|
||||
|
||||
/*
|
||||
The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed.
|
||||
*/
|
||||
NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier);
|
||||
|
||||
/*
|
||||
Get the integer represented by identifier. If identifier is not an
|
||||
integer identifier, the behaviour is undefined.
|
||||
*/
|
||||
int32_t NPN_IntFromIdentifier(NPIdentifier identifier);
|
||||
|
||||
/*
|
||||
NPObject behavior is implemented using the following set of
|
||||
callback functions.
|
||||
|
||||
The NPVariant *result argument of these functions (where
|
||||
applicable) should be released using NPN_ReleaseVariantValue().
|
||||
*/
|
||||
typedef NPObject *(*NPAllocateFunctionPtr)(NPP npp, NPClass *aClass);
|
||||
typedef void (*NPDeallocateFunctionPtr)(NPObject *npobj);
|
||||
typedef void (*NPInvalidateFunctionPtr)(NPObject *npobj);
|
||||
typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name);
|
||||
typedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name,
|
||||
const NPVariant *args, uint32_t argCount,
|
||||
NPVariant *result);
|
||||
typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj,
|
||||
const NPVariant *args,
|
||||
uint32_t argCount,
|
||||
NPVariant *result);
|
||||
typedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name);
|
||||
typedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
|
||||
NPVariant *result);
|
||||
typedef bool (*NPSetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,
|
||||
const NPVariant *value);
|
||||
typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj,
|
||||
NPIdentifier name);
|
||||
typedef bool (*NPEnumerationFunctionPtr)(NPObject *npobj, NPIdentifier **value,
|
||||
uint32_t *count);
|
||||
typedef bool (*NPConstructFunctionPtr)(NPObject *npobj,
|
||||
const NPVariant *args,
|
||||
uint32_t argCount,
|
||||
NPVariant *result);
|
||||
|
||||
/*
|
||||
NPObjects returned by create, retain, invoke, and getProperty pass
|
||||
a reference count to the caller. That is, the callee adds a
|
||||
reference count which passes to the caller. It is the caller's
|
||||
responsibility to release the returned object.
|
||||
|
||||
NPInvokeFunctionPtr function may return 0 to indicate a void
|
||||
result.
|
||||
|
||||
NPInvalidateFunctionPtr is called by the scripting environment
|
||||
when the native code is shutdown. Any attempt to message a
|
||||
NPObject instance after the invalidate callback has been
|
||||
called will result in undefined behavior, even if the native code
|
||||
is still retaining those NPObject instances. (The runtime
|
||||
will typically return immediately, with 0 or NULL, from an attempt
|
||||
to dispatch to a NPObject, but this behavior should not be
|
||||
depended upon.)
|
||||
|
||||
The NPEnumerationFunctionPtr function may pass an array of
|
||||
NPIdentifiers back to the caller. The callee allocs the memory of
|
||||
the array using NPN_MemAlloc(), and it's the caller's responsibility
|
||||
to release it using NPN_MemFree().
|
||||
*/
|
||||
struct NPClass
|
||||
{
|
||||
uint32_t structVersion;
|
||||
NPAllocateFunctionPtr allocate;
|
||||
NPDeallocateFunctionPtr deallocate;
|
||||
NPInvalidateFunctionPtr invalidate;
|
||||
NPHasMethodFunctionPtr hasMethod;
|
||||
NPInvokeFunctionPtr invoke;
|
||||
NPInvokeDefaultFunctionPtr invokeDefault;
|
||||
NPHasPropertyFunctionPtr hasProperty;
|
||||
NPGetPropertyFunctionPtr getProperty;
|
||||
NPSetPropertyFunctionPtr setProperty;
|
||||
NPRemovePropertyFunctionPtr removeProperty;
|
||||
NPEnumerationFunctionPtr enumerate;
|
||||
NPConstructFunctionPtr construct;
|
||||
};
|
||||
|
||||
#define NP_CLASS_STRUCT_VERSION 3
|
||||
|
||||
#define NP_CLASS_STRUCT_VERSION_ENUM 2
|
||||
#define NP_CLASS_STRUCT_VERSION_CTOR 3
|
||||
|
||||
#define NP_CLASS_STRUCT_VERSION_HAS_ENUM(npclass) \
|
||||
((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM)
|
||||
|
||||
#define NP_CLASS_STRUCT_VERSION_HAS_CTOR(npclass) \
|
||||
((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR)
|
||||
|
||||
struct NPObject {
|
||||
NPClass *_class;
|
||||
uint32_t referenceCount;
|
||||
/*
|
||||
* Additional space may be allocated here by types of NPObjects
|
||||
*/
|
||||
};
|
||||
|
||||
/*
|
||||
If the class has an allocate function, NPN_CreateObject invokes
|
||||
that function, otherwise a NPObject is allocated and
|
||||
returned. This method will initialize the referenceCount member of
|
||||
the NPObject to 1.
|
||||
*/
|
||||
NPObject *NPN_CreateObject(NPP npp, NPClass *aClass);
|
||||
|
||||
/*
|
||||
Increment the NPObject's reference count.
|
||||
*/
|
||||
NPObject *NPN_RetainObject(NPObject *npobj);
|
||||
|
||||
/*
|
||||
Decremented the NPObject's reference count. If the reference
|
||||
count goes to zero, the class's destroy function is invoke if
|
||||
specified, otherwise the object is freed directly.
|
||||
*/
|
||||
void NPN_ReleaseObject(NPObject *npobj);
|
||||
|
||||
/*
|
||||
Functions to access script objects represented by NPObject.
|
||||
|
||||
Calls to script objects are synchronous. If a function returns a
|
||||
value, it will be supplied via the result NPVariant
|
||||
argument. Successful calls will return true, false will be
|
||||
returned in case of an error.
|
||||
|
||||
Calls made from plugin code to script must be made from the thread
|
||||
on which the plugin was initialized.
|
||||
*/
|
||||
|
||||
bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName,
|
||||
const NPVariant *args, uint32_t argCount, NPVariant *result);
|
||||
bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args,
|
||||
uint32_t argCount, NPVariant *result);
|
||||
bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script,
|
||||
NPVariant *result);
|
||||
bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
|
||||
NPVariant *result);
|
||||
bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,
|
||||
const NPVariant *value);
|
||||
bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
|
||||
bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
|
||||
bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName);
|
||||
bool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier,
|
||||
uint32_t *count);
|
||||
bool NPN_Construct(NPP npp, NPObject *npobj, const NPVariant *args,
|
||||
uint32_t argCount, NPVariant *result);
|
||||
|
||||
/*
|
||||
NPN_SetException may be called to trigger a script exception upon
|
||||
return from entry points into NPObjects. Typical usage:
|
||||
|
||||
NPN_SetException (npobj, message);
|
||||
*/
|
||||
void NPN_SetException(NPObject *npobj, const NPUTF8 *message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
121
browser-plugin/npapi/nptypes.h
Normal file
121
browser-plugin/npapi/nptypes.h
Normal file
@ -0,0 +1,121 @@
|
||||
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Johnny Stenback <jst@mozilla.org> (Original author)
|
||||
*
|
||||
* 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
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nptypes_h_
|
||||
#define nptypes_h_
|
||||
|
||||
/*
|
||||
* Header file for ensuring that C99 types ([u]int32_t, [u]int64_t and bool) and
|
||||
* true/false macros are available.
|
||||
*/
|
||||
|
||||
#if defined(WIN32) || defined(OS2)
|
||||
/*
|
||||
* Win32 and OS/2 don't know C99, so define [u]int_16/32/64 here. The bool
|
||||
* is predefined tho, both in C and C++.
|
||||
*/
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#elif defined(_AIX) || defined(__sun) || defined(__osf__) || defined(IRIX) || defined(HPUX)
|
||||
/*
|
||||
* AIX and SunOS ship a inttypes.h header that defines [u]int32_t,
|
||||
* but not bool for C.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef int bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
#elif defined(bsdi) || defined(FREEBSD) || defined(OPENBSD)
|
||||
/*
|
||||
* BSD/OS, FreeBSD, and OpenBSD ship sys/types.h that define int32_t and
|
||||
* u_int32_t.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* BSD/OS ships no header that defines uint32_t, nor bool (for C)
|
||||
*/
|
||||
#if defined(bsdi)
|
||||
typedef u_int32_t uint32_t;
|
||||
typedef u_int64_t uint64_t;
|
||||
|
||||
#if !defined(__cplusplus)
|
||||
typedef int bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
#else
|
||||
/*
|
||||
* FreeBSD and OpenBSD define uint32_t and bool.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
#elif defined(BEOS)
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
/*
|
||||
* For those that ship a standard C99 stdint.h header file, include
|
||||
* it. Can't do the same for stdbool.h tho, since some systems ship
|
||||
* with a stdbool.h file that doesn't compile!
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
#if !defined(__GNUC__) || (__GNUC__ > 2 || __GNUC_MINOR__ > 95)
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
/*
|
||||
* GCC 2.91 can't deal with a typedef for bool, but a #define
|
||||
* works.
|
||||
*/
|
||||
#define bool int
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* nptypes_h_ */
|
37
configure.ac
37
configure.ac
@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.63)
|
||||
AC_INIT([gnome-shell],[3.1.90.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
AC_INIT([gnome-shell],[3.1.92],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||
@ -9,8 +9,8 @@ AC_CONFIG_AUX_DIR([config])
|
||||
AC_SUBST([PACKAGE_NAME], ["$PACKAGE_NAME"])
|
||||
AC_SUBST([PACKAGE_VERSION], ["$PACKAGE_VERSION"])
|
||||
|
||||
AM_INIT_AUTOMAKE([1.10 dist-bzip2 no-dist-gzip foreign])
|
||||
AM_MAINTAINER_MODE
|
||||
AM_INIT_AUTOMAKE([1.10 dist-xz no-dist-gzip foreign])
|
||||
AM_MAINTAINER_MODE([enable])
|
||||
|
||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
||||
|
||||
@ -102,6 +102,8 @@ PKG_CHECK_MODULES(SHELL_PERF_HELPER, gtk+-3.0 gio-2.0)
|
||||
|
||||
PKG_CHECK_MODULES(SHELL_HOTPLUG_SNIFFER, gio-2.0 gdk-pixbuf-2.0)
|
||||
|
||||
PKG_CHECK_MODULES(BROWSER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION json-glib-1.0 >= 0.13.2)
|
||||
|
||||
GJS_VERSION=`$PKG_CONFIG --modversion gjs-internals-1.0`
|
||||
AC_DEFINE_UNQUOTED([GJS_VERSION], ["$GJS_VERSION"], [The version of GJS we're linking to])
|
||||
AC_SUBST([GJS_VERSION], ["$GJS_VERSION"])
|
||||
@ -208,12 +210,41 @@ AC_ARG_ENABLE(jhbuild-wrapper-script,
|
||||
AS_HELP_STRING([--jhbuild-wrapper-script=yes],[Make "gnome-shell" script work for jhbuild]),,enable_jhbuild_wrapper_script=no)
|
||||
AM_CONDITIONAL(USE_JHBUILD_WRAPPER_SCRIPT, test "x$enable_jhbuild_wrapper_script" = xyes)
|
||||
|
||||
AC_MSG_CHECKING([location of system Certificate Authority list])
|
||||
AC_ARG_WITH(ca-certificates,
|
||||
[AC_HELP_STRING([--with-ca-certificates=@<:@path@:>@],
|
||||
[path to system Certificate Authority list])])
|
||||
|
||||
if test "$with_ca_certificates" = "no"; then
|
||||
AC_MSG_RESULT([disabled])
|
||||
else
|
||||
if test -z "$with_ca_certificates"; then
|
||||
for f in /etc/pki/tls/certs/ca-bundle.crt \
|
||||
/etc/ssl/certs/ca-certificates.crt; do
|
||||
if test -f "$f"; then
|
||||
with_ca_certificates="$f"
|
||||
fi
|
||||
done
|
||||
if test -z "$with_ca_certificates"; then
|
||||
AC_MSG_ERROR([could not find. Use --with-ca-certificates=path to set, or --without-ca-certificates to disable])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT($with_ca_certificates)
|
||||
AC_DEFINE_UNQUOTED(SHELL_SYSTEM_CA_FILE, ["$with_ca_certificates"], [The system TLS CA list])
|
||||
fi
|
||||
AC_SUBST(SHELL_SYSTEM_CA_FILE,["$with_ca_certificates"])
|
||||
|
||||
BROWSER_PLUGIN_DIR="${BROWSER_PLUGIN_DIR:-"\${libdir}/mozilla/plugins"}"
|
||||
AC_ARG_VAR([BROWSER_PLUGIN_DIR],[Where to install the plugin to])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
data/Makefile
|
||||
js/Makefile
|
||||
js/misc/config.js
|
||||
src/Makefile
|
||||
browser-plugin/Makefile
|
||||
tests/Makefile
|
||||
po/Makefile.in
|
||||
man/Makefile
|
||||
|
@ -31,7 +31,7 @@
|
||||
</_description>
|
||||
</key>
|
||||
<key name="favorite-apps" type="as">
|
||||
<default>[ 'firefox.desktop', 'evolution.desktop', 'empathy.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'libreoffice-writer.desktop', 'nautilus.desktop', 'gnome-documents.desktop' ]</default>
|
||||
<default>[ 'epiphany.desktop', 'evolution.desktop', 'empathy.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'libreoffice-writer.desktop', 'nautilus.desktop', 'gnome-documents.desktop' ]</default>
|
||||
<_summary>List of desktop file IDs for favorite applications</_summary>
|
||||
<_description>
|
||||
The applications corresponding to these identifiers
|
||||
@ -69,13 +69,6 @@
|
||||
|
||||
<schema id="org.gnome.shell.keyboard" path="/org/gnome/shell/keyboard/"
|
||||
gettext-domain="@GETTEXT_PACKAGE@">
|
||||
<key name="show-keyboard" type="b">
|
||||
<default>false</default>
|
||||
<_summary>Show the onscreen keyboard</_summary>
|
||||
<_description>
|
||||
If true, display onscreen keyboard.
|
||||
</_description>
|
||||
</key>
|
||||
<key name="keyboard-type" type="s">
|
||||
<default>'touch'</default>
|
||||
<_summary>Which keyboard to use</_summary>
|
||||
|
@ -1,5 +1,5 @@
|
||||
#version 110
|
||||
uniform sampler2D sampler0;
|
||||
uniform sampler2D tex;
|
||||
uniform float fraction;
|
||||
uniform float height;
|
||||
const float c = -0.2;
|
||||
@ -12,15 +12,16 @@ mat4 contrast = mat4 (1.0 + c, 0.0, 0.0, 0.0,
|
||||
vec4 off = vec4(0.633, 0.633, 0.633, 0);
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture2D(sampler0, gl_TexCoord[0].st);
|
||||
float y = height * gl_TexCoord[0][1];
|
||||
vec4 color = texture2D(tex, cogl_tex_coord_in[0].xy);
|
||||
float y = height * cogl_tex_coord_in[0].y;
|
||||
|
||||
// To reduce contrast, blend with a mid gray
|
||||
gl_FragColor = color * contrast - off * c;
|
||||
cogl_color_out = color * contrast - off * c * color.a;
|
||||
|
||||
// We only fully dim at a distance of BORDER_MAX_HEIGHT from the edge and
|
||||
// We only fully dim at a distance of BORDER_MAX_HEIGHT from the top and
|
||||
// when the fraction is 1.0. For other locations and fractions we linearly
|
||||
// interpolate back to the original undimmed color.
|
||||
gl_FragColor = color + (gl_FragColor - color) * min(y / border_max_height, 1.0);
|
||||
gl_FragColor = color + (gl_FragColor - color) * fraction;
|
||||
// interpolate back to the original undimmed color, so the top of the window
|
||||
// is at full color.
|
||||
cogl_color_out = color + (cogl_color_out - color) * max(min(y / border_max_height, 1.0), 0.0);
|
||||
cogl_color_out = color + (cogl_color_out - color) * fraction;
|
||||
}
|
||||
|
@ -30,6 +30,10 @@
|
||||
min-width: 350px;
|
||||
}
|
||||
|
||||
.login-dialog-prompt-fingerprint-message {
|
||||
font-size: 10.5pt;
|
||||
}
|
||||
|
||||
.login-dialog-user-list-view {
|
||||
-st-vfade-offset: 1em;
|
||||
}
|
||||
@ -110,6 +114,7 @@
|
||||
background-color: white;
|
||||
caret-color: black;
|
||||
caret-size: 1px;
|
||||
width: 15em;
|
||||
}
|
||||
|
||||
.login-dialog-session-list {
|
||||
|
@ -164,6 +164,10 @@ StTooltip StLabel {
|
||||
background-color: #4c4c4c;
|
||||
}
|
||||
|
||||
.popup-menu-item:insensitive {
|
||||
color: #9f9f9f;
|
||||
}
|
||||
|
||||
.popup-image-menu-item {
|
||||
}
|
||||
|
||||
@ -276,12 +280,12 @@ StTooltip StLabel {
|
||||
background-color: black;
|
||||
border-image: url("panel-border.svg") 1;
|
||||
font-size: 10.5pt;
|
||||
font-weight: bold;
|
||||
height: 1.86em;
|
||||
}
|
||||
|
||||
#panelLeft, #panelCenter, #panelRight {
|
||||
#panelLeft, #panelCenter {
|
||||
spacing: 4px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#panelLeft:ltr {
|
||||
@ -335,7 +339,8 @@ StTooltip StLabel {
|
||||
}
|
||||
|
||||
.panel-button {
|
||||
padding: 0px 12px;
|
||||
-natural-hpadding: 12px;
|
||||
-minimum-hpadding: 6px;
|
||||
font-weight: bold;
|
||||
color: #ccc;
|
||||
transition-duration: 100;
|
||||
@ -355,9 +360,9 @@ StTooltip StLabel {
|
||||
text-shadow: black 0px 2px 2px;
|
||||
}
|
||||
|
||||
#statusTray > .panel-button:active,
|
||||
#statusTray > .panel-button:checked,
|
||||
#statusTray > .panel-button:focus {
|
||||
.panel-status-button:active,
|
||||
.panel-status-button:checked,
|
||||
.panel-status-button:focus {
|
||||
background-image: url("panel-button-highlight-narrow.svg");
|
||||
}
|
||||
|
||||
@ -371,19 +376,7 @@ StTooltip StLabel {
|
||||
-boxpointer-gap: 4px
|
||||
}
|
||||
|
||||
/* The rounded panel corners we draw don't
|
||||
* support transitions, so disable transitions
|
||||
* for the buttons at the left/right edges
|
||||
*/
|
||||
#panelActivities {
|
||||
transition-duration: 0;
|
||||
}
|
||||
|
||||
#panelStatus {
|
||||
transition-duration: 0;
|
||||
}
|
||||
|
||||
#panelStatusMenu {
|
||||
#panelUserMenu {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
@ -410,6 +403,7 @@ StTooltip StLabel {
|
||||
.status-chooser-user-name {
|
||||
font-weight: bold;
|
||||
font-size: 1.3em;
|
||||
min-width: 120pt;
|
||||
}
|
||||
|
||||
.status-chooser-combo {
|
||||
@ -426,24 +420,10 @@ StTooltip StLabel {
|
||||
}
|
||||
|
||||
.status-chooser-status-item,
|
||||
.status-chooser-combo > .popup-combobox-item {
|
||||
.status-chooser-combo .popup-combobox-item {
|
||||
spacing: .4em;
|
||||
}
|
||||
|
||||
#legacyTray {
|
||||
spacing: 14px;
|
||||
padding-left: 14px;
|
||||
}
|
||||
|
||||
#legacyTray:rtl {
|
||||
padding-left: 0px;
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
#legacyTray:compact {
|
||||
spacing: 8px;
|
||||
}
|
||||
|
||||
.system-status-icon {
|
||||
icon-size: 1.14em;
|
||||
}
|
||||
@ -531,8 +511,6 @@ StTooltip StLabel {
|
||||
|
||||
.dash-placeholder {
|
||||
background-image: url("dash-placeholder.svg");
|
||||
height: 27px;
|
||||
width: 48px;
|
||||
}
|
||||
|
||||
#viewSelector {
|
||||
@ -951,7 +929,7 @@ StTooltip StLabel {
|
||||
.calendar-vertical-separator {
|
||||
-stipple-width: 1px;
|
||||
-stipple-color: #505050;
|
||||
width: 1.5em;
|
||||
width: 0.3em;
|
||||
}
|
||||
|
||||
#calendarPopup {
|
||||
@ -974,13 +952,14 @@ StTooltip StLabel {
|
||||
.calendar-month-label {
|
||||
color: #666666;
|
||||
font-size: 7.5pt;
|
||||
padding: 2px;
|
||||
padding-bottom: 8px;
|
||||
padding-top: 8px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.calendar-change-month-back {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
width: 18px;
|
||||
height: 12px;
|
||||
background-image: url("calendar-arrow-left.svg");
|
||||
border-radius: 4px;
|
||||
}
|
||||
@ -997,8 +976,8 @@ StTooltip StLabel {
|
||||
}
|
||||
|
||||
.calendar-change-month-forward {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
width: 18px;
|
||||
height: 12px;
|
||||
background-image: url("calendar-arrow-right.svg");
|
||||
border-radius: 4px;
|
||||
}
|
||||
@ -1030,6 +1009,7 @@ StTooltip StLabel {
|
||||
|
||||
.calendar-day-base:hover {
|
||||
background-color: #777777;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.calendar-day-base:active {
|
||||
@ -1038,6 +1018,7 @@ StTooltip StLabel {
|
||||
|
||||
.calendar-day-heading {
|
||||
color: #666666;
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
.calendar-week-number {
|
||||
@ -1100,7 +1081,8 @@ StTooltip StLabel {
|
||||
font-size: 9pt;
|
||||
font-weight: bold;
|
||||
color: rgba(153, 153, 153, 1.0);
|
||||
padding-left: 0.3em;
|
||||
padding-left: 1.8em;
|
||||
padding-top: 0.8em;
|
||||
}
|
||||
|
||||
.events-day-header:rtl {
|
||||
|
@ -3,7 +3,10 @@ jsdir = $(pkgdatadir)/js
|
||||
|
||||
nobase_dist_js_DATA = \
|
||||
gdm/batch.js \
|
||||
gdm/consoleKit.js \
|
||||
gdm/fingerprint.js \
|
||||
gdm/loginDialog.js \
|
||||
gdm/powerMenu.js \
|
||||
misc/config.js \
|
||||
misc/docInfo.js \
|
||||
misc/fileUtils.js \
|
||||
|
32
js/gdm/consoleKit.js
Normal file
32
js/gdm/consoleKit.js
Normal file
@ -0,0 +1,32 @@
|
||||
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
|
||||
|
||||
const DBus = imports.dbus;
|
||||
|
||||
const ConsoleKitManagerIface = {
|
||||
name: 'org.freedesktop.ConsoleKit.Manager',
|
||||
methods: [{ name: 'CanRestart',
|
||||
inSignature: '',
|
||||
outSignature: 'b' },
|
||||
{ name: 'CanStop',
|
||||
inSignature: '',
|
||||
outSignature: 'b' },
|
||||
{ name: 'Restart',
|
||||
inSignature: '',
|
||||
outSignature: '' },
|
||||
{ name: 'Stop',
|
||||
inSignature: '',
|
||||
outSignature: '' }]
|
||||
};
|
||||
|
||||
function ConsoleKitManager() {
|
||||
this._init();
|
||||
};
|
||||
|
||||
ConsoleKitManager.prototype = {
|
||||
_init: function() {
|
||||
DBus.system.proxifyObject(this,
|
||||
'org.freedesktop.ConsoleKit',
|
||||
'/org/freedesktop/ConsoleKit/Manager');
|
||||
}
|
||||
};
|
||||
DBus.proxifyPrototype(ConsoleKitManager.prototype, ConsoleKitManagerIface);
|
26
js/gdm/fingerprint.js
Normal file
26
js/gdm/fingerprint.js
Normal file
@ -0,0 +1,26 @@
|
||||
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
|
||||
|
||||
const DBus = imports.dbus;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const FprintManagerIface = {
|
||||
name: 'net.reactivated.Fprint.Manager',
|
||||
methods: [{ name: 'GetDefaultDevice',
|
||||
inSignature: '',
|
||||
outSignature: 'o' }]
|
||||
};
|
||||
|
||||
function FprintManager() {
|
||||
this._init();
|
||||
};
|
||||
|
||||
FprintManager.prototype = {
|
||||
_init: function() {
|
||||
DBus.system.proxifyObject(this,
|
||||
'net.reactivated.Fprint',
|
||||
'/net/reactivated/Fprint/Manager');
|
||||
}
|
||||
};
|
||||
DBus.proxifyPrototype(FprintManager.prototype, FprintManagerIface);
|
@ -33,15 +33,25 @@ const St = imports.gi.St;
|
||||
const GdmGreeter = imports.gi.GdmGreeter;
|
||||
|
||||
const Batch = imports.gdm.batch;
|
||||
const DBus = imports.dbus;
|
||||
const Fprint = imports.gdm.fingerprint;
|
||||
const Lightbox = imports.ui.lightbox;
|
||||
const Main = imports.ui.main;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const _PASSWORD_SERVICE_NAME = 'gdm-password';
|
||||
const _FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
|
||||
const _FADE_ANIMATION_TIME = 0.16;
|
||||
const _RESIZE_ANIMATION_TIME = 0.25;
|
||||
const _SCROLL_ANIMATION_TIME = 2.0;
|
||||
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
|
||||
const _LOGO_ICON_NAME_SIZE = 48;
|
||||
|
||||
const _LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
|
||||
const _FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication';
|
||||
|
||||
const _LOGO_KEY = 'logo';
|
||||
|
||||
let _loginDialog = null;
|
||||
|
||||
@ -246,12 +256,15 @@ UserListItem.prototype = {
|
||||
showFocusAnimation: function(time) {
|
||||
let hold = new Batch.Hold();
|
||||
|
||||
let node = this.actor.get_theme_node();
|
||||
let padding = node.get_horizontal_padding();
|
||||
|
||||
let box = this._verticalBox.get_allocation_box();
|
||||
|
||||
Tweener.removeTweens(this._focusBin);
|
||||
this._focusBin.width = 0;
|
||||
Tweener.addTween(this._focusBin,
|
||||
{ width: box.x2 - box.x1,
|
||||
{ width: (box.x2 - box.x1 - padding),
|
||||
time: time,
|
||||
transition: 'linear',
|
||||
onComplete: function() {
|
||||
@ -580,8 +593,11 @@ function SessionList() {
|
||||
|
||||
SessionList.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new St.BoxLayout({ style_class: 'login-dialog-session-list',
|
||||
vertical: true});
|
||||
this.actor = new St.Bin();
|
||||
|
||||
this._box = new St.BoxLayout({ style_class: 'login-dialog-session-list',
|
||||
vertical: true});
|
||||
this.actor.child = this._box;
|
||||
|
||||
this._button = new St.Button({ style_class: 'login-dialog-session-list-button',
|
||||
can_focus: true,
|
||||
@ -606,17 +622,17 @@ SessionList.prototype = {
|
||||
|
||||
this._button.connect('clicked',
|
||||
Lang.bind(this, this._onClicked));
|
||||
this.actor.add_actor(this._button,
|
||||
{ x_fill: true,
|
||||
y_fill: true,
|
||||
expand: true });
|
||||
this._box.add_actor(this._button,
|
||||
{ x_fill: true,
|
||||
y_fill: true,
|
||||
expand: true });
|
||||
this._scrollView = new St.ScrollView({ style_class: 'login-dialog-session-list-scroll-view'});
|
||||
this._scrollView.set_policy(Gtk.PolicyType.NEVER,
|
||||
Gtk.PolicyType.AUTOMATIC);
|
||||
this.actor.add_actor(this._scrollView,
|
||||
{ x_fill: true,
|
||||
y_fill: true,
|
||||
expand: true });
|
||||
this._box.add_actor(this._scrollView,
|
||||
{ x_fill: true,
|
||||
y_fill: true,
|
||||
expand: true });
|
||||
this._itemList = new St.BoxLayout({ style_class: 'login-dialog-session-item-list',
|
||||
vertical: true });
|
||||
this._scrollView.add_actor(this._itemList,
|
||||
@ -679,9 +695,9 @@ SessionList.prototype = {
|
||||
ids.sort();
|
||||
|
||||
if (ids.length <= 1)
|
||||
this.actor.hide();
|
||||
this._box.hide();
|
||||
else
|
||||
this.actor.show();
|
||||
this._box.show();
|
||||
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
let [sessionName, sessionDescription] = GdmGreeter.get_session_name_and_description(ids[i]);
|
||||
@ -731,7 +747,7 @@ LoginDialog.prototype = {
|
||||
|
||||
this._greeterClient.open_connection();
|
||||
|
||||
this._greeterClient.call_start_conversation('gdm-password');
|
||||
this._greeterClient.call_start_conversation(_PASSWORD_SERVICE_NAME);
|
||||
|
||||
this._greeterClient.connect('reset',
|
||||
Lang.bind(this, this._onReset));
|
||||
@ -754,8 +770,19 @@ LoginDialog.prototype = {
|
||||
this._greeterClient.connect('conversation-stopped',
|
||||
Lang.bind(this, this._onConversationStopped));
|
||||
|
||||
this._settings = new Gio.Settings({ schema: _LOGIN_SCREEN_SCHEMA });
|
||||
|
||||
this._fprintManager = new Fprint.FprintManager();
|
||||
this._startFingerprintConversationIfNeeded();
|
||||
this._settings.connect('changed::' + _LOGO_KEY,
|
||||
Lang.bind(this, this._updateLogo));
|
||||
|
||||
this._logoBox = new St.Bin({ style_class: 'login-dialog-logo-box' });
|
||||
this.contentLayout.add(this._logoBox);
|
||||
this._updateLogo();
|
||||
|
||||
this._titleLabel = new St.Label({ style_class: 'login-dialog-title',
|
||||
text: _("Sign In") });
|
||||
text: C_("title", "Sign In") });
|
||||
|
||||
this.contentLayout.add(this._titleLabel,
|
||||
{ y_fill: false,
|
||||
@ -798,6 +825,12 @@ LoginDialog.prototype = {
|
||||
x_fill: true,
|
||||
y_fill: false,
|
||||
x_align: St.Align.START });
|
||||
// translators: this message is shown below the password entry field
|
||||
// to indicate the user can swipe their finger instead
|
||||
this._promptFingerprintMessage = new St.Label({ text: _("(or swipe finger)"),
|
||||
style_class: 'login-dialog-prompt-fingerprint-message' });
|
||||
this._promptFingerprintMessage.hide();
|
||||
this._promptBox.add(this._promptFingerprintMessage);
|
||||
|
||||
this._sessionList = new SessionList();
|
||||
this._sessionList.connect('session-activated',
|
||||
@ -806,11 +839,10 @@ LoginDialog.prototype = {
|
||||
}));
|
||||
|
||||
this._promptBox.add(this._sessionList.actor,
|
||||
{ expand: true,
|
||||
x_fill: true,
|
||||
y_fill: true,
|
||||
x_align: St.Align.START,
|
||||
y_align: St.Align.START});
|
||||
{ expand: true,
|
||||
x_fill: false,
|
||||
y_fill: true,
|
||||
x_align: St.Align.START });
|
||||
this._promptBox.hide();
|
||||
|
||||
let notListedLabel = new St.Label({ text: _("Not listed?"),
|
||||
@ -846,15 +878,47 @@ LoginDialog.prototype = {
|
||||
this._onUserListActivated(item);
|
||||
}));
|
||||
|
||||
},
|
||||
|
||||
_startFingerprintConversationIfNeeded: function() {
|
||||
this._haveFingerprintReader = false;
|
||||
|
||||
if (!this._settings.get_boolean(_FINGERPRINT_AUTHENTICATION_KEY))
|
||||
return;
|
||||
|
||||
this._fprintManager.GetDefaultDeviceRemote(DBus.CALL_FLAG_START, Lang.bind(this,
|
||||
function(device, error) {
|
||||
if (!error && device)
|
||||
this._haveFingerprintReader = true;
|
||||
|
||||
if (this._haveFingerprintReader)
|
||||
this._greeterClient.call_start_conversation(_FINGERPRINT_SERVICE_NAME);
|
||||
}));
|
||||
},
|
||||
|
||||
_updateLogo: function() {
|
||||
this._logoBox.child = null;
|
||||
let path = this._settings.get_string(_LOGO_KEY);
|
||||
|
||||
if (path) {
|
||||
let file = Gio.file_new_for_path(path);
|
||||
let uri = file.get_uri();
|
||||
|
||||
let textureCache = St.TextureCache.get_default();
|
||||
this._logoBox.child = textureCache.load_uri_async(uri, -1, _LOGO_ICON_NAME_SIZE);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
_onReset: function(client, serviceName) {
|
||||
this._greeterClient.call_start_conversation('gdm-password');
|
||||
this._greeterClient.call_start_conversation(_PASSWORD_SERVICE_NAME);
|
||||
this._startFingerprintConversationIfNeeded();
|
||||
|
||||
let tasks = [this._hidePrompt,
|
||||
|
||||
new Batch.ConcurrentBatch(this, [this._fadeInTitleLabel,
|
||||
this._fadeInNotListedButton]),
|
||||
this._fadeInNotListedButton,
|
||||
this._fadeInLogo]),
|
||||
|
||||
function() {
|
||||
this._sessionList.close();
|
||||
@ -879,10 +943,17 @@ LoginDialog.prototype = {
|
||||
},
|
||||
|
||||
_onInfo: function(client, serviceName, info) {
|
||||
// we don't want fingerprint messages with the word UPEK in them
|
||||
if (serviceName != _PASSWORD_SERVICE_NAME)
|
||||
return;
|
||||
Main.notifyError(info);
|
||||
},
|
||||
|
||||
_onProblem: function(client, serviceName, problem) {
|
||||
// we don't want to show auth failed messages to
|
||||
// users who haven't enrolled their fingerprint.
|
||||
if (serviceName != _PASSWORD_SERVICE_NAME)
|
||||
return;
|
||||
Main.notifyError(problem);
|
||||
},
|
||||
|
||||
@ -899,6 +970,13 @@ LoginDialog.prototype = {
|
||||
return _fadeInActor(this._promptEntry);
|
||||
},
|
||||
|
||||
function() {
|
||||
if (!this._haveFingerprintReader)
|
||||
return null;
|
||||
|
||||
return _fadeInActor(this._promptFingerprintMessage);
|
||||
},
|
||||
|
||||
function() {
|
||||
return _fadeInActor(this._promptBox);
|
||||
},
|
||||
@ -928,7 +1006,7 @@ LoginDialog.prototype = {
|
||||
{ action: Lang.bind(this, function() {
|
||||
hold.release();
|
||||
}),
|
||||
label: _("Sign In") }];
|
||||
label: C_("button", "Sign In") }];
|
||||
|
||||
this._promptEntryActivateCallbackId = this._promptEntry.clutter_text.connect('activate',
|
||||
Lang.bind(this, function() {
|
||||
@ -967,6 +1045,7 @@ LoginDialog.prototype = {
|
||||
},
|
||||
|
||||
function() {
|
||||
this._promptFingerprintMessage.hide();
|
||||
this._promptEntry.set_text('');
|
||||
}];
|
||||
|
||||
@ -990,12 +1069,20 @@ LoginDialog.prototype = {
|
||||
return batch.run();
|
||||
},
|
||||
_onInfoQuery: function(client, serviceName, question) {
|
||||
// We only expect questions to come from the main auth service
|
||||
if (serviceName != _PASSWORD_SERVICE_NAME)
|
||||
return;
|
||||
|
||||
this._promptEntry.set_text('');
|
||||
this._promptEntry.clutter_text.set_password_char('');
|
||||
this._askQuestion(serviceName, question);
|
||||
},
|
||||
|
||||
_onSecretInfoQuery: function(client, serviceName, secretQuestion) {
|
||||
// We only expect secret requests to come from the main auth service
|
||||
if (serviceName != _PASSWORD_SERVICE_NAME)
|
||||
return;
|
||||
|
||||
this._promptEntry.set_text('');
|
||||
this._promptEntry.clutter_text.set_password_char('\u25cf');
|
||||
this._askQuestion(serviceName, secretQuestion);
|
||||
@ -1132,7 +1219,14 @@ LoginDialog.prototype = {
|
||||
},
|
||||
|
||||
_onConversationStopped: function(client, serviceName) {
|
||||
this._greeterClient.call_cancel();
|
||||
// if the password service fails, then cancel everything.
|
||||
// But if, e.g., fingerprint fails, still give
|
||||
// password authentication a chance to succeed
|
||||
if (serviceName == _PASSWORD_SERVICE_NAME) {
|
||||
this._greeterClient.call_cancel();
|
||||
} else if (serviceName == _FINGERPRINT_SERVICE_NAME) {
|
||||
_fadeOutActor(this._promptFingerprintMessage);
|
||||
}
|
||||
},
|
||||
|
||||
_onNotListedClicked: function(user) {
|
||||
@ -1149,16 +1243,25 @@ LoginDialog.prototype = {
|
||||
},
|
||||
|
||||
new Batch.ConcurrentBatch(this, [this._fadeOutTitleLabel,
|
||||
this._fadeOutNotListedButton]),
|
||||
this._fadeOutNotListedButton,
|
||||
this._fadeOutLogo]),
|
||||
|
||||
function() {
|
||||
this._greeterClient.call_begin_verification('gdm-password');
|
||||
this._greeterClient.call_begin_verification(_PASSWORD_SERVICE_NAME);
|
||||
}];
|
||||
|
||||
let batch = new Batch.ConsecutiveBatch(this, tasks);
|
||||
batch.run();
|
||||
},
|
||||
|
||||
_fadeInLogo: function() {
|
||||
return _fadeInActor(this._logoBox);
|
||||
},
|
||||
|
||||
_fadeOutLogo: function() {
|
||||
return _fadeOutActor(this._logoBox);
|
||||
},
|
||||
|
||||
_fadeInTitleLabel: function() {
|
||||
return _fadeInActor(this._titleLabel);
|
||||
},
|
||||
@ -1194,7 +1297,8 @@ LoginDialog.prototype = {
|
||||
},
|
||||
|
||||
new Batch.ConcurrentBatch(this, [this._fadeOutTitleLabel,
|
||||
this._fadeOutNotListedButton]),
|
||||
this._fadeOutNotListedButton,
|
||||
this._fadeOutLogo]),
|
||||
|
||||
function() {
|
||||
return this._userList.shrinkToNaturalHeight();
|
||||
@ -1202,8 +1306,11 @@ LoginDialog.prototype = {
|
||||
|
||||
function() {
|
||||
let userName = activatedItem.user.get_user_name();
|
||||
this._greeterClient.call_begin_verification_for_user('gdm-password',
|
||||
this._greeterClient.call_begin_verification_for_user(_PASSWORD_SERVICE_NAME,
|
||||
userName);
|
||||
|
||||
if (this._haveFingerprintReader)
|
||||
this._greeterClient.call_begin_verification_for_user(_FINGERPRINT_SERVICE_NAME, userName);
|
||||
}];
|
||||
|
||||
this._user = activatedItem.user;
|
||||
|
146
js/gdm/powerMenu.js
Normal file
146
js/gdm/powerMenu.js
Normal file
@ -0,0 +1,146 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*-
|
||||
*
|
||||
* Copyright 2011 Red Hat, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
const Lang = imports.lang;
|
||||
const UPowerGlib = imports.gi.UPowerGlib;
|
||||
|
||||
const ConsoleKit = imports.gdm.consoleKit;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
|
||||
function PowerMenuButton() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
PowerMenuButton.prototype = {
|
||||
__proto__: PanelMenu.SystemStatusButton.prototype,
|
||||
|
||||
_init: function() {
|
||||
PanelMenu.SystemStatusButton.prototype._init.call(this, 'system-shutdown', null);
|
||||
this._consoleKitManager = new ConsoleKit.ConsoleKitManager();
|
||||
this._upClient = new UPowerGlib.Client();
|
||||
|
||||
this._createSubMenu();
|
||||
|
||||
this._upClient.connect('notify::can-suspend',
|
||||
Lang.bind(this, this._updateHaveSuspend));
|
||||
this._updateHaveSuspend();
|
||||
|
||||
// ConsoleKit doesn't send notifications when shutdown/reboot
|
||||
// are disabled, so we update the menu item each time the menu opens
|
||||
this.menu.connect('open-state-changed', Lang.bind(this,
|
||||
function(menu, open) {
|
||||
if (open) {
|
||||
this._updateHaveShutdown();
|
||||
this._updateHaveRestart();
|
||||
}
|
||||
}));
|
||||
this._updateHaveShutdown();
|
||||
this._updateHaveRestart();
|
||||
},
|
||||
|
||||
_updateVisibility: function() {
|
||||
if (!this._haveSuspend && !this._haveShutdown && !this._haveRestart)
|
||||
this.actor.hide();
|
||||
else
|
||||
this.actor.show();
|
||||
},
|
||||
|
||||
_updateHaveShutdown: function() {
|
||||
this._consoleKitManager.CanStopRemote(Lang.bind(this,
|
||||
function(result, error) {
|
||||
if (!error)
|
||||
this._haveShutdown = result;
|
||||
else
|
||||
this._haveShutdown = false;
|
||||
|
||||
if (this._haveShutdown) {
|
||||
this._powerOffItem.actor.show();
|
||||
} else {
|
||||
this._powerOffItem.actor.hide();
|
||||
}
|
||||
|
||||
this._updateVisibility();
|
||||
}));
|
||||
},
|
||||
|
||||
_updateHaveRestart: function() {
|
||||
this._consoleKitManager.CanRestartRemote(Lang.bind(this,
|
||||
function(result, error) {
|
||||
if (!error)
|
||||
this._haveRestart = result;
|
||||
else
|
||||
this._haveRestart = false;
|
||||
|
||||
if (this._haveRestart) {
|
||||
this._restartItem.actor.show();
|
||||
} else {
|
||||
this._restartItem.actor.hide();
|
||||
}
|
||||
|
||||
this._updateVisibility();
|
||||
}));
|
||||
},
|
||||
|
||||
_updateHaveSuspend: function() {
|
||||
this._haveSuspend = this._upClient.get_can_suspend();
|
||||
|
||||
if (this._haveSuspend)
|
||||
this._suspendItem.actor.show();
|
||||
else
|
||||
this._suspendItem.actor.hide();
|
||||
|
||||
this._updateVisibility();
|
||||
},
|
||||
|
||||
_createSubMenu: function() {
|
||||
let item;
|
||||
|
||||
item = new PopupMenu.PopupMenuItem(_("Suspend"));
|
||||
item.connect('activate', Lang.bind(this, this._onActivateSuspend));
|
||||
this.menu.addMenuItem(item);
|
||||
this._suspendItem = item;
|
||||
|
||||
item = new PopupMenu.PopupMenuItem(_("Restart"));
|
||||
item.connect('activate', Lang.bind(this, this._onActivateRestart));
|
||||
this.menu.addMenuItem(item);
|
||||
this._restartItem = item;
|
||||
|
||||
item = new PopupMenu.PopupMenuItem(_("Power Off"));
|
||||
item.connect('activate', Lang.bind(this, this._onActivatePowerOff));
|
||||
this.menu.addMenuItem(item);
|
||||
this._powerOffItem = item;
|
||||
},
|
||||
|
||||
_onActivateSuspend: function() {
|
||||
if (this._haveSuspend)
|
||||
this._upClient.suspend_sync(null);
|
||||
},
|
||||
|
||||
_onActivateRestart: function() {
|
||||
if (this._haveRestart)
|
||||
this._consoleKitManager.RestartRemote();
|
||||
},
|
||||
|
||||
_onActivatePowerOff: function() {
|
||||
if (this._haveShutdown)
|
||||
this._consoleKitManager.StopRemote();
|
||||
}
|
||||
};
|
@ -7,4 +7,5 @@ const PACKAGE_VERSION = '@PACKAGE_VERSION@';
|
||||
const GJS_VERSION = '@GJS_VERSION@';
|
||||
/* 1 if gnome-bluetooth is available, 0 otherwise */
|
||||
const HAVE_BLUETOOTH = @HAVE_BLUETOOTH@;
|
||||
|
||||
/* The system TLS CA list */
|
||||
const SHELL_SYSTEM_CA_FILE = '@SHELL_SYSTEM_CA_FILE@';
|
||||
|
@ -20,3 +20,25 @@ function listDirAsync(file, callback) {
|
||||
enumerator.next_files_async(100, GLib.PRIORITY_LOW, null, onNextFileComplete);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteGFile(file) {
|
||||
// Work around 'delete' being a keyword in JS.
|
||||
return file['delete'](null);
|
||||
}
|
||||
|
||||
function recursivelyDeleteDir(dir) {
|
||||
let children = dir.enumerate_children('standard::name,standard::type',
|
||||
Gio.FileQueryInfoFlags.NONE, null);
|
||||
|
||||
let info, child;
|
||||
while ((info = children.next_file(null)) != null) {
|
||||
let type = info.get_file_type();
|
||||
let child = dir.get_child(info.get_name());
|
||||
if (type == Gio.FileType.REGULAR)
|
||||
deleteGFile(child);
|
||||
else if (type == Gio.TypeType.DIRECTORY)
|
||||
recursivelyDeleteDir(child);
|
||||
}
|
||||
|
||||
deleteGFile(dir);
|
||||
}
|
||||
|
@ -7,8 +7,32 @@ const Shell = imports.gi.Shell;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
/* http://daringfireball.net/2010/07/improved_regex_for_matching_urls */
|
||||
const _urlRegexp = new RegExp('\\b(([a-z][\\w-]+:(/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)([^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:\'\\".,<>?«»“”‘’]))', 'gi');
|
||||
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
||||
const _balancedParens = '\\((?:[^\\s()<>]+|(?:\\(?:[^\\s()<>]+\\)))*\\)';
|
||||
const _leadingJunk = '[\\s`(\\[{\'\\"<\u00AB\u201C\u2018]';
|
||||
const _notTrailingJunk = '[^\\s`!()\\[\\]{};:\'\\".,<>?\u00AB\u00BB\u201C\u201D\u2018\u2019]';
|
||||
|
||||
const _urlRegexp = new RegExp(
|
||||
'(^|' + _leadingJunk + ')' +
|
||||
'(' +
|
||||
'(?:' +
|
||||
'[a-z][\\w-]+://' + // scheme://
|
||||
'|' +
|
||||
'www\\d{0,3}[.]' + // www.
|
||||
'|' +
|
||||
'[a-z0-9.\\-]+[.][a-z]{2,4}/' + // foo.xx/
|
||||
')' +
|
||||
'(?:' + // one or more:
|
||||
'[^\\s()<>]+' + // run of non-space non-()
|
||||
'|' + // or
|
||||
_balancedParens + // balanced parens
|
||||
')+' +
|
||||
'(?:' + // end with:
|
||||
_balancedParens + // balanced parens
|
||||
'|' + // or
|
||||
_notTrailingJunk + // last non-junk char
|
||||
')' +
|
||||
')', 'gi');
|
||||
|
||||
// findUrls:
|
||||
// @str: string to find URLs in
|
||||
@ -21,7 +45,7 @@ const _urlRegexp = new RegExp('\\b(([a-z][\\w-]+:(/{1,3}|[a-z0-9%])|www\\d{0,3}[
|
||||
function findUrls(str) {
|
||||
let res = [], match;
|
||||
while ((match = _urlRegexp.exec(str)))
|
||||
res.push({ url: match[0], pos: match.index });
|
||||
res.push({ url: match[2], pos: match.index + match[1].length });
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,18 @@ function mod(a, b) {
|
||||
return (a + b) % b;
|
||||
}
|
||||
|
||||
function primaryModifier(mask) {
|
||||
if (mask == 0)
|
||||
return 0;
|
||||
|
||||
let primary = 1;
|
||||
while (mask > 1) {
|
||||
mask >>= 1;
|
||||
primary <<= 1;
|
||||
}
|
||||
return primary;
|
||||
}
|
||||
|
||||
function AltTabPopup() {
|
||||
this._init();
|
||||
}
|
||||
@ -48,6 +60,7 @@ AltTabPopup.prototype = {
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
|
||||
this._haveModal = false;
|
||||
this._modifierMask = 0;
|
||||
|
||||
this._currentApp = 0;
|
||||
this._currentWindow = -1;
|
||||
@ -121,9 +134,9 @@ AltTabPopup.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
show : function(backward, binding) {
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
let apps = tracker.get_running_apps ('');
|
||||
show : function(backward, binding, mask) {
|
||||
let appSys = Shell.AppSystem.get_default();
|
||||
let apps = appSys.get_running ();
|
||||
|
||||
if (!apps.length)
|
||||
return false;
|
||||
@ -131,6 +144,7 @@ AltTabPopup.prototype = {
|
||||
if (!Main.pushModal(this.actor))
|
||||
return false;
|
||||
this._haveModal = true;
|
||||
this._modifierMask = primaryModifier(mask);
|
||||
|
||||
this.actor.connect('key-press-event', Lang.bind(this, this._keyPressEvent));
|
||||
this.actor.connect('key-release-event', Lang.bind(this, this._keyReleaseEvent));
|
||||
@ -147,6 +161,8 @@ AltTabPopup.prototype = {
|
||||
|
||||
// Need to force an allocation so we can figure out whether we
|
||||
// need to scroll when selecting
|
||||
this.actor.opacity = 0;
|
||||
this.actor.show();
|
||||
this.actor.get_allocation_box();
|
||||
|
||||
// Make the initial selection
|
||||
@ -177,7 +193,7 @@ AltTabPopup.prototype = {
|
||||
// details.) So we check now. (Have to do this after updating
|
||||
// selection.)
|
||||
let [x, y, mods] = global.get_pointer();
|
||||
if (!(mods & Gdk.ModifierType.MOD1_MASK)) {
|
||||
if (!(mods & this._modifierMask)) {
|
||||
this._finish();
|
||||
return false;
|
||||
}
|
||||
@ -186,7 +202,7 @@ AltTabPopup.prototype = {
|
||||
// disturbed by the popup briefly flashing.
|
||||
this._initialDelayTimeoutId = Mainloop.timeout_add(POPUP_DELAY_TIMEOUT,
|
||||
Lang.bind(this, function () {
|
||||
this.actor.show();
|
||||
this.actor.opacity = 255;
|
||||
this._initialDelayTimeoutId = 0;
|
||||
}));
|
||||
|
||||
@ -254,7 +270,7 @@ AltTabPopup.prototype = {
|
||||
|
||||
_keyReleaseEvent : function(actor, event) {
|
||||
let [x, y, mods] = global.get_pointer();
|
||||
let state = mods & Clutter.ModifierType.MOD1_MASK;
|
||||
let state = mods & this._modifierMask;
|
||||
|
||||
if (state == 0)
|
||||
this._finish();
|
||||
@ -479,6 +495,10 @@ AltTabPopup.prototype = {
|
||||
|
||||
this.actor.add_actor(this._thumbnails.actor);
|
||||
|
||||
// Need to force an allocation so we can figure out whether we
|
||||
// need to scroll when selecting
|
||||
this._thumbnails.actor.get_allocation_box();
|
||||
|
||||
this._thumbnails.actor.opacity = 0;
|
||||
Tweener.addTween(this._thumbnails.actor,
|
||||
{ opacity: 255,
|
||||
@ -630,11 +650,10 @@ SwitcherList.prototype = {
|
||||
this._items[this._highlighted].add_style_pseudo_class('selected');
|
||||
}
|
||||
|
||||
let monitor = Main.layoutManager.primaryMonitor;
|
||||
let itemSize = this._items[index].allocation.x2 - this._items[index].allocation.x1;
|
||||
let [posX, posY] = this._items[index].get_transformed_position();
|
||||
posX += this.actor.x;
|
||||
if (posX + itemSize > monitor.width + monitor.x)
|
||||
let [absItemX, absItemY] = this._items[index].get_transformed_position();
|
||||
let [result, posX, posY] = this.actor.transform_stage_point(absItemX, 0);
|
||||
let [containerWidth, containerHeight] = this.actor.get_transformed_size();
|
||||
if (posX + this._items[index].get_width() > containerWidth)
|
||||
this._scrollToRight();
|
||||
else if (posX < 0)
|
||||
this._scrollToLeft();
|
||||
|
@ -208,7 +208,8 @@ ViewByCategories.prototype = {
|
||||
if (!entry.get_app_info().get_nodisplay())
|
||||
appList.push(app);
|
||||
} else if (nextType == GMenu.TreeItemType.DIRECTORY) {
|
||||
this._loadCategory(iter.get_directory(), appList);
|
||||
if (!dir.get_is_nodisplay())
|
||||
this._loadCategory(iter.get_directory(), appList);
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -262,6 +263,8 @@ ViewByCategories.prototype = {
|
||||
while ((nextType = iter.next()) != GMenu.TreeItemType.INVALID) {
|
||||
if (nextType == GMenu.TreeItemType.DIRECTORY) {
|
||||
var dir = iter.get_directory();
|
||||
if (dir.get_is_nodisplay())
|
||||
continue;
|
||||
this._addCategory(dir.get_name(), i, dir);
|
||||
i++;
|
||||
}
|
||||
@ -556,7 +559,7 @@ AppWellIcon.prototype = {
|
||||
this._menu.connect('activate-window', Lang.bind(this, function (menu, window) {
|
||||
this.activateWindow(window);
|
||||
}));
|
||||
this._menu.connect('popup', Lang.bind(this, function (menu, isPoppedUp) {
|
||||
this._menu.connect('open-state-changed', Lang.bind(this, function (menu, isPoppedUp) {
|
||||
if (!isPoppedUp)
|
||||
this._onMenuPoppedDown();
|
||||
}));
|
||||
@ -640,7 +643,6 @@ AppIconMenu.prototype = {
|
||||
this._source = source;
|
||||
|
||||
this.connect('activate', Lang.bind(this, this._onActivate));
|
||||
this.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
|
||||
|
||||
this.actor.add_style_class_name('app-well-menu');
|
||||
|
||||
@ -704,14 +706,6 @@ AppIconMenu.prototype = {
|
||||
this.open();
|
||||
},
|
||||
|
||||
_onOpenStateChanged: function (menu, open) {
|
||||
if (open) {
|
||||
this.emit('popup', true);
|
||||
} else {
|
||||
this.emit('popup', false);
|
||||
}
|
||||
},
|
||||
|
||||
_onActivate: function (actor, child) {
|
||||
if (child._window) {
|
||||
let metaWindow = child._window;
|
||||
|
@ -23,8 +23,6 @@ const AutorunSetting = {
|
||||
ASK: 3
|
||||
};
|
||||
|
||||
const HOTPLUG_ICON_SIZE = 16;
|
||||
|
||||
// misc utils
|
||||
function ignoreAutorunForMount(mount) {
|
||||
let root = mount.get_root();
|
||||
@ -284,7 +282,7 @@ AutorunResidentSource.prototype = {
|
||||
this._mounts = [];
|
||||
|
||||
this._notification = new AutorunResidentNotification(this);
|
||||
this._setSummaryIcon(this.createNotificationIcon(HOTPLUG_ICON_SIZE));
|
||||
this._setSummaryIcon(this.createNotificationIcon());
|
||||
},
|
||||
|
||||
addMount: function(mount, apps) {
|
||||
@ -329,10 +327,10 @@ AutorunResidentSource.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
createNotificationIcon: function(iconSize) {
|
||||
createNotificationIcon: function() {
|
||||
return new St.Icon ({ icon_name: 'media-removable',
|
||||
icon_type: St.IconType.FULLCOLOR,
|
||||
icon_size: iconSize ? iconSize : this.ICON_SIZE });
|
||||
icon_size: this.ICON_SIZE });
|
||||
}
|
||||
}
|
||||
|
||||
@ -533,16 +531,16 @@ AutorunTransientSource.prototype = {
|
||||
this.apps = apps;
|
||||
|
||||
this._notification = new AutorunTransientNotification(this);
|
||||
this._setSummaryIcon(this.createNotificationIcon(this.ICON_SIZE));
|
||||
this._setSummaryIcon(this.createNotificationIcon());
|
||||
|
||||
// add ourselves as a source, and popup the notification
|
||||
Main.messageTray.add(this);
|
||||
this.notify(this._notification);
|
||||
},
|
||||
|
||||
createNotificationIcon: function(iconSize) {
|
||||
createNotificationIcon: function() {
|
||||
return new St.Icon({ gicon: this.mount.get_icon(),
|
||||
icon_size: iconSize ? iconSize : this.ICON_SIZE });
|
||||
icon_size: this.ICON_SIZE });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ CtrlAltTabManager.prototype = {
|
||||
return a.x - b.x;
|
||||
},
|
||||
|
||||
popup: function(backwards) {
|
||||
popup: function(backwards, mask) {
|
||||
// Start with the set of focus groups that are currently mapped
|
||||
let items = this._items.filter(function (item) { return item.proxy.mapped; });
|
||||
|
||||
@ -123,7 +123,16 @@ CtrlAltTabManager.prototype = {
|
||||
return;
|
||||
|
||||
items.sort(Lang.bind(this, this._sortItems));
|
||||
new CtrlAltTabPopup().show(items, backwards);
|
||||
|
||||
if (!this._popup) {
|
||||
this._popup = new CtrlAltTabPopup();
|
||||
this._popup.show(items, backwards, mask);
|
||||
|
||||
this._popup.actor.connect('destroy',
|
||||
Lang.bind(this, function() {
|
||||
this._popup = null;
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -147,6 +156,7 @@ CtrlAltTabPopup.prototype = {
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
|
||||
this._haveModal = false;
|
||||
this._modifierMask = 0;
|
||||
this._selection = 0;
|
||||
|
||||
Main.uiGroup.add_actor(this.actor);
|
||||
@ -183,10 +193,11 @@ CtrlAltTabPopup.prototype = {
|
||||
this._switcher.actor.allocate(childBox, flags);
|
||||
},
|
||||
|
||||
show : function(items, startBackwards) {
|
||||
show : function(items, startBackwards, mask) {
|
||||
if (!Main.pushModal(this.actor))
|
||||
return false;
|
||||
this._haveModal = true;
|
||||
this._modifierMask = AltTab.primaryModifier(mask);
|
||||
|
||||
this._keyPressEventId = this.actor.connect('key-press-event', Lang.bind(this, this._keyPressEvent));
|
||||
this._keyReleaseEventId = this.actor.connect('key-release-event', Lang.bind(this, this._keyReleaseEvent));
|
||||
@ -200,7 +211,7 @@ CtrlAltTabPopup.prototype = {
|
||||
this._select(this._selection);
|
||||
|
||||
let [x, y, mods] = global.get_pointer();
|
||||
if (!(mods & Gdk.ModifierType.MOD1_MASK)) {
|
||||
if (!(mods & this._modifierMask)) {
|
||||
this._finish();
|
||||
return false;
|
||||
}
|
||||
@ -246,7 +257,7 @@ CtrlAltTabPopup.prototype = {
|
||||
|
||||
_keyReleaseEvent : function(actor, event) {
|
||||
let [x, y, mods] = global.get_pointer();
|
||||
let state = mods & Clutter.ModifierType.MOD1_MASK;
|
||||
let state = mods & this._modifierMask;
|
||||
|
||||
if (state == 0)
|
||||
this._finish();
|
||||
|
@ -275,7 +275,7 @@ Dash.prototype = {
|
||||
|
||||
this._appSystem.connect('installed-changed', Lang.bind(this, this._queueRedisplay));
|
||||
AppFavorites.getAppFavorites().connect('changed', Lang.bind(this, this._queueRedisplay));
|
||||
this._tracker.connect('app-state-changed', Lang.bind(this, this._queueRedisplay));
|
||||
this._appSystem.connect('app-state-changed', Lang.bind(this, this._queueRedisplay));
|
||||
|
||||
Main.overview.connect('item-drag-begin',
|
||||
Lang.bind(this, this._onDragBegin));
|
||||
@ -471,10 +471,7 @@ Dash.prototype = {
|
||||
_redisplay: function () {
|
||||
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
|
||||
|
||||
/* hardcode here pending some design about how exactly desktop contexts behave */
|
||||
let contextId = '';
|
||||
|
||||
let running = this._tracker.get_running_apps(contextId);
|
||||
let running = this._appSystem.get_running();
|
||||
|
||||
let children = this._box.get_children().filter(function(actor) {
|
||||
return actor._delegate.child &&
|
||||
@ -687,6 +684,8 @@ Dash.prototype = {
|
||||
}
|
||||
|
||||
this._dragPlaceholder = new DragPlaceholderItem();
|
||||
this._dragPlaceholder.child.set_width (this.iconSize);
|
||||
this._dragPlaceholder.child.set_height (this.iconSize / 2);
|
||||
this._box.insert_actor(this._dragPlaceholder.actor,
|
||||
this._dragPlaceholderPos);
|
||||
if (fadeIn)
|
||||
|
@ -60,7 +60,7 @@ DateMenuButton.prototype = {
|
||||
PanelMenu.Button.prototype._init.call(this, menuAlignment);
|
||||
|
||||
this._clock = new St.Label();
|
||||
this.actor.set_child(this._clock);
|
||||
this.actor.add_actor(this._clock);
|
||||
|
||||
hbox = new St.BoxLayout({name: 'calendarArea' });
|
||||
this.menu.addActor(hbox);
|
||||
|
@ -60,8 +60,16 @@ const logoutDialogContent = {
|
||||
subjectWithUser: _("Log Out %s"),
|
||||
subject: _("Log Out"),
|
||||
inhibitedDescription: _("Click Log Out to quit these applications and log out of the system."),
|
||||
uninhibitedDescriptionWithUser: _("%s will be logged out automatically in %d seconds."),
|
||||
uninhibitedDescription: _("You will be logged out automatically in %d seconds."),
|
||||
uninhibitedDescriptionWithUser: function(user, seconds) {
|
||||
return ngettext("%s will be logged out automatically in %d second.",
|
||||
"%s will be logged out automatically in %d seconds.",
|
||||
seconds).format(user, seconds);
|
||||
},
|
||||
uninhibitedDescription: function(seconds) {
|
||||
return ngettext("You will be logged out automatically in %d second.",
|
||||
"You will be logged out automatically in %d seconds.",
|
||||
seconds).format(seconds);
|
||||
},
|
||||
endDescription: _("Logging out of the system."),
|
||||
confirmButtons: [{ signal: 'ConfirmedLogout',
|
||||
label: _("Log Out") }],
|
||||
@ -71,7 +79,11 @@ const logoutDialogContent = {
|
||||
const shutdownDialogContent = {
|
||||
subject: _("Power Off"),
|
||||
inhibitedDescription: _("Click Power Off to quit these applications and power off the system."),
|
||||
uninhibitedDescription: _("The system will power off automatically in %d seconds."),
|
||||
uninhibitedDescription: function(seconds) {
|
||||
return ngettext("The system will power off automatically in %d second.",
|
||||
"The system will power off automatically in %d seconds.",
|
||||
seconds).format(seconds);
|
||||
},
|
||||
endDescription: _("Powering off the system."),
|
||||
confirmButtons: [{ signal: 'ConfirmedReboot',
|
||||
label: _("Restart") },
|
||||
@ -84,7 +96,11 @@ const shutdownDialogContent = {
|
||||
const restartDialogContent = {
|
||||
subject: _("Restart"),
|
||||
inhibitedDescription: _("Click Restart to quit these applications and restart the system."),
|
||||
uninhibitedDescription: _("The system will restart automatically in %d seconds."),
|
||||
uninhibitedDescription: function(seconds) {
|
||||
return ngettext("The system will restart automatically in %d second.",
|
||||
"The system will restart automatically in %d seconds.",
|
||||
seconds).format(seconds);
|
||||
},
|
||||
endDescription: _("Restarting the system."),
|
||||
confirmButtons: [{ signal: 'ConfirmedReboot',
|
||||
label: _("Restart") }],
|
||||
@ -388,14 +404,14 @@ EndSessionDialog.prototype = {
|
||||
subject = dialogContent.subjectWithUser.format(realName);
|
||||
|
||||
if (dialogContent.uninhibitedDescriptionWithUser)
|
||||
description = dialogContent.uninhibitedDescriptionWithUser.format(realName, displayTime);
|
||||
description = dialogContent.uninhibitedDescriptionWithUser(realName, displayTime);
|
||||
else
|
||||
description = dialogContent.uninhibitedDescription.format(displayTime);
|
||||
description = dialogContent.uninhibitedDescription(displayTime);
|
||||
}
|
||||
}
|
||||
|
||||
if (!description)
|
||||
description = dialogContent.uninhibitedDescription.format(displayTime);
|
||||
description = dialogContent.uninhibitedDescription(displayTime);
|
||||
} else {
|
||||
description = dialogContent.endDescription;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const St = imports.gi.St;
|
||||
@ -10,6 +11,10 @@ const Shell = imports.gi.Shell;
|
||||
const Soup = imports.gi.Soup;
|
||||
|
||||
const Config = imports.misc.config;
|
||||
const FileUtils = imports.misc.fileUtils;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
|
||||
const API_VERSION = 1;
|
||||
|
||||
const ExtensionState = {
|
||||
ENABLED: 1,
|
||||
@ -28,6 +33,10 @@ const ExtensionType = {
|
||||
PER_USER: 2
|
||||
};
|
||||
|
||||
const REPOSITORY_URL_BASE = 'https://extensions.gnome.org';
|
||||
const REPOSITORY_URL_DOWNLOAD = REPOSITORY_URL_BASE + '/download-extension/%s.shell-extension.zip';
|
||||
const REPOSITORY_URL_INFO = REPOSITORY_URL_BASE + '/extension-info/';
|
||||
|
||||
const _httpSession = new Soup.SessionAsync();
|
||||
|
||||
// The unfortunate state of gjs, gobject-introspection and libsoup
|
||||
@ -37,6 +46,16 @@ const _httpSession = new Soup.SessionAsync();
|
||||
if (Soup.Session.prototype.add_feature != null)
|
||||
Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault());
|
||||
|
||||
function _getCertFile() {
|
||||
let localCert = GLib.build_filenamev([global.userdatadir, 'extensions.gnome.org.crt']);
|
||||
if (GLib.file_test(localCert, GLib.FileTest.EXISTS))
|
||||
return localCert;
|
||||
else
|
||||
return Config.SHELL_SYSTEM_CA_FILE;
|
||||
}
|
||||
|
||||
_httpSession.ssl_ca_file = _getCertFile();
|
||||
|
||||
// Maps uuid -> metadata object
|
||||
const extensionMeta = {};
|
||||
// Maps uuid -> importer object (extension directory tree)
|
||||
@ -92,53 +111,51 @@ function versionCheck(required, current) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function installExtensionFromManifestURL(uuid, url) {
|
||||
_httpSession.queue_message(
|
||||
Soup.Message.new('GET', url),
|
||||
function(session, message) {
|
||||
if (message.status_code != Soup.KnownStatusCode.OK) {
|
||||
logExtensionError(uuid, 'downloading manifest: ' + message.status_code.toString());
|
||||
return;
|
||||
}
|
||||
function installExtensionFromUUID(uuid, version_tag) {
|
||||
let params = { uuid: uuid,
|
||||
version_tag: version_tag,
|
||||
shell_version: Config.PACKAGE_VERSION,
|
||||
api_version: API_VERSION.toString() };
|
||||
|
||||
let manifest;
|
||||
try {
|
||||
manifest = JSON.parse(message.response_body.data);
|
||||
} catch (e) {
|
||||
logExtensionError(uuid, 'parsing: ' + e.toString());
|
||||
return;
|
||||
}
|
||||
let message = Soup.form_request_new_from_hash('GET', REPOSITORY_URL_INFO, params);
|
||||
|
||||
if (uuid != manifest['uuid']) {
|
||||
logExtensionError(uuid, 'manifest: manifest uuids do not match');
|
||||
return;
|
||||
}
|
||||
|
||||
let meta = extensionMeta[uuid] = { uuid: uuid,
|
||||
state: ExtensionState.DOWNLOADING,
|
||||
error: '' };
|
||||
|
||||
_signals.emit('extension-state-changed', meta);
|
||||
|
||||
installExtensionFromManifest(manifest, meta);
|
||||
});
|
||||
_httpSession.queue_message(message,
|
||||
function(session, message) {
|
||||
let info = JSON.parse(message.response_body.data);
|
||||
let dialog = new InstallExtensionDialog(uuid, version_tag, info.name);
|
||||
dialog.open(global.get_current_time());
|
||||
});
|
||||
}
|
||||
|
||||
function installExtensionFromManifest(manifest, meta) {
|
||||
let uuid = manifest['uuid'];
|
||||
let name = manifest['name'];
|
||||
function uninstallExtensionFromUUID(uuid) {
|
||||
let meta = extensionMeta[uuid];
|
||||
if (!meta)
|
||||
return false;
|
||||
|
||||
if (!versionCheck(manifest['shell-version'], Config.PACKAGE_VERSION)) {
|
||||
meta.state = ExtensionState.OUT_OF_DATE;
|
||||
logExtensionError(uuid, 'version: ' + name + ' is not compatible with current GNOME Shell version', meta.state);
|
||||
return;
|
||||
}
|
||||
// Try to disable it -- if it's ERROR'd, we can't guarantee that,
|
||||
// but it will be removed on next reboot, and hopefully nothing
|
||||
// broke too much.
|
||||
disableExtension(uuid);
|
||||
|
||||
let url = manifest['__installer'];
|
||||
_httpSession.queue_message(Soup.Message.new('GET', url),
|
||||
function(session, message) {
|
||||
gotExtensionZipFile(session, message, uuid);
|
||||
});
|
||||
// Don't try to uninstall system extensions
|
||||
if (meta.type != ExtensionType.PER_USER)
|
||||
return false;
|
||||
|
||||
meta.state = ExtensionState.UNINSTALLED;
|
||||
_signals.emit('extension-state-changed', meta);
|
||||
|
||||
delete extensionMeta[uuid];
|
||||
|
||||
// Importers are marked as PERMANENT, so we can't do this.
|
||||
// delete extensions[uuid];
|
||||
extensions[uuid] = undefined;
|
||||
|
||||
delete extensionStateObjs[uuid];
|
||||
delete errors[uuid];
|
||||
|
||||
FileUtils.recursivelyDeleteDir(Gio.file_new_for_path(meta.path));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function gotExtensionZipFile(session, message, uuid) {
|
||||
@ -173,6 +190,14 @@ function gotExtensionZipFile(session, message, uuid) {
|
||||
|
||||
GLib.child_watch_add(GLib.PRIORITY_DEFAULT, pid, function(pid, status) {
|
||||
GLib.spawn_close_pid(pid);
|
||||
|
||||
// Add extension to 'enabled-extensions' for the user, always...
|
||||
let enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
|
||||
if (enabledExtensions.indexOf(uuid) == -1) {
|
||||
enabledExtensions.push(uuid);
|
||||
global.settings.set_strv(ENABLED_EXTENSIONS_KEY, enabledExtensions);
|
||||
}
|
||||
|
||||
loadExtension(dir, true, ExtensionType.PER_USER);
|
||||
});
|
||||
}
|
||||
@ -434,3 +459,73 @@ function loadExtensions() {
|
||||
_loadExtensionsIn(dir, ExtensionType.SYSTEM);
|
||||
}
|
||||
}
|
||||
|
||||
function InstallExtensionDialog(uuid, version_tag, name) {
|
||||
this._init(uuid, version_tag, name);
|
||||
}
|
||||
|
||||
InstallExtensionDialog.prototype = {
|
||||
__proto__: ModalDialog.ModalDialog.prototype,
|
||||
|
||||
_init: function(uuid, version_tag, name) {
|
||||
ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'extension-dialog' });
|
||||
|
||||
this._uuid = uuid;
|
||||
this._version_tag = version_tag;
|
||||
this._name = name;
|
||||
|
||||
this.setButtons([{ label: _("Cancel"),
|
||||
action: Lang.bind(this, this._onCancelButtonPressed),
|
||||
key: Clutter.Escape
|
||||
},
|
||||
{ label: _("Install"),
|
||||
action: Lang.bind(this, this._onInstallButtonPressed)
|
||||
}]);
|
||||
|
||||
let message = _("Download and install '%s' from extensions.gnome.org?").format(name);
|
||||
|
||||
this._descriptionLabel = new St.Label({ text: message });
|
||||
|
||||
this.contentLayout.add(this._descriptionLabel,
|
||||
{ y_fill: true,
|
||||
y_align: St.Align.START });
|
||||
},
|
||||
|
||||
_onCancelButtonPressed: function(button, event) {
|
||||
this.close(global.get_current_time());
|
||||
|
||||
// Even though the extension is already "uninstalled", send through
|
||||
// a state-changed signal for any users who want to know if the install
|
||||
// went through correctly -- using proper async DBus would block more
|
||||
// traditional clients like the plugin
|
||||
let meta = { uuid: this._uuid,
|
||||
state: ExtensionState.UNINSTALLED,
|
||||
error: '' };
|
||||
|
||||
_signals.emit('extension-state-changed', meta);
|
||||
},
|
||||
|
||||
_onInstallButtonPressed: function(button, event) {
|
||||
let meta = { uuid: this._uuid,
|
||||
state: ExtensionState.DOWNLOADING,
|
||||
error: '' };
|
||||
|
||||
extensionMeta[this._uuid] = meta;
|
||||
|
||||
_signals.emit('extension-state-changed', meta);
|
||||
|
||||
let params = { version_tag: this._version_tag,
|
||||
shell_version: Config.PACKAGE_VERSION,
|
||||
api_version: API_VERSION.toString() };
|
||||
|
||||
let url = REPOSITORY_URL_DOWNLOAD.format(this._uuid);
|
||||
let message = Soup.form_request_new_from_hash('GET', url, params);
|
||||
|
||||
_httpSession.queue_message(message,
|
||||
Lang.bind(this, function(session, message) {
|
||||
gotExtensionZipFile(session, message, this._uuid);
|
||||
}));
|
||||
|
||||
this.close(global.get_current_time());
|
||||
}
|
||||
};
|
||||
|
@ -15,9 +15,11 @@ const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
|
||||
const KEYBOARD_SCHEMA = 'org.gnome.shell.keyboard';
|
||||
const SHOW_KEYBOARD = 'show-keyboard';
|
||||
const KEYBOARD_TYPE = 'keyboard-type';
|
||||
|
||||
const A11Y_APPLICATIONS_SCHEMA = 'org.gnome.desktop.a11y.applications';
|
||||
const SHOW_KEYBOARD = 'screen-keyboard-enabled';
|
||||
|
||||
// Key constants taken from Antler
|
||||
// FIXME: ought to be moved into libcaribou
|
||||
const PRETTY_KEYS = {
|
||||
@ -199,26 +201,25 @@ function Keyboard() {
|
||||
Keyboard.prototype = {
|
||||
_init: function () {
|
||||
DBus.session.exportObject('/org/gnome/Caribou/Keyboard', this);
|
||||
DBus.session.acquire_name('org.gnome.Caribou.Keyboard', 0, null, null);
|
||||
|
||||
this.actor = null;
|
||||
|
||||
this._timestamp = global.get_current_time();
|
||||
this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
|
||||
Main.layoutManager.keyboardBox.add_actor(this.actor);
|
||||
Main.layoutManager.trackChrome(this.actor);
|
||||
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._redraw));
|
||||
|
||||
this._keyboardSettings = new Gio.Settings({ schema: KEYBOARD_SCHEMA });
|
||||
this._keyboardSettings.connect('changed', Lang.bind(this, this._settingsChanged));
|
||||
this._a11yApplicationsSettings = new Gio.Settings({ schema: A11Y_APPLICATIONS_SCHEMA });
|
||||
this._a11yApplicationsSettings.connect('changed', Lang.bind(this, this._settingsChanged));
|
||||
this._settingsChanged();
|
||||
},
|
||||
|
||||
init: function () {
|
||||
if (this._enableKeyboard)
|
||||
this._redraw();
|
||||
this._redraw();
|
||||
},
|
||||
|
||||
_settingsChanged: function () {
|
||||
this._enableKeyboard = this._keyboardSettings.get_boolean(SHOW_KEYBOARD);
|
||||
this._enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
|
||||
if (!this._enableKeyboard && !this._keyboard)
|
||||
return;
|
||||
if (this._enableKeyboard && this._keyboard &&
|
||||
@ -239,12 +240,17 @@ Keyboard.prototype = {
|
||||
if (this._focusNotifyId)
|
||||
global.stage.disconnect(this._focusNotifyId);
|
||||
this._keyboard = null;
|
||||
this.actor.destroy_children();
|
||||
this.actor.destroy();
|
||||
this.actor = null;
|
||||
|
||||
this._destroySource();
|
||||
},
|
||||
|
||||
_setupKeyboard: function() {
|
||||
this.actor = new St.BoxLayout({ name: 'keyboard', vertical: true, reactive: true });
|
||||
Main.layoutManager.keyboardBox.add_actor(this.actor);
|
||||
Main.layoutManager.trackChrome(this.actor);
|
||||
|
||||
this._keyboard = new Caribou.KeyboardModel({ keyboard_type: this._keyboardSettings.get_string(KEYBOARD_TYPE) });
|
||||
this._groups = {};
|
||||
this._current_page = null;
|
||||
@ -263,15 +269,14 @@ Keyboard.prototype = {
|
||||
_onKeyFocusChanged: function () {
|
||||
let focus = global.stage.key_focus;
|
||||
|
||||
if (focus == global.stage || focus == null)
|
||||
// Showing an extended key popup will grab focus, but ignore that
|
||||
if (focus && focus._extended_keys)
|
||||
return;
|
||||
|
||||
if (focus instanceof Clutter.Text)
|
||||
this.show();
|
||||
else {
|
||||
if (focus._extended_keys == null)
|
||||
this.hide();
|
||||
}
|
||||
else
|
||||
this.hide();
|
||||
},
|
||||
|
||||
_addKeys: function () {
|
||||
@ -359,6 +364,9 @@ Keyboard.prototype = {
|
||||
},
|
||||
|
||||
_redraw: function () {
|
||||
if (!this._enableKeyboard)
|
||||
return;
|
||||
|
||||
let monitor = Main.layoutManager.bottomMonitor;
|
||||
let maxHeight = monitor.height / 3;
|
||||
this.actor.width = monitor.width;
|
||||
|
135
js/ui/layout.js
135
js/ui/layout.js
@ -40,20 +40,14 @@ LayoutManager.prototype = {
|
||||
this.panelBox.connect('allocation-changed',
|
||||
Lang.bind(this, this._updatePanelBarriers));
|
||||
|
||||
// bottomBox contains the tray and keyboard (which move
|
||||
// together, since the tray slides up from the top of the
|
||||
// keyboard when the keyboard is visible).
|
||||
this._bottomBox = new St.BoxLayout({ name: 'bottomBox',
|
||||
vertical: true });
|
||||
this.addChrome(this._bottomBox, { visibleInFullscreen: true });
|
||||
|
||||
this.trayBox = new St.BoxLayout({ name: 'trayBox' });
|
||||
this.addChrome(this.trayBox, { visibleInFullscreen: true });
|
||||
this.trayBox.connect('allocation-changed',
|
||||
Lang.bind(this, this._updateTrayBarrier));
|
||||
this._bottomBox.add_actor(this.trayBox);
|
||||
|
||||
this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox' });
|
||||
this._bottomBox.add_actor(this.keyboardBox);
|
||||
this.addChrome(this.keyboardBox, { visibleInFullscreen: true });
|
||||
this._keyboardHeightNotifyId = 0;
|
||||
|
||||
global.screen.connect('monitors-changed',
|
||||
Lang.bind(this, this._monitorsChanged));
|
||||
@ -153,11 +147,13 @@ LayoutManager.prototype = {
|
||||
this.panelBox.set_position(this.primaryMonitor.x, this.primaryMonitor.y);
|
||||
this.panelBox.set_size(this.primaryMonitor.width, -1);
|
||||
|
||||
this._bottomBox.set_position(this.bottomMonitor.x,
|
||||
this.bottomMonitor.y + this.bottomMonitor.height);
|
||||
this._bottomBox.set_size(this.bottomMonitor.width, -1);
|
||||
this.keyboardBox.set_position(this.bottomMonitor.x,
|
||||
this.bottomMonitor.y + this.bottomMonitor.height);
|
||||
this.keyboardBox.set_size(this.bottomMonitor.width, -1);
|
||||
|
||||
this.trayBox.width = this.bottomMonitor.width;
|
||||
this.trayBox.set_position(this.bottomMonitor.x,
|
||||
this.bottomMonitor.y + this.bottomMonitor.height);
|
||||
this.trayBox.set_size(this.bottomMonitor.width, -1);
|
||||
|
||||
// Set trayBox's clip to show things above it, but not below
|
||||
// it (so it's not visible behind the keyboard). The exact
|
||||
@ -250,23 +246,38 @@ LayoutManager.prototype = {
|
||||
},
|
||||
|
||||
_startupAnimation: function() {
|
||||
// Don't animate the strut
|
||||
this._chrome.freezeUpdateRegions();
|
||||
|
||||
this.panelBox.anchor_y = this.panelBox.height;
|
||||
Tweener.addTween(this.panelBox,
|
||||
{ anchor_y: 0,
|
||||
time: STARTUP_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad'
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: this._startupAnimationComplete,
|
||||
onCompleteScope: this
|
||||
});
|
||||
},
|
||||
|
||||
_startupAnimationComplete: function() {
|
||||
this._chrome.thawUpdateRegions();
|
||||
},
|
||||
|
||||
showKeyboard: function () {
|
||||
Main.messageTray.hide();
|
||||
Tweener.addTween(this._bottomBox,
|
||||
{ anchor_y: this._bottomBox.height,
|
||||
this.keyboardBox.raise_top();
|
||||
Tweener.addTween(this.keyboardBox,
|
||||
{ anchor_y: this.keyboardBox.height,
|
||||
time: KEYBOARD_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: this._showKeyboardComplete,
|
||||
onCompleteScope: this
|
||||
});
|
||||
Tweener.addTween(this.trayBox,
|
||||
{ anchor_y: this.keyboardBox.height,
|
||||
time: KEYBOARD_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
},
|
||||
|
||||
_showKeyboardComplete: function() {
|
||||
@ -274,20 +285,30 @@ LayoutManager.prototype = {
|
||||
// anchor point changes
|
||||
this._chrome.updateRegions();
|
||||
|
||||
this._bottomBox.connect('notify::height', Lang.bind(this, function () {
|
||||
this._bottomBoxAnchor = this._bottomBox.height;
|
||||
this._keyboardHeightNotifyId = this.keyboardBox.connect('notify::height', Lang.bind(this, function () {
|
||||
this.keyboardBox.anchor_y = this.keyboardBox.height;
|
||||
this.trayBox.anchor_y = this.keyboardBox.height;
|
||||
}));
|
||||
},
|
||||
|
||||
hideKeyboard: function (immediate) {
|
||||
Main.messageTray.hide();
|
||||
Tweener.addTween(this._bottomBox,
|
||||
if (this._keyboardHeightNotifyId) {
|
||||
this.keyboardBox.disconnect(this._keyboardHeightNotifyId);
|
||||
this._keyboardHeightNotifyId = 0;
|
||||
}
|
||||
Tweener.addTween(this.keyboardBox,
|
||||
{ anchor_y: 0,
|
||||
time: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: this._showKeyboardComplete,
|
||||
onComplete: this._hideKeyboardComplete,
|
||||
onCompleteScope: this
|
||||
});
|
||||
Tweener.addTween(this.trayBox,
|
||||
{ anchor_y: 0,
|
||||
time: immediate ? 0 : KEYBOARD_ANIMATION_TIME,
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
},
|
||||
|
||||
_hideKeyboardComplete: function() {
|
||||
@ -295,11 +316,11 @@ LayoutManager.prototype = {
|
||||
},
|
||||
|
||||
// addChrome:
|
||||
// @actor: an actor to add to the chrome layer
|
||||
// @actor: an actor to add to the chrome
|
||||
// @params: (optional) additional params
|
||||
//
|
||||
// Adds @actor to the chrome layer and (unless %affectsInputRegion
|
||||
// in @params is %false) extends the input region to include it.
|
||||
// Adds @actor to the chrome, and (unless %affectsInputRegion in
|
||||
// @params is %false) extends the input region to include it.
|
||||
// Changes in @actor's size, position, and visibility will
|
||||
// automatically result in appropriate changes to the input
|
||||
// region.
|
||||
@ -341,9 +362,9 @@ LayoutManager.prototype = {
|
||||
},
|
||||
|
||||
// removeChrome:
|
||||
// @actor: a child of the chrome layer
|
||||
// @actor: a chrome actor
|
||||
//
|
||||
// Removes @actor from the chrome layer
|
||||
// Removes @actor from the chrome
|
||||
removeChrome: function(actor) {
|
||||
this._chrome.removeActor(actor);
|
||||
}
|
||||
@ -542,13 +563,10 @@ Chrome.prototype = {
|
||||
_init: function(layoutManager) {
|
||||
this._layoutManager = layoutManager;
|
||||
|
||||
// The group itself has zero size so it doesn't interfere with DND
|
||||
this.actor = new Shell.GenericContainer({ width: 0, height: 0 });
|
||||
Main.uiGroup.add_actor(this.actor);
|
||||
this.actor.connect('allocate', Lang.bind(this, this._allocated));
|
||||
|
||||
this._monitors = [];
|
||||
this._inOverview = false;
|
||||
this._updateRegionIdle = 0;
|
||||
this._freezeUpdateCount = 0;
|
||||
|
||||
this._trackedActors = [];
|
||||
|
||||
@ -561,6 +579,7 @@ Chrome.prototype = {
|
||||
global.screen.connect('notify::n-workspaces',
|
||||
Lang.bind(this, this._queueUpdateRegions));
|
||||
|
||||
this._screenSaverActive = false;
|
||||
this._screenSaverProxy = new ScreenSaver.ScreenSaverProxy();
|
||||
this._screenSaverProxy.connect('ActiveChanged', Lang.bind(this, this._onScreenSaverActiveChanged));
|
||||
this._screenSaverProxy.GetActiveRemote(Lang.bind(this,
|
||||
@ -579,14 +598,8 @@ Chrome.prototype = {
|
||||
Lang.bind(this, this._overviewHidden));
|
||||
},
|
||||
|
||||
_allocated: function(actor, box, flags) {
|
||||
let children = this.actor.get_children();
|
||||
for (let i = 0; i < children.length; i++)
|
||||
children[i].allocate_preferred_size(flags);
|
||||
},
|
||||
|
||||
addActor: function(actor, params) {
|
||||
this.actor.add_actor(actor);
|
||||
Main.uiGroup.add_actor(actor);
|
||||
this._trackActor(actor, params);
|
||||
},
|
||||
|
||||
@ -598,7 +611,7 @@ Chrome.prototype = {
|
||||
index = this._findActor(ancestor);
|
||||
}
|
||||
if (!ancestor)
|
||||
throw new Error('actor is not a descendent of the chrome layer');
|
||||
throw new Error('actor is not a descendent of a chrome actor');
|
||||
|
||||
let ancestorData = this._trackedActors[index];
|
||||
if (!params)
|
||||
@ -618,7 +631,7 @@ Chrome.prototype = {
|
||||
},
|
||||
|
||||
removeActor: function(actor) {
|
||||
this.actor.remove_actor(actor);
|
||||
Main.uiGroup.remove_actor(actor);
|
||||
this._untrackActor(actor);
|
||||
},
|
||||
|
||||
@ -637,6 +650,7 @@ Chrome.prototype = {
|
||||
|
||||
let actorData = Params.parse(params, defaultParams);
|
||||
actorData.actor = actor;
|
||||
actorData.isToplevel = actor.get_parent() == Main.uiGroup;
|
||||
actorData.visibleId = actor.connect('notify::visible',
|
||||
Lang.bind(this, this._queueUpdateRegions));
|
||||
actorData.allocationId = actor.connect('notify::allocation',
|
||||
@ -666,18 +680,29 @@ Chrome.prototype = {
|
||||
},
|
||||
|
||||
_actorReparented: function(actor, oldParent) {
|
||||
if (!this.actor.contains(actor))
|
||||
let newParent = actor.get_parent();
|
||||
if (!newParent)
|
||||
this._untrackActor(actor);
|
||||
else
|
||||
actorData.isToplevel = (newParent == Main.uiGroup);
|
||||
},
|
||||
|
||||
_updateVisibility: function() {
|
||||
for (let i = 0; i < this._trackedActors.length; i++) {
|
||||
let actorData = this._trackedActors[i];
|
||||
if (!this._inOverview && !actorData.visibleInFullscreen &&
|
||||
this._findMonitorForActor(actorData.actor).inFullscreen)
|
||||
this.actor.set_skip_paint(actorData.actor, true);
|
||||
let actorData = this._trackedActors[i], visible;
|
||||
if (!actorData.isToplevel)
|
||||
continue;
|
||||
|
||||
if (this._screenSaverActive)
|
||||
visible = false;
|
||||
else if (this._inOverview)
|
||||
visible = true;
|
||||
else if (!actorData.visibleInFullscreen &&
|
||||
this._findMonitorForActor(actorData.actor).inFullscreen)
|
||||
visible = false;
|
||||
else
|
||||
this.actor.set_skip_paint(actorData.actor, false);
|
||||
visible = true;
|
||||
Main.uiGroup.set_skip_paint(actorData.actor, !visible);
|
||||
}
|
||||
},
|
||||
|
||||
@ -703,7 +728,8 @@ Chrome.prototype = {
|
||||
},
|
||||
|
||||
_onScreenSaverActiveChanged: function(proxy, screenSaverActive) {
|
||||
this.actor.visible = !screenSaverActive;
|
||||
this._screenSaverActive = screenSaverActive;
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
@ -744,11 +770,22 @@ Chrome.prototype = {
|
||||
},
|
||||
|
||||
_queueUpdateRegions: function() {
|
||||
if (!this._updateRegionIdle)
|
||||
if (!this._updateRegionIdle && !this._freezeUpdateCount)
|
||||
this._updateRegionIdle = Mainloop.idle_add(Lang.bind(this, this.updateRegions),
|
||||
Meta.PRIORITY_BEFORE_REDRAW);
|
||||
},
|
||||
|
||||
freezeUpdateRegions: function() {
|
||||
if (this._updateRegionIdle)
|
||||
this.updateRegions();
|
||||
this._freezeUpdateCount++;
|
||||
},
|
||||
|
||||
thawUpdateRegions: function() {
|
||||
this._freezeUpdateCount--;
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_updateFullscreen: function() {
|
||||
let windows = Main.getWindowActorsForWorkspace(global.screen.get_active_workspace_index());
|
||||
|
||||
@ -756,7 +793,7 @@ Chrome.prototype = {
|
||||
for (let i = 0; i < this._monitors.length; i++)
|
||||
this._monitors[i].inFullscreen = false;
|
||||
|
||||
// The chrome layer should be visible unless there is a window
|
||||
// Ordinary chrome should be visible unless there is a window
|
||||
// with layer FULLSCREEN, or a window with layer
|
||||
// OVERRIDE_REDIRECT that covers the whole screen.
|
||||
// ('override_redirect' is not actually a layer above all
|
||||
@ -837,7 +874,7 @@ Chrome.prototype = {
|
||||
|
||||
if (actorData.affectsInputRegion &&
|
||||
actorData.actor.get_paint_visibility() &&
|
||||
!this.actor.get_skip_paint(actorData.actor))
|
||||
!Main.uiGroup.get_skip_paint(actorData.actor))
|
||||
rects.push(rect);
|
||||
|
||||
if (!actorData.affectsStruts)
|
||||
|
@ -6,6 +6,7 @@ const GConf = imports.gi.GConf;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Pango = imports.gi.Pango;
|
||||
const St = imports.gi.St;
|
||||
const Shell = imports.gi.Shell;
|
||||
@ -606,6 +607,9 @@ Memory.prototype = {
|
||||
this._gjs_closure = new St.Label();
|
||||
this.actor.add(this._gjs_closure);
|
||||
|
||||
this._last_gc_seconds_ago = new St.Label();
|
||||
this.actor.add(this._last_gc_seconds_ago);
|
||||
|
||||
this._gcbutton = new St.Button({ label: 'Full GC',
|
||||
style_class: 'lg-obj-inspector-button' });
|
||||
this._gcbutton.connect('clicked', Lang.bind(this, function () { global.gc(); this._renderText(); }));
|
||||
@ -625,6 +629,7 @@ Memory.prototype = {
|
||||
this._gjs_gobject.text = 'gjs_gobject: ' + memInfo.gjs_gobject;
|
||||
this._gjs_function.text = 'gjs_function: ' + memInfo.gjs_function;
|
||||
this._gjs_closure.text = 'gjs_closure: ' + memInfo.gjs_closure;
|
||||
this._last_gc_seconds_ago.text = 'last_gc_seconds_ago: ' + memInfo.last_gc_seconds_ago;
|
||||
}
|
||||
};
|
||||
|
||||
@ -761,9 +766,13 @@ LookingGlass.prototype = {
|
||||
Lang.bind(this, this._updateFont));
|
||||
this._updateFont();
|
||||
|
||||
// we add it to the chrome because we want it to appear to slide
|
||||
// out from underneath the panel
|
||||
Main.layoutManager.addChrome(this.actor);
|
||||
// We want it to appear to slide out from underneath the panel
|
||||
Main.layoutManager.panelBox.add_actor(this.actor);
|
||||
this.actor.lower_bottom();
|
||||
Main.layoutManager.panelBox.connect('allocation-changed',
|
||||
Lang.bind(this, this._queueResize));
|
||||
Main.layoutManager.keyboardBox.connect('allocation-changed',
|
||||
Lang.bind(this, this._queueResize));
|
||||
|
||||
this._objInspector = new ObjInspector();
|
||||
Main.uiGroup.add_actor(this._objInspector.actor);
|
||||
@ -844,6 +853,8 @@ LookingGlass.prototype = {
|
||||
|
||||
this._history = new History.HistoryManager({ gsettingsKey: HISTORY_KEY,
|
||||
entry: this._entry.clutter_text });
|
||||
|
||||
this._resize();
|
||||
},
|
||||
|
||||
_updateFont: function() {
|
||||
@ -918,13 +929,18 @@ LookingGlass.prototype = {
|
||||
this.open();
|
||||
},
|
||||
|
||||
_resizeTo: function(actor) {
|
||||
_queueResize: function() {
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
|
||||
Lang.bind(this, function () { this._resize(); }));
|
||||
},
|
||||
|
||||
_resize: function() {
|
||||
let primary = Main.layoutManager.primaryMonitor;
|
||||
let myWidth = primary.width * 0.7;
|
||||
let myHeight = primary.height * 0.7;
|
||||
let [srcX, srcY] = actor.get_transformed_position();
|
||||
this.actor.x = srcX + (primary.width - myWidth) / 2;
|
||||
this._hiddenY = srcY + actor.height - myHeight - 4; // -4 to hide the top corners
|
||||
let availableHeight = primary.height - Main.layoutManager.keyboardBox.height;
|
||||
let myHeight = Math.min(primary.height * 0.7, availableHeight * 0.9);
|
||||
this.actor.x = (primary.width - myWidth) / 2;
|
||||
this._hiddenY = this.actor.get_parent().height - myHeight - 4; // -4 to hide the top corners
|
||||
this._targetY = this._hiddenY + myHeight;
|
||||
this.actor.y = this._hiddenY;
|
||||
this.actor.width = myWidth;
|
||||
@ -934,14 +950,6 @@ LookingGlass.prototype = {
|
||||
this._targetY + Math.floor(myHeight * 0.1));
|
||||
},
|
||||
|
||||
slaveTo: function(actor) {
|
||||
this._slaveTo = actor;
|
||||
actor.connect('notify::allocation', Lang.bind(this, function () {
|
||||
this._resizeTo(actor);
|
||||
}));
|
||||
this._resizeTo(actor);
|
||||
},
|
||||
|
||||
insertObject: function(obj) {
|
||||
this._pushResult('<insert>', obj);
|
||||
},
|
||||
@ -974,7 +982,6 @@ LookingGlass.prototype = {
|
||||
|
||||
this._notebook.selectIndex(0);
|
||||
this.actor.show();
|
||||
this.actor.lower_bottom();
|
||||
this._open = true;
|
||||
this._history.lastItem();
|
||||
|
||||
@ -1005,7 +1012,6 @@ LookingGlass.prototype = {
|
||||
|
||||
Main.popModal(this._entry);
|
||||
|
||||
this.actor.lower_bottom();
|
||||
Tweener.addTween(this.actor, { time: 0.5 / St.get_slow_down_factor(),
|
||||
transition: 'easeOutQuad',
|
||||
y: this._hiddenY,
|
||||
|
@ -193,7 +193,13 @@ function start() {
|
||||
loadTheme();
|
||||
|
||||
// Set up stage hierarchy to group all UI actors under one container.
|
||||
uiGroup = new Clutter.Group();
|
||||
uiGroup = new Shell.GenericContainer({ name: 'uiGroup' });
|
||||
uiGroup.connect('allocate',
|
||||
function (actor, box, flags) {
|
||||
let children = uiGroup.get_children();
|
||||
for (let i = 0; i < children.length; i++)
|
||||
children[i].allocate_preferred_size(flags);
|
||||
});
|
||||
St.set_ui_root(global.stage, uiGroup);
|
||||
global.window_group.reparent(uiGroup);
|
||||
global.overlay_group.reparent(uiGroup);
|
||||
@ -220,6 +226,7 @@ function start() {
|
||||
|
||||
panel.startStatusArea();
|
||||
|
||||
layoutManager.init();
|
||||
keyboard.init();
|
||||
overview.init();
|
||||
|
||||
@ -588,9 +595,9 @@ function _globalKeyPressHandler(actor, event) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Other bindings are only available when the overview is up and
|
||||
// Other bindings are only available to the user session when the overview is up and
|
||||
// no modal dialog is present.
|
||||
if (!overview.visible || modalCount > 1)
|
||||
if (global.session_type == Shell.SessionType.USER && (!overview.visible || modalCount > 1))
|
||||
return false;
|
||||
|
||||
// This isn't a Meta.KeyBindingAction yet
|
||||
@ -600,7 +607,8 @@ function _globalKeyPressHandler(actor, event) {
|
||||
}
|
||||
|
||||
if (action == Meta.KeyBindingAction.SWITCH_PANELS) {
|
||||
ctrlAltTabManager.popup(modifierState & Clutter.ModifierType.SHIFT_MASK);
|
||||
ctrlAltTabManager.popup(modifierState & Clutter.ModifierType.SHIFT_MASK,
|
||||
modifierState);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -758,7 +766,6 @@ function popModal(actor, timestamp) {
|
||||
function createLookingGlass() {
|
||||
if (lookingGlass == null) {
|
||||
lookingGlass = new LookingGlass.LookingGlass();
|
||||
lookingGlass.slaveTo(panel.actor);
|
||||
}
|
||||
return lookingGlass;
|
||||
}
|
||||
|
@ -111,12 +111,21 @@ URLHighlighter.prototype = {
|
||||
|
||||
this.setMarkup(text, allowMarkup);
|
||||
this.actor.connect('button-press-event', Lang.bind(this, function(actor, event) {
|
||||
// Don't try to URL highlight when invisible.
|
||||
// The MessageTray doesn't actually hide us, so
|
||||
// we need to check for paint opacities as well.
|
||||
if (!actor.visible || actor.get_paint_opacity() == 0)
|
||||
return false;
|
||||
|
||||
// Keep Notification.actor from seeing this and taking
|
||||
// a pointer grab, which would block our button-release-event
|
||||
// handler, if an URL is clicked
|
||||
return this._findUrlAtPos(event) != -1;
|
||||
}));
|
||||
this.actor.connect('button-release-event', Lang.bind(this, function (actor, event) {
|
||||
if (!actor.visible || actor.get_paint_opacity() == 0)
|
||||
return false;
|
||||
|
||||
let urlId = this._findUrlAtPos(event);
|
||||
if (urlId != -1) {
|
||||
let url = this._urls[urlId].url;
|
||||
@ -134,6 +143,9 @@ URLHighlighter.prototype = {
|
||||
return false;
|
||||
}));
|
||||
this.actor.connect('motion-event', Lang.bind(this, function(actor, event) {
|
||||
if (!actor.visible || actor.get_paint_opacity() == 0)
|
||||
return false;
|
||||
|
||||
let urlId = this._findUrlAtPos(event);
|
||||
if (urlId != -1 && !this._cursorChanged) {
|
||||
global.set_cursor(Shell.Cursor.POINTING_HAND);
|
||||
@ -145,6 +157,9 @@ URLHighlighter.prototype = {
|
||||
return false;
|
||||
}));
|
||||
this.actor.connect('leave-event', Lang.bind(this, function() {
|
||||
if (!this.actor.visible || this.actor.get_paint_opacity() == 0)
|
||||
return;
|
||||
|
||||
if (this._cursorChanged) {
|
||||
this._cursorChanged = false;
|
||||
global.unset_cursor();
|
||||
@ -269,7 +284,8 @@ FocusGrabber.prototype = {
|
||||
let source = event.get_source();
|
||||
switch (event.type()) {
|
||||
case Clutter.EventType.BUTTON_PRESS:
|
||||
if (!this.actor.contains(source) && !Main.keyboard.actor.contains(source))
|
||||
if (!this.actor.contains(source) &&
|
||||
!Main.layoutManager.keyboardBox.contains(source))
|
||||
this.emit('button-pressed', source);
|
||||
break;
|
||||
case Clutter.EventType.KEY_PRESS:
|
||||
@ -776,11 +792,12 @@ Notification.prototype = {
|
||||
},
|
||||
|
||||
_bannerBoxAllocate: function(actor, box, flags) {
|
||||
let [titleMinW, titleNatW] = this._titleLabel.get_preferred_width(-1);
|
||||
let [titleMinH, titleNatH] = this._titleLabel.get_preferred_height(-1);
|
||||
let [bannerMinW, bannerNatW] = this._bannerLabel.get_preferred_width(-1);
|
||||
let availWidth = box.x2 - box.x1;
|
||||
|
||||
let [titleMinW, titleNatW] = this._titleLabel.get_preferred_width(-1);
|
||||
let [titleMinH, titleNatH] = this._titleLabel.get_preferred_height(availWidth);
|
||||
let [bannerMinW, bannerNatW] = this._bannerLabel.get_preferred_width(availWidth);
|
||||
|
||||
let titleBox = new Clutter.ActorBox();
|
||||
let titleBoxW = Math.min(titleNatW, availWidth);
|
||||
if (this._titleDirection == St.TextDirection.RTL) {
|
||||
@ -1154,9 +1171,7 @@ SummaryItem.prototype = {
|
||||
this.notificationStack = new St.BoxLayout({ name: 'summary-notification-stack',
|
||||
vertical: true });
|
||||
this.notificationStackView.add_actor(this.notificationStack);
|
||||
this._notificationExpandedIds = [];
|
||||
this._notificationDoneDisplayingIds = [];
|
||||
this._notificationDestroyedIds = [];
|
||||
this._stackedNotifications = [];
|
||||
|
||||
this._oldMaxScrollAdjustment = 0;
|
||||
|
||||
@ -1225,18 +1240,19 @@ SummaryItem.prototype = {
|
||||
|
||||
doneShowingNotificationStack: function() {
|
||||
let notificationActors = this.notificationStack.get_children();
|
||||
for (let i = 0; i < notificationActors.length; i++) {
|
||||
notificationActors[i]._delegate.collapseCompleted();
|
||||
notificationActors[i]._delegate.disconnect(this._notificationExpandedIds[i]);
|
||||
notificationActors[i]._delegate.disconnect(this._notificationDoneDisplayingIds[i]);
|
||||
notificationActors[i]._delegate.disconnect(this._notificationDestroyedIds[i]);
|
||||
this.notificationStack.remove_actor(notificationActors[i]);
|
||||
notificationActors[i]._delegate.setIconVisible(true);
|
||||
notificationActors[i]._delegate.enableScrolling(true);
|
||||
for (let i = 0; i < this._stackedNotifications.length; i++) {
|
||||
let stackedNotification = this._stackedNotifications[i];
|
||||
let notification = stackedNotification.notification;
|
||||
notification.collapseCompleted();
|
||||
notification.disconnect(stackedNotification.notificationExpandedId);
|
||||
notification.disconnect(stackedNotification.notificationDoneDisplayingId);
|
||||
notification.disconnect(stackedNotification.notificationDestroyedId);
|
||||
if (notification.actor.get_parent() == this.notificationStack)
|
||||
this.notificationStack.remove_actor(notification.actor);
|
||||
notification.setIconVisible(true);
|
||||
notification.enableScrolling(true);
|
||||
}
|
||||
this._notificationExpandedIds = [];
|
||||
this._notificationDoneDisplayingIds = [];
|
||||
this._notificationDestroyedIds = [];
|
||||
this._stackedNotifications = [];
|
||||
},
|
||||
|
||||
_notificationAddedToSource: function(source, notification) {
|
||||
@ -1245,12 +1261,12 @@ SummaryItem.prototype = {
|
||||
},
|
||||
|
||||
_appendNotificationToStack: function(notification) {
|
||||
let notificationExpandedId = notification.connect('expanded', Lang.bind(this, this._contentUpdated));
|
||||
this._notificationExpandedIds.push(notificationExpandedId);
|
||||
let notificationDoneDisplayingId = notification.connect('done-displaying', Lang.bind(this, this._notificationDoneDisplaying));
|
||||
this._notificationDoneDisplayingIds.push(notificationDoneDisplayingId);
|
||||
let notificationDestroyedId = notification.connect('destroy', Lang.bind(this, this._notificationDestroyed));
|
||||
this._notificationDestroyedIds.push(notificationDestroyedId);
|
||||
let stackedNotification = {};
|
||||
stackedNotification.notification = notification;
|
||||
stackedNotification.notificationExpandedId = notification.connect('expanded', Lang.bind(this, this._contentUpdated));
|
||||
stackedNotification.notificationDoneDisplayingId = notification.connect('done-displaying', Lang.bind(this, this._notificationDoneDisplaying));
|
||||
stackedNotification.notificationDestroyedId = notification.connect('destroy', Lang.bind(this, this._notificationDestroyed));
|
||||
this._stackedNotifications.push(stackedNotification);
|
||||
if (!this.source.isChat)
|
||||
notification.enableScrolling(false);
|
||||
if (this.notificationStack.get_children().length > 0)
|
||||
@ -1280,17 +1296,18 @@ SummaryItem.prototype = {
|
||||
},
|
||||
|
||||
_notificationDestroyed: function(notification) {
|
||||
let index = this.notificationStack.get_children().indexOf(notification.actor);
|
||||
if (index >= 0) {
|
||||
notification.disconnect(this._notificationExpandedIds[index]);
|
||||
this._notificationExpandedIds.splice(index, 1);
|
||||
notification.disconnect(this._notificationDoneDisplayingIds[index]);
|
||||
this._notificationDoneDisplayingIds.splice(index, 1);
|
||||
notification.disconnect(this._notificationDestroyedIds[index]);
|
||||
this._notificationDestroyedIds.splice(index, 1);
|
||||
this.notificationStack.remove_actor(notification.actor);
|
||||
this._contentUpdated();
|
||||
for (let i = 0; i < this._stackedNotifications.length; i++) {
|
||||
if (this._stackedNotifications[i].notification == notification) {
|
||||
let stackedNotification = this._stackedNotifications[i];
|
||||
notification.disconnect(stackedNotification.notificationExpandedId);
|
||||
notification.disconnect(stackedNotification.notificationDoneDisplayingId);
|
||||
notification.disconnect(stackedNotification.notificationDestroyedId);
|
||||
this._stackedNotifications.splice(i, 1);
|
||||
this._contentUpdated();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.notificationStack.get_children().length > 0)
|
||||
this.notificationStack.get_children()[0]._delegate.setIconVisible(true);
|
||||
}
|
||||
@ -1479,8 +1496,11 @@ MessageTray.prototype = {
|
||||
// after notifications are done showing. However, we don't want that to happen for
|
||||
// transient sources, which are removed after the notification is shown, but are
|
||||
// not removed fast enough because of the callbacks to avoid the summary popping up.
|
||||
// So we just don't add transient sources to this._newSummaryItems .
|
||||
if (!source.isTransient)
|
||||
// So we just don't add transient sources to this._newSummaryItems.
|
||||
// We don't want that to happen for chat sources neither, because they
|
||||
// can be added when the user starts a chat from Empathy and they are not transient.
|
||||
// The notification will popup on incoming message anyway. See bug #657249.
|
||||
if (!source.isTransient && !source.isChat)
|
||||
this._newSummaryItems.push(summaryItem);
|
||||
|
||||
source.connect('notify', Lang.bind(this, this._onNotify));
|
||||
@ -2222,7 +2242,7 @@ MessageTray.prototype = {
|
||||
_showSummaryBoxPointer: function() {
|
||||
this._summaryBoxPointerItem = this._clickedSummaryItem;
|
||||
this._summaryBoxPointerContentUpdatedId = this._summaryBoxPointerItem.connect('content-updated',
|
||||
Lang.bind(this, this._adjustSummaryBoxPointerPosition));
|
||||
Lang.bind(this, this._onSummaryBoxPointerContentUpdated));
|
||||
this._summaryBoxPointerDoneDisplayingId = this._summaryBoxPointerItem.connect('done-displaying-content',
|
||||
Lang.bind(this, this._escapeTray));
|
||||
if (this._clickedSummaryItemMouseButton == 1) {
|
||||
@ -2257,6 +2277,13 @@ MessageTray.prototype = {
|
||||
}));
|
||||
},
|
||||
|
||||
_onSummaryBoxPointerContentUpdated: function() {
|
||||
if (this._summaryBoxPointerItem.notificationStack.get_children().length == 0)
|
||||
this._hideSummaryBoxPointer();
|
||||
this._adjustSummaryBoxPointerPosition();
|
||||
|
||||
},
|
||||
|
||||
_adjustSummaryBoxPointerPosition: function() {
|
||||
// The position of the arrow origin should be the same as center of this._clickedSummaryItem.actor
|
||||
if (!this._clickedSummaryItem)
|
||||
@ -2280,6 +2307,14 @@ MessageTray.prototype = {
|
||||
},
|
||||
|
||||
_hideSummaryBoxPointer: function() {
|
||||
// We should be sure to hide the box pointer if all notifications in it are destroyed while
|
||||
// it is hiding, so that we don't show an an animation of an empty blob being hidden.
|
||||
if (this._summaryBoxPointerState == State.HIDING &&
|
||||
this._summaryBoxPointerItem.notificationStack.get_children().length == 0) {
|
||||
this._summaryBoxPointer.actor.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
this._summaryBoxPointerState = State.HIDING;
|
||||
// Unset this._clickedSummaryItem if we are no longer showing the summary
|
||||
if (this._summaryState != State.SHOWN)
|
||||
|
@ -110,9 +110,8 @@ ModalDialog.prototype = {
|
||||
this._buttonLayout.destroy_children();
|
||||
this._actionKeys = {};
|
||||
|
||||
let i = 0;
|
||||
for (let index in buttons) {
|
||||
let buttonInfo = buttons[index];
|
||||
for (let i = 0; i < buttons.length; i ++) {
|
||||
let buttonInfo = buttons[i];
|
||||
let label = buttonInfo['label'];
|
||||
let action = buttonInfo['action'];
|
||||
let key = buttonInfo['key'];
|
||||
@ -132,7 +131,9 @@ ModalDialog.prototype = {
|
||||
else
|
||||
x_alignment = St.Align.MIDDLE;
|
||||
|
||||
this._initialKeyFocus = buttonInfo.button;
|
||||
if (this._initialKeyFocus == this._dialogLayout ||
|
||||
this._buttonLayout.contains(this._initialKeyFocus))
|
||||
this._initialKeyFocus = buttonInfo.button;
|
||||
this._buttonLayout.add(buttonInfo.button,
|
||||
{ expand: true,
|
||||
x_fill: false,
|
||||
@ -144,11 +145,10 @@ ModalDialog.prototype = {
|
||||
|
||||
if (key)
|
||||
this._actionKeys[key] = action;
|
||||
i++;
|
||||
}
|
||||
|
||||
// Fade in buttons if there weren't any before
|
||||
if (!hadChildren && i > 0) {
|
||||
if (!hadChildren && buttons.length > 0) {
|
||||
this._buttonLayout.opacity = 0;
|
||||
Tweener.addTween(this._buttonLayout,
|
||||
{ opacity: 255,
|
||||
|
@ -91,6 +91,7 @@ NetworkSecretDialog.prototype = {
|
||||
}
|
||||
|
||||
let secretTable = new St.Table({ style_class: 'network-dialog-secret-table' });
|
||||
let initialFocusSet = false;
|
||||
let pos = 0;
|
||||
for (let i = 0; i < this._content.secrets.length; i++) {
|
||||
let secret = this._content.secrets[i];
|
||||
@ -109,6 +110,12 @@ NetworkSecretDialog.prototype = {
|
||||
secret.valid = secret.value.length > 0;
|
||||
|
||||
if (reactive) {
|
||||
if (!initialFocusSet) {
|
||||
this.setInitialKeyFocus(secret.entry);
|
||||
initialFocusSet = true;
|
||||
}
|
||||
|
||||
secret.entry.clutter_text.connect('activate', Lang.bind(this, this._onOk));
|
||||
secret.entry.clutter_text.connect('text-changed', Lang.bind(this, function() {
|
||||
secret.value = secret.entry.get_text();
|
||||
if (secret.validate)
|
||||
@ -360,7 +367,7 @@ NetworkSecretDialog.prototype = {
|
||||
case 'bluetooth':
|
||||
content.title = _("Mobile broadband network password");
|
||||
content.message = _("A password is required to connect to '%s'.").format(connectionSetting.get_id());
|
||||
this._getMobileSecrets(content.secrets);
|
||||
this._getMobileSecrets(content.secrets, connectionType);
|
||||
break;
|
||||
default:
|
||||
log('Invalid connection type: ' + connectionType);
|
||||
|
@ -208,11 +208,11 @@ Overview.prototype = {
|
||||
this._viewSelector.addViewTab('applications', _("Applications"), appView.actor, 'system-run');
|
||||
|
||||
// Default search providers
|
||||
this._viewSelector.addSearchProvider(new AppDisplay.AppSearchProvider());
|
||||
this._viewSelector.addSearchProvider(new AppDisplay.SettingsSearchProvider());
|
||||
this._viewSelector.addSearchProvider(new PlaceDisplay.PlaceSearchProvider());
|
||||
this._viewSelector.addSearchProvider(new DocDisplay.DocSearchProvider());
|
||||
this._viewSelector.addSearchProvider(new ContactDisplay.ContactSearchProvider());
|
||||
this.addSearchProvider(new AppDisplay.AppSearchProvider());
|
||||
this.addSearchProvider(new AppDisplay.SettingsSearchProvider());
|
||||
this.addSearchProvider(new PlaceDisplay.PlaceSearchProvider());
|
||||
this.addSearchProvider(new DocDisplay.DocSearchProvider());
|
||||
this.addSearchProvider(new ContactDisplay.ContactSearchProvider());
|
||||
|
||||
// TODO - recalculate everything when desktop size changes
|
||||
this._dash = new Dash.Dash();
|
||||
@ -233,6 +233,14 @@ Overview.prototype = {
|
||||
this._relayout();
|
||||
},
|
||||
|
||||
addSearchProvider: function(provider) {
|
||||
this._viewSelector.addSearchProvider(provider);
|
||||
},
|
||||
|
||||
removeSearchProvider: function(provider) {
|
||||
this._viewSelector.removeSearchProvider(provider);
|
||||
},
|
||||
|
||||
setMessage: function(text, undoCallback, undoLabel) {
|
||||
if (this.isDummy)
|
||||
return;
|
||||
|
157
js/ui/panel.js
157
js/ui/panel.js
@ -16,7 +16,6 @@ const Layout = imports.ui.layout;
|
||||
const Overview = imports.ui.overview;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
const UserMenu = imports.ui.userMenu;
|
||||
const DateMenu = imports.ui.dateMenu;
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
@ -28,29 +27,31 @@ const BUTTON_DND_ACTIVATION_TIMEOUT = 250;
|
||||
const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
|
||||
const SPINNER_ANIMATION_TIME = 0.2;
|
||||
|
||||
const STANDARD_TRAY_ICON_ORDER = ['a11y', 'keyboard', 'volume', 'bluetooth', 'network', 'battery'];
|
||||
const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION = {
|
||||
const STANDARD_STATUS_AREA_ORDER = ['a11y', 'keyboard', 'volume', 'bluetooth', 'network', 'battery', 'userMenu'];
|
||||
const STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION = {
|
||||
'a11y': imports.ui.status.accessibility.ATIndicator,
|
||||
'volume': imports.ui.status.volume.Indicator,
|
||||
'battery': imports.ui.status.power.Indicator,
|
||||
'keyboard': imports.ui.status.keyboard.XKBIndicator
|
||||
'keyboard': imports.ui.status.keyboard.XKBIndicator,
|
||||
'userMenu': imports.ui.userMenu.UserMenuButton
|
||||
};
|
||||
|
||||
if (Config.HAVE_BLUETOOTH)
|
||||
STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['bluetooth'] = imports.ui.status.bluetooth.Indicator;
|
||||
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['bluetooth'] = imports.ui.status.bluetooth.Indicator;
|
||||
|
||||
try {
|
||||
STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['network'] = imports.ui.status.network.NMApplet;
|
||||
STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['network'] = imports.ui.status.network.NMApplet;
|
||||
} catch(e) {
|
||||
log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
|
||||
}
|
||||
|
||||
const GDM_TRAY_ICON_ORDER = ['a11y', 'display', 'keyboard', 'volume', 'battery'];
|
||||
const GDM_TRAY_ICON_SHELL_IMPLEMENTATION = {
|
||||
const GDM_STATUS_AREA_ORDER = ['a11y', 'display', 'keyboard', 'volume', 'battery', 'powerMenu'];
|
||||
const GDM_STATUS_AREA_SHELL_IMPLEMENTATION = {
|
||||
'a11y': imports.ui.status.accessibility.ATIndicator,
|
||||
'volume': imports.ui.status.volume.Indicator,
|
||||
'battery': imports.ui.status.power.Indicator,
|
||||
'keyboard': imports.ui.status.keyboard.XKBIndicator
|
||||
'keyboard': imports.ui.status.keyboard.XKBIndicator,
|
||||
'powerMenu': imports.gdm.powerMenu.PowerMenuButton
|
||||
};
|
||||
|
||||
// To make sure the panel corners blend nicely with the panel,
|
||||
@ -248,7 +249,7 @@ AppMenuButton.prototype = {
|
||||
this._targetApp = null;
|
||||
|
||||
let bin = new St.Bin({ name: 'appMenu' });
|
||||
this.actor.set_child(bin);
|
||||
this.actor.add_actor(bin);
|
||||
|
||||
this.actor.reactive = false;
|
||||
this._targetIsCurrent = false;
|
||||
@ -292,8 +293,9 @@ AppMenuButton.prototype = {
|
||||
this._spinner.actor.lower_bottom();
|
||||
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
let appSys = Shell.AppSystem.get_default();
|
||||
tracker.connect('notify::focus-app', Lang.bind(this, this._sync));
|
||||
tracker.connect('app-state-changed', Lang.bind(this, this._onAppStateChanged));
|
||||
appSys.connect('app-state-changed', Lang.bind(this, this._onAppStateChanged));
|
||||
|
||||
global.window_manager.connect('switch-workspace', Lang.bind(this, this._sync));
|
||||
|
||||
@ -457,7 +459,7 @@ AppMenuButton.prototype = {
|
||||
this._targetApp.request_quit();
|
||||
},
|
||||
|
||||
_onAppStateChanged: function(tracker, app) {
|
||||
_onAppStateChanged: function(appSys, app) {
|
||||
let state = app.state;
|
||||
if (state != Shell.AppState.STARTING) {
|
||||
this._startingApps = this._startingApps.filter(function(a) {
|
||||
@ -562,10 +564,10 @@ ActivitiesButton.prototype = {
|
||||
PanelMenu.Button.prototype._init.call(this, 0.0);
|
||||
|
||||
let container = new Shell.GenericContainer();
|
||||
container.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||
container.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||
container.connect('allocate', Lang.bind(this, this._allocate));
|
||||
this.actor.child = container;
|
||||
container.connect('get-preferred-width', Lang.bind(this, this._containerGetPreferredWidth));
|
||||
container.connect('get-preferred-height', Lang.bind(this, this._containerGetPreferredHeight));
|
||||
container.connect('allocate', Lang.bind(this, this._containerAllocate));
|
||||
this.actor.add_actor(container);
|
||||
this.actor.name = 'panelActivities';
|
||||
|
||||
/* Translators: If there is no suitable word for "Activities"
|
||||
@ -597,15 +599,15 @@ ActivitiesButton.prototype = {
|
||||
this._xdndTimeOut = 0;
|
||||
},
|
||||
|
||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||
_containerGetPreferredWidth: function(actor, forHeight, alloc) {
|
||||
[alloc.min_size, alloc.natural_size] = this._label.get_preferred_width(forHeight);
|
||||
},
|
||||
|
||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||
_containerGetPreferredHeight: function(actor, forWidth, alloc) {
|
||||
[alloc.min_size, alloc.natural_size] = this._label.get_preferred_height(forWidth);
|
||||
},
|
||||
|
||||
_allocate: function(actor, box, flags) {
|
||||
_containerAllocate: function(actor, box, flags) {
|
||||
this._label.allocate(box, flags);
|
||||
|
||||
// The hot corner needs to be outside any padding/alignment
|
||||
@ -763,16 +765,28 @@ PanelCorner.prototype = {
|
||||
},
|
||||
|
||||
_boxStyleChanged: function() {
|
||||
let button;
|
||||
let side = this._side;
|
||||
|
||||
if (this._side == St.Side.LEFT)
|
||||
let rtlAwareContainer = this._box instanceof St.BoxLayout;
|
||||
if (rtlAwareContainer &&
|
||||
this._box.get_direction() == St.TextDirection.RTL) {
|
||||
if (this._side == St.Side.LEFT)
|
||||
side = St.Side.RIGHT;
|
||||
else if (this._side == St.Side.RIGHT)
|
||||
side = St.Side.LEFT;
|
||||
}
|
||||
|
||||
let button;
|
||||
if (side == St.Side.LEFT)
|
||||
button = this._findLeftmostButton(this._box);
|
||||
else if (this._side == St.Side.RIGHT)
|
||||
else if (side == St.Side.RIGHT)
|
||||
button = this._findRightmostButton(this._box);
|
||||
|
||||
if (button) {
|
||||
if (this._button && this._buttonStyleChangedSignalId)
|
||||
if (this._button && this._buttonStyleChangedSignalId) {
|
||||
this._button.disconnect(this._buttonStyleChangedSignalId);
|
||||
this._button.style = null;
|
||||
}
|
||||
|
||||
this._button = button;
|
||||
|
||||
@ -790,6 +804,10 @@ PanelCorner.prototype = {
|
||||
let pseudoClass = button.get_style_pseudo_class();
|
||||
this.actor.set_style_pseudo_class(pseudoClass);
|
||||
}));
|
||||
|
||||
// The corner doesn't support theme transitions, so override
|
||||
// the .panel-button default
|
||||
button.style = 'transition-duration: 0';
|
||||
}
|
||||
},
|
||||
|
||||
@ -884,14 +902,6 @@ Panel.prototype = {
|
||||
this.actor.remove_style_class_name('in-overview');
|
||||
}));
|
||||
|
||||
if (global.session_type == Shell.SessionType.GDM) {
|
||||
this._tray_icon_order = GDM_TRAY_ICON_ORDER;
|
||||
this._tray_icon_shell_implementation = GDM_TRAY_ICON_SHELL_IMPLEMENTATION;
|
||||
} else {
|
||||
this._tray_icon_order = STANDARD_TRAY_ICON_ORDER;
|
||||
this._tray_icon_shell_implementation = STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION;
|
||||
}
|
||||
|
||||
this._menus = new PopupMenu.PopupMenuManager(this);
|
||||
|
||||
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
|
||||
@ -942,21 +952,12 @@ Panel.prototype = {
|
||||
this._menus.addMenu(this._dateMenu.menu);
|
||||
|
||||
/* right */
|
||||
|
||||
// System status applets live in statusBox, while legacy tray icons
|
||||
// live in trayBox
|
||||
// The trayBox is hidden when there are no tray icons.
|
||||
this._trayBox = new St.BoxLayout({ name: 'legacyTray' });
|
||||
this._statusBox = new St.BoxLayout({ name: 'statusTray' });
|
||||
|
||||
this._trayBox.hide();
|
||||
this._rightBox.add(this._trayBox);
|
||||
this._rightBox.add(this._statusBox);
|
||||
|
||||
if (global.session_type == Shell.SessionType.USER) {
|
||||
this._userMenu = new UserMenu.UserMenuButton();
|
||||
this._userMenu.actor.name = 'panelStatus';
|
||||
this._rightBox.add(this._userMenu.actor);
|
||||
if (global.session_type == Shell.SessionType.GDM) {
|
||||
this._status_area_order = GDM_STATUS_AREA_ORDER;
|
||||
this._status_area_shell_implementation = GDM_STATUS_AREA_SHELL_IMPLEMENTATION;
|
||||
} else {
|
||||
this._status_area_order = STANDARD_STATUS_AREA_ORDER;
|
||||
this._status_area_shell_implementation = STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION;
|
||||
}
|
||||
|
||||
Main.statusIconDispatcher.connect('status-icon-added', Lang.bind(this, this._onTrayIconAdded));
|
||||
@ -1042,9 +1043,9 @@ Panel.prototype = {
|
||||
},
|
||||
|
||||
startStatusArea: function() {
|
||||
for (let i = 0; i < this._tray_icon_order.length; i++) {
|
||||
let role = this._tray_icon_order[i];
|
||||
let constructor = this._tray_icon_shell_implementation[role];
|
||||
for (let i = 0; i < this._status_area_order.length; i++) {
|
||||
let role = this._status_area_order[i];
|
||||
let constructor = this._status_area_shell_implementation[role];
|
||||
if (!constructor) {
|
||||
// This icon is not implemented (this is a bug)
|
||||
continue;
|
||||
@ -1053,11 +1054,23 @@ Panel.prototype = {
|
||||
let indicator = new constructor();
|
||||
this.addToStatusArea(role, indicator, i);
|
||||
}
|
||||
},
|
||||
|
||||
// PopupMenuManager depends on menus being added in order for
|
||||
// keyboard navigation
|
||||
if (this._userMenu)
|
||||
this._menus.addMenu(this._userMenu.menu);
|
||||
_insertStatusItem: function(actor, position) {
|
||||
let children = this._rightBox.get_children();
|
||||
let i;
|
||||
for (i = children.length - 1; i >= 0; i--) {
|
||||
let rolePosition = children[i]._rolePosition;
|
||||
if (position > rolePosition) {
|
||||
this._rightBox.insert_actor(actor, i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == -1) {
|
||||
// If we didn't find a position, we must be first
|
||||
this._rightBox.insert_actor(actor, 0);
|
||||
}
|
||||
actor._rolePosition = position;
|
||||
},
|
||||
|
||||
addToStatusArea: function(role, indicator, position) {
|
||||
@ -1069,8 +1082,7 @@ Panel.prototype = {
|
||||
|
||||
if (!position)
|
||||
position = 0;
|
||||
|
||||
this._statusBox.insert_actor(indicator.actor, position);
|
||||
this._insertStatusItem(indicator.actor, position);
|
||||
this._menus.addMenu(indicator.menu);
|
||||
|
||||
this._statusArea[role] = indicator;
|
||||
@ -1083,39 +1095,24 @@ Panel.prototype = {
|
||||
},
|
||||
|
||||
_onTrayIconAdded: function(o, icon, role) {
|
||||
icon.height = PANEL_ICON_SIZE;
|
||||
|
||||
if (this._tray_icon_shell_implementation[role]) {
|
||||
if (this._status_area_shell_implementation[role]) {
|
||||
// This icon is legacy, and replaced by a Shell version
|
||||
// Hide it
|
||||
return;
|
||||
}
|
||||
// Figure out the index in our well-known order for this icon
|
||||
let position = this._tray_icon_order.indexOf(role);
|
||||
icon._rolePosition = position;
|
||||
let children = this._trayBox.get_children();
|
||||
let i;
|
||||
// Walk children backwards, until we find one that isn't
|
||||
// well-known, or one where we should follow
|
||||
for (i = children.length - 1; i >= 0; i--) {
|
||||
let rolePosition = children[i]._rolePosition;
|
||||
if (!rolePosition || position > rolePosition) {
|
||||
this._trayBox.insert_actor(icon, i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == -1) {
|
||||
// If we didn't find a position, we must be first
|
||||
this._trayBox.insert_actor(icon, 0);
|
||||
}
|
||||
|
||||
// Make sure the trayBox is shown.
|
||||
this._trayBox.show();
|
||||
icon.height = PANEL_ICON_SIZE;
|
||||
let buttonBox = new PanelMenu.ButtonBox();
|
||||
let box = buttonBox.actor;
|
||||
box.add_actor(icon);
|
||||
|
||||
this._insertStatusItem(box, this._status_area_order.indexOf(role));
|
||||
},
|
||||
|
||||
_onTrayIconRemoved: function(o, icon) {
|
||||
if (icon.get_parent() != null)
|
||||
this._trayBox.remove_actor(icon);
|
||||
let box = icon.get_parent();
|
||||
if (box && box._delegate instanceof PanelMenu.ButtonBox)
|
||||
box.destroy();
|
||||
},
|
||||
|
||||
};
|
||||
|
@ -2,26 +2,110 @@
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const Lang = imports.lang;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
|
||||
function ButtonBox(params) {
|
||||
this._init.apply(this, arguments);
|
||||
};
|
||||
|
||||
ButtonBox.prototype = {
|
||||
_init: function(params) {
|
||||
params = Params.parse(params, { style_class: 'panel-button' }, true);
|
||||
this.actor = new Shell.GenericContainer(params);
|
||||
this.actor._delegate = this;
|
||||
|
||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
||||
|
||||
this.actor.connect('style-changed', Lang.bind(this, this._onStyleChanged));
|
||||
this._minHPadding = this._natHPadding = 0.0;
|
||||
},
|
||||
|
||||
_onStyleChanged: function(actor) {
|
||||
let themeNode = actor.get_theme_node();
|
||||
|
||||
this._minHPadding = themeNode.get_length('-minimum-hpadding');
|
||||
this._natHPadding = themeNode.get_length('-natural-hpadding');
|
||||
},
|
||||
|
||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||
let children = actor.get_children();
|
||||
let child = children.length > 0 ? children[0] : null;
|
||||
|
||||
if (child) {
|
||||
[alloc.min_size, alloc.natural_size] = child.get_preferred_width(-1);
|
||||
} else {
|
||||
alloc.min_size = alloc.natural_size = 0;
|
||||
}
|
||||
|
||||
alloc.min_size += 2 * this._minHPadding;
|
||||
alloc.natural_size += 2 * this._natHPadding;
|
||||
},
|
||||
|
||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||
let children = actor.get_children();
|
||||
let child = children.length > 0 ? children[0] : null;
|
||||
|
||||
if (child) {
|
||||
[alloc.min_size, alloc.natural_size] = child.get_preferred_height(-1);
|
||||
} else {
|
||||
alloc.min_size = alloc.natural_size = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_allocate: function(actor, box, flags) {
|
||||
let children = actor.get_children();
|
||||
if (children.length == 0)
|
||||
return;
|
||||
|
||||
let child = children[0];
|
||||
let [minWidth, natWidth] = child.get_preferred_width(-1);
|
||||
let [minHeight, natHeight] = child.get_preferred_height(-1);
|
||||
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let availHeight = box.y2 - box.y1;
|
||||
|
||||
let childBox = new Clutter.ActorBox();
|
||||
if (natWidth + 2 * this._natHPadding <= availWidth) {
|
||||
childBox.x1 = this._natHPadding;
|
||||
childBox.x2 = availWidth - this._natHPadding;
|
||||
} else {
|
||||
childBox.x1 = this._minHPadding;
|
||||
childBox.x2 = availWidth - this._minHPadding;
|
||||
}
|
||||
|
||||
if (natHeight <= availHeight) {
|
||||
childBox.y1 = Math.floor((availHeight - natHeight) / 2);
|
||||
childBox.y2 = childBox.y1 + natHeight;
|
||||
} else {
|
||||
childBox.y1 = 0;
|
||||
childBox.y2 = availHeight;
|
||||
}
|
||||
|
||||
child.allocate(childBox, flags);
|
||||
},
|
||||
}
|
||||
|
||||
function Button(menuAlignment) {
|
||||
this._init(menuAlignment);
|
||||
}
|
||||
|
||||
Button.prototype = {
|
||||
__proto__: ButtonBox.prototype,
|
||||
|
||||
_init: function(menuAlignment) {
|
||||
this.actor = new St.Bin({ style_class: 'panel-button',
|
||||
reactive: true,
|
||||
can_focus: true,
|
||||
x_fill: true,
|
||||
y_fill: false,
|
||||
track_hover: true });
|
||||
this.actor._delegate = this;
|
||||
ButtonBox.prototype._init.call(this, { reactive: true,
|
||||
can_focus: true,
|
||||
track_hover: true });
|
||||
|
||||
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
||||
this.actor.connect('key-press-event', Lang.bind(this, this._onSourceKeyPress));
|
||||
this.menu = new PopupMenu.PopupMenu(this.actor, menuAlignment, St.Side.TOP);
|
||||
@ -112,7 +196,8 @@ SystemStatusButton.prototype = {
|
||||
this._iconActor = new St.Icon({ icon_name: iconName,
|
||||
icon_type: St.IconType.SYMBOLIC,
|
||||
style_class: 'system-status-icon' });
|
||||
this.actor.set_child(this._iconActor);
|
||||
this.actor.add_actor(this._iconActor);
|
||||
this.actor.add_style_class_name('panel-status-button');
|
||||
this.setTooltip(tooltipText);
|
||||
},
|
||||
|
||||
|
@ -142,6 +142,7 @@ AuthenticationDialog.prototype = {
|
||||
this._passwordEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivate));
|
||||
this._passwordBox.add(this._passwordEntry,
|
||||
{expand: true });
|
||||
this.setInitialKeyFocus(this._passwordEntry);
|
||||
this._passwordBox.hide();
|
||||
|
||||
this._errorMessageLabel = new St.Label({ style_class: 'polkit-dialog-error-label' });
|
||||
@ -186,13 +187,6 @@ AuthenticationDialog.prototype = {
|
||||
this._session.connect('request', Lang.bind(this, this._onSessionRequest));
|
||||
this._session.connect('show-error', Lang.bind(this, this._onSessionShowError));
|
||||
this._session.connect('show-info', Lang.bind(this, this._onSessionShowInfo));
|
||||
|
||||
// Delay focus grab to avoid ModalDialog stealing focus with
|
||||
// its buttons
|
||||
this.connect('opened',
|
||||
Lang.bind(this, function() {
|
||||
this._passwordEntry.grab_key_focus();
|
||||
}));
|
||||
},
|
||||
|
||||
startAuthentication: function() {
|
||||
|
@ -35,6 +35,7 @@ PopupBaseMenuItem.prototype = {
|
||||
params = Params.parse (params, { reactive: true,
|
||||
activate: true,
|
||||
hover: true,
|
||||
sensitive: true,
|
||||
style_class: null
|
||||
});
|
||||
this.actor = new Shell.GenericContainer({ style_class: 'popup-menu-item',
|
||||
@ -52,11 +53,15 @@ PopupBaseMenuItem.prototype = {
|
||||
this._columnWidths = null;
|
||||
this._spacing = 0;
|
||||
this.active = false;
|
||||
this._activatable = params.reactive && params.activate;
|
||||
this.sensitive = this._activatable && params.sensitive;
|
||||
|
||||
this.setSensitive(this.sensitive);
|
||||
|
||||
if (params.style_class)
|
||||
this.actor.add_style_class_name(params.style_class);
|
||||
|
||||
if (params.reactive && params.activate) {
|
||||
if (this._activatable) {
|
||||
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonReleaseEvent));
|
||||
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
|
||||
}
|
||||
@ -117,6 +122,23 @@ PopupBaseMenuItem.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
setSensitive: function(sensitive) {
|
||||
if (!this._activatable)
|
||||
return;
|
||||
if (this.sensitive == sensitive)
|
||||
return;
|
||||
|
||||
this.sensitive = sensitive;
|
||||
this.actor.reactive = sensitive;
|
||||
this.actor.can_focus = sensitive;
|
||||
|
||||
if (sensitive)
|
||||
this.actor.remove_style_pseudo_class('insensitive');
|
||||
else
|
||||
this.actor.add_style_pseudo_class('insensitive');
|
||||
this.emit('sensitive-changed', sensitive);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.actor.destroy();
|
||||
this.emit('destroy');
|
||||
@ -214,7 +236,7 @@ PopupBaseMenuItem.prototype = {
|
||||
let child = this._children[i];
|
||||
if (i > 0)
|
||||
width += this._spacing;
|
||||
let [min, natural] = child.actor.get_preferred_width(forHeight);
|
||||
let [min, natural] = child.actor.get_preferred_width(-1);
|
||||
width += natural;
|
||||
}
|
||||
}
|
||||
@ -222,10 +244,25 @@ PopupBaseMenuItem.prototype = {
|
||||
},
|
||||
|
||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||
let height = 0;
|
||||
let height = 0, x = 0, minWidth, childWidth;
|
||||
for (let i = 0; i < this._children.length; i++) {
|
||||
let child = this._children[i];
|
||||
let [min, natural] = child.actor.get_preferred_height(-1);
|
||||
if (this._columnWidths) {
|
||||
if (child.span == -1) {
|
||||
childWidth = 0;
|
||||
for (let j = i; j < this._columnWidths.length; j++)
|
||||
childWidth += this._columnWidths[j]
|
||||
} else
|
||||
childWidth = this._columnWidths[i];
|
||||
} else {
|
||||
if (child.span == -1)
|
||||
childWidth = forWidth - x;
|
||||
else
|
||||
[minWidth, childWidth] = child.actor.get_preferred_width(-1);
|
||||
}
|
||||
x += childWidth;
|
||||
|
||||
let [min, natural] = child.actor.get_preferred_height(childWidth);
|
||||
if (natural > height)
|
||||
height = natural;
|
||||
}
|
||||
@ -283,7 +320,10 @@ PopupBaseMenuItem.prototype = {
|
||||
}
|
||||
extraWidth = availWidth - naturalWidth;
|
||||
} else {
|
||||
availWidth = naturalWidth;
|
||||
if (child.span == -1)
|
||||
availWidth = box.x2 - x;
|
||||
else
|
||||
availWidth = naturalWidth;
|
||||
extraWidth = 0;
|
||||
}
|
||||
|
||||
@ -291,7 +331,7 @@ PopupBaseMenuItem.prototype = {
|
||||
if (child.expand) {
|
||||
childBox.x1 = x;
|
||||
childBox.x2 = x + availWidth;
|
||||
} else if (child.align === St.Align.CENTER) {
|
||||
} else if (child.align === St.Align.MIDDLE) {
|
||||
childBox.x1 = x + Math.round(extraWidth / 2);
|
||||
childBox.x2 = childBox.x1 + naturalWidth;
|
||||
} else if (child.align === St.Align.END) {
|
||||
@ -305,7 +345,7 @@ PopupBaseMenuItem.prototype = {
|
||||
if (child.expand) {
|
||||
childBox.x1 = x - availWidth;
|
||||
childBox.x2 = x;
|
||||
} else if (child.align === St.Align.CENTER) {
|
||||
} else if (child.align === St.Align.MIDDLE) {
|
||||
childBox.x1 = x - Math.round(extraWidth / 2);
|
||||
childBox.x2 = childBox.x1 + naturalWidth;
|
||||
} else if (child.align === St.Align.END) {
|
||||
@ -319,7 +359,7 @@ PopupBaseMenuItem.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
let [minHeight, naturalHeight] = child.actor.get_preferred_height(-1);
|
||||
let [minHeight, naturalHeight] = child.actor.get_preferred_height(childBox.x2 - childBox.x1);
|
||||
childBox.y1 = Math.round(box.y1 + (height - naturalHeight) / 2);
|
||||
childBox.y2 = childBox.y1 + naturalHeight;
|
||||
|
||||
@ -899,6 +939,17 @@ PopupMenuBase.prototype = {
|
||||
this.emit('active-changed', null);
|
||||
}
|
||||
}));
|
||||
menuItem._sensitiveChangeId = menuItem.connect('sensitive-changed', Lang.bind(this, function(menuItem, sensitive) {
|
||||
if (!sensitive && this._activeMenuItem == menuItem) {
|
||||
if (!this.actor.navigate_focus(menuItem.actor,
|
||||
Gtk.DirectionType.TAB_FORWARD,
|
||||
true))
|
||||
this.actor.grab_key_focus();
|
||||
} else if (sensitive && this._activeMenuItem == null) {
|
||||
if (global.stage.get_key_focus() == this.actor)
|
||||
menuItem.actor.grab_key_focus();
|
||||
}
|
||||
}));
|
||||
menuItem._activateId = menuItem.connect('activate', Lang.bind(this, function (menuItem, event) {
|
||||
this.emit('activate', menuItem);
|
||||
this.close(true);
|
||||
@ -906,6 +957,7 @@ PopupMenuBase.prototype = {
|
||||
menuItem.connect('destroy', Lang.bind(this, function(emitter) {
|
||||
menuItem.disconnect(menuItem._activateId);
|
||||
menuItem.disconnect(menuItem._activeChangeId);
|
||||
menuItem.disconnect(menuItem._sensitiveChangeId);
|
||||
if (menuItem.menu) {
|
||||
menuItem.menu.disconnect(menuItem._subMenuActivateId);
|
||||
menuItem.menu.disconnect(menuItem._subMenuActiveChangeId);
|
||||
@ -1507,6 +1559,10 @@ PopupComboMenu.prototype = {
|
||||
}
|
||||
|
||||
this._getMenuItems()[position].actor.visible = visible;
|
||||
},
|
||||
|
||||
getItemVisible: function(position) {
|
||||
return this._getMenuItems()[position].actor.visible;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1524,7 +1580,8 @@ PopupComboBoxMenuItem.prototype = {
|
||||
this.addActor(this._itemBox);
|
||||
|
||||
let expander = new St.Label({ text: '\u2304' });
|
||||
this.addActor(expander, { align: St.Align.END });
|
||||
this.addActor(expander, { align: St.Align.END,
|
||||
span: -1 });
|
||||
|
||||
this._menu = new PopupComboMenu(this.actor);
|
||||
Main.uiGroup.add_actor(this._menu.actor);
|
||||
@ -1533,6 +1590,8 @@ PopupComboBoxMenuItem.prototype = {
|
||||
if (params.style_class)
|
||||
this._menu.actor.add_style_class_name(params.style_class);
|
||||
|
||||
this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
|
||||
|
||||
this._activeItemPos = -1;
|
||||
this._items = [];
|
||||
},
|
||||
@ -1551,6 +1610,33 @@ PopupComboBoxMenuItem.prototype = {
|
||||
return null;
|
||||
},
|
||||
|
||||
_onScrollEvent: function(actor, event) {
|
||||
if (this._activeItemPos == -1)
|
||||
return;
|
||||
|
||||
let position = this._activeItemPos;
|
||||
let direction = event.get_scroll_direction();
|
||||
if (direction == Clutter.ScrollDirection.DOWN) {
|
||||
while (position < this._items.length - 1) {
|
||||
position++;
|
||||
if (this._menu.getItemVisible(position))
|
||||
break;
|
||||
}
|
||||
} else if (direction == Clutter.ScrollDirection.UP) {
|
||||
while (position > 0) {
|
||||
position--;
|
||||
if (this._menu.getItemVisible(position))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (position == this._activeItemPos)
|
||||
return;
|
||||
|
||||
this.setActiveItem(position);
|
||||
this.emit('active-item-changed', position);
|
||||
},
|
||||
|
||||
activate: function(event) {
|
||||
let topMenu = this._getTopMenu();
|
||||
if (!topMenu)
|
||||
|
@ -356,6 +356,14 @@ SearchSystem.prototype = {
|
||||
this._providers.push(provider);
|
||||
},
|
||||
|
||||
unregisterProvider: function (provider) {
|
||||
let index = this._providers.indexOf(provider);
|
||||
if (index == -1)
|
||||
return;
|
||||
provider.searchSystem = null;
|
||||
this._providers.splice(index, 1);
|
||||
},
|
||||
|
||||
getProviders: function() {
|
||||
return this._providers;
|
||||
},
|
||||
|
@ -294,11 +294,23 @@ SearchResults.prototype = {
|
||||
}
|
||||
resultDisplayBin.set_child(resultDisplay.actor);
|
||||
|
||||
this._providerMeta.push({ actor: providerBox,
|
||||
this._providerMeta.push({ provider: provider,
|
||||
actor: providerBox,
|
||||
resultDisplay: resultDisplay });
|
||||
this._content.add(providerBox);
|
||||
},
|
||||
|
||||
destroyProviderMeta: function(provider) {
|
||||
for (let i=0; i < this._providerMeta.length; i++) {
|
||||
let meta = this._providerMeta[i];
|
||||
if (meta.provider == provider) {
|
||||
meta.actor.destroy();
|
||||
this._providerMeta.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_clearDisplay: function() {
|
||||
this._selectedProvider = -1;
|
||||
this._visibleResultsCount = 0;
|
||||
|
@ -46,8 +46,12 @@ const GnomeShellIface = {
|
||||
outSignature: ''
|
||||
},
|
||||
{ name: 'InstallRemoteExtension',
|
||||
inSignature: 's',
|
||||
inSignature: 'ss',
|
||||
outSignature: ''
|
||||
},
|
||||
{ name: 'UninstallExtension',
|
||||
inSignature: 's',
|
||||
outSignature: 'b'
|
||||
}
|
||||
],
|
||||
signals: [{ name: 'ExtensionStatusChanged',
|
||||
@ -174,8 +178,12 @@ GnomeShell.prototype = {
|
||||
global.settings.set_strv(ExtensionSystem.ENABLED_EXTENSIONS_KEY, enabledExtensions);
|
||||
},
|
||||
|
||||
InstallRemoteExtension: function(uuid, url) {
|
||||
ExtensionSystem.installExtensionFromManifestURL(uuid, url);
|
||||
InstallRemoteExtension: function(uuid, version_tag) {
|
||||
ExtensionSystem.installExtensionFromUUID(uuid, version_tag);
|
||||
},
|
||||
|
||||
UninstallExtension: function(uuid) {
|
||||
return ExtensionSystem.uninstallExtensionFromUUID(uuid);
|
||||
},
|
||||
|
||||
get OverviewActive() {
|
||||
@ -189,7 +197,7 @@ GnomeShell.prototype = {
|
||||
Main.overview.hide();
|
||||
},
|
||||
|
||||
ApiVersion: 1,
|
||||
ApiVersion: ExtensionSystem.API_VERSION,
|
||||
|
||||
ShellVersion: Config.PACKAGE_VERSION,
|
||||
|
||||
|
@ -68,9 +68,9 @@ ATIndicator.prototype = {
|
||||
// 'screen-reader-enabled');
|
||||
// this.menu.addMenuItem(screenReader);
|
||||
|
||||
// let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
|
||||
// 'screen-keyboard-enabled');
|
||||
// this.menu.addMenuItem(screenKeyboard);
|
||||
let screenKeyboard = this._buildItem(_("Screen Keyboard"), APPLICATIONS_SCHEMA,
|
||||
'screen-keyboard-enabled');
|
||||
this.menu.addMenuItem(screenKeyboard);
|
||||
|
||||
let visualBell = this._buildItemGConf(_("Visual Alerts"), client, KEY_VISUAL_BELL);
|
||||
this.menu.addMenuItem(visualBell);
|
||||
|
@ -49,10 +49,11 @@ XKBIndicator.prototype = {
|
||||
PanelMenu.Button.prototype._init.call(this, St.Align.START);
|
||||
|
||||
this._container = new Shell.GenericContainer();
|
||||
this._container.connect('get-preferred-width', Lang.bind(this, this._get_preferred_width));
|
||||
this._container.connect('get-preferred-height', Lang.bind(this, this._get_preferred_height));
|
||||
this._container.connect('allocate', Lang.bind(this, this._allocate));
|
||||
this.actor.set_child(this._container);
|
||||
this._container.connect('get-preferred-width', Lang.bind(this, this._containerGetPreferredWidth));
|
||||
this._container.connect('get-preferred-height', Lang.bind(this, this._containerGetPreferredHeight));
|
||||
this._container.connect('allocate', Lang.bind(this, this._containerAllocate));
|
||||
this.actor.add_actor(this._container);
|
||||
this.actor.add_style_class_name('panel-status-button');
|
||||
|
||||
this._iconActor = new St.Icon({ icon_name: 'keyboard', icon_type: St.IconType.SYMBOLIC, style_class: 'system-status-icon' });
|
||||
this._container.add_actor(this._iconActor);
|
||||
@ -61,21 +62,23 @@ XKBIndicator.prototype = {
|
||||
|
||||
this._showFlags = false;
|
||||
this._config = Gkbd.Configuration.get();
|
||||
this._config.connect('changed', Lang.bind(this, this._sync_config));
|
||||
this._config.connect('group-changed', Lang.bind(this, this._sync_group));
|
||||
this._config.connect('changed', Lang.bind(this, this._syncConfig));
|
||||
this._config.connect('group-changed', Lang.bind(this, this._syncGroup));
|
||||
this._config.start_listen();
|
||||
|
||||
this._sync_config();
|
||||
this._syncConfig();
|
||||
|
||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||
this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, function() {
|
||||
Main.overview.hide();
|
||||
Util.spawn(['gkbd-keyboard-display', '-g', String(this._config.get_current_group() + 1)]);
|
||||
}));
|
||||
if (global.session_type == Shell.SessionType.USER) {
|
||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||
this.menu.addAction(_("Show Keyboard Layout"), Lang.bind(this, function() {
|
||||
Main.overview.hide();
|
||||
Util.spawn(['gkbd-keyboard-display', '-g', String(this._config.get_current_group() + 1)]);
|
||||
}));
|
||||
}
|
||||
this.menu.addSettingsAction(_("Region and Language Settings"), 'gnome-region-panel.desktop');
|
||||
},
|
||||
|
||||
_adjust_group_names: function(names) {
|
||||
_adjustGroupNames: function(names) {
|
||||
// Disambiguate duplicate names with a subscript
|
||||
// This is O(N^2) to avoid sorting names
|
||||
// but N <= 4 so who cares?
|
||||
@ -97,7 +100,7 @@ XKBIndicator.prototype = {
|
||||
return names;
|
||||
},
|
||||
|
||||
_sync_config: function() {
|
||||
_syncConfig: function() {
|
||||
this._showFlags = this._config.if_flags_shown();
|
||||
if (this._showFlags) {
|
||||
this._container.set_skip_paint(this._iconActor, false);
|
||||
@ -119,7 +122,7 @@ XKBIndicator.prototype = {
|
||||
for (let i = 0; i < this._labelActors.length; i++)
|
||||
this._labelActors[i].destroy();
|
||||
|
||||
let short_names = this._adjust_group_names(this._config.get_short_group_names());
|
||||
let short_names = this._adjustGroupNames(this._config.get_short_group_names());
|
||||
|
||||
this._selectedLayout = null;
|
||||
this._layoutItems = [ ];
|
||||
@ -144,10 +147,10 @@ XKBIndicator.prototype = {
|
||||
this._container.set_skip_paint(shortLabel, true);
|
||||
}
|
||||
|
||||
this._sync_group();
|
||||
this._syncGroup();
|
||||
},
|
||||
|
||||
_sync_group: function() {
|
||||
_syncGroup: function() {
|
||||
let selected = this._config.get_current_group();
|
||||
|
||||
if (this._selectedLayout) {
|
||||
@ -170,10 +173,10 @@ XKBIndicator.prototype = {
|
||||
this._selectedLayout = item;
|
||||
},
|
||||
|
||||
_get_preferred_width: function(container, for_height, alloc) {
|
||||
/* Here, and in _get_preferred_height, we need to query for the
|
||||
height of all children, but we ignore the results for those
|
||||
we don't actually display. */
|
||||
_containerGetPreferredWidth: function(container, for_height, alloc) {
|
||||
// Here, and in _containerGetPreferredHeight, we need to query
|
||||
// for the height of all children, but we ignore the results
|
||||
// for those we don't actually display.
|
||||
let max_min_width = 0, max_natural_width = 0;
|
||||
if (this._showFlags)
|
||||
[max_min_width, max_natural_width] = this._iconActor.get_preferred_width(for_height);
|
||||
@ -190,7 +193,7 @@ XKBIndicator.prototype = {
|
||||
alloc.natural_size = max_natural_width;
|
||||
},
|
||||
|
||||
_get_preferred_height: function(container, for_width, alloc) {
|
||||
_containerGetPreferredHeight: function(container, for_width, alloc) {
|
||||
let max_min_height = 0, max_natural_height = 0;
|
||||
if (this._showFlags)
|
||||
[max_min_height, max_natural_height] = this._iconActor.get_preferred_height(for_width);
|
||||
@ -207,7 +210,7 @@ XKBIndicator.prototype = {
|
||||
alloc.natural_size = max_natural_height;
|
||||
},
|
||||
|
||||
_allocate: function(container, box, flags) {
|
||||
_containerAllocate: function(container, box, flags) {
|
||||
// translate box to (0, 0)
|
||||
box.x2 -= box.x1;
|
||||
box.x1 = 0;
|
||||
|
@ -1291,6 +1291,9 @@ NMDeviceWireless.prototype = {
|
||||
apObj.accessPoints.splice(i, 1);
|
||||
|
||||
if (apObj.accessPoints.length == 0) {
|
||||
if (this._activeNetwork == apObj)
|
||||
this._activeNetwork = null;
|
||||
|
||||
if (apObj.item)
|
||||
apObj.item.destroy();
|
||||
|
||||
@ -1480,6 +1483,11 @@ NMDeviceWireless.prototype = {
|
||||
},
|
||||
|
||||
_createNetworkItem: function(apObj, position) {
|
||||
if(!apObj.accessPoints || apObj.accessPoints.length == 0) {
|
||||
// this should not happen, but I have no idea why it happens
|
||||
return;
|
||||
}
|
||||
|
||||
if(apObj.connections.length > 0) {
|
||||
if (apObj.connections.length == 1)
|
||||
apObj.item = this._createAPItem(apObj.connections[0], apObj, false);
|
||||
@ -1742,13 +1750,6 @@ NMApplet.prototype = {
|
||||
if (wrapperClass) {
|
||||
let wrapper = new wrapperClass(this._client, device, this._connections);
|
||||
|
||||
wrapper._networkLostId = wrapper.connect('network-lost', Lang.bind(this, function(device) {
|
||||
this._notifyForDevice(device, 'network-offline',
|
||||
_("Connectivity lost"),
|
||||
_("You're no longer connected to the network"),
|
||||
// set critical urgency to popup the notification automatically
|
||||
MessageTray.Urgency.CRITICAL);
|
||||
}));
|
||||
wrapper._activationFailedId = wrapper.connect('activation-failed', Lang.bind(this, function(device, reason) {
|
||||
// XXX: nm-applet has no special text depending on reason
|
||||
// but I'm not sure of this generic message
|
||||
@ -1761,7 +1762,6 @@ NMApplet.prototype = {
|
||||
this._syncSectionTitle(dev.category);
|
||||
}));
|
||||
wrapper._destroyId = wrapper.connect('destroy', function(wrapper) {
|
||||
wrapper.disconnect(wrapper._networkLostId);
|
||||
wrapper.disconnect(wrapper._activationFailedId);
|
||||
wrapper.disconnect(wrapper._deviceStateChangedId);
|
||||
wrapper.disconnect(wrapper._destroyId);
|
||||
@ -1828,7 +1828,7 @@ NMApplet.prototype = {
|
||||
if (!a._inited) {
|
||||
a._notifyDefaultId = a.connect('notify::default', Lang.bind(this, this._updateIcon));
|
||||
a._notifyDefault6Id = a.connect('notify::default6', Lang.bind(this, this._updateIcon));
|
||||
a._notifyStateId = a.connect('notify::state', Lang.bind(this, this._updateIcon));
|
||||
a._notifyStateId = a.connect('notify::state', Lang.bind(this, this._notifyActivated));
|
||||
|
||||
a._inited = true;
|
||||
}
|
||||
@ -1872,12 +1872,28 @@ NMApplet.prototype = {
|
||||
|
||||
if (a._primaryDevice)
|
||||
a._primaryDevice.setActiveConnection(a);
|
||||
|
||||
if (a.state == NetworkManager.ActiveConnectionState.ACTIVATED
|
||||
&& a._primaryDevice && a._primaryDevice._notification) {
|
||||
a._primaryDevice._notification.destroy();
|
||||
a._primaryDevice._notification = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._mainConnection = activating || default_ip4 || default_ip6 || this._activeConnections[0] || null;
|
||||
},
|
||||
|
||||
_notifyActivated: function(activeConnection) {
|
||||
if (activeConnection.state == NetworkManager.ActiveConnectionState.ACTIVATED
|
||||
&& activeConnection._primaryDevice && activeConnection._primaryDevice._notification) {
|
||||
activeConnection._primaryDevice._notification.destroy();
|
||||
activeConnection._primaryDevice._notification = null;
|
||||
}
|
||||
|
||||
this._updateIcon();
|
||||
},
|
||||
|
||||
_readConnections: function() {
|
||||
let connections = this._settings.list_connections();
|
||||
for (let i = 0; i < connections.length; i++) {
|
||||
|
@ -118,7 +118,7 @@ Indicator.prototype = {
|
||||
timestring = ngettext("%d minute remaining", "%d minutes remaining", minutes).format(minutes);
|
||||
this._batteryItem.label.text = timestring;
|
||||
}
|
||||
this._primaryPercentage.text = Math.round(percentage) + '%';
|
||||
this._primaryPercentage.text = C_("percent of battery remaining", "%d%%").format(Math.round(percentage));
|
||||
this._batteryItem.actor.show();
|
||||
} else {
|
||||
this._hasPrimary = false;
|
||||
@ -191,7 +191,7 @@ DeviceItem.prototype = {
|
||||
this._box.add_actor(this._label);
|
||||
this.addActor(this._box);
|
||||
|
||||
let percentLabel = new St.Label({ text: '%d%%'.format(Math.round(percentage)) });
|
||||
let percentLabel = new St.Label({ text: C_("percent of battery remaining", "%d%%").format(Math.round(percentage)) });
|
||||
this.addActor(percentLabel, { align: St.Align.END });
|
||||
},
|
||||
|
||||
|
@ -35,7 +35,6 @@ Indicator.prototype = {
|
||||
this._control.connect('stream-added', Lang.bind(this, this._maybeShowInput));
|
||||
this._control.connect('stream-removed', Lang.bind(this, this._maybeShowInput));
|
||||
this._volumeMax = this._control.get_vol_max_norm();
|
||||
this._volumeMaxAmplified = this._control.get_vol_max_amplified();
|
||||
|
||||
this._output = null;
|
||||
this._outputVolumeId = 0;
|
||||
@ -66,21 +65,13 @@ Indicator.prototype = {
|
||||
this._control.open();
|
||||
},
|
||||
|
||||
_getMaxVolume: function(property) {
|
||||
if (this[property].get_can_decibel())
|
||||
return this._volumeMaxAmplified;
|
||||
else
|
||||
return this._volumeMax;
|
||||
},
|
||||
|
||||
_onScrollEvent: function(actor, event) {
|
||||
let direction = event.get_scroll_direction();
|
||||
let currentVolume = this._output.volume;
|
||||
let maxVolume = this._getMaxVolume('_output');
|
||||
|
||||
if (direction == Clutter.ScrollDirection.DOWN) {
|
||||
let prev_muted = this._output.is_muted;
|
||||
this._output.volume = Math.max(0, currentVolume - maxVolume * VOLUME_ADJUSTMENT_STEP);
|
||||
this._output.volume = Math.max(0, currentVolume - this._volumeMax * VOLUME_ADJUSTMENT_STEP);
|
||||
if (this._output.volume < 1) {
|
||||
this._output.volume = 0;
|
||||
if (!prev_muted)
|
||||
@ -89,7 +80,7 @@ Indicator.prototype = {
|
||||
this._output.push_volume();
|
||||
}
|
||||
else if (direction == Clutter.ScrollDirection.UP) {
|
||||
this._output.volume = Math.min(maxVolume, currentVolume + maxVolume * VOLUME_ADJUSTMENT_STEP);
|
||||
this._output.volume = Math.min(this._volumeMax, currentVolume + this._volumeMax * VOLUME_ADJUSTMENT_STEP);
|
||||
this._output.change_is_muted(false);
|
||||
this._output.push_volume();
|
||||
}
|
||||
@ -171,11 +162,10 @@ Indicator.prototype = {
|
||||
},
|
||||
|
||||
_volumeToIcon: function(volume) {
|
||||
let maxVolume = this._getMaxVolume('_output');
|
||||
if (volume <= 0) {
|
||||
return 'audio-volume-muted';
|
||||
} else {
|
||||
let n = Math.floor(3 * volume / maxVolume) + 1;
|
||||
let n = Math.floor(3 * volume / this._volumeMax) + 1;
|
||||
if (n < 2)
|
||||
return 'audio-volume-low';
|
||||
if (n >= 3)
|
||||
@ -189,7 +179,7 @@ Indicator.prototype = {
|
||||
log ('Volume slider changed for %s, but %s does not exist'.format(property, property));
|
||||
return;
|
||||
}
|
||||
let volume = value * this._getMaxVolume(property);
|
||||
let volume = value * this._volumeMax;
|
||||
let prev_muted = this[property].is_muted;
|
||||
if (volume < 1) {
|
||||
this[property].volume = 0;
|
||||
@ -211,8 +201,7 @@ Indicator.prototype = {
|
||||
_mutedChanged: function(object, param_spec, property) {
|
||||
let muted = this[property].is_muted;
|
||||
let slider = this[property+'Slider'];
|
||||
let maxVolume = this._getMaxVolume(property);
|
||||
slider.setValue(muted ? 0 : (this[property].volume / maxVolume));
|
||||
slider.setValue(muted ? 0 : (this[property].volume / this._volumeMax));
|
||||
if (property == '_output') {
|
||||
if (muted)
|
||||
this.setIcon('audio-volume-muted');
|
||||
@ -222,8 +211,7 @@ Indicator.prototype = {
|
||||
},
|
||||
|
||||
_volumeChanged: function(object, param_spec, property) {
|
||||
let maxVolume = this._getMaxVolume(property);
|
||||
this[property+'Slider'].setValue(this[property].volume / maxVolume);
|
||||
this[property+'Slider'].setValue(this[property].volume / this._volumeMax);
|
||||
if (property == '_output' && !this._output.is_muted)
|
||||
this.setIcon(this._volumeToIcon(this._output.volume));
|
||||
}
|
||||
|
@ -83,6 +83,9 @@ Client.prototype = {
|
||||
this._chatSources = {};
|
||||
this._chatState = Tp.ChannelChatState.ACTIVE;
|
||||
|
||||
// account path -> AccountNotification
|
||||
this._accountNotifications = {};
|
||||
|
||||
// Set up a SimpleObserver, which will call _observeChannels whenever a
|
||||
// channel matching its filters is detected.
|
||||
// The second argument, recover, means _observeChannels will be run
|
||||
@ -420,7 +423,6 @@ Client.prototype = {
|
||||
|
||||
/* Display notification to ask user to accept/reject request */
|
||||
let source = this._ensureSubscriptionSource();
|
||||
Main.messageTray.add(source);
|
||||
|
||||
let notif = new SubscriptionRequestNotification(source, contact);
|
||||
source.notify(notif);
|
||||
@ -430,6 +432,7 @@ Client.prototype = {
|
||||
if (this._subscriptionSource == null) {
|
||||
this._subscriptionSource = new MultiNotificationSource(
|
||||
_("Subscription request"), 'gtk-dialog-question');
|
||||
Main.messageTray.add(this._subscriptionSource);
|
||||
this._subscriptionSource.connect('destroy', Lang.bind(this, function () {
|
||||
this._subscriptionSource = null;
|
||||
}));
|
||||
@ -446,11 +449,18 @@ Client.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
let notif = this._accountNotifications[account.get_object_path()];
|
||||
if (notif)
|
||||
return;
|
||||
|
||||
/* Display notification that account failed to connect */
|
||||
let source = this._ensureAccountSource();
|
||||
Main.messageTray.add(source);
|
||||
|
||||
let notif = new AccountNotification(source, account, connectionError);
|
||||
notif = new AccountNotification(source, account, connectionError);
|
||||
this._accountNotifications[account.get_object_path()] = notif;
|
||||
notif.connect('destroy', Lang.bind(this, function() {
|
||||
delete this._accountNotifications[account.get_object_path()];
|
||||
}));
|
||||
source.notify(notif);
|
||||
},
|
||||
|
||||
@ -458,6 +468,7 @@ Client.prototype = {
|
||||
if (this._accountSource == null) {
|
||||
this._accountSource = new MultiNotificationSource(
|
||||
_("Connection error"), 'gtk-dialog-error');
|
||||
Main.messageTray.add(this._accountSource);
|
||||
this._accountSource.connect('destroy', Lang.bind(this, function () {
|
||||
this._accountSource = null;
|
||||
}));
|
||||
@ -1019,7 +1030,7 @@ ChatNotification.prototype = {
|
||||
IM name. */
|
||||
let message = '<i>' + _("%s is now known as %s").format(oldAlias, newAlias) + '</i>';
|
||||
|
||||
let label = this._append({ body: text,
|
||||
let label = this._append({ body: message,
|
||||
group: 'meta',
|
||||
styles: ['chat-meta-message'] });
|
||||
|
||||
@ -1426,8 +1437,7 @@ _connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.CONNECTION_LOST)]
|
||||
_connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.ALREADY_CONNECTED)]
|
||||
= _("This resource is already connected to the server");
|
||||
_connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.CONNECTION_REPLACED)]
|
||||
= _("Connection has been replaced by a new connection using the "
|
||||
+ "same resource");
|
||||
= _("Connection has been replaced by a new connection using the same resource");
|
||||
_connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.REGISTRATION_EXISTS)]
|
||||
= _("The account already exists on the server");
|
||||
_connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.SERVICE_BUSY)]
|
||||
@ -1435,12 +1445,9 @@ _connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.SERVICE_BUSY)]
|
||||
_connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.CERT_REVOKED)]
|
||||
= _("Certificate has been revoked");
|
||||
_connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.CERT_INSECURE)]
|
||||
= _("Certificate uses an insecure cipher algorithm or is "
|
||||
+ "cryptographically weak");
|
||||
= _("Certificate uses an insecure cipher algorithm or is cryptographically weak");
|
||||
_connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.CERT_LIMIT_EXCEEDED)]
|
||||
= _("The length of the server certificate, or the depth of the "
|
||||
+ "server certificate chain, exceed the limits imposed by the "
|
||||
+ "cryptography library");
|
||||
= _("The length of the server certificate, or the depth of the server certificate chain, exceed the limits imposed by the cryptography library");
|
||||
|
||||
AccountNotification.prototype = {
|
||||
__proto__: MessageTray.Notification.prototype,
|
||||
@ -1452,17 +1459,12 @@ AccountNotification.prototype = {
|
||||
_("Connection to %s failed").format(account.get_display_name()),
|
||||
null, { customContent: true });
|
||||
|
||||
let message;
|
||||
if (connectionError in _connectionErrorMessages) {
|
||||
message = _connectionErrorMessages[connectionError];
|
||||
} else {
|
||||
message = _("Unknown reason");
|
||||
}
|
||||
this._label = new St.Label();
|
||||
this.addActor(this._label);
|
||||
this._updateMessage(connectionError);
|
||||
|
||||
this._account = account;
|
||||
|
||||
this.addBody(message);
|
||||
|
||||
this.addButton('reconnect', _("Reconnect"));
|
||||
this.addButton('edit', _("Edit account"));
|
||||
|
||||
@ -1496,11 +1498,25 @@ AccountNotification.prototype = {
|
||||
|
||||
this._connectionStatusId = account.connect('notify::connection-status',
|
||||
Lang.bind(this, function() {
|
||||
if (account.connection_status != Tp.ConnectionStatus.DISCONNECTED)
|
||||
let status = account.connection_status;
|
||||
if (status == Tp.ConnectionStatus.CONNECTED) {
|
||||
this.destroy();
|
||||
} else if (status == Tp.ConnectionStatus.DISCONNECTED) {
|
||||
this._updateMessage(account.connection_error);
|
||||
}
|
||||
}));
|
||||
},
|
||||
|
||||
_updateMessage: function(connectionError) {
|
||||
let message;
|
||||
if (connectionError in _connectionErrorMessages) {
|
||||
message = _connectionErrorMessages[connectionError];
|
||||
} else {
|
||||
message = _("Unknown reason");
|
||||
}
|
||||
this._label.set_text(message);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
if (this._enabledId != 0) {
|
||||
this._account.disconnect(this._enabledId);
|
||||
|
@ -5,6 +5,7 @@ const DBus = imports.dbus;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
const Tp = imports.gi.TelepathyGLib;
|
||||
@ -22,7 +23,6 @@ const DISABLE_USER_SWITCH_KEY = 'disable-user-switching';
|
||||
const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen';
|
||||
const DISABLE_LOG_OUT_KEY = 'disable-log-out';
|
||||
|
||||
const WRAP_WIDTH = 150;
|
||||
const DIALOG_ICON_SIZE = 64;
|
||||
|
||||
const IMStatus = {
|
||||
@ -87,28 +87,20 @@ IMUserNameItem.prototype = {
|
||||
|
||||
this.label = new St.Label();
|
||||
this.label.clutter_text.set_line_wrap(true);
|
||||
this.label.clutter_text.set_ellipsize(Pango.EllipsizeMode.NONE);
|
||||
this._wrapper.add_actor(this.label);
|
||||
},
|
||||
|
||||
_wrapperGetPreferredWidth: function(actor, forHeight, alloc) {
|
||||
[alloc.min_size, alloc.natural_size] = this.label.get_preferred_width(-1);
|
||||
if (alloc.natural_size > WRAP_WIDTH)
|
||||
alloc.natural_size = WRAP_WIDTH;
|
||||
alloc.min_size = 1;
|
||||
alloc.natural_size = 1;
|
||||
},
|
||||
|
||||
_wrapperGetPreferredHeight: function(actor, forWidth, alloc) {
|
||||
let minWidth, natWidth;
|
||||
[alloc.min_size, alloc.natural_size] = this.label.get_preferred_height(forWidth);
|
||||
[minWidth, natWidth] = this.label.get_preferred_width(-1);
|
||||
if (natWidth > WRAP_WIDTH) {
|
||||
alloc.min_size *= 2;
|
||||
alloc.natural_size *= 2;
|
||||
}
|
||||
},
|
||||
|
||||
_wrapperAllocate: function(actor, box, flags) {
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let availHeight = box.y2 - box.y1;
|
||||
this.label.allocate(box, flags);
|
||||
}
|
||||
};
|
||||
@ -170,6 +162,7 @@ IMStatusChooserItem.prototype = {
|
||||
this._presence.connect('StatusChanged',
|
||||
Lang.bind(this, this._sessionStatusChanged));
|
||||
|
||||
this._currentPresence = undefined;
|
||||
this._previousPresence = undefined;
|
||||
|
||||
this._accountMgr = Tp.AccountManager.dup()
|
||||
@ -193,6 +186,10 @@ IMStatusChooserItem.prototype = {
|
||||
this._userChangedId = this._user.connect('changed',
|
||||
Lang.bind(this,
|
||||
this._updateUser));
|
||||
this.actor.connect('notify::mapped', Lang.bind(this, function() {
|
||||
if (this.actor.mapped)
|
||||
this._updateUser();
|
||||
}));
|
||||
},
|
||||
|
||||
// Override getColumnWidths()/setColumnWidths() to make the item
|
||||
@ -202,9 +199,6 @@ IMStatusChooserItem.prototype = {
|
||||
},
|
||||
|
||||
setColumnWidths: function(widths) {
|
||||
this._columnWidths = PopupMenu.PopupBaseMenuItem.prototype.getColumnWidths.call(this);
|
||||
let sectionWidths = this._section.getColumnWidths();
|
||||
this._section.setColumnWidths(sectionWidths);
|
||||
},
|
||||
|
||||
_updateUser: function() {
|
||||
@ -267,6 +261,11 @@ IMStatusChooserItem.prototype = {
|
||||
},
|
||||
|
||||
_IMStatusChanged: function(accountMgr, presence, status, message) {
|
||||
if (presence == this._currentPresence)
|
||||
return;
|
||||
|
||||
this._currentPresence = presence;
|
||||
|
||||
if (presence == Tp.ConnectionPresenceType.AVAILABLE)
|
||||
this._presence.setStatus(GnomeSession.PresenceStatus.AVAILABLE);
|
||||
|
||||
@ -315,33 +314,35 @@ IMStatusChooserItem.prototype = {
|
||||
this._accountMgr.set_all_requested_presences(newPresence, status, msg);
|
||||
},
|
||||
|
||||
getIMPresenceForSessionStatus: function(sessionStatus) {
|
||||
if (sessionStatus == GnomeSession.PresenceStatus.AVAILABLE)
|
||||
return this._previousPresence;
|
||||
|
||||
if (sessionStatus == GnomeSession.PresenceStatus.BUSY) {
|
||||
// Only change presence if the current one is "more present" than
|
||||
// busy, or if coming back from idle
|
||||
if (this._currentPresence == Tp.ConnectionPresenceType.AVAILABLE ||
|
||||
this._currentPresence == Tp.ConnectionPresenceType.EXTENDED_AWAY)
|
||||
return Tp.ConnectionPresenceType.BUSY;
|
||||
}
|
||||
|
||||
if (sessionStatus == GnomeSession.PresenceStatus.IDLE) {
|
||||
// Only change presence if the current one is "more present" than
|
||||
// idle
|
||||
if (this._currentPresence != Tp.ConnectionPresenceType.OFFLINE)
|
||||
return Tp.ConnectionPresenceType.EXTENDED_AWAY;
|
||||
}
|
||||
|
||||
return this._currentPresence;
|
||||
},
|
||||
|
||||
_sessionStatusChanged: function(sessionPresence, sessionStatus) {
|
||||
let [presence, s, msg] = this._accountMgr.get_most_available_presence();
|
||||
let newPresence, status;
|
||||
|
||||
if (sessionStatus == GnomeSession.PresenceStatus.AVAILABLE) {
|
||||
newPresence = this._previousPresence;
|
||||
} else if (sessionStatus == GnomeSession.PresenceStatus.BUSY) {
|
||||
// Only change presence if the current one is "more present" than
|
||||
// busy, or if coming back from idle
|
||||
if (presence == Tp.ConnectionPresenceType.AVAILABLE ||
|
||||
presence == Tp.ConnectionPresenceType.EXTENDED_AWAY) {
|
||||
newPresence = Tp.ConnectionPresenceType.BUSY;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else if (sessionStatus == GnomeSession.PresenceStatus.IDLE) {
|
||||
// Only change presence if the current one is "more present" than
|
||||
// idle
|
||||
if (presence != Tp.ConnectionPresenceType.OFFLINE)
|
||||
newPresence = Tp.ConnectionPresenceType.EXTENDED_AWAY;
|
||||
else
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
let newPresence = this.getIMPresenceForSessionStatus(sessionStatus);
|
||||
|
||||
if (newPresence == undefined)
|
||||
if (!newPresence || newPresence == presence)
|
||||
return;
|
||||
|
||||
status = this._statusForPresence(newPresence);
|
||||
@ -362,8 +363,8 @@ UserMenuButton.prototype = {
|
||||
|
||||
_init: function() {
|
||||
PanelMenu.Button.prototype._init.call(this, 0.0);
|
||||
let box = new St.BoxLayout({ name: 'panelStatusMenu' });
|
||||
this.actor.set_child(box);
|
||||
let box = new St.BoxLayout({ name: 'panelUserMenu' });
|
||||
this.actor.add_actor(box);
|
||||
|
||||
this._lockdownSettings = new Gio.Settings({ schema: LOCKDOWN_SCHEMA });
|
||||
|
||||
@ -413,6 +414,7 @@ UserMenuButton.prototype = {
|
||||
box.add(this._name, { y_align: St.Align.MIDDLE, y_fill: false });
|
||||
this._userLoadedId = this._user.connect('notify::is-loaded', Lang.bind(this, this._updateUserName));
|
||||
this._userChangedId = this._user.connect('changed', Lang.bind(this, this._updateUserName));
|
||||
this._updateUserName();
|
||||
|
||||
this._createSubMenu();
|
||||
this._userManager.connect('notify::is-loaded',
|
||||
@ -516,8 +518,8 @@ UserMenuButton.prototype = {
|
||||
},
|
||||
|
||||
_updateSwitch: function(presence, status) {
|
||||
let active = status == GnomeSession.PresenceStatus.BUSY;
|
||||
this._dontDisturbSwitch.setToggleState(active);
|
||||
let active = status == GnomeSession.PresenceStatus.AVAILABLE;
|
||||
this._notificationsSwitch.setToggleState(active);
|
||||
},
|
||||
|
||||
_updatePresenceIcon: function(accountMgr, presence, status, message) {
|
||||
@ -541,11 +543,12 @@ UserMenuButton.prototype = {
|
||||
item = new IMStatusChooserItem();
|
||||
item.connect('activate', Lang.bind(this, this._onMyAccountActivate));
|
||||
this.menu.addMenuItem(item);
|
||||
this._statusChooser = item;
|
||||
|
||||
item = new PopupMenu.PopupSwitchMenuItem(_("Do Not Disturb"));
|
||||
item = new PopupMenu.PopupSwitchMenuItem(_("Notifications"));
|
||||
item.connect('activate', Lang.bind(this, this._updatePresenceStatus));
|
||||
this.menu.addMenuItem(item);
|
||||
this._dontDisturbSwitch = item;
|
||||
this._notificationsSwitch = item;
|
||||
|
||||
item = new PopupMenu.PopupSeparatorMenuItem();
|
||||
this.menu.addMenuItem(item);
|
||||
@ -588,8 +591,21 @@ UserMenuButton.prototype = {
|
||||
},
|
||||
|
||||
_updatePresenceStatus: function(item, event) {
|
||||
let status = item.state ? GnomeSession.PresenceStatus.BUSY
|
||||
: GnomeSession.PresenceStatus.AVAILABLE;
|
||||
let status;
|
||||
|
||||
if (item.state) {
|
||||
status = GnomeSession.PresenceStatus.AVAILABLE;
|
||||
} else {
|
||||
status = GnomeSession.PresenceStatus.BUSY;
|
||||
|
||||
let [presence, s, msg] = this._account_mgr.get_most_available_presence();
|
||||
let newPresence = this._statusChooser.getIMPresenceForSessionStatus(status);
|
||||
if (newPresence != presence &&
|
||||
newPresence == Tp.ConnectionPresenceType.BUSY)
|
||||
Main.notify(_("Your chat status will be set to busy"),
|
||||
_("Notifications are now disabled, including chat messages. Your online status has been adjusted to let others know that you might not see their messages."));
|
||||
}
|
||||
|
||||
this._presence.setStatus(status);
|
||||
},
|
||||
|
||||
|
@ -210,6 +210,11 @@ SearchTab.prototype = {
|
||||
this._searchResults.createProviderMeta(provider);
|
||||
},
|
||||
|
||||
removeSearchProvider: function(provider) {
|
||||
this._searchSystem.unregisterProvider(provider);
|
||||
this._searchResults.destroyProviderMeta(provider);
|
||||
},
|
||||
|
||||
startSearch: function(event) {
|
||||
global.stage.set_key_focus(this._text);
|
||||
this._text.event(event, false);
|
||||
@ -563,6 +568,10 @@ ViewSelector.prototype = {
|
||||
|
||||
addSearchProvider: function(provider) {
|
||||
this._searchTab.addSearchProvider(provider);
|
||||
},
|
||||
|
||||
removeSearchProvider: function(provider) {
|
||||
this._searchTab.removeSearchProvider(provider);
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(ViewSelector.prototype);
|
||||
|
@ -19,47 +19,47 @@ const UNDIM_TIME = 0.250;
|
||||
|
||||
var dimShader = undefined;
|
||||
|
||||
function getDimShader() {
|
||||
if (dimShader === null)
|
||||
return null;
|
||||
if (!dimShader) {
|
||||
let source = Shell.get_file_contents_utf8_sync(global.datadir + '/shaders/dim-window.glsl');
|
||||
try {
|
||||
let shader = new Clutter.Shader();
|
||||
shader.set_fragment_source(source, -1);
|
||||
shader.compile();
|
||||
|
||||
dimShader = shader;
|
||||
} catch (e) {
|
||||
log(e.message);
|
||||
dimShader = null;
|
||||
}
|
||||
}
|
||||
function getDimShaderSource() {
|
||||
if (!dimShader)
|
||||
dimShader = Shell.get_file_contents_utf8_sync(global.datadir + '/shaders/dim-window.glsl');
|
||||
return dimShader;
|
||||
}
|
||||
|
||||
function getTopInvisibleBorder(metaWindow) {
|
||||
let outerRect = metaWindow.get_outer_rect();
|
||||
let inputRect = metaWindow.get_input_rect();
|
||||
return outerRect.y - inputRect.y;
|
||||
}
|
||||
|
||||
function WindowDimmer(actor) {
|
||||
this._init(actor);
|
||||
}
|
||||
|
||||
WindowDimmer.prototype = {
|
||||
_init: function(actor) {
|
||||
this.effect = new Clutter.ShaderEffect({ shader_type: Clutter.ShaderType.FRAGMENT_SHADER });
|
||||
this.effect.set_shader_source(getDimShaderSource());
|
||||
|
||||
this.actor = actor;
|
||||
},
|
||||
|
||||
set dimFraction(fraction) {
|
||||
this._dimFraction = fraction;
|
||||
let shader = getDimShader();
|
||||
if (!Meta.prefs_get_attach_modal_dialogs() || !shader) {
|
||||
this.actor.set_shader(null);
|
||||
if (!Meta.prefs_get_attach_modal_dialogs()) {
|
||||
this.effect.enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fraction > 0.01) {
|
||||
this.actor.set_shader(shader);
|
||||
this.actor.set_shader_param_float('height', this.actor.get_height());
|
||||
this.actor.set_shader_param_float('fraction', fraction);
|
||||
} else
|
||||
this.actor.set_shader(null);
|
||||
Shell.shader_effect_set_double_uniform(this.effect, 'height', this.actor.get_height());
|
||||
Shell.shader_effect_set_double_uniform(this.effect, 'fraction', fraction);
|
||||
|
||||
if (!this.effect.actor)
|
||||
this.actor.add_effect(this.effect);
|
||||
} else {
|
||||
if (this.effect.actor)
|
||||
this.actor.remove_effect(this.effect);
|
||||
}
|
||||
},
|
||||
|
||||
get dimFraction() {
|
||||
@ -69,11 +69,11 @@ WindowDimmer.prototype = {
|
||||
_dimFraction: 0.0
|
||||
};
|
||||
|
||||
function getWindowDimmer(texture) {
|
||||
if (!texture._windowDimmer)
|
||||
texture._windowDimmer = new WindowDimmer(texture);
|
||||
function getWindowDimmer(actor) {
|
||||
if (!actor._windowDimmer)
|
||||
actor._windowDimmer = new WindowDimmer(actor);
|
||||
|
||||
return texture._windowDimmer;
|
||||
return actor._windowDimmer;
|
||||
}
|
||||
|
||||
function WindowManager() {
|
||||
@ -268,30 +268,28 @@ WindowManager.prototype = {
|
||||
let actor = window.get_compositor_private();
|
||||
if (!actor)
|
||||
return;
|
||||
let texture = actor.get_texture();
|
||||
if (animate)
|
||||
Tweener.addTween(getWindowDimmer(texture),
|
||||
Tweener.addTween(getWindowDimmer(actor),
|
||||
{ dimFraction: 1.0,
|
||||
time: DIM_TIME,
|
||||
transition: 'linear'
|
||||
});
|
||||
else
|
||||
getWindowDimmer(texture).dimFraction = 1.0;
|
||||
getWindowDimmer(actor).dimFraction = 1.0;
|
||||
},
|
||||
|
||||
_undimWindow: function(window, animate) {
|
||||
let actor = window.get_compositor_private();
|
||||
if (!actor)
|
||||
return;
|
||||
let texture = actor.get_texture();
|
||||
if (animate)
|
||||
Tweener.addTween(getWindowDimmer(texture),
|
||||
Tweener.addTween(getWindowDimmer(actor),
|
||||
{ dimFraction: 0.0,
|
||||
time: UNDIM_TIME,
|
||||
transition: 'linear'
|
||||
});
|
||||
else
|
||||
getWindowDimmer(texture).dimFraction = 0.0;
|
||||
getWindowDimmer(actor).dimFraction = 0.0;
|
||||
},
|
||||
|
||||
_mapWindow : function(shellwm, actor) {
|
||||
@ -528,22 +526,22 @@ WindowManager.prototype = {
|
||||
shellwm.completed_switch_workspace();
|
||||
},
|
||||
|
||||
_startAppSwitcher : function(shellwm, binding, window, backwards) {
|
||||
_startAppSwitcher : function(shellwm, binding, mask, window, backwards) {
|
||||
/* prevent a corner case where both popups show up at once */
|
||||
if (this._workspaceSwitcherPopup != null)
|
||||
this._workspaceSwitcherPopup.actor.hide();
|
||||
|
||||
let tabPopup = new AltTab.AltTabPopup();
|
||||
|
||||
if (!tabPopup.show(backwards, binding))
|
||||
if (!tabPopup.show(backwards, binding, mask))
|
||||
tabPopup.destroy();
|
||||
},
|
||||
|
||||
_startA11ySwitcher : function(shellwm, binding, window, backwards) {
|
||||
Main.ctrlAltTabManager.popup(backwards);
|
||||
_startA11ySwitcher : function(shellwm, binding, mask, window, backwards) {
|
||||
Main.ctrlAltTabManager.popup(backwards, mask);
|
||||
},
|
||||
|
||||
_showWorkspaceSwitcher : function(shellwm, binding, window, backwards) {
|
||||
_showWorkspaceSwitcher : function(shellwm, binding, mask, window, backwards) {
|
||||
if (global.screen.n_workspaces == 1)
|
||||
return;
|
||||
|
||||
|
@ -102,6 +102,12 @@ WindowClone.prototype = {
|
||||
this._windowClone = new Clutter.Clone({ source: realWindow.get_texture(),
|
||||
x: -borderX,
|
||||
y: -borderY });
|
||||
// We expect this.actor to be used for all interaction rather than
|
||||
// this._windowClone; as the former is reactive and the latter
|
||||
// is not, this just works for most cases. However, for DND all
|
||||
// actors are picked, so DND operations would operate on the clone.
|
||||
// To avoid this, we hide it from pick.
|
||||
Shell.util_set_hidden_from_pick(this._windowClone, true);
|
||||
|
||||
this.origX = realWindow.x + borderX;
|
||||
this.origY = realWindow.y + borderY;
|
||||
|
@ -567,8 +567,6 @@ WorkspacesDisplay.prototype = {
|
||||
this._updateAlwaysZoom();
|
||||
|
||||
Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateAlwaysZoom));
|
||||
global.screen.connect('notify::n-workspaces',
|
||||
Lang.bind(this, this._workspacesChanged));
|
||||
|
||||
Main.xdndHandler.connect('drag-begin', Lang.bind(this, function(){
|
||||
this._alwaysZoomOut = true;
|
||||
@ -581,6 +579,7 @@ WorkspacesDisplay.prototype = {
|
||||
|
||||
this._switchWorkspaceNotifyId = 0;
|
||||
|
||||
this._nWorkspacesChangedId = 0;
|
||||
this._itemDragBeginId = 0;
|
||||
this._itemDragCancelledId = 0;
|
||||
this._itemDragEndId = 0;
|
||||
@ -589,7 +588,7 @@ WorkspacesDisplay.prototype = {
|
||||
this._windowDragEndId = 0;
|
||||
},
|
||||
|
||||
show: function() {
|
||||
show: function() {
|
||||
this._zoomOut = this._alwaysZoomOut;
|
||||
this._zoomFraction = this._alwaysZoomOut ? 1 : 0;
|
||||
this._updateZoom();
|
||||
@ -612,6 +611,9 @@ WorkspacesDisplay.prototype = {
|
||||
global.screen.connect('restacked',
|
||||
Lang.bind(this, this._onRestacked));
|
||||
|
||||
if (this._nWorkspacesChangedId == 0)
|
||||
this._nWorkspacesChangedId = global.screen.connect('notify::n-workspaces',
|
||||
Lang.bind(this, this._workspacesChanged));
|
||||
if (this._itemDragBeginId == 0)
|
||||
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
|
||||
Lang.bind(this, this._dragBegin));
|
||||
|
@ -37,6 +37,7 @@ ms
|
||||
nb
|
||||
nl
|
||||
nn
|
||||
or
|
||||
pa
|
||||
pl
|
||||
pt
|
||||
|
@ -1,6 +1,7 @@
|
||||
data/gnome-shell.desktop.in.in
|
||||
data/org.gnome.shell.gschema.xml.in
|
||||
js/gdm/loginDialog.js
|
||||
js/gdm/powerMenu.js
|
||||
js/misc/util.js
|
||||
js/ui/appDisplay.js
|
||||
js/ui/appFavorites.js
|
||||
@ -11,6 +12,7 @@ js/ui/dash.js
|
||||
js/ui/dateMenu.js
|
||||
js/ui/docDisplay.js
|
||||
js/ui/endSessionDialog.js
|
||||
js/ui/extensionSystem.js
|
||||
js/ui/keyboard.js
|
||||
js/ui/lookingGlass.js
|
||||
js/ui/messageTray.js
|
||||
|
1070
po/en_GB.po
1070
po/en_GB.po
File diff suppressed because it is too large
Load Diff
1123
po/pt_BR.po
1123
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
1228
po/sr@latin.po
1228
po/sr@latin.po
File diff suppressed because it is too large
Load Diff
919
po/zh_CN.po
919
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
871
po/zh_HK.po
871
po/zh_HK.po
File diff suppressed because it is too large
Load Diff
875
po/zh_TW.po
875
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,7 @@ typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
|
||||
servicedir = $(datadir)/dbus-1/services
|
||||
service_DATA = $(service_in_files:.service.in=.service)
|
||||
|
||||
$(service_DATA): $(service_in_files) Makefile
|
||||
%.service: %.service.in Makefile
|
||||
$(AM_V_GEN) \
|
||||
[ -d $(@D) ] || $(mkdir_p) $(@D) ; \
|
||||
sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@.tmp && mv $@.tmp $@
|
||||
@ -126,6 +126,7 @@ libgnome_shell_la_SOURCES = \
|
||||
$(shell_built_sources) \
|
||||
$(shell_public_headers_h) \
|
||||
shell-app-private.h \
|
||||
shell-app-system-private.h \
|
||||
shell-embedded-window-private.h \
|
||||
shell-global-private.h \
|
||||
shell-jsapi-compat-private.h \
|
||||
|
11
src/main.c
11
src/main.c
@ -117,6 +117,17 @@ shell_dbus_init (gboolean replace)
|
||||
g_print ("failed to acquire org.freedesktop.Notifications: %s\n", error->message);
|
||||
}
|
||||
|
||||
/* ...and the on-screen keyboard service */
|
||||
if (!dbus_g_proxy_call (bus, "RequestName", &error,
|
||||
G_TYPE_STRING, "org.gnome.Caribou.Keyboard",
|
||||
G_TYPE_UINT, DBUS_NAME_FLAG_REPLACE_EXISTING | request_name_flags,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_UINT, &request_name_result,
|
||||
G_TYPE_INVALID))
|
||||
{
|
||||
g_print ("failed to acquire org.gnome.Caribou.Keyboard: %s\n", error->message);
|
||||
}
|
||||
|
||||
g_object_unref (bus);
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,7 @@ main(int argc, char **argv)
|
||||
setlocale (LC_ALL, "");
|
||||
g_type_init ();
|
||||
|
||||
_shell_global_init (NULL);
|
||||
global = shell_global_get ();
|
||||
js_context = _shell_global_get_gjs_context (global);
|
||||
|
||||
|
@ -50,6 +50,7 @@ static char*
|
||||
get_atk_bridge_path (void)
|
||||
{
|
||||
GSettings *atspi_settings = NULL;
|
||||
GVariant *variant = NULL;
|
||||
char *value = NULL;
|
||||
const char * const *schemas = NULL;
|
||||
gboolean found = FALSE;
|
||||
@ -74,8 +75,9 @@ get_atk_bridge_path (void)
|
||||
}
|
||||
|
||||
atspi_settings = g_settings_new (AT_SPI_SCHEMA);
|
||||
value = g_settings_get_string (atspi_settings, ATK_BRIDGE_LOCATION_KEY);
|
||||
|
||||
variant = g_settings_get_value (atspi_settings, ATK_BRIDGE_LOCATION_KEY);
|
||||
value = g_variant_dup_bytestring (variant, NULL);
|
||||
g_variant_unref (variant);
|
||||
g_object_unref (atspi_settings);
|
||||
|
||||
return value;
|
||||
|
@ -14,6 +14,8 @@ ShellApp* _shell_app_new_for_window (MetaWindow *window);
|
||||
|
||||
ShellApp* _shell_app_new (GMenuTreeEntry *entry);
|
||||
|
||||
void _shell_app_set_entry (ShellApp *app, GMenuTreeEntry *entry);
|
||||
|
||||
void _shell_app_handle_startup_sequence (ShellApp *app, SnStartupSequence *sequence);
|
||||
|
||||
void _shell_app_add_window (ShellApp *app, MetaWindow *window);
|
||||
|
9
src/shell-app-system-private.h
Normal file
9
src/shell-app-system-private.h
Normal file
@ -0,0 +1,9 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
#ifndef __SHELL_APP_SYSTEM_PRIVATE_H__
|
||||
#define __SHELL_APP_SYSTEM_PRIVATE_H__
|
||||
|
||||
#include "shell-app-system.h"
|
||||
|
||||
void _shell_app_system_notify_app_state_changed (ShellAppSystem *self, ShellApp *app);
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user