static void
update_spacers(GtkWidget *nw)
{
	WindowData *windata = g_object_get_data(G_OBJECT(nw), "windata");

	if (windata->arrow.has_arrow)
	{
		switch (get_notification_arrow_type(GTK_WIDGET(nw)))
		{
			case GTK_ARROW_UP:
				gtk_widget_show(windata->top_spacer);
				gtk_widget_hide(windata->bottom_spacer);
				break;

			case GTK_ARROW_DOWN:
				gtk_widget_hide(windata->top_spacer);
				gtk_widget_show(windata->bottom_spacer);
				break;

			default:
				g_assert_not_reached();
		}
	}
	else
	{
		gtk_widget_hide(windata->top_spacer);
		gtk_widget_hide(windata->bottom_spacer);
	}
}
/* Set arrow parameters like offset and position */
static void
set_arrow_parameters (WindowData *windata)
{
	int screen_height;
	int screen_width;
	int x,y;
	GtkArrowType arrow_type;

	screen_height = gdk_screen_get_height(
		gdk_drawable_get_screen(GDK_DRAWABLE(windata->win->window)));
	screen_width = gdk_screen_get_width(
		gdk_drawable_get_screen(GDK_DRAWABLE(windata->win->window)));


	/* Set arrow offset */
	if ((windata->arrow.position.x - DEFAULT_ARROW_SKEW - 
		DEFAULT_ARROW_OFFSET + windata->win->allocation.width) > 
			screen_width)
	{
		windata->arrow.offset = windata->arrow.position.x - 
					DEFAULT_ARROW_SKEW - 
					(screen_width - 
						windata->win->allocation.width);
	}
	else if ((windata->arrow.position.x - DEFAULT_ARROW_SKEW - 
		DEFAULT_ARROW_OFFSET < 0))
	{
		windata->arrow.offset = windata->arrow.position.x - 
					DEFAULT_ARROW_SKEW;
	}
	else
	{
		windata->arrow.offset = DEFAULT_ARROW_OFFSET;
	}

	if (windata->arrow.offset < 6)
	{
		windata->arrow.offset = 6;
		windata->arrow.position.x += 6;
	}
	else if (windata->arrow.offset + DEFAULT_ARROW_WIDTH + 6 > 
			windata->win->allocation.width)
	{
		windata->arrow.offset = windata->win->allocation.width - 6 - 
					DEFAULT_ARROW_WIDTH;
		windata->arrow.position.x -= 6;
	}

	/* Set arrow points X position */
	windata->arrow.point_begin.x = windata->arrow.offset;
	windata->arrow.point_middle.x = windata->arrow.offset + 
					DEFAULT_ARROW_SKEW;
	windata->arrow.point_end.x = windata->arrow.offset +
					DEFAULT_ARROW_WIDTH;
	x = windata->arrow.position.x - DEFAULT_ARROW_SKEW - windata->arrow.offset;

	/* Set arrow points Y position */
	arrow_type = get_notification_arrow_type(windata->win);
	
	switch (arrow_type)
	{
		case GTK_ARROW_UP:
			windata->arrow.point_begin.y = DEFAULT_ARROW_HEIGHT;
			windata->arrow.point_middle.y = 0;
			windata->arrow.point_end.y = DEFAULT_ARROW_HEIGHT;
			y = windata->arrow.position.y;
			break;
		case GTK_ARROW_DOWN:
			windata->arrow.point_begin.y = 
				windata->win->allocation.height - 
					DEFAULT_ARROW_HEIGHT;
			windata->arrow.point_middle.y = 
				windata->win->allocation.height;
			windata->arrow.point_end.y = 
				windata->win->allocation.height - 
					DEFAULT_ARROW_HEIGHT;
			y = windata->arrow.position.y - windata->win->allocation.height;
			break;
		default:
			g_assert_not_reached();
	}

	/* Move window to requested position */
	gtk_window_move(GTK_WINDOW(windata->win), x, y);
}
Exemplo n.º 3
0
static void create_border_with_arrow(GtkWidget* nw, WindowData* windata)
{
	int             width;
	int             height;
	int             y;
	int             norm_point_x;
	int             norm_point_y;
	GtkArrowType    arrow_type;
	GdkScreen*      screen;
	int             arrow_side1_width = DEFAULT_ARROW_WIDTH / 2;
	int             arrow_side2_width = DEFAULT_ARROW_WIDTH / 2;
	int             arrow_offset = DEFAULT_ARROW_OFFSET;
	GdkPoint*       shape_points = NULL;
	int             i = 0;
	int             monitor;
	GdkRectangle    monitor_geometry;

	width = windata->width;
	height = windata->height;

	screen = gdk_window_get_screen(GDK_WINDOW(gtk_widget_get_window(nw)));
	monitor = gdk_screen_get_monitor_at_point(screen, windata->point_x, windata->point_y);
	gdk_screen_get_monitor_geometry(screen, monitor, &monitor_geometry);

	windata->num_border_points = 5;

	arrow_type = get_notification_arrow_type(windata->win);

	norm_point_x = windata->point_x - monitor_geometry.x;
	norm_point_y = windata->point_y - monitor_geometry.y;

	/* Handle the offset and such */
	switch (arrow_type)
	{
		case GTK_ARROW_UP:
		case GTK_ARROW_DOWN:

			if (norm_point_x < arrow_side1_width)
			{
				arrow_side1_width = 0;
				arrow_offset = 0;
			}
			else if (norm_point_x > monitor_geometry.width - arrow_side2_width)
			{
				arrow_side2_width = 0;
				arrow_offset = width - arrow_side1_width;
			}
			else
			{
				if (norm_point_x - arrow_side2_width + width >= monitor_geometry.width)
				{
					arrow_offset = width - monitor_geometry.width + norm_point_x;
				}
				else
				{
					arrow_offset = MIN(norm_point_x - arrow_side1_width, DEFAULT_ARROW_OFFSET);
				}

				if (arrow_offset == 0 || arrow_offset == width - arrow_side1_width)
				{
					windata->num_border_points++;
				}
				else
				{
					windata->num_border_points += 2;
				}
			}

			/*
			 * Why risk this for official builds? If it's somehow off the
			 * screen, it won't horribly impact the user. Definitely less
			 * than an assertion would...
			 */
			#if 0
				g_assert(arrow_offset + arrow_side1_width >= 0);
				g_assert(arrow_offset + arrow_side1_width + arrow_side2_width <= width);
			#endif

			windata->border_points = g_new0(GdkPoint, windata->num_border_points);
			shape_points = g_new0(GdkPoint, windata->num_border_points);

			windata->drawn_arrow_begin_x = arrow_offset;
			windata->drawn_arrow_middle_x = arrow_offset + arrow_side1_width;
			windata->drawn_arrow_end_x = arrow_offset + arrow_side1_width + arrow_side2_width;

			if (arrow_type == GTK_ARROW_UP)
			{
				windata->drawn_arrow_begin_y = DEFAULT_ARROW_HEIGHT;
				windata->drawn_arrow_middle_y = 0;
				windata->drawn_arrow_end_y = DEFAULT_ARROW_HEIGHT;

				if (arrow_side1_width == 0)
				{
					ADD_POINT(0, 0, 0, 0);
				}
				else
				{
					ADD_POINT(0, DEFAULT_ARROW_HEIGHT, 0, 0);

					if (arrow_offset > 0)
					{
						ADD_POINT(arrow_offset - (arrow_side2_width > 0 ? 0 : 1), DEFAULT_ARROW_HEIGHT, 0, 0);
					}

					ADD_POINT(arrow_offset + arrow_side1_width - (arrow_side2_width > 0 ? 0 : 1), 0, 0, 0);
				}

				if (arrow_side2_width > 0)
				{
					ADD_POINT(windata->drawn_arrow_end_x, windata->drawn_arrow_end_y, 1, 0);
					ADD_POINT(width - 1, DEFAULT_ARROW_HEIGHT, 1, 0);
				}

				ADD_POINT(width - 1, height - 1, 1, 1);
				ADD_POINT(0, height - 1, 0, 1);

				y = windata->point_y;
			}
			else
			{
				windata->drawn_arrow_begin_y = height - DEFAULT_ARROW_HEIGHT;
				windata->drawn_arrow_middle_y = height;
				windata->drawn_arrow_end_y = height - DEFAULT_ARROW_HEIGHT;

				ADD_POINT(0, 0, 0, 0);
				ADD_POINT(width - 1, 0, 1, 0);

				if (arrow_side2_width == 0)
				{
					ADD_POINT(width - 1, height, (arrow_side1_width > 0 ? 0 : 1), 0);
				}
				else
				{
					ADD_POINT(width - 1, height - DEFAULT_ARROW_HEIGHT, 1, 1);

					if (arrow_offset < width - arrow_side1_width)
					{
						ADD_POINT(arrow_offset + arrow_side1_width + arrow_side2_width, height - DEFAULT_ARROW_HEIGHT, 0, 1);
					}

					ADD_POINT(arrow_offset + arrow_side1_width, height, 0, 1);
				}

				if (arrow_side1_width > 0)
				{
					ADD_POINT(windata->drawn_arrow_begin_x - (arrow_side2_width > 0 ? 0 : 1), windata->drawn_arrow_begin_y, 0, 0);
					ADD_POINT(0, height - DEFAULT_ARROW_HEIGHT, 0, 1);
				}

				y = windata->point_y - height;
			}

			#if 0
				g_assert(i == windata->num_border_points);
				g_assert(windata->point_x - arrow_offset - arrow_side1_width >= 0);
			#endif

			gtk_window_move(GTK_WINDOW(windata->win), windata->point_x - arrow_offset - arrow_side1_width, y);

			break;

		case GTK_ARROW_LEFT:
		case GTK_ARROW_RIGHT:

			if (norm_point_y < arrow_side1_width)
			{
				arrow_side1_width = 0;
				arrow_offset = norm_point_y;
			}
			else if (norm_point_y > monitor_geometry.height - arrow_side2_width)
			{
				arrow_side2_width = 0;
				arrow_offset = norm_point_y - arrow_side1_width;
			}
			break;

		default:
			g_assert_not_reached();
	}

	g_assert(shape_points != NULL);

#if GTK_CHECK_VERSION(3, 0, 0)
	/* FIXME!!! */
#else
	windata->window_region = gdk_region_polygon(shape_points, windata->num_border_points, GDK_EVEN_ODD_RULE);
#endif
	g_free(shape_points);
}