/* Remove a window from application tracker item if it exists */
static gboolean _xfdashboard_application_tracker_item_remove_window(XfdashboardApplicationTrackerItem *inItem,
																	XfdashboardWindowTrackerWindow *inWindow)
{
	GList									*iter;
	XfdashboardWindowTrackerWindow			*window;

	g_return_val_if_fail(inItem, FALSE);
	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow), FALSE);

	/* Iterate through list of windows for application tracker item and if window
	 * was found remove it from list of windows and return immediately.
	 */
	for(iter=inItem->windows; iter; iter=g_list_next(iter))
	{
		/* Get window */
		window=(XfdashboardWindowTrackerWindow*)iter->data;
		if(!window) continue;

		/* Check if window we are iterating right now is the one to lookup */
		if(window==inWindow)
		{
			inItem->windows=g_list_delete_link(inItem->windows, iter);
			return(TRUE);
		}
	}

	/* If we get here the window to remove was not found, so return FALSE here */
	return(FALSE);
}
Beispiel #2
0
/* Find live window actor by window */
static ClutterActor* _xfdashboard_live_workspace_find_by_window(XfdashboardLiveWorkspace *self,
																XfdashboardWindowTrackerWindow *inWindow)
{
	ClutterActor						*child;
	ClutterActorIter					iter;
	ClutterContent						*content;
	XfdashboardWindowTrackerWindow		*window;

	g_return_val_if_fail(XFDASHBOARD_IS_LIVE_WORKSPACE(self), NULL);
	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow), NULL);

	/* Iterate through list of current actors and find the one for requested window */
	clutter_actor_iter_init(&iter, CLUTTER_ACTOR(self));
	while(clutter_actor_iter_next(&iter, &child))
	{
		content=clutter_actor_get_content(child);
		if(!content || !XFDASHBOARD_IS_WINDOW_CONTENT(content)) continue;

		window=xfdashboard_window_content_get_window(XFDASHBOARD_WINDOW_CONTENT(content));
		if(window==inWindow) return(child);
	}

	/* If we get here we did not find the window and we return NULL */
	return(NULL);
}
Beispiel #3
0
/* A window's workspace has changed */
static void _xfdashboard_live_workspace_on_window_workspace_changed(XfdashboardLiveWorkspace *self,
																	XfdashboardWindowTrackerWindow *inWindow,
																	XfdashboardWindowTrackerWorkspace *inWorkspace,
																	gpointer inUserData)
{
	XfdashboardLiveWorkspacePrivate		*priv;
	ClutterActor						*windowActor;

	g_return_if_fail(XFDASHBOARD_IS_LIVE_WORKSPACE(self));
	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow));

	priv=self->priv;

	/* Check if window was removed from workspace or added */
	if(inWorkspace!=priv->workspace)
	{
		/* Find actor for window */
		windowActor=_xfdashboard_live_workspace_find_by_window(self, inWindow);

		/* Destroy window actor */
		if(windowActor) clutter_actor_destroy(windowActor);
	}
		else
		{
			/* Add window actor */
			_xfdashboard_live_workspace_create_and_add_window_actor(self, inWindow);
		}
}
/* The active window has changed */
static void _xfdashboard_application_tracker_on_active_window_changed(XfdashboardApplicationTracker *self,
																		XfdashboardWindowTrackerWindow *inOldActiveWindow,
																		XfdashboardWindowTrackerWindow *inNewActiveWindow,
																		gpointer inUserData)
{
	XfdashboardApplicationTrackerItem		*item;

	g_return_if_fail(XFDASHBOARD_IS_APPLICATION_TRACKER(self));
	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inNewActiveWindow));

	/* Find application tracker item in list of known running applications
	 * matching the new active window.
	 */
	item= _xfdashboard_application_tracker_find_item_by_window(self, inNewActiveWindow);
	if(!item)
	{
		g_debug("Could not find running application for new active window '%s'",
					xfdashboard_window_tracker_window_get_title(inNewActiveWindow));

		return;
	}

	g_debug("New active window is '%s' and belongs to desktop ID '%s'",
				xfdashboard_window_tracker_window_get_title(inNewActiveWindow),
				item->desktopID);

	/* Move new active window of found application tracker item to begin of
	 * list of windows by removing window from list and prepending it to list
	 * again. This will sort the list of window in order of last activation.
	 * That means the first window in list was the last active one for this
	 * application.
	 */
	item->windows=g_list_remove(item->windows, inNewActiveWindow);
	item->windows=g_list_prepend(item->windows, inNewActiveWindow);
}
/* Add a window to application tracker item but avoid duplicates */
static gboolean _xfdashboard_application_tracker_item_add_window(XfdashboardApplicationTrackerItem *inItem,
																XfdashboardWindowTrackerWindow *inWindow)
{
	GList									*iter;
	XfdashboardWindowTrackerWindow			*window;

	g_return_val_if_fail(inItem, FALSE);
	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow), FALSE);

	/* Iterate through list of windows for application tracker item and return
	 * immediately if requested window to add is found in list.
	 */
	for(iter=inItem->windows; iter; iter=g_list_next(iter))
	{
		/* Get window */
		window=(XfdashboardWindowTrackerWindow*)iter->data;
		if(!window) continue;

		/* Check if window we are iterating right now is the one to lookup */
		if(window==inWindow) return(FALSE);
	}

	/* If we get here the window was not found in list of windows of application
	 * tracker item, so add it to beginning of this list as it should be the
	 * last active windows for this application.
	 */
	inItem->windows=g_list_prepend(inItem->windows, inWindow);

	/* Return TRUE as window was added */
	return(TRUE);
}
Beispiel #6
0
/* A window's position and/or size has changed */
static void _xfdashboard_live_workspace_on_window_geometry_changed(XfdashboardLiveWorkspace *self,
																	XfdashboardWindowTrackerWindow *inWindow,
																	gpointer inUserData)
{
	g_return_if_fail(XFDASHBOARD_IS_LIVE_WORKSPACE(self));
	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow));

	/* Actor's allocation may change because of new geometry so relayout */
	clutter_actor_queue_relayout(CLUTTER_ACTOR(self));
}
/* A window was created */
static void _xfdashboard_application_tracker_on_window_opened(XfdashboardApplicationTracker *self,
																XfdashboardWindowTrackerWindow *inWindow,
																gpointer inUserData)
{
	XfdashboardApplicationTrackerPrivate	*priv;
	GAppInfo								*appInfo;
	XfdashboardApplicationTrackerItem		*item;

	g_return_if_fail(XFDASHBOARD_IS_APPLICATION_TRACKER(self));
	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow));

	priv=self->priv;
	appInfo=NULL;

	/* Try to find application for window */
	appInfo=_xfdashboard_application_tracker_get_desktop_id_from_environment(self, inWindow);
	if(!appInfo) appInfo=_xfdashboard_application_tracker_get_desktop_id_from_window_names(self, inWindow);

	/* If we could not resolve window to a desktop application info, then stop here */
	if(!appInfo)
	{
		g_debug("Could not resolve window '%s' to any desktop ID",
					xfdashboard_window_tracker_window_get_title(inWindow));

		return;
	}

	g_debug("Window '%s' belongs to desktop ID '%s'",
				xfdashboard_window_tracker_window_get_title(inWindow),
				g_app_info_get_id(appInfo));

	/* Create application tracker if no one exists for application and window ... */
	item= _xfdashboard_application_tracker_find_item_by_app_info(self, appInfo);
	if(!item)
	{
		/* Create application tracker item */
		item=_xfdashboard_application_tracker_item_new(appInfo, inWindow);

		/* Add new item to list of running applications */
		priv->runningApps=g_list_prepend(priv->runningApps, item);

		/* Emit signal as this application is known to be running now */
		g_debug("Emitting signal 'state-changed' to running for desktop ID '%s'", item->desktopID);
		g_signal_emit(self, XfdashboardApplicationTrackerSignals[SIGNAL_STATE_CHANGED], g_quark_from_string(item->desktopID), item->desktopID, TRUE);
	}
		/* ... otherwise add window to existing one */
		else
		{
			/* Add window to list of window for known running application */
			_xfdashboard_application_tracker_item_add_window(item, inWindow);
		}

	/* Release allocated resources */
	if(appInfo) g_object_unref(appInfo);
}
Beispiel #8
0
/* A window was closed */
static void _xfdashboard_live_workspace_on_window_closed(XfdashboardLiveWorkspace *self,
															XfdashboardWindowTrackerWindow *inWindow,
															gpointer inUserData)
{
	ClutterActor						*windowActor;

	g_return_if_fail(XFDASHBOARD_IS_LIVE_WORKSPACE(self));
	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow));

	/* Find and destroy actor */
	windowActor=_xfdashboard_live_workspace_find_by_window(self, inWindow);
	if(windowActor) clutter_actor_destroy(windowActor);
}
Beispiel #9
0
/* A window was opened */
static void _xfdashboard_live_workspace_on_window_opened(XfdashboardLiveWorkspace *self,
															XfdashboardWindowTrackerWindow *inWindow,
															gpointer inUserData)
{
	g_return_if_fail(XFDASHBOARD_IS_LIVE_WORKSPACE(self));
	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow));

	/* Check if window is visible on this workspace */
	if(!_xfdashboard_live_workspace_is_visible_window(self, inWindow)) return;

	/* Create actor for window */
	_xfdashboard_live_workspace_create_and_add_window_actor(self, inWindow);
}
/* Create new application tracker item */
static XfdashboardApplicationTrackerItem* _xfdashboard_application_tracker_item_new(GAppInfo *inAppInfo,
																					XfdashboardWindowTrackerWindow *inWindow)
{
	XfdashboardApplicationTrackerItem		*item;

	g_return_val_if_fail(G_IS_APP_INFO(inAppInfo), NULL);
	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow), NULL);

	/* Create new application item and set up */
	item=g_new0(XfdashboardApplicationTrackerItem, 1);
	item->pid=xfdashboard_window_tracker_window_get_pid(inWindow);
	item->appInfo=g_object_ref(inAppInfo);
	item->desktopID=g_strdup(g_app_info_get_id(inAppInfo));
	item->windows=g_list_prepend(item->windows, inWindow);

	/* Return newly created application tracker item */
	return(item);
}
Beispiel #11
0
/* Check if window should be shown */
static gboolean _xfdashboard_live_workspace_is_visible_window(XfdashboardLiveWorkspace *self,
																XfdashboardWindowTrackerWindow *inWindow)
{
	XfdashboardLiveWorkspacePrivate		*priv;

	g_return_val_if_fail(XFDASHBOARD_IS_LIVE_WORKSPACE(self), FALSE);
	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow), FALSE);

	priv=self->priv;

	/* Determine if windows should be shown depending on its state */
	if(xfdashboard_window_tracker_window_is_skip_pager(inWindow) ||
		xfdashboard_window_tracker_window_is_skip_tasklist(inWindow) ||
		(priv->workspace && !xfdashboard_window_tracker_window_is_visible_on_workspace(inWindow, priv->workspace)) ||
		xfdashboard_window_tracker_window_is_stage(inWindow))
	{
		return(FALSE);
	}

	/* If we get here the window should be shown */
	return(TRUE);
}
/* Find application tracker item by window */
static XfdashboardApplicationTrackerItem* _xfdashboard_application_tracker_find_item_by_window(XfdashboardApplicationTracker *self,
																								XfdashboardWindowTrackerWindow *inWindow)
{
	XfdashboardApplicationTrackerPrivate		*priv;
	GList										*appIter;

	g_return_val_if_fail(XFDASHBOARD_IS_APPLICATION_TRACKER(self), NULL);
	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow), NULL);

	priv=self->priv;

	/* Iterate through list of window of each application tracker item and
	 * lookup item owning the requested window.
	 */
	for(appIter=priv->runningApps; appIter; appIter=g_list_next(appIter))
	{
		XfdashboardApplicationTrackerItem		*item;
		GList									*windowIter;
		XfdashboardWindowTrackerWindow			*window;

		/* Get application tracker item */
		item=(XfdashboardApplicationTrackerItem*)appIter->data;
		if(!item) continue;

		/* Iterate through list of known window for item */
		for(windowIter=item->windows; windowIter; windowIter=g_list_next(windowIter))
		{
			/* Get window */
			window=(XfdashboardWindowTrackerWindow*)windowIter->data;
			if(!window) continue;

			/* Check if window we are iterating right now is the one to lookup */
			if(window==inWindow) return(item);
		}
	}

	/* If we get here no item owns requested window */
	return(NULL);
}
Beispiel #13
0
/* A window's state has changed */
static void _xfdashboard_live_workspace_on_window_state_changed(XfdashboardLiveWorkspace *self,
																XfdashboardWindowTrackerWindow *inWindow,
																gpointer inUserData)
{
	/* We need to see it from the point of view of a workspace.
	 * If a window is visible on the workspace but we have no actor
	 * for this window then create it. If a window is not visible anymore
	 * on this workspace then destroy the corresponding actor.
	 * That is why initially we set any window to invisible because if
	 * changed window is not visible on this workspace it will do nothing.
	 */

	ClutterActor		*windowActor;
	gboolean			newVisible;
	gboolean			currentVisible;

	g_return_if_fail(XFDASHBOARD_IS_LIVE_WORKSPACE(self));
	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow));

	currentVisible=FALSE;

	/* Find window and get current visibility state */
	windowActor=_xfdashboard_live_workspace_find_by_window(self, inWindow);
	if(windowActor)
	{
		currentVisible=!!CLUTTER_ACTOR_IS_VISIBLE(windowActor);
	}

	/* Check if window's visibility has changed */
	newVisible=_xfdashboard_live_workspace_is_visible_window(self, inWindow);
	if(newVisible!=currentVisible)
	{
		if(newVisible) _xfdashboard_live_workspace_create_and_add_window_actor(self, inWindow);
			else if(windowActor) clutter_actor_destroy(windowActor);
	}
}
/* Get desktop ID from window names.
 * Callee is responsible to free result with g_object_unref().
 */
