Exemple #1
0
/* Perform several periodic tasks */
void perform_periodic_tasks(int mask)
{
	struct TrayIcon *ti;
	/* 1. Remove all invalid icons */
	while ((ti = icon_list_forall(&find_invalid_icons)) != NULL) {
		LOG_TRACE(("icon 0x%x is invalid; removing\n", ti->wid));
		remove_icon(ti->wid);
	}
	/* 2. Print tray status if asked to */
	if (tray_status_requested) dump_tray_status();
	/* 3. KLUDGE to fix window size on (buggy?) WMs */
	if (settings.kludge_flags & KLUDGE_FIX_WND_SIZE) {
		/* KLUDGE TODO: resolve */
		XWindowAttributes xwa;
		XGetWindowAttributes(tray_data.dpy, tray_data.tray, &xwa);
		if (!tray_data.is_reparented && 
				(xwa.width != tray_data.xsh.width || xwa.height != tray_data.xsh.height)) 
		{
			LOG_TRACE(("KLUDGE: fixing tray window size (current: %dx%d, required: %dx%d)\n",
						xwa.width, xwa.height,
						tray_data.xsh.width, tray_data.xsh.height));
			tray_update_window_props();
		} 
	}
	/* 4. run scrollbars periodic tasks */
	if (mask & PT_MASK_SB) scrollbars_periodic_tasks();
}
Exemple #2
0
void systray_destroy_event(TrayWindow *traywin)
{
	if (systray_profile)
		fprintf(stderr,
		        "[%f] %s:%d win = %lu (%s)\n",
		        profiling_get_time(),
		        __FUNCTION__,
		        __LINE__,
		        traywin->win,
		        traywin->name);
	remove_icon(traywin);
}
Exemple #3
0
static inline DISPLAY_INFO*
reset_display_info(DISPLAY_INFO* const di, NOTIFICATION_INFO* const ni) {
  di->timeout = 500;
  di->pos     = 0;
  di->offset  = 0;
  di->hover   = FALSE;
  free_notification_info(di->ni);
  di->ni = ni;
  gtk_widget_hide_all(di->widget.popup);
  gtk_window_set_opacity(GTK_WINDOW(di->widget.popup), 0.8);
  remove_icon(di);
  return di;
}
Exemple #4
0
void destroy_notify(XDestroyWindowEvent ev)
{
	if (!tray_data.is_active && ev.window == tray_data.old_selection_owner) {
		/* Old tray selection owner was destroyed. Take over selection ownership. */
		tray_acquire_selection();
	} else if (ev.window != tray_data.tray) {
		/* Try to remove icon from the tray */
		remove_icon(ev.window);
#ifndef NO_NATIVE_KDE
	} else if (kde_tray_is_old_icon(ev.window)) {
		/* Since X Server may reuse window ids, remove ev.window
		 * from the list of old KDE icons */
		kde_tray_old_icons_remove(ev.window);
#endif
	}
}
Exemple #5
0
void reparent_notify(XReparentEvent ev)
{
	struct TrayIcon *ti;
	ti = icon_list_find(ev.window);
	if (ti == NULL) return;
	/* Reparenting out of the tray is one of non-destructive
	 * ways to end XEMBED protocol (see spec) */
	if (ti->is_embedded && ti->mid_parent != ev.parent) {
		LOG_TRACE(("will now unembed 0x%x\n", ti->wid));
#ifdef DEBUG
		print_icon_data(ti);
		x11_dump_win_info(tray_data.dpy, ev.parent);
#endif
		remove_icon(ev.window);
	}
}
Exemple #6
0
void stop_net()
{
	if (systray_profile)
		fprintf(stderr, "[%f] %s:%d\n", profiling_get_time(), __FUNCTION__, __LINE__);
	if (systray.list_icons) {
		// remove_icon change systray.list_icons
		while (systray.list_icons)
			remove_icon((TrayWindow *)systray.list_icons->data);

		g_slist_free(systray.list_icons);
		systray.list_icons = NULL;
	}

	if (net_sel_win != None) {
		XDestroyWindow(server.display, net_sel_win);
		net_sel_win = None;
	}
}
Exemple #7
0
gboolean embed_icon(TrayWindow *traywin)
{
	if (systray_profile)
		fprintf(stderr,
		        "[%f] %s:%d win = %lu (%s)\n",
		        profiling_get_time(),
		        __FUNCTION__,
		        __LINE__,
		        traywin->win,
		        traywin->name);
	if (traywin->embedded)
		return TRUE;

	Panel *panel = systray.area.panel;

	XSync(server.display, False);
	error = FALSE;
	XErrorHandler old = XSetErrorHandler(window_error_handler);

	if (0) {
		Atom acttype;
		int actfmt;
		unsigned long nbitem, bytes;
		unsigned long *data = 0;
		int ret;

		if (systray_profile)
			fprintf(stderr,
					"XGetWindowProperty(server.display, traywin->win, server.atom._XEMBED_INFO, 0, 2, False, "
			        "server.atom._XEMBED_INFO, &acttype, &actfmt, &nbitem, &bytes, &data)\n");
		ret = XGetWindowProperty(server.display,
		                         traywin->win,
		                         server.atom._XEMBED_INFO,
		                         0,
		                         2,
		                         False,
		                         server.atom._XEMBED_INFO,
		                         &acttype,
		                         &actfmt,
		                         &nbitem,
		                         &bytes,
		                         (unsigned char **)&data);
		if (ret == Success) {
			if (data) {
				if (nbitem >= 2) {
					int hide = ((data[1] & XEMBED_MAPPED) == 0);
					if (hide) {
						// In theory we have to check the embedding with this and remove icons that refuse embedding.
						// In practice we have no idea when the other application processes the event and accepts the
						// embed so we cannot check now without a race.
						// Race can be triggered with PyGtk(2) apps.
						// We could defer this for later (if we set PropertyChangeMask in XSelectInput we get notified)
						// but for some reason it breaks transparency for Qt icons. So we don't.
						// fprintf(stderr, RED "tint2: window refused embedding" RESET "\n");
						// remove_icon(traywin);
						// XFree(data);
						// return FALSE;
					}
				}
				XFree(data);
			}
		} else {
			fprintf(stderr, RED "tint2 : xembed error" RESET "\n");
			remove_icon(traywin);
			return FALSE;
		}
	}

	// Redirect rendering when using compositing
	if (systray_composited) {
		if (systray_profile)
			fprintf(stderr, "XDamageCreate(server.display, traywin->parent, XDamageReportRawRectangles)\n");
		traywin->damage = XDamageCreate(server.display, traywin->parent, XDamageReportRawRectangles);
		if (systray_profile)
			fprintf(stderr, "XCompositeRedirectWindow(server.display, traywin->parent, CompositeRedirectManual)\n");
		XCompositeRedirectWindow(server.display, traywin->parent, CompositeRedirectManual);
	}

	XRaiseWindow(server.display, traywin->win);

	// Make the icon visible
	if (systray_profile)
		fprintf(stderr, "XMapWindow(server.display, traywin->win)\n");
	XMapWindow(server.display, traywin->win);
	if (!panel->is_hidden) {
		if (systray_profile)
			fprintf(stderr, "XMapRaised(server.display, traywin->parent)\n");
		XMapRaised(server.display, traywin->parent);
	}

	if (systray_profile)
		fprintf(stderr, "XSync(server.display, False)\n");
	XSync(server.display, False);
	XSetErrorHandler(old);
	if (error != FALSE) {
		fprintf(stderr,
		        RED "systray %d: cannot embed icon for window %lu (%s) parent %lu pid %d" RESET "\n",
		        __LINE__,
		        traywin->win,
		        traywin->name,
		        traywin->parent,
		        traywin->pid);
		remove_icon(traywin);
		return FALSE;
	}

	traywin->embedded = TRUE;

	if (systray_profile)
		fprintf(stderr,
		        "[%f] %s:%d win = %lu (%s)\n",
		        profiling_get_time(),
		        __FUNCTION__,
		        __LINE__,
		        traywin->win,
		        traywin->name);

	return TRUE;
}
Exemple #8
0
gboolean reparent_icon(TrayWindow *traywin)
{
	if (systray_profile)
		fprintf(stderr,
		        "[%f] %s:%d win = %lu (%s)\n",
		        profiling_get_time(),
		        __FUNCTION__,
		        __LINE__,
		        traywin->win,
		        traywin->name);
	if (traywin->reparented)
		return TRUE;

	// Watch for the icon trying to resize itself / closing again
	XSync(server.display, False);
	error = FALSE;
	XErrorHandler old = XSetErrorHandler(window_error_handler);
	if (systray_profile)
		fprintf(stderr, "XSelectInput(server.display, traywin->win, ...)\n");
	XSelectInput(server.display, traywin->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask);
	XWithdrawWindow(server.display, traywin->win, server.screen);
	XReparentWindow(server.display, traywin->win, traywin->parent, 0, 0);

	if (systray_profile)
		fprintf(stderr,
				"XMoveResizeWindow(server.display, traywin->win = %ld, 0, 0, traywin->width = %d, traywin->height = "
				"%d)\n",
		        traywin->win,
		        traywin->width,
		        traywin->height);
	XMoveResizeWindow(server.display, traywin->win, 0, 0, traywin->width, traywin->height);

	// Embed into parent
	{
		XEvent e;
		e.xclient.type = ClientMessage;
		e.xclient.serial = 0;
		e.xclient.send_event = True;
		e.xclient.message_type = server.atom._XEMBED;
		e.xclient.window = traywin->win;
		e.xclient.format = 32;
		e.xclient.data.l[0] = CurrentTime;
		e.xclient.data.l[1] = XEMBED_EMBEDDED_NOTIFY;
		e.xclient.data.l[2] = 0;
		e.xclient.data.l[3] = traywin->parent;
		e.xclient.data.l[4] = 0;
		if (systray_profile)
			fprintf(stderr, "XSendEvent(server.display, traywin->win, False, NoEventMask, &e)\n");
		XSendEvent(server.display, traywin->win, False, NoEventMask, &e);
	}

	XSync(server.display, False);
	XSetErrorHandler(old);
	if (error != FALSE) {
		fprintf(stderr,
		        RED "systray %d: cannot embed icon for window %lu (%s) parent %lu pid %d" RESET "\n",
		        __LINE__,
		        traywin->win,
		        traywin->name,
		        traywin->parent,
		        traywin->pid);
		remove_icon(traywin);
		return FALSE;
	}

	traywin->reparented = TRUE;

	if (systray_profile)
		fprintf(stderr,
		        "[%f] %s:%d win = %lu (%s)\n",
		        profiling_get_time(),
		        __FUNCTION__,
		        __LINE__,
		        traywin->win,
		        traywin->name);

	return TRUE;
}