|
9 | 9 | * (at your option) any later version. |
10 | 10 | */ |
11 | 11 |
|
| 12 | +using GtkLayerShell; |
| 13 | + |
12 | 14 | namespace Budgie { |
13 | 15 | /** |
14 | 16 | * We need to probe the dbus daemon directly, hence this interface |
@@ -109,15 +111,101 @@ namespace Budgie { |
109 | 111 | this.load_buttons(); |
110 | 112 |
|
111 | 113 | /* Set size properties */ |
| 114 | + var display = Gdk.Display.get_default(); |
| 115 | + var screen = Gdk.Screen.get_default(); |
112 | 116 | int x, y; |
113 | | - get_position(out x, out y); |
114 | | - var monitor = get_screen().get_display().get_monitor_at_point(x, y); |
115 | | - var rect = monitor.get_workarea(); |
| 117 | + bool have_pos = false; |
| 118 | + // using the display seat should be reliable to find the point position |
| 119 | + var seat = display.get_default_seat(); |
| 120 | + if (seat != null) { |
| 121 | + var pointer = seat.get_pointer(); |
| 122 | + if (pointer != null) { |
| 123 | + pointer.get_position( out screen, out x, out y); |
| 124 | + have_pos = true; |
| 125 | + } |
| 126 | + } |
| 127 | + |
| 128 | + Gdk.Rectangle? rect = null; |
| 129 | + |
| 130 | + if (!have_pos) { |
| 131 | + // if for some reason we can't determine the pointer position |
| 132 | + // then assume we are placing on the primary monitor |
| 133 | + var primary = display.get_primary_monitor(); |
| 134 | + if (primary != null) { |
| 135 | + rect = primary.get_workarea(); |
| 136 | + x = rect.x + rect.width / 2; |
| 137 | + y = rect.y + rect.height / 2; |
| 138 | + } |
| 139 | + } |
| 140 | + |
| 141 | + Gdk.Monitor? monitor_obj = null; |
| 142 | + int monitor_index = 0; |
| 143 | + |
| 144 | + // get the monitor for the pointer location |
| 145 | + if (display.get_monitor_at_point != null) { |
| 146 | + monitor_obj = display.get_monitor_at_point(x, y); |
| 147 | + } |
| 148 | + |
| 149 | + if (monitor_obj == null) { |
| 150 | + // we still don't know the monitor ... so try to get the primary |
| 151 | + monitor_obj = display.get_primary_monitor(); |
| 152 | + } |
| 153 | + |
| 154 | + // ultimate fallback - just use monitor index of zero to find the monitor |
| 155 | + if (monitor_obj == null) { |
| 156 | + if (display.get_monitor != null) { |
| 157 | + monitor_obj = display.get_monitor(0); |
| 158 | + } |
| 159 | + } |
| 160 | + |
| 161 | + // if we have a handle on the current monitor try to get its dimensions |
| 162 | + if (monitor_obj != null) { |
| 163 | + rect = monitor_obj.get_workarea(); |
| 164 | + } else { |
| 165 | + // ultimate fallback - use deprecated methods to get screen width and height |
| 166 | + rect = Gdk.Rectangle(); |
| 167 | + rect.x = 0; |
| 168 | + rect.y = 0; |
| 169 | + rect.width = screen.get_width(); |
| 170 | + rect.height = screen.get_height(); |
| 171 | + } |
| 172 | + |
116 | 173 | var width = (rect.width / 3).clamp(420, 840); |
117 | 174 |
|
118 | 175 | set_size_request(width, -1); |
119 | 176 | set_default_size(width, -1); |
120 | 177 |
|
| 178 | + GtkLayerShell.init_for_window(this); |
| 179 | + GtkLayerShell.set_layer(this, GtkLayerShell.Layer.TOP); |
| 180 | + |
| 181 | + if (monitor_obj != null) { |
| 182 | + GtkLayerShell.set_monitor(this, monitor_obj); |
| 183 | + } else { |
| 184 | + return; |
| 185 | + } |
| 186 | + |
| 187 | + GtkLayerShell.set_anchor(this, GtkLayerShell.Edge.LEFT, true); |
| 188 | + GtkLayerShell.set_anchor(this, GtkLayerShell.Edge.TOP, true); |
| 189 | + // ensure opposite anchors are false so it doesn't stretch |
| 190 | + GtkLayerShell.set_anchor(this, GtkLayerShell.Edge.RIGHT, false); |
| 191 | + GtkLayerShell.set_anchor(this, GtkLayerShell.Edge.BOTTOM, false); |
| 192 | + GtkLayerShell.set_keyboard_mode(this, GtkLayerShell.KeyboardMode.ON_DEMAND); |
| 193 | + |
| 194 | + // calculate where to place the window in the monitor horizontally |
| 195 | + int margin_left = rect.x; |
| 196 | + margin_left += (rect.width - width) / 2; |
| 197 | + GtkLayerShell.set_margin(this, GtkLayerShell.Edge.LEFT, margin_left - rect.x); |
| 198 | + |
| 199 | + // we don't know the run dialog height until its displayed |
| 200 | + // so wait and then set the vertical position |
| 201 | + this.size_allocate.connect((allocation) => { |
| 202 | + int real_h = allocation.height; |
| 203 | + if (real_h <= 0) return; |
| 204 | + |
| 205 | + int y_pos = rect.y + (rect.height - real_h) / 2; |
| 206 | + GtkLayerShell.set_margin(this, GtkLayerShell.Edge.TOP, y_pos - rect.y); |
| 207 | + }); |
| 208 | + |
121 | 209 | /* Connect events */ |
122 | 210 | focus_out_event.connect(() => { |
123 | 211 | if (!this.focus_quit) { |
|
0 commit comments