static GAppInfo* _xfdashboard_application_tracker_get_desktop_id_from_window_names(XfdashboardApplicationTracker *self,
																					XfdashboardWindowTrackerWindow *inWindow)
{
	XfdashboardApplicationTrackerPrivate	*priv;
	GAppInfo								*foundAppInfo;
	gchar									**names;
	gchar									**iter;
	GList									*apps;

	g_return_val_if_fail(XFDASHBOARD_IS_APPLICATION_TRACKER(self), NULL);
	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow), NULL);

	priv=self->priv;
	foundAppInfo=NULL;

	/* Get list of applications */
	apps=xfdashboard_application_database_get_all_applications(priv->appDatabase);

	/* Get window's names */
	names=xfdashboard_window_tracker_window_get_instance_names(inWindow);

	/* Iterate through window's names to try to find matching desktop file */
	iter=names;
	while(iter && *iter)
	{
		GAppInfo							*appInfo;
		gchar								*iterName;
		gchar								*iterNameLowerCase;

		/* Build desktop ID from iterated name */
		if(!g_str_has_suffix(*iter, ".desktop")) iterName=g_strconcat(*iter, ".desktop", NULL);
			else iterName=g_strdup(*iter);

		iterNameLowerCase=g_utf8_strdown(iterName, -1);

		/* Lookup application from unmodified name */
		appInfo=xfdashboard_application_database_lookup_desktop_id(priv->appDatabase, iterName);

		/* Lookup application from to-lower-case converted name if previous
		 * lookup with unmodified name failed.
		 */
		if(!appInfo)
		{
			/* Lookup application from lower-case name */
			appInfo=xfdashboard_application_database_lookup_desktop_id(priv->appDatabase, iterNameLowerCase);
		}

		/* If no application was found for the name it may be an application
		 * located in a subdirectory. Then the desktop ID is prefixed with
		 * the subdirectory's name followed by a dash. So iterate through all
		 * applications and lookup with glob pattern '*-' followed by name
		 * and suffix '.desktop'.
		 */
		if(!appInfo)
		{
			GList							*iterApps;
			GList							*foundSubdirApps;
			gchar							*globName;
			GPatternSpec					*globPattern;
			GAppInfo						*globAppInfo;

			/* Build glob pattern */
			globAppInfo=NULL;
			globName=g_strconcat("*-", iterNameLowerCase, NULL);
			globPattern=g_pattern_spec_new(globName);

			/* Iterate through application and collect applications matching
			 * glob pattern.
			 */
			foundSubdirApps=NULL;
			for(iterApps=apps; iterApps; iterApps=g_list_next(iterApps))
			{
				if(!G_IS_APP_INFO(iterApps->data)) continue;
				globAppInfo=G_APP_INFO(iterApps->data);

				if(g_pattern_match_string(globPattern, g_app_info_get_id(globAppInfo)))
				{
					foundSubdirApps=g_list_prepend(foundSubdirApps, globAppInfo);
					g_debug("Found possible application '%s' for window '%s' using pattern '%s'",
							g_app_info_get_id(globAppInfo),
							xfdashboard_window_tracker_window_get_title(inWindow),
							globName);
				}
			}

			/* If exactly one application was collected because it matched
			 * the glob pattern then we found the application.
			 */
			if(g_list_length(foundSubdirApps)==1)
			{
				appInfo=G_APP_INFO(g_object_ref(G_OBJECT(foundSubdirApps->data)));

				g_debug("Found exactly one application named '%s' for window '%s' using pattern '%s'",
						g_app_info_get_id(appInfo),
						xfdashboard_window_tracker_window_get_title(inWindow),
						globName);
			}

			/* Release allocated resources */
			if(foundSubdirApps) g_list_free(foundSubdirApps);
			if(globPattern) g_pattern_spec_free(globPattern);
			if(globName) g_free(globName);
		}

		/* If we still did not find an application continue with next
		 * name in list.
		 */
		if(!appInfo)
		{
			/* Release allocated resources */
			if(iterName) g_free(iterName);
			if(iterNameLowerCase) g_free(iterNameLowerCase);

			/* Continue with next name in list */
			iter++;
			continue;
		}

		/* Check if found application info matches previous one. If it does not match
		 * the desktop IDs found previously are ambigous, so return NULL result.
		 */
		if(foundAppInfo &&
			!g_app_info_equal(foundAppInfo, appInfo))
		{
			g_debug("Resolved window names of '%s' are ambiguous - discarding desktop IDs '%s' and '%s'",
						xfdashboard_window_tracker_window_get_title(inWindow),
						g_app_info_get_id(foundAppInfo),
						g_app_info_get_id(appInfo));

			/* Release allocated resources */
			if(iterName) g_free(iterName);
			if(iterNameLowerCase) g_free(iterNameLowerCase);
			if(foundAppInfo) g_object_unref(foundAppInfo);
			if(appInfo) g_object_unref(appInfo);
			if(names) g_strfreev(names);
			if(apps) g_list_free_full(apps, g_object_unref);

			return(NULL);
		}

		/* If it is the first application info found, remember it */
		if(!foundAppInfo) foundAppInfo=g_object_ref(appInfo);

		/* Release allocated resources */
		if(iterName) g_free(iterName);
		if(iterNameLowerCase) g_free(iterNameLowerCase);
		if(appInfo) g_object_unref(appInfo);

		/* Continue with next name in list */
		iter++;
	}

	/* Release allocated resources */
	if(names) g_strfreev(names);
	if(apps) g_list_free_full(apps, g_object_unref);

	/* Return found application info */
	g_debug("Resolved window names of '%s' to desktop ID '%s'",
				xfdashboard_window_tracker_window_get_title(inWindow),
				foundAppInfo ? g_app_info_get_id(foundAppInfo) : "<nil>");

	return(foundAppInfo);
}
/* A window was closed */
static void _xfdashboard_application_tracker_on_window_closed(XfdashboardApplicationTracker *self,
																XfdashboardWindowTrackerWindow *inWindow,
																gpointer inUserData)
{
	XfdashboardApplicationTrackerPrivate	*priv;
	XfdashboardApplicationTrackerItem		*item;

	g_return_if_fail(XFDASHBOARD_IS_APPLICATION_TRACKER(self));
	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow));

	priv=self->priv;

	/* Find application tracker item in list of known running applications
	 * matching the window just closed.
	 */
	item= _xfdashboard_application_tracker_find_item_by_window(self, inWindow);
	if(!item)
	{
		g_debug("Could not find running application for window '%s'",
					xfdashboard_window_tracker_window_get_title(inWindow));

		return;
	}

	g_debug("Closing window '%s' for desktop ID '%s'",
				xfdashboard_window_tracker_window_get_title(inWindow),
				item->desktopID);

	/* Remove window from found application tracker item */
	_xfdashboard_application_tracker_item_remove_window(item, inWindow);

	/* If it was the last window then application is not running anymore
	 * because it has no window.
	 */
	if(!item->windows ||
		g_list_length(item->windows)==0)
	{
		gchar								*desktopID;

		g_debug("Closing window '%s' for desktop ID '%s' closed last window so remove application from list of running ones",
					xfdashboard_window_tracker_window_get_title(inWindow),
					item->desktopID);

		/* Create a copy of desktop ID for signal emission because the
		 * application tracker item will be removed and freed before.
		 */
		desktopID=g_strdup(item->desktopID);

		/* Remove application tracker item from list of running applications
		 * and free it.
		 */
		priv->runningApps=g_list_remove(priv->runningApps, item);
		_xfdashboard_application_tracker_item_free(item);

		/* Emit signal as this application is not running anymore */
		g_debug("Emitting signal 'state-changed' to stopped for desktop ID '%s'", desktopID);
		g_signal_emit(self, XfdashboardApplicationTrackerSignals[SIGNAL_STATE_CHANGED], g_quark_from_string(desktopID), desktopID, FALSE);

		/* Release allocated resources */
		g_free(desktopID);
	}
}
/* Get desktop ID from window names.
 * Callee is responsible to free result with g_object_unref().
 */
static GAppInfo* _xfdashboard_application_tracker_get_desktop_id_from_window_names(XfdashboardApplicationTracker *self,
																					XfdashboardWindowTrackerWindow *inWindow)
{
	XfdashboardApplicationTrackerPrivate	*priv;
	GAppInfo								*foundAppInfo;
	gchar									**names;
	gchar									**iter;

	g_return_val_if_fail(XFDASHBOARD_IS_APPLICATION_TRACKER(self), NULL);
	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow), NULL);

	priv=self->priv;
	foundAppInfo=NULL;

	/* Get window's names */
	names=xfdashboard_window_tracker_window_get_instance_names(inWindow);

	/* Iterate through window's names to try to find matching desktop file */
	iter=names;
	while(iter && *iter)
	{
		GAppInfo							*appInfo;

		/* Lookup application from unmodified name */
		if(g_str_has_suffix(*iter, ".desktop"))
		{
			appInfo=xfdashboard_application_database_lookup_desktop_id(priv->appDatabase, *iter);
		}
			else
			{
				gchar						*desktopID;

				desktopID=g_strconcat(*iter, ".desktop", NULL);
				appInfo=xfdashboard_application_database_lookup_desktop_id(priv->appDatabase, desktopID);
				g_free(desktopID);
			}

		/* Lookup application from to-lower-case converted name if previous
		 * lookup with unmodified name failed.
		 */
		if(!appInfo)
		{
			gchar							*lowerDesktopID;

			/* Convert name to lower case */
			lowerDesktopID=g_utf8_strdown(*iter, -1);

			/* Lookup application from lower-case name. No need to add '.desktop'
			 * as suffix as it was done before.
			 */
			if(g_str_has_suffix(lowerDesktopID, ".desktop"))
			{
				appInfo=xfdashboard_application_database_lookup_desktop_id(priv->appDatabase, lowerDesktopID);
			}
				else
				{
					gchar					*desktopID;

					desktopID=g_strconcat(lowerDesktopID, ".desktop", NULL);
					appInfo=xfdashboard_application_database_lookup_desktop_id(priv->appDatabase, desktopID);
					g_free(desktopID);
				}

			/* Free lower case of name */
			g_free(lowerDesktopID);

			/* If we still did not find an application continue with next
			 * name in list.
			 */
			if(!appInfo)
			{
				/* Continue with next name in list */
				iter++;
				continue;
			}
		}

		/* Check if found application info matches previous one. If it does not match
		 * the desktop IDs found previously are ambigous, so return NULL result.
		 */
		if(foundAppInfo &&
			!g_app_info_equal(foundAppInfo, appInfo))
		{
			g_debug("Resolved window names of '%s' are ambiguous - discarding desktop IDs '%s' and '%s'",
						xfdashboard_window_tracker_window_get_title(inWindow),
						g_app_info_get_id(foundAppInfo),
						g_app_info_get_id(appInfo));

			/* Release allocated resources */
			if(foundAppInfo) g_object_unref(foundAppInfo);
			if(appInfo) g_object_unref(appInfo);
			if(names) g_strfreev(names);

			return(NULL);
		}

		/* If it is the first application info found, remember it */
		if(!foundAppInfo) foundAppInfo=g_object_ref(appInfo);

		/* Release allocated resources */
		if(appInfo) g_object_unref(appInfo);

		/* Continue with next name in list */
		iter++;
	}

	/* Release allocated resources */
	if(names) g_strfreev(names);

	/* Return found application info */
	g_debug("Resolved window names of '%s' to desktop ID '%s'",
				xfdashboard_window_tracker_window_get_title(inWindow),
				foundAppInfo ? g_app_info_get_id(foundAppInfo) : "<nil>");

	return(foundAppInfo);
}
/* Get desktop ID from process' environment which owns window.
 * Callee is responsible to free result with g_object_unref().
 */
static GAppInfo* _xfdashboard_application_tracker_get_desktop_id_from_environment(XfdashboardApplicationTracker *self,
																					XfdashboardWindowTrackerWindow *inWindow)
{
	XfdashboardApplicationTrackerPrivate	*priv;
	GAppInfo								*foundAppInfo;
	gint									windowPID;
	gchar									*procEnvFile;
	gchar									*envContent;
	gsize									envLength;
	GError									*error;
	gchar									*iter;
	const gchar								*gioLaunchedPID;
	const gchar								*gioLaunchedDesktopFile;

	g_return_val_if_fail(XFDASHBOARD_IS_APPLICATION_TRACKER(self), NULL);
	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow), NULL);

	priv=self->priv;
	foundAppInfo=NULL;
	error=NULL;

	/* Get process ID running this window */
	windowPID=xfdashboard_window_tracker_window_get_pid(inWindow);
	if(windowPID<=0)
	{
		g_debug("Could not get PID for window '%s' of a running application to parse environment variables",
				xfdashboard_window_tracker_window_get_title(inWindow));

		return(NULL);
	}

	/* Open enviroment variables of process.
	 * This is the initial set of environment variables set when process was spawned.
	 * But that is ok because the environment variables we lookup are set
	 * at launch time and do not change.
	 */
	envContent=NULL;
	envLength=0;

	procEnvFile=g_strdup_printf("/proc/%d/environ", windowPID);
	if(!g_file_get_contents(procEnvFile, &envContent, &envLength, &error))
	{
		g_debug("Could read in enviroment varibles for PID %d of window '%s' at %s: %s",
					windowPID,
					xfdashboard_window_tracker_window_get_title(inWindow),
					procEnvFile,
					error ? error->message : _("Unknown error"));

		/* Release allocated resources */
		if(error) g_error_free(error);
		if(procEnvFile) g_free(procEnvFile);
		if(envContent) g_free(envContent);

		/* Return NULL result */
		return(NULL);
	}

	g_debug("Enviroment set at %s is %lu bytes long for window '%s'",
				procEnvFile,
				envLength,
				xfdashboard_window_tracker_window_get_title(inWindow));

	/* Iterate through enviroment variables and lookup GIO_LAUNCHED_DESKTOP_FILE
	 * and GIO_LAUNCHED_DESKTOP_FILE_PID.
	 */
	gioLaunchedPID=NULL;
	gioLaunchedDesktopFile=NULL;

	iter=envContent;
	while(envLength>0)
	{
		gsize								len;

		/* Skip NULL-termination */
		if(!*iter)
		{
			envLength--;
			iter++;
			continue;
		}

		/* Check current iterated enviroment variable matches a requested one */
		if(g_str_has_prefix(iter, "GIO_LAUNCHED_DESKTOP_FILE="))
		{
			/* Each enviroment variable should be listed only once
			 * otherwise is an error.
			 */
			if(gioLaunchedDesktopFile)
			{
				g_debug("Could parse in enviroment varibles for PID %d of window '%s' at %s because GIO_LAUNCHED_DESKTOP_FILE exists more than once",
							windowPID,
							xfdashboard_window_tracker_window_get_title(inWindow),
							procEnvFile);

				/* Release allocated resources */
				if(foundAppInfo) g_object_unref(foundAppInfo);
				if(procEnvFile) g_free(procEnvFile);
				if(envContent) g_free(envContent);

				/* Return NULL result */
				return(NULL);
			}

			/* Remember value of environment variable */
			gioLaunchedDesktopFile=iter;
		}
			else if(g_str_has_prefix(iter, "GIO_LAUNCHED_DESKTOP_FILE_PID="))
			{
				/* Each enviroment variable should be listed only once
				 * otherwise is an error.
				 */
				if(gioLaunchedPID)
				{
					g_debug("Could parse in enviroment varibles for PID %d of window '%s' at %s because GIO_LAUNCHED_DESKTOP_FILE_PID exists more than once",
								windowPID,
								xfdashboard_window_tracker_window_get_title(inWindow),
								procEnvFile);

					/* Release allocated resources */
					if(foundAppInfo) g_object_unref(foundAppInfo);
					if(procEnvFile) g_free(procEnvFile);
					if(envContent) g_free(envContent);

					/* Return NULL result */
					return(NULL);
				}

				/* Remember value of environment variable */
				gioLaunchedPID=iter;
			}

		/* If all requested environment variable has been found stop iterating */
		if(gioLaunchedPID && gioLaunchedDesktopFile) break;

		/* Continue with next environment variable */
		len=strlen(iter);
		iter+=len;
		envLength-=len;
	}

	/* If all requested environment variable has been found then check if
	 * GIO_LAUNCHED_DESKTOP_FILE_PID matches window owner's process ID.
	 */
	if(gioLaunchedPID && gioLaunchedDesktopFile)
	{
		/* Move pointer of environment variables to value */
		while(*gioLaunchedPID && *gioLaunchedPID!='=') gioLaunchedPID++;
		while(*gioLaunchedDesktopFile && *gioLaunchedDesktopFile!='=') gioLaunchedDesktopFile++;

		/* Check if pointers points to value assignment character */
		if(*gioLaunchedPID=='=' &&
			*gioLaunchedDesktopFile=='=')
		{
			gint							checkPID;

			/* Move pointer one byte further where value begins really */
			gioLaunchedPID++;
			gioLaunchedDesktopFile++;

			/* Check if PID of enviroment variable matches window owner's
			 * process ID.
			 */
			checkPID=atoi(gioLaunchedPID);
			if(checkPID==windowPID)
			{
				/* Lookup application from full path */
				foundAppInfo=xfdashboard_application_database_lookup_desktop_id(priv->appDatabase, gioLaunchedDesktopFile);
				if(!foundAppInfo)
				{
					/* Lookup application from basename of path */
					gioLaunchedDesktopFile=g_strrstr(gioLaunchedDesktopFile, G_DIR_SEPARATOR_S);
					if(gioLaunchedDesktopFile)
					{
						gioLaunchedDesktopFile++;
						foundAppInfo=xfdashboard_application_database_lookup_desktop_id(priv->appDatabase, gioLaunchedDesktopFile);
					}
				}
			}
				else
				{
					g_debug("PID %d of environment variable does not match window PID %d for '%s'",
								checkPID,
								windowPID,
								xfdashboard_window_tracker_window_get_title(inWindow));
				}
		}
	}

	/* Release allocated resources */
	if(procEnvFile) g_free(procEnvFile);
	if(envContent) g_free(envContent);

	/* Return found application info */
	g_debug("Resolved enviroment variables of window '%s' to desktop ID '%s'",
				xfdashboard_window_tracker_window_get_title(inWindow),
				foundAppInfo ? g_app_info_get_id(foundAppInfo) : "<nil>");

	return(foundAppInfo);
}
Beispiel #18
0
/* Create actor for window but respect window stacking when adding */
static ClutterActor* _xfdashboard_live_workspace_create_and_add_window_actor(XfdashboardLiveWorkspace *self,
																				XfdashboardWindowTrackerWindow *inWindow)
{
	XfdashboardLiveWorkspacePrivate	*priv;
	ClutterActor					*actor;
	ClutterContent					*content;
	GList							*windows;
	ClutterActor					*lastWindowActor;
	XfdashboardWindowTrackerWindow	*window;

	g_return_val_if_fail(XFDASHBOARD_IS_LIVE_WORKSPACE(self), NULL);
	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow), NULL);

	priv=self->priv;

	/* We cannot assume that each window newly opened or moved to this workspace
	 * will be on top of all other windows. We need to respect window stacking.
	 * Therefore we iterate through list of windows in stacking order and find
	 * the last window we have an actor for before we the window requested.
	 */
	lastWindowActor=NULL;
	windows=xfdashboard_window_tracker_get_windows_stacked(priv->windowTracker);
	for( ; windows; windows=g_list_next(windows))
	{
		/* Get window from list */
		window=XFDASHBOARD_WINDOW_TRACKER_WINDOW(windows->data);
		if(!window) continue;

		/* We do not need to check if window would be visible on this workspace
		 * as it should not have been created if it is not visible.
		 */
		lastWindowActor=_xfdashboard_live_workspace_find_by_window(self, window);
		if(lastWindowActor) break;
	}

	/* Check if we have to "move" an existing window actor or if we have to create
	 * a new actor for window
	 */
	actor=_xfdashboard_live_workspace_find_by_window(self, inWindow);
	if(actor)
	{
		/* Move existing window actor to new stacking position */
		g_object_ref(actor);
		clutter_actor_remove_child(CLUTTER_ACTOR(self), actor);
		clutter_actor_insert_child_above(CLUTTER_ACTOR(self), actor, lastWindowActor);
		g_object_unref(actor);
	}
		else
		{
			/* Create actor */
			actor=clutter_actor_new();
			content=xfdashboard_window_content_new_for_window(inWindow);
			clutter_actor_set_content(actor, content);
			g_object_unref(content);

			/* Add new actor at right stacking position */
			clutter_actor_insert_child_above(CLUTTER_ACTOR(self), actor, lastWindowActor);
		}

	return(actor);
}
/* Get desktop ID from process' environment which owns window.
 * Callee is responsible to free result with g_object_unref().
 */
static GAppInfo* _xfdashboard_application_tracker_get_desktop_id_from_environment(XfdashboardApplicationTracker *self,
																					XfdashboardWindowTrackerWindow *inWindow)
{
	XfdashboardApplicationTrackerPrivate	*priv;
	GAppInfo								*foundAppInfo;
	gint									windowPID;
	GHashTable								*environments;
	gchar									*value;
	gint									checkPID;

	g_return_val_if_fail(XFDASHBOARD_IS_APPLICATION_TRACKER(self), NULL);
	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow), NULL);

	priv=self->priv;
	foundAppInfo=NULL;

	/* Get process ID running this window */
	windowPID=xfdashboard_window_tracker_window_get_pid(inWindow);
	if(windowPID<=0)
	{
		g_debug("Could not get PID for window '%s' of a running application to parse environment variables",
				xfdashboard_window_tracker_window_get_title(inWindow));

		/* Return NULL result */
		return(NULL);
	}

	/* Get hash-table with environment variables found for window's PID */
	environments=_xfdashboard_application_tracker_get_environment_from_pid(windowPID);
	if(!environments)
	{
		g_debug("Could not get environments for PID %d of windows '%s'",
				windowPID,
				xfdashboard_window_tracker_window_get_title(inWindow));

		/* Return NULL result */
		return(NULL);
	}

	/* Check that environment variable GIO_LAUNCHED_DESKTOP_FILE_PID exists.
	 * Also check that the PID in value matches the requested window's PID
	 * as the process may inherit the environments of its parent process
	 * but then this one is not the initial process for this application.
	 */
	if(!g_hash_table_lookup_extended(environments, "GIO_LAUNCHED_DESKTOP_FILE_PID", NULL, (gpointer)&value))
	{
		g_debug("Missing 'GIO_LAUNCHED_DESKTOP_FILE_PID' in environment variables for PID %d of windows '%s'",
					windowPID,
					xfdashboard_window_tracker_window_get_title(inWindow));

		/* Release allocated resources */
		if(environments) g_hash_table_destroy(environments);

		/* Return NULL result */
		return(NULL);
	}

	checkPID=atoi(value);
	if(checkPID!=windowPID)
	{
		g_debug("PID %d of environment variables does not match requested window PID %d for '%s'",
					checkPID,
					windowPID,
					xfdashboard_window_tracker_window_get_title(inWindow));

		/* Release allocated resources */
		if(environments) g_hash_table_destroy(environments);

		/* Return NULL result */
		return(NULL);
	}

	/* Check that environment variable GIO_LAUNCHED_DESKTOP_FILE exists and
	 * lookup application from full path as set in environment's value.
	 */
	if(!g_hash_table_lookup_extended(environments, "GIO_LAUNCHED_DESKTOP_FILE", NULL, (gpointer)&value))
	{
		g_debug("Missing 'GIO_LAUNCHED_DESKTOP_FILE' in environment variables for PID %d of windows '%s'",
					windowPID,
					xfdashboard_window_tracker_window_get_title(inWindow));

		/* Release allocated resources */
		if(environments) g_hash_table_destroy(environments);

		/* Return NULL result */
		return(NULL);
	}

	foundAppInfo=xfdashboard_application_database_lookup_desktop_id(priv->appDatabase, value);
	if(!foundAppInfo)
	{
		/* Lookup application from basename of path */
		value=g_strrstr(value, G_DIR_SEPARATOR_S);
		if(value)
		{
			value++;
			foundAppInfo=xfdashboard_application_database_lookup_desktop_id(priv->appDatabase, value);
		}
	}

	/* Release allocated resources */
	if(environments) g_hash_table_destroy(environments);

	/* Return found application info which may be NULL if not found in
	 * application database.
	 */
	g_debug("Resolved enviroment variables of window '%s' to desktop ID '%s'",
				xfdashboard_window_tracker_window_get_title(inWindow),
				foundAppInfo ? g_app_info_get_id(foundAppInfo) : "<nil>");

	return(foundAppInfo);
}