nativeshell/shell/platform/linux/
size_widget.rs1use std::{cmp::max, ffi::CString, mem, ptr};
2
3use glib::{
4 translate::{FromGlibPtrFull, FromGlibPtrNone},
5 ObjectExt,
6};
7use gtk::{prelude::WidgetExt, Widget};
8
9unsafe extern "C" fn class_init(class: glib_sys::gpointer, _class_data: glib_sys::gpointer) {
10 let widget_class = class as *mut gtk_sys::GtkWidgetClass;
11 let widget_class = &mut *widget_class;
12 widget_class.get_preferred_width = Some(get_preferred_width);
13 widget_class.get_preferred_height = Some(get_preferred_height);
14}
15
16unsafe extern "C" fn instance_init(
17 _instance: *mut gobject_sys::GTypeInstance,
18 _instance_data: glib_sys::gpointer,
19) {
20}
21
22fn size_widget_get_type() -> glib_sys::GType {
23 static ONCE: ::std::sync::Once = ::std::sync::Once::new();
24
25 static mut TYPE: glib_sys::GType = 0;
26
27 ONCE.call_once(|| unsafe {
28 let name = CString::new("NativeShellSizeWidget").unwrap();
29 TYPE = gobject_sys::g_type_register_static_simple(
30 gtk_sys::gtk_bin_get_type(),
31 name.as_ptr(),
32 mem::size_of::<gtk_sys::GtkBinClass>() as u32,
33 Some(class_init),
34 mem::size_of::<gtk_sys::GtkBin>() as u32,
35 Some(instance_init),
36 0,
37 );
38 });
39
40 unsafe { TYPE }
41}
42
43unsafe extern "C" fn get_preferred_width(
44 widget: *mut gtk_sys::GtkWidget,
45 minimum: *mut i32,
46 natural: *mut i32,
47) {
48 let widget = Widget::from_glib_none(widget);
49 let width: Option<ptr::NonNull<i32>> = widget.data("nativeshell_minimum_width");
50 if let Some(width) = width.map(|w| *w.as_ref()) {
51 *minimum = max(width, 1);
52 *natural = max(width, 1);
53 } else {
54 *minimum = 1;
55 *natural = 1;
56 }
57}
58
59unsafe extern "C" fn get_preferred_height(
60 widget: *mut gtk_sys::GtkWidget,
61 minimum: *mut i32,
62 natural: *mut i32,
63) {
64 let widget = Widget::from_glib_none(widget);
65 let height: Option<ptr::NonNull<i32>> = widget.data("nativeshell_minimum_height");
66 if let Some(height) = height.map(|h| *h.as_ref()) {
67 *minimum = max(height, 1);
68 *natural = max(height, 1);
69 } else {
70 *minimum = 1;
71 *natural = 1;
72 }
73}
74
75pub(super) fn create_size_widget() -> gtk::Widget {
76 unsafe {
77 let instance = gobject_sys::g_object_new(size_widget_get_type(), std::ptr::null_mut());
78 gobject_sys::g_object_ref_sink(instance);
79 gtk::Widget::from_glib_full(instance as *mut _)
80 }
81}
82
83pub(super) fn size_widget_set_min_size(widget: >k::Widget, width: i32, height: i32) {
84 unsafe {
85 widget.set_data("nativeshell_minimum_width", width);
86 widget.set_data("nativeshell_minimum_height", height);
87 }
88 widget.queue_resize();
89}