Skip to content

Commit 177931b

Browse files
V413-013: Event handling issue for floating toplevel
Don't use Gtk.Main.Grab_Get_Current in Keymanager, in case of a modal dialog it will still return a widget from the Main_Window which is in the wrong toplevel. Modify Get_Current_Focus_Widget to first check if a toplevel is active before relying on Grab_Get_Current. Add a test. Change-Id: I494ce5a59d710f5043a669c425fb958141a421e3
1 parent 86df0f9 commit 177931b

File tree

6 files changed

+61
-11
lines changed

6 files changed

+61
-11
lines changed

kernel/src/gps-kernel-mdi.adb

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1894,7 +1894,7 @@ package body GPS.Kernel.MDI is
18941894
(Kernel : access Kernel_Handle_Record'Class) return Gtk.Widget.Gtk_Widget
18951895
is
18961896
use Widget_List;
1897-
W, W2 : Gtk_Widget;
1897+
W, W2 : Gtk_Widget := null;
18981898
Toplevel : Gtk_Window;
18991899
List, List2 : Widget_List.Glist;
19001900
Tooltip_Focus_Widget : constant Gtk_Widget :=
@@ -1906,14 +1906,6 @@ package body GPS.Kernel.MDI is
19061906
return Tooltip_Focus_Widget;
19071907
end if;
19081908

1909-
-- Then check if a window currently has a grab
1910-
1911-
W := Gtk.Main.Grab_Get_Current;
1912-
if W /= null then
1913-
Toplevel := Gtk_Window (Get_Toplevel (W));
1914-
W := Get_Focus (Toplevel);
1915-
end if;
1916-
19171909
-- Then check all toplevel windows and stop at the one that has
19181910
-- the focus.
19191911

@@ -1938,6 +1930,16 @@ package body GPS.Kernel.MDI is
19381930
Free (List);
19391931
end if;
19401932

1933+
-- Then check if a window currently has a grab
1934+
1935+
if W = null then
1936+
W := Gtk.Main.Grab_Get_Current;
1937+
if W /= null then
1938+
Toplevel := Gtk_Window (Get_Toplevel (W));
1939+
W := Get_Focus (Toplevel);
1940+
end if;
1941+
end if;
1942+
19411943
-- If still no one has the focus, then no window in GNAT Studio
19421944
-- currently has it. In this case, we assume that would be the main
19431945
-- GNAT Studio window unless a floating child last had the focus.

keymanager/src/keymanager_module.adb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ with Gdk.Window; use Gdk.Window;
3131
with Glib.Convert; use Glib.Convert;
3232
with Glib; use Glib;
3333
with Gtk.Accel_Group; use Gtk.Accel_Group;
34-
with Gtk.Main; use Gtk.Main;
34+
with Gtk.Main;
3535
with Gtk.Widget; use Gtk.Widget;
3636
with Gtk.Window; use Gtk.Window;
3737
with Gtkada.MDI; use Gtkada.MDI;
@@ -522,7 +522,7 @@ package body KeyManager_Module is
522522
-- another "Continue Search?" dialog to appear.
523523

524524
declare
525-
Current : constant Gtk_Widget := Grab_Get_Current;
525+
Current : constant Gtk_Widget := Get_Current_Focus_Widget (Kernel);
526526
begin
527527
if Current = null
528528
or else (Current.Get_Realized and then
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
project Default is
2+
for Main use ("main.adb");
3+
end Default;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
procedure Main is
2+
begin
3+
null;
4+
end Main;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
When a dialog modal is opened no actions should be executed in the editor.
3+
"""
4+
import GPS
5+
from gs_utils.internal.utils import *
6+
from gs_utils.internal.dialogs import *
7+
8+
9+
@run_test_driver
10+
def test_driver():
11+
GPS.Preference("General-Use-Native-Dialogs").set(False)
12+
b = GPS.EditorBuffer.get(GPS.File("main.adb"))
13+
expected = b.get_chars()
14+
b.current_view().goto(b.at(1, 18))
15+
d = Gtk_File_Chooser_Dialog()
16+
yield d.open_and_yield("save as")
17+
# The first BACKSPACE will be sent to the "new name entry" which will
18+
# trigger the completion
19+
entry = get_widgets_by_type(Gtk.Entry, d.dialogs[0])[0]
20+
gps_assert(entry.get_text(), "main.adb", "Wrong text in entry")
21+
entry.get_toplevel().grab_focus()
22+
entry.grab_focus()
23+
send_key_event(GDK_BACKSPACE)
24+
yield timeout(200)
25+
# During the completion the focus is whacky => the second and third
26+
# BACKSPACE should do nothing
27+
send_key_event(GDK_BACKSPACE)
28+
yield timeout(200)
29+
send_key_event(GDK_BACKSPACE)
30+
yield timeout(200)
31+
gps_assert(entry.get_text(),
32+
".adb",
33+
"Backspace should have affected the entry")
34+
yield d.cancel()
35+
gps_assert(len(b.get_chars()),
36+
len(expected),
37+
"The buffer has been modified while a modal dialog was shown")
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
title: 'V413-013.dialog.focus'
2+
skip:
3+
# not compatible with xvfb
4+
- ['SKIP', 'env.build.os.name == "linux"']

0 commit comments

Comments
 (0)