#Information before anything else
This entire thread assumes all that is desired is Nemo without CInnamon. Not that it matters because even if installing Nemo normally, none of the dconf schemas for it seem to function. So users may as well trim the fat and stick with this method, with the knowledge that some media functions within Nemo cannot be modified.
Previous and ongoing Compiz issues between repositories
Previously, Noobslab's PPA was the only one that functioned in Wily with Compiz, at least on my machine. It never mattered what I did, how I did it, or the order of how I did it, webupd8's PPA for Nemo just had something _wrong_ with it. Now that Xenial is out, I took another look at their PPA and it works...Except for Zesty users who composite their desktop with Compiz. I am still looking into ths.
If you want folder colours...
If Costales' folder color extension for nemo is necessary for daily operation, this is the only PPA that allows use of his extension for some reason. [s]That, or there is the folder-color package from webupd8's PPA. Either way gives you more folder personalization options.[/s] folder-color is in Ubuntu's Universe repo. My apologies; webupd8 has no such package to my knowledge.If upgrading from Wily or Xenial...
>If you installed Nemo 2.8 on Xenial, you can now add the new PPA for Nemo 3 and upgrade to it. The guide below shows a more thorough, albeit destructive way of doing it, but either means (upgrading from or removing 2.8) requires `nemo -q`, then `nemo -n` to relaunch it.#Introduction
If coming from Linux Mint, or if Caja is lacking in certain aspects for daily use, there's fortunately an alternative which may be more preferable. While functionally similar to Caja, Nemo provides other things of interest to some users, such as a graphical representation of volume space, zoom slider, enhanced file transfer options, a slick-looking interface provided via GTK3 (for those who care) and so on.
#Finding Nemo
There are a variety of ways that one can go about obtaining Nemo. Below are steps relevant for each version of Ubuntu MATE in use;
###Wily / Xenial outdated (Nemo 2.8)
- Do either to add a PPA to install Nemo 2.8 from;
sudo add-apt-repository ppa:webupd8team/nemo
(preferred)sudo add-apt-repository ppa:noobslab/nemo
- Do
sudo apt-get update
- Do
sudo apt-get install nemo
- Proceed to Other package actions that can be performed / Additional packages
###Xenial post-upgrade / Yakkety pre-upgrade, outdated (Nemo 3.2)
(Since this was written, you may end up with 3.6 instead! If you've held nemo before, you might want to unhold to install the latest version.)
- If upgrading from Xenial, perform the following;
- Unlock any locked packages for Nemo to avoid further complications.
sudo apt --purge autoremove nemo*
sudo apt rm -rf /etc/apt/sources.list.d/webupd8-ubuntu-nemo*
- Add the Nemo 3.0 PPA;
sudo add-apt-repository ppa:webupd8team/nemo3
- Do
sudo apt update
- Do
sudo apt install nemo
- Do
sudo apt-mark hold nemo
- Carry on below.
###Cosmic fresh install (Nemo 3.6)
- Save this package: Ubuntu – Error
- Use
dpkg
orgdebi-gtk
to install it. - Add the Nemo 3.0 PPA;
sudo add-apt-repository ppa:webupd8team/nemo3
- This will cause errors; modify
/etc/apt/sources.list.d/webupd8team-ubuntu-nemo3-cosmic.list
soartful
is used instead ofcosmic
. - Install the following packages from webupd8's Nemo 3 repo in order;
sudo apt install -y libxapp1=1.0.4-1~webupd8~artful nemo-data=3.6.5-1~webupd8~artful01 libnemo-extension1=3.6.5-1~webupd8~artful01
sudo apt install -y nemo=3.6.5-1~webupd8~artful01
sudo apt install -y nemo-fileroller=3.6.0-1~webupd8~artful
- Do
sudo apt-mark hold libnemo-extension1 nemo nemo-data nemo-fileroller libxapp1
###Other package actions that can be performed
Additional packages
There are a bevy of other packages that can be added alongside Nemo. As listed below;
nemo-terminal
(maybe slightly broken)
nemo-fileroller nemo-compare nemo-dropbox
(Requires official Dropbox package if from Noobslabs' PPA)
nemo-media-columns nemo-pastebin nemo-seahorse nemo-share nemo-emblems nemo-image-converter nemo-audio-tab
If you have trouble installing any of these, or if any of them demand otherwise-unnecessary cinnamon dependencies, try seeing your system's install policy with apt-cache policy
followed by a package name above.
Packages that can be removed
Feel free to do the following to remove Nemo's archival tool; These packages are not necessary and can be removed if a leaner system is of preference;
sudo apt --purge remove nemo-fileroller file-roller
Do note; there may be some functions from file-roller
that Nemo may need depending on how the file manager is used, so it might be best to keep those until is it certain they are not necessary.
#Making everything else find Nemo
###More terminal stuff
Using Cosmic? You can skip the first command as xdg-mime doesn't complain.
After installing nemo
, do this in a terminal:
mkdir -p ~/.local/share/applications
The above is so xdg-mime
doesn't complain about missing folders, which will now be used to make nemo
the default FM:
xdg-mime default nemo-folder-handler.desktop inode/directory application/x-mate-saved-search application/x-gnome-saved-search
(Most guides suggest nemo.desktop
, though nemo-folder-handler.desktop
works just as well and it acts exactly as caja-folder-handler does.)
Previously I said it was best to set nemo as a required component for MATE with gsettings; This is foolish if you use autorun functions from Caja, since Webupd8's Nemo package lacks the schemas it relies on for autorun to work with it.
gsettings set org.nemo.desktop
can also be done, appended with the following booleen arguments:
background-fade network-icon-visible volumes-visible computer-icon-visible home-icon-visible show-desktop-icons trash-icon-visible
Use any selection, and follow with true
or false
for on or off. Example:
gsettings set org.nemo.desktop volumes-visible true
gsettings set org.mate.background show-desktop-icons false
should be done so caja
can continue to run in the background, since there is no way for nemo
to have media autorun functions defined.
###Modifying MATE menu's Places plugin
The below steps will make it so mate-menu
will open whatever xdg prefers to use. This procedure should also be done to anything else that relies solely on caja
as its file manager, and the command below is only an example: Use whatever text editor is preferred;
gksu pluma /usr/lib/python2.7/dist-packages/mate_menu/plugins/places.py
Edit that so everything using caja
as an open command uses the provided xdg binaries instead. Conveniently, programming isn't complete for it, and every single instance has a FIXME comment because the team behind the script failed to make xdg binaries as fallback. Else for those who are lazy and want it done for them, select all below and paste into places.py:
#####For raw version from Pastebin, see here.
# Copyright (C) 2007-2014 Clement Lefebvre <[email protected]>
# Copyright (C) 2015 Martin Wimpress <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
import ctypes
import gettext
import os
import shutil
from ctypes import *
from gi.repository import Gtk, Gio
from mate_menu.easybuttons import *
from mate_menu.easygsettings import EasyGSettings
from mate_menu.execute import Execute
from user import home
from urllib import unquote
gtk = CDLL("libgtk-x11-2.0.so.0")
# i18n
gettext.install("mate-menu", "/usr/share/locale")
class pluginclass( object ):
def __init__(self, mateMenuWin, toggleButton):
self.mateMenuWin = mateMenuWin
self.toggleButton = toggleButton
# Read UI file
builder = Gtk.Builder()
builder.add_from_file( os.path.join( '/', 'usr', 'share', 'mate-menu', 'plugins', 'places.glade' ))
self.placesBtnHolder = builder.get_object( "places_button_holder" )
self.editableBtnHolder = builder.get_object( "editable_button_holder" )
self.scrolledWindow=builder.get_object("scrolledwindow2")
# These properties are NECESSARY to maintain consistency
# Set 'window' property for the plugin (Must be the root widget)
self.window = builder.get_object( "mainWindow" )
# Set 'heading' property for plugin
self.heading = _("Places")
# This should be the first item added to the window in glade
self.content_holder = builder.get_object( "Places" )
# Items to get custom colors
self.itemstocolor = [ builder.get_object( "viewport2" ) ]
# Settings
self.settings = EasyGSettings("org.mate.mate-menu.plugins.places")
self.settings.notifyAdd( "icon-size", self.RegenPlugin )
self.settings.notifyAdd( "show-computer", self.RegenPlugin )
self.settings.notifyAdd( "show-desktop", self.RegenPlugin )
self.settings.notifyAdd( "show-home_folder", self.RegenPlugin )
self.settings.notifyAdd( "show-network", self.RegenPlugin )
self.settings.notifyAdd( "show-trash", self.RegenPlugin )
self.settings.notifyAdd( "custom-names", self.RegenPlugin )
self.settings.notifyAdd( "allow-scrollbar", self.RegenPlugin )
self.settings.notifyAdd( "show-gtk-bookmarks", self.RegenPlugin )
self.settings.notifyAdd( "height", self.changePluginSize )
self.settings.notifyAdd( "width", self.changePluginSize )
self.loadSettings()
self.content_holder.set_size_request( self.width, self.height )
def wake (self) :
if ( self.showtrash == True ):
self.refreshTrash()
def destroy( self ):
self.settings.notifyRemoveAll()
def changePluginSize( self, settings, key, args = None):
self.allowScrollbar = self.settings.get( "bool", "allow-scrollbar" )
self.width = self.settings.get( "int", "width" )
if (self.allowScrollbar == False):
self.height = -1
self.scrolledWindow.set_policy( Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.NEVER )
else:
self.scrolledWindow.set_policy( Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC )
self.height = self.settings.get( "int", "height" )
self.content_holder.set_size_request( self.width, self.height )
def RegenPlugin( self, *args, **kargs ):
self.loadSettings()
self.ClearAll()
self.do_standard_places()
self.do_custom_places()
self.do_gtk_bookmarks()
def loadSettings( self ):
self.width = self.settings.get( "int", "width" )
self.allowScrollbar = self.settings.get( "bool", "allow-scrollbar" )
self.showGTKBookmarks = self.settings.get( "bool", "show-gtk-bookmarks" )
self.scrolledWindow.set_policy( Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC )
self.height = self.settings.get( "int", "height" )
self.content_holder.set_size_request( self.width, self.height )
if (self.allowScrollbar == False):
self.height = -1
self.scrolledWindow.set_policy( Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.NEVER )
self.content_holder.set_size_request( self.width, self.height )
self.iconsize = self.settings.get( "int", "icon-size" )
# Check default items
self.showcomputer = self.settings.get( "bool", "show-computer" )
self.showhomefolder = self.settings.get( "bool", "show-home-folder" )
self.shownetwork = self.settings.get( "bool", "show-network" )
self.showdesktop = self.settings.get( "bool", "show-desktop" )
self.showtrash = self.settings.get( "bool", "show-trash" )
# Get paths for custom items
self.custompaths = self.settings.get( "list-string", "custom-paths" )
# Get names for custom items
self.customnames = self.settings.get( "list-string", "custom-names" )
# Plugin icon
self.icon = self.settings.get( "string", "icon" )
# Allow plugin to be minimized to the left plugin pane
self.sticky = self.settings.get( "bool", "sticky")
self.minimized = self.settings.get( "bool", "minimized")
def ClearAll(self):
for child in self.placesBtnHolder.get_children():
child.destroy()
for child in self.editableBtnHolder.get_children():
child.destroy()
#Add standard places
def do_standard_places( self ):
if ( self.showcomputer == True ):
Button1 = easyButton( "computer", self.iconsize, [_("Computer")], -1, -1 )
#FIXME: Check for caja on the path and fall back to xdg-open
#Button1.connect( "clicked", self.ButtonClicked, "caja computer:" )
Button1.connect( "clicked", self.ButtonClicked, "xdg-open /" )
Button1.show()
self.placesBtnHolder.pack_start( Button1, False, False, 0)
self.mateMenuWin.setTooltip( Button1, _("Browse all local and remote disks and folders accessible from this computer") )
if ( self.showhomefolder == True ):
Button2 = easyButton( "user-home", self.iconsize, [_("Home Folder")], -1, -1 )
#FIXME: Check for caja on the path and fall back to xdg-open
#Button2.connect( "clicked", self.ButtonClicked, "caja %s " % home )
Button2.connect( "clicked", self.ButtonClicked, "xdg-open %s " % home )
Button2.show()
self.placesBtnHolder.pack_start( Button2, False, False, 0)
self.mateMenuWin.setTooltip( Button2, _("Open your personal folder") )
if ( self.shownetwork == True):
mate_settings = Gio.Settings.new("org.mate.interface")
icon_theme = mate_settings.get_string( "icon-theme" )
Button3 = easyButton( "network-workgroup", self.iconsize, [_("Network")], -1, -1)
#FIXME: Check for caja on the path and fall back to xdg-open
#Button3.connect( "clicked", self.ButtonClicked, "caja network:" )
Button3.connect( "clicked", self.ButtonClicked, "xdg-open network:" )
Button3.show()
self.placesBtnHolder.pack_start( Button3, False, False, 0)
self.mateMenuWin.setTooltip( Button3, _("Browse bookmarked and local network locations") )
if ( self.showdesktop == True ):
# Determine where the Desktop folder is (could be localized)
desktopDir = home + "/Desktop"
try:
from configobj import ConfigObj
config = ConfigObj(home + "/.config/user-dirs.dirs")
tmpdesktopDir = config['XDG_DESKTOP_DIR']
if os.path.exists(tmpdesktopDir):
desktopDir = tmpdesktopDir
except Exception, detail:
print detail
Button4 = easyButton( "desktop", self.iconsize, [_("Desktop")], -1, -1 )
#FIXME: Check for caja on the path and fall back to xdg-open
#Button4.connect( "clicked", self.ButtonClicked, "caja \"" + desktopDir + "\"")
Button4.connect( "clicked", self.ButtonClicked, "xdg-open \"" + desktopDir + "\"")
Button4.show()
self.placesBtnHolder.pack_start( Button4, False, False, 0)
self.mateMenuWin.setTooltip( Button4, _("Browse items placed on the desktop") )
if ( self.showtrash == True ):
self.trashButton = easyButton( "user-trash", self.iconsize, [_("Trash")], -1, -1 )
#FIXME: Check for caja on the path and fall back to xdg-open
#self.trashButton.connect( "clicked", self.ButtonClicked, "caja trash:" )
self.trashButton.connect( "clicked", self.ButtonClicked, "xdg-open trash:" )
self.trashButton.show()
self.trashButton.connect( "button-release-event", self.trashPopup )
self.refreshTrash()
self.placesBtnHolder.pack_start( self.trashButton, False, False, 0)
self.mateMenuWin.setTooltip( self.trashButton, _("Browse deleted files") )
def do_custom_places( self ):
for index in range( len(self.custompaths) ):
path = self.custompaths[index]
path = path.replace("~", home)
#FIXME: Check for caja on the path and fall back to xdg-open
#command = ( "caja \"" + path + "\"")
command = ( "xdg-open \"" + path + "\"")
currentbutton = easyButton( "folder", self.iconsize, [self.customnames[index]], -1, -1 )
currentbutton.connect( "clicked", self.ButtonClicked, command )
currentbutton.show()
self.placesBtnHolder.pack_start( currentbutton, False, False, 0)
def do_gtk_bookmarks( self ):
if self.showGTKBookmarks:
if not os.path.exists(os.path.expanduser('~/.gtk-bookmarks')):
return
bookmarks = []
with open(os.path.expanduser('~/.gtk-bookmarks'), 'r') as f:
for line in f:
#line = line.replace('file://', '')
line = line.rstrip()
if not line:
continue
parts = line.split(' ', 1)
if len(parts) == 2:
path, name = parts
elif len(parts) == 1:
path = parts[0]
name = os.path.basename(os.path.normpath(path))
bookmarks.append((name, path))
for name, path in bookmarks:
name = unquote(name)
currentbutton = easyButton( "folder", self.iconsize, [name], -1, -1 )
currentbutton.connect( "clicked", self.launch_gtk_bookmark, path )
currentbutton.show()
self.placesBtnHolder.pack_start( currentbutton, False, False, 0)
def launch_gtk_bookmark (self, widget, path):
self.mateMenuWin.hide()
#FIXME: Check for caja on the path and fall back to xdg-open
#os.system("caja \"%s\" &" % path)
os.system("xdg-open \"%s\" &" % path)
def trashPopup( self, widget, event ):
if event.button == 3:
trashMenu = Gtk.Menu()
emptyTrashMenuItem = Gtk.MenuItem(_("Empty trash"))
trashMenu.append(emptyTrashMenuItem)
trashMenu.show_all()
emptyTrashMenuItem.connect ( "activate", self.emptyTrash, widget )
self.mateMenuWin.stopHiding()
gtk.gtk_menu_popup(hash(trashMenu), None, None, None, None, 3, 0)
def emptyTrash( self, menu, widget):
trash_info = os.path.join(os.path.expanduser('~'), '.local','share','Trash','info')
trash_files = os.path.join(os.path.expanduser('~'), '.local','share','Trash','files')
shutil.rmtree(trash_info)
shutil.rmtree(trash_files)
self.trashButton.setIcon('user-trash')
def ButtonClicked( self, widget, Exec ):
self.mateMenuWin.hide()
if Exec:
Execute( Exec )
def do_plugin( self ):
self.do_standard_places()
self.do_custom_places()
self.do_gtk_bookmarks()
def refreshTrash (self):
iconName = 'user-trash'
trash_info = os.path.join(os.path.expanduser('~'), '.local','share','Trash','info')
if os.path.exists(trash_info) and os.listdir(trash_info):
iconName = 'user-trash-full'
self.trashButton.setIcon(iconName)
Responsible users make backups; Don't overwrite the old file, rather, save under a different filename and rename the original; the new file can be symbolically linked as `places.py, and should it be necessary to undo this change, the link can be deleted and remade to use the old file instead.
More than that is probably necessary depending on panel applets in use, but for most people it'll be all they need to bother with.
#The desktop background
If it hasn't been noticed, nemo
's default background is a pleasant, solid shade of blue. (In Nemo 3.x there's an XML file used instead which has pre-defined backgrounds that occasionally change.) This is because it's relying on a dconf scheme that isn't for MATE (since it's a GTK3 app, it'll rely on schemas for GNOME and Cinnamon). To change the desktop background for nemo
, perform the following;
gsettings set org.gnome.desktop.background picture-uri file://bgpath
bgpath
being the file location of your image, Must begin with forward-slash.
###An alternative; Symbolic link
I recently discovered that symbolic links will work for pictures, as well; just make a symbolic link to whatever image is preferred. I would recommend using ln
from terminal for this; ex: ln -s ~/Pictures/myimg.png ~/Pictures/desktopbg
(You can make the link named whatever you want.)
Afterward, using the above ln
example, perform the following;
gsettings set org.gnome.desktop.background picture-uri file:///home/user/Pictures/desktopbg gsettings set org.nemo.background picture-filename /home/user/Pictures/desktopbg
Replace user
with your user name. If you cannot see this, you can type whoami
in a terminal, or run mate-about-me
to find this.
desktop issues with Compiz
Previously, installing Nemo via ppa:webupd8team/nemo
(at least in Xenial) no longer caused a weird display issue that rendered the desktop completely unusable. This same issue has happened again in Zesty, and no amount of downgrading I've seen can resolve it. I don't know how to fix it yet, this will be updated when I do figure it out.
terminal issues
By default, unless specified by the installation of another terminal application like terminator
, Nemo will open lxterm
. To fix this, do the following;
- Setting update-alternatives to use whatever terminal you want
Do sudo update-alternatives --config x-terminal-emulator and manually define your preferred terminal emulator of choice. - Optionally, for consistency with GNOME
gsettings set org.mate.applications-terminal exec 'x-terminal-emulator' gsettings set org.mate.applications-terminal exec-arg '-e'
#Bookmarks
Some rely on them, and may be slightly disappointed the bookmarks from Caja aren't usable in Nemo by default . The quick fix for this is simple enough. Open a terminal and perform the following;
- If bookmarks were already made
rm -rf ~/.config/gtk-3.0/bookmarks ln -s ~/.gtk-bookmarks ~/.config/gtk-3.0/bookmarks
- If bookmarks are yet to be made
touch ~/.gtk-bookmarks mkdir -p ~/.config/gtk-3.0 ln -s ~/.gtk-bookmarks ~/.config/gtk-3.0/bookmarks
Since they are essentially the same file, their contents can also be merged together prior to linking by duplicating the contents of one into the other. Either way, the end result is bookmarks synchronized between both file managers and also, having all bookmarks appear in places for all GTK2 menus that show it.
#Undoing the above
Simple instructions are provided via this guide. Please use the contents above to remove and undo any additional files as necessary.
#Information sources