Compare commits
	
		
			14 Commits
		
	
	
		
			3.7.3.1
			...
			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