Skip to content

Commit d5bf60b

Browse files
committed
moved signals to Gtk/Widgets/Window
1 parent 7d0a030 commit d5bf60b

File tree

2 files changed

+95
-45
lines changed

2 files changed

+95
-45
lines changed

Sources/Gtk/Widgets/Window.swift

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,75 @@ open class Window: Widget {
8282

8383
public func present() {
8484
gtk_window_present(castedPointer())
85+
86+
addSignal(name: "close-request") { [weak self] () in
87+
guard let self = self else { return }
88+
self.onCloseRequest?(self)
89+
}
90+
}
91+
92+
public func setEscapeKeyPressedHandler(to handler: (() -> Void)?) {
93+
if let data = escapeKeyHandlerData {
94+
Unmanaged<ValueBox<() -> Void>>.fromOpaque(data).release()
95+
escapeKeyHandlerData = nil
96+
}
97+
98+
if let oldController = escapeKeyEventController {
99+
gtk_widget_remove_controller(widgetPointer, oldController)
100+
escapeKeyEventController = nil
101+
}
102+
103+
escapeKeyPressed = handler
104+
105+
guard handler != nil else { return }
106+
107+
let keyEventController = gtk_event_controller_key_new()
108+
gtk_event_controller_set_propagation_phase(keyEventController, GTK_PHASE_BUBBLE)
109+
110+
let thunk: @convention(c) (
111+
UnsafeMutableRawPointer?, guint, guint, GdkModifierType, gpointer?
112+
) -> gboolean = { _, keyval, _, _, userData in
113+
if keyval == GDK_KEY_Escape {
114+
guard let userData else { return 1 }
115+
let box = Unmanaged<ValueBox<() -> Void>>.fromOpaque(userData).takeUnretainedValue()
116+
box.value()
117+
return 1
118+
}
119+
return 0
120+
}
121+
122+
let boxedHandler = Unmanaged.passRetained(
123+
ValueBox(value: handler!)
124+
).toOpaque()
125+
126+
g_signal_connect_data(
127+
UnsafeMutableRawPointer(keyEventController),
128+
"key-pressed",
129+
unsafeBitCast(thunk, to: GCallback.self),
130+
boxedHandler,
131+
{ data, _ in
132+
if let data {
133+
Unmanaged<ValueBox<() -> Void>>.fromOpaque(data).release()
134+
}
135+
},
136+
.init(0)
137+
)
138+
139+
gtk_widget_add_controller(widgetPointer, keyEventController)
140+
escapeKeyEventController = keyEventController
141+
escapeKeyHandlerData = boxedHandler
142+
}
143+
144+
private var escapeKeyEventController: OpaquePointer?
145+
private var escapeKeyHandlerData: UnsafeMutableRawPointer?
146+
147+
public var onCloseRequest: ((Window) -> Int32)?
148+
public var escapeKeyPressed: (() -> Void)?
149+
}
150+
151+
final class ValueBox<T> {
152+
let value: T
153+
init(value: T) {
154+
self.value = value
85155
}
86156
}

Sources/GtkBackend/GtkBackend.swift

Lines changed: 25 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -64,31 +64,7 @@ public final class GtkBackend: AppBackend {
6464
private var sheetContexts: [OpaquePointer: SheetContext] = [:]
6565
private var connectedCloseHandlers: Set<OpaquePointer> = []
6666

67-
// C thunk for GtkWindow::close-request
68-
private static let closeRequestThunk:
69-
@convention(c) (
70-
UnsafeMutableRawPointer?, UnsafeMutableRawPointer?
71-
) -> Int32 = { instance, userData in
72-
// TRUE (1) = consume event (prevent native close)
73-
guard let instance, let userData else { return 1 }
74-
let backend = Unmanaged<GtkBackend>.fromOpaque(userData).takeUnretainedValue()
75-
let key = OpaquePointer(instance)
76-
guard let ctx = backend.sheetContexts[key] else { return 1 }
77-
78-
if ctx.interactiveDismissDisabled { return 1 }
79-
80-
if ctx.isProgrammaticDismiss {
81-
ctx.isProgrammaticDismiss = false
82-
return 1
83-
}
84-
85-
backend.runInMainThread {
86-
ctx.onDismiss()
87-
}
88-
return 1
89-
}
90-
91-
// C-convention thunk for key-pressed
67+
/* // C-convention thunk for key-pressed
9268
private let escapeKeyPressedThunk:
9369
@convention(c) (
9470
UnsafeMutableRawPointer?, guint, guint, GdkModifierType, gpointer?
@@ -102,7 +78,7 @@ public final class GtkBackend: AppBackend {
10278
}
10379
return 0
10480
}
105-
81+
*/
10682
// A separate initializer to satisfy ``AppBackend``'s requirements.
10783
public convenience init() {
10884
self.init(appIdentifier: nil)
@@ -1643,17 +1619,21 @@ public final class GtkBackend: AppBackend {
16431619
sheet.css.set(property: .cornerRadius(defaultSheetCornerRadius))
16441620

16451621
if connectedCloseHandlers.insert(key).inserted {
1646-
let handler: GCallback = unsafeBitCast(Self.closeRequestThunk, to: GCallback.self)
1647-
g_signal_connect_data(
1648-
UnsafeMutableRawPointer(sheet.gobjectPointer),
1649-
"close-request",
1650-
handler,
1651-
Unmanaged.passUnretained(self).toOpaque(),
1652-
nil,
1653-
GConnectFlags(0)
1654-
)
1622+
sheet.onCloseRequest = {[weak self] _ in
1623+
if ctx.interactiveDismissDisabled { return 1 }
1624+
1625+
if ctx.isProgrammaticDismiss {
1626+
ctx.isProgrammaticDismiss = false
1627+
return 1
1628+
}
1629+
1630+
self?.runInMainThread {
1631+
ctx.onDismiss()
1632+
}
1633+
return 1
1634+
}
16551635

1656-
let escapeHandler = gtk_event_controller_key_new()
1636+
/* let escapeHandler = gtk_event_controller_key_new()
16571637
gtk_event_controller_set_propagation_phase(escapeHandler, GTK_PHASE_BUBBLE)
16581638
g_signal_connect_data(
16591639
UnsafeMutableRawPointer(escapeHandler),
@@ -1673,8 +1653,15 @@ public final class GtkBackend: AppBackend {
16731653
}
16741654
},
16751655
.init(0)
1676-
)
1677-
gtk_widget_add_controller(sheet.widgetPointer, escapeHandler)
1656+
)*/
1657+
sheet.setEscapeKeyPressedHandler {
1658+
print("escapeKeyPressed")
1659+
if ctx.interactiveDismissDisabled { return }
1660+
self.runInMainThread {
1661+
ctx.onDismiss()
1662+
}
1663+
}
1664+
16781665
}
16791666
}
16801667

@@ -1736,10 +1723,3 @@ extension UnsafeMutablePointer {
17361723
class CustomListBox: ListBox {
17371724
var cachedSelection: Int? = nil
17381725
}
1739-
1740-
final class ValueBox<T> {
1741-
let value: T
1742-
init(value: T) {
1743-
self.value = value
1744-
}
1745-
}

0 commit comments

Comments
 (0)