about summary refs log tree commit diff stats
Commit message (Expand)AuthorAgeFilesLines
* now tiled windows can be resized/moved, their floating state will be toggled ...Anselm R. Garbe2007-09-162-8/+12
* some more rearrangementsAnselm R. Garbe2007-09-161-147/+143
* ordered all functions alphabeticallyAnselm R. Garbe2007-09-161-1025/+1023
* corrected a misleading commentAnselm R. Garbe2007-09-161-1/+1
* macros which have been defined in config.h can only be used at function level...Anselm R. Garbe2007-09-161-6/+10
* ordered function forward definitionsAnselm R. Garbe2007-09-151-56/+57
* backporting my intro-comment of old dwm.hAnselm R. Garbe2007-09-151-1/+30
* removed grabkeys, not necessaryAnselm R. Garbe2007-09-151-26/+21
* micromizing dwm step 1Anselm R. Garbe2007-09-1513-1971/+1861
* new colorscheme (16-bit compliant)Anselm R. Garbe2007-09-154-15/+14
* moved bar-related stuff to bar.c (merged draw.c into that)Anselm R. Garbe2007-09-156-259/+269
* renamed drawstatus into drawbarAnselm R. Garbe2007-09-156-10/+10
* renamed config.default.h into config.hAnselm R. Garbe2007-09-152-6/+2
* dist target only needs to add config.default.hAnselm R. Garbe2007-09-151-1/+1
* removed config.arg.h, only 1 config.h necessaryAnselm R. Garbe2007-09-152-112/+22
* small changes of the colorsAnselm R. Garbe2007-09-141-7/+10
* other colorAnselm R. Garbe2007-09-111-3/+3
* using light colorscheme, preparing merge of config.arg.h with config.default.hAnselm R. Garbe2007-09-111-7/+7
* I work with enabled RESIZEHINTS, simply because I force myself to continue th...Anselm R. Garbe2007-09-091-1/+1
* introduced new define RESIZEHINTS, which allows to enable/disable size hint h...Anselm R. Garbe2007-09-094-2/+4
* 14px fonts drives me nutsAnselm R. Garbe2007-09-071-1/+1
* Added tag 4.4.1 for changeset 7c117df5d202Anselm R. Garbe2007-08-261-0/+1
* prepared 4.4.1 bugfix and minor feature enhancement release 4.4.1Anselm R. Garbe2007-08-265-5/+5
* Added tag 4.4 for changeset 408014d21261Anselm R. Garbe2007-08-231-0/+1
* removed unnecessary include, prepared dwm-4.4 4.4Anselm R. Garbe2007-08-231-1/+0
* setlayout should perform strcmp's if arg != NULL, because Layout is local to ...Anselm R. Garbe2007-08-221-1/+2
* reverted release CFLAGsAnselm R. Garbe2007-08-221-2/+2
* removed the _DWM_PROPERTIES handling, reverted ban/unban to XMoveWindow(), an...Anselm R. Garbe2007-08-226-101/+23
* renamed char prop[] into buf[]Anselm R. Garbe2007-08-192-27/+27
* fixed misappearance of iconified windows on SIGKILLAnselm R. Garbe2007-08-192-4/+29
* moved updatebarpos to screenAnselm R. Garbe2007-08-193-28/+28
* added screen.c, removed layout.c and tag.cAnselm R. Garbe2007-08-197-228/+215
* prepared merging layout.c and tag.c into screen.cAnselm R. Garbe2007-08-194-46/+39
* small fixAnselm R. Garbe2007-08-191-1/+1
* hmm I doubt the usefulness of storing this information...Anselm R. Garbe2007-08-186-31/+74
* cleaned up settags-handlingAnselm R. Garbe2007-08-184-81/+90
* applied Gottox mwfact patchAnselm R. Garbe2007-08-181-8/+7
* replaced static Layout *lt with static unsigned int sellayout... (will be ada...Anselm R. Garbe2007-08-171-13/+12
* renamed seltag into seltagsAnselm R. Garbe2007-08-174-13/+13
* applied Jukka Salmi's setmwfact patchAnselm R. Garbe2007-08-174-10/+16
* made plural arraysAnselm R. Garbe2007-08-165-29/+29
* fixed the issue observed by various people, that clients appeared on empty tagsAnselm R. Garbe2007-08-161-4/+3
* made tag/view/toggle{tag,view} work on pointer to tags-array, there was the n...Anselm R. Garbe2007-08-166-112/+127
* applied Jukka's patchAnselm R. Garbe2007-08-161-1/+3
* fixed _DWM_CONFIG persistation, fixed the client disapperance bug during rest...Anselm R. Garbe2007-08-151-5/+5
* fififiAnselm R. Garbe2007-08-156-30/+35
* fix of resize (thanks Sander for the hint!)Anselm R. Garbe2007-08-141-2/+2
* fixed a typoAnselm R. Garbe2007-08-141-1/+1
* small bugfixAnselm R. Garbe2007-08-131-9/+19
* tags should be persistent now during X server runAnselm R. Garbe2007-08-134-7/+33
an class="w"> """Raised when trying to do a kind of operation (e.g. copying) which is not supported on a special file (e.g. a named pipe)""" try: WindowsError except NameError: WindowsError = None def copyfileobj(fsrc, fdst, length=16*1024): """copy data from file-like object fsrc to file-like object fdst""" while 1: buf = fsrc.read(length) if not buf: break fdst.write(buf) yield def _samefile(src, dst): # Macintosh, Unix. if hasattr(os.path,'samefile'): try: return os.path.samefile(src, dst) except OSError: return False # All other platforms: check for same pathname. return (os.path.normcase(os.path.abspath(src)) == os.path.normcase(os.path.abspath(dst))) def copyfile(src, dst): """Copy data from src to dst""" if _samefile(src, dst): raise Error("`%s` and `%s` are the same file" % (src, dst)) fsrc = None fdst = None for fn in [src, dst]: try: st = os.stat(fn) except OSError: # File most likely does not exist pass else: # XXX What about other special files? (sockets, devices...) if stat.S_ISFIFO(st.st_mode): raise SpecialFileError("`%s` is a named pipe" % fn) try: fsrc = open(src, 'rb') fdst = open(dst, 'wb') for _ in copyfileobj(fsrc, fdst): yield finally: if fdst: fdst.close() if fsrc: fsrc.close() def copymode(src, dst): """Copy mode bits from src to dst""" if hasattr(os, 'chmod'): st = os.stat(src) mode = stat.S_IMODE(st.st_mode) os.chmod(dst, mode) def copystat(src, dst): """Copy all stat info (mode bits, atime, mtime, flags) from src to dst""" st = os.stat(src) mode = stat.S_IMODE(st.st_mode) if hasattr(os, 'utime'): os.utime(dst, (st.st_atime, st.st_mtime)) if hasattr(os, 'chmod'): os.chmod(dst, mode) if hasattr(os, 'chflags') and hasattr(st, 'st_flags'): os.chflags(dst, st.st_flags) def copy(src, dst, overwrite=False): """Copy data and mode bits ("cp src dst"). The destination may be a directory. """ if os.path.isdir(dst): dst = os.path.join(dst, os.path.basename(src)) if not overwrite: dst = get_safe_path(dst) for _ in copyfile(src, dst): yield copymode(src, dst) def copy2(src, dst, overwrite=False, symlinks=False): """Copy data and all stat info ("cp -p src dst"). The destination may be a directory. """ if os.path.isdir(dst): dst = os.path.join(dst, os.path.basename(src)) if not overwrite: dst = get_safe_path(dst) if symlinks and os.path.islink(src): linkto = os.readlink(src) os.symlink(linkto, dst) else: for _ in copyfile(src, dst): yield copystat(src, dst) def get_safe_path(dst): if not os.path.exists(dst): return dst if not dst.endswith(APPENDIX): dst += APPENDIX if not os.path.exists(dst): return dst n = 0 test_dst = dst + str(n) while os.path.exists(test_dst): n += 1 test_dst = dst + str(n) return test_dst def ignore_patterns(*patterns): """Function that can be used as copytree() ignore parameter. Patterns is a sequence of glob-style patterns that are used to exclude files""" def _ignore_patterns(path, names): ignored_names = [] for pattern in patterns: ignored_names.extend(fnmatch.filter(names, pattern)) return set(ignored_names) return _ignore_patterns def copytree(src, dst, symlinks=False, ignore=None, overwrite=False): """Recursively copy a directory tree using copy2(). The destination directory must not already exist. If exception(s) occur, an Error is raised with a list of reasons. If the optional symlinks flag is true, symbolic links in the source tree result in symbolic links in the destination tree; if it is false, the contents of the files pointed to by symbolic links are copied. The optional ignore argument is a callable. If given, it is called with the `src` parameter, which is the directory being visited by copytree(), and `names` which is the list of `src` contents, as returned by os.listdir(): callable(src, names) -> ignored_names Since copytree() is called recursively, the callable will be called once for each directory that is copied. It returns a list of names relative to the `src` directory that should not be copied. XXX Consider this example code rather than the ultimate tool. """ names = os.listdir(src) if ignore is not None: ignored_names = ignore(src, names) else: ignored_names = set() errors = [] try: os.makedirs(dst) except Exception as err: if not overwrite: dst = get_safe_path(dst) os.makedirs(dst) for name in names: if name in ignored_names: continue srcname = os.path.join(src, name) dstname = os.path.join(dst, name) try: if symlinks and os.path.islink(srcname): linkto = os.readlink(srcname) if os.path.lexists(dstname): if not os.path.islink(dstname) \ or os.readlink(dstname) != linkto: os.unlink(dstname) os.symlink(linkto, dstname) elif os.path.isdir(srcname): for _ in copytree(srcname, dstname, symlinks, ignore, overwrite): yield else: # Will raise a SpecialFileError for unsupported file types for _ in copy2(srcname, dstname, overwrite=overwrite, symlinks=symlinks): yield # catch the Error from the recursive copytree so that we can # continue with other files except Error as err: errors.extend(err.args[0]) except EnvironmentError as why: errors.append((srcname, dstname, str(why))) try: copystat(src, dst) except OSError as why: if WindowsError is not None and isinstance(why, WindowsError): # Copying file access times may fail on Windows pass else: errors.extend((src, dst, str(why))) if errors: raise Error(errors) def rmtree(path, ignore_errors=False, onerror=None): """Recursively delete a directory tree. If ignore_errors is set, errors are ignored; otherwise, if onerror is set, it is called to handle the error with arguments (func, path, exc_info) where func is os.listdir, os.remove, or os.rmdir; path is the argument to that function that caused it to fail; and exc_info is a tuple returned by sys.exc_info(). If ignore_errors is false and onerror is None, an exception is raised. """ if ignore_errors: def onerror(*args): pass elif onerror is None: def onerror(*args): raise try: if os.path.islink(path): # symlinks to directories are forbidden, see bug #1669 raise OSError("Cannot call rmtree on a symbolic link") except OSError: onerror(os.path.islink, path, sys.exc_info()) # can't continue even if onerror hook returns return names = [] try: names = os.listdir(path) except os.error as err: onerror(os.listdir, path, sys.exc_info()) for name in names: fullname = os.path.join(path, name) try: mode = os.lstat(fullname).st_mode except os.error: mode = 0 if stat.S_ISDIR(mode): rmtree(fullname, ignore_errors, onerror) else: try: os.remove(fullname) except os.error as err: onerror(os.remove, fullname, sys.exc_info()) try: os.rmdir(path) except os.error: onerror(os.rmdir, path, sys.exc_info()) def _basename(path): # A basename() variant which first strips the trailing slash, if present. # Thus we always get the last component of the path, even for directories. return os.path.basename(path.rstrip(os.path.sep)) def move(src, dst, overwrite=False): """Recursively move a file or directory to another location. This is similar to the Unix "mv" command. If the destination is a directory or a symlink to a directory, the source is moved inside the directory. The destination path must not already exist. If the destination already exists but is not a directory, it may be overwritten depending on os.rename() semantics. If the destination is on our current filesystem, then rename() is used. Otherwise, src is copied to the destination and then removed. A lot more could be done here... A look at a mv.c shows a lot of the issues this implementation glosses over. """ real_dst = dst if not overwrite and os.path.isdir(dst): real_dst = os.path.join(dst, _basename(src)) if os.path.exists(real_dst): raise Error("Destination path '%s' already exists" % real_dst) if not overwrite: real_dst = get_safe_path(real_dst) try: os.rename(src, real_dst) except OSError: if os.path.isdir(src): if _destinsrc(src, dst): raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst)) for _ in copytree(src, real_dst, symlinks=True, overwrite=overwrite): yield rmtree(src) else: for _ in copy2(src, real_dst, symlinks=True, overwrite=overwrite): yield os.unlink(src) def _destinsrc(src, dst): src = abspath(src) dst = abspath(dst) if not src.endswith(os.path.sep): src += os.path.sep if not dst.endswith(os.path.sep): dst += os.path.sep return dst.startswith(src) # vi: expandtab sts=4 ts=4 sw=4