Branch: refs/heads/master
Author: Enrico Tröger <enrico.troeger(a)uvena.de>
Committer: Enrico Tröger <enrico.troeger(a)uvena.de>
Date: Wed, 28 Dec 2016 22:20:47 UTC
Commit: 16ea1d35a6fa9cd0164bddf2b2813b7db8e2455e
https://github.com/geany/geany/commit/16ea1d35a6fa9cd0164bddf2b2813b7db8e24…
Log Message:
-----------
Fix file names of generated tags files for C, PHP and Python
Modified Paths:
--------------
scripts/create_c_tags.sh
scripts/create_php_tags.py
scripts/create_py_tags.py
Modified: scripts/create_c_tags.sh
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -7,7 +7,7 @@
#
tmpfile="tmp.c.tags"
-tagfile="data/tags/c99.tags"
+tagfile="data/tags/std99.c.tags"
headers="\
assert.h \
Modified: scripts/create_php_tags.py
4 lines changed, 2 insertions(+), 2 deletions(-)
===================================================================
@@ -7,7 +7,7 @@
# This script downloads the PHP tag definitions in JSON format from
# http://doc.php.net/downloads/json/php_manual_en.json.
# From those defintions all function tags are extracted and written
-# to ../data/tags/php.tags (relative to the script's location, not $CWD).
+# to ../data/tags/std.php.tags (relative to the script's location, not $CWD).
from json import loads
from os.path import dirname, join
@@ -85,7 +85,7 @@ def parse_and_create_php_tags_file():
# write tags
script_dir = dirname(__file__)
- tags_file_path = join(script_dir, '..', 'data', 'tags', 'php.tags')
+ tags_file_path = join(script_dir, '..', 'data', 'tags', 'std.php.tags')
with open(tags_file_path, 'w') as tags_file:
tags_file.write('# format=tagmanager\n')
for tag_name, tag_type, return_type, arg_list, scope in sorted(tag_list):
Modified: scripts/create_py_tags.py
4 lines changed, 2 insertions(+), 2 deletions(-)
===================================================================
@@ -9,7 +9,7 @@
# This script should be run in the top source directory.
#
# Parses all files given on command line for Python classes or functions and write
-# them into data/tags/python.tags (internal tagmanager format).
+# them into data/tags/std.py.tags (internal tagmanager format).
# If called without command line arguments, a preset of common Python libs is used.
#
# WARNING
@@ -51,7 +51,7 @@
TYPE_CLASS = '%d' % 1
TYPE_FUNCTION = '%d' % 128
-tag_filename = 'data/tags/python.tags'
+tag_filename = 'data/tags/std.py.tags'
tag_regexp = '^[ \t]*(def|class)[ \t]+([a-zA-Z0-9_]+)[ \t]*(\(.*\))[:]'
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Enrico Tröger <enrico.troeger(a)uvena.de>
Committer: Enrico Tröger <enrico.troeger(a)uvena.de>
Date: Wed, 28 Dec 2016 21:59:46 UTC
Commit: 59f080d058a0eb6f602e770ee6b71c0c63cabd79
https://github.com/geany/geany/commit/59f080d058a0eb6f602e770ee6b71c0c63cab…
Log Message:
-----------
Update tags and filedefs path references in scripts
This is a follow-up of #485.
Modified Paths:
--------------
scripts/create_c_tags.sh
scripts/create_php_tags.py
scripts/create_py_tags.py
scripts/update-python-identifiers.sh
Modified: scripts/create_c_tags.sh
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -7,7 +7,7 @@
#
tmpfile="tmp.c.tags"
-tagfile="data/c99.tags"
+tagfile="data/tags/c99.tags"
headers="\
assert.h \
Modified: scripts/create_php_tags.py
4 lines changed, 2 insertions(+), 2 deletions(-)
===================================================================
@@ -7,7 +7,7 @@
# This script downloads the PHP tag definitions in JSON format from
# http://doc.php.net/downloads/json/php_manual_en.json.
# From those defintions all function tags are extracted and written
-# to ../data/php.tags (relative to the script's location, not $CWD).
+# to ../data/tags/php.tags (relative to the script's location, not $CWD).
from json import loads
from os.path import dirname, join
@@ -85,7 +85,7 @@ def parse_and_create_php_tags_file():
# write tags
script_dir = dirname(__file__)
- tags_file_path = join(script_dir, '..', 'data', 'php.tags')
+ tags_file_path = join(script_dir, '..', 'data', 'tags', 'php.tags')
with open(tags_file_path, 'w') as tags_file:
tags_file.write('# format=tagmanager\n')
for tag_name, tag_type, return_type, arg_list, scope in sorted(tag_list):
Modified: scripts/create_py_tags.py
4 lines changed, 2 insertions(+), 2 deletions(-)
===================================================================
@@ -9,7 +9,7 @@
# This script should be run in the top source directory.
#
# Parses all files given on command line for Python classes or functions and write
-# them into data/python.tags (internal tagmanager format).
+# them into data/tags/python.tags (internal tagmanager format).
# If called without command line arguments, a preset of common Python libs is used.
#
# WARNING
@@ -51,7 +51,7 @@
TYPE_CLASS = '%d' % 1
TYPE_FUNCTION = '%d' % 128
-tag_filename = 'data/python.tags'
+tag_filename = 'data/tags/python.tags'
tag_regexp = '^[ \t]*(def|class)[ \t]+([a-zA-Z0-9_]+)[ \t]*(\(.*\))[:]'
Modified: scripts/update-python-identifiers.sh
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -8,7 +8,7 @@
set -e
-file=data/filetypes.python
+file=data/filedefs/filetypes.python
[ -f "$file" ]
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Thomas Martitz <kugel(a)rockbox.org>
Committer: Thomas Martitz <kugel(a)rockbox.org>
Date: Tue, 27 Dec 2016 23:39:35 UTC
Commit: 129389c75bd416c33d10e64cb73017df47c90ab5
https://github.com/geany/geany/commit/129389c75bd416c33d10e64cb73017df47c90…
Log Message:
-----------
api: rework GeanyProxyProbeResults compat symbols as defines
Constants with different namespace in the same enum confuse g-ir-scanner.
Modified Paths:
--------------
src/plugindata.h
Modified: src/plugindata.h
30 lines changed, 15 insertions(+), 15 deletions(-)
===================================================================
@@ -345,29 +345,17 @@ void geany_plugin_set_data(GeanyPlugin *plugin, gpointer data, GDestroyNotify fr
*/
typedef enum
{
- /** @deprecated Use GEANY_PROXY_IGNORE instead.
- * @since 1.26 (API 226)
- */
- PROXY_IGNORED,
- /** @deprecated Use GEANY_PROXY_MATCH instead.
- * @since 1.26 (API 226)
- */
- PROXY_MATCHED,
- /** @deprecated Use GEANY_PROXY_RELATED instead.
- * @since 1.26 (API 226)
- */
- PROXY_NOLOAD = 0x100,
/** The proxy is not responsible at all, and Geany or other plugins are free
* to probe it.
*
* @since 1.29 (API 229)
**/
- GEANY_PROXY_IGNORE = PROXY_IGNORED,
+ GEANY_PROXY_IGNORE,
/** The proxy is responsible for this file, and creates a plugin for it.
*
* @since 1.29 (API 229)
*/
- GEANY_PROXY_MATCH = PROXY_MATCHED,
+ GEANY_PROXY_MATCH,
/** The proxy is does not directly load it, but it's still tied to the proxy.
*
* This is for plugins that come in multiple files where only one of these
@@ -378,10 +366,22 @@ typedef enum
*
* @since 1.29 (API 229)
*/
- GEANY_PROXY_RELATED = PROXY_MATCHED | PROXY_NOLOAD
+ GEANY_PROXY_RELATED = GEANY_PROXY_MATCH | 0x100
}
GeanyProxyProbeResults;
+/** @deprecated Use GEANY_PROXY_IGNORE instead.
+ * @since 1.26 (API 226)
+ */
+#define PROXY_IGNORED GEANY_PROXY_IGNORE
+/** @deprecated Use GEANY_PROXY_MATCH instead.
+ * @since 1.26 (API 226)
+ */
+#define PROXY_MATCHED GEANY_PROXY_MATCH
+/** @deprecated Use GEANY_PROXY_RELATED instead.
+ * @since 1.26 (API 226)
+ */
+#define PROXY_NOLOAD 0x100
/** Hooks that need to be implemented by every proxy
*
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Jiří Techet <techet(a)gmail.com>
Committer: Jiří Techet <techet(a)gmail.com>
Date: Thu, 22 Dec 2016 14:08:52 UTC
Commit: fb6a911e8c1c8b55d38873917991b2ed2a74b0ef
https://github.com/geany/geany-osx/commit/fb6a911e8c1c8b55d38873917991b2ed2…
Log Message:
-----------
Make gtk-building single-line command
Easier to copy-paste and build in one step.
Modified Paths:
--------------
README.md
Modified: README.md
4 lines changed, 1 insertions(+), 3 deletions(-)
===================================================================
@@ -98,9 +98,7 @@ To create the bundle, you need to first install JHBuild and GTK as described bel
6. Install GTK 2 and all its dependencies using the following commands:
```
- jhbuild bootstrap
- jhbuild build meta-gtk-osx-bootstrap
- jhbuild build meta-gtk-osx-core
+ jhbuild bootstrap && jhbuild build meta-gtk-osx-bootstrap && jhbuild build meta-gtk-osx-core
```
Instead of meta-gtk-osx-core (GTK 2) you can also use `meta-gtk-osx-gtk3` to
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Jiří Techet <techet(a)gmail.com>
Committer: Jiří Techet <techet(a)gmail.com>
Date: Thu, 22 Dec 2016 14:03:00 UTC
Commit: 15c0f3e5cc841cb47101fb59273d51d4734e0ae3
https://github.com/geany/geany-osx/commit/15c0f3e5cc841cb47101fb59273d51d47…
Log Message:
-----------
Create bundle signature directly using codesign
The method used by gtk-mac-bundler doesn’t seem to work for all OS X
versions (e.g. doesn’t work on 10.10.5). Signing directly with codesign
seems to work now - though the signature probably isn’t “right” because
libraries are in resource directories and therefore signed as resources
instead of binaries (the “right” signature for binaries signs every code
page independently so signatures can be verified lazily as the code
gets loaded instead of all the code at the launch time).
Modified Paths:
--------------
README.md
create_dmg.sh
Modified: README.md
23 lines changed, 15 insertions(+), 8 deletions(-)
===================================================================
@@ -169,25 +169,32 @@ Bundling
from within the geany-osx directory.
-5. Optionally if you have a development account at Apple and want to sign the
+5. Create the app bundle by calling
+
+ ```
+ gtk-mac-bundler geany.bundle
+ ```
+
+ from within the geany-osx directory.
+
+6. Optionally if you have a development account at Apple and want to sign the
resulting bundle so it can be started without warning dialogs, use
```
- export APPLICATION_CERT="your certificate name"
+ export SIGN_CERTIFICATE="your certificate name"
```
The certificate should be installed in your login keychain. You can get the
certificate name by running `security find-identity -p codesigning` and
- checking for "Developer ID Application" - the name that follows it is the
- certificate name.
+ checking for "Developer ID Application" - the whole name in apostrophes is
+ the certificate name.
-6. Create the app bundle by calling
+ Then run
```
- gtk-mac-bundler geany.bundle
+ codesign -s $SIGN_CERTIFICATE --deep --force ./Geany.app
```
- from within the geany-osx directory.
Distribution
------------
@@ -203,7 +210,7 @@ Distribution
./create_dmg.sh
```
- from within the geany-osx directory. If the APPLICATION_CERT variable is
+ from within the geany-osx directory. If the SIGN_CERTIFICATE variable is
defined, the image gets signed by the specified certificate.
Maintenance
Modified: create_dmg.sh
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -29,5 +29,5 @@ rm -rf "${TMPDIR}"
if [ -n "$APPLICATION_CERT" ]
then
- codesign -s "$APPLICATION_CERT" "$DMGNAME"
+ codesign -s "$SIGN_CERTIFICATE" "$DMGNAME"
fi
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Colomban Wendling <ban(a)herbesfolles.org>
Committer: Colomban Wendling <ban(a)herbesfolles.org>
Date: Thu, 22 Dec 2016 12:54:16 UTC
Commit: cad224d204b08f0e0b96f87dfa4bfefadfeb9a77
https://github.com/geany/geany/commit/cad224d204b08f0e0b96f87dfa4bfefadfeb9…
Log Message:
-----------
Merge pull request #1280 from b4n/current-scope
Fix the current scope shown in the statusbar
Modified Paths:
--------------
src/symbols.c
Modified: src/symbols.c
48 lines changed, 44 insertions(+), 4 deletions(-)
===================================================================
@@ -45,6 +45,7 @@
#include "encodings.h"
#include "filetypesprivate.h"
#include "geanyobject.h"
+#include "highlighting.h"
#include "main.h"
#include "navqueue.h"
#include "sciwrappers.h"
@@ -2275,14 +2276,51 @@ static gchar *parse_cpp_function_at_line(ScintillaObject *sci, gint tag_line)
}
+/* gets the fold header after or on @line, but skipping folds created because of parentheses */
static gint get_fold_header_after(ScintillaObject *sci, gint line)
{
- gint line_count = sci_get_line_count(sci);
+ const gint line_count = sci_get_line_count(sci);
for (; line < line_count; line++)
{
if (sci_get_fold_level(sci, line) & SC_FOLDLEVELHEADERFLAG)
- return line;
+ {
+ const gint last_child = scintilla_send_message(sci, SCI_GETLASTCHILD, line, -1);
+ const gint line_end = sci_get_line_end_position(sci, line);
+ const gint lexer = sci_get_lexer(sci);
+ gint parenthesis_match_line = -1;
+
+ /* now find any unbalanced open parenthesis on the line and see where the matching
+ * brace would be, mimicking what folding on () does */
+ for (gint pos = sci_get_position_from_line(sci, line); pos < line_end; pos++)
+ {
+ if (highlighting_is_code_style(lexer, sci_get_style_at(sci, pos)) &&
+ sci_get_char_at(sci, pos) == '(')
+ {
+ const gint matching = sci_find_matching_brace(sci, pos);
+
+ if (matching >= 0)
+ {
+ parenthesis_match_line = sci_get_line_from_position(sci, matching);
+ if (parenthesis_match_line != line)
+ break; /* match is on a different line, we found a possible fold */
+ else
+ pos = matching; /* just skip the range and continue searching */
+ }
+ }
+ }
+
+ /* if the matching parenthesis matches the fold level, skip it and continue.
+ * it matches if it either spans the same lines, or spans one more but the next one is
+ * a fold header (in which case the last child of the fold is one less to let the
+ * header be at the parent level) */
+ if ((parenthesis_match_line == last_child) ||
+ (parenthesis_match_line == last_child + 1 &&
+ sci_get_fold_level(sci, parenthesis_match_line) & SC_FOLDLEVELHEADERFLAG))
+ line = last_child;
+ else
+ return line;
+ }
}
return -1;
@@ -2309,10 +2347,12 @@ static gint get_current_tag_name(GeanyDocument *doc, gchar **tagname, TMTagType
/* if it may be a false positive because we're inside a fold level not inside anything
* we match, e.g. a #if in C or C++, we check we're inside the fold level that start
- * right after the tag we got from TM */
+ * right after the tag we got from TM.
+ * Additionally, we perform parentheses matching on the initial line not to get confused
+ * by folding on () in case the parameter list spans multiple lines */
if (abs(tag_line - parent) > 1)
{
- gint tag_fold = get_fold_header_after(doc->editor->sci, tag_line);
+ const gint tag_fold = get_fold_header_after(doc->editor->sci, tag_line);
if (tag_fold >= 0)
last_child = scintilla_send_message(doc->editor->sci, SCI_GETLASTCHILD, tag_fold, -1);
}
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Colomban Wendling <ban(a)herbesfolles.org>
Committer: Colomban Wendling <ban(a)herbesfolles.org>
Date: Thu, 22 Dec 2016 12:52:12 UTC
Commit: 19af3caa73a916d51ab9f151bc15015026dbd598
https://github.com/geany/geany/commit/19af3caa73a916d51ab9f151bc15015026dbd…
Log Message:
-----------
Fix the current scope shown in the statusbar
Since the Scintilla C++ lexer started to fold on `()` [1], the code
looking up the current scope is confused whenever the function
signature spans multiple lines. Fix this by skipping fold levels that
correspond to parentheses.
Fixes #1279.
[1] https://sourceforge.net/p/scintilla/feature-requests/1138/
imported in 24f91981c057a7e212c09da66fb974c3ccc85bd6
Modified Paths:
--------------
src/symbols.c
Modified: src/symbols.c
48 lines changed, 44 insertions(+), 4 deletions(-)
===================================================================
@@ -45,6 +45,7 @@
#include "encodings.h"
#include "filetypesprivate.h"
#include "geanyobject.h"
+#include "highlighting.h"
#include "main.h"
#include "navqueue.h"
#include "sciwrappers.h"
@@ -2275,14 +2276,51 @@ static gchar *parse_cpp_function_at_line(ScintillaObject *sci, gint tag_line)
}
+/* gets the fold header after or on @line, but skipping folds created because of parentheses */
static gint get_fold_header_after(ScintillaObject *sci, gint line)
{
- gint line_count = sci_get_line_count(sci);
+ const gint line_count = sci_get_line_count(sci);
for (; line < line_count; line++)
{
if (sci_get_fold_level(sci, line) & SC_FOLDLEVELHEADERFLAG)
- return line;
+ {
+ const gint last_child = scintilla_send_message(sci, SCI_GETLASTCHILD, line, -1);
+ const gint line_end = sci_get_line_end_position(sci, line);
+ const gint lexer = sci_get_lexer(sci);
+ gint parenthesis_match_line = -1;
+
+ /* now find any unbalanced open parenthesis on the line and see where the matching
+ * brace would be, mimicking what folding on () does */
+ for (gint pos = sci_get_position_from_line(sci, line); pos < line_end; pos++)
+ {
+ if (highlighting_is_code_style(lexer, sci_get_style_at(sci, pos)) &&
+ sci_get_char_at(sci, pos) == '(')
+ {
+ const gint matching = sci_find_matching_brace(sci, pos);
+
+ if (matching >= 0)
+ {
+ parenthesis_match_line = sci_get_line_from_position(sci, matching);
+ if (parenthesis_match_line != line)
+ break; /* match is on a different line, we found a possible fold */
+ else
+ pos = matching; /* just skip the range and continue searching */
+ }
+ }
+ }
+
+ /* if the matching parenthesis matches the fold level, skip it and continue.
+ * it matches if it either spans the same lines, or spans one more but the next one is
+ * a fold header (in which case the last child of the fold is one less to let the
+ * header be at the parent level) */
+ if ((parenthesis_match_line == last_child) ||
+ (parenthesis_match_line == last_child + 1 &&
+ sci_get_fold_level(sci, parenthesis_match_line) & SC_FOLDLEVELHEADERFLAG))
+ line = last_child;
+ else
+ return line;
+ }
}
return -1;
@@ -2309,10 +2347,12 @@ static gint get_current_tag_name(GeanyDocument *doc, gchar **tagname, TMTagType
/* if it may be a false positive because we're inside a fold level not inside anything
* we match, e.g. a #if in C or C++, we check we're inside the fold level that start
- * right after the tag we got from TM */
+ * right after the tag we got from TM.
+ * Additionally, we perform parentheses matching on the initial line not to get confused
+ * by folding on () in case the parameter list spans multiple lines */
if (abs(tag_line - parent) > 1)
{
- gint tag_fold = get_fold_header_after(doc->editor->sci, tag_line);
+ const gint tag_fold = get_fold_header_after(doc->editor->sci, tag_line);
if (tag_fold >= 0)
last_child = scintilla_send_message(doc->editor->sci, SCI_GETLASTCHILD, tag_fold, -1);
}
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Colomban Wendling <ban(a)herbesfolles.org>
Committer: Colomban Wendling <ban(a)herbesfolles.org>
Date: Tue, 20 Dec 2016 20:47:51 UTC
Commit: a8bc8905411ff65f825a504966fcf8fbef49af86
https://github.com/geany/geany/commit/a8bc8905411ff65f825a504966fcf8fbef49a…
Log Message:
-----------
Merge branch 'scintilla/accessible-fixes'
Fix some various issues with accessibility code in Scintilla.
Modified Paths:
--------------
scintilla/gtk/ScintillaGTKAccessible.cxx
scintilla/gtk/ScintillaGTKAccessible.h
Modified: scintilla/gtk/ScintillaGTKAccessible.cxx
83 lines changed, 56 insertions(+), 27 deletions(-)
===================================================================
@@ -3,6 +3,28 @@
/* Copyright 2016 by Colomban Wendling <colomban(a)geany.org>
* The License.txt file describes the conditions under which this software may be distributed. */
+// REFERENCES BETWEEN THE DIFFERENT OBJECTS
+//
+// ScintillaGTKAccessible is the actual implementation, as a C++ class.
+// ScintillaObjectAccessible is the GObject derived from AtkObject that
+// implements the various ATK interfaces, through ScintillaGTKAccessible.
+// This follows the same pattern as ScintillaGTK and ScintillaObject.
+//
+// ScintillaGTK owns a strong reference to the ScintillaObjectAccessible, and
+// is both responsible for creating and destroying that object.
+//
+// ScintillaObjectAccessible owns a strong reference to ScintillaGTKAccessible,
+// and is responsible for creating and destroying that object.
+//
+// ScintillaGTKAccessible has weak references to both the ScintillaGTK and
+// the ScintillaObjectAccessible objects associated, but does not own any
+// strong references to those objects.
+//
+// The chain of ownership is as follows:
+// ScintillaGTK -> ScintillaObjectAccessible -> ScintillaGTKAccessible
+
+// DETAILS ON THE GOBJECT TYPE IMPLEMENTATION
+//
// On GTK < 3.2, we need to use the AtkObjectFactory. We need to query
// the factory to see what type we should derive from, thus making use of
// dynamic inheritance. It's tricky, but it works so long as it's done
@@ -134,6 +156,7 @@ ScintillaGTKAccessible *ScintillaGTKAccessible::FromAccessible(GtkAccessible *ac
ScintillaGTKAccessible::ScintillaGTKAccessible(GtkAccessible *accessible_, GtkWidget *widget_) :
accessible(accessible_),
sci(ScintillaGTK::FromWidget(widget_)),
+ deletionLengthChar(0),
old_pos(-1) {
g_signal_connect(widget_, "sci-notify", G_CALLBACK(SciNotify), this);
}
@@ -455,7 +478,7 @@ void ScintillaGTKAccessible::GetCharacterExtents(int charOffset,
} else if (nextByteOffset > byteOffset) {
/* maybe next position was on the next line or something.
* just compute the expected character width */
- int style = sci->pdoc->StyleAt(byteOffset);
+ int style = StyleAt(byteOffset, true);
int len = nextByteOffset - byteOffset;
char *ch = new char[len + 1];
sci->pdoc->GetCharRange(ch, byteOffset, len);
@@ -531,15 +554,16 @@ AtkAttributeSet *ScintillaGTKAccessible::GetRunAttributes(int charOffset, int *s
}
int length = sci->pdoc->Length();
- g_return_val_if_fail(byteOffset < length, NULL);
+ g_return_val_if_fail(byteOffset <= length, NULL);
- const char style = sci->pdoc->StyleAt(byteOffset);
+ const char style = StyleAt(byteOffset, true);
// compute the range for this style
Position startByte = byteOffset;
+ // when going backwards, we know the style is already computed
while (startByte > 0 && sci->pdoc->StyleAt((startByte) - 1) == style)
(startByte)--;
- Position endByte = byteOffset;
- while ((endByte) + 1 < length && sci->pdoc->StyleAt((endByte) + 1) == style)
+ Position endByte = byteOffset + 1;
+ while (endByte < length && StyleAt(endByte, true) == style)
(endByte)++;
CharacterRangeFromByteRange(startByte, endByte, startChar, endChar);
@@ -835,10 +859,15 @@ void ScintillaGTKAccessible::Notify(GtkWidget *, gint, SCNotification *nt) {
g_signal_emit_by_name(accessible, "text-changed::insert", startChar, lengthChar);
UpdateCursor();
}
+ if (nt->modificationType & SC_MOD_BEFOREDELETE) {
+ // We cannot compute the deletion length in DELETETEXT as it requires accessing the
+ // buffer, so that the character are still present. So, we cache the value here,
+ // and use it in DELETETEXT that fires quickly after.
+ deletionLengthChar = sci->pdoc->CountCharacters(nt->position, nt->position + nt->length);
+ }
if (nt->modificationType & SC_MOD_DELETETEXT) {
int startChar = CharacterOffsetFromByteOffset(nt->position);
- int lengthChar = sci->pdoc->CountCharacters(nt->position, nt->position + nt->length);
- g_signal_emit_by_name(accessible, "text-changed::delete", startChar, lengthChar);
+ g_signal_emit_by_name(accessible, "text-changed::delete", startChar, deletionLengthChar);
UpdateCursor();
}
if (nt->modificationType & SC_MOD_CHANGESTYLE) {
@@ -1042,10 +1071,12 @@ static AtkObject *scintilla_object_accessible_new(GType parent_type, GObject *ob
// @p cache pointer to store the AtkObject between repeated calls. Might or might not be filled.
// @p widget_parent_class pointer to the widget's parent class (to chain up method calls).
AtkObject *ScintillaGTKAccessible::WidgetGetAccessibleImpl(GtkWidget *widget, AtkObject **cache, gpointer widget_parent_class G_GNUC_UNUSED) {
-#if HAVE_GTK_A11Y_H // just instantiate the accessible
- if (*cache == NULL) {
- *cache = scintilla_object_accessible_new(0, G_OBJECT(widget));
+ if (*cache != NULL) {
+ return *cache;
}
+
+#if HAVE_GTK_A11Y_H // just instantiate the accessible
+ *cache = scintilla_object_accessible_new(0, G_OBJECT(widget));
#elif HAVE_GTK_FACTORY // register in the factory and let GTK instantiate
static volatile gsize registered = 0;
@@ -1063,24 +1094,22 @@ AtkObject *ScintillaGTKAccessible::WidgetGetAccessibleImpl(GtkWidget *widget, At
}
g_once_init_leave(®istered, 1);
}
- *cache = GTK_WIDGET_CLASS(widget_parent_class)->get_accessible(widget);
+ AtkObject *obj = GTK_WIDGET_CLASS(widget_parent_class)->get_accessible(widget);
+ *cache = static_cast<AtkObject*>(g_object_ref(obj));
#else // no public API, no factory, so guess from the parent and instantiate
- if (*cache == NULL) {
- static GType parent_atk_type = 0;
-
- if (parent_atk_type == 0) {
- AtkObject *parent_obj = GTK_WIDGET_CLASS(widget_parent_class)->get_accessible(widget);
- if (parent_obj) {
- GType parent_atk_type = G_OBJECT_TYPE(parent_obj);
-
- // Figure out whether accessibility is enabled by looking at the type of the accessible
- // object which would be created for the parent type of ScintillaObject.
- if (g_type_is_a(parent_atk_type, GTK_TYPE_ACCESSIBLE)) {
- *cache = scintilla_object_accessible_new(parent_atk_type, G_OBJECT(widget));
- g_object_unref(parent_obj);
- } else {
- *cache = parent_obj;
- }
+ static GType parent_atk_type = 0;
+
+ if (parent_atk_type == 0) {
+ AtkObject *parent_obj = GTK_WIDGET_CLASS(widget_parent_class)->get_accessible(widget);
+ if (parent_obj) {
+ GType parent_atk_type = G_OBJECT_TYPE(parent_obj);
+
+ // Figure out whether accessibility is enabled by looking at the type of the accessible
+ // object which would be created for the parent type of ScintillaObject.
+ if (g_type_is_a(parent_atk_type, GTK_TYPE_ACCESSIBLE)) {
+ *cache = scintilla_object_accessible_new(parent_atk_type, G_OBJECT(widget));
+ } else {
+ *cache = static_cast<AtkObject*>(g_object_ref(parent_obj));
}
}
}
Modified: scintilla/gtk/ScintillaGTKAccessible.h
9 lines changed, 9 insertions(+), 0 deletions(-)
===================================================================
@@ -16,9 +16,12 @@ namespace Scintilla {
class ScintillaGTKAccessible {
private:
+ // weak references to related objects
GtkAccessible *accessible;
ScintillaGTK *sci;
+ // cached length of the deletion, in characters (see Notify())
+ int deletionLengthChar;
// local state for comparing
Position old_pos;
std::vector<SelectionRange> old_sels;
@@ -70,6 +73,12 @@ class ScintillaGTKAccessible {
return sci->pdoc->MovePositionOutsideChar(pos + 1, 1, true);
}
+ int StyleAt(Position position, bool ensureStyle = false) {
+ if (ensureStyle)
+ sci->pdoc->EnsureStyledTo(position);
+ return sci->pdoc->StyleAt(position);
+ }
+
// For AtkText
gchar *GetTextRangeUTF8(Position startByte, Position endByte);
gchar *GetText(int startChar, int endChar);
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Colomban Wendling <ban(a)herbesfolles.org>
Committer: Colomban Wendling <ban(a)herbesfolles.org>
Date: Tue, 20 Dec 2016 20:45:29 UTC
Commit: 407cb36cebdc58231c08fbc7f7bb535fcdc0e465
https://github.com/geany/geany/commit/407cb36cebdc58231c08fbc7f7bb535fcdc0e…
Log Message:
-----------
GTK: Add some documentation on accessible object reference ownerships
Modified Paths:
--------------
scintilla/gtk/ScintillaGTKAccessible.cxx
scintilla/gtk/ScintillaGTKAccessible.h
Modified: scintilla/gtk/ScintillaGTKAccessible.cxx
22 lines changed, 22 insertions(+), 0 deletions(-)
===================================================================
@@ -3,6 +3,28 @@
/* Copyright 2016 by Colomban Wendling <colomban(a)geany.org>
* The License.txt file describes the conditions under which this software may be distributed. */
+// REFERENCES BETWEEN THE DIFFERENT OBJECTS
+//
+// ScintillaGTKAccessible is the actual implementation, as a C++ class.
+// ScintillaObjectAccessible is the GObject derived from AtkObject that
+// implements the various ATK interfaces, through ScintillaGTKAccessible.
+// This follows the same pattern as ScintillaGTK and ScintillaObject.
+//
+// ScintillaGTK owns a strong reference to the ScintillaObjectAccessible, and
+// is both responsible for creating and destroying that object.
+//
+// ScintillaObjectAccessible owns a strong reference to ScintillaGTKAccessible,
+// and is responsible for creating and destroying that object.
+//
+// ScintillaGTKAccessible has weak references to both the ScintillaGTK and
+// the ScintillaObjectAccessible objects associated, but does not own any
+// strong references to those objects.
+//
+// The chain of ownership is as follows:
+// ScintillaGTK -> ScintillaObjectAccessible -> ScintillaGTKAccessible
+
+// DETAILS ON THE GOBJECT TYPE IMPLEMENTATION
+//
// On GTK < 3.2, we need to use the AtkObjectFactory. We need to query
// the factory to see what type we should derive from, thus making use of
// dynamic inheritance. It's tricky, but it works so long as it's done
Modified: scintilla/gtk/ScintillaGTKAccessible.h
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -16,6 +16,7 @@ namespace Scintilla {
class ScintillaGTKAccessible {
private:
+ // weak references to related objects
GtkAccessible *accessible;
ScintillaGTK *sci;
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).