Compare commits
	
		
			14 Commits
		
	
	
		
			wip/carlos
			...
			workspace-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					87ce301faa | ||
| 
						 | 
					1ab526dc64 | ||
| 
						 | 
					c11162f794 | ||
| 
						 | 
					8e5d613bfa | ||
| 
						 | 
					8786da0044 | ||
| 
						 | 
					3d5cb0f30a | ||
| 
						 | 
					fb28f77c85 | ||
| 
						 | 
					58c8006f1f | ||
| 
						 | 
					277cff3013 | ||
| 
						 | 
					cde3ce2e27 | ||
| 
						 | 
					57a4ad2d00 | ||
| 
						 | 
					8bc0caa21b | ||
| 
						 | 
					ae478c2344 | ||
| 
						 | 
					0dfdc9371e | 
@@ -24,7 +24,6 @@ dist_images_DATA =				\
 | 
			
		||||
 | 
			
		||||
themedir = $(pkgdatadir)/theme
 | 
			
		||||
dist_theme_DATA =				\
 | 
			
		||||
	theme/add-workspace.svg			\
 | 
			
		||||
	theme/calendar-arrow-left.svg		\
 | 
			
		||||
	theme/calendar-arrow-right.svg		\
 | 
			
		||||
	theme/close-window.svg			\
 | 
			
		||||
@@ -37,7 +36,6 @@ dist_theme_DATA =				\
 | 
			
		||||
	theme/mosaic-view.svg			\
 | 
			
		||||
	theme/move-window-on-new.svg		\
 | 
			
		||||
	theme/process-working.png		\
 | 
			
		||||
	theme/remove-workspace.svg		\
 | 
			
		||||
	theme/running-indicator.svg		\
 | 
			
		||||
	theme/scroll-button-down-hover.png	\
 | 
			
		||||
	theme/scroll-button-down.png		\
 | 
			
		||||
 
 | 
			
		||||
@@ -1,98 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="23"
 | 
			
		||||
   height="15"
 | 
			
		||||
   id="svg6375"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.47pre4 r22446"
 | 
			
		||||
   sodipodi:docname="New document 13">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs6377">
 | 
			
		||||
    <inkscape:perspective
 | 
			
		||||
       sodipodi:type="inkscape:persp3d"
 | 
			
		||||
       inkscape:vp_x="0 : 16 : 1"
 | 
			
		||||
       inkscape:vp_y="0 : 1000 : 0"
 | 
			
		||||
       inkscape:vp_z="32 : 16 : 1"
 | 
			
		||||
       inkscape:persp3d-origin="16 : 10.666667 : 1"
 | 
			
		||||
       id="perspective6383" />
 | 
			
		||||
    <inkscape:perspective
 | 
			
		||||
       id="perspective6366"
 | 
			
		||||
       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
 | 
			
		||||
       inkscape:vp_z="1 : 0.5 : 1"
 | 
			
		||||
       inkscape:vp_y="0 : 1000 : 0"
 | 
			
		||||
       inkscape:vp_x="0 : 0.5 : 1"
 | 
			
		||||
       sodipodi:type="inkscape:persp3d" />
 | 
			
		||||
  </defs>
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="11.197802"
 | 
			
		||||
     inkscape:cx="16"
 | 
			
		||||
     inkscape:cy="16"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="true"
 | 
			
		||||
     inkscape:grid-bbox="true"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:window-width="1680"
 | 
			
		||||
     inkscape:window-height="997"
 | 
			
		||||
     inkscape:window-x="0"
 | 
			
		||||
     inkscape:window-y="26"
 | 
			
		||||
     inkscape:window-maximized="1" />
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata6380">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     transform="translate(0,-17)">
 | 
			
		||||
    <g
 | 
			
		||||
       style="display:inline"
 | 
			
		||||
       id="g6243"
 | 
			
		||||
       transform="translate(-986.28859,-658.2796)">
 | 
			
		||||
      <rect
 | 
			
		||||
         style="fill:#000000;fill-opacity:0.98770495;stroke:#666666;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
 | 
			
		||||
         id="rect5318"
 | 
			
		||||
         width="22"
 | 
			
		||||
         height="14"
 | 
			
		||||
         x="986.89801"
 | 
			
		||||
         y="675.86743"
 | 
			
		||||
         rx="0.49999979"
 | 
			
		||||
         ry="0.5" />
 | 
			
		||||
      <g
 | 
			
		||||
         id="g5320"
 | 
			
		||||
         transform="translate(402.77304,-12.882544)">
 | 
			
		||||
        <path
 | 
			
		||||
           id="path5322"
 | 
			
		||||
           d="m 595.125,692.53048 0,6.43903"
 | 
			
		||||
           style="fill:none;stroke:#666666;stroke-width:1.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
 | 
			
		||||
        <path
 | 
			
		||||
           id="path5324"
 | 
			
		||||
           d="m 598.34451,695.75 -6.43902,0"
 | 
			
		||||
           style="fill:none;stroke:#666666;stroke-width:1.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" />
 | 
			
		||||
      </g>
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 3.2 KiB  | 
@@ -260,44 +260,23 @@ StTooltip StLabel {
 | 
			
		||||
    spacing: 25px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.workspace-indicator-panel {
 | 
			
		||||
    spacing: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.workspace-indicator {
 | 
			
		||||
    width: 24px;
 | 
			
		||||
    height: 16px;
 | 
			
		||||
    background: rgba(255,255,255,0.2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.workspace-indicator.active {
 | 
			
		||||
    background: rgba(255,255,255,0.8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.workspace-controls {
 | 
			
		||||
    width: 48px;
 | 
			
		||||
    font-size: 32px;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    color: #ffffff;
 | 
			
		||||
    border: 2px solid rgba(128, 128, 128, 0.4);
 | 
			
		||||
    border: 1px solid #424242;
 | 
			
		||||
    border-right: 0px;
 | 
			
		||||
    border-radius: 9px 0px 0px 9px;
 | 
			
		||||
    background: #071524;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.add-workspace {
 | 
			
		||||
    background-color: rgba(128, 128, 128, 0.4);
 | 
			
		||||
.workspace-thumbnails {
 | 
			
		||||
    spacing: 7px;
 | 
			
		||||
    padding: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.add-workspace:hover {
 | 
			
		||||
    background-color: rgba(128, 128, 128, 0.6);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.remove-workspace {
 | 
			
		||||
    height: 48px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.remove-workspace:hover {
 | 
			
		||||
    background-color: rgba(128, 128, 128, 0.2);
 | 
			
		||||
.workspace-thumbnail-indicator {
 | 
			
		||||
    outline: 2px solid white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.window-caption {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,92 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="23"
 | 
			
		||||
   height="15"
 | 
			
		||||
   id="svg5501"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   inkscape:version="0.47pre4 r22446"
 | 
			
		||||
   sodipodi:docname="add-workspace.svg">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs5503">
 | 
			
		||||
    <inkscape:perspective
 | 
			
		||||
       sodipodi:type="inkscape:persp3d"
 | 
			
		||||
       inkscape:vp_x="0 : 16 : 1"
 | 
			
		||||
       inkscape:vp_y="0 : 1000 : 0"
 | 
			
		||||
       inkscape:vp_z="32 : 16 : 1"
 | 
			
		||||
       inkscape:persp3d-origin="16 : 10.666667 : 1"
 | 
			
		||||
       id="perspective5509" />
 | 
			
		||||
    <inkscape:perspective
 | 
			
		||||
       id="perspective5314"
 | 
			
		||||
       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
 | 
			
		||||
       inkscape:vp_z="1 : 0.5 : 1"
 | 
			
		||||
       inkscape:vp_y="0 : 1000 : 0"
 | 
			
		||||
       inkscape:vp_x="0 : 0.5 : 1"
 | 
			
		||||
       sodipodi:type="inkscape:persp3d" />
 | 
			
		||||
  </defs>
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="11.197802"
 | 
			
		||||
     inkscape:cx="-0.074583208"
 | 
			
		||||
     inkscape:cy="16"
 | 
			
		||||
     inkscape:current-layer="layer1"
 | 
			
		||||
     showgrid="true"
 | 
			
		||||
     inkscape:grid-bbox="true"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:window-width="1680"
 | 
			
		||||
     inkscape:window-height="997"
 | 
			
		||||
     inkscape:window-x="0"
 | 
			
		||||
     inkscape:window-y="26"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-grids="true"
 | 
			
		||||
     inkscape:snap-bbox="true" />
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata5506">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     inkscape:label="Layer 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     transform="translate(0,-17)">
 | 
			
		||||
    <g
 | 
			
		||||
       style="display:inline"
 | 
			
		||||
       id="g6239"
 | 
			
		||||
       transform="translate(-953.97989,-657.32287)">
 | 
			
		||||
      <rect
 | 
			
		||||
         style="fill:#000000;fill-opacity:0.98770495;stroke:#666666;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
 | 
			
		||||
         id="rect5318-6"
 | 
			
		||||
         width="22"
 | 
			
		||||
         height="14"
 | 
			
		||||
         x="954.5"
 | 
			
		||||
         y="675"
 | 
			
		||||
         rx="0.49999979"
 | 
			
		||||
         ry="0.5" />
 | 
			
		||||
      <path
 | 
			
		||||
         style="fill:none;stroke:#666666;stroke-width:1.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
 | 
			
		||||
         d="m 968.71951,682 -6.43902,0"
 | 
			
		||||
         id="path5324-5" />
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 2.9 KiB  | 
@@ -58,6 +58,7 @@ nobase_dist_js_DATA = 	\
 | 
			
		||||
	ui/windowAttentionHandler.js	\
 | 
			
		||||
	ui/windowManager.js	\
 | 
			
		||||
	ui/workspace.js		\
 | 
			
		||||
	ui/workspaceThumbnail.js	\
 | 
			
		||||
	ui/workspacesView.js	\
 | 
			
		||||
	ui/workspaceSwitcherPopup.js    \
 | 
			
		||||
	ui/xdndHandler.js
 | 
			
		||||
 
 | 
			
		||||
@@ -29,8 +29,8 @@ DocInfo.prototype = {
 | 
			
		||||
        return St.TextureCache.get_default().load_recent_thumbnail(size, this.recentInfo);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    launch : function() {
 | 
			
		||||
        Shell.DocSystem.get_default().open(this.recentInfo);
 | 
			
		||||
    launch : function(workspaceIndex) {
 | 
			
		||||
        Shell.DocSystem.get_default().open(this.recentInfo, workspaceIndex);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    matchTerms: function(terms) {
 | 
			
		||||
 
 | 
			
		||||
@@ -223,14 +223,20 @@ BaseAppSearchProvider.prototype = {
 | 
			
		||||
                 'icon': app.create_icon_texture(Search.RESULT_ICON_SIZE)};
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateResult: function(id) {
 | 
			
		||||
    activateResult: function(id, params) {
 | 
			
		||||
        params = Params.parse(params, { workspace: null,
 | 
			
		||||
                                        timestamp: null });
 | 
			
		||||
 | 
			
		||||
        let app = this._appSys.get_app(id);
 | 
			
		||||
        app.activate();
 | 
			
		||||
        app.activate(params.workspace ? params.workspace.index() : -1);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    dragActivateResult: function(id) {
 | 
			
		||||
    dragActivateResult: function(id, params) {
 | 
			
		||||
        params = Params.parse(params, { workspace: null,
 | 
			
		||||
                                        timestamp: null });
 | 
			
		||||
 | 
			
		||||
        let app = this._appSys.get_app(id);
 | 
			
		||||
        app.open_new_window();
 | 
			
		||||
        app.open_new_window(params.workspace ? params.workspace.get_index() : -1);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -397,7 +403,7 @@ AppWellIcon.prototype = {
 | 
			
		||||
            if (newWorkspace != null) {
 | 
			
		||||
                newWorkspace.activate(global.get_current_time());
 | 
			
		||||
                this.emit('launching');
 | 
			
		||||
                this.app.open_new_window();
 | 
			
		||||
                this.app.open_new_window(-1);
 | 
			
		||||
                Main.overview.hide();
 | 
			
		||||
            }
 | 
			
		||||
        } else if (button == 3) {
 | 
			
		||||
@@ -485,9 +491,9 @@ AppWellIcon.prototype = {
 | 
			
		||||
 | 
			
		||||
        if (modifiers & Clutter.ModifierType.CONTROL_MASK
 | 
			
		||||
            && this.app.state == Shell.AppState.RUNNING) {
 | 
			
		||||
            this.app.open_new_window();
 | 
			
		||||
            this.app.open_new_window(-1);
 | 
			
		||||
        } else {
 | 
			
		||||
            this.app.activate();
 | 
			
		||||
            this.app.activate(-1);
 | 
			
		||||
        }
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
    },
 | 
			
		||||
@@ -497,8 +503,11 @@ AppWellIcon.prototype = {
 | 
			
		||||
        return this._menu.menuEventFilter(event);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    shellWorkspaceLaunch : function() {
 | 
			
		||||
        this.app.open_new_window();
 | 
			
		||||
    shellWorkspaceLaunch : function(params) {
 | 
			
		||||
        params = Params.parse(params, { workspace: null,
 | 
			
		||||
                                        timestamp: null });
 | 
			
		||||
 | 
			
		||||
        this.app.open_new_window(params.workspace ? params.workspace.index() : -1);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getDragActor: function() {
 | 
			
		||||
@@ -630,7 +639,7 @@ AppIconMenu.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _findMetaWindowForActor: function (actor) {
 | 
			
		||||
        if (actor._delegate instanceof Workspace.WindowClone)
 | 
			
		||||
        if (actor._delegate.metaWindow)
 | 
			
		||||
            return actor._delegate.metaWindow;
 | 
			
		||||
        else if (actor.get_meta_window)
 | 
			
		||||
            return actor.get_meta_window();
 | 
			
		||||
@@ -667,7 +676,7 @@ AppIconMenu.prototype = {
 | 
			
		||||
            let metaWindow = child._window;
 | 
			
		||||
            this.emit('activate-window', metaWindow);
 | 
			
		||||
        } else if (child == this._newWindowMenuItem) {
 | 
			
		||||
            this._source.app.open_new_window();
 | 
			
		||||
            this._source.app.open_new_window(-1);
 | 
			
		||||
            this.emit('activate-window', null);
 | 
			
		||||
        } else if (child == this._toggleFavoriteMenuItem) {
 | 
			
		||||
            let favs = AppFavorites.getAppFavorites();
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,7 @@ RemoveFavoriteIcon.prototype = {
 | 
			
		||||
        if (source instanceof AppDisplay.AppWellIcon) {
 | 
			
		||||
            let appSystem = Shell.AppSystem.get_default();
 | 
			
		||||
            app = appSystem.get_app(source.getId());
 | 
			
		||||
        } else if (source instanceof Workspace.WindowClone) {
 | 
			
		||||
        } else if (source.metaWindow) {
 | 
			
		||||
            let tracker = Shell.WindowTracker.get_default();
 | 
			
		||||
            app = tracker.get_window_app(source.metaWindow);
 | 
			
		||||
        }
 | 
			
		||||
@@ -148,7 +148,7 @@ Dash.prototype = {
 | 
			
		||||
        let app = null;
 | 
			
		||||
        if (dragEvent.source instanceof AppDisplay.AppWellIcon)
 | 
			
		||||
            app = this._appSystem.get_app(dragEvent.source.getId());
 | 
			
		||||
        else if (dragEvent.source instanceof Workspace.WindowClone)
 | 
			
		||||
        else if (dragEvent.source.metaWindow)
 | 
			
		||||
            app = this._tracker.get_window_app(dragEvent.source.metaWindow);
 | 
			
		||||
        else
 | 
			
		||||
            return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
@@ -265,7 +265,7 @@ Dash.prototype = {
 | 
			
		||||
        let app = null;
 | 
			
		||||
        if (source instanceof AppDisplay.AppWellIcon)
 | 
			
		||||
            app = this._appSystem.get_app(source.getId());
 | 
			
		||||
        else if (source instanceof Workspace.WindowClone)
 | 
			
		||||
        else if (source.metaWindow)
 | 
			
		||||
            app = this._tracker.get_window_app(source.metaWindow);
 | 
			
		||||
 | 
			
		||||
        // Don't allow favoriting of transient apps
 | 
			
		||||
@@ -316,7 +316,7 @@ Dash.prototype = {
 | 
			
		||||
        let app = null;
 | 
			
		||||
        if (source instanceof AppDisplay.AppWellIcon) {
 | 
			
		||||
            app = this._appSystem.get_app(source.getId());
 | 
			
		||||
        } else if (source instanceof Workspace.WindowClone) {
 | 
			
		||||
        } else if (source.metaWindow) {
 | 
			
		||||
            app = this._tracker.get_window_app(source.metaWindow);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										46
									
								
								js/ui/dnd.js
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								js/ui/dnd.js
									
									
									
									
									
								
							@@ -101,6 +101,12 @@ _Draggable.prototype = {
 | 
			
		||||
        this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
 | 
			
		||||
        this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
 | 
			
		||||
 | 
			
		||||
        // During the drag, we eat enter/leave events so that actors don't prelight or show
 | 
			
		||||
        // tooltips. But we remember the relevant events (first leave, last enter) so we can
 | 
			
		||||
        // fix up the hover state after the drag ends.
 | 
			
		||||
        this._firstLeaveEvent = null;
 | 
			
		||||
        this._lastEnterEvent = null;
 | 
			
		||||
 | 
			
		||||
        this._eventsGrabbed = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -198,6 +204,11 @@ _Draggable.prototype = {
 | 
			
		||||
                this._cancelDrag(event.get_time());
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        } else if (event.type() == Clutter.EventType.LEAVE) {
 | 
			
		||||
            if (this._firstLeaveEvent == null)
 | 
			
		||||
                this._firstLeaveEvent = event;
 | 
			
		||||
        } else if (event.type() == Clutter.EventType.ENTER) {
 | 
			
		||||
            this._lastEnterEvent = event;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
@@ -485,7 +496,7 @@ _Draggable.prototype = {
 | 
			
		||||
        if (this._actorDestroyed) {
 | 
			
		||||
            global.unset_cursor();
 | 
			
		||||
            if (!this._buttonDown)
 | 
			
		||||
                this._ungrabEvents();
 | 
			
		||||
                this._dragComplete();
 | 
			
		||||
            this.emit('drag-end', eventTime, false);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -542,12 +553,41 @@ _Draggable.prototype = {
 | 
			
		||||
            this._dragComplete();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Actor is an actor we might have entered or left during the drag; call
 | 
			
		||||
    // st_widget_sync_hover on all StWidget ancestors
 | 
			
		||||
    _syncHover: function(actor) {
 | 
			
		||||
        // If the actor was reparented from its original location and
 | 
			
		||||
        // destroyed, then start syncing hover at the original parent
 | 
			
		||||
        if (actor == this._dragActor && this._actorDestroyed)
 | 
			
		||||
            actor = this._dragOrigParent;
 | 
			
		||||
 | 
			
		||||
        while (actor) {
 | 
			
		||||
            let parent = actor.get_parent();
 | 
			
		||||
            if (actor instanceof St.Widget)
 | 
			
		||||
                actor.sync_hover();
 | 
			
		||||
 | 
			
		||||
            actor = parent;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _dragComplete: function() {
 | 
			
		||||
        Shell.util_set_hidden_from_pick(this._dragActor, false);
 | 
			
		||||
        if (!this._actorDestroyed)
 | 
			
		||||
            Shell.util_set_hidden_from_pick(this._dragActor, false);
 | 
			
		||||
 | 
			
		||||
        this._ungrabEvents();
 | 
			
		||||
 | 
			
		||||
        if (this._firstLeaveEvent) {
 | 
			
		||||
            this._syncHover(this._firstLeaveEvent.get_source());
 | 
			
		||||
            this._firstLeaveEvent = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._lastEnterEvent) {
 | 
			
		||||
            this._syncHover(this._lastEnterEvent.get_source());
 | 
			
		||||
            this._lastEnterEvent = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._dragActor = undefined;
 | 
			
		||||
        currentDraggable = null;
 | 
			
		||||
        this._ungrabEvents();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ const Gettext = imports.gettext.domain('gnome-shell');
 | 
			
		||||
const _ = Gettext.gettext;
 | 
			
		||||
 | 
			
		||||
const DocInfo = imports.misc.docInfo;
 | 
			
		||||
const Params = imports.misc.params;
 | 
			
		||||
const Search = imports.ui.search;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -28,9 +29,12 @@ DocSearchProvider.prototype = {
 | 
			
		||||
                 'icon': docInfo.createIcon(Search.RESULT_ICON_SIZE)};
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateResult: function(id) {
 | 
			
		||||
    activateResult: function(id, params) {
 | 
			
		||||
        params = Params.parse(params, { workspace: null,
 | 
			
		||||
                                        timestamp: null });
 | 
			
		||||
 | 
			
		||||
        let docInfo = this._docManager.lookupByUri(id);
 | 
			
		||||
        docInfo.launch();
 | 
			
		||||
        docInfo.launch(params.workspace ? params.workspace.index() : -1);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getInitialResultSet: function(terms) {
 | 
			
		||||
 
 | 
			
		||||
@@ -171,7 +171,7 @@ ListItem.prototype = {
 | 
			
		||||
 | 
			
		||||
    _onClicked: function() {
 | 
			
		||||
        this.emit('activate');
 | 
			
		||||
        this._app.activate();
 | 
			
		||||
        this._app.activate(-1);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(ListItem.prototype);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										129
									
								
								js/ui/main.js
									
									
									
									
									
								
							
							
						
						
									
										129
									
								
								js/ui/main.js
									
									
									
									
									
								
							@@ -175,6 +175,8 @@ function start() {
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT, false, -1, 1);
 | 
			
		||||
 | 
			
		||||
    // Provide the bus object for gnome-session to
 | 
			
		||||
    // initiate logouts.
 | 
			
		||||
    EndSessionDialog.init();
 | 
			
		||||
@@ -197,14 +199,103 @@ function start() {
 | 
			
		||||
    _log('info', 'loaded at ' + _startDate);
 | 
			
		||||
    log('GNOME Shell started at ' + _startDate);
 | 
			
		||||
 | 
			
		||||
    Mainloop.idle_add(_removeUnusedWorkspaces);
 | 
			
		||||
 | 
			
		||||
    let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
 | 
			
		||||
    if (perfModuleName) {
 | 
			
		||||
        let perfOutput = GLib.getenv("SHELL_PERF_OUTPUT");
 | 
			
		||||
        let module = eval('imports.perf.' + perfModuleName + ';');
 | 
			
		||||
        Scripting.runPerfScript(module, perfOutput);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    global.screen.connect('notify::n-workspaces', _nWorkspacesChanged);
 | 
			
		||||
    Mainloop.idle_add(_nWorkspacesChanged);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let _workspaces = [];
 | 
			
		||||
let _checkWorkspacesId = 0;
 | 
			
		||||
 | 
			
		||||
function _checkWorkspaces() {
 | 
			
		||||
    let i;
 | 
			
		||||
    let emptyWorkspaces = [];
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < _workspaces.length; i++)
 | 
			
		||||
        emptyWorkspaces[i] = true;
 | 
			
		||||
 | 
			
		||||
    let windows = global.get_window_actors();
 | 
			
		||||
    for (i = 0; i < windows.length; i++) {
 | 
			
		||||
        let win = windows[i];
 | 
			
		||||
 | 
			
		||||
        if (win.get_meta_window().is_on_all_workspaces())
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        let workspaceIndex = win.get_workspace();
 | 
			
		||||
        emptyWorkspaces[workspaceIndex] = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we don't have an empty workspace at the end, add one
 | 
			
		||||
    if (!emptyWorkspaces[emptyWorkspaces.length -1]) {
 | 
			
		||||
        global.screen.append_new_workspace(false, global.get_current_time());
 | 
			
		||||
        emptyWorkspaces.push(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Delete other empty workspaces; do it from the end to avoid index changes
 | 
			
		||||
    for (i = emptyWorkspaces.length - 2; i >= 0; i--) {
 | 
			
		||||
        if (emptyWorkspaces[i])
 | 
			
		||||
            global.screen.remove_workspace(_workspaces[i], global.get_current_time());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _checkWorkspacesId = 0;
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _queueCheckWorkspaces() {
 | 
			
		||||
    if (_checkWorkspacesId == 0)
 | 
			
		||||
        _checkWorkspacesId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, _checkWorkspaces);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _nWorkspacesChanged() {
 | 
			
		||||
    let oldNumWorkspaces = _workspaces.length;
 | 
			
		||||
    let newNumWorkspaces = global.screen.n_workspaces;
 | 
			
		||||
 | 
			
		||||
    if (oldNumWorkspaces == newNumWorkspaces)
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    let lostWorkspaces = [];
 | 
			
		||||
    if (newNumWorkspaces > oldNumWorkspaces) {
 | 
			
		||||
        let w;
 | 
			
		||||
 | 
			
		||||
        // Assume workspaces are only added at the end
 | 
			
		||||
        for (w = oldNumWorkspaces; w < newNumWorkspaces; w++)
 | 
			
		||||
            _workspaces[w] = global.screen.get_workspace_by_index(w);
 | 
			
		||||
 | 
			
		||||
        for (w = oldNumWorkspaces; w < newNumWorkspaces; w++) {
 | 
			
		||||
            let workspace = _workspaces[w];
 | 
			
		||||
            workspace._windowAddedId = workspace.connect('window-added', _queueCheckWorkspaces);
 | 
			
		||||
            workspace._windowRemovedId = workspace.connect('window-removed', _queueCheckWorkspaces);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
        // Assume workspaces are only removed sequentially
 | 
			
		||||
        // (e.g. 2,3,4 - not 2,4,7)
 | 
			
		||||
        let removedIndex;
 | 
			
		||||
        let removedNum = oldNumWorkspaces - newNumWorkspaces;
 | 
			
		||||
        for (let w = 0; w < oldNumWorkspaces; w++) {
 | 
			
		||||
            let workspace = global.screen.get_workspace_by_index(w);
 | 
			
		||||
            if (_workspaces[w] != workspace) {
 | 
			
		||||
                removedIndex = w;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let lostWorkspaces = _workspaces.splice(removedIndex, removedNum);
 | 
			
		||||
        lostWorkspaces.forEach(function(workspace) {
 | 
			
		||||
                                   workspace.disconnect(workspace._windowAddedId);
 | 
			
		||||
                                   workspace.disconnect(workspace._windowRemovedId);
 | 
			
		||||
                               });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _queueCheckWorkspaces();
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -301,34 +392,6 @@ function _relayout() {
 | 
			
		||||
    overview.hide();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// metacity-clutter currently uses the same prefs as plain metacity,
 | 
			
		||||
// which probably means we'll be starting out with multiple workspaces;
 | 
			
		||||
// remove any unused ones. (We do this from an idle handler, because
 | 
			
		||||
// global.get_window_actors() still returns NULL at the point when start()
 | 
			
		||||
// is called.)
 | 
			
		||||
function _removeUnusedWorkspaces() {
 | 
			
		||||
 | 
			
		||||
    let windows = global.get_window_actors();
 | 
			
		||||
    let maxWorkspace = 0;
 | 
			
		||||
    for (let i = 0; i < windows.length; i++) {
 | 
			
		||||
        let win = windows[i];
 | 
			
		||||
 | 
			
		||||
        if (!win.get_meta_window().is_on_all_workspaces() &&
 | 
			
		||||
            win.get_workspace() > maxWorkspace) {
 | 
			
		||||
            maxWorkspace = win.get_workspace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    let screen = global.screen;
 | 
			
		||||
    if (screen.n_workspaces > maxWorkspace) {
 | 
			
		||||
        for (let w = screen.n_workspaces - 1; w > maxWorkspace; w--) {
 | 
			
		||||
            let workspace = screen.get_workspace_by_index(w);
 | 
			
		||||
            screen.remove_workspace(workspace, 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This function encapsulates hacks to make certain global keybindings
 | 
			
		||||
// work even when we are in one of our modes where global keybindings
 | 
			
		||||
// are disabled with a global grab. (When there is a global grab, then
 | 
			
		||||
@@ -376,6 +439,12 @@ function _globalKeyPressHandler(actor, event) {
 | 
			
		||||
        case Meta.KeyBindingAction.WORKSPACE_RIGHT:
 | 
			
		||||
            wm.actionMoveWorkspaceRight();
 | 
			
		||||
            return true;
 | 
			
		||||
        case Meta.KeyBindingAction.WORKSPACE_UP:
 | 
			
		||||
            wm.actionMoveWorkspaceUp();
 | 
			
		||||
            return true;
 | 
			
		||||
        case Meta.KeyBindingAction.WORKSPACE_DOWN:
 | 
			
		||||
            wm.actionMoveWorkspaceDown();
 | 
			
		||||
            return true;
 | 
			
		||||
        case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
 | 
			
		||||
        case Meta.KeyBindingAction.COMMAND_2:
 | 
			
		||||
            getRunDialog().open();
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ const _ = Gettext.gettext;
 | 
			
		||||
 | 
			
		||||
const DND = imports.ui.dnd;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const Params = imports.misc.params;
 | 
			
		||||
const Search = imports.ui.search;
 | 
			
		||||
const Util = imports.misc.util;
 | 
			
		||||
 | 
			
		||||
@@ -58,6 +59,21 @@ PlaceInfo.prototype = {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Helper function to translate launch parameters into a GAppLaunchContext
 | 
			
		||||
function _makeLaunchContext(params)
 | 
			
		||||
{
 | 
			
		||||
    params = Params.parse(params, { workspace: null,
 | 
			
		||||
                                    timestamp: null });
 | 
			
		||||
 | 
			
		||||
    let launchContext = global.create_app_launch_context();
 | 
			
		||||
    if (params.workspace != null)
 | 
			
		||||
        launchContext.set_desktop(params.workspace.index());
 | 
			
		||||
    if (params.timestamp != null)
 | 
			
		||||
        launchContext.set_timestamp(params.timestamp);
 | 
			
		||||
 | 
			
		||||
    return launchContext;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function PlaceDeviceInfo(mount) {
 | 
			
		||||
    this._init(mount);
 | 
			
		||||
}
 | 
			
		||||
@@ -77,9 +93,9 @@ PlaceDeviceInfo.prototype = {
 | 
			
		||||
        return St.TextureCache.get_default().load_gicon(null, icon, size);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    launch: function() {
 | 
			
		||||
    launch: function(param) {
 | 
			
		||||
        Gio.app_info_launch_default_for_uri(this._mount.get_root().get_uri(),
 | 
			
		||||
                                            global.create_app_launch_context());
 | 
			
		||||
                                            _makeLaunchContex(params));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    isRemovable: function() {
 | 
			
		||||
@@ -111,7 +127,6 @@ PlaceDeviceInfo.prototype = {
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function PlacesManager() {
 | 
			
		||||
    this._init();
 | 
			
		||||
}
 | 
			
		||||
@@ -130,8 +145,8 @@ PlacesManager.prototype = {
 | 
			
		||||
            function(size) {
 | 
			
		||||
                return St.TextureCache.get_default().load_gicon(null, homeIcon, size);
 | 
			
		||||
            },
 | 
			
		||||
            function() {
 | 
			
		||||
                Gio.app_info_launch_default_for_uri(homeUri, global.create_app_launch_context());
 | 
			
		||||
            function(params) {
 | 
			
		||||
                Gio.app_info_launch_default_for_uri(homeUri, _makeLaunchContext(params));
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        let desktopPath = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP);
 | 
			
		||||
@@ -143,8 +158,8 @@ PlacesManager.prototype = {
 | 
			
		||||
            function(size) {
 | 
			
		||||
                return St.TextureCache.get_default().load_gicon(null, desktopIcon, size);
 | 
			
		||||
            },
 | 
			
		||||
            function() {
 | 
			
		||||
                Gio.app_info_launch_default_for_uri(desktopUri, global.create_app_launch_context());
 | 
			
		||||
            function(params) {
 | 
			
		||||
                Gio.app_info_launch_default_for_uri(desktopUri, _makeLaunchContext(params));
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        this._connect = new PlaceInfo('special:connect', _("Connect to..."),
 | 
			
		||||
@@ -153,7 +168,11 @@ PlacesManager.prototype = {
 | 
			
		||||
                                     icon_type: St.IconType.FULLCOLOR,
 | 
			
		||||
                                     icon_size: size });
 | 
			
		||||
            },
 | 
			
		||||
            function () {
 | 
			
		||||
            function (params) {
 | 
			
		||||
                // BUG: nautilus-connect-server doesn't have a desktop file, so we can'
 | 
			
		||||
                // launch it with the workspace from params. It's probably pretty rare
 | 
			
		||||
                // and odd to drag this place onto a workspace in any case
 | 
			
		||||
 | 
			
		||||
                Util.spawn(['nautilus-connect-server']);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
@@ -173,8 +192,12 @@ PlacesManager.prototype = {
 | 
			
		||||
                function(size) {
 | 
			
		||||
                    return networkApp.create_icon_texture(size);
 | 
			
		||||
                },
 | 
			
		||||
                function () {
 | 
			
		||||
                    networkApp.launch();
 | 
			
		||||
                function (params) {
 | 
			
		||||
                    params = Params.parse(params, { workspace: null,
 | 
			
		||||
                                                    timestamp: 0 });
 | 
			
		||||
 | 
			
		||||
                    networkApp.launch_full(params.timestamp, [],
 | 
			
		||||
                                           params.workspace ? params.workspace.index() : -1);
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -314,8 +337,8 @@ PlacesManager.prototype = {
 | 
			
		||||
                function(size) {
 | 
			
		||||
                    return St.TextureCache.get_default().load_gicon(null, icon, size);
 | 
			
		||||
                },
 | 
			
		||||
                function() {
 | 
			
		||||
                    Gio.app_info_launch_default_for_uri(bookmark, global.create_app_launch_context());
 | 
			
		||||
                function(params) {
 | 
			
		||||
                    Gio.app_info_launch_default_for_uri(bookmark, _makeLaunchContext(params));
 | 
			
		||||
                });
 | 
			
		||||
            this._bookmarks.push(item);
 | 
			
		||||
        }
 | 
			
		||||
@@ -395,9 +418,9 @@ PlaceSearchProvider.prototype = {
 | 
			
		||||
                 'icon': placeInfo.iconFactory(Search.RESULT_ICON_SIZE) };
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateResult: function(id) {
 | 
			
		||||
    activateResult: function(id, params) {
 | 
			
		||||
        let placeInfo = Main.placesManager.lookupPlaceById(id);
 | 
			
		||||
        placeInfo.launch();
 | 
			
		||||
        placeInfo.launch(params);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _compareResultMeta: function (idA, idB) {
 | 
			
		||||
 
 | 
			
		||||
@@ -267,7 +267,7 @@ OpenSearchSystem.prototype = {
 | 
			
		||||
        return lang != null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateResult: function(id) {
 | 
			
		||||
    activateResult: function(id, params) {
 | 
			
		||||
        let searchTerms = this._terms.join(' ');
 | 
			
		||||
 | 
			
		||||
        let url = this._providers[id].url.replace('{searchTerms}', encodeURIComponent(searchTerms));
 | 
			
		||||
 
 | 
			
		||||
@@ -81,11 +81,11 @@ SearchResult.prototype = {
 | 
			
		||||
        return new Clutter.Clone({ source: this.metaInfo['icon'] });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    shellWorkspaceLaunch: function() {
 | 
			
		||||
    shellWorkspaceLaunch: function(params) {
 | 
			
		||||
        if (this.provider.dragActivateResult)
 | 
			
		||||
            this.provider.dragActivateResult(this.metaInfo.id);
 | 
			
		||||
            this.provider.dragActivateResult(this.metaInfo.id, params);
 | 
			
		||||
        else
 | 
			
		||||
            this.provider.activateResult(this.metaInfo.id);
 | 
			
		||||
            this.provider.activateResult(this.metaInfo.id, params);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -525,23 +525,20 @@ WindowManager.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _showWorkspaceSwitcher : function(shellwm, binding, window, backwards) {
 | 
			
		||||
        /* We don't support this kind of layout */
 | 
			
		||||
        if (binding == 'switch_to_workspace_up' || binding == 'switch_to_workspace_down')
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (global.screen.n_workspaces == 1)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (this._workspaceSwitcherPopup == null)
 | 
			
		||||
            this._workspaceSwitcherPopup = new WorkspaceSwitcherPopup.WorkspaceSwitcherPopup();
 | 
			
		||||
 | 
			
		||||
        if (binding == 'switch_to_workspace_left') {
 | 
			
		||||
        if (binding == 'switch_to_workspace_left')
 | 
			
		||||
            this.actionMoveWorkspaceLeft();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (binding == 'switch_to_workspace_right') {
 | 
			
		||||
        else if (binding == 'switch_to_workspace_right')
 | 
			
		||||
            this.actionMoveWorkspaceRight();
 | 
			
		||||
        }
 | 
			
		||||
        else if (binding == 'switch_to_workspace_up')
 | 
			
		||||
            this.actionMoveWorkspaceUp();
 | 
			
		||||
        else if (binding == 'switch_to_workspace_down')
 | 
			
		||||
            this.actionMoveWorkspaceDown();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    actionMoveWorkspaceLeft: function() {
 | 
			
		||||
@@ -572,6 +569,32 @@ WindowManager.prototype = {
 | 
			
		||||
        if (indexToActivate != activeWorkspaceIndex)
 | 
			
		||||
            global.screen.get_workspace_by_index(indexToActivate).activate(global.get_current_time());
 | 
			
		||||
 | 
			
		||||
        if (!Main.overview.visible)
 | 
			
		||||
            this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.RIGHT, indexToActivate);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    actionMoveWorkspaceUp: function() {
 | 
			
		||||
        let activeWorkspaceIndex = global.screen.get_active_workspace_index();
 | 
			
		||||
        let indexToActivate = activeWorkspaceIndex;
 | 
			
		||||
        if (activeWorkspaceIndex > 0)
 | 
			
		||||
            indexToActivate--;
 | 
			
		||||
 | 
			
		||||
        if (indexToActivate != activeWorkspaceIndex)
 | 
			
		||||
            global.screen.get_workspace_by_index(indexToActivate).activate(global.get_current_time());
 | 
			
		||||
 | 
			
		||||
        if (!Main.overview.visible)
 | 
			
		||||
            this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.LEFT, indexToActivate);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    actionMoveWorkspaceDown: function() {
 | 
			
		||||
        let activeWorkspaceIndex = global.screen.get_active_workspace_index();
 | 
			
		||||
        let indexToActivate = activeWorkspaceIndex;
 | 
			
		||||
        if (activeWorkspaceIndex < global.screen.n_workspaces - 1)
 | 
			
		||||
            indexToActivate++;
 | 
			
		||||
 | 
			
		||||
        if (indexToActivate != activeWorkspaceIndex)
 | 
			
		||||
            global.screen.get_workspace_by_index(indexToActivate).activate(global.get_current_time());
 | 
			
		||||
 | 
			
		||||
        if (!Main.overview.visible)
 | 
			
		||||
            this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.RIGHT, indexToActivate);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1402,7 +1402,7 @@ Workspace.prototype = {
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    acceptDrop : function(source, actor, x, y, time) {
 | 
			
		||||
        if (source instanceof WindowClone) {
 | 
			
		||||
        if (source.realWindow) {
 | 
			
		||||
            let win = source.realWindow;
 | 
			
		||||
            if (this._isMyWindow(win))
 | 
			
		||||
                return false;
 | 
			
		||||
@@ -1421,8 +1421,8 @@ Workspace.prototype = {
 | 
			
		||||
                                                 time);
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if (source.shellWorkspaceLaunch) {
 | 
			
		||||
            this.metaWorkspace.activate(time);
 | 
			
		||||
            source.shellWorkspaceLaunch();
 | 
			
		||||
            source.shellWorkspaceLaunch({ workspace: this.metaWorkspace,
 | 
			
		||||
                                          timestamp: time });
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										310
									
								
								js/ui/workspaceThumbnail.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										310
									
								
								js/ui/workspaceThumbnail.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,310 @@
 | 
			
		||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 | 
			
		||||
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const Lang = imports.lang;
 | 
			
		||||
const Mainloop = imports.mainloop;
 | 
			
		||||
const Shell = imports.gi.Shell;
 | 
			
		||||
const Signals = imports.signals;
 | 
			
		||||
const St = imports.gi.St;
 | 
			
		||||
 | 
			
		||||
const DND = imports.ui.dnd;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
const Workspace = imports.ui.workspace;
 | 
			
		||||
 | 
			
		||||
// Fraction of original screen size for thumbnails
 | 
			
		||||
let THUMBNAIL_SCALE = 1/8.;
 | 
			
		||||
 | 
			
		||||
function WindowClone(realWindow) {
 | 
			
		||||
    this._init(realWindow);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WindowClone.prototype = {
 | 
			
		||||
    _init : function(realWindow) {
 | 
			
		||||
        this.actor = new Clutter.Clone({ source: realWindow.get_texture(),
 | 
			
		||||
                                         clip_to_allocation: true,
 | 
			
		||||
                                         reactive: true });
 | 
			
		||||
        this.actor._delegate = this;
 | 
			
		||||
        this.realWindow = realWindow;
 | 
			
		||||
        this.metaWindow = realWindow.meta_window;
 | 
			
		||||
        this.metaWindow._delegate = this;
 | 
			
		||||
 | 
			
		||||
        this._positionChangedId = this.realWindow.connect('position-changed',
 | 
			
		||||
                                                          Lang.bind(this, this._onPositionChanged));
 | 
			
		||||
        this._onPositionChanged();
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('button-release-event',
 | 
			
		||||
                           Lang.bind(this, this._onButtonRelease));
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
 | 
			
		||||
 | 
			
		||||
        this._draggable = DND.makeDraggable(this.actor,
 | 
			
		||||
                                            { restoreOnSuccess: true,
 | 
			
		||||
                                              dragActorMaxSize: Workspace.WINDOW_DND_SIZE,
 | 
			
		||||
                                              dragActorOpacity: Workspace.DRAGGING_WINDOW_OPACITY });
 | 
			
		||||
        this._draggable.connect('drag-begin', Lang.bind(this, this._onDragBegin));
 | 
			
		||||
        this._draggable.connect('drag-end', Lang.bind(this, this._onDragEnd));
 | 
			
		||||
        this.inDrag = false;
 | 
			
		||||
 | 
			
		||||
        this._selected = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setStackAbove: function (actor) {
 | 
			
		||||
        this._stackAbove = actor;
 | 
			
		||||
        if (this._stackAbove == null)
 | 
			
		||||
            this.actor.lower_bottom();
 | 
			
		||||
        else
 | 
			
		||||
            this.actor.raise(this._stackAbove);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy: function () {
 | 
			
		||||
        this.actor.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onPositionChanged: function() {
 | 
			
		||||
        let rect = this.metaWindow.get_outer_rect();
 | 
			
		||||
        this.actor.set_position(this.realWindow.x, this.realWindow.y);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy: function() {
 | 
			
		||||
        this.metaWindow._delegate = null;
 | 
			
		||||
        this.actor._delegate = null;
 | 
			
		||||
 | 
			
		||||
        if (this._positionChangedId != 0) {
 | 
			
		||||
            this.realWindow.disconnect(this._positionChangedId);
 | 
			
		||||
            this._positionChangedId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.inDrag) {
 | 
			
		||||
            this.emit('drag-end');
 | 
			
		||||
            this.inDrag = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.disconnectAll();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onButtonRelease : function (actor, event) {
 | 
			
		||||
        this._selected = true;
 | 
			
		||||
        this.emit('selected', event.get_time());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragBegin : function (draggable, time) {
 | 
			
		||||
        this.inDrag = true;
 | 
			
		||||
        this.emit('drag-begin');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDragEnd : function (draggable, time, snapback) {
 | 
			
		||||
        this.inDrag = false;
 | 
			
		||||
 | 
			
		||||
        // We may not have a parent if DnD completed successfully, in
 | 
			
		||||
        // which case our clone will shortly be destroyed and replaced
 | 
			
		||||
        // with a new one on the target workspace.
 | 
			
		||||
        if (this.actor.get_parent() != null) {
 | 
			
		||||
            if (this._stackAbove == null)
 | 
			
		||||
                this.actor.lower_bottom();
 | 
			
		||||
            else
 | 
			
		||||
                this.actor.raise(this._stackAbove);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        this.emit('drag-end');
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
Signals.addSignalMethods(WindowClone.prototype);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @metaWorkspace: a #Meta.Workspace
 | 
			
		||||
 */
 | 
			
		||||
function WorkspaceThumbnail(metaWorkspace) {
 | 
			
		||||
    this._init(metaWorkspace);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WorkspaceThumbnail.prototype = {
 | 
			
		||||
    _init : function(metaWorkspace) {
 | 
			
		||||
        // When dragging a window, we use this slot for reserve space.
 | 
			
		||||
        this.metaWorkspace = metaWorkspace;
 | 
			
		||||
 | 
			
		||||
        this.actor = new St.Bin({ reactive: true,
 | 
			
		||||
                                  style_class: 'workspace-thumbnail' });
 | 
			
		||||
        this.actor._delegate = this;
 | 
			
		||||
 | 
			
		||||
        this._group = new Clutter.Group();
 | 
			
		||||
        this.actor.add_actor(this._group);
 | 
			
		||||
 | 
			
		||||
        this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
 | 
			
		||||
        this.actor.connect('button-press-event', Lang.bind(this,
 | 
			
		||||
            function(actor, event) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }));
 | 
			
		||||
        this.actor.connect('button-release-event', Lang.bind(this,
 | 
			
		||||
            function(actor, event) {
 | 
			
		||||
                this.metaWorkspace.activate(event.get_time());
 | 
			
		||||
                return true;
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        this._background = new Clutter.Clone({ source: global.background_actor });
 | 
			
		||||
        this._group.add_actor(this._background);
 | 
			
		||||
 | 
			
		||||
        this._group.set_size(THUMBNAIL_SCALE * global.screen_width, THUMBNAIL_SCALE * global.screen_height);
 | 
			
		||||
        this._group.set_scale(THUMBNAIL_SCALE, THUMBNAIL_SCALE);
 | 
			
		||||
 | 
			
		||||
        let windows = global.get_window_actors().filter(this._isMyWindow, this);
 | 
			
		||||
 | 
			
		||||
        // Create clones for windows that should be visible in the Overview
 | 
			
		||||
        this._windows = [];
 | 
			
		||||
        for (let i = 0; i < windows.length; i++) {
 | 
			
		||||
            if (this._isOverviewWindow(windows[i])) {
 | 
			
		||||
                this._addWindowClone(windows[i]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Track window changes
 | 
			
		||||
        this._windowAddedId = this.metaWorkspace.connect('window-added',
 | 
			
		||||
                                                          Lang.bind(this, this._windowAdded));
 | 
			
		||||
        this._windowRemovedId = this.metaWorkspace.connect('window-removed',
 | 
			
		||||
                                                           Lang.bind(this, this._windowRemoved));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _lookupIndex: function (metaWindow) {
 | 
			
		||||
        for (let i = 0; i < this._windows.length; i++) {
 | 
			
		||||
            if (this._windows[i].metaWindow == metaWindow) {
 | 
			
		||||
                return i;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return -1;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    syncStacking: function(stackIndices) {
 | 
			
		||||
        this._windows.sort(function (a, b) { return stackIndices[a.metaWindow.get_stable_sequence()] - stackIndices[b.metaWindow.get_stable_sequence()]; });
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < this._windows.length; i++) {
 | 
			
		||||
            let clone = this._windows[i];
 | 
			
		||||
            let metaWindow = clone.metaWindow;
 | 
			
		||||
            if (i == 0) {
 | 
			
		||||
                clone.setStackAbove(this._background);
 | 
			
		||||
            } else {
 | 
			
		||||
                let previousClone = this._windows[i - 1];
 | 
			
		||||
                clone.setStackAbove(previousClone.actor);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowRemoved : function(metaWorkspace, metaWin) {
 | 
			
		||||
        let win = metaWin.get_compositor_private();
 | 
			
		||||
 | 
			
		||||
        // find the position of the window in our list
 | 
			
		||||
        let index = this._lookupIndex (metaWin);
 | 
			
		||||
 | 
			
		||||
        if (index == -1)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let clone = this._windows[index];
 | 
			
		||||
        this._windows.splice(index, 1);
 | 
			
		||||
        clone.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _windowAdded : function(metaWorkspace, metaWin) {
 | 
			
		||||
        if (this.leavingOverview)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let win = metaWin.get_compositor_private();
 | 
			
		||||
 | 
			
		||||
        if (!win) {
 | 
			
		||||
            // Newly-created windows are added to a workspace before
 | 
			
		||||
            // the compositor finds out about them...
 | 
			
		||||
            Mainloop.idle_add(Lang.bind(this,
 | 
			
		||||
                                        function () {
 | 
			
		||||
                                            if (this.actor && metaWin.get_compositor_private())
 | 
			
		||||
                                                this._windowAdded(metaWorkspace, metaWin);
 | 
			
		||||
                                            return false;
 | 
			
		||||
                                        }));
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this._isOverviewWindow(win))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let clone = this._addWindowClone(win);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    destroy : function() {
 | 
			
		||||
        this.actor.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onDestroy: function(actor) {
 | 
			
		||||
        this.metaWorkspace.disconnect(this._windowAddedId);
 | 
			
		||||
        this.metaWorkspace.disconnect(this._windowRemovedId);
 | 
			
		||||
 | 
			
		||||
        this._windows = [];
 | 
			
		||||
        this.actor = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Tests if @win belongs to this workspaces
 | 
			
		||||
    _isMyWindow : function (win) {
 | 
			
		||||
        return win.get_workspace() == this.metaWorkspace.index() ||
 | 
			
		||||
            (win.get_meta_window() && win.get_meta_window().is_on_all_workspaces());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Tests if @win should be shown in the Overview
 | 
			
		||||
    _isOverviewWindow : function (win) {
 | 
			
		||||
        let tracker = Shell.WindowTracker.get_default();
 | 
			
		||||
        return tracker.is_window_interesting(win.get_meta_window());
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Create a clone of a (non-desktop) window and add it to the window list
 | 
			
		||||
    _addWindowClone : function(win) {
 | 
			
		||||
        let clone = new WindowClone(win);
 | 
			
		||||
 | 
			
		||||
        clone.connect('selected',
 | 
			
		||||
                      Lang.bind(this, this._onCloneSelected));
 | 
			
		||||
        clone.connect('drag-begin',
 | 
			
		||||
                      Lang.bind(this, function(clone) {
 | 
			
		||||
                          Main.overview.beginWindowDrag();
 | 
			
		||||
                      }));
 | 
			
		||||
        clone.connect('drag-end',
 | 
			
		||||
                      Lang.bind(this, function(clone) {
 | 
			
		||||
                          Main.overview.endWindowDrag();
 | 
			
		||||
                      }));
 | 
			
		||||
        this._group.add_actor(clone.actor);
 | 
			
		||||
 | 
			
		||||
        this._windows.push(clone);
 | 
			
		||||
 | 
			
		||||
        return clone;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onCloneSelected : function (clone, time) {
 | 
			
		||||
        this.metaWorkspace.activate(time);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Draggable target interface
 | 
			
		||||
    handleDragOver : function(source, actor, x, y, time) {
 | 
			
		||||
        if (source.realWindow)
 | 
			
		||||
            return DND.DragMotionResult.MOVE_DROP;
 | 
			
		||||
        if (source.shellWorkspaceLaunch)
 | 
			
		||||
            return DND.DragMotionResult.COPY_DROP;
 | 
			
		||||
 | 
			
		||||
        return DND.DragMotionResult.CONTINUE;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    acceptDrop : function(source, actor, x, y, time) {
 | 
			
		||||
        if (source.realWindow) {
 | 
			
		||||
            let win = source.realWindow;
 | 
			
		||||
            if (this._isMyWindow(win))
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            let metaWindow = win.get_meta_window();
 | 
			
		||||
            metaWindow.change_workspace_by_index(this.metaWorkspace.index(),
 | 
			
		||||
                                                 false, // don't create workspace
 | 
			
		||||
                                                 time);
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if (source.shellWorkspaceLaunch) {
 | 
			
		||||
            source.shellWorkspaceLaunch({ workspace: this.metaWorkspace,
 | 
			
		||||
                                          timestamp: time });
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Signals.addSignalMethods(WorkspaceThumbnail.prototype);
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -411,6 +411,8 @@ shell_app_activate_window (ShellApp     *app,
 | 
			
		||||
/**
 | 
			
		||||
 * shell_app_activate:
 | 
			
		||||
 * @app: a #ShellApp
 | 
			
		||||
 * @workspace: launch on this workspace, or -1 for default. Ignored if
 | 
			
		||||
 *   activating an existing window
 | 
			
		||||
 *
 | 
			
		||||
 * Perform an appropriate default action for operating on this application,
 | 
			
		||||
 * dependent on its current state.  For example, if the application is not
 | 
			
		||||
@@ -419,13 +421,19 @@ shell_app_activate_window (ShellApp     *app,
 | 
			
		||||
 * recently used transient for that window).
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
shell_app_activate (ShellApp  *app)
 | 
			
		||||
shell_app_activate (ShellApp      *app,
 | 
			
		||||
                    int            workspace)
 | 
			
		||||
{
 | 
			
		||||
  switch (app->state)
 | 
			
		||||
    {
 | 
			
		||||
      case SHELL_APP_STATE_STOPPED:
 | 
			
		||||
        /* TODO sensibly handle this error */
 | 
			
		||||
        shell_app_info_launch (app->info, NULL);
 | 
			
		||||
        shell_app_info_launch_full (app->info,
 | 
			
		||||
                                    0,
 | 
			
		||||
                                    NULL,
 | 
			
		||||
                                    workspace,
 | 
			
		||||
                                    NULL,
 | 
			
		||||
                                    NULL);
 | 
			
		||||
        break;
 | 
			
		||||
      case SHELL_APP_STATE_STARTING:
 | 
			
		||||
        break;
 | 
			
		||||
@@ -438,11 +446,13 @@ shell_app_activate (ShellApp  *app)
 | 
			
		||||
/**
 | 
			
		||||
 * shell_app_open_new_window:
 | 
			
		||||
 * @app: a #ShellApp
 | 
			
		||||
 * @workspace: open on this workspace, or -1 for default
 | 
			
		||||
 *
 | 
			
		||||
 * Request that the application create a new window.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
shell_app_open_new_window (ShellApp *app)
 | 
			
		||||
shell_app_open_new_window (ShellApp      *app,
 | 
			
		||||
                           int            workspace)
 | 
			
		||||
{
 | 
			
		||||
  /* Here we just always launch the application again, even if we know
 | 
			
		||||
   * it was already running.  For most applications this
 | 
			
		||||
@@ -452,7 +462,12 @@ shell_app_open_new_window (ShellApp *app)
 | 
			
		||||
   * as say Pidgin.  Ideally, we have the application express to us
 | 
			
		||||
   * that it supports an explicit new-window action.
 | 
			
		||||
   */
 | 
			
		||||
  shell_app_info_launch (app->info, NULL);
 | 
			
		||||
  shell_app_info_launch_full (app->info,
 | 
			
		||||
                              0,
 | 
			
		||||
                              NULL,
 | 
			
		||||
                              workspace,
 | 
			
		||||
                              NULL,
 | 
			
		||||
                              NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -44,9 +44,11 @@ gboolean shell_app_is_transient (ShellApp *app);
 | 
			
		||||
 | 
			
		||||
void shell_app_activate_window (ShellApp *app, MetaWindow *window, guint32 timestamp);
 | 
			
		||||
 | 
			
		||||
void shell_app_activate (ShellApp *app);
 | 
			
		||||
void shell_app_activate (ShellApp      *app,
 | 
			
		||||
                         int            workspace);
 | 
			
		||||
 | 
			
		||||
void shell_app_open_new_window (ShellApp *app);
 | 
			
		||||
void shell_app_open_new_window (ShellApp *app,
 | 
			
		||||
                                int       workspace);
 | 
			
		||||
 | 
			
		||||
ShellAppState shell_app_get_state (ShellApp *app);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -227,17 +227,24 @@ shell_doc_system_on_recent_changed (GtkRecentManager  *manager,
 | 
			
		||||
 * shell_doc_system_open:
 | 
			
		||||
 * @system: A #ShellDocSystem
 | 
			
		||||
 * @info: A #GtkRecentInfo
 | 
			
		||||
 * @workspace: Open on this workspace, or -1 for default
 | 
			
		||||
 *
 | 
			
		||||
 * Launch the default application associated with the mime type of
 | 
			
		||||
 * @info, using its uri.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
shell_doc_system_open (ShellDocSystem *system,
 | 
			
		||||
                       GtkRecentInfo  *info)
 | 
			
		||||
                       GtkRecentInfo  *info,
 | 
			
		||||
                       int             workspace)
 | 
			
		||||
{
 | 
			
		||||
  GFile *file;
 | 
			
		||||
  GAppInfo *app_info;
 | 
			
		||||
  gboolean needs_uri;
 | 
			
		||||
  GAppLaunchContext *context;
 | 
			
		||||
 | 
			
		||||
  context = shell_global_create_app_launch_context (shell_global_get ());
 | 
			
		||||
  if (workspace != -1)
 | 
			
		||||
    gdk_app_launch_context_set_desktop ((GdkAppLaunchContext *)context, workspace);
 | 
			
		||||
 | 
			
		||||
  file = g_file_new_for_uri (gtk_recent_info_get_uri (info));
 | 
			
		||||
  needs_uri = g_file_get_path (file) == NULL;
 | 
			
		||||
@@ -248,7 +255,7 @@ shell_doc_system_open (ShellDocSystem *system,
 | 
			
		||||
    {
 | 
			
		||||
      GList *uris;
 | 
			
		||||
      uris = g_list_prepend (NULL, (gpointer)gtk_recent_info_get_uri (info));
 | 
			
		||||
      g_app_info_launch_uris (app_info, uris, shell_global_create_app_launch_context (shell_global_get ()), NULL);
 | 
			
		||||
      g_app_info_launch_uris (app_info, uris, context, NULL);
 | 
			
		||||
      g_list_free (uris);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
@@ -267,7 +274,6 @@ shell_doc_system_open (ShellDocSystem *system,
 | 
			
		||||
      if (gtk_recent_info_get_application_info (info, app_name, &app_exec, &count, &time))
 | 
			
		||||
        {
 | 
			
		||||
          GRegex *regex;
 | 
			
		||||
          GAppLaunchContext *context;
 | 
			
		||||
 | 
			
		||||
          /* TODO: Change this once better support for creating
 | 
			
		||||
             GAppInfo is added to GtkRecentInfo, as right now
 | 
			
		||||
@@ -298,13 +304,13 @@ shell_doc_system_open (ShellDocSystem *system,
 | 
			
		||||
             despite passing the app launch context, no startup
 | 
			
		||||
             notification occurs.
 | 
			
		||||
           */
 | 
			
		||||
          context = shell_global_create_app_launch_context (shell_global_get ());
 | 
			
		||||
          g_app_info_launch (app_info, NULL, context, NULL);
 | 
			
		||||
          g_object_unref (context);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      g_free (app_name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_object_unref (context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,7 @@ void shell_doc_system_queue_existence_check (ShellDocSystem   *system,
 | 
			
		||||
                                             guint             n_items);
 | 
			
		||||
 | 
			
		||||
void shell_doc_system_open (ShellDocSystem *system,
 | 
			
		||||
                            GtkRecentInfo  *info);
 | 
			
		||||
                            GtkRecentInfo  *info,
 | 
			
		||||
                            int             workspace);
 | 
			
		||||
 | 
			
		||||
#endif /* __SHELL_DOC_SYSTEM_H__ */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user