| 1187 GtkRequisition requisition; |
1187 GtkRequisition requisition; |
| 1188 GdkScreen *screen; |
1188 GdkScreen *screen; |
| 1189 GdkRectangle monitor; |
1189 GdkRectangle monitor; |
| 1190 gint monitor_num; |
1190 gint monitor_num; |
| 1191 gint space_left, space_right, space_above, space_below; |
1191 gint space_left, space_right, space_above, space_below; |
| 1192 gint needed_width; |
|
| 1193 gint needed_height; |
|
| 1194 gint xthickness; |
|
| 1195 gint ythickness; |
|
| 1196 gboolean rtl; |
1192 gboolean rtl; |
| 1197 |
1193 |
| 1198 g_return_if_fail(GTK_IS_MENU(menu)); |
1194 g_return_if_fail(GTK_IS_MENU(menu)); |
| 1199 |
1195 |
| 1200 widget = GTK_WIDGET(menu); |
1196 widget = GTK_WIDGET(menu); |
| 1201 screen = gtk_widget_get_screen(widget); |
1197 screen = gtk_widget_get_screen(widget); |
| 1202 context = gtk_widget_get_style_context(widget); |
|
| 1203 gtk_style_context_get(context, gtk_style_context_get_state(context), |
|
| 1204 "xthickness", &xthickness, |
|
| 1205 "ythickness", &ythickness, NULL); |
|
| 1206 rtl = (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL); |
1198 rtl = (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL); |
| 1207 |
1199 |
| 1208 /* |
1200 /* |
| 1209 * We need the requisition to figure out the right place to |
1201 * We need the requisition to figure out the right place to |
| 1210 * popup the menu. In fact, we always need to ask here, since |
1202 * popup the menu. In fact, we always need to ask here, since |
| 1243 space_above = *y - monitor.y; |
1235 space_above = *y - monitor.y; |
| 1244 space_below = monitor.y + monitor.height - *y - 1; |
1236 space_below = monitor.y + monitor.height - *y - 1; |
| 1245 |
1237 |
| 1246 /* position horizontally */ |
1238 /* position horizontally */ |
| 1247 |
1239 |
| 1248 /* the amount of space we need to position the menu. Note the |
1240 if (requisition.width <= space_left || |
| 1249 * menu is offset "xthickness" pixels |
1241 requisition.width <= space_right) |
| 1250 */ |
|
| 1251 needed_width = requisition.width - xthickness; |
|
| 1252 |
|
| 1253 if (needed_width <= space_left || |
|
| 1254 needed_width <= space_right) |
|
| 1255 { |
1242 { |
| 1256 if ((rtl && needed_width <= space_left) || |
1243 if ((rtl && requisition.width <= space_left) || |
| 1257 (!rtl && needed_width > space_right)) |
1244 (!rtl && requisition.width > space_right)) |
| 1258 { |
1245 { |
| 1259 /* position left */ |
1246 /* position left */ |
| 1260 *x = *x + xthickness - requisition.width + 1; |
1247 *x = *x - requisition.width + 1; |
| 1261 } |
|
| 1262 else |
|
| 1263 { |
|
| 1264 /* position right */ |
|
| 1265 *x = *x - xthickness; |
|
| 1266 } |
1248 } |
| 1267 |
1249 |
| 1268 /* x is clamped on-screen further down */ |
1250 /* x is clamped on-screen further down */ |
| 1269 } |
1251 } |
| 1270 else if (requisition.width <= monitor.width) |
1252 else if (requisition.width <= monitor.width) |
| 1299 } |
1281 } |
| 1300 |
1282 |
| 1301 /* Position vertically. The algorithm is the same as above, but |
1283 /* Position vertically. The algorithm is the same as above, but |
| 1302 * simpler because we don't have to take RTL into account. |
1284 * simpler because we don't have to take RTL into account. |
| 1303 */ |
1285 */ |
| 1304 needed_height = requisition.height - ythickness; |
1286 |
| 1305 |
1287 if (requisition.height <= space_above || |
| 1306 if (needed_height <= space_above || |
1288 requisition.height <= space_below) |
| 1307 needed_height <= space_below) |
|
| 1308 { |
1289 { |
| 1309 if (needed_height <= space_below) |
1290 if (requisition.height > space_below) { |
| 1310 *y = *y - ythickness; |
1291 *y = *y - requisition.height + 1; |
| 1311 else |
1292 } |
| 1312 *y = *y + ythickness - requisition.height + 1; |
|
| 1313 |
1293 |
| 1314 *y = CLAMP (*y, monitor.y, |
1294 *y = CLAMP (*y, monitor.y, |
| 1315 monitor.y + monitor.height - requisition.height); |
1295 monitor.y + monitor.height - requisition.height); |
| 1316 } |
1296 } |
| 1317 else if (needed_height > space_below && needed_height > space_above) |
1297 else if (requisition.height > space_below && |
| |
1298 requisition.height > space_above) |
| 1318 { |
1299 { |
| 1319 if (space_below >= space_above) |
1300 if (space_below >= space_above) |
| 1320 *y = monitor.y + monitor.height - requisition.height; |
1301 *y = monitor.y + monitor.height - requisition.height; |
| 1321 else |
1302 else |
| 1322 *y = monitor.y; |
1303 *y = monitor.y; |
| 1338 GtkWidget *widget = GTK_WIDGET(data); |
1319 GtkWidget *widget = GTK_WIDGET(data); |
| 1339 GtkTreeView *tv = GTK_TREE_VIEW(data); |
1320 GtkTreeView *tv = GTK_TREE_VIEW(data); |
| 1340 GtkTreePath *path; |
1321 GtkTreePath *path; |
| 1341 GtkTreeViewColumn *col; |
1322 GtkTreeViewColumn *col; |
| 1342 GdkRectangle rect; |
1323 GdkRectangle rect; |
| 1343 GtkStyleContext *context; |
1324 |
| 1344 gint ythickness; |
|
| 1345 |
|
| 1346 context = gtk_widget_get_style_context(GTK_WIDGET(menu)); |
|
| 1347 gtk_style_context_get(context, gtk_style_context_get_state(context), |
|
| 1348 "ythickness", &ythickness, NULL); |
|
| 1349 gdk_window_get_origin (gtk_widget_get_window(widget), x, y); |
1325 gdk_window_get_origin (gtk_widget_get_window(widget), x, y); |
| 1350 gtk_tree_view_get_cursor (tv, &path, &col); |
1326 gtk_tree_view_get_cursor (tv, &path, &col); |
| 1351 gtk_tree_view_get_cell_area (tv, path, col, &rect); |
1327 gtk_tree_view_get_cell_area (tv, path, col, &rect); |
| 1352 |
1328 |
| 1353 *x += rect.x+rect.width; |
1329 *x += rect.x+rect.width; |
| 1354 *y += rect.y+rect.height+ythickness; |
1330 *y += rect.y + rect.height; |
| 1355 pidgin_menu_position_func_helper(menu, x, y, push_in, data); |
1331 pidgin_menu_position_func_helper(menu, x, y, push_in, data); |
| 1356 } |
1332 } |
| 1357 |
1333 |
| 1358 static void dnd_image_ok_callback(_DndData *data, int choice) |
1334 static void dnd_image_ok_callback(_DndData *data, int choice) |
| 1359 { |
1335 { |