Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
60612cace9 | |||
f057502834 | |||
21a1149532 | |||
6724ca4f63 | |||
7a6c25b3fb | |||
0366e320af | |||
f03793b825 | |||
0907f030b4 | |||
7542e68b6f | |||
9003a34285 |
47
NEWS
47
NEWS
@ -1,3 +1,50 @@
|
|||||||
|
3.1.4
|
||||||
|
=====
|
||||||
|
* Take over inserted media handling and autorun from gnome-session [Cosimo]
|
||||||
|
* Message Tray
|
||||||
|
- Display a count of unread notifications on icons
|
||||||
|
[Jasper, Guillaume; #649356, #654139]
|
||||||
|
- Only remove icons when the sender quits from D-Bus, not when it
|
||||||
|
closes its last window [Neha, Marina; #645764]
|
||||||
|
- Solve problems switching chats between shell and Empathy
|
||||||
|
[Guillaume; #654237]
|
||||||
|
- Fix handling of bad GMarkup in messages [Dan; #650298]
|
||||||
|
- Never show notifications when the screensaver is active [Dan; #654550]
|
||||||
|
* Telepathy integrationpp
|
||||||
|
- Implement Telepathy Debug interface to enable empathy-debugger
|
||||||
|
[Guillaume; #652816]
|
||||||
|
- Allow approving room invitations, and audio/video calls
|
||||||
|
[Guillaume; #653740 #653939]
|
||||||
|
- Send typing notifications [Jonny; #650196]
|
||||||
|
* Fix selection highlighting for light-on-dark entries [Jasper; #643768]
|
||||||
|
* Make control-Return in the overview open a new window [Maxim]
|
||||||
|
* Delay showing the alt-Tab switcher to reduce visual noise when
|
||||||
|
flipping betweeen windows [Dan; #652346]
|
||||||
|
* When we have vertically stacked monitors, put the message tray
|
||||||
|
on the bottom one [Dan; #636963]
|
||||||
|
* Fix various problems with keynav and the Activities button
|
||||||
|
[Dan; #641253 #645759]
|
||||||
|
* Ensure screensaver is locked when switching users [Colin; #654565]
|
||||||
|
* Improve extension creation tool [Jasper; #653206]
|
||||||
|
* Fix compatibility with latest GJS [Giovanni; #654349]
|
||||||
|
* Code cleanups [Adel, Dan, Jasper; #645759 #654577 #654791 #654987]
|
||||||
|
* Misc bug fixes [Richard, Dan, Florian, Giovanni, Jasper, Marc-Antoine, Rui;
|
||||||
|
#647175 #649513 #650452 #651082 #653700 #653989 #654105 #654791 #654267
|
||||||
|
#654269 #654527 #655446]
|
||||||
|
* Build fixes [Florian, Siegfried; #654300]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Cosimo Cecchi, Guillaume Desmottes, Neha Doijode,
|
||||||
|
Maxim Ermilov, Adel Gadllah, Siegfried-Angel Gevatter Pujals, Richard Hughes,
|
||||||
|
Jonny Lamb, Rui Matos, Florian Müllner, Marc-Antoine Perennou, Colin Walters,
|
||||||
|
Dan Winship, Marina Zhurakhinskaya
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Mario Blättermann, Paul Seyfert [de], Jorge González, Daniel Mustieles [es],
|
||||||
|
Fran Dieguez [gl], Yaron Shahrabani [he], Luca Ferretti [it],
|
||||||
|
Rudolfs Mazurs [lv], Kjartan Maraas [nb], A S Alam [pa], Yuri Kozlov [ru],
|
||||||
|
Michal Štrba, Matej Urbančič [sl]
|
||||||
|
|
||||||
3.1.3
|
3.1.3
|
||||||
=====
|
=====
|
||||||
* Fix problem with "user theme extension" breaking the CSS for other
|
* Fix problem with "user theme extension" breaking the CSS for other
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
AC_PREREQ(2.63)
|
AC_PREREQ(2.63)
|
||||||
AC_INIT([gnome-shell],[3.1.3],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
AC_INIT([gnome-shell],[3.1.4],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||||
|
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||||
@ -66,7 +66,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
|||||||
|
|
||||||
CLUTTER_MIN_VERSION=1.7.5
|
CLUTTER_MIN_VERSION=1.7.5
|
||||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
||||||
GJS_MIN_VERSION=0.7.11
|
GJS_MIN_VERSION=1.29.15
|
||||||
MUTTER_MIN_VERSION=3.0.0
|
MUTTER_MIN_VERSION=3.0.0
|
||||||
GTK_MIN_VERSION=3.0.0
|
GTK_MIN_VERSION=3.0.0
|
||||||
GIO_MIN_VERSION=2.25.9
|
GIO_MIN_VERSION=2.25.9
|
||||||
|
@ -289,6 +289,11 @@ Chrome.prototype = {
|
|||||||
|
|
||||||
for (let i = windows.length - 1; i > -1; i--) {
|
for (let i = windows.length - 1; i > -1; i--) {
|
||||||
let window = windows[i];
|
let window = windows[i];
|
||||||
|
|
||||||
|
// Skip minimized windows
|
||||||
|
if (!window.showing_on_its_workspace())
|
||||||
|
continue;
|
||||||
|
|
||||||
let layer = window.get_meta_window().get_layer();
|
let layer = window.get_meta_window().get_layer();
|
||||||
|
|
||||||
if (layer == Meta.StackLayer.FULLSCREEN) {
|
if (layer == Meta.StackLayer.FULLSCREEN) {
|
||||||
|
@ -68,14 +68,19 @@ function _fixMarkup(text, allowMarkup) {
|
|||||||
// Support &, ", ', < and >, escape all other
|
// Support &, ", ', < and >, escape all other
|
||||||
// occurrences of '&'.
|
// occurrences of '&'.
|
||||||
let _text = text.replace(/&(?!amp;|quot;|apos;|lt;|gt;)/g, '&');
|
let _text = text.replace(/&(?!amp;|quot;|apos;|lt;|gt;)/g, '&');
|
||||||
|
|
||||||
// Support <b>, <i>, and <u>, escape anything else
|
// Support <b>, <i>, and <u>, escape anything else
|
||||||
// so it displays as raw markup.
|
// so it displays as raw markup.
|
||||||
return _text.replace(/<(\/?[^biu]>|[^>\/][^>])/g, '<$1');
|
_text = _text.replace(/<(?!\/?[biu]>)/g, '<');
|
||||||
} else {
|
|
||||||
// Escape everything
|
try {
|
||||||
let _text = text.replace(/&/g, '&');
|
Pango.parse_markup(_text, -1, '');
|
||||||
return _text.replace(/</g, '<');
|
return _text;
|
||||||
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// !allowMarkup, or invalid markup
|
||||||
|
return GLib.markup_escape_text(text, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function URLHighlighter(text, lineWrap, allowMarkup) {
|
function URLHighlighter(text, lineWrap, allowMarkup) {
|
||||||
|
@ -461,9 +461,11 @@ Source.prototype = {
|
|||||||
|
|
||||||
_onNameVanished: function() {
|
_onNameVanished: function() {
|
||||||
// Destroy the notification source when its sender is removed from DBus.
|
// Destroy the notification source when its sender is removed from DBus.
|
||||||
|
// Only do so if this.app is set to avoid removing "notify-send" sources, senders
|
||||||
|
// of which аre removed from DBus immediately.
|
||||||
// Sender being removed from DBus would normally result in a tray icon being removed,
|
// Sender being removed from DBus would normally result in a tray icon being removed,
|
||||||
// so allow the code path that handles the tray icon being removed to handle that case.
|
// so allow the code path that handles the tray icon being removed to handle that case.
|
||||||
if (!this.trayIcon)
|
if (!this.trayIcon && this.app)
|
||||||
this.destroy();
|
this.destroy();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ CLEANFILES += $(service_DATA)
|
|||||||
CLEANFILES += $(gir_DATA) $(typelib_DATA)
|
CLEANFILES += $(gir_DATA) $(typelib_DATA)
|
||||||
|
|
||||||
bin_SCRIPTS += gnome-shell-extension-tool
|
bin_SCRIPTS += gnome-shell-extension-tool
|
||||||
|
EXTRA_DIST += gnome-shell-extension-tool.in
|
||||||
bin_PROGRAMS = gnome-shell-real
|
bin_PROGRAMS = gnome-shell-real
|
||||||
|
|
||||||
if USE_JHBUILD_WRAPPER_SCRIPT
|
if USE_JHBUILD_WRAPPER_SCRIPT
|
||||||
@ -36,6 +37,7 @@ bin_SCRIPTS += gnome-shell-jhbuild
|
|||||||
else
|
else
|
||||||
gnome_shell = gnome-shell-real
|
gnome_shell = gnome-shell-real
|
||||||
endif
|
endif
|
||||||
|
EXTRA_DIST += gnome-shell-jhbuild.in
|
||||||
|
|
||||||
noinst_DATA = gnome-shell
|
noinst_DATA = gnome-shell
|
||||||
gnome-shell: $(gnome_shell) Makefile
|
gnome-shell: $(gnome_shell) Makefile
|
||||||
@ -65,7 +67,6 @@ gnome-shell-extension-tool: gnome-shell-extension-tool.in Makefile
|
|||||||
$(AM_V_GEN) sed $(generated_script_substitutions) $< > $@.tmp && mv $@.tmp $@ && chmod a+x $@
|
$(AM_V_GEN) sed $(generated_script_substitutions) $< > $@.tmp && mv $@.tmp $@ && chmod a+x $@
|
||||||
|
|
||||||
CLEANFILES += gnome-shell $(bin_SCRIPTS)
|
CLEANFILES += gnome-shell $(bin_SCRIPTS)
|
||||||
EXTRA_DIST += $(bin_SCRIPTS:=.in)
|
|
||||||
|
|
||||||
include Makefile-gdmuser.am
|
include Makefile-gdmuser.am
|
||||||
include Makefile-st.am
|
include Makefile-st.am
|
||||||
|
@ -32,18 +32,17 @@
|
|||||||
|
|
||||||
#include <clutter/x11/clutter-x11.h>
|
#include <clutter/x11/clutter-x11.h>
|
||||||
#include <gdk/gdkx.h>
|
#include <gdk/gdkx.h>
|
||||||
|
#include <girepository.h>
|
||||||
#include <gjs/gjs.h>
|
#include <gjs/gjs.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#include "shell-global.h"
|
#include "shell-global.h"
|
||||||
#include "shell-global-private.h"
|
#include "shell-global-private.h"
|
||||||
|
|
||||||
static char **include_path = NULL;
|
|
||||||
static char *command = NULL;
|
static char *command = NULL;
|
||||||
|
|
||||||
static GOptionEntry entries[] = {
|
static GOptionEntry entries[] = {
|
||||||
{ "command", 'c', 0, G_OPTION_ARG_STRING, &command, "Program passed in as a string", "COMMAND" },
|
{ "command", 'c', 0, G_OPTION_ARG_STRING, &command, "Program passed in as a string", "COMMAND" },
|
||||||
{ "include-path", 'I', 0, G_OPTION_ARG_STRING_ARRAY, &include_path, "Add the directory DIR to the list of directories to search for js files.", "DIR" },
|
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -131,6 +130,14 @@ main(int argc, char **argv)
|
|||||||
clutter_stage_set_title (CLUTTER_STAGE (stage), title);
|
clutter_stage_set_title (CLUTTER_STAGE (stage), title);
|
||||||
g_free (title);
|
g_free (title);
|
||||||
|
|
||||||
|
#if HAVE_BLUETOOTH
|
||||||
|
/* The module imports are all so intertwined that if the test
|
||||||
|
* imports anything in js/ui, it will probably eventually end up
|
||||||
|
* pulling in ui/status/bluetooth.js. So we need this.
|
||||||
|
*/
|
||||||
|
g_irepository_prepend_search_path (BLUETOOTH_DIR);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* evaluate the script */
|
/* evaluate the script */
|
||||||
error = NULL;
|
error = NULL;
|
||||||
if (!gjs_context_eval (js_context, script, len,
|
if (!gjs_context_eval (js_context, script, len,
|
||||||
|
@ -18,7 +18,8 @@ TEST_JS = \
|
|||||||
testcommon/border-image.png \
|
testcommon/border-image.png \
|
||||||
testcommon/face-plain.png \
|
testcommon/face-plain.png \
|
||||||
testcommon/ui.js \
|
testcommon/ui.js \
|
||||||
unit/format.js
|
unit/format.js \
|
||||||
|
unit/markup.js
|
||||||
EXTRA_DIST += $(TEST_JS)
|
EXTRA_DIST += $(TEST_JS)
|
||||||
|
|
||||||
TEST_MISC = \
|
TEST_MISC = \
|
||||||
@ -28,6 +29,7 @@ EXTRA_DIST += $(TEST_MISC)
|
|||||||
run-test.sh: run-test.sh.in
|
run-test.sh: run-test.sh.in
|
||||||
$(AM_V_GEN) sed \
|
$(AM_V_GEN) sed \
|
||||||
-e "s|@MUTTER_TYPELIB_DIR[@]|$(MUTTER_TYPELIB_DIR)|" \
|
-e "s|@MUTTER_TYPELIB_DIR[@]|$(MUTTER_TYPELIB_DIR)|" \
|
||||||
|
-e "s|@JHBUILD_TYPELIBDIR[@]|$(JHBUILD_TYPELIBDIR)|" \
|
||||||
-e "s|@srcdir[@]|$(srcdir)|" \
|
-e "s|@srcdir[@]|$(srcdir)|" \
|
||||||
$< > $@ && chmod a+x $@
|
$< > $@ && chmod a+x $@
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ builddir=`cd $builddir && pwd`
|
|||||||
srcdir=$builddir/@srcdir@
|
srcdir=$builddir/@srcdir@
|
||||||
srcdir=`cd $srcdir && pwd`
|
srcdir=`cd $srcdir && pwd`
|
||||||
|
|
||||||
GI_TYPELIB_PATH="@MUTTER_TYPELIB_DIR@:$builddir/../src"
|
GI_TYPELIB_PATH="$GI_TYPELIB_PATH${GI_TYPELIB_PATH:+:}@MUTTER_TYPELIB_DIR@:@JHBUILD_TYPELIBDIR@:$builddir/../src"
|
||||||
GJS_PATH="$srcdir:$srcdir/../js"
|
GJS_PATH="$srcdir:$srcdir/../js"
|
||||||
GJS_DEBUG_OUTPUT=stderr
|
GJS_DEBUG_OUTPUT=stderr
|
||||||
$verbose || GJS_DEBUG_TOPICS="JS ERROR;JS LOG"
|
$verbose || GJS_DEBUG_TOPICS="JS ERROR;JS LOG"
|
||||||
|
142
tests/unit/markup.js
Normal file
142
tests/unit/markup.js
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
// Test cases for MessageTray markup parsing
|
||||||
|
|
||||||
|
const JsUnit = imports.jsUnit;
|
||||||
|
const Pango = imports.gi.Pango;
|
||||||
|
|
||||||
|
const Environment = imports.ui.environment;
|
||||||
|
Environment.init();
|
||||||
|
|
||||||
|
const MessageTray = imports.ui.messageTray;
|
||||||
|
|
||||||
|
// Assert that @input, assumed to be markup, gets "fixed" to @output,
|
||||||
|
// which is valid markup. If @output is null, @input is expected to
|
||||||
|
// convert to itself
|
||||||
|
function assertConverts(input, output) {
|
||||||
|
if (!output)
|
||||||
|
output = input;
|
||||||
|
let fixed = MessageTray._fixMarkup(input, true);
|
||||||
|
JsUnit.assertEquals(output, fixed);
|
||||||
|
|
||||||
|
let parsed = false;
|
||||||
|
try {
|
||||||
|
Pango.parse_markup(fixed, -1, '');
|
||||||
|
parsed = true;
|
||||||
|
} catch (e) {}
|
||||||
|
JsUnit.assertEquals(true, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that @input, assumed to be plain text, gets escaped to @output,
|
||||||
|
// which is valid markup.
|
||||||
|
function assertEscapes(input, output) {
|
||||||
|
let fixed = MessageTray._fixMarkup(input, false);
|
||||||
|
JsUnit.assertEquals(output, fixed);
|
||||||
|
|
||||||
|
let parsed = false;
|
||||||
|
try {
|
||||||
|
Pango.parse_markup(fixed, -1, '');
|
||||||
|
parsed = true;
|
||||||
|
} catch (e) {}
|
||||||
|
JsUnit.assertEquals(true, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// CORRECT MARKUP
|
||||||
|
|
||||||
|
assertConverts('foo');
|
||||||
|
assertEscapes('foo', 'foo');
|
||||||
|
|
||||||
|
assertConverts('<b>foo</b>');
|
||||||
|
assertEscapes('<b>foo</b>', '<b>foo</b>');
|
||||||
|
|
||||||
|
assertConverts('something <i>foo</i>');
|
||||||
|
assertEscapes('something <i>foo</i>', 'something <i>foo</i>');
|
||||||
|
|
||||||
|
assertConverts('<u>foo</u> something');
|
||||||
|
assertEscapes('<u>foo</u> something', '<u>foo</u> something');
|
||||||
|
|
||||||
|
assertConverts('<b>bold</b> <i>italic <u>and underlined</u></i>');
|
||||||
|
assertEscapes('<b>bold</b> <i>italic <u>and underlined</u></i>', '<b>bold</b> <i>italic <u>and underlined</u></i>');
|
||||||
|
|
||||||
|
assertConverts('this & that');
|
||||||
|
assertEscapes('this & that', 'this &amp; that');
|
||||||
|
|
||||||
|
assertConverts('this < that');
|
||||||
|
assertEscapes('this < that', 'this &lt; that');
|
||||||
|
|
||||||
|
assertConverts('this < that > the other');
|
||||||
|
assertEscapes('this < that > the other', 'this &lt; that &gt; the other');
|
||||||
|
|
||||||
|
assertConverts('this <<i>that</i>>');
|
||||||
|
assertEscapes('this <<i>that</i>>', 'this &lt;<i>that</i>&gt;');
|
||||||
|
|
||||||
|
assertConverts('<b>this</b> > <i>that</i>');
|
||||||
|
assertEscapes('<b>this</b> > <i>that</i>', '<b>this</b> > <i>that</i>');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// PARTIALLY CORRECT MARKUP
|
||||||
|
// correct bits are kept, incorrect bits are escaped
|
||||||
|
|
||||||
|
// unrecognized entity
|
||||||
|
assertConverts('<b>smile</b> ☺!', '<b>smile</b> &#9786;!');
|
||||||
|
assertEscapes('<b>smile</b> ☺!', '<b>smile</b> &#9786;!');
|
||||||
|
|
||||||
|
// stray '&'; this is really a bug, but it's easier to do it this way
|
||||||
|
assertConverts('<b>this</b> & <i>that</i>', '<b>this</b> & <i>that</i>');
|
||||||
|
assertEscapes('<b>this</b> & <i>that</i>', '<b>this</b> & <i>that</i>');
|
||||||
|
|
||||||
|
// likewise with stray '<'
|
||||||
|
assertConverts('this < that', 'this < that');
|
||||||
|
assertEscapes('this < that', 'this < that');
|
||||||
|
|
||||||
|
assertConverts('<b>this</b> < <i>that</i>', '<b>this</b> < <i>that</i>');
|
||||||
|
assertEscapes('<b>this</b> < <i>that</i>', '<b>this</b> < <i>that</i>');
|
||||||
|
|
||||||
|
assertConverts('this < that > the other', 'this < that > the other');
|
||||||
|
assertEscapes('this < that > the other', 'this < that > the other');
|
||||||
|
|
||||||
|
assertConverts('this <<i>that</i>>', 'this <<i>that</i>>');
|
||||||
|
assertEscapes('this <<i>that</i>>', 'this <<i>that</i>>');
|
||||||
|
|
||||||
|
// unknown tags
|
||||||
|
assertConverts('<unknown>tag</unknown>', '<unknown>tag</unknown>');
|
||||||
|
assertEscapes('<unknown>tag</unknown>', '<unknown>tag</unknown>');
|
||||||
|
|
||||||
|
// make sure we check beyond the first letter
|
||||||
|
assertConverts('<bunknown>tag</bunknown>', '<bunknown>tag</bunknown>');
|
||||||
|
assertEscapes('<bunknown>tag</bunknown>', '<bunknown>tag</bunknown>');
|
||||||
|
|
||||||
|
// with mix of good and bad, we keep the good and escape the bad
|
||||||
|
assertConverts('<i>known</i> and <unknown>tag</unknown>', '<i>known</i> and <unknown>tag</unknown>');
|
||||||
|
assertEscapes('<i>known</i> and <unknown>tag</unknown>', '<i>known</i> and <unknown>tag</unknown>');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// FULLY INCORRECT MARKUP
|
||||||
|
// (fall back to escaping the whole thing)
|
||||||
|
|
||||||
|
// tags not matched up
|
||||||
|
assertConverts('<b>in<i>com</i>plete', '<b>in<i>com</i>plete');
|
||||||
|
assertEscapes('<b>in<i>com</i>plete', '<b>in<i>com</i>plete');
|
||||||
|
|
||||||
|
assertConverts('in<i>com</i>plete</b>', 'in<i>com</i>plete</b>');
|
||||||
|
assertEscapes('in<i>com</i>plete</b>', 'in<i>com</i>plete</b>');
|
||||||
|
|
||||||
|
// we don't support attributes, and it's too complicated to try
|
||||||
|
// to escape both start and end tags, so we just treat it as bad
|
||||||
|
assertConverts('<b>good</b> and <b style=\'bad\'>bad</b>', '<b>good</b> and <b style='bad'>bad</b>');
|
||||||
|
assertEscapes('<b>good</b> and <b style=\'bad\'>bad</b>', '<b>good</b> and <b style='bad'>bad</b>');
|
||||||
|
|
||||||
|
// this is just syntactically invalid
|
||||||
|
assertConverts('<b>unrecognized</b stuff>', '<b>unrecognized</b stuff>');
|
||||||
|
assertEscapes('<b>unrecognized</b stuff>', '<b>unrecognized</b stuff>');
|
||||||
|
|
||||||
|
// mismatched tags
|
||||||
|
assertConverts('<b>mismatched</i>', '<b>mismatched</i>');
|
||||||
|
assertEscapes('<b>mismatched</i>', '<b>mismatched</i>');
|
||||||
|
|
||||||
|
assertConverts('<b>mismatched/unknown</bunknown>', '<b>mismatched/unknown</bunknown>');
|
||||||
|
assertEscapes('<b>mismatched/unknown</bunknown>', '<b>mismatched/unknown</bunknown>');
|
Reference in New Issue
Block a user