pekwm-0.4.4/0000775000175000017500000000000015164641624006416 5pekwm-0.4.4/config.guess0000755000175000017500000014306715126246531010663 #! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2024-07-27' # This file 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 3 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, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system '$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # Just in case it came from the environment. GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still # use 'HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039,SC3028 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c17 c99 c89 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case $UNAME_SYSTEM in Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" #if defined(__ANDROID__) LIBC=android #else #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu #elif defined(__LLVM_LIBC__) LIBC=llvm #else #include /* First heuristic to detect musl libc. */ #ifdef __DEFINED_va_list LIBC=musl #endif #endif #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl; then LIBC=musl fi # If the system lacks a compiler, then just pick glibc. # We could probably try harder. if [ "$LIBC" = unknown ]; then LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` case $UNAME_MACHINE_ARCH in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case $UNAME_VERSION in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. GUESS=$machine-${os}${release}${abi-} ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE ;; *:SecBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE ;; *:MidnightBSD:*:*) GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE ;; *:ekkoBSD:*:*) GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE ;; *:SolidBSD:*:*) GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE ;; *:OS108:*:*) GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE ;; macppc:MirBSD:*:*) GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE ;; *:MirBSD:*:*) GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE ;; *:Sortix:*:*) GUESS=$UNAME_MACHINE-unknown-sortix ;; *:Twizzler:*:*) GUESS=$UNAME_MACHINE-unknown-twizzler ;; *:Redox:*:*) GUESS=$UNAME_MACHINE-unknown-redox ;; mips:OSF1:*.*) GUESS=mips-dec-osf1 ;; alpha:OSF1:*:*) # Reset EXIT trap before exiting to avoid spurious non-zero exit code. trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` GUESS=$UNAME_MACHINE-dec-osf$OSF_REL ;; Amiga*:UNIX_System_V:4.0:*) GUESS=m68k-unknown-sysv4 ;; *:[Aa]miga[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-amigaos ;; *:[Mm]orph[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-morphos ;; *:OS/390:*:*) GUESS=i370-ibm-openedition ;; *:z/VM:*:*) GUESS=s390-ibm-zvmoe ;; *:OS400:*:*) GUESS=powerpc-ibm-os400 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) GUESS=arm-acorn-riscix$UNAME_RELEASE ;; arm*:riscos:*:*|arm*:RISCOS:*:*) GUESS=arm-unknown-riscos ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) GUESS=hppa1.1-hitachi-hiuxmpp ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. case `(/bin/universe) 2>/dev/null` in att) GUESS=pyramid-pyramid-sysv3 ;; *) GUESS=pyramid-pyramid-bsd ;; esac ;; NILE*:*:*:dcosx) GUESS=pyramid-pyramid-svr4 ;; DRS?6000:unix:4.0:6*) GUESS=sparc-icl-nx6 ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) GUESS=sparc-icl-nx7 ;; esac ;; s390x:SunOS:*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL ;; sun4H:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-hal-solaris2$SUN_REL ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris2$SUN_REL ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) GUESS=i386-pc-auroraux$UNAME_RELEASE ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$SUN_ARCH-pc-solaris2$SUN_REL ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris3$SUN_REL ;; sun4*:SunOS:*:*) case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like '4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; sun3*:SunOS:*:*) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case `/bin/arch` in sun3) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac ;; aushp:SunOS:*:*) GUESS=sparc-auspex-sunos$UNAME_RELEASE ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) GUESS=m68k-milan-mint$UNAME_RELEASE ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) GUESS=m68k-hades-mint$UNAME_RELEASE ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) GUESS=m68k-unknown-mint$UNAME_RELEASE ;; m68k:machten:*:*) GUESS=m68k-apple-machten$UNAME_RELEASE ;; powerpc:machten:*:*) GUESS=powerpc-apple-machten$UNAME_RELEASE ;; RISC*:Mach:*:*) GUESS=mips-dec-mach_bsd4.3 ;; RISC*:ULTRIX:*:*) GUESS=mips-dec-ultrix$UNAME_RELEASE ;; VAX*:ULTRIX*:*:*) GUESS=vax-dec-ultrix$UNAME_RELEASE ;; 2020:CLIX:*:* | 2430:CLIX:*:*) GUESS=clipper-intergraph-clix$UNAME_RELEASE ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } GUESS=mips-mips-riscos$UNAME_RELEASE ;; Motorola:PowerMAX_OS:*:*) GUESS=powerpc-motorola-powermax ;; Motorola:*:4.3:PL8-*) GUESS=powerpc-harris-powermax ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) GUESS=powerpc-harris-powermax ;; Night_Hawk:Power_UNIX:*:*) GUESS=powerpc-harris-powerunix ;; m88k:CX/UX:7*:*) GUESS=m88k-harris-cxux7 ;; m88k:*:4*:R4*) GUESS=m88k-motorola-sysv4 ;; m88k:*:3*:R3*) GUESS=m88k-motorola-sysv3 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then GUESS=m88k-dg-dgux$UNAME_RELEASE else GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else GUESS=i586-dg-dgux$UNAME_RELEASE fi ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) GUESS=m88k-dolphin-sysv3 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 GUESS=m88k-motorola-sysv3 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) GUESS=m88k-tektronix-sysv3 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) GUESS=m68k-tektronix-bsd ;; *:IRIX*:*:*) IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` GUESS=mips-sgi-irix$IRIX_REL ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) GUESS=i386-ibm-aix ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then GUESS=$SYSTEM_NAME else GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then GUESS=rs6000-ibm-aix3.2.4 else GUESS=rs6000-ibm-aix3.2 fi ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$IBM_ARCH-ibm-aix$IBM_REV ;; *:AIX:*:*) GUESS=rs6000-ibm-aix ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) GUESS=romp-ibm-bsd4.4 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) GUESS=rs6000-bull-bosx ;; DPX/2?00:B.O.S.:*:*) GUESS=m68k-bull-sysv3 ;; 9000/[34]??:4.3bsd:1.*:*) GUESS=m68k-hp-bsd ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) GUESS=m68k-hp-bsd4.4 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if test "$HP_ARCH" = hppa2.0w then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi GUESS=$HP_ARCH-hp-hpux$HPUX_REV ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` GUESS=ia64-hp-hpux$HPUX_REV ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } GUESS=unknown-hitachi-hiuxwe2 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) GUESS=hppa1.1-hp-bsd ;; 9000/8??:4.3bsd:*:*) GUESS=hppa1.0-hp-bsd ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) GUESS=hppa1.0-hp-mpeix ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) GUESS=hppa1.1-hp-osf ;; hp8??:OSF1:*:*) GUESS=hppa1.0-hp-osf ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then GUESS=$UNAME_MACHINE-unknown-osf1mk else GUESS=$UNAME_MACHINE-unknown-osf1 fi ;; parisc*:Lites*:*:*) GUESS=hppa1.1-hp-lites ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) GUESS=c1-convex-bsd ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) GUESS=c34-convex-bsd ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) GUESS=c38-convex-bsd ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) GUESS=c4-convex-bsd ;; CRAY*Y-MP:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=ymp-cray-unicos$CRAY_REL ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=t90-cray-unicos$CRAY_REL ;; CRAY*T3E:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=alphaev5-cray-unicosmk$CRAY_REL ;; CRAY*SV1:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=sv1-cray-unicos$CRAY_REL ;; *:UNICOS/mp:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=craynv-cray-unicosmp$CRAY_REL ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE ;; sparc*:BSD/OS:*:*) GUESS=sparc-unknown-bsdi$UNAME_RELEASE ;; *:BSD/OS:*:*) GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi else FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf fi ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL ;; i*:CYGWIN*:*) GUESS=$UNAME_MACHINE-pc-cygwin ;; *:MINGW64*:*) GUESS=$UNAME_MACHINE-pc-mingw64 ;; *:MINGW*:*) GUESS=$UNAME_MACHINE-pc-mingw32 ;; *:MSYS*:*) GUESS=$UNAME_MACHINE-pc-msys ;; i*:PW*:*) GUESS=$UNAME_MACHINE-pc-pw32 ;; *:SerenityOS:*:*) GUESS=$UNAME_MACHINE-pc-serenity ;; *:Interix*:*) case $UNAME_MACHINE in x86) GUESS=i586-pc-interix$UNAME_RELEASE ;; authenticamd | genuineintel | EM64T) GUESS=x86_64-unknown-interix$UNAME_RELEASE ;; IA64) GUESS=ia64-unknown-interix$UNAME_RELEASE ;; esac ;; i*:UWIN*:*) GUESS=$UNAME_MACHINE-pc-uwin ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) GUESS=x86_64-pc-cygwin ;; prep*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=powerpcle-unknown-solaris2$SUN_REL ;; *:GNU:*:*) # the GNU system GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL ;; *:GNU/*:*:*) # other systems with GNU libc and userland GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) GUESS="$UNAME_MACHINE-pc-managarm-mlibc" ;; *:[Mm]anagarm:*:*) GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) set_cc_for_build CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then ABI=64 sed 's/^ //' << EOF > "$dummy.c" #ifdef __ARM_EABI__ #ifdef __ARM_PCS_VFP ABI=eabihf #else ABI=eabi #endif #endif EOF cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` eval "$cc_set_abi" case $ABI in eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; esac fi GUESS=$CPU-unknown-linux-$LIBCABI ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi ;; avr32*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; cris:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; crisv32:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; e2k:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; frv:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; hexagon:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:Linux:*:*) GUESS=$UNAME_MACHINE-pc-linux-$LIBC ;; ia64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; kvx:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; kvx:cos:*:*) GUESS=$UNAME_MACHINE-unknown-cos ;; kvx:mbr:*:*) GUESS=$UNAME_MACHINE-unknown-mbr ;; loongarch32:Linux:*:* | loongarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m68*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel #undef mips64 #undef mips64el #if ${IS_GLIBC} && defined(_ABI64) LIBCABI=gnuabi64 #else #if ${IS_GLIBC} && defined(_ABIN32) LIBCABI=gnuabin32 #else LIBCABI=${LIBC} #endif #endif #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa64r6 #else #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa32r6 #else #if defined(__mips64) CPU=mips64 #else CPU=mips #endif #endif #endif #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) MIPS_ENDIAN= #else MIPS_ENDIAN= #endif #endif EOF cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` eval "$cc_set_vars" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; openrisc*:Linux:*:*) GUESS=or1k-unknown-linux-$LIBC ;; or32:Linux:*:* | or1k*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; padre:Linux:*:*) GUESS=sparc-unknown-linux-$LIBC ;; parisc64:Linux:*:* | hppa64:Linux:*:*) GUESS=hppa64-unknown-linux-$LIBC ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; *) GUESS=hppa-unknown-linux-$LIBC ;; esac ;; ppc64:Linux:*:*) GUESS=powerpc64-unknown-linux-$LIBC ;; ppc:Linux:*:*) GUESS=powerpc-unknown-linux-$LIBC ;; ppc64le:Linux:*:*) GUESS=powerpc64le-unknown-linux-$LIBC ;; ppcle:Linux:*:*) GUESS=powerpcle-unknown-linux-$LIBC ;; riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; s390:Linux:*:* | s390x:Linux:*:*) GUESS=$UNAME_MACHINE-ibm-linux-$LIBC ;; sh64*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sh*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sparc:Linux:*:* | sparc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; tile*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; vax:Linux:*:*) GUESS=$UNAME_MACHINE-dec-linux-$LIBC ;; x86_64:Linux:*:*) set_cc_for_build CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then ABI=64 sed 's/^ //' << EOF > "$dummy.c" #ifdef __i386__ ABI=x86 #else #ifdef __ILP32__ ABI=x32 #endif #endif EOF cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` eval "$cc_set_abi" case $ABI in x86) CPU=i686 ;; x32) LIBCABI=${LIBC}x32 ;; esac fi GUESS=$CPU-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. GUESS=i386-sequent-sysv4 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) # If we were able to find 'uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; i*86:XTS-300:*:STOP) GUESS=$UNAME_MACHINE-unknown-stop ;; i*86:atheos:*:*) GUESS=$UNAME_MACHINE-unknown-atheos ;; i*86:syllable:*:*) GUESS=$UNAME_MACHINE-pc-syllable ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) GUESS=i386-unknown-lynxos$UNAME_RELEASE ;; i*86:*DOS:*:*) GUESS=$UNAME_MACHINE-pc-msdosdjgpp ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv32 fi ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. GUESS=i586-pc-msdosdjgpp ;; Intel:Mach:3*:*) GUESS=i386-pc-mach3 ;; paragon:*:*:*) GUESS=i860-intel-osf1 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi ;; mini*:CTIX:SYS*5:*) # "miniframe" GUESS=m68010-convergent-sysv ;; mc68k:UNIX:SYSTEM5:3.51m) GUESS=m68k-convergent-sysv ;; M680?0:D-NIX:5.3:*) GUESS=m68k-diab-dnix ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) GUESS=m68k-unknown-lynxos$UNAME_RELEASE ;; mc68030:UNIX_System_V:4.*:*) GUESS=m68k-atari-sysv4 ;; TSUNAMI:LynxOS:2.*:*) GUESS=sparc-unknown-lynxos$UNAME_RELEASE ;; rs6000:LynxOS:2.*:*) GUESS=rs6000-unknown-lynxos$UNAME_RELEASE ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) GUESS=powerpc-unknown-lynxos$UNAME_RELEASE ;; SM[BE]S:UNIX_SV:*:*) GUESS=mips-dde-sysv$UNAME_RELEASE ;; RM*:ReliantUNIX-*:*:*) GUESS=mips-sni-sysv4 ;; RM*:SINIX-*:*:*) GUESS=mips-sni-sysv4 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` GUESS=$UNAME_MACHINE-sni-sysv4 else GUESS=ns32k-sni-sysv fi ;; PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm GUESS=hppa1.1-stratus-sysv4 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. GUESS=i860-stratus-sysv4 ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. GUESS=$UNAME_MACHINE-stratus-vos ;; *:VOS:*:*) # From Paul.Green@stratus.com. GUESS=hppa1.1-stratus-vos ;; mc68*:A/UX:*:*) GUESS=m68k-apple-aux$UNAME_RELEASE ;; news*:NEWS-OS:6*:*) GUESS=mips-sony-newsos6 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then GUESS=mips-nec-sysv$UNAME_RELEASE else GUESS=mips-unknown-sysv$UNAME_RELEASE fi ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. GUESS=powerpc-be-beos ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. GUESS=powerpc-apple-beos ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. GUESS=i586-pc-beos ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; ppc:Haiku:*:*) # Haiku running on Apple PowerPC GUESS=powerpc-apple-haiku ;; *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) GUESS=$UNAME_MACHINE-unknown-haiku ;; SX-4:SUPER-UX:*:*) GUESS=sx4-nec-superux$UNAME_RELEASE ;; SX-5:SUPER-UX:*:*) GUESS=sx5-nec-superux$UNAME_RELEASE ;; SX-6:SUPER-UX:*:*) GUESS=sx6-nec-superux$UNAME_RELEASE ;; SX-7:SUPER-UX:*:*) GUESS=sx7-nec-superux$UNAME_RELEASE ;; SX-8:SUPER-UX:*:*) GUESS=sx8-nec-superux$UNAME_RELEASE ;; SX-8R:SUPER-UX:*:*) GUESS=sx8r-nec-superux$UNAME_RELEASE ;; SX-ACE:SUPER-UX:*:*) GUESS=sxace-nec-superux$UNAME_RELEASE ;; Power*:Rhapsody:*:*) GUESS=powerpc-apple-rhapsody$UNAME_RELEASE ;; *:Rhapsody:*:*) GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE ;; arm64:Darwin:*:*) GUESS=aarch64-apple-darwin$UNAME_RELEASE ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac if command -v xcode-select > /dev/null 2> /dev/null && \ ! xcode-select --print-path > /dev/null 2> /dev/null ; then # Avoid executing cc if there is no toolchain installed as # cc will be a stub that puts up a graphical alert # prompting the user to install developer tools. CC_FOR_BUILD=no_compiler_found else set_cc_for_build fi if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE ;; *:QNX:*:4*) GUESS=i386-pc-qnx ;; NEO-*:NONSTOP_KERNEL:*:*) GUESS=neo-tandem-nsk$UNAME_RELEASE ;; NSE-*:NONSTOP_KERNEL:*:*) GUESS=nse-tandem-nsk$UNAME_RELEASE ;; NSR-*:NONSTOP_KERNEL:*:*) GUESS=nsr-tandem-nsk$UNAME_RELEASE ;; NSV-*:NONSTOP_KERNEL:*:*) GUESS=nsv-tandem-nsk$UNAME_RELEASE ;; NSX-*:NONSTOP_KERNEL:*:*) GUESS=nsx-tandem-nsk$UNAME_RELEASE ;; *:NonStop-UX:*:*) GUESS=mips-compaq-nonstopux ;; BS2000:POSIX*:*:*) GUESS=bs2000-siemens-sysv ;; DS/*:UNIX_System_V:*:*) GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "${cputype-}" = 386; then UNAME_MACHINE=i386 elif test "x${cputype-}" != x; then UNAME_MACHINE=$cputype fi GUESS=$UNAME_MACHINE-unknown-plan9 ;; *:TOPS-10:*:*) GUESS=pdp10-unknown-tops10 ;; *:TENEX:*:*) GUESS=pdp10-unknown-tenex ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) GUESS=pdp10-dec-tops20 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) GUESS=pdp10-xkl-tops20 ;; *:TOPS-20:*:*) GUESS=pdp10-unknown-tops20 ;; *:ITS:*:*) GUESS=pdp10-unknown-its ;; SEI:*:*:SEIUX) GUESS=mips-sei-seiux$UNAME_RELEASE ;; *:DragonFly:*:*) DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case $UNAME_MACHINE in A*) GUESS=alpha-dec-vms ;; I*) GUESS=ia64-dec-vms ;; V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) GUESS=i386-pc-xenix ;; i*86:skyos:*:*) SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL ;; i*86:rdos:*:*) GUESS=$UNAME_MACHINE-pc-rdos ;; i*86:Fiwix:*:*) GUESS=$UNAME_MACHINE-pc-fiwix ;; *:AROS:*:*) GUESS=$UNAME_MACHINE-unknown-aros ;; x86_64:VMkernel:*:*) GUESS=$UNAME_MACHINE-unknown-esx ;; amd64:Isilon\ OneFS:*:*) GUESS=x86_64-unknown-onefs ;; *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; *:Ironclad:*:*) GUESS=$UNAME_MACHINE-unknown-ironclad ;; esac # Do we have a guess based on uname results? if test "x$GUESS" != x; then echo "$GUESS" exit fi # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" < #include #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #include #if defined(_SIZE_T_) || defined(SIGLOST) #include #endif #endif #endif int main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) #include #if defined (BSD) #if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); #else #if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); #else printf ("vax-dec-bsd\n"); exit (0); #endif #endif #else printf ("vax-dec-bsd\n"); exit (0); #endif #else #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname un; uname (&un); printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname *un; uname (&un); printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else printf ("mips-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF fi exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: pekwm-0.4.4/depcomp0000755000175000017500000005621715126246531007720 #! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2024-06-19.01; # UTC # Copyright (C) 1999-2024 Free Software Foundation, Inc. # 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, 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, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . GNU Automake home page: . General help using GNU software: . EOF exit $? ;; -v | --v*) echo "depcomp (GNU Automake) $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interference from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsolete pre-3.x GCC compilers. ## but also to in-use compilers like IBM xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: pekwm-0.4.4/missing0000755000175000017500000001706015126246531007733 #! /bin/sh # Common wrapper for a few potentially missing GNU and other programs. scriptversion=2024-06-07.14; # UTC # shellcheck disable=SC2006,SC2268 # we must support pre-POSIX shells # Copyright (C) 1996-2024 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # 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, 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, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autogen autoheader autom4te automake autoreconf bison flex help2man lex makeinfo perl yacc Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Report bugs to . GNU Automake home page: . General help using GNU software: ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing (GNU Automake) $scriptversion" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=https://www.perl.org/ flex_URL=https://github.com/westes/flex gnu_software_URL=https://www.gnu.org/software program_details () { case $1 in aclocal|automake|autoreconf) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; *) : ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" autoheader_deps="'acconfig.h'" automake_deps="'Makefile.am'" aclocal_deps="'acinclude.m4'" case $normalized_program in aclocal*) echo "You should only need it if you modified $aclocal_deps or" echo "$configure_deps." ;; autoconf*) echo "You should only need it if you modified $configure_deps." ;; autogen*) echo "You should only need it if you modified a '.def' or '.tpl' file." echo "You may want to install the GNU AutoGen package:" echo "<$gnu_software_URL/autogen/>" ;; autoheader*) echo "You should only need it if you modified $autoheader_deps or" echo "$configure_deps." ;; automake*) echo "You should only need it if you modified $automake_deps or" echo "$configure_deps." ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." ;; autoreconf*) echo "You should only need it if you modified $aclocal_deps or" echo "$automake_deps or $autoheader_deps or $automake_deps or" echo "$configure_deps." ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; perl*) echo "You should only need it to run GNU Autoconf, GNU Automake, " echo " assorted other tools, or if you modified a Perl source file." echo "You may want to install the Perl 5 language interpreter:" echo "<$perl_URL>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac program_details "$normalized_program" } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: pekwm-0.4.4/CMakeLists.txt0000664000175000017500000002575515164641451011112 cmake_minimum_required(VERSION 3.10) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake/Modules/") project(pekwm) set(pekwm_VERSION_MAJOR 0) set(pekwm_VERSION_MINOR 4) set(pekwm_VERSION_PATCH 4) set(pekwm_VERSION "${pekwm_VERSION_MAJOR}.${pekwm_VERSION_MINOR}.${pekwm_VERSION_PATCH}") set(PEKWM_THEMES "https://www.pekwm.se/themes" CACHE STRING "base url where theme index resides, without ending /") # Check for C++98 set(CMAKE_CXX_STANDARD 98) # Export compile commands, LSP integrations set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include(CheckTypeSize) include(CheckCXXCompilerFlag) include(CheckCXXSourceCompiles) include(CheckCXXSymbolExists) include(CheckIncludeFile) include(CheckIncludeFileCXX) include(GNUInstallDirs) include(FindPkgConfig) include(FindCURL) # Look for dependencies find_package(X11 REQUIRED) check_include_file_cxx(limits PEKWM_HAVE_LIMITS) if (NOT PEKWM_HAVE_LIMITS) check_include_file(sys/limits.h PEKWM_HAVE_SYS_LIMITS_H) endif (NOT PEKWM_HAVE_LIMITS) check_include_file(stdint.h PEKWM_HAVE_STDINT_H) check_include_file_cxx(locale PEKWM_HAVE_LOCALE) if (PEKWM_HAVE_LOCALE) check_cxx_source_compiles(" #include int main() { std::locale num_locale(\"\"); std::locale locale = std::locale().combine >(num_locale); return 0; } " PEKWM_HAVE_LOCALE_COMBINE) else() check_include_file(locale.h PEKWM_HAVE_LOCALE_H REQUIRED) endif (PEKWM_HAVE_LOCALE) check_function_exists(localtime_r PEKWM_HAVE_LOCALTIME_R REQUIRED) # Add work-around for missing -std=c++98 flag when running the # check_cxx_source_compiles tests set(orig_CMAKE_CXX_FLAGS ${CMAKE_CXX98_FLAGS}) set(CMAKE_CXX_FLAGS ${CMAKE_CXX98_STANDARD_COMPILE_OPTION}) check_cxx_source_compiles(" #include #include int main() { std::tm tm = {0}; std::cout << std::put_time(&tm, \"%S\"); return 0; } " PEKWM_HAVE_PUT_TIME) check_cxx_source_compiles(" #include #include int main() { std::to_string(42); return 0; } " PEKWM_HAVE_TO_STRING) check_cxx_source_compiles(" #include int main() { std::stod(\"42.2\"); return 0; } " PEKWM_HAVE_STOD) check_cxx_source_compiles(" #include int main() { std::size_t pos; std::stoi(\"42\", &pos, 10); return 0; } " PEKWM_HAVE_STOI) check_cxx_source_compiles(" #include int main() { std::stof(\"42.0\"); return 0; } " PEKWM_HAVE_STOF) check_cxx_source_compiles(" extern \"C\" { #include } int main() { double val = NAN; return 0; } " PEKWM_HAVE_NAN) set(CMAKE_CXX_FLAGS ${orig_CMAKE_CXX_FLAGS}) # Look for platform specific methods check_function_exists(execvpe PEKWM_HAVE_EXECVPE) check_function_exists(setenv PEKWM_HAVE_SETENV) check_function_exists(unsetenv PEKWM_HAVE_UNSETENV) check_function_exists(daemon PEKWM_HAVE_DAEMON) check_function_exists(clock_gettime PEKWM_HAVE_CLOCK_GETTIME) check_function_exists(pledge PEKWM_HAVE_PLEDGE) check_function_exists(timegm PEKWM_HAVE_TIMEGM) check_cxx_symbol_exists(timersub sys/time.h PEKWM_HAVE_TIMERSUB) check_cxx_symbol_exists(environ unistd.h PEKWM_HAVE_ENVIRON) # Look for modern X11 functions set(CMAKE_REQUIRED_INCLUDES ${X11_INCLUDE_DIR}) set(CMAKE_EXTRA_INCLUDE_FILES "X11/Intrinsic.h") check_type_size(Cardinal CARDINAL) set(CMAKE_EXTRA_INCLUDE_FILES "") set(CMAKE_REQUIRED_LIBRARIES ${X11_LIBRARIES}) check_cxx_symbol_exists(Xutf8SetWMProperties X11/Xutil.h PEKWM_HAVE_XUTF8) # Look for platform specific tools message(STATUS "Looking for program awk") find_program(AWK awk PATHS /usr/pkg/bin /usr/xpg4/bin /usr/local/bin /usr/bin /bin NO_DEFAULT_PATH REQUIRED) message(STATUS "Looking for program awk - ${AWK}") message(STATUS "Looking for program grep") find_program(GREP ggrep grep PATHS /usr/pkg/bin /usr/sfw/bin /usr/local/bin /usr/bin /bin NO_DEFAULT_PATH REQUIRED) message(STATUS "Looking for program grep - ${GREP}") message(STATUS "Looking for program sed") find_program(SED gsed sed PATHS /usr/pkg/bin /usr/sfw/bin /usr/local/bin /usr/bin /bin NO_DEFAULT_PATH REQUIRED) message(STATUS "Looking for program sed - ${SED}") message(STATUS "Looking for program sh") find_program(SH sh PATHS /usr/pkg/bin /usr/xpg4/bin /usr/local/bin /usr/bin /bin NO_DEFAULT_PATH REQUIRED) message(STATUS "Looking for program sh - ${SH}") # Optons option(ENABLE_SHAPE "include support for Xshape" ON) option(ENABLE_XDBE "include support for XDBE" ON) option(ENABLE_XINERAMA "include support for Xinerama" ON) option(ENABLE_RANDR "include support for Xrandr" ON) option(ENABLE_XFT "include support for Xft font rendering" ON) option(ENABLE_PANGO "include support for Pango font rendering" ON) option(ENABLE_IMAGE_JPEG "include support for JPEG images" ON) option(ENABLE_IMAGE_PNG "include support for PNG images" ON) option(ENABLE_IMAGE_XPM "include support for XPM images" ON) option(ENABLE_CURL "include support for CURL HTTP client" ON) option(ENABLE_LIBUDEV "include support for libudev" ON) option(PEDANTIC "turn on strict compile-time warnings" OFF) option(TESTS "include tests" OFF) option(DEV "include development tools" OFF) if (TESTS) set(PEKWM_HAVE_TESTS 1) endif (TESTS) if (ENABLE_XFT) find_package(Freetype) endif (ENABLE_XFT) if (ENABLE_PANGO) pkg_check_modules(PANGO pango>=1.44) pkg_check_modules(PANGOCAIRO pangocairo) pkg_check_modules(PANGOXFT pangoxft) endif (ENABLE_PANGO) if (ENABLE_IMAGE_JPEG) find_package(JPEG) endif (ENABLE_IMAGE_JPEG) if (ENABLE_IMAGE_PNG) find_package(PNG) endif (ENABLE_IMAGE_PNG) if (ENABLE_LIBUDEV) pkg_check_modules(LIBUDEV libudev>=100) endif (ENABLE_LIBUDEV) # setup compile/link flags, one location for sharing between the different # compile directories set(common_INCLUDE_DIRS ${PROJECT_BINARY_DIR}/src ${PROJECT_SOURCE_DIR}/src/lib ${X11_INCLUDE_DIR}) set(common_LIBRARIES ${X11_LIBRARIES}) if (ENABLE_SHAPE AND X11_Xshape_FOUND) set(pekwm_FEATURES "${pekwm_FEATURES} XShape") set(PEKWM_HAVE_SHAPE 1) set(common_INCLUDE_DIRS ${common_INCLUDE_DIRS} ${X11_Xshape_INCLUDE_PATH}) set(common_LIBRARIES ${common_LIBRARIES} ${X11_Xshape_LIB}) endif (ENABLE_SHAPE AND X11_Xshape_FOUND) if (ENABLE_XDBE AND X11_Xext_FOUND) set(pekwm_FEATURES "${pekwm_FEATURES} XDBE") set(PEKWM_HAVE_XDBE 1) set(common_LIBRARIES ${common_LIBRARIES} ${X11_Xext_LIB}) endif (ENABLE_XDBE AND X11_Xext_FOUND) if (ENABLE_XINERAMA AND X11_Xinerama_FOUND) set(pekwm_FEATURES "${pekwm_FEATURES} Xinerama") set(PEKWM_HAVE_XINERAMA 1) set(common_INCLUDE_DIRS ${common_INCLUDE_DIRS} ${X11_Xinerama_INCLUDE_PATH}) set(common_LIBRARIES ${common_LIBRARIES} ${X11_Xinerama_LIB}) endif (ENABLE_XINERAMA AND X11_Xinerama_FOUND) if (ENABLE_XFT AND X11_Xft_FOUND AND FREETYPE_FOUND) set(pekwm_FEATURES "${pekwm_FEATURES} Xft") set(PEKWM_HAVE_XFT 1) set(common_INCLUDE_DIRS ${common_INCLUDE_DIRS} ${X11_Xft_INCLUDE_PATH} ${FREETYPE_INCLUDE_DIRS}) set(common_LIBRARIES ${common_LIBRARIES} ${X11_Xft_LIB} ${FREETYPE_LIBRARIES}) endif (ENABLE_XFT AND X11_Xft_FOUND AND FREETYPE_FOUND) if (ENABLE_PANGO AND PANGO_FOUND) set(common_INCLUDE_DIRS ${common_INCLUDE_DIRS} ${PANGO_INCLUDE_DIRS}) set(common_LIBRARIES ${common_LIBRARIES} ${PANGO_LINK_LIBRARIES}) set(PEKWM_HAVE_PANGO 1) if (PANGOCAIRO_FOUND) set(pekwm_FEATURES "${pekwm_FEATURES} PangoCairo") set(PEKWM_HAVE_PANGO_CAIRO 1) set(common_INCLUDE_DIRS ${common_INCLUDE_DIRS} ${PANGOCAIRO_INCLUDE_DIRS}) set(common_LIBRARIES ${common_LIBRARIES} ${PANGOCAIRO_LINK_LIBRARIES}) endif (PANGOCAIRO_FOUND) if (PANGOXFT_FOUND) set(pekwm_FEATURES "${pekwm_FEATURES} PangoXft") set(PEKWM_HAVE_PANGO_XFT 1) set(common_INCLUDE_DIRS ${common_INCLUDE_DIRS} ${PANGOXFT_INCLUDE_DIRS}) set(common_LIBRARIES ${common_LIBRARIES} ${PANGOXFT_LINK_LIBRARIES}) endif (PANGOXFT_FOUND) endif (ENABLE_PANGO AND PANGO_FOUND) if (ENABLE_IMAGE_JPEG AND JPEG_FOUND) set(pekwm_FEATURES "${pekwm_FEATURES} image-jpeg") set(PEKWM_HAVE_IMAGE_JPEG 1) set(common_INCLUDE_DIRS ${common_INCLUDE_DIRS} ${JPEG_INCLUDE_DIR}) set(common_LIBRARIES ${common_LIBRARIES} ${JPEG_LIBRARY}) endif (ENABLE_IMAGE_JPEG AND JPEG_FOUND) if (ENABLE_IMAGE_PNG AND PNG_FOUND) set(pekwm_FEATURES "${pekwm_FEATURES} image-png") set(PEKWM_HAVE_IMAGE_PNG 1) set(common_INCLUDE_DIRS ${common_INCLUDE_DIRS} ${PNG_INCLUDE_DIR}) set(common_LIBRARIES ${common_LIBRARIES} ${PNG_LIBRARY_RELEASE}) endif (ENABLE_IMAGE_PNG AND PNG_FOUND) if (ENABLE_IMAGE_XPM AND X11_Xpm_FOUND) set(pekwm_FEATURES "${pekwm_FEATURES} image-xpm") set(PEKWM_HAVE_IMAGE_XPM 1) set(common_INCLUDE_DIRS ${common_INCLUDE_DIRS} ${X11_Xpm_INCLUDE_PATH}) set(common_LIBRARIES ${common_LIBRARIES} ${X11_Xpm_LIB}) endif (ENABLE_IMAGE_XPM AND X11_Xpm_FOUND) if (ENABLE_RANDR AND X11_Xrandr_FOUND) set(pekwm_FEATURES "${pekwm_FEATURES} Xrandr") set(PEKWM_HAVE_XRANDR 1) set(common_INCLUDE_DIRS ${common_INCLUDE_DIRS} ${X11_Xrandr_INCLUDE_PATH}) set(common_LIBRARIES ${common_LIBRARIES} ${X11_Xrandr_LIB}) set(CMAKE_REQUIRED_LIBRARIES ${X11_LIBRARIES} ${X11_Xrandr_LIB}) check_symbol_exists(XRRGetOutputPrimary X11/extensions/Xrandr.h PEKWM_HAVE_XRRGETOUTPUTPRIMARY) endif (ENABLE_RANDR AND X11_Xrandr_FOUND) if (ENABLE_CURL AND CURL_FOUND) set(pekwm_FEATURES "${pekwm_FEATURES} curl") set(common_INCLUDE_DIRS ${common_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS}) set(common_LIBRARIES ${common_LIBRARIES} ${CURL_LIBRARIES}) set(PEKWM_HAVE_CURL 1) endif (ENABLE_CURL AND CURL_FOUND) if (ENABLE_LIBUDEV AND LIBUDEV_FOUND) set(pekwm_FEATURES "${pekwm_FEATURES} libudev") set(common_INCLUDE_DIRS ${common_INCLUDE_DIRS} ${LIBUDEV_INCLUDE_DIRS}) set(common_LIBRARIES ${common_LIBRARIES} ${LIBUDEV_LINK_LIBRARIES}) set(PEKWM_HAVE_LIBUDEV 1) endif (ENABLE_LIBUDEV AND LIBUDEV_FOUND) if (CMAKE_BUILD_TYPE MATCHES Debug) set(pekwm_FEATURES "${pekwm_FEATURES} debug") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -Wall") endif (CMAKE_BUILD_TYPE MATCHES Debug) if (PEDANTIC) set(pekwm_FEATURES "${pekwm_FEATURES} pedantic") # Using C++98 with modern headers cause -pedantic to error out, # no longer use -Werror for that reason. (long long is C++11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic") check_cxx_compiler_flag("-Wno-variadic-macros" NO_VARIADIC_MACROS) if (NO_VARIADIC_MACROS) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-variadic-macros") endif (NO_VARIADIC_MACROS) endif (PEDANTIC) # check after pedantic check, -Wall -pedantic will cause this to fail if # missing/ignored check_cxx_source_compiles(" #pragma GCC diagnostic push #pragma GCC diagnostic ignored \"-Wdeprecated-declarations\" int main() { return 0; } " PEKWM_HAVE_GCC_DIAGNOSTICS_PUSH) add_definitions(-DVERSION="${pekwm_VERSION}" -DFEATURES="${pekwm_FEATURES}" -DBINDIR="${CMAKE_INSTALL_PREFIX}/bin" -DDATADIR="${CMAKE_INSTALL_PREFIX}/share" -DSYSCONFDIR="${CMAKE_INSTALL_FULL_SYSCONFDIR}/pekwm") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH True) # Subdirectories add_subdirectory(contrib) add_subdirectory(data) add_subdirectory(doc) add_subdirectory(src) if (DEV) add_subdirectory(dev) endif (DEV) if (TESTS) enable_testing() add_subdirectory(test) endif (TESTS) pekwm-0.4.4/contrib/0000775000175000017500000000000015164641624010056 5pekwm-0.4.4/contrib/lobo/0000775000175000017500000000000015164641624011011 5pekwm-0.4.4/contrib/lobo/pekwm_menu_config.pl.vars0000664000175000017500000001566115126136025015735 ' pekwm_menu_config.pl variable list ' this is a comment ' int|Section/VarName|Description|Minimum value|Maxiumum value int|CmdDialog/HistorySaveInterval|Defines how often the history file should be saved counting each time the CmdDialog finish a command. Default 16.|0|100 int|CmdDialog/HistorySize|Number of entries in the history that should be kept track of. Default 1024.|0|2000 int|Harbour/DockApp/SideMax|Controls the maximum size of dockapp clients. If a dockapp client is larger than the maximum, it gets resized down to the SideMax value. Integer is a number of pixels.|0|100 int|Harbour/DockApp/SideMin|Controls the minimum size of dockapp clients. If a dockapp client is smaller than the minimum, it gets resized up to the SideMin value. Integer is a number of pixels.|0|100 int|Harbour/Head|When RandR or Xinerama is on, decides on what head the harbour resides on. Integer is the head number.|0|20 int|MoveResize/EdgeAttract|The distance from screen edge required for the window to snap against it in pixels.|0|100 int|MoveResize/EdgeResist|The distance from screen edge required for the window moving to start being resisted in pixels.|0|100 int|MoveResize/WindowAttract|The distance from other clients that a window will snap against them to in pixels.|0|100 int|MoveResize/WindowResist|The distance from other clients that a window movement will start being resisted.|0|100 int|Screen/DoubleClickTime|Time, in milliseconds, between clicks to be counted as a doubleclick.|0|1000| int|Screen/Placement/Smart/OffsetX|Pixels to leave between new and old windows and screen edges. When 0, no space is reserved.|0|100 int|Screen/Placement/Smart/OffsetY|Pixels to leave between new and old windows and screen edges. When 0, no space is reserved.|0|100 int|Screen/ShowWorkspaceIndicator|Show WorkspaceIndicator for N milliseconds. If set to less than 1, the WorkspaceIndicator is disabled.|0|3000 int|Screen/Workspaces|Number of workspaces enabled.|0|20 int|Screen/WorkspaceIndicatorScale|Changes the size of the WorkspaceIndicator, higher value means smaller size.|0|100 int|Screen/WorkspacesPerRow|Number of workspaces on each row. Value less than 1 fits all workspaces on a single row.|0|20 ' string|Section/VarName|Description string|Screen/EdgeSize|How many pixels from the edge of the screen should screen edges be. Parameters correspond to the following edges: top bottom left right. A value of 0 disables edges. string|Screen/UniqueNames/Post|String to place after the unique client number. string|Screen/UniqueNames/Pre|String to place before the unique client number. string|Screen/TrimTitle|This string contains what pekwm uses to trim down overlong window titles. If it's empty, no trimming down is performed at all. string|Screen/WorkspaceNames|List of names for workspaces separated by ;. ' file|Section/VarName|Description file|CmdDialog/HistoryFile|Path to history file where history is persisted between session. Default ~/.pekwm/history file|Files/AutoProps|The location of the autoprops file file|Files/Keys|The location of the keys file file|Files/Menu|The location of the menu file file|Files/Mouse|The location of the mouse file file|Files/Start|The location of the start file ' dir|Section/VarName|Description dir|Files/Icons|The location of the icons directory dir|Files/Theme|The location of the Theme directory ' bool|Section/VarName|Description bool|CmdDialog/HistoryUnique|If true, identical items in the history will only appear once where the most recently used is the first item. Default true. bool|Harbour/MaximizeOver|Controls whether maximized clients will cover the harbour (true), or if they will stop at the edge of the harbour (false). bool|Harbour/OnTop|Whether or not the harbour is \"always on top\" bool|Menu/DisplayIcons|If true, turns on the drawing of application icons in menus. bool|MoveResize/OpaqueMove|If true, turns on opaque Moving bool|MoveResize/OpaqueResize|If true, turns on opaque Resizing bool|Screen/EdgeIndent|Toggles if the screen edge should be reserved space. bool|Screen/FocusNew|Toggles if new windows should be focused when they pop up. bool|Screen/FullscreenAbove|Toggles restacking of windows when going to and from fullscreen mode. Windows are restacked to the top of all windows when going to fullscreen and to the top of their layer when being restored from fullscreen. bool|Screen/FullscreenDetect|Toggles detection of broken fullscreen requests setting clients to fullscreen mode when requesting to be the size of the screen. Default true. bool|Screen/HonourRandr|Toggles reading of XRANDR information, this can be disabled if the display driver gives both Xinerama and Randr information and only of the two is correct. Default true. bool|Screen/PlaceNew|Toggles if new windows should be placed using the rules found in the Placement subsection, or just opened on the top left corner of your screen. bool|Screen/Placement/Smart/LeftToRight|If false, the window is placed starting from the right. bool|Screen/Placement/Smart/Row|Whether to use row or column placement, if true, uses row. bool|Screen/Placement/Smart/TopToBottom|If false, the window is placed starting from the bottom. bool|Screen/ShowClientID|Should Client IDs be displayed in window titles. bool|Screen/ShowFrameList|Controls whether a list of all available frames on the workspace is displayed during the NextFrame/PrevFrame actions. bool|Screen/ShowStatusWindow|Controls whether a size/position info window is shown when moving or resizing windows. bool|Screen/UniqueNames/SetUnique|Decides if the feature is used or not. False or True. ' option|Section/VarName|Description|Opt1:Opt2:Opt3|Single = 0 Multi = 1 option|Harbour/Orientation|From what to which direction the harbour expands. One of TopToBottom, BottomToTop, RightToLeft, LeftToRight.|TopToBottom:BottomToTop:RightToLeft:LeftToRight|0 option|Harbour/Placement|Which edge to place the harbour on. One of Right, Left, Top, or Bottom.|Right:Left:Top:Bottom|0 option|Menu/Enter|Decides on what mouse events to enter a submenu. String is one of \"ButtonPress, ButtonRelease, DoubleClick, Motion, MotionPressed\"|ButtonPress:ButtonRelease:DoubleClick:Motion:MotionPressed|0 option|Menu/Exec|Decides on what mouse events to execute an entry. String is one of \"ButtonPress, ButtonRelease, DoubleClick, Motion, MotionPressed\"|ButtonPress:ButtonRelease:DoubleClick:Motion:MotionPressed|0 option|Menu/Select|Decides on what mouse events to select a menu entry. String is one of \"ButtonPress, ButtonRelease, DoubleClick, Motion\"|ButtonPress:ButtonRelease:DoubleClick:Motion|0 option|Screen/Placement/Model|Smart - Tries to place windows where no other window is present\nMouseCentered - Places the center of the window underneath the current mouse pointer position\nMouseTopLeft - Places the top-left corner of the window under the pointer\nMouseNotUnder - Places windows on screen corners avoiding the current mouse cursor position.\nCenteredOnParent - Places transient windows at center of their parent window.|Smart:MouseCentered:MouseTopLeft:MouseNotUnder:CenteredOnParent|1 pekwm-0.4.4/contrib/lobo/check.png0000664000175000017500000000032315126136025012502 ‰PNG  IHDR PXêsRGB®Îé pHYs  šœtIMEØ 3#w&brtEXtCommentCreated with GIMPW�@IDATÓ¥ŽQ Cgx==¬Ð>„‚!Ú׃Û€6@DJçîœdf‡SU¼{ˆGDÂè·ÿ4ß{…Οϙ?ä ÿ²z£IEND®B`‚pekwm-0.4.4/contrib/lobo/CMakeLists.txt0000664000175000017500000000004515126136025013460 cmake_minimum_required(VERSION 3.10) pekwm-0.4.4/contrib/lobo/pekwm_menu_config.pl0000775000175000017500000002331215126136025014756 #!/usr/bin/env perl # pekwm_menu_config.pl # Written by: Matt Hayes # # !!! Requires package 'zenity' for the GTK2 dialogs. # !!! Back up your config, this will rewrite it in alphabetical order. # Nothing usually goes wrong, but do it just to be safe. # # Generates a dynamic pekwm menu of all ~/.pekwm/config variables. # For boolean values, clicking on the menu entry will toggle between # 'True' or 'False'. Clicking on single integer values will pop up # a scale dialog which has a graphical slider to select a new value. # Any other values are treated as strings and will be edited by a # graphical entry box. # # Add to your menu an entry like so: # # Submenu = "Config" { # Entry { Actions = "Dynamic /path/to/pekwm_menu_config.pl --genmenu" } # } # # Put check.png and uncheck.png in your icons directory (~/.pekwm/icons/). use strict; use warnings; use Cwd qw(abs_path); # Path to this script. my $path = abs_path($0); my $vars_path = $path.".vars"; # Config file my $config_in = $ENV{'PEKWM_CONFIG_FILE'}; my $config_out = $config_in; # Check command line arguments. if ($ARGV[0] && $ARGV[0] eq "--genmenu") { my $h = hashify($config_in); print "Dynamic {\n"; gen_menu($h, ""); print "}\n"; } elsif ($ARGV[0] && $ARGV[1] && $ARGV[0] eq "--update") { edit_var($ARGV[1]); } else { exit 0; } # edit_var(arg) sub edit_var { my $arg = shift; my @sec = split(/\//, $arg); my $hashref = hashify($config_in); my $h = $hashref; my $did = 0; # Traverse to the needed section. foreach my $i (0..$#sec - 1) { $h = $h->{$sec[$i]}; } # Read through the variables file. open(INFILE, "<".$vars_path) or die "Could not find: ".$vars_path."\n"; while () { # int if ($_ =~ /int\|$arg\|(.+)\|(\d+)\|(\d+)/) { edit_int($sec[$#sec], $h, $1, $2, $3); $did = 1; # file } elsif ($_ =~ /file\|$arg\|(.+)/) { edit_file($sec[$#sec], $h, $1); $did = 1; # dir } elsif ($_ =~ /dir\|$arg\|(.+)/) { edit_dir($sec[$#sec], $h, $1); $did = 1; # bool } elsif ($_ =~ /bool\|$arg\|(.+)/) { edit_bool($sec[$#sec], $h, $1); $did = 1; # option } elsif ($_ =~ /option\|$arg\|(.+)\|(.+)\|(\d)/) { edit_option($sec[$#sec], $h, $1, $2, $3); $did = 1; # string } elsif ($_ =~ /string\|$arg\|(.+)/) { edit_string($sec[$#sec], $h, $1); $did = 1; } } close(INFILE); # If this variable does not have a vars entry, we will treat it # as a string. if (!$did) { edit_string($sec[$#sec], $h, "No description available."); } # Write updated hash to file. open my $fh, '>', $config_out or die "Could not open config for writing!\n"; write_hash($hashref, $fh, ""); close $fh; # Reload pekwm my $reload = `kill -HUP \$(xprop -root _NET_WM_PID | awk '/_NET_WM_PID/ { print \$3 }')`; } # edit_int(key, value, desc, min, max) sub edit_int { my ($key, $hashref, $desc, $min, $max) = @_; my $nval; my $value = $hashref->{$key}; # Check that we have the correct data type. If not, set the start # value to the min value. if (!($value =~ /\d+/)) { $value = $min; } $nval = `zenity --title=\"$key\" --scale --text=\"$desc\" --value=$value --min-value=$min --max-value=$max --step=1`; chomp($nval); # If cancel wasn't pressed... if ($nval) { # Set to the new value. $hashref->{$key} = $nval; } else { exit 0; } } # edit_string(key, value, desc) sub edit_string { my ($key, $hashref, $desc) = @_; my $nval = `zenity --title=\"$key\" --entry --text=\"$desc\" --entry-text=\"$hashref->{$key}\"`; chomp($nval); if ($nval) { # Set to the new value. $hashref->{$key} = $nval; } else { exit 0; } } # edit_file(key, value, desc) sub edit_file { my ($key, $hashref, $desc) = @_; my $nval = `zenity --title=\"$key\" --file-selection --text=\"$desc\" --filename=\"$hashref->{$key}\"`; chomp($nval); if ($nval) { # Set to the new value. $hashref->{$key} = $nval; } else { exit 0; } } # edit_dir(key, value, desc) sub edit_dir { my ($key, $hashref, $desc) = @_; my $nval = `zenity --title=\"$key\" --file-selection --directory --text=\"$desc\" --filename=\"$hashref->{$key}\"`; chomp($nval); if ($nval) { # Set to the new value. $hashref->{$key} = $nval; } else { exit 0; } } # edit_bool(key, value, desc) sub edit_bool { my ($key, $hashref, $desc) = @_; my ($TRUE, $FALSE); if ($hashref->{$key} eq "True") { $TRUE = "TRUE"; $FALSE = "FALSE"; } else { $TRUE = "FALSE"; $FALSE = "TRUE"; } my $nval = `zenity --title=\"$key\" --list --radiolist --text=\"$desc\" --column \"Check\" --column \"Option\" $TRUE True $FALSE False`; chomp($nval); if ($nval) { # Set to the new value. $hashref->{$key} = $nval; } else { exit 0; } } # edit_bool(key, value, desc) sub edit_option { my ($key, $hashref, $desc, $opt, $multi) = @_; my ($nval, $selstr, $tmp, $gotone, @multicur); my @opts = split(/:/, $opt); if (!$multi) { $selstr = ""; foreach (@opts) { if ($_ eq $hashref->{$key}) { $selstr .= "TRUE ".$_." "; } else { $selstr .= "FALSE ".$_." "; } } $nval = `zenity --title=\"$key\" --list --radiolist --text=\"$desc\" --column \"Check\" --column \"Option\" $selstr`; } else { $selstr = ""; @multicur = split(/ /, $hashref->{$key}); foreach my $tmp (@opts) { $gotone = 0; foreach (@multicur) { if ($tmp eq $_) { $selstr .= "TRUE ".$_." "; $gotone = 1; } } if (!$gotone) { $selstr .= "FALSE ".$tmp." " } } $nval = `zenity --title=\"$key\" --list --checklist --separator=\" \" --text=\"$desc\" --column \"Check\" --column \"Option\" $selstr`; } chomp($nval); if ($nval) { # Set to the new value. $hashref->{$key} = $nval; } else { exit 0; } } # write_hash(hash ref) # Write out the hash to config file format. sub write_hash { my ($hashref, $fh, $tabs) = @_; foreach my $key (sort(keys %$hashref)) { if (ref($hashref->{$key}) eq 'HASH') { print $fh $tabs.$key." {\n"; write_hash($hashref->{$key}, $fh, $tabs."\t"); print $fh $tabs."}\n"; } else { print $fh $tabs.$key." = \"".$hashref->{$key}."\"\n"; } } } # gen_menu(hash ref, location string) # This will generate the menu. sub gen_menu { my ($hashref, $loc) = @_; foreach my $key (sort(keys %$hashref)) { if (ref($hashref->{$key}) eq 'HASH') { print "Submenu = \" ".$key."\" {\n"; gen_menu($hashref->{$key}, $loc.$key."/"); print "}\n"; } else { gen_entry($key, $hashref->{$key}, $loc); } } } # gen_entry(key, value, location) sub gen_entry { my ($key, $value, $loc) = @_; # Boolean value if ($value eq "True") { print "Entry = \" ".$key."\" { Icon = \"check.png\"; Actions = \"Exec ".$path." --update ".$loc.$key."\" }\n"; } elsif ($value eq "False") { print "Entry = \" ".$key."\" { Icon = \"uncheck.png\"; Actions = \"Exec ".$path." --update ".$loc.$key."\" }\n"; } else { print "Entry = \" ".$key." [".$value."]\" { Actions = \"Exec ".$path." --update ".$loc.$key."\" }\n"; } } # hashify(file name) # This should read a valid config file and store all of it into # a logical hash table. sub hashify { # Filename parameter my $file = shift; # Replace ~ with home directory $file =~ s/^~/$ENV{'HOME'}/; my $comment = 0; my ($key, $value, $hval, $val); my @name_stack; my @hash_stack; push(@hash_stack, {}); # Open file for reading. open(INFILE, $file) or return pop(@hash_stack); # Read through file, line by line. while (my $line = ) { # Remove the new line character. chomp($line); # If we are currently within a comment, we need to check for # the end comment symbols. if ($comment) { # If we hit the end comment characters, we are done # commenting. if ($line =~ s<.*\*/><>) { $comment = 0; } # We are still commenting, so just skip the rest of this # code. else { next; } } # Remove /* bleh */ one liners. $line =~ s<>; # Remove /* bleh. This also means we have begun a multi-line # comment, so set $comment to 1. if ($line =~ s<>) { $comment = 1; next; } # If we're not currently in a multi-line comment, # remove // style comments. if (!$comment) { $line =~ s<>; } # If we have no line or this is a comment, skip the rest. if (!$line || $comment) { next; } # Is this a block? while ($line =~ s/(\w+)\s*\{// || $line =~ s/\"(.+)\"\s*\{//) { push(@name_stack, $1); push(@hash_stack, {}); # Is this a variable? # This, by the way, is needed for those one lined nested # blocks and variables. while ($line =~ s/^\s*(\w+)\s*=\s*\"(.*)\"// || $line =~ s/^\s*\"([\w\s]+)\"\s*=\s*\"(.*)\"//) { $hash_stack[$#hash_stack]->{$1} = $2; # Check if we have a bracket coming up, signifying # the end of a block. while ($line =~ s/^\s*\}//) { $val = pop(@name_stack); $hval = pop(@hash_stack); # Add each key/value pair to the section/subsection. while (($key, $value) = each(%$hval)) { $hash_stack[$#hash_stack]->{$val}->{$key} = $value; } } } } # Is this a variable? if ( $line =~ s/^\s*(\w+)\s*=\s*\"(.*)\"// || $line =~ s/^\s*\"([\w\s]+)\"\s*=\s*\"(.*)\"//) { $hash_stack[$#hash_stack]->{$1} = $2; # Check if we have a bracket coming up, signifying # the end of a block. while ($line =~ s/^\s*\}//) { $val = pop(@name_stack); $hval = pop(@hash_stack); # Add each key/value pair to the section/subsection. while (($key, $value) = each(%$hval)) { $hash_stack[$#hash_stack]->{$val}->{$key} = $value; } } } # End of block? while ($line =~ s/^\s*\}//) { $val = pop(@name_stack); $hval = pop(@hash_stack); # Add each key/value pair to the section/subsection. while (($key, $value) = each(%$hval)) { $hash_stack[$#hash_stack]->{$val}->{$key} = $value; } } } # Return fully assembled hash. return pop(@hash_stack); } pekwm-0.4.4/contrib/lobo/README0000664000175000017500000000351715126136025011607 Official URL for these scripts is http://nxc.ath.cx/lobo/filez/pekwm/ ****** pekwm scripts ****** ***** pekwm autoprops generator ***** Required files: * pekwm_autoprop.pl If you upgrade to the latest version of pekwm, 0.1.9 and call this script from a pekwm window menu, an autoproperty will be generated for you without having to click the window with the crosshair. This script uses xprop and xwininfo to generate a 'Property' block for the pekwm autoproperties configuration file. Usage: a) If you would like to run this script manually from the console to produce the block, simply run the script with no parameters: ./pekwm_autoprop.pl Upon execution, you will be given a crosshair mouse cursor. This is simply 'xwininfo' prompting you to click your desired window. b) To generate the 'Property' block and write it to your ~/.pekwm/ autoproperties file, run the script with the '-w' switch: ./pekwm_autoprop.pl -w I like to add the following to my pekwm window menu: Submenu = "Autoprops" { Entry = "Save" { Actions = "Exec /home/matt/code/perl/pekwm_autoprop.pl -w" } } ***** pekwm menu config ***** Required files: * pekwm_menu_config.pl * pekwm_menu_config.pl.vars * check.png * uncheck.png Dependencies: * Perl * Zenity This script parses the pekwm config file and creates a dynamic menu showing all configuration options. When you click on an option the script will detect what type of variable is being edited and will pop up a corresponding zenity dialog. The config will then be rewritten and pekwm reloaded to reflect the change. Usage: Add the following to your pekwm menu: Submenu = "Config" { Entry { Actions = "Dynamic /home/matt/code/perl/pekwm_menu_config.pl -- genmenu" } } Also, place check.png and uncheck.png in your icons directory (usually ~/.pekwm/icons). pekwm-0.4.4/contrib/lobo/pekwm_autoprop.pl0000775000175000017500000001016615126136025014341 #!/usr/bin/env perl # pekwm_autoprop.pl # Written by: Matt Hayes # # Generates and adds a Property block to ~/.pekwm/autoproperties. # # Add a menu entry or run this script manually. You will notice # that upon running you get a crosshair cursor, use this to click on # the window you want autoproperties generated for. # # Usage: # Only generate: ./pekwm_autoprop.pl # Generate and write: ./pekwm_autoprop.pl -w use strict; use warnings; my ($_pekwm_frame_decor, $_net_wm_state, $_net_wm_desktop, $wm_class, $window_id, $wm_window_role, $win_x, $win_y, $win_w, $win_h, $one, $two, @wininfo, $prop, $info, $state, @states, $autoprops_file, $write, @props, $sticky); # Get xwininfo. @wininfo = get_xwininfo(); # Parse out window geometry info. foreach $info (@wininfo) { if ($info =~ /(.+):\s+([.\w]+)/) { $one = $1, $two = $2; if ($one =~ /xwininfo: Window id/) { $window_id = $two; } elsif ($one =~ /Absolute upper-left X/) { $win_x = $two; } elsif ($one =~ /Absolute upper-left Y/) { $win_y = $two; } elsif ($one =~ /Width/) { $win_w = $two; } elsif ($one =~ /Height/) { $win_h = $two; } } } # Get xprops. @props = get_xprops($window_id); # Parse out the properties we need. foreach $prop (@props) { if ($prop =~ /(.+) = (.+)/) { if ($1 eq "WM_WINDOW_ROLE(STRING)") { $wm_window_role = $2; } elsif ($1 eq "_PEKWM_FRAME_DECOR(CARDINAL)") { $_pekwm_frame_decor = $2; } elsif ($1 eq "_NET_WM_STATE(ATOM)") { $_net_wm_state = $2; } elsif ($1 eq "_NET_WM_DESKTOP(CARDINAL)") { $_net_wm_desktop = $2; } elsif ($1 eq "WM_CLASS(STRING)") { $wm_class = $2; } } elsif ($prop =~ /(.+): (.+)/) { $one = $1, $two = $2; if ($one =~ /window id \# of group leader/) { $window_id = $two; } } } $wm_class =~ /\"(.+)\", \"(.+)\"/; # Assemble write string. $write = "\n// Auto-generated autoproperty:\n". "// ".$1." ".$2."\n"; $write .= "Property = \"^".$1.",^".$2."\" {\n". "\tApplyOn = \"Start New Reload\"\n". "\tClientGeometry = \"".$win_w."x".$win_h."+".$win_x."+".$win_y."\"\n"; # Set decor options if (defined($_pekwm_frame_decor)) { # Titlebar false if ($_pekwm_frame_decor == 4 || $_pekwm_frame_decor == 0) { $write .= "\tTitlebar = \"False\"\n"; } # Border false if ($_pekwm_frame_decor == 2 || $_pekwm_frame_decor == 0) { $write .= "\tBorder = \"False\"\n"; } } # Add state booleans. if ($_net_wm_state) { @states = split(/, /, $_net_wm_state); foreach $state (@states) { if ($state eq "_NET_WM_STATE_STICKY") { $write .= "\tSticky = \"True\"\n"; $sticky = 1; } elsif ($state eq "_NET_WM_STATE_SHADED") { $write .= "\tShaded = \"True\"\n"; } } } # Set workspace if this window isn't sticky. if (!$sticky) { $write .= "\tWorkspace = \"".($_net_wm_desktop + 1)."\"\n"; } # Set role if ($wm_window_role) { $write .= "\tRole = ".$wm_window_role."\n"; } # End of section. $write .= "}\n"; # Write to autoproperties or to console. if ($ARGV[0] && $ARGV[0] eq "-w") { $autoprops_file = get_autoprops_file(); $autoprops_file =~ s/~/$ENV{'HOME'}/; open(OUTFILE, ">>".$autoprops_file) or die "Could not open ~/.pekwm/autoproperties for writing!\n"; print OUTFILE $write; close(OUTFILE); print "Successfully wrote autoproperty.\n"; } else { print $write; } # Find the autoprops file. sub get_autoprops_file { open(OUTFILE, "<".$ENV{'PEKWM_CONFIG_FILE'}) or die "Could not open pekwm config for reading!\n"; my $in_sec = 0; while () { if (!$in_sec && $_ =~ /Files\s+\{/) { $in_sec = 1; } elsif ($in_sec) { if ($_ =~ /AutoProps\s+=\s+\"(.+)\"/) { close(OUTFILE); return $1; } } } close(OUTFILE); if ($ENV[PEKWM_CONFIG_PATH]) { return $ENV{PEKWM_CONFIG_PATH}."/autoproperties"; } return $ENV{HOME}."/.pekwm/autoproperties"; } # Create an xprops array. sub get_xprops { my $id = shift; my $xprop = `xprop -id $id`; my @xprops = split(/\n/, $xprop); return @xprops; } # Create an xwininfo array. sub get_xwininfo { my $xwininfo; if ($ENV{CLIENT_WINDOW}) { $xwininfo = `xwininfo -id $ENV{CLIENT_WINDOW}`; } else { $xwininfo = `xwininfo`; } my @xwininfos = split(/\n/, $xwininfo); return @xwininfos; } pekwm-0.4.4/contrib/lobo/uncheck.png0000664000175000017500000000030415126136025013044 ‰PNG  IHDR PXêsRGB®Îé pHYs  šœtIMEØ 3¿ñ3òtEXtCommentCreated with GIMPW�1IDATÓc`À |}}±ÊmÞ¼™ÂÚ´išœŸŸ~ÃRšÙ�$þPw7àIEND®B`‚pekwm-0.4.4/contrib/CMakeLists.txt0000664000175000017500000000007515126136025012530 cmake_minimum_required(VERSION 3.10) add_subdirectory(lobo) pekwm-0.4.4/contrib/Makefile.am0000664000175000017500000000034415126136025012023 EXTRA_DIST = CMakeLists.txt \ lobo/CMakeLists.txt \ lobo/README \ lobo/check.png \ lobo/pekwm_autoprop.pl \ lobo/pekwm_menu_config.pl \ lobo/pekwm_menu_config.pl.vars \ lobo/uncheck.png pekwm-0.4.4/contrib/Makefile.in0000664000175000017500000003146115164641453012050 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = contrib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIB_CFLAGS = @LIB_CFLAGS@ LIB_LIBS = @LIB_LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PEKWM_FEATURES = @PEKWM_FEATURES@ PEKWM_SH = @PEKWM_SH@ PEKWM_THEMES = @PEKWM_THEMES@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TK_CFLAGS = @TK_CFLAGS@ TK_LIBS = @TK_LIBS@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libcurl_CFLAGS = @libcurl_CFLAGS@ libcurl_LIBS = @libcurl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ libjpeg_CFLAGS = @libjpeg_CFLAGS@ libjpeg_LIBS = @libjpeg_LIBS@ libpng_CFLAGS = @libpng_CFLAGS@ libpng_LIBS = @libpng_LIBS@ libudev_CFLAGS = @libudev_CFLAGS@ libudev_LIBS = @libudev_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pango_CFLAGS = @pango_CFLAGS@ pango_LIBS = @pango_LIBS@ pangocairo_CFLAGS = @pangocairo_CFLAGS@ pangocairo_LIBS = @pangocairo_LIBS@ pangoxft_CFLAGS = @pangoxft_CFLAGS@ pangoxft_LIBS = @pangoxft_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xext_CFLAGS = @xext_CFLAGS@ xext_LIBS = @xext_LIBS@ xft_CFLAGS = @xft_CFLAGS@ xft_LIBS = @xft_LIBS@ xinerama_CFLAGS = @xinerama_CFLAGS@ xinerama_LIBS = @xinerama_LIBS@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ xrandr_CFLAGS = @xrandr_CFLAGS@ xrandr_LIBS = @xrandr_LIBS@ EXTRA_DIST = CMakeLists.txt \ lobo/CMakeLists.txt \ lobo/README \ lobo/check.png \ lobo/pekwm_autoprop.pl \ lobo/pekwm_menu_config.pl \ lobo/pekwm_menu_config.pl.vars \ lobo/uncheck.png all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign contrib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign contrib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% pekwm-0.4.4/Makefile.am0000664000175000017500000000020115126136025010353 SUBDIRS = src data dev doc contrib if ENABLE_TESTS SUBDIRS += test endif EXTRA_DIST = CMake/config.h.in CMakeLists.txt LICENSE pekwm-0.4.4/src/0000775000175000017500000000000015164641623007204 5pekwm-0.4.4/src/dialog/0000775000175000017500000000000015164641623010443 5pekwm-0.4.4/src/dialog/CMakeLists.txt0000664000175000017500000000042715126136025013117 cmake_minimum_required(VERSION 3.10) add_executable(pekwm_dialog pekwm_dialog.cc ../pekwm_env.cc) target_include_directories(pekwm_dialog PUBLIC ${common_INCLUDE_DIRS}) target_link_libraries(pekwm_dialog tk lib ${common_LIBRARIES}) install(TARGETS pekwm_dialog DESTINATION bin) pekwm-0.4.4/src/dialog/pekwm_dialog.hh0000664000175000017500000000523715126136025013346 // // pekwm_dialog.hh for pekwm // Copyright (C) 2023-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_DIALOG_HH_ #define _PEKWM_DIALOG_HH_ #include #include "../tk/PImage.hh" #include "../tk/PPixmapSurface.hh" #include "../tk/Theme.hh" #include "../tk/TkWidget.hh" #include "../tk/X11App.hh" class PekwmDialogConfig { public: PekwmDialogConfig(const std::string& title, PImage* image, const std::string& message, const std::vector& options) : _title(title.empty() ? "pekwm_dialog" : title), _image(image), _message(message), _options(options) { if (_options.empty()) { _options.push_back("Ok"); } } const std::string& getTitle() const { return _title; } PImage* getImage() const { return _image; } const std::string& getMessage() const { return _message; } const std::vector& getOptions() const { return _options; } private: std::string _title; PImage* _image; std::string _message; std::vector _options; }; /** * Dialog * * -------------------------------------------- * | TITLE | * -------------------------------------------- * | Image if any is displayed here | * | | * | | * | | * -------------------------------------------- * | Message text goes here | * | | * -------------------------------------------- * | [Option1] [Option2] | * -------------------------------------------- * */ class PekwmDialog : public X11App { public: PekwmDialog(const std::string &theme_dir, const std::string &theme_variant, const Geometry &gm, int gm_mask, int decorations, bool raise, const PekwmDialogConfig& config); virtual ~PekwmDialog(); static PekwmDialog *instance() { return _instance; } virtual void handleEvent(XEvent *ev); virtual void resize(uint width, uint height); void show(void); void render(); void setState(Window window, ButtonState state); void click(Window window); protected: void initWidgets(const PekwmDialogConfig& config); void placeWidgets(void); private: virtual void themeChanged(const std::string& name, const std::string& variant, float scale); static void stopDialog(int retcode); Geometry _initial_gm; Theme _theme; Theme::DialogData* _data; bool _raise; PPixmapSurface _background; std::vector _widgets; static PekwmDialog *_instance; }; #endif // _PEKWM_DIALOG_HH_ pekwm-0.4.4/src/dialog/Makefile.am0000664000175000017500000000042215126136025012406 bin_PROGRAMS = pekwm_dialog pekwm_dialog_SOURCES = pekwm_dialog.cc pekwm_dialog.hh ../pekwm_env.cc pekwm_dialog_CXXFLAGS = $(LIB_CFLAGS) $(TK_CFLAGS) -I../lib pekwm_dialog_LDADD = ../tk/libpekwm_tk.a ../lib/libpekwm_lib.a $(LIB_LIBS) $(TK_LIBS) EXTRA_DIST = CMakeLists.txt pekwm-0.4.4/src/dialog/Makefile.in0000664000175000017500000006134615164641454012444 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = pekwm_dialog$(EXEEXT) subdir = src/dialog ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am__dirstamp = $(am__leading_dot)dirstamp am_pekwm_dialog_OBJECTS = pekwm_dialog-pekwm_dialog.$(OBJEXT) \ ../pekwm_dialog-pekwm_env.$(OBJEXT) pekwm_dialog_OBJECTS = $(am_pekwm_dialog_OBJECTS) am__DEPENDENCIES_1 = pekwm_dialog_DEPENDENCIES = ../tk/libpekwm_tk.a ../lib/libpekwm_lib.a \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) pekwm_dialog_LINK = $(CXXLD) $(pekwm_dialog_CXXFLAGS) $(CXXFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ../$(DEPDIR)/pekwm_dialog-pekwm_env.Po \ ./$(DEPDIR)/pekwm_dialog-pekwm_dialog.Po am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(pekwm_dialog_SOURCES) DIST_SOURCES = $(pekwm_dialog_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIB_CFLAGS = @LIB_CFLAGS@ LIB_LIBS = @LIB_LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PEKWM_FEATURES = @PEKWM_FEATURES@ PEKWM_SH = @PEKWM_SH@ PEKWM_THEMES = @PEKWM_THEMES@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TK_CFLAGS = @TK_CFLAGS@ TK_LIBS = @TK_LIBS@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libcurl_CFLAGS = @libcurl_CFLAGS@ libcurl_LIBS = @libcurl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ libjpeg_CFLAGS = @libjpeg_CFLAGS@ libjpeg_LIBS = @libjpeg_LIBS@ libpng_CFLAGS = @libpng_CFLAGS@ libpng_LIBS = @libpng_LIBS@ libudev_CFLAGS = @libudev_CFLAGS@ libudev_LIBS = @libudev_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pango_CFLAGS = @pango_CFLAGS@ pango_LIBS = @pango_LIBS@ pangocairo_CFLAGS = @pangocairo_CFLAGS@ pangocairo_LIBS = @pangocairo_LIBS@ pangoxft_CFLAGS = @pangoxft_CFLAGS@ pangoxft_LIBS = @pangoxft_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xext_CFLAGS = @xext_CFLAGS@ xext_LIBS = @xext_LIBS@ xft_CFLAGS = @xft_CFLAGS@ xft_LIBS = @xft_LIBS@ xinerama_CFLAGS = @xinerama_CFLAGS@ xinerama_LIBS = @xinerama_LIBS@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ xrandr_CFLAGS = @xrandr_CFLAGS@ xrandr_LIBS = @xrandr_LIBS@ pekwm_dialog_SOURCES = pekwm_dialog.cc pekwm_dialog.hh ../pekwm_env.cc pekwm_dialog_CXXFLAGS = $(LIB_CFLAGS) $(TK_CFLAGS) -I../lib pekwm_dialog_LDADD = ../tk/libpekwm_tk.a ../lib/libpekwm_lib.a $(LIB_LIBS) $(TK_LIBS) EXTRA_DIST = CMakeLists.txt all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/dialog/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/dialog/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files clean-binPROGRAMS: -$(am__rm_f) $(bin_PROGRAMS) ../$(am__dirstamp): @$(MKDIR_P) .. @: >>../$(am__dirstamp) ../$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ../$(DEPDIR) @: >>../$(DEPDIR)/$(am__dirstamp) ../pekwm_dialog-pekwm_env.$(OBJEXT): ../$(am__dirstamp) \ ../$(DEPDIR)/$(am__dirstamp) pekwm_dialog$(EXEEXT): $(pekwm_dialog_OBJECTS) $(pekwm_dialog_DEPENDENCIES) $(EXTRA_pekwm_dialog_DEPENDENCIES) @rm -f pekwm_dialog$(EXEEXT) $(AM_V_CXXLD)$(pekwm_dialog_LINK) $(pekwm_dialog_OBJECTS) $(pekwm_dialog_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f ../*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@../$(DEPDIR)/pekwm_dialog-pekwm_env.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_dialog-pekwm_dialog.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` pekwm_dialog-pekwm_dialog.o: pekwm_dialog.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_dialog_CXXFLAGS) $(CXXFLAGS) -MT pekwm_dialog-pekwm_dialog.o -MD -MP -MF $(DEPDIR)/pekwm_dialog-pekwm_dialog.Tpo -c -o pekwm_dialog-pekwm_dialog.o `test -f 'pekwm_dialog.cc' || echo '$(srcdir)/'`pekwm_dialog.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_dialog-pekwm_dialog.Tpo $(DEPDIR)/pekwm_dialog-pekwm_dialog.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pekwm_dialog.cc' object='pekwm_dialog-pekwm_dialog.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_dialog_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_dialog-pekwm_dialog.o `test -f 'pekwm_dialog.cc' || echo '$(srcdir)/'`pekwm_dialog.cc pekwm_dialog-pekwm_dialog.obj: pekwm_dialog.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_dialog_CXXFLAGS) $(CXXFLAGS) -MT pekwm_dialog-pekwm_dialog.obj -MD -MP -MF $(DEPDIR)/pekwm_dialog-pekwm_dialog.Tpo -c -o pekwm_dialog-pekwm_dialog.obj `if test -f 'pekwm_dialog.cc'; then $(CYGPATH_W) 'pekwm_dialog.cc'; else $(CYGPATH_W) '$(srcdir)/pekwm_dialog.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_dialog-pekwm_dialog.Tpo $(DEPDIR)/pekwm_dialog-pekwm_dialog.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pekwm_dialog.cc' object='pekwm_dialog-pekwm_dialog.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_dialog_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_dialog-pekwm_dialog.obj `if test -f 'pekwm_dialog.cc'; then $(CYGPATH_W) 'pekwm_dialog.cc'; else $(CYGPATH_W) '$(srcdir)/pekwm_dialog.cc'; fi` ../pekwm_dialog-pekwm_env.o: ../pekwm_env.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_dialog_CXXFLAGS) $(CXXFLAGS) -MT ../pekwm_dialog-pekwm_env.o -MD -MP -MF ../$(DEPDIR)/pekwm_dialog-pekwm_env.Tpo -c -o ../pekwm_dialog-pekwm_env.o `test -f '../pekwm_env.cc' || echo '$(srcdir)/'`../pekwm_env.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../$(DEPDIR)/pekwm_dialog-pekwm_env.Tpo ../$(DEPDIR)/pekwm_dialog-pekwm_env.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../pekwm_env.cc' object='../pekwm_dialog-pekwm_env.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_dialog_CXXFLAGS) $(CXXFLAGS) -c -o ../pekwm_dialog-pekwm_env.o `test -f '../pekwm_env.cc' || echo '$(srcdir)/'`../pekwm_env.cc ../pekwm_dialog-pekwm_env.obj: ../pekwm_env.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_dialog_CXXFLAGS) $(CXXFLAGS) -MT ../pekwm_dialog-pekwm_env.obj -MD -MP -MF ../$(DEPDIR)/pekwm_dialog-pekwm_env.Tpo -c -o ../pekwm_dialog-pekwm_env.obj `if test -f '../pekwm_env.cc'; then $(CYGPATH_W) '../pekwm_env.cc'; else $(CYGPATH_W) '$(srcdir)/../pekwm_env.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../$(DEPDIR)/pekwm_dialog-pekwm_env.Tpo ../$(DEPDIR)/pekwm_dialog-pekwm_env.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../pekwm_env.cc' object='../pekwm_dialog-pekwm_env.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_dialog_CXXFLAGS) $(CXXFLAGS) -c -o ../pekwm_dialog-pekwm_env.obj `if test -f '../pekwm_env.cc'; then $(CYGPATH_W) '../pekwm_env.cc'; else $(CYGPATH_W) '$(srcdir)/../pekwm_env.cc'; fi` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) -$(am__rm_f) ../$(DEPDIR)/$(am__dirstamp) -$(am__rm_f) ../$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -f ../$(DEPDIR)/pekwm_dialog-pekwm_env.Po -rm -f ./$(DEPDIR)/pekwm_dialog-pekwm_dialog.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ../$(DEPDIR)/pekwm_dialog-pekwm_env.Po -rm -f ./$(DEPDIR)/pekwm_dialog-pekwm_dialog.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% pekwm-0.4.4/src/dialog/pekwm_dialog.cc0000664000175000017500000003032315126136025013326 // // pekwm_dialog.cc for pekwm // Copyright (C) 2021-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "CfgParser.hh" #include "Charset.hh" #include "Debug.hh" #include "Util.hh" #include "X11.hh" #include "../pekwm_env.hh" #include "pekwm_dialog.hh" #include #include #include #include #include #include "../tk/CfgUtil.hh" #include "../tk/FontHandler.hh" #include "../tk/ImageHandler.hh" #include "../tk/PPixmapSurface.hh" #include "../tk/PWinObj.hh" #include "../tk/Render.hh" #include "../tk/TextureHandler.hh" #include "../tk/Theme.hh" #include "../tk/ThemeUtil.hh" #include "../tk/X11Util.hh" #include "../tk/TkWidget.hh" #include "../tk/TkButtonRow.hh" #include "../tk/TkImage.hh" #include "../tk/TkText.hh" extern "C" { #include #include #include #include #include } static const uint WIDTH_DEFAULT = 250; static const uint HEIGHT_DEFAULT = 50; static std::string _config_script_path; static ObserverMapping *_observer_mapping = nullptr; static FontHandler* _font_handler = nullptr; static ImageHandler* _image_handler = nullptr; static TextureHandler* _texture_handler = nullptr; PekwmDialog* PekwmDialog::_instance = nullptr; namespace pekwm { const std::string& configScriptPath() { return _config_script_path; } ObserverMapping* observerMapping() { return _observer_mapping; } FontHandler* fontHandler() { return _font_handler; } ImageHandler* imageHandler() { return _image_handler; } TextureHandler* textureHandler() { return _texture_handler; } } PekwmDialog::PekwmDialog(const std::string &theme_dir, const std::string &theme_variant, const Geometry &gm, int gm_mask, int decorations, bool raise, const PekwmDialogConfig& config) : X11App(gm, gm_mask, config.getTitle(), "dialog", "pekwm_dialog", WINDOW_TYPE_DIALOG, nullptr, true), _initial_gm(gm), _theme(_font_handler, _image_handler, _texture_handler, theme_dir, theme_variant), _data(_theme.getDialogData()), _raise(raise) { X11::selectInput(_window, ExposureMask|StructureNotifyMask); assert(_instance == nullptr); _instance = this; if (decorations) { MwmHints mwm_hints(MWM_HINTS_DECORATIONS, 0, decorations); X11Util::setMwmHints(_window, mwm_hints); } // TODO: setup size minimum based on image initWidgets(config); placeWidgets(); } PekwmDialog::~PekwmDialog(void) { std::vector::iterator it = _widgets.begin(); for (; it != _widgets.end(); ++it) { delete *it; } _instance = nullptr; } void PekwmDialog::handleEvent(XEvent *ev) { switch (ev->type) { case ButtonPress: setState(ev->xbutton.window, BUTTON_STATE_PRESSED); break; case ButtonRelease: click(ev->xbutton.window); break; case ConfigureNotify: resize(ev->xconfigure.width, ev->xconfigure.height); break; case EnterNotify: setState(ev->xbutton.window, BUTTON_STATE_HOVER); break; case Expose: render(); break; case LeaveNotify: setState(ev->xbutton.window, BUTTON_STATE_FOCUSED); break; case MapNotify: break; case ReparentNotify: break; case UnmapNotify: break; default: P_DBG("UNKNOWN EVENT " << ev->type); break; } } void PekwmDialog::resize(uint width, uint height) { if (_gm.width == width && _gm.height == height) { return; } _gm.width = width; _gm.height = height; // FIXME: first pass calculating "important" height req, then // assign size left to image int y = 0; std::vector::iterator it = _widgets.begin(); for (; it != _widgets.end(); ++it) { (*it)->place((*it)->getX(), y, width, height); (*it)->setHeight((*it)->heightReq(width)); y += (*it)->getHeight(); } render(); } void PekwmDialog::show(void) { render(); if (_raise) { X11::mapRaised(_window); } else { X11::mapWindow(_window); } } void PekwmDialog::render() { Drawable draw; if (hasBuffer()) { draw = getRenderDrawable(); } else { if (_background.resize(_gm.width, _gm.height)) { setBackground(_background.getDrawable()); } draw = _background.getDrawable(); } X11Render rend(draw, None); RenderSurface surface(rend, _gm); _data->getBackground()->render(rend, 0, 0, _gm.width, _gm.height); std::vector::iterator it = _widgets.begin(); for (; it != _widgets.end(); ++it) { (*it)->render(rend, surface); } if (hasBuffer()) { swapBuffer(); } else { X11::clearWindow(_window); } } void PekwmDialog::setState(Window window, ButtonState state) { std::vector::iterator it = _widgets.begin(); for (; it != _widgets.end(); ++it) { if ((*it)->setState(window, state)) { break; } } } void PekwmDialog::click(Window window) { std::vector::iterator it = _widgets.begin(); for (; it != _widgets.end(); ++it) { if ((*it)->click(window)) { break; } } } void PekwmDialog::initWidgets(const PekwmDialogConfig& config) { if (! config.getTitle().empty()) { TkWidget* widget = new TkText(_data, *this, config.getTitle(), true); _widgets.push_back(widget); } if (config.getImage() != nullptr) { TkWidget* widget = new TkImage(_data, *this, config.getImage()); _widgets.push_back(widget); } if (! config.getMessage().empty()) { TkWidget* widget = new TkText(_data, *this, config.getMessage(), false); _widgets.push_back(widget); } _widgets.push_back(new TkButtonRow(_data, *this, PekwmDialog::stopDialog, config.getOptions())); } void PekwmDialog::placeWidgets(void) { // height is dependent on the available width, get requested // width first. uint width = _initial_gm.width; std::vector::iterator it = _widgets.begin(); for (; it != _widgets.end(); ++it) { uint width_req = (*it)->widthReq(); if (width_req && width_req > width) { width = width_req; } } if (width == 0) { float scale = pekwm::textureHandler()->getScale(); width = ThemeUtil::scaledPixelValue(scale, WIDTH_DEFAULT); } uint y = 0; it = _widgets.begin(); for (; it != _widgets.end(); ++it) { (*it)->place(0, y, width, 0); (*it)->setHeight((*it)->heightReq(width)); y += (*it)->getHeight(); } PWinObj::resize(std::max(width, _initial_gm.width), std::max(y, _initial_gm.height)); } void PekwmDialog::themeChanged(const std::string& name, const std::string& variant, float scale) { bool scale_changed = scale != _texture_handler->getScale(); if (scale_changed) { _font_handler->setScale(scale); _image_handler->setScale(scale); _texture_handler->setScale(scale); } _theme.load(name, variant, scale_changed /* force */); placeWidgets(); render(); } void PekwmDialog::stopDialog(int retcode) { PekwmDialog::instance()->stop(retcode); } static void init(Display* dpy, float scale, bool font_default_x11, const std::string &font_charset_override) { _observer_mapping = new ObserverMapping(); _font_handler = new FontHandler(scale, font_default_x11, font_charset_override); _image_handler = new ImageHandler(scale); _texture_handler = new TextureHandler(scale); } static void cleanup() { delete _texture_handler; delete _image_handler; delete _font_handler; delete _observer_mapping; } static void usage(const char* name, int ret) { std::cout << "usage: " << name; std::cout << " [-dDhitfl] [-o option|-o option...] message" << std::endl; std::cout << " -d --display dpy Display" << std::endl; std::cout << " -D --decorations str [all|no-border|no-titlebar]" << std::endl; std::cout << " -h --help Display this information" << std::endl; std::cout << " -i --image Image under title" << std::endl; std::cout << " -o --option Option (many allowed)" << std::endl; std::cout << " -t --title Dialog title" << std::endl; std::cout << " -f --log-file Set log file" << std::endl; std::cout << " -l --log-level Set log level" << std::endl; exit(ret); } static int parse_decorations(const std::string& decorations) { if (decorations.empty() || decorations == "all") { return MWM_DECOR_ALL; } int mask = MWM_DECOR_BORDER | MWM_DECOR_TITLE; std::vector toks; Util::splitString(decorations, toks, ","); std::vector::iterator it(toks.begin()); for (; it != toks.end(); ++it) { if (*it == "no-border") { mask &= ~MWM_DECOR_BORDER; } else if (*it == "no-titlebar") { mask &= ~MWM_DECOR_TITLE; } else { std::cerr << "unknown decor: " << *it << std::endl; } } return mask; } int main(int argc, char* argv[]) { pledge_x11_required(""); const char* display = NULL; Geometry gm(0, 0, 0, 0); int gm_mask = WIDTH_VALUE | HEIGHT_VALUE; bool raise; std::string title; std::string config_file = Util::getEnv("PEKWM_CONFIG_FILE"); std::string image_name; std::vector options; int decorations = 0; const struct option opts[] = { {const_cast("config"), required_argument, nullptr, 'c'}, {const_cast("display"), required_argument, nullptr, 'd'}, {const_cast("decoration"), required_argument, nullptr, 'D'}, {const_cast("geometry"), required_argument, nullptr, 'g'}, {const_cast("help"), no_argument, nullptr, 'h'}, {const_cast("image"), required_argument, nullptr, 'i'}, {const_cast("option"), required_argument, nullptr, 'o'}, {const_cast("raise"), no_argument, nullptr, 'r'}, {const_cast("title"), required_argument, nullptr, 't'}, {const_cast("log-level"), required_argument, nullptr, 'l'}, {const_cast("log-file"), required_argument, nullptr, 'f'}, {nullptr, 0, nullptr, 0} }; Charset::init(); initEnv(false); int ch; while ((ch = getopt_long(argc, argv, "c:d:D:g:hi:o:rt:", opts, nullptr)) != -1) { switch (ch) { case 'c': config_file = optarg; break; case 'd': display = optarg; break; case 'D': decorations = parse_decorations(optarg); break; case 'g': gm_mask |= X11::parseGeometry(optarg, gm); break; case 'h': usage(argv[0], 0); break; case 'i': image_name = optarg; Util::expandFileName(image_name); break; case 'o': options.push_back(optarg); break; case 'r': raise = true; break; case 't': title = optarg; break; case 'f': if (! Debug::setLogFile(optarg)) { std::cerr << "Failed to open log file " << optarg << std::endl; } break; case 'l': Debug::setLevel(Debug::getLevel(optarg)); break; default: usage(argv[0], 1); break; } } if (config_file.empty()) { config_file = Util::getConfigDir() + "/config"; } Util::expandFileName(config_file); std::string message; for (int i = optind; i < argc; i++) { if (i > optind) { message += ' '; } message += argv[i]; } Display *dpy = XOpenDisplay(display); if (! dpy) { std::string actual_display = display ? display : Util::getEnv("DISPLAY"); std::cerr << "Can not open display!" << std::endl << "Your DISPLAY variable currently is set to: " << actual_display << std::endl; return 1; } float scale; std::string theme_dir, theme_variant; bool font_default_x11; std::string font_charset_override; { CfgParser cfg(CfgParserOpt("")); cfg.parse(config_file, CfgParserSource::SOURCE_FILE, true); std::string theme_path; CfgUtil::getScreenScale(cfg.getEntryRoot(), scale); CfgUtil::getThemeDir(cfg.getEntryRoot(), theme_dir, theme_variant, theme_path); CfgUtil::getFontSettings(cfg.getEntryRoot(), font_default_x11, font_charset_override); } X11::init(dpy, true); init(dpy, scale, font_default_x11, font_charset_override); if (gm.width == 0) { gm.width = ThemeUtil::scaledPixelValue(scale, WIDTH_DEFAULT); } if (gm.height == 0) { gm.height = ThemeUtil::scaledPixelValue(scale, HEIGHT_DEFAULT); } _image_handler->path_push_back("./"); PImage *image = nullptr; if (image_name.size()) { image = _image_handler->getImage(image_name); if (image) { image->setType(IMAGE_TYPE_SCALED); } } int ret; { // run in separate scope to get Theme destructed before cleanup PekwmDialogConfig config(title, image, message, options); PekwmDialog dialog(theme_dir, theme_variant, gm, gm_mask, decorations, raise, config); dialog.show(); ret = dialog.main(60); } if (image) { _image_handler->returnImage(image); } cleanup(); X11::destruct(); Charset::destruct(); return ret; } pekwm-0.4.4/src/sys/0000775000175000017500000000000015164641623010022 5pekwm-0.4.4/src/sys/SysMonitorChange.cc0000664000175000017500000000276115126136025013504 // // SysResources.cc for pekwm // Copyright (C) 2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "Debug.hh" #include "SysMonitorChange.hh" SysMonitorChange::SysMonitorChange() : _fd(-1) { #ifdef PEKWM_HAVE_LIBUDEV _udev = udev_new(); if (_udev == nullptr) { P_ERR("failed to create udev"); return; } _mon = udev_monitor_new_from_netlink(_udev, "udev"); if (_mon == nullptr) { P_ERR("failed to create udev monitor"); return; } udev_monitor_filter_add_match_subsystem_devtype(_mon, "drm", nullptr); udev_monitor_enable_receiving(_mon); _fd = udev_monitor_get_fd(_mon); #endif // PEKWM_HAVE_LIBUDEV } SysMonitorChange::~SysMonitorChange() { #ifdef PEKWM_HAVE_LIBUDEV if (_mon) { udev_monitor_unref(_mon); } if (_udev) { udev_unref(_udev); } #endif // PEKWM_HAVE_LIBUDEV } bool SysMonitorChange::handle() { #ifdef PEKWM_HAVE_LIBUDEV struct udev_device *dev = udev_monitor_receive_device(_mon); if (dev == nullptr) { P_TRACE("no device received"); return false; } const char *action = udev_device_get_action(dev); const char *sysname = udev_device_get_sysname(dev); const char *status = udev_device_get_sysattr_value(dev, "status"); if (status == nullptr) { status = "unknown"; } P_TRACE("libudev: " << action << " sysname: " << sysname << " status: " << status); udev_device_unref(dev); return true; #else // !PEKWM_HAVE_LIBUDEV return false; #endif // PEKWM_HAVE_LIBUDEV } pekwm-0.4.4/src/sys/SysMonitorChange.hh0000664000175000017500000000144115126136025013510 // // SysMonitorChange.hh for pekwm // Copyright (C) 2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_SYS_MONITOR_CHANGE_HH_ #define _PEKWM_SYS_MONITOR_CHANGE_HH_ #include "config.h" #include "Compat.hh" extern "C" { #ifdef PEKWM_HAVE_LIBUDEV #include #endif // PEKWM_HAVE_LIBUDEV } class SysMonitorChange { public: SysMonitorChange(); ~SysMonitorChange(); int getFd() const { return _fd; } bool handle(); private: SysMonitorChange(const SysMonitorChange&); SysMonitorChange& operator=(const SysMonitorChange&); int _fd; #ifdef PEKWM_HAVE_LIBUDEV struct udev *_udev; struct udev_monitor *_mon; #endif // PEKWM_HAVE_LIBUDEV }; #endif // _PEKWM_SYS_MONITOR_CHANGE_HH_ pekwm-0.4.4/src/sys/SysResources.hh0000664000175000017500000000272315126136025012731 // // SysResources.hh for pekwm // Copyright (C) 2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_SYS_RESOURCES_HH_ #define _PEKWM_SYS_RESOURCES_HH_ #include #include "Daytime.hh" #include "SysConfig.hh" #include "X11.hh" class SysResources { public: SysResources(const SysConfig &cfg); ~SysResources(); void setLocationCountry(const std::string &location_country) { _location_country = location_country; } void setLocationCity(const std::string &location_city) { _location_city = location_city; } void update(const Daytime &daytime, TimeOfDay tod); void setXResourceDpi(); void notifyXTerms(); void setConfiguredXResources(TimeOfDay tod); private: void setXAtoms(const char *theme_variant); void setXResources(const Daytime &daytime, TimeOfDay tod, const char *daylight, const char *theme_variant); void setXResourcesMap(const SysConfig::string_map &x_resources, const char *ctx); void removeStaleThemeXresources(); void notifyXTerm(Window win); bool readClientList(std::vector &windowsv); uint calcXTermHash(); const SysConfig &_cfg; std::string _location_country; std::string _location_city; uint _xterm_hash; /** current theme X resources, tracked separately in order to support * removing old resources when changing theme. */ SysConfig::string_map _theme_x_resources; }; #endif // _PEKWM_SYS_RESOURCES_HH_ pekwm-0.4.4/src/sys/XSettings.hh0000664000175000017500000000736515126136025012217 // // XSettings.hh for pekwm // Copyright (C) 2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_XSETTINGS_HH_ #define _PEKWM_XSETTINGS_HH_ #include "CfgParserSource.hh" #include "Types.hh" #include "X11.hh" #include extern "C" { #ifdef PEKWM_HAVE_STDINT_H #include #endif // PEKWM_HAVE_STDINT_H } enum XSettingType { XSETTING_TYPE_INTEGER = 0, XSETTING_TYPE_STRING = 1, XSETTING_TYPE_COLOR = 2 }; class XSetting { public: virtual ~XSetting() { } enum XSettingType getType() const { return _type; } uint32_t getLastChanged() const { return _last_changed; } void setLastChanged(unsigned long last_changed) { _last_changed = last_changed; } virtual void write(std::ostream &os, const std::string& name); virtual std::string toString() const = 0; static bool validateName(const std::string &name, std::string &error); protected: XSetting(enum XSettingType type) : _type(type), _last_changed(0) { } void writePad(std::ostream &os, size_t len, size_t multiple); private: enum XSettingType _type; uint32_t _last_changed; }; /** * String, 32bit length. */ class XSettingString : public XSetting { public: XSettingString(const std::string &value) : XSetting(XSETTING_TYPE_STRING), _value(value) { } virtual ~XSettingString() { } virtual void write(std::ostream &os, const std::string& name); virtual std::string toString() const; const std::string &getValue() const { return _value; } private: std::string _value; }; /** * Integer 32bit signed. */ class XSettingInteger : public XSetting { public: XSettingInteger(int32_t value) : XSetting(XSETTING_TYPE_INTEGER), _value(value) { } virtual ~XSettingInteger() { } virtual void write(std::ostream &os, const std::string& name); virtual std::string toString() const; int32_t getValue() const { return _value; } private: int32_t _value; }; /** * Color with alpha. * * 2 r (uint16) * 2 g (uint16) * 2 b (uint16) * 2 a (uint16) */ class XSettingColor : public XSetting { public: XSettingColor(uint16_t r, uint16_t g, uint16_t b, uint16_t a) : XSetting(XSETTING_TYPE_COLOR), _r(r), _g(g), _b(b), _a(a) { } virtual ~XSettingColor() { } virtual void write(std::ostream &os, const std::string& name); virtual std::string toString() const; uint16_t getR() const { return _r; } uint16_t getG() const { return _g; } uint16_t getB() const { return _b; } uint16_t getA() const { return _a; } private: uint16_t _r; uint16_t _g; uint16_t _b; uint16_t _a; }; XSetting *mkXSetting(const std::string& str); class XSettings { public: typedef std::map map; XSettings(); ~XSettings(); bool isOwner() const { return _owner; } void setOwner(bool owner) { _owner = owner; } Atom getAtom() const { return _session_atom; } bool setServerOwner(); void clearServerOwner(); void updateServer(); void selectOwnerDestroyInput(); bool load(const std::string &source, CfgParserSource::Type type = CfgParserSource::SOURCE_FILE); bool save(const std::string &path); void save(std::ostream &os); const XSetting *get(const std::string &name) const; void setString(const std::string &name, const std::string &value); void setInt32(const std::string &name, int32_t value); void setColor(const std::string &name, uint16_t r, uint16_t g, uint16_t b, uint16_t a); void remove(const std::string &name); protected: void writeProp(std::ostream &os, unsigned long serial); private: void set(const std::string &name, XSetting *setting); void sendOwnerMessage(Time timestamp); unsigned long getTime(Time &cur_time) const; Window _window; Atom _session_atom; bool _owner; map _settings; }; #endif // _PEKWM_XSETTINGS_HH_ pekwm-0.4.4/src/sys/CMakeLists.txt0000664000175000017500000000067115126136025012477 cmake_minimum_required(VERSION 3.10) add_executable(pekwm_sys pekwm_sys.cc SysConfig.cc SysResources.cc SysMonitorChange.cc SysMonitorConfig.cc XSettings.cc) target_include_directories(pekwm_sys PUBLIC ${common_INCLUDE_DIRS} ${LIBUDEV_INCLUDE_DIRS}) target_link_libraries(pekwm_sys tk lib ${common_LIBRARIES} ${LIBUDEV_LINK_LIBRARIES}) install(TARGETS pekwm_sys DESTINATION bin) pekwm-0.4.4/src/sys/pekwm_sys.cc0000664000175000017500000004053215126136025012267 // // pekwm_sys.cc for pekwm // Copyright (C) 2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "pekwm_sys.hh" #include "Calendar.hh" #include "Compat.hh" #include "CfgParser.hh" #include "Debug.hh" #include "String.hh" #include "SysMonitorConfig.hh" #include "Location.hh" #include "Mem.hh" #include "Util.hh" #include "X11.hh" #include "../tk/Hooks.hh" #include "../tk/ThemeUtil.hh" extern "C" { #include #include } enum PekwmSysAction { PEKWM_SYS_DAY_CHANGED }; static bool _is_sigchld = false; static Hooks *_hooks = nullptr; #ifndef UNITTEST static const char *progname = nullptr; extern "C" { static void sigHandler(int signal) { switch (signal) { case SIGCHLD: _is_sigchld = true; break; default: // do nothing break; } } } #endif // UNITTEST /** static pekwm resources, accessed via the pekwm namespace. */ static std::string _config_script_path; namespace pekwm { const std::string& configScriptPath() { return _config_script_path; } Hooks *hooks() { return _hooks; } } PekwmSys::PekwmSys(const std::string &config_file, bool interactive, Os *os) : _stop(false), _interactive(interactive), _os(os), _select(mkOsSelect()), _cfg(config_file, os), _resources(_cfg), _tod(static_cast(-1)), _tod_override(static_cast(-1)) { } PekwmSys::~PekwmSys() { delete _select; } int PekwmSys::main(const std::string &theme) { if (! _cfg.parseConfig()) { std::cerr << "failed to parse configuration" << std::endl; return 1; } if (! pekwm::ascii_ncase_equal(_cfg.getTimeOfDay(), "AUTO")) { P_TRACE("using static time of day " << _cfg.getTimeOfDay()); time_of_day_from_string(_cfg.getTimeOfDay(), _tod_override); } // load theme before time of day detection, to get the right resources // set the first time around handleTheme(theme); // get location in order to have correct theme and X resources setup. updateLocation(); // init time of day TimeOfDay tod = updateDaytime(time(NULL)); _tod = timeOfDayChanged(getEffectiveTimeOfDay(tod)); // run after first time of day change to get properties initial values // set. if (! _cfg.getXSettingsPath().empty() && _os->pathExists(_cfg.getXSettingsPath())) { _xsettings.load(_cfg.getXSettingsPath()); } if (_cfg.isXSettingsEnabled()) { _xsettings.setServerOwner(); if (! _cfg.getNetIconTheme().empty()) { setNetIconTheme(); } setDpi(); _xsettings.updateServer(); } _select->add(STDIN_FILENO, OsSelect::OS_SELECT_READ); _select->add(X11::getFd(), OsSelect::OS_SELECT_READ); if (_monitor_change.getFd() >= 0) { P_TRACE("listening for udev changes on " << _monitor_change.getFd()); _select->add(_monitor_change.getFd(), OsSelect::OS_SELECT_READ); } P_TRACE("Enter event loop."); do { if (_is_sigchld) { handleSigchld(); _is_sigchld = false; } XEvent ev; struct timeval *tv; TimeoutAction action; if (_timeouts.getNextTimeout(&tv, action)) { // only action handled is time of day change tod = updateDaytime(time(NULL)); _tod = timeOfDayChanged(getEffectiveTimeOfDay(tod)); } else if (X11::pending() > 0) { X11::getNextEvent(ev); handleXEvent(ev); } else if (_select->wait(tv)) { if (_select->isSet(X11::getFd(), OsSelect::OS_SELECT_READ)) { X11::getNextEvent(ev); handleXEvent(ev); } else if (_select->isSet(STDIN_FILENO, OsSelect::OS_SELECT_READ)) { handleStdin(); } else if (_select->isSet(_monitor_change.getFd(), OsSelect::OS_SELECT_READ)) { handleMonitorChange(); } } } while (! _stop); return 0; } void PekwmSys::handleSigchld() { int status; while (waitpid(-1, &status, WNOHANG) > 0) { } } void PekwmSys::handleXEvent(XEvent &ev) { P_TRACE("got X11 event " << X11::getEventTypeString(ev.type)); switch (ev.type) { case DestroyNotify: if (_cfg.isXSettingsEnabled() && _xsettings.setServerOwner()) { _xsettings.updateServer(); } break; case SelectionClear: if (ev.xselectionclear.selection == _xsettings.getAtom()) { _xsettings.setOwner(false); _xsettings.selectOwnerDestroyInput(); P_LOG("no longer owner of xsettings"); } break; default: break; }; } void PekwmSys::handleStdin() { std::string buf; std::vector args; if (_interactive) { std::getline(std::cin, buf); args = StringUtil::shell_split(buf); } else { uint32_t len; std::cin.read(reinterpret_cast(&len), sizeof(len)); buf.resize(len + 1); std::cin.read(const_cast(buf.data()), len); args = StringUtil::shell_split(buf); } if (args.empty() || args[0].empty()) { return; } std::string command = args[0]; args.erase(args.begin()); if (pekwm::ascii_ncase_equal(command, "EXIT")) { _stop = true; } else if (pekwm::ascii_ncase_equal(command, "RELOAD")) { reload(); } else if (pekwm::ascii_ncase_equal(command, "THEME")) { handleTheme(StringView(buf, 0, 6)); _resources.notifyXTerms(); } else if (pekwm::ascii_ncase_equal(command, "TIMEOFDAY")) { handleSetTimeOfDay(args); } else if (pekwm::ascii_ncase_equal(command, "DPI")) { handleSetDpi(args); } else if (pekwm::ascii_ncase_equal(command, "MONLOAD")) { handleMonLoad(args); } else if (pekwm::ascii_ncase_equal(command, "MONSAVE")) { handleMonSave(args); } else if (pekwm::ascii_ncase_equal(command, "XSET")) { handleSetXSETTING(args, XSETTING_TYPE_STRING); } else if (pekwm::ascii_ncase_equal(command, "XSETCOLOR")) { handleSetXSETTING(args, XSETTING_TYPE_COLOR); } else if (pekwm::ascii_ncase_equal(command, "XSETINT")) { handleSetXSETTING(args, XSETTING_TYPE_INTEGER); } else if (pekwm::ascii_ncase_equal(command, "XSAVE")) { handleXSave(); } else { // unknown command P_DBG("unknown command: " << command); } } void PekwmSys::handleMonitorChange() { if (_monitor_change.handle()) { bool loaded = false; if (_cfg.isMonitorLoadOnChange()) { loaded = monLoad(); } if (! loaded && _cfg.isMonitorAutoConfig()) { monAutoConfig(); } std::map args; pekwm::hooks()->run(PEKWM_HOOK_ON_MONITOR_CHANGE, args); } } void PekwmSys::handleSetXSETTING(const std::vector &args, enum XSettingType type) { if (args.size() != 2) { P_TRACE("Sys XSet* expected 2 arguments, got " << args.size()); return; } bool updated; switch (type) { case XSETTING_TYPE_INTEGER: updated = setXSettingInteger(args[0], args[1]); break; case XSETTING_TYPE_COLOR: updated = setXSettingColor(args[0], args[1]); break; case XSETTING_TYPE_STRING: updated = setXSettingString(args[0], args[1]); break; } if (updated) { _xsettings.updateServer(); } } bool PekwmSys::setXSettingInteger(const std::string &key, const std::string &sval) { int val; try { val = std::stoi(sval); } catch (std::invalid_argument&) { return false; } _xsettings.setInt32(key, val); return true; } static uint16_t parseHex(const char *p) { char val[3] = {p[0], p[1], 0}; return static_cast(strtol(val, NULL, 16)); } bool PekwmSys::setXSettingColor(const std::string &key, const std::string &sval) { uint16_t r, g, b, a; const char *p = sval.c_str(); if (*p != '#' || (sval.size() != 7 && sval.size() != 9)) { return false; } // #RRGGBB(AA) r = parseHex(p + 1) << 8; g = parseHex(p + 3) << 8; b = parseHex(p + 5) << 8; if (sval.size() == 7) { a = UINT16_MAX; } else { a = parseHex(p + 7) << 8; } _xsettings.setColor(key, r, g, b, a); return true; } bool PekwmSys::setXSettingString(const std::string &key, const std::string &sval) { _xsettings.setString(key, sval); return true; } void PekwmSys::handleXSave() { if (_cfg.getXSettingsPath().empty()) { P_WARN("can not save XSETTINGS, path not set"); } else { _xsettings.save(_cfg.getXSettingsPath()); } } bool PekwmSys::handleSetTimeOfDay(const std::vector &args) { if (args.size() != 1) { P_TRACE("Set TimeOfDay expected 1 argument, got " << args.size()); return false; } if (pekwm::ascii_ncase_equal(args[0], "AUTO")) { _tod_override = static_cast(-1); } else if (pekwm::ascii_ncase_equal(args[0], "TOGGLE")) { // toggle between day and night if (_tod == TIME_OF_DAY_DAY) { _tod_override = TIME_OF_DAY_NIGHT; } else { _tod_override = TIME_OF_DAY_DAY; } } else if (pekwm::ascii_ncase_equal(args[0], "NEXT")) { // go to next time of day including dawn and dusk _tod_override = static_cast(_tod + 1); if (_tod_override > TIME_OF_DAY_DUSK) { _tod_override = TIME_OF_DAY_NIGHT; } } else if (! time_of_day_from_string(args[0], _tod_override)) { return false; } _tod = timeOfDayChanged(getEffectiveTimeOfDay(_daytime.getTimeOfDay())); return true; } void PekwmSys::handleSetDpi(const std::vector &args) { if (args.size() != 1) { P_TRACE("Set Dpi expected 1 argument, got " << args.size()); return; } double dpi; try { dpi = std::stod(args[0]); } catch (std::invalid_argument&) { P_LOG("Set Dpi " << args[0] << " is not a valid number"); return; } if (dpi > 0.0) { _cfg.setDpiOverride(dpi); _resources.setXResourceDpi(); setDpi(); _xsettings.updateServer(); P_TRACE("dpi override set to " << dpi); } else { P_LOG("Set Dpi " << dpi << " must be greater than 0.0"); } } void PekwmSys::handleMonLoad(const std::vector &args) { monLoad(); } void PekwmSys::handleMonSave(const std::vector &args) { const std::string &path = _cfg.getMonitorsPath(); P_TRACE("save monitor configuration to " << path); SysMonitorConfig config; config.load(path); SysMonitorConfig::MonitorsConfig monitors; if (config.mk(monitors)) { config.add(monitors); config.save(path); } else { P_TRACE("failed to create configuration monitor configuration"); } } void PekwmSys::handleTheme(const StringView &theme) { std::map x_resources; std::string theme_dir = Util::getDir(theme.str()); CfgParser cfg(CfgParserOpt("")); if (! theme.empty() && ThemeUtil::load(cfg, theme_dir, theme.str(), true)) { SysConfig::parseConfigXResources(cfg.getEntryRoot(), x_resources, "XRESOURCES"); } _cfg.setThemeXResources(x_resources); X11::loadXrmResources(); _resources.setConfiguredXResources(_tod); X11::saveXrmResources(); } void PekwmSys::reload() { SysConfig old_cfg(_cfg); if (! _cfg.parseConfig()) { P_WARN("failed to parse configuration"); return; } if (old_cfg.isXSettingsEnabled() != _cfg.isXSettingsEnabled()) { P_TRACE("XSETTINGS changed to " << _cfg.isXSettingsEnabled()); if (_cfg.isXSettingsEnabled()) { _xsettings.setServerOwner(); } else { _xsettings.clearServerOwner(); } } bool update_tod = old_cfg.getLatitude() != _cfg.getLatitude() || old_cfg.getLongitude() != _cfg.getLongitude(); if (! old_cfg.isLocationLookup() && _cfg.isLocationLookup()) { P_TRACE("location lookup changed to " << _cfg.isLocationLookup()); updateLocation(); update_tod = true; } if (old_cfg.getTimeOfDay() != _cfg.getTimeOfDay()) { P_TRACE("time of day changed to " << _cfg.getTimeOfDay()); if (pekwm::ascii_ncase_equal(_cfg.getTimeOfDay(), "AUTO")) { _tod_override = static_cast(-1); update_tod = true; } else if (time_of_day_from_string(_cfg.getTimeOfDay(), _tod_override)) { update_tod = true; } else { P_TRACE("invalid time of day " << _cfg.getTimeOfDay()); } } if (update_tod) { _tod = updateDaytime(time(NULL)); } TimeOfDay tod = getEffectiveTimeOfDay(); if (old_cfg.getNetTheme() != _cfg.getNetTheme() || old_cfg.getNetIconTheme() != _cfg.getNetIconTheme()) { P_TRACE("NetTheme/NetIconTheme changed to " << _cfg.getNetTheme() << "/" << _cfg.getNetIconTheme()); setNetTheme(tod); setNetIconTheme(); _xsettings.updateServer(); } if (old_cfg.getXResources(tod) != _cfg.getXResources(tod)) { P_TRACE("X resources for changed"); _resources.setConfiguredXResources(tod); } } bool PekwmSys::monLoad() { const std::string &path = _cfg.getMonitorsPath(); P_TRACE("apply monitor configuration from " << path); SysMonitorConfig config; SysMonitorConfig::MonitorsConfig monitors; if (config.load(path) && config.find(monitors)) { return config.apply(monitors); } return false; } bool PekwmSys::monAutoConfig() { SysMonitorConfig config; return config.autoConfig(); } void PekwmSys::updateLocation() { if (! _cfg.isLocationLookup()) { P_TRACE("location lookup is disabled"); return; } Location location(mkHttpClient()); double latitude, longitude; P_TRACE("get location from Location service"); if (location.get(latitude, longitude)) { P_TRACE("got location latitude: " << latitude << " longitude: " << longitude); _cfg.setLatitude(latitude); _cfg.setLongitude(longitude); _resources.setLocationCountry(location.getCountry()); _resources.setLocationCity(location.getCity()); } } TimeOfDay PekwmSys::updateDaytime(time_t now) { TimeOfDay tod = TIME_OF_DAY_DAY; time_t next = Calendar(now).nextDay().getTimestamp(); if (isTimeOfDayOverride()) { tod = _tod_override; } else if (_cfg.haveLocation()) { _daytime = Daytime(now, _cfg.getLatitude(), _cfg.getLongitude()); next = std::min(next, _daytime.getTimeOfDayEnd(now)); tod = _daytime.getTimeOfDay(now); } _timeouts.replaceTime(PEKWM_SYS_DAY_CHANGED, next); return tod; } enum TimeOfDay PekwmSys::timeOfDayChanged(enum TimeOfDay tod) { if (_tod == static_cast(-1)) { P_LOG("initial time of day: " << time_of_day_to_string(tod)); } else if (_tod != tod) { P_LOG("time of day changed from " << time_of_day_to_string(_tod) << " to " << time_of_day_to_string(tod)); } else { P_TRACE("not updating time of day, not changed"); return tod; } _resources.update(_daytime, tod); // automatic XSETTINGS theme switch if (! _cfg.getNetTheme().empty()) { setNetTheme(tod); _xsettings.updateServer(); } // daytime switch commands OsEnv daytime_command_env; std::string tod_str = time_of_day_to_string(tod); Util::to_lower(tod_str); daytime_command_env.override("PEKWM_SYS_TIMEOFDAY", tod_str); const SysConfig::string_vector &commands = _cfg.getDaytimeCommands(); SysConfig::string_vector::const_iterator it(commands.begin()); for (; it != commands.end(); ++it) { std::vector args = StringUtil::shell_split(*it); _os->processExec(args, &daytime_command_env); } return tod; } #ifndef UNITTEST static void usage(int ret) { std::cout << "usage: " << progname << " [-dh]" << std::endl; std::cout << " -d --display Display to connect to." << std::endl; std::cout << " -f --log-file Set log file." << std::endl; std::cout << " -h --help Show this info." << std::endl; std::cout << " -l --log-level Set log level." << std::endl; std::cout << " -t --theme Path to theme." << std::endl; exit(ret); } int main(int argc, char *argv[]) { pledge_x11_required(""); progname = argv[0]; const char *display = NULL; std::string theme; std::string config_file = Util::getEnv("PEKWM_CONFIG_FILE"); bool interactive = false; static struct option opts[] = { {const_cast("display"), required_argument, nullptr, 'd'}, {const_cast("help"), no_argument, nullptr, 'h'}, {const_cast("log-level"), required_argument, nullptr, 'l'}, {const_cast("log-file"), required_argument, nullptr, 'f'}, {const_cast("theme"), required_argument, nullptr, 't'}, {const_cast("interactive"), no_argument, nullptr, 'i'}, {nullptr, 0, nullptr, 0} }; int ch; while ((ch = getopt_long(argc, argv, "c:d:h:il:f:t:", opts, nullptr)) != -1) { switch (ch) { case 'c': config_file = optarg; break; case 'd': display = optarg; break; case 'h': usage(0); break; case 'f': if (! Debug::setLogFile(optarg)) { std::cerr << "Failed to open log file " << optarg << std::endl; } break; case 'l': Debug::setLevel(Debug::getLevel(optarg)); break; case 't': theme = optarg; break; case 'i': interactive = true; break; default: usage(1); break; } } if (! X11::init(display, std::cerr)) { return 1; } struct sigaction act; act.sa_handler = sigHandler; act.sa_mask = sigset_t(); act.sa_flags = SA_NOCLDSTOP | SA_NODEFER; sigaction(SIGCHLD, &act, 0); if (config_file.empty()) { config_file = Util::getConfigDir() + "/config"; } Util::expandFileName(config_file); Destruct os(mkOs()); _hooks = new Hooks(*os); _hooks->load(config_file); Destruct hooks(_hooks); PekwmSys sys(config_file, interactive, *os); return sys.main(theme); } #endif // UNITTEST pekwm-0.4.4/src/sys/SysResources.cc0000664000175000017500000001466515126136025012727 // // SysResources.cc for pekwm // Copyright (C) 2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "Calendar.hh" #include "Debug.hh" #include "SysResources.hh" #include "X11.hh" struct osc_xresource { int code1; int code2; const char *name; }; static struct osc_xresource _osc_to_resource[] = { { 4, 0, "XTerm*color0" }, { 4, 1, "XTerm*color1" }, { 4, 2, "XTerm*color2" }, { 4, 3, "XTerm*color3" }, { 4, 4, "XTerm*color4" }, { 4, 5, "XTerm*color5" }, { 4, 6, "XTerm*color6" }, { 4, 7, "XTerm*color7" }, { 4, 8, "XTerm*color8" }, { 4, 9, "XTerm*color9" }, { 4, 10, "XTerm*color10" }, { 4, 11, "XTerm*color11" }, { 4, 12, "XTerm*color12" }, { 4, 13, "XTerm*color13" }, { 4, 14, "XTerm*color14" }, { 4, 15, "XTerm*color15" }, { 10, -1, "XTerm*foreground" }, { 11, -1, "XTerm*background" }, { -1, -1, nullptr } }; SysResources::SysResources(const SysConfig &cfg) : _cfg(cfg), _xterm_hash(0) { } SysResources::~SysResources() { } void SysResources::update(const Daytime &daytime, TimeOfDay tod) { const char *daylight; const char *theme_variant; switch (tod) { case TIME_OF_DAY_DAWN: daylight = "dawn"; theme_variant = "dark"; break; case TIME_OF_DAY_DUSK: daylight = "dusk"; theme_variant = "dark"; break; case TIME_OF_DAY_NIGHT: daylight = "night"; theme_variant = "dark"; break; case TIME_OF_DAY_DAY: default: daylight = "day"; theme_variant = "light"; break; }; setXAtoms(theme_variant); setXResources(daytime, tod, daylight, theme_variant); notifyXTerms(); X11::flush(); } void SysResources::setXAtoms(const char *theme_variant) { X11::setString(X11::getRoot(), PEKWM_THEME_VARIANT, theme_variant); } void SysResources::setXResources(const Daytime &daytime, TimeOfDay tod, const char *daylight, const char *theme_variant) { X11::loadXrmResources(); if (_cfg.haveDpi()) { X11::setXrmString("Xft.dpi", pekwm::to_string(_cfg.getDpi(), 2)); } X11::setXrmString("pekwm.daylight", daylight); X11::setXrmString("pekwm.theme.variant", theme_variant); if (_cfg.haveLocation()) { X11::setXrmString("pekwm.location.latitude", std::to_string(_cfg.getLatitude())); X11::setXrmString("pekwm.location.longitude", std::to_string(_cfg.getLongitude())); X11::setXrmString("pekwm.location.country", _location_country); X11::setXrmString("pekwm.location.city", _location_city); } if (daytime.isValid()) { X11::setXrmString("pekwm.location.sunrise", Calendar(daytime.getSunRise()).toString()); X11::setXrmString("pekwm.location.sunset", Calendar(daytime.getSunSet()).toString()); X11::setXrmString("pekwm.location.dawn", Calendar(daytime.getDawn()).toString()); X11::setXrmString("pekwm.location.night", Calendar(daytime.getNight()).toString()); } setConfiguredXResources(tod); X11::saveXrmResources(); } void SysResources::setXResourceDpi() { if (! _cfg.haveDpi()) { return; } X11::loadXrmResources(); X11::setXrmString("Xft.dpi", pekwm::to_string(_cfg.getDpi(), 2)); X11::saveXrmResources(); } void SysResources::setConfiguredXResources(TimeOfDay tod) { removeStaleThemeXresources(); setXResourcesMap(_cfg.getXResources(tod), "configuration"); setXResourcesMap(_cfg.getThemeXResources(), "theme"); _theme_x_resources = _cfg.getThemeXResources(); } void SysResources::setXResourcesMap(const SysConfig::string_map &x_resources, const char *ctx) { SysConfig::string_map::const_iterator it(x_resources.begin()); for (; it != x_resources.end(); ++it) { X11::setXrmString(it->first, it->second); } P_TRACE("set " << x_resources.size() << " X resources from " << ctx); } void SysResources::removeStaleThemeXresources() { const SysConfig::string_map &theme_x_resources = _cfg.getThemeXResources(); std::string val; SysConfig::string_map::iterator old_it(_theme_x_resources.begin()); std::vector del_names; for (; old_it != _theme_x_resources.end(); ++old_it) { SysConfig::string_map::const_iterator new_it = theme_x_resources.find(old_it->first); // If the resource no longer exists and still has its original // value, remove it from the resources. if (new_it == theme_x_resources.end() && X11::getXrmString(old_it->first, val) && val == old_it->second) { del_names.push_back(old_it->first); } } X11::xrmDeleteResources(del_names); } void SysResources::notifyXTerms() { // Avoid sending messages to all clients if no relevant Xrm resource // has changed since last run. uint xterm_hash = calcXTermHash(); if (xterm_hash == _xterm_hash) { return; } std::vector windows; readClientList(windows); P_TRACE("checking " << windows.size() << " windows for XTerm clients"); std::vector::iterator it(windows.begin()); for (; it != windows.end(); ++it) { X11::ClassHint class_hint; if (X11::getClassHint(*it, class_hint) && strcmp("XTerm", class_hint.getClass()) == 0) { notifyXTerm(*it); } } } void SysResources::notifyXTerm(Window win) { P_TRACE("notify XTerm " << win << " using XTERM_CONTROL"); XEvent ev = {}; ev.type = ev.xclient.type = ClientMessage; ev.xclient.serial = 0; ev.xclient.send_event = True; ev.xclient.message_type = X11::getAtom(XTERM_CONTROL); ev.xclient.window = win; ev.xclient.format = 8; for (int i = 0; _osc_to_resource[i].name; i++) { std::string value; if (! X11::getXrmString(_osc_to_resource[i].name, value)) { continue; } if (_osc_to_resource[i].code2 == -1) { snprintf(ev.xclient.data.b, sizeof(ev.xclient.data.b), "%d;%s", _osc_to_resource[i].code1, value.c_str()); } else { snprintf(ev.xclient.data.b, sizeof(ev.xclient.data.b), "%d;%d;%s", _osc_to_resource[i].code1, _osc_to_resource[i].code2, value.c_str()); } X11::sendEvent(win, False, 0, &ev); } } bool SysResources::readClientList(std::vector &windowsv) { ulong actual; Window *windows; if (! X11::getProperty(X11::getRoot(), X11::getAtom(PEKWM_CLIENT_LIST), XA_WINDOW, 0, reinterpret_cast(&windows), &actual)) { return false; } windowsv.clear(); for (ulong i = 0; i < actual; i++) { windowsv.push_back(windows[i]); } X11::free(windows); return true; } uint SysResources::calcXTermHash() { std::string buf; for (int i = 0; _osc_to_resource[i].name; i++) { buf += std::to_string(i); std::string value; if (! X11::getXrmString(_osc_to_resource[i].name, value)) { continue; } buf += value; } return pekwm::str_hash(buf); } pekwm-0.4.4/src/sys/Makefile.am0000664000175000017500000000076715126136025012001 bin_PROGRAMS = pekwm_sys pekwm_sys_SOURCES = pekwm_sys.cc pekwm_sys.hh \ SysConfig.cc SysConfig.hh \ SysMonitorChange.cc SysMonitorChange.hh \ SysMonitorConfig.cc SysMonitorConfig.hh \ SysResources.cc SysResources.hh \ XSettings.cc XSettings.hh pekwm_sys_CXXFLAGS = $(LIB_CFLAGS) $(libcurl_CFLAGS) $(libudev_CFLAGS) \ -I../lib pekwm_sys_LDADD = ../lib/libpekwm_lib.a ../tk/libpekwm_tk.a $(LIB_LIBS) \ $(libcurl_LIBS) $(libudev_LIBS) EXTRA_DIST = CMakeLists.txt pekwm-0.4.4/src/sys/Makefile.in0000664000175000017500000010250515164641454012014 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = pekwm_sys$(EXEEXT) subdir = src/sys ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_pekwm_sys_OBJECTS = pekwm_sys-pekwm_sys.$(OBJEXT) \ pekwm_sys-SysConfig.$(OBJEXT) \ pekwm_sys-SysMonitorChange.$(OBJEXT) \ pekwm_sys-SysMonitorConfig.$(OBJEXT) \ pekwm_sys-SysResources.$(OBJEXT) pekwm_sys-XSettings.$(OBJEXT) pekwm_sys_OBJECTS = $(am_pekwm_sys_OBJECTS) am__DEPENDENCIES_1 = pekwm_sys_DEPENDENCIES = ../lib/libpekwm_lib.a ../tk/libpekwm_tk.a \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) pekwm_sys_LINK = $(CXXLD) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pekwm_sys-SysConfig.Po \ ./$(DEPDIR)/pekwm_sys-SysMonitorChange.Po \ ./$(DEPDIR)/pekwm_sys-SysMonitorConfig.Po \ ./$(DEPDIR)/pekwm_sys-SysResources.Po \ ./$(DEPDIR)/pekwm_sys-XSettings.Po \ ./$(DEPDIR)/pekwm_sys-pekwm_sys.Po am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(pekwm_sys_SOURCES) DIST_SOURCES = $(pekwm_sys_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIB_CFLAGS = @LIB_CFLAGS@ LIB_LIBS = @LIB_LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PEKWM_FEATURES = @PEKWM_FEATURES@ PEKWM_SH = @PEKWM_SH@ PEKWM_THEMES = @PEKWM_THEMES@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TK_CFLAGS = @TK_CFLAGS@ TK_LIBS = @TK_LIBS@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libcurl_CFLAGS = @libcurl_CFLAGS@ libcurl_LIBS = @libcurl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ libjpeg_CFLAGS = @libjpeg_CFLAGS@ libjpeg_LIBS = @libjpeg_LIBS@ libpng_CFLAGS = @libpng_CFLAGS@ libpng_LIBS = @libpng_LIBS@ libudev_CFLAGS = @libudev_CFLAGS@ libudev_LIBS = @libudev_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pango_CFLAGS = @pango_CFLAGS@ pango_LIBS = @pango_LIBS@ pangocairo_CFLAGS = @pangocairo_CFLAGS@ pangocairo_LIBS = @pangocairo_LIBS@ pangoxft_CFLAGS = @pangoxft_CFLAGS@ pangoxft_LIBS = @pangoxft_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xext_CFLAGS = @xext_CFLAGS@ xext_LIBS = @xext_LIBS@ xft_CFLAGS = @xft_CFLAGS@ xft_LIBS = @xft_LIBS@ xinerama_CFLAGS = @xinerama_CFLAGS@ xinerama_LIBS = @xinerama_LIBS@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ xrandr_CFLAGS = @xrandr_CFLAGS@ xrandr_LIBS = @xrandr_LIBS@ pekwm_sys_SOURCES = pekwm_sys.cc pekwm_sys.hh \ SysConfig.cc SysConfig.hh \ SysMonitorChange.cc SysMonitorChange.hh \ SysMonitorConfig.cc SysMonitorConfig.hh \ SysResources.cc SysResources.hh \ XSettings.cc XSettings.hh pekwm_sys_CXXFLAGS = $(LIB_CFLAGS) $(libcurl_CFLAGS) $(libudev_CFLAGS) \ -I../lib pekwm_sys_LDADD = ../lib/libpekwm_lib.a ../tk/libpekwm_tk.a $(LIB_LIBS) \ $(libcurl_LIBS) $(libudev_LIBS) EXTRA_DIST = CMakeLists.txt all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/sys/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/sys/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files clean-binPROGRAMS: -$(am__rm_f) $(bin_PROGRAMS) pekwm_sys$(EXEEXT): $(pekwm_sys_OBJECTS) $(pekwm_sys_DEPENDENCIES) $(EXTRA_pekwm_sys_DEPENDENCIES) @rm -f pekwm_sys$(EXEEXT) $(AM_V_CXXLD)$(pekwm_sys_LINK) $(pekwm_sys_OBJECTS) $(pekwm_sys_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_sys-SysConfig.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_sys-SysMonitorChange.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_sys-SysMonitorConfig.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_sys-SysResources.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_sys-XSettings.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_sys-pekwm_sys.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` pekwm_sys-pekwm_sys.o: pekwm_sys.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -MT pekwm_sys-pekwm_sys.o -MD -MP -MF $(DEPDIR)/pekwm_sys-pekwm_sys.Tpo -c -o pekwm_sys-pekwm_sys.o `test -f 'pekwm_sys.cc' || echo '$(srcdir)/'`pekwm_sys.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_sys-pekwm_sys.Tpo $(DEPDIR)/pekwm_sys-pekwm_sys.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pekwm_sys.cc' object='pekwm_sys-pekwm_sys.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_sys-pekwm_sys.o `test -f 'pekwm_sys.cc' || echo '$(srcdir)/'`pekwm_sys.cc pekwm_sys-pekwm_sys.obj: pekwm_sys.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -MT pekwm_sys-pekwm_sys.obj -MD -MP -MF $(DEPDIR)/pekwm_sys-pekwm_sys.Tpo -c -o pekwm_sys-pekwm_sys.obj `if test -f 'pekwm_sys.cc'; then $(CYGPATH_W) 'pekwm_sys.cc'; else $(CYGPATH_W) '$(srcdir)/pekwm_sys.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_sys-pekwm_sys.Tpo $(DEPDIR)/pekwm_sys-pekwm_sys.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pekwm_sys.cc' object='pekwm_sys-pekwm_sys.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_sys-pekwm_sys.obj `if test -f 'pekwm_sys.cc'; then $(CYGPATH_W) 'pekwm_sys.cc'; else $(CYGPATH_W) '$(srcdir)/pekwm_sys.cc'; fi` pekwm_sys-SysConfig.o: SysConfig.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -MT pekwm_sys-SysConfig.o -MD -MP -MF $(DEPDIR)/pekwm_sys-SysConfig.Tpo -c -o pekwm_sys-SysConfig.o `test -f 'SysConfig.cc' || echo '$(srcdir)/'`SysConfig.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_sys-SysConfig.Tpo $(DEPDIR)/pekwm_sys-SysConfig.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SysConfig.cc' object='pekwm_sys-SysConfig.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_sys-SysConfig.o `test -f 'SysConfig.cc' || echo '$(srcdir)/'`SysConfig.cc pekwm_sys-SysConfig.obj: SysConfig.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -MT pekwm_sys-SysConfig.obj -MD -MP -MF $(DEPDIR)/pekwm_sys-SysConfig.Tpo -c -o pekwm_sys-SysConfig.obj `if test -f 'SysConfig.cc'; then $(CYGPATH_W) 'SysConfig.cc'; else $(CYGPATH_W) '$(srcdir)/SysConfig.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_sys-SysConfig.Tpo $(DEPDIR)/pekwm_sys-SysConfig.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SysConfig.cc' object='pekwm_sys-SysConfig.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_sys-SysConfig.obj `if test -f 'SysConfig.cc'; then $(CYGPATH_W) 'SysConfig.cc'; else $(CYGPATH_W) '$(srcdir)/SysConfig.cc'; fi` pekwm_sys-SysMonitorChange.o: SysMonitorChange.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -MT pekwm_sys-SysMonitorChange.o -MD -MP -MF $(DEPDIR)/pekwm_sys-SysMonitorChange.Tpo -c -o pekwm_sys-SysMonitorChange.o `test -f 'SysMonitorChange.cc' || echo '$(srcdir)/'`SysMonitorChange.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_sys-SysMonitorChange.Tpo $(DEPDIR)/pekwm_sys-SysMonitorChange.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SysMonitorChange.cc' object='pekwm_sys-SysMonitorChange.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_sys-SysMonitorChange.o `test -f 'SysMonitorChange.cc' || echo '$(srcdir)/'`SysMonitorChange.cc pekwm_sys-SysMonitorChange.obj: SysMonitorChange.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -MT pekwm_sys-SysMonitorChange.obj -MD -MP -MF $(DEPDIR)/pekwm_sys-SysMonitorChange.Tpo -c -o pekwm_sys-SysMonitorChange.obj `if test -f 'SysMonitorChange.cc'; then $(CYGPATH_W) 'SysMonitorChange.cc'; else $(CYGPATH_W) '$(srcdir)/SysMonitorChange.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_sys-SysMonitorChange.Tpo $(DEPDIR)/pekwm_sys-SysMonitorChange.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SysMonitorChange.cc' object='pekwm_sys-SysMonitorChange.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_sys-SysMonitorChange.obj `if test -f 'SysMonitorChange.cc'; then $(CYGPATH_W) 'SysMonitorChange.cc'; else $(CYGPATH_W) '$(srcdir)/SysMonitorChange.cc'; fi` pekwm_sys-SysMonitorConfig.o: SysMonitorConfig.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -MT pekwm_sys-SysMonitorConfig.o -MD -MP -MF $(DEPDIR)/pekwm_sys-SysMonitorConfig.Tpo -c -o pekwm_sys-SysMonitorConfig.o `test -f 'SysMonitorConfig.cc' || echo '$(srcdir)/'`SysMonitorConfig.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_sys-SysMonitorConfig.Tpo $(DEPDIR)/pekwm_sys-SysMonitorConfig.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SysMonitorConfig.cc' object='pekwm_sys-SysMonitorConfig.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_sys-SysMonitorConfig.o `test -f 'SysMonitorConfig.cc' || echo '$(srcdir)/'`SysMonitorConfig.cc pekwm_sys-SysMonitorConfig.obj: SysMonitorConfig.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -MT pekwm_sys-SysMonitorConfig.obj -MD -MP -MF $(DEPDIR)/pekwm_sys-SysMonitorConfig.Tpo -c -o pekwm_sys-SysMonitorConfig.obj `if test -f 'SysMonitorConfig.cc'; then $(CYGPATH_W) 'SysMonitorConfig.cc'; else $(CYGPATH_W) '$(srcdir)/SysMonitorConfig.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_sys-SysMonitorConfig.Tpo $(DEPDIR)/pekwm_sys-SysMonitorConfig.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SysMonitorConfig.cc' object='pekwm_sys-SysMonitorConfig.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_sys-SysMonitorConfig.obj `if test -f 'SysMonitorConfig.cc'; then $(CYGPATH_W) 'SysMonitorConfig.cc'; else $(CYGPATH_W) '$(srcdir)/SysMonitorConfig.cc'; fi` pekwm_sys-SysResources.o: SysResources.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -MT pekwm_sys-SysResources.o -MD -MP -MF $(DEPDIR)/pekwm_sys-SysResources.Tpo -c -o pekwm_sys-SysResources.o `test -f 'SysResources.cc' || echo '$(srcdir)/'`SysResources.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_sys-SysResources.Tpo $(DEPDIR)/pekwm_sys-SysResources.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SysResources.cc' object='pekwm_sys-SysResources.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_sys-SysResources.o `test -f 'SysResources.cc' || echo '$(srcdir)/'`SysResources.cc pekwm_sys-SysResources.obj: SysResources.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -MT pekwm_sys-SysResources.obj -MD -MP -MF $(DEPDIR)/pekwm_sys-SysResources.Tpo -c -o pekwm_sys-SysResources.obj `if test -f 'SysResources.cc'; then $(CYGPATH_W) 'SysResources.cc'; else $(CYGPATH_W) '$(srcdir)/SysResources.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_sys-SysResources.Tpo $(DEPDIR)/pekwm_sys-SysResources.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SysResources.cc' object='pekwm_sys-SysResources.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_sys-SysResources.obj `if test -f 'SysResources.cc'; then $(CYGPATH_W) 'SysResources.cc'; else $(CYGPATH_W) '$(srcdir)/SysResources.cc'; fi` pekwm_sys-XSettings.o: XSettings.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -MT pekwm_sys-XSettings.o -MD -MP -MF $(DEPDIR)/pekwm_sys-XSettings.Tpo -c -o pekwm_sys-XSettings.o `test -f 'XSettings.cc' || echo '$(srcdir)/'`XSettings.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_sys-XSettings.Tpo $(DEPDIR)/pekwm_sys-XSettings.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='XSettings.cc' object='pekwm_sys-XSettings.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_sys-XSettings.o `test -f 'XSettings.cc' || echo '$(srcdir)/'`XSettings.cc pekwm_sys-XSettings.obj: XSettings.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -MT pekwm_sys-XSettings.obj -MD -MP -MF $(DEPDIR)/pekwm_sys-XSettings.Tpo -c -o pekwm_sys-XSettings.obj `if test -f 'XSettings.cc'; then $(CYGPATH_W) 'XSettings.cc'; else $(CYGPATH_W) '$(srcdir)/XSettings.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_sys-XSettings.Tpo $(DEPDIR)/pekwm_sys-XSettings.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='XSettings.cc' object='pekwm_sys-XSettings.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_sys_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_sys-XSettings.obj `if test -f 'XSettings.cc'; then $(CYGPATH_W) 'XSettings.cc'; else $(CYGPATH_W) '$(srcdir)/XSettings.cc'; fi` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pekwm_sys-SysConfig.Po -rm -f ./$(DEPDIR)/pekwm_sys-SysMonitorChange.Po -rm -f ./$(DEPDIR)/pekwm_sys-SysMonitorConfig.Po -rm -f ./$(DEPDIR)/pekwm_sys-SysResources.Po -rm -f ./$(DEPDIR)/pekwm_sys-XSettings.Po -rm -f ./$(DEPDIR)/pekwm_sys-pekwm_sys.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pekwm_sys-SysConfig.Po -rm -f ./$(DEPDIR)/pekwm_sys-SysMonitorChange.Po -rm -f ./$(DEPDIR)/pekwm_sys-SysMonitorConfig.Po -rm -f ./$(DEPDIR)/pekwm_sys-SysResources.Po -rm -f ./$(DEPDIR)/pekwm_sys-XSettings.Po -rm -f ./$(DEPDIR)/pekwm_sys-pekwm_sys.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ install-am install-binPROGRAMS install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% pekwm-0.4.4/src/sys/SysConfig.hh0000664000175000017500000001025015126136025012156 // // SysConfig.hh for pekwm // Copyright (C) 2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_SYS_CONFIG_HH_ #define _PEKWM_SYS_CONFIG_HH_ #include "CfgParser.hh" #include "Daytime.hh" #include "Os.hh" extern "C" { #include } class SysConfig { public: typedef std::vector string_vector; typedef std::map string_map; SysConfig(const std::string &config_file, Os *os); SysConfig(const SysConfig &cfg); ~SysConfig(); bool parseConfig(); bool isXSettingsEnabled() const { return _enable_xsettings; } const std::string& getXSettingsPath() const { return _xsettings_path; } bool haveDpi() const { return _dpi_override != 0.0 || ! isnan(_dpi); } double getDpi() const { return _dpi_override == 0.0 ? _dpi : _dpi_override; } void setDpiOverride(double dpi) { _dpi_override = dpi; } bool isLocationLookup() const { return _location_lookup; } bool haveLocation() const { return ! isnan(_latitude) && ! isnan(_longitude); } double getLatitude() const { return _latitude; } void setLatitude(double latitude) { _latitude = latitude; } double getLongitude() const { return _longitude; } void setLongitude(double longitude) { _longitude = longitude; } const std::string &getTimeOfDay() const { return _tod; } const std::string &getMonitorsPath() const { return _monitors_path; } bool isMonitorLoadOnChange() const { return _monitor_load_on_change; } bool isMonitorAutoConfig() const { return _monitor_auto_configure; } const string_vector &getDaytimeCommands() const { return _daytime_commands; } const string_vector &getLocationCommands() const { return _location_commands; } const std::string &getNetTheme() const { return _net_theme; } const std::string &getNetIconTheme() const { return _net_icon_theme; } const string_map &getXResources(TimeOfDay tod) const { if (tod == TIME_OF_DAY_DAY) { return _x_resources_day; } else if (tod == TIME_OF_DAY_DAWN && !_x_resources_dawn.empty()) { return _x_resources_dawn; } else if (tod == TIME_OF_DAY_DUSK && !_x_resources_dawn.empty()) { return _x_resources_dusk; } else { return _x_resources_night; } } void setXResources(TimeOfDay tod, const string_map &x_resources) { if (tod == TIME_OF_DAY_DAY) { _x_resources_day = x_resources; } else if (tod == TIME_OF_DAY_DAWN) { _x_resources_dawn = x_resources; } else if (tod == TIME_OF_DAY_DUSK) { _x_resources_dusk = x_resources; } else { _x_resources_night = x_resources; } } const string_map &getThemeXResources() const { return _theme_x_resources; } void setThemeXResources(const string_map &theme_x_resources) { _theme_x_resources = theme_x_resources; } static void parseConfigXResources(CfgParser::Entry *section, string_map &resources, const std::string &key); private: void parseCommands(CfgParser::Entry *section, string_vector &commands); std::string _config_file; Os *_os; bool _enable_xsettings; std::string _xsettings_path; double _dpi; double _dpi_override; bool _location_lookup; double _latitude; double _longitude; std::string _tod; /* Commands run whenever daytime changes */ string_vector _daytime_commands; /* Commands run whenever location changes */ string_vector _location_commands; std::string _monitors_path; /* if true, monitor configuration is loaded (if matching) upon * connect/disconnect of a monitor */ bool _monitor_load_on_change; /* if true, monitor will be auto configured right of current monitor * upon connect if load is disabled/fails. */ bool _monitor_auto_configure; /* If set, update Net/ThemeName XSetting with no suffix or -dark * suffix depending on time of day */ std::string _net_theme; /* Set Net/IconThemeName if non-empty */ std::string _net_icon_theme; /* X resources set on dawn */ string_map _x_resources_dawn; /* X resources set on day */ string_map _x_resources_day; /* X resources set on dusk */ string_map _x_resources_dusk; /* X resources set on night */ string_map _x_resources_night; /* X resources set by current theme */ string_map _theme_x_resources; }; #endif // _PEKWM_SYS_CONFIG_HH_ pekwm-0.4.4/src/sys/XSettings.cc0000664000175000017500000002453315126136025012201 // // XSettings.cc for pekwm // Copyright (C) 2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "CfgParser.hh" #include "Charset.hh" #include "Debug.hh" #include "Util.hh" #include "XSettings.hh" std::string _quote(const std::string &str_in) { std::string str; Charset::Utf8Iterator it(str_in); for (; ! it.end(); ++it) { const char *c = *it; if (c[1] == '\0' && (c[0] == '\\' || c[0] == '"')) { str += '\\'; } str += c; } return str; } void XSetting::write(std::ostream &os, const std::string &name) { os.put(_type); os.put(0); uint16_t name_len = static_cast(name.size()); os.write(reinterpret_cast(&name_len), 2); os.write(name.c_str(), name_len); writePad(os, name_len, 4); os.write(reinterpret_cast(&_last_changed), 4); } void XSetting::writePad(std::ostream &os, size_t len, size_t multiple) { int pad_bytes = len % multiple; if (pad_bytes != 0) { pad_bytes = 4 - pad_bytes; } for (int i = 0; i < pad_bytes; i++) { os.put(0); } } /** * Validate name against XSETTINGS specification. * * (A-Z, a-z, 0-9, _ and /, no leading or ending /, no double //, must * start with A-Z or a-z, not empty) */ bool XSetting::validateName(const std::string &name, std::string &error) { error = ""; if (name.empty()) { error = "name must not be empty"; } else if (! ((name[0] >= 'A' && name[0] <= 'Z') || (name[0] >= 'a' && name[0] <= 'z'))) { error = "name must start with a-z, A-Z"; } else if (name[name.size() - 1] == '/') { error = "name must not end with /"; } int last_slash = -1;; int name_size = static_cast(name.size()); for (int i = 1; error.empty() && i < name_size; i++) { if (name[i] == '/' && last_slash == (i - 1)) { error = "name must not contain //"; } else if (name[i] == '/') { last_slash = i; } else if (! ((name[i] >= 'A' && name[i] <= 'Z') || (name[i] >= 'a' && name[i] <= 'z') || (name[i] >= '0' && name[i] <= '9'))) { error = "name can only contain a-z, A-Z, 0-9 and /"; } } return error.empty(); } void XSettingString::write(std::ostream &os, const std::string &name) { XSetting::write(os, name); uint32_t value_len = static_cast(_value.size()); os.write(reinterpret_cast(&value_len), 4); os.write(_value.c_str(), value_len); writePad(os, value_len, 4); } std::string XSettingString::toString() const { std::string str("s"); return str + _quote(_value); } void XSettingInteger::write(std::ostream &os, const std::string &name) { XSetting::write(os, name); os.write(reinterpret_cast(&_value), 4); } std::string XSettingInteger::toString() const { std::string str("i"); return str + std::to_string(_value); } void XSettingColor::write(std::ostream &os, const std::string &name) { XSetting::write(os, name); os.write(reinterpret_cast(&_r), 2); os.write(reinterpret_cast(&_b), 2); os.write(reinterpret_cast(&_g), 2); os.write(reinterpret_cast(&_a), 2); } std::string XSettingColor::toString() const { std::stringstream buf; buf << "c(" << _r << ", " << _g << ", " << _b << ", " << _a << ")"; return buf.str(); } XSettingColor* mkXSettingColor(const std::string &str) { if (str.size() < 10 || str[0] != 'c' || str[1] != '(' || str[str.size() - 1] != ')') { return nullptr; } std::vector toks; if (Util::splitString(str.substr(2, str.size() - 3), toks, ",", 0, true) != 4) { return nullptr; } try { uint16_t r = std::stoi(toks[0]); uint16_t g = std::stoi(toks[1]); uint16_t b = std::stoi(toks[2]); uint16_t a = std::stoi(toks[3]); return new XSettingColor(r, g, b, a); } catch (std::invalid_argument&) { return nullptr; } } XSetting* mkXSetting(const std::string &str) { if (str.empty()) { return nullptr; } switch (str[0]) { case 's': return new XSettingString(str.substr(1)); case 'i': try { int value = std::stoi(str.substr(1)); return new XSettingInteger(value); } catch (std::invalid_argument&) { return nullptr; } case 'c': return mkXSettingColor(str); default: return nullptr; } } XSettings::XSettings() : _session_atom(None), _owner(false) { _window = X11::createWmWindow(X11::getRoot(), -200, -200, 5, 5, InputOutput, PropertyChangeMask); } XSettings::~XSettings() { map::iterator it(_settings.begin()); for (; it != _settings.end(); ++it) { delete it->second; } X11::destroyWindow(_window); } bool XSettings::setServerOwner() { _owner = false; std::string screen_num = std::to_string(X11::getScreenNum()); std::string session_name("_XSETTINGS_S" + screen_num); _session_atom = X11::getAtomId(session_name); X11::grabServer(); Window session_owner = X11::getSelectionOwner(_session_atom); if (session_owner != None) { P_LOG(session_name << " already owned by " << session_owner << ", not claiming ownership"); X11::selectInput(session_owner, StructureNotifyMask); X11::ungrabServer(false); return false; } Time timestamp; getTime(timestamp); X11::setSelectionOwner(_session_atom, _window, timestamp); X11::ungrabServer(false); session_owner = X11::getSelectionOwner(_session_atom); if (session_owner != _window) { P_LOG("failed to set ownership on " << session_name); return false; } _owner = true; P_LOG("updated xsettings owner " << session_name << " to " << _window); sendOwnerMessage(timestamp); return true; } void XSettings::clearServerOwner() { if (_owner) { Time timestamp; getTime(timestamp); X11::setSelectionOwner(_session_atom, None); } _owner = false; } void XSettings::sendOwnerMessage(Time timestamp) { X11::sendEvent(X11::getRoot(), X11::getRoot(), X11::getAtom(MANAGER), StructureNotifyMask, timestamp, _session_atom, _window); } void XSettings::updateServer() { std::stringstream buf; Time timestamp; unsigned long serial = getTime(timestamp); writeProp(buf, serial); Atom atom = X11::getAtom(XSETTINGS_SETTINGS); const std::string &val = buf.str(); const uchar *val_c = reinterpret_cast(val.c_str()); X11::changeProperty(_window, atom, atom, 8, PropModeReplace, val_c, val.size()); P_TRACE("set _XSETTINGS_SETTINGS on " << std::hex << _window << std::dec << ", wrote " << val.size() << " bytes"); } void XSettings::selectOwnerDestroyInput() { X11::grabServer(); Window session_owner = X11::getSelectionOwner(_session_atom); if (session_owner != None) { X11::selectInput(session_owner, StructureNotifyMask); } X11::ungrabServer(false); } bool XSettings::load(const std::string &source, CfgParserSource::Type type) { P_TRACE("loading XSETTINGS from " << source); CfgParser cfg(CfgParserOpt("")); if (! cfg.parse(source, type)) { return false; } CfgParser::Entry *section = cfg.getEntryRoot()->findSection("SETTINGS"); if (section == nullptr) { return true; } CfgParser::Entry::entry_cit it(section->begin()); for (; it != section->end(); ++it) { XSetting *setting = nullptr; std::string error; if (XSetting::validateName((*it)->getName(), error)) { setting = mkXSetting((*it)->getValue()); if (! setting) { error = "invalid setting value"; } } if (setting) { set((*it)->getName(), setting); } else { P_WARN("invalid setting " << (*it)->getValue() << " at " << (*it)->getSourceName() << ":" << (*it)->getLine() << ": " << error); } } return true; } bool XSettings::save(const std::string &path) { P_TRACE("saving XSETTINGS to " << path); std::ofstream os(path.c_str()); if (! os.good()) { return false; } save(os); os.close(); return true; } void XSettings::save(std::ostream &os) { os << "# written by pekwm_sys, overwritten by Sys XSave" << std::endl; os << "Settings {" << std::endl; map::iterator it(_settings.begin()); for (; it != _settings.end(); ++it) { os << "\t\"" << _quote(it->first) << "\" = \"" << it->second->toString() << "\"" << std::endl; } os << "}" << std::endl; } void XSettings::writeProp(std::ostream &os, unsigned long serial) { int n = 1; if (reinterpret_cast(&n)[0]) { os.put(LSBFirst); } else { os.put(MSBFirst); } os.put(0); os.put(0); os.put(0); os.write(reinterpret_cast(&serial), 4); uint32_t num_settings = static_cast(_settings.size()); os.write(reinterpret_cast(&num_settings), 4); map::iterator it(_settings.begin()); for (; it != _settings.end(); ++it) { it->second->write(os, it->first); } } /** * Get setting with the provided key, returns nullptr if it is not set. */ const XSetting* XSettings::get(const std::string &name) const { map::const_iterator it(_settings.find(name)); return it == _settings.end() ? nullptr : it->second; } /** * Add string setting, overwrites existing value if any. */ void XSettings::setString(const std::string &name, const std::string &value) { set(name, new XSettingString(value)); } /** * Add int32 setting, overwrites existing value if any. */ void XSettings::setInt32(const std::string &name, int32_t value) { set(name, new XSettingInteger(value)); } /** * Add color setting, overwrites existing value if any. */ void XSettings::setColor(const std::string &name, uint16_t r, uint16_t g, uint16_t b, uint16_t a) { set(name, new XSettingColor(r, g, b, a)); } /** * Set property in settings, NOT updating value on X server. */ void XSettings::set(const std::string &name, XSetting *setting) { map::iterator it(_settings.find(name)); if (it == _settings.end()) { _settings[name] = setting; } else { if (setting->getLastChanged() == 0) { // last changed not set and previous value exist, // increment last changed. uint32_t last_changed = it->second->getLastChanged() + 1; setting->setLastChanged(last_changed); } delete it->second; it->second = setting; } } /** * Remove setting, independent of type, from configured settings. */ void XSettings::remove(const std::string &name) { map::iterator it(_settings.find(name)); if (it != _settings.end()) { delete it->second; _settings.erase(it); } } /** * Get current time of server by generating an event and reading the * timestamp on it. * * @return Time on server. */ unsigned long XSettings::getTime(Time &cur_time) const { X11::changeProperty(_window, X11::getAtom(WM_CLASS), X11::getAtom(STRING), 8, PropModeAppend, 0, 0); XEvent event; X11::getWindowEvent(_window, PropertyChangeMask, event); cur_time = event.xproperty.time; return event.xproperty.serial; } pekwm-0.4.4/src/sys/SysMonitorConfig.hh0000664000175000017500000000772015126136025013536 // // SysMonitorConfig.hh for pekwm // Copyright (C) 2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_SYS_MONITOR_CONFIG_HH_ #define _PEKWM_SYS_MONITOR_CONFIG_HH_ #include #include #include #include "config.h" #include "CfgParser.hh" #include "Md5.hh" #include "Types.hh" #include "X11_XRandr.hh" class SysMonitorConfig { public: class MonitorConfig { public: MonitorConfig() : _refresh_rate(0.0), _pos_x(0), _pos_y(0), _rotation(RR_Rotate_0) { } MonitorConfig(const std::string &name, const std::string &mode_name, const std::string &edid_md5, double refresh_rate, int pos_x, int pos_y, Rotation rotation) : _name(name), _mode_name(mode_name), _edid_md5(edid_md5), _refresh_rate(refresh_rate), _pos_x(pos_x), _pos_y(pos_y), _rotation(rotation) { } const std::string &getName() const { return _name; } const std::string &getModeName() const { return _mode_name; } const std::string &getEdidMd5() const { return _edid_md5; } const double getRefreshRate() const { return _refresh_rate; } const int getPosX() const { return _pos_x; } const int getPosY() const { return _pos_y; } Rotation getRotation() const { return _rotation; } private: std::string _name; std::string _mode_name; std::string _edid_md5; double _refresh_rate; int _pos_x; int _pos_y; Rotation _rotation; }; class MonitorsConfig { public: typedef std::vector vector; typedef vector::iterator iterator; typedef vector::const_iterator const_iterator; MonitorsConfig(int width = 0, int height = 0, int width_mm = 0, int height_mm = 0) : _width(width), _height(height), _width_mm(width_mm), _height_mm(height_mm) { } const std::string &getId() const { return _id; } int getWidth() const { return _width; } int getHeight() const { return _height; } void setWidth(int width) { _width = width; } void setHeight(int height) { _height = height; } int getWidthMm() const { return _width_mm; } int getHeightMm() const { return _height_mm; } void setWidthMm(int width_mm) { _width_mm = width_mm; } void setHeightMm(int height_mm) { _height_mm = height_mm; } bool haveSize() const { return _width > 0 && _height > 0 && _width_mm > 0 && _height_mm > 0; } void add(const MonitorConfig &monitor) { _monitors.push_back(monitor); updateId(); } const_iterator begin() const { return _monitors.begin(); } const_iterator end() const { return _monitors.end(); } private: void updateId() { Md5 md5; const_iterator it(begin()); for (; it != end(); ++it) { md5.update(it->getName()); md5.update(it->getEdidMd5()); } md5.finalize(); _id = md5.hexDigest(); } std::string _id; int _width; int _height; int _width_mm; int _height_mm; vector _monitors; }; SysMonitorConfig(); ~SysMonitorConfig(); bool load(const std::string &path); bool load(CfgParser::Entry *section); bool save(const std::string &path); bool save(std::ostream &os); bool mk(MonitorsConfig &monitors); std::string mkId(); bool find(MonitorsConfig &monitors); bool apply(const MonitorsConfig &monitors); bool autoConfig(); void add(const MonitorsConfig &monitors) { _config[monitors.getId()] = monitors; } private: MonitorsConfig loadMonitors(CfgParser::Entry *section); MonitorConfig loadMonitor(CfgParser::Entry *section); void saveMonitors(std::ostream &os, const MonitorsConfig &msc) const; void saveMonitor(std::ostream &os, const MonitorConfig &mc) const; bool applyMonitor(X11_XRandr_ScreenResources *sr, const MonitorConfig &mc); /** screen resources representing the current screen configuration. */ X11_XRandr_ScreenResources *_sr; /** current configuration. */ MonitorsConfig _monitors; std::map _config; }; #endif // _PEKWM_SYS_MONITOR_CONFIG_HH_ pekwm-0.4.4/src/sys/pekwm_sys.hh0000664000175000017500000000533415126136025012302 // // pekwm_sys.hh for pekwm // Copyright (C) 2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_SYS_HH_ #define _PEKWM_SYS_HH_ #include "Compat.hh" #include "Daytime.hh" #include "SysConfig.hh" #include "SysMonitorChange.hh" #include "SysResources.hh" #include "Timeouts.hh" #include "XSettings.hh" class PekwmSys { public: PekwmSys(const std::string &config_file, bool interactive, Os *os); ~PekwmSys(); int main(const std::string &theme); #ifndef UNITTEST private: #endif // UNITTEST void handleSigchld(); void handleXEvent(XEvent &ev); void handleStdin(); void handleSetXSETTING(const std::vector &args, enum XSettingType type); bool setXSettingInteger(const std::string &key, const std::string &sval); bool setXSettingColor(const std::string &key, const std::string &sval); bool setXSettingString(const std::string &key, const std::string &sval); void handleMonitorChange(); void handleXSave(); bool handleSetTimeOfDay(const std::vector &args); void handleSetDpi(const std::vector &args); void handleMonLoad(const std::vector &args); void handleMonSave(const std::vector &args); void handleTheme(const StringView &theme); void reload(); bool monLoad(); bool monAutoConfig(); TimeOfDay getEffectiveTimeOfDay() const { return getEffectiveTimeOfDay(_tod); } TimeOfDay getEffectiveTimeOfDay(TimeOfDay tod) const { return isTimeOfDayOverride() ? _tod_override : tod; } bool isTimeOfDayOverride() const { return _tod_override != static_cast(-1); } void updateLocation(); TimeOfDay updateDaytime(time_t now); enum TimeOfDay timeOfDayChanged(enum TimeOfDay tod); std::string themeSuffix(enum TimeOfDay tod) { return tod == TIME_OF_DAY_DAY ? "" : "-Dark"; } void setNetTheme(TimeOfDay tod) { const std::string &theme = _cfg.getNetTheme(); if (theme.empty()) { _xsettings.remove("Net/ThemeName"); } else { _xsettings.setString("Net/ThemeName", theme + themeSuffix(tod)); } } void setNetIconTheme() { const std::string &theme = _cfg.getNetIconTheme(); if (theme.empty()) { _xsettings.remove("Net/IconThemeName"); } else { _xsettings.setString("Net/IconThemeName", theme); } } void setDpi() { if (_cfg.haveDpi()) { int dpi = static_cast(_cfg.getDpi() * 1024); _xsettings.setInt32("Xft/DPI", dpi); } } bool _stop; Timeouts _timeouts; bool _interactive; Os *_os; OsSelect *_select; SysConfig _cfg; SysResources _resources; SysMonitorChange _monitor_change; XSettings _xsettings; Daytime _daytime; TimeOfDay _tod; TimeOfDay _tod_override; }; #endif // _PEKWM_SYS_HH_ pekwm-0.4.4/src/sys/SysConfig.cc0000664000175000017500000001004215126136025012143 // // SysConfig.cc for pekwm // Copyright (C) 2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "CfgParser.hh" #include "Debug.hh" #include "SysConfig.hh" #include "Util.hh" #include "Compat.hh" extern "C" { #include } SysConfig::SysConfig(const std::string &config_file, Os *os) : _config_file(config_file), _os(os), _enable_xsettings(true), _xsettings_path("~/.pekwm/xsettings.save"), _dpi(NAN), _dpi_override(0.0), _location_lookup(false), _latitude(NAN), _longitude(NAN), _monitors_path("~/.pekwm/monitors.save"), _monitor_load_on_change(false), _monitor_auto_configure(false) { Util::expandFileName(_xsettings_path); Util::expandFileName(_monitors_path); } SysConfig::SysConfig(const SysConfig &cfg) : _config_file(cfg._config_file), _os(cfg._os), _enable_xsettings(cfg._enable_xsettings), _xsettings_path(cfg._xsettings_path), _dpi(cfg._dpi), _dpi_override(cfg._dpi_override), _location_lookup(cfg._location_lookup), _latitude(cfg._latitude), _longitude(cfg._longitude), _tod(cfg._tod), _daytime_commands(cfg._daytime_commands), _location_commands(cfg._location_commands), _monitors_path(cfg._monitors_path), _monitor_load_on_change(cfg._monitor_load_on_change), _monitor_auto_configure(cfg._monitor_auto_configure), _net_theme(cfg._net_theme), _net_icon_theme(cfg._net_icon_theme), _x_resources_dawn(cfg._x_resources_dawn), _x_resources_day(cfg._x_resources_day), _x_resources_dusk(cfg._x_resources_dusk), _x_resources_night(cfg._x_resources_night) { } SysConfig::~SysConfig() { } bool SysConfig::parseConfig() { CfgParser cfg(CfgParserOpt("")); if (! cfg.parse(_config_file, CfgParserSource::SOURCE_FILE, true)) { return false; } CfgParserKeys keys; keys.add_bool("XSETTINGS", _enable_xsettings, true); keys.add_path("XSETTINGSPATH", _xsettings_path, "~/.pekwm/xsettings.save"); keys.add_bool("LOCATIONLOOKUP", _location_lookup, false); keys.add_path("MONITORSPATH", _monitors_path, "~/.pekwm/monitors.save"); keys.add_bool("MONITORLOADONCHANGE", _monitor_load_on_change, false); keys.add_bool("MONITORAUTOCONFIGURE", _monitor_auto_configure, false); keys.add_numeric("DPI", _dpi, NAN); keys.add_numeric("LATITUDE", _latitude, NAN, -90.0, 90.0); keys.add_numeric("LONGITUDE", _longitude, NAN, -180.0, 180.0); keys.add_string("TIMEOFDAY", _tod, "AUTO"); keys.add_string("NETTHEME", _net_theme, ""); keys.add_string("NETICONTHEME", _net_icon_theme, ""); CfgParser::Entry *sys = cfg.getEntryRoot()->findSection("SYS"); CfgParser::Entry *xresources; if (sys) { sys->parseKeyValues(keys.begin(), keys.end()); parseCommands(sys->findSection("DAYTIMECOMMANDS"), _daytime_commands); parseCommands(sys->findSection("LOCATIONCOMMANDS"), _location_commands); xresources = sys->findSection("XRESOURCES"); } else { keys.set_defaults(); _daytime_commands.clear(); _location_commands.clear(); xresources = nullptr; } parseConfigXResources(xresources, _x_resources_dawn, "DAWN"); parseConfigXResources(xresources, _x_resources_day, "DAY"); parseConfigXResources(xresources, _x_resources_dusk, "DUSK"); parseConfigXResources(xresources, _x_resources_night, "NIGHT"); return true; } void SysConfig::parseCommands(CfgParser::Entry *section, string_vector &commands) { commands.clear(); if (! section) { return; } CfgParser::Entry::entry_cit it(section->begin()); for (; it != section->end(); ++it) { std::string command = (*it)->getValue(); Util::expandFileName(command); commands.push_back(command); } } void SysConfig::parseConfigXResources(CfgParser::Entry *xresources, string_map &resources, const std::string &key) { resources.clear(); CfgParser::Entry *section = xresources ? xresources->findSection(key) : nullptr; if (! section) { return; } CfgParser::Entry::entry_cit it(section->begin()); for (; it != section->end(); ++it) { resources[(*it)->getName()] = (*it)->getValue(); } } pekwm-0.4.4/src/sys/SysMonitorConfig.cc0000664000175000017500000001775215126136025013532 // // SysMonitorConfig.cc for pekwm // Copyright (C) 2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include #include #include "Debug.hh" #include "SysMonitorConfig.hh" #include "X11.hh" SysMonitorConfig::SysMonitorConfig() : _sr(mkX11_XRandr_ScreenResouces()) { } SysMonitorConfig::~SysMonitorConfig() { delete _sr; } bool SysMonitorConfig::load(const std::string &path) { CfgParser cfg(CfgParserOpt("")); if (! cfg.parse(path, CfgParserSource::SOURCE_FILE, true)) { return false; } return load(cfg.getEntryRoot()); } bool SysMonitorConfig::load(CfgParser::Entry *section) { _config.clear(); if (section == nullptr) { return false; } CfgParser::Entry::entry_cit it(section->begin()); for (; it != section->end(); ++it) { if (! pekwm::ascii_ncase_equal((*it)->getName(), "MONITORS")) { continue; } MonitorsConfig monitors = loadMonitors((*it)->getSection()); _config[monitors.getId()] = monitors; } return true; } SysMonitorConfig::MonitorsConfig SysMonitorConfig::loadMonitors(CfgParser::Entry *section) { if (section == nullptr) { return MonitorsConfig(); } CfgParserKeys keys; int width, height, width_mm, height_mm; keys.add_numeric("WIDTH", width, 0); keys.add_numeric("HEIGHT", height, 0); keys.add_numeric("WIDTHMM", width_mm, 0); keys.add_numeric("HEIGHTMM", height_mm, 0); section->parseKeyValues(keys.begin(), keys.end()); MonitorsConfig monitors(width, height, width_mm, height_mm); CfgParser::Entry::entry_cit it(section->begin()); for (; it != section->end(); ++it) { if (pekwm::ascii_ncase_equal((*it)->getName(), "MONITOR") && (*it)->getSection() != nullptr) { MonitorConfig monitor = loadMonitor((*it)->getSection()); monitors.add(monitor); } } return monitors; } static Rotation _rotation_from_int(int rotation) { switch (rotation) { case 90: return RR_Rotate_90; case 180: return RR_Rotate_180; case 270: return RR_Rotate_270; default: return RR_Rotate_0; } } static int _rotation_to_int(Rotation rotation) { switch (rotation) { case RR_Rotate_90: return 90; case RR_Rotate_180: return 180; case RR_Rotate_270: return 270; default: return 0; } } SysMonitorConfig::MonitorConfig SysMonitorConfig::loadMonitor(CfgParser::Entry *section) { CfgParserKeys keys; std::string mode_name, edid; int pos_x, pos_y, rotation_int; double refresh; keys.add_string("MODENAME", mode_name); keys.add_string("EDID", edid); keys.add_numeric("REFRESHRATE", refresh, 0.0, 0.0); keys.add_numeric("POSX", pos_x, 0); keys.add_numeric("POSY", pos_y, 0); keys.add_numeric("ROTATION", rotation_int, 0, 0, 270); section->parseKeyValues(keys.begin(), keys.end()); return MonitorConfig(section->getValue(), mode_name, edid, refresh, pos_x, pos_y, _rotation_from_int(rotation_int)); } bool SysMonitorConfig::save(const std::string &path) { std::ofstream ofs(path.c_str(), std::ios::out | std::ios::trunc); if (ofs.good()) { return save(ofs); } return false; } bool SysMonitorConfig::save(std::ostream &os) { std::map::iterator it(_config.begin()); for (; it != _config.end(); ++it) { if (it != _config.begin()) { os << std::endl; } saveMonitors(os, it->second); } return true; } void SysMonitorConfig::saveMonitors(std::ostream &os, const MonitorsConfig &msc) const { os << "Monitors = \"" << msc.getId() << "\" {" << std::endl << "\tWidth = \"" << msc.getWidth() << "\"" << std::endl << "\tHeight = \"" << msc.getHeight() << "\"" << std::endl << "\tWidthMm = \"" << msc.getWidthMm() << "\"" << std::endl << "\tHeightMm = \"" << msc.getHeightMm() << "\"" << std::endl; MonitorsConfig::const_iterator it(msc.begin()); for (; it != msc.end(); ++it) { if (it != msc.begin()) { os << std::endl; } saveMonitor(os, *it); } os << "}" << std::endl; } void SysMonitorConfig::saveMonitor(std::ostream &os, const MonitorConfig &mc) const { os << "\tMonitor = \"" << mc.getName() << "\" {" << std::endl << "\t\tModeName = \"" << mc.getModeName() << "\"" << std::endl << "\t\tEdid = \"" << mc.getEdidMd5() << "\"" << std::endl << "\t\tRefreshRate = \"" << pekwm::to_string(mc.getRefreshRate(), 2) << "\"" << std::endl << "\t\tPosX = \"" << mc.getPosX() << "\"" << std::endl << "\t\tPosY = \"" << mc.getPosY() << "\"" << std::endl << "\t\tRotate = \"" << _rotation_to_int(mc.getRotation()) << "\"" << std::endl << "\t}" << std::endl; } /** * Construct a MonitorsConfig object from the current Xrandr configuration. */ bool SysMonitorConfig::mk(MonitorsConfig &monitors) { Destruct sr(mkX11_XRandr_ScreenResouces()); if (sr->empty()) { std::ostringstream os; os << X11::getWidth() << "x" << X11::getHeight(); MonitorConfig monitor("X11", os.str(), "", 0.0, 0, 0, RR_Rotate_0); monitors.add(monitor); return true; } monitors.setWidth(X11::getWidth()); monitors.setHeight(X11::getHeight()); monitors.setWidthMm(X11::getWidthMm()); monitors.setHeightMm(X11::getHeightMm()); for (int i = 0; i < sr->size(); i++) { X11_XRandr_OutputInfo *oi = sr->getOutput(i); Destruct mi( sr->getModeInfo(oi->getCrtcModeId())); if (! oi->isConnected() || ! oi->haveCrtc() || *mi == nullptr) { continue; } Md5 edidMd5(oi->getEdid()); monitors.add( MonitorConfig(oi->getName(), mi->getName(), edidMd5.hexDigest(), mi->getRefresh(), oi->getCrtcX(), oi->getCrtcY(), oi->getCrtcRotation())); } return true; } std::string SysMonitorConfig::mkId() { if (! X11::hasExtensionXRandr()) { return "X11"; } Md5 md5; Destruct sr(mkX11_XRandr_ScreenResouces()); for (int i = 0; i < sr->size(); i++) { X11_XRandr_OutputInfo *oi = sr->getOutput(i); if (oi->isConnected()) { md5.update(oi->getName()); Md5 edidMd5(oi->getEdid()); md5.update(edidMd5.hexDigest()); } } md5.finalize(); return md5.hexDigest(); } bool SysMonitorConfig::find(MonitorsConfig &monitors) { std::string id = mkId(); if (id.empty()) { return false; } std::map::iterator it(_config.find(id)); if (it == _config.end()) { P_TRACE("did not find a configuration for id " << id << " looking in " << _config.size() << " configurations"); return false; } monitors = it->second; return true; } bool SysMonitorConfig::apply(const MonitorsConfig &monitors) { Destruct sr(mkX11_XRandr_ScreenResouces()); if (sr->empty()) { return false; } MonitorsConfig::const_iterator it(monitors.begin()); for (; it != monitors.end(); ++it) { if (! applyMonitor(*sr, *it)) { return false; } } if (monitors.haveSize()) { X11_XRandr_SetSize(monitors.getWidth(), monitors.getHeight(), monitors.getWidthMm(), monitors.getHeightMm()); } return true; } bool SysMonitorConfig::applyMonitor(X11_XRandr_ScreenResources *sr, const MonitorConfig &mc) { Destruct mi( sr->findModeInfo(mc.getModeName(), mc.getRefreshRate())); if (*mi == nullptr) { P_LOG("mode " << mc.getModeName() << "@" << mc.getRefreshRate() << " not found for " << "output " << mc.getName()); return false; } if (! sr->haveOutput(mc.getName())) { P_LOG("output " << mc.getName() << " not found"); return false; } X11_XRandr_OutputInfo *oi = sr->getOutput(mc.getName()); if (! oi->isConnected()) { P_LOG("output " << oi->getName() << " not connected"); return false; } return sr->setCrtcConfig(oi, mc.getPosX(), mc.getPosY(), *mi, static_cast(mc.getRotation())); } bool SysMonitorConfig::autoConfig() { Destruct newSr(mkX11_XRandr_ScreenResouces()); if (! X11::hasExtensionXRandr() || newSr->empty()) { return false; } for (int i = 0; i < newSr->size(); i++) { X11_XRandr_OutputInfo *oi = newSr->getOutput(i); if (oi->isCrtcUsed()) { continue; } } return true; } pekwm-0.4.4/src/panel/0000775000175000017500000000000015164641623010303 5pekwm-0.4.4/src/panel/WidgetFactory.hh0000664000175000017500000000171715126136025013316 // // WidgetFactory.hh for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_WIDGET_FACTORY_HH_ #define _PEKWM_PANEL_WIDGET_FACTORY_HH_ #include "pekwm_panel.hh" #include "PanelConfig.hh" #include "PanelTheme.hh" #include "PanelWidget.hh" #include "VarData.hh" #include "WmState.hh" #include "Os.hh" /** * Widget construction. */ class WidgetFactory { public: WidgetFactory(Os *os, PWinObj* parent, Observer* observer, const PanelTheme& theme, VarData& var_data, WmState& wm_state) : _data(os, observer, theme, var_data, wm_state), _parent(parent) { } PanelWidget* construct(const WidgetConfig& cfg); private: PanelWidget* mk(const WidgetConfig& cfg); void addClicks(const WidgetConfig& cfg, PanelWidget *widget); PanelWidgetData _data; PWinObj* _parent; }; #endif // _PEKWM_PANEL_WIDGET_FACTORY_HH_ pekwm-0.4.4/src/panel/PanelTheme.hh0000664000175000017500000000352415126136025012563 // // PanelTheme.hh for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_PANEL_THEME_HH_ #define _PEKWM_PANEL_PANEL_THEME_HH_ #include #include "pekwm_panel.hh" #include "CfgParser.hh" #include "X11.hh" #include "../tk/PFont.hh" #include "../tk/PTexture.hh" /** * Theme for the panel and its widgets. */ class PanelTheme { public: PanelTheme(); ~PanelTheme(); void load(const std::string &theme_dir, const std::string& theme_path); void unload(); void setIconPath(const std::string& config_path, const std::string& theme_path); uint getHeight(void) const { return _height; } PFont *getFont(ClientState state) const; PTexture *getBackground(void) const { return _background; } PTexture *getSep(void) const { return _sep; } PTexture *getHandle(void) const { return _handle; } // Bar specific themeing XColor *getBarBorder(void) const { return _bar_border; } XColor *getBarFill(void) const { return _bar_fill; } private: void loadState(CfgParser::Entry *section, ClientState state); void check(void); /** Panel height, can be fixed or calculated from font size */ uint _height; /** Set to true after load has been called. */ bool _loaded; /** Panel background texture. */ PTexture *_background; /** If < 255 (dervied from 0-100%) panel background is blended on top of background image. */ uchar _background_opacity; /** Texture rendered between widgets in the bar. */ PTexture *_sep; /** Texture rendered at the left and right of the bar, optional. */ PTexture *_handle; PFont* _fonts[CLIENT_STATE_NO]; PFont::Color* _colors[CLIENT_STATE_NO]; /** Bar border color. */ XColor *_bar_border; /** Bar fill color. */ XColor *_bar_fill; }; #endif // _PEKWM_PANEL_PANEL_THEME_HH_ pekwm-0.4.4/src/panel/BarWidget.hh0000664000175000017500000000502115126136025012403 // // BarWidget.hh for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // // DOC // // Renders a filled rectangle, with an optional text string in it, that is // changing color depending on the fill level. // // The field should be a value between 0 and 100. // // Color is selected based on the value, first color with a value below the // current value is chosen. Given the configuration below and a value of 80 // #cccc00 will be selected. // // ``` // Bar = "field" { // Size = "Pixels 24" // Text = "F" // Colors { // Percent = "0" { // Color = "#00cc00" // } // Percent = "75" { // Color = "#cccc00" // } // Percent = "90" { // Color = "#cc0000" // } // } // } // // # Rendering with two values, extra-field on top of field is also possible. // Bar = "field extra-field" { // } // // ``` // ENDDOC #ifndef _PEKWM_PANEL_BAR_WIDGET_HH_ #define _PEKWM_PANEL_BAR_WIDGET_HH_ #include #include #include "CfgParser.hh" #include "Observable.hh" #include "PanelWidget.hh" #include "VarData.hh" /** * Widget display a bar filled from 0-100% getting fill percentage * from external command data. */ class BarWidget : public PanelWidget { public: BarWidget(const PanelWidgetData &data, const PWinObj* parent, const WidgetConfig& cfg, const std::string& field, const std::string& field_extra); virtual ~BarWidget(void); const char *getName() const { return "Bar"; } virtual void notify(Observable* observable, Observation *observation) { FieldObservation *efo = dynamic_cast(observation); if (efo != nullptr && efo->getField() == _field) { _dirty = true; } PanelWidget::notify(observable, observation); } virtual void render(Render &rend, PSurface *surface); private: void renderFill(Render &rend, PSurface *surface, const std::string &field, bool checker); int getBarWidth() const { return getWidth() - 3; } int getBarHeight() const { return _theme.getHeight() - 4; } int getBarFill(float percent) const; float getPercent(const std::string& str) const; void parseConfig(const CfgParser::Entry* section); void parseColors(const CfgParser::Entry* section); void addColor(float percent, XColor* color); std::string _field; /** extra field value rendered on-top of field */ std::string _field_extra; std::string _text; XColor *_checker_color; std::vector > _colors; }; #endif // _PEKWM_PANEL_BAR_WIDGET_HH_ pekwm-0.4.4/src/panel/CMakeLists.txt0000664000175000017500000000166715126136025012766 cmake_minimum_required(VERSION 3.10) add_executable(pekwm_panel pekwm_panel.cc ../pekwm_env.cc BarWidget.cc ClientInfo.cc ClientListWidget.cc ExternalCommandData.cc IconWidget.cc PanelConfig.cc PanelTheme.cc PanelWidget.cc SystrayWidget.cc TextFormatter.cc TextWidget.cc VarData.cc WidgetFactory.cc WmState.cc) target_compile_definitions(pekwm_panel PUBLIC PEKWM_SH="${SH}") target_include_directories(pekwm_panel PUBLIC ${common_INCLUDE_DIRS}) target_link_libraries(pekwm_panel lib tk ${common_LIBRARIES}) install(TARGETS pekwm_panel DESTINATION bin) add_executable(pekwm_panel_sysinfo pekwm_panel_sysinfo.c) if (CMAKE_SYSTEM_NAME STREQUAL "SunOS") target_link_libraries(pekwm_panel_sysinfo -lkstat) endif (CMAKE_SYSTEM_NAME STREQUAL "SunOS") install(TARGETS pekwm_panel_sysinfo DESTINATION share/pekwm/scripts) pekwm-0.4.4/src/panel/pekwm_panel.cc0000664000175000017500000004610415126136025013032 // // pekwm_panel.cc for pekwm // Copyright (C) 2021-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "Charset.hh" #include "Compat.hh" #include "Cond.hh" #include "Debug.hh" #include "Os.hh" #include "Observable.hh" #include "Util.hh" #include "String.hh" #include "X11.hh" #include "../pekwm_env.hh" #include "pekwm_panel.hh" #include "ExternalCommandData.hh" #include "PanelConfig.hh" #include "PanelTheme.hh" #include "PanelWidget.hh" #include "VarData.hh" #include "WidgetFactory.hh" #include "WmState.hh" #include "../tk/CfgUtil.hh" #include "../tk/FontHandler.hh" #include "../tk/ImageHandler.hh" #include "../tk/TextureHandler.hh" #include "../tk/ThemeUtil.hh" #include "../tk/X11App.hh" #include "../tk/X11Util.hh" extern "C" { #include #include #include #include } /** pekwm configuration file. */ static std::string _pekwm_config_file; /** empty string, used as default return value. */ static std::string _empty_string; /** static pekwm resources, accessed via the pekwm namespace. */ static std::string _config_script_path; static ObserverMapping* _observer_mapping = nullptr; static FontHandler* _font_handler = nullptr; static ImageHandler* _image_handler = nullptr; static TextureHandler* _texture_handler = nullptr; namespace pekwm { const std::string& configScriptPath() { return _config_script_path; } ObserverMapping* observerMapping() { return _observer_mapping; } FontHandler* fontHandler() { return _font_handler; } ImageHandler* imageHandler() { return _image_handler; } TextureHandler* textureHandler() { return _texture_handler; } } static void loadTheme(PanelTheme& theme, CfgParser& cfg) { std::string theme_dir, theme_variant, theme_path; bool font_default_x11; std::string font_charset_override; CfgUtil::getThemeDir(cfg.getEntryRoot(), theme_dir, theme_variant, theme_path); CfgUtil::getFontSettings(cfg.getEntryRoot(), font_default_x11, font_charset_override); pekwm::fontHandler()->setDefaultFontX11(font_default_x11); pekwm::fontHandler()->setCharsetOverride(font_charset_override); ThemeUtil::loadRequire(cfg, theme_dir, theme_path); theme.load(theme_dir, theme_path); std::string icon_path; CfgUtil::getIconDir(cfg.getEntryRoot(), icon_path); theme.setIconPath(icon_path, theme_dir + "/icons/"); } static void loadTheme(PanelTheme& theme, const std::string& pekwm_config_file) { CfgParser cfg(CfgParserOpt("")); cfg.parse(pekwm_config_file, CfgParserSource::SOURCE_FILE, true); loadTheme(theme, cfg); } typedef bool(*renderPredFun)(PanelWidget *w, void *opaque); static bool renderPredExposeEv(PanelWidget *w, void *opaque) { XExposeEvent *ev = reinterpret_cast(opaque); return (w->getX() >= ev->x) && (w->getRX() <= (ev->x + ev->width)); } static bool renderPredDirty(PanelWidget *w, void*) { return w->isDirty(); } static bool renderPredAlways(PanelWidget*, void*) { return true; } /** * Widgets in the panel are given a size when configured, can be given * in: * * * pixels, number of pixels * * percent, percent of the screen width the panel is on. * * required, minimum required size. * * *, all space not occupied by the other widgets. All * share the * remaining space. * * required 300px * * ---------------------------------------------------------------------------- * | [WorkspaceNumber] | [Text] | [ClientList] | * ---------------------------------------------------------------------------- * */ class PekwmPanel : public X11App, public Observer { public: PekwmPanel(const PanelConfig &cfg, PanelTheme &theme, XSizeHints *sh); virtual ~PekwmPanel(void); void configure(void); void setStrut(void); void place(void); void render(); virtual void notify(Observable*, Observation *observation); virtual void refresh(bool timed_out); virtual void handleEvent(XEvent *ev); private: virtual ActionEvent *handleButtonPress(XButtonEvent* ev) { X11::setLastEventTime(ev->time); PanelWidget *widget = findWidget(ev->x); if (widget != nullptr) { widget->click(ev->button, ev->x - widget->getX(), ev->y - _gm.y); } return nullptr; } virtual ActionEvent *handleButtonRelease(XButtonEvent* ev) { X11::setLastEventTime(ev->time); return nullptr; } void handleExpose(XExposeEvent *ev) { renderPred(renderPredExposeEv, reinterpret_cast(ev)); } void handlePropertyNotify(XPropertyEvent *ev) { X11::setLastEventTime(ev->time); if (_wm_state.handlePropertyNotify(ev)) { render(); } } virtual void handleFd(int fd) { _ext_data.input(fd); } virtual void handleChildDone(pid_t pid, int) { _ext_data.done(pid, PekwmPanel::ppRemoveFd, reinterpret_cast(this)); } virtual void screenChanged(const ScreenChangeNotification&) { P_TRACE("screen geometry updated, resizing"); place(); resizeWidgets(); } virtual void themeChanged(const std::string& name, const std::string& variant, float scale) { // scale changed, update before re-loadint the theme bool scale_changed = scale != pekwm::textureHandler()->getScale(); if (scale_changed) { pekwm::fontHandler()->setScale(scale); pekwm::imageHandler()->setScale(scale); pekwm::textureHandler()->setScale(scale); } loadTheme(_theme, _pekwm_config_file); setStrut(); place(); // resize widgets after loading, separator size, handles and // scale can alter available amount of space. resizeWidgets(scale_changed); // re-render renderBackground(); renderPred(renderPredAlways, nullptr); } PanelWidget* findWidget(int x) { std::vector::iterator it = _widgets.begin(); for (; it != _widgets.end(); ++it) { if ((*it)->isVisible() && x >= (*it)->getX() && x <= (*it)->getRX()) { return *it; } } return nullptr; } PanelWidget* findWidget(Window win) { std::vector::iterator it = _widgets.begin(); for (; it != _widgets.end(); ++it) { if (*(*it) == win) { return *it; } } return nullptr; } void addWidgets(); void resizeWidgets(bool scale_changed=false); void renderPred(renderPredFun pred, void *opaque); void renderBackground(); int renderHandle(Drawable drawable) { PTexture *handle = _theme.getHandle(); if (! handle) { return 0; } handle->render(drawable, 0, 0, handle->getWidth(), handle->getHeight(), 0, 0); handle->render(drawable, _gm.width - handle->getWidth(), 0, handle->getWidth(), handle->getHeight(), 0, 0); return handle->getWidth(); } static void ppAddFd(int fd, void *opaque) { PekwmPanel *panel = reinterpret_cast(opaque); panel->addFd(fd); } static void ppRemoveFd(int fd, void *opaque) { PekwmPanel *panel = reinterpret_cast(opaque); panel->removeFd(fd); } private: Os* _os; const PanelConfig& _cfg; PanelTheme& _theme; VarData _var_data; ExternalCommandData _ext_data; WmState _wm_state; std::vector _widgets; uint _widgets_visible; PPixmapSurface _background; }; PekwmPanel::PekwmPanel(const PanelConfig &cfg, PanelTheme &theme, XSizeHints *sh) : X11App(Geometry(sh->x, sh->y, static_cast(sh->width), static_cast(sh->height)), X_VALUE|Y_VALUE|WIDTH_VALUE|HEIGHT_VALUE, "", "panel", "pekwm_panel", WINDOW_TYPE_DOCK, sh, true), _os(mkOs()), _cfg(cfg), _theme(theme), _ext_data(cfg, _var_data), _wm_state(_var_data), _widgets_visible(0), _background(sh->width, sh->height) { X11::selectInput(_window, ButtonPressMask|ButtonReleaseMask| ExposureMask| PropertyChangeMask|SubstructureNotifyMask); renderBackground(); setBackground(_background.getDrawable()); Atom state[] = { X11::getAtom(STATE_STICKY), X11::getAtom(STATE_SKIP_TASKBAR), X11::getAtom(STATE_SKIP_PAGER), X11::getAtom(STATE_ABOVE) }; X11::setAtoms(_window, STATE, state, sizeof(state)/sizeof(state[0])); setStrut(); pekwm::observerMapping()->addObserver(&_wm_state, this, 100); } PekwmPanel::~PekwmPanel(void) { if (! _widgets.empty()) { pekwm::observerMapping()->removeObserver(&_var_data, this); } pekwm::observerMapping()->removeObserver(&_wm_state, this); std::vector::iterator it = _widgets.begin(); for (; it != _widgets.end(); ++it) { delete *it; } delete _os; } void PekwmPanel::configure(void) { if (! _widgets.empty()) { pekwm::observerMapping()->removeObserver(&_var_data, this); } addWidgets(); if (! _widgets.empty()) { pekwm::observerMapping()->addObserver(&_var_data, this, 100); } resizeWidgets(); _wm_state.read(); } void PekwmPanel::setStrut(void) { Cardinal strut[STRUT_SIZE] = {0}; if (_cfg.getPlacement() == PANEL_TOP) { strut[STRUT_TOP] = _theme.getHeight(); } else { strut[STRUT_BOTTOM] = _theme.getHeight(); } X11::setCardinals(_window, NET_WM_STRUT, strut, PEKWM_ARRLEN(strut)); } void PekwmPanel::place(void) { Geometry head = X11Util::getHeadGeometry(_cfg.getHead()); int y; if (_cfg.getPlacement() == PANEL_TOP) { y = head.y; } else { y = head.y + head.height - _theme.getHeight(); } moveResize(head.x, y, head.width, _theme.getHeight()); } void PekwmPanel::render(void) { renderPred(renderPredDirty, nullptr); } void PekwmPanel::notify(Observable* o, Observation *observation) { if (dynamic_cast(observation)) { renderBackground(); renderPred(renderPredAlways, nullptr); } else if (dynamic_cast(observation)) { P_LOG("RequiredSizeChanged notification"); resizeWidgets(); renderBackground(); renderPred(renderPredAlways, nullptr); } else { renderPred(renderPredDirty, nullptr); } } void PekwmPanel::refresh(bool timed_out) { _ext_data.refresh(ppAddFd, reinterpret_cast(this)); if (timed_out) { renderPred(renderPredAlways, nullptr); } } void PekwmPanel::handleEvent(XEvent* ev) { PanelWidget *widget = findWidget(ev->xany.window); if (widget != nullptr) { if (widget->handleXEvent(ev)) { return; } } switch (ev->type) { case ButtonPress: P_TRACE("ButtonPress"); handleButtonPress(&ev->xbutton); break; case ButtonRelease: P_TRACE("ButtonRelease"); handleButtonRelease(&ev->xbutton); break; case ConfigureNotify: P_TRACE("ConfigureNotify"); break; case DestroyNotify: P_TRACE("DestroyNotify"); break; case EnterNotify: P_TRACE("EnterNotify"); X11::setLastEventTime(ev->xcrossing.time); break; case Expose: P_TRACE("Expose " << ev->xexpose.x << "x" << ev->xexpose.y << "x" << ev->xexpose.width << "x" << ev->xexpose.height); handleExpose(&ev->xexpose); break; case NoExpose: break; case LeaveNotify: P_TRACE("LeaveNotify"); X11::setLastEventTime(ev->xcrossing.time); break; case KeyPress: case KeyRelease: X11::setLastEventTime(ev->xkey.time); break; case MapNotify: P_TRACE("MapNotify"); break; case MappingNotify: P_TRACE("MappingNotify"); break; case MotionNotify: X11::setLastEventTime(ev->xkey.time); break; case ReparentNotify: P_TRACE("ReparentNotify"); break; case UnmapNotify: P_TRACE("UnmapNotify"); break; case PropertyNotify: P_TRACE("PropertyNotify"); handlePropertyNotify(&ev->xproperty); break; case SelectionClear: X11::setLastEventTime(ev->xselectionclear.time); break; case SelectionRequest: X11::setLastEventTime(ev->xselectionrequest.time); break; case SelectionNotify: X11::setLastEventTime(ev->xselection.time); break; default: P_DBG("UNKNOWN EVENT " << ev->type); break; } } void PekwmPanel::addWidgets(void) { WidgetFactory factory(_os, this, this, _theme, _var_data, _wm_state); std::vector::const_iterator it = _cfg.widgetsBegin(); for (; it != _cfg.widgetsEnd(); ++it) { PanelWidget *widget = factory.construct(*it); if (widget == nullptr) { USER_WARN("failed to construct widget"); continue; } _widgets.push_back(widget); } } void PekwmPanel::resizeWidgets(bool scale_changed) { if (_widgets.empty()) { return; } PTexture *sep = _theme.getSep(); uint num_rest = 0; uint width_left = _gm.width; PTexture *handle = _theme.getHandle(); if (handle) { width_left -= handle->getWidth() * 2; } uint width; PFont *font; float scale = pekwm::textureHandler()->getScale(); _widgets_visible = 0; std::vector::iterator it = _widgets.begin(); for (; it != _widgets.end(); ++it) { if (! Cond::eval((*it)->getIf())) { continue; } if (scale_changed) { (*it)->scaleChanged(); } switch ((*it)->getSizeReq().getUnit()) { case WIDGET_UNIT_PIXELS: width = ThemeUtil::scaledPixelValue( scale, (*it)->getSizeReq().getSize()); width_left -= width; (*it)->setWidth(width); break; case WIDGET_UNIT_PERCENT: width = static_cast(_gm.width * (static_cast( (*it)->getSizeReq().getSize()) / 100)); width_left -= width; (*it)->setWidth(width); break; case WIDGET_UNIT_REQUIRED: width_left -= (*it)->getRequiredSize(); (*it)->setWidth((*it)->getRequiredSize()); break; case WIDGET_UNIT_REST: num_rest++; break; case WIDGET_UNIT_TEXT_WIDTH: font = _theme.getFont(CLIENT_STATE_UNFOCUSED); width = font->getWidth((*it)->getSizeReq().getText()); width_left -= width; (*it)->setWidth(width); break; } if ((*it)->isVisible()) { _widgets_visible++; } } // remove size for separators before calculating rest widget sizes, // this is done after the main calculation to get the correct number // of visible widgets if (_widgets_visible != 0) { width_left -= sep->getWidth() * (_widgets_visible - 1); } uint x = handle ? handle->getWidth() : 0; uint rest = static_cast(width_left / static_cast(num_rest)); for (it = _widgets.begin(); it != _widgets.end(); ++it) { if ((*it)->getSizeReq().getUnit() == WIDGET_UNIT_REST) { (*it)->setWidth(rest); } if (! (*it)->isVisible()) { continue; } (*it)->move(x); x += (*it)->getWidth() + sep->getWidth(); } } void PekwmPanel::renderPred(renderPredFun pred, void *opaque) { if (_widgets_visible == 0) { P_TRACE("no visible widgets to render"); return; } int x = renderHandle(getRenderDrawable()); PanelWidget *last_widget = _widgets.back(); X11Render rend(getRenderDrawable(), getRenderBackground()); RenderSurface surface(rend, _gm); std::vector::iterator it = _widgets.begin(); for (; it != _widgets.end(); ++it) { if (! (*it)->isVisible()) { continue; } bool do_render = pred(*it, opaque); if (do_render) { (*it)->render(rend, &surface); } x += (*it)->getWidth(); if (*it != last_widget) { PTexture *sep = _theme.getSep(); if (do_render) { sep->render(rend, x, 0, sep->getWidth(), sep->getHeight()); } x += sep->getWidth(); } } swapBuffer(); } void PekwmPanel::renderBackground() { if (_background.resize(_gm.width, _gm.height)) { setBackground(_background.getDrawable()); } _theme.getBackground()->render(_background.getDrawable(), 0, 0, _gm.width, _gm.height, _gm.x, _gm.y); renderHandle(_background.getDrawable()); } static bool loadConfig(PanelConfig& cfg, const std::string& file) { if (file.size() && cfg.load(file)) { return true; } std::string panel_config = Util::getConfigDir() + "/panel"; if (cfg.load(panel_config)) { return true; } return cfg.load(SYSCONFDIR "/panel"); } static void init(Display* dpy, float scale) { _observer_mapping = new ObserverMapping(); // options setup in loadTheme later on _font_handler = new FontHandler(scale, false, ""); _image_handler = new ImageHandler(scale); _texture_handler = new TextureHandler(scale); } static void cleanup() { delete _texture_handler; delete _image_handler; delete _font_handler; delete _observer_mapping; } static void usage(const char* name, int ret) { std::cout << "usage: " << name << " [-dh]" << std::endl; std::cout << " -c --config path Configuration file" << std::endl; std::cout << " -C --pekwm-config path pekwm Configuration file" << std::endl; std::cout << " -d --display dpy Display" << std::endl; std::cout << " -h --help Display this information" << std::endl; std::cout << " -f --log-file Set log file." << std::endl; std::cout << " -l --log-level Set log level." << std::endl; exit(ret); } int main(int argc, char *argv[]) { pledge_x11_required(""); std::string config_file; const char* display = NULL; static struct option opts[] = { {const_cast("config"), required_argument, nullptr, 'c'}, {const_cast("pekwm-config"), required_argument, nullptr, 'C'}, {const_cast("display"), required_argument, nullptr, 'd'}, {const_cast("help"), no_argument, nullptr, 'h'}, {const_cast("log-level"), required_argument, nullptr, 'l'}, {const_cast("log-file"), required_argument, nullptr, 'f'}, {nullptr, 0, nullptr, 0} }; Charset::init(); initEnv(false); int ch; while ((ch = getopt_long(argc, argv, "c:C:d:f:hl:", opts, nullptr)) != -1) { switch (ch) { case 'c': config_file = optarg; break; case 'C': _pekwm_config_file = optarg; break; case 'd': display = optarg; break; case 'h': usage(argv[0], 0); break; case 'f': if (! Debug::setLogFile(optarg)) { std::cerr << "Failed to open log file " << optarg << std::endl; } break; case 'l': Debug::setLevel(Debug::getLevel(optarg)); break; default: usage(argv[0], 1); break; } } if (config_file.empty()) { config_file = Util::getConfigDir() + "/panel"; } if (_pekwm_config_file.empty()) { _pekwm_config_file = Util::getConfigDir() + "/config"; } Util::expandFileName(config_file); Util::expandFileName(_pekwm_config_file); initEnvConfig(Util::getDir(_pekwm_config_file), _pekwm_config_file); if (! X11::init(display, std::cerr)) { return 1; } Destruct pekwm_cfg(new CfgParser(CfgParserOpt(""))); (*pekwm_cfg)->parse(_pekwm_config_file, CfgParserSource::SOURCE_FILE, true); float scale; CfgUtil::getScreenScale((*pekwm_cfg)->getEntryRoot(), scale); init(X11::getDpy(), scale); P_TRACE("pekwm_panel PID " << getpid()); { PanelTheme theme; CfgUtil::getScriptsDir((*pekwm_cfg)->getEntryRoot(), _config_script_path); loadTheme(theme, *(*pekwm_cfg)); // free up resources, pekwm_cfg will not be used after this. pekwm_cfg.destruct(); // run in separate scope to get resources cleaned up before // X11 cleanup PanelConfig cfg; if (loadConfig(cfg, config_file)) { Geometry head = X11Util::getHeadGeometry(cfg.getHead()); XSizeHints normal_hints = {0}; normal_hints.flags = PPosition|PSize; normal_hints.x = head.x; normal_hints.width = head.width; normal_hints.height = theme.getHeight(); if (cfg.getPlacement() == PANEL_TOP) { normal_hints.y = head.y; } else { normal_hints.y = head.y + head.height - normal_hints.height; } PekwmPanel panel(cfg, theme, &normal_hints); panel.configure(); panel.mapWindow(); panel.render(); panel.main(cfg.getRefreshIntervalS()); } else { std::cerr << "failed to read panel configuration" << std::endl; } } cleanup(); X11::destruct(); Charset::destruct(); return 0; } pekwm-0.4.4/src/panel/WmState.hh0000664000175000017500000000535515126136025012131 // // WmState.hh for pekwm // Copyright (C) 2022-2024 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_WM_STATE_HH_ #define _PEKWM_PANEL_WM_STATE_HH_ #include "pekwm_panel.hh" #include "ClientInfo.hh" #include "Observable.hh" #include "VarData.hh" #include "X11.hh" /** * Current window manager state. */ class WmState : public Observable { public: /** * Base for all WmState observations. */ class WmStateObservation : public Observation { }; class XROOTPMAP_ID_Changed : public WmStateObservation { }; /** * Observation sent whenever _NET_CURRENT_DESKTOP is changed. */ class ActiveWorkspace_Changed : public WmStateObservation { }; /** * Observation sent whenever _NET_ACTIVE_WINDOW is changed. */ class ActiveWindow_Changed : public WmStateObservation { }; /** * Observation sent whenever the client list of the WM state has been * updated. */ class ClientList_Changed : public WmStateObservation { }; /** * Observation sent whenever a single client state from the client list * has been updated. */ class ClientState_Changed : public WmStateObservation { }; typedef std::vector client_info_vector; typedef client_info_vector::const_iterator client_info_it; WmState(VarData& var_data); virtual ~WmState(void); void read(void); uint getActiveWorkspace(void) const { return _workspace; } const std::string& getWorkspaceName(uint num) const; Window getActiveWindow(void) const { return _active_window; } ClientInfo *findClientInfo(Window win) const; uint numClients(void) const { return _clients.size(); } client_info_it clientsBegin(void) const { return _clients.begin(); } client_info_it clientsEnd(void) const { return _clients.end(); } bool handlePropertyNotify(XPropertyEvent *ev); private: ClientInfo* findClientInfo(Window win, const std::vector &clients) const; ClientInfo* popClientInfo(Window win, std::vector &clients); bool readActiveWorkspace(void); bool readActiveWindow(void); bool readClientList(void); bool readDesktopNames(void); void readRootProperties(void); bool readRootProperty(Atom atom); const std::string& getAtomName(Atom atom); private: VarData& _var_data; Window _active_window; uint _workspace; client_info_vector _clients; std::vector _desktop_names; std::map _atom_names; WmStateObservation _wm_state_observation; XROOTPMAP_ID_Changed _xrootpmap_id_changed; ActiveWorkspace_Changed _active_workspace_changed; ActiveWindow_Changed _active_window_changed; ClientList_Changed _client_list_changed; ClientState_Changed _client_state_changed; }; #endif // _PEKWM_PANEL_WM_STATE_HH_ pekwm-0.4.4/src/panel/PanelWidget.hh0000664000175000017500000000567515126136025012755 // // PanelWidget.hh for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_PANEL_WIDGET_HH_ #define _PEKWM_PANEL_PANEL_WIDGET_HH_ #include #include "pekwm_panel.hh" #include "PanelAction.hh" #include "PanelConfig.hh" #include "PanelTheme.hh" #include "TextFormatter.hh" #include "VarData.hh" #include "WmState.hh" #include "../tk/PWinObj.hh" class PanelWidgetData { public: PanelWidgetData(Os *os_, Observer* observer_, const PanelTheme &theme_, VarData &var_data_, WmState &wm_state_) : os(os_), observer(observer_), theme(theme_), var_data(var_data_), wm_state(wm_state_) { } Os *os; Observer *observer; const PanelTheme &theme; VarData &var_data; WmState &wm_state; }; /** * Base class for all widgets displayed on the panel. */ class PanelWidget : public Observer, public Observable { public: PanelWidget(const PanelWidgetData &data, const PWinObj* parent, const SizeReq& size_req, const std::string& if_); virtual ~PanelWidget(); virtual const char *getName() const = 0; virtual void notify(Observable *, Observation *observation); bool isDirty() const { return _dirty; } bool isVisible() const { return _width != 0 && _cond_true; } int getX(void) const { return _x; } int getRX(void) const { return _rx; } void setButtonAction(int button, const PanelAction &action); virtual void move(int x); uint getWidth(void) const { return _width; } void setWidth(uint width) { _width = width; _rx = _x + width; } const SizeReq& getSizeReq(void) const { return _size_req; } virtual void scaleChanged() { }; std::string getIf() { return _if_tfo.format(); } virtual uint getRequiredSize(void) const { return 0; } virtual void click(int button, int x, int y); virtual void render(Render& render, PSurface*) { render.clear(_x, 0, _width, _theme.getHeight()); _dirty = false; } /** * Return true if win is one of PanelWidget windows (if any are used) */ virtual bool operator==(Window win) const { return false; } /** * Handle X11 event, return true if the event was processed by * this widget. */ virtual bool handleXEvent(XEvent* ev) { return false; } protected: int renderText(Render &rend, PSurface *surface, PFont *font, int x, const std::string& text, uint max_width); void sendRequiredSizeChanged(); void runAction(const PanelAction &action); void runActionExec(const std::string ¶m, const std::string &command); void runActionPekwm(const std::string ¶m, const std::string &command); Os *_os; Observer *_observer; const PanelTheme &_theme; VarData &_var_data; WmState &_wm_state; const PWinObj* _parent; bool _dirty; TextFormatObserver _if_tfo; std::map _button_actions; private: int _x; int _rx; uint _width; SizeReq _size_req; bool _cond_true; }; #endif // _PEKWM_PANEL_PANEL_WIDGET_HH_ pekwm-0.4.4/src/panel/ClientListWidget.hh0000664000175000017500000000353215126136025013756 // // ClientListWidget.hh for pekwm // Copyright (C) 2022-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_CLIENT_LIST_WIDGET_HH_ #define _PEKWM_PANEL_CLIENT_LIST_WIDGET_HH_ #include #include #include "pekwm_panel.hh" #include "Observable.hh" #include "PanelTheme.hh" #include "PanelWidget.hh" #include "WmState.hh" #include "../tk/PImage.hh" /** * List of Frames/Clients on the current workspace. * * ClientList [separator] */ class ClientListWidget : public PanelWidget { public: class Entry { public: Entry(const std::string& name, ClientState state, int x, Window window, PImage *icon) : _name(name), _state(state), _x(x), _window(window), _icon(icon) { } const std::string &getName(void) const { return _name; } ClientState getState(void) const { return _state; } int getX(void) const { return _x; } void setX(int x) { _x = x; } Window getWindow(void) const { return _window; } PImage *getIcon(void) const { return _icon; } private: std::string _name; ClientState _state; int _x; Window _window; PImage *_icon; }; ClientListWidget(const PanelWidgetData &data, const PWinObj* parent, const WidgetConfig& cfg, const std::string& draw_separator); virtual ~ClientListWidget(void); virtual const char *getName() const { return "ClientList"; } virtual void notify(Observable*, Observation*); virtual void click(int button, int x, int); virtual void render(Render &rend, PSurface* surface); private: void initOptions(const std::string& options); Window findClientAt(int x); void update(void); void createEntries(void); int _entry_width; std::vector _entries; bool _draw_icon; bool _draw_separator; }; #endif // _PEKWM_PANEL_CLIENT_LIST_WIDGET_HH_ pekwm-0.4.4/src/panel/TextWidget.hh0000664000175000017500000000222715126136025012630 // // TextWidget.hh for pekwm // Copyright (C) 2022-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_TEXT_WIDGET_HH_ #define _PEKWM_PANEL_TEXT_WIDGET_HH_ #include #include "Observable.hh" #include "PanelWidget.hh" #include "RegexString.hh" #include "TextFormatter.hh" /** * Text widget with format string that is able to reference command * data, window manager state data and environment variables. * * Format $external, $:wm, $_env */ class TextWidget : public PanelWidget { public: TextWidget(const PanelWidgetData &data, const PWinObj* parent, const WidgetConfig& cfg, const std::string& format); virtual ~TextWidget(); virtual const char *getName() const { return "Text"; } virtual void notify(Observable *, Observation *observation); virtual uint getRequiredSize(void) const; virtual void render(Render &rend, PSurface* surface); private: void parseText(const CfgParser::Entry* section); TextFormatObserver _tfo; /** Regex transform of formatted output */ RegexString _transform; }; #endif // _PEKWM_PANEL_TEXT_WIDGET_HH_ pekwm-0.4.4/src/panel/SystrayWidget.cc0000664000175000017500000002243515126136025013353 // // SystrayWidget.cc for pekwm // Copyright (C) 2022-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include extern "C" { #include } #include "Compat.hh" #include "Debug.hh" #include "SystrayWidget.hh" enum XEmbedOpcode { XEMBED_EMBEDDED_NOTIFY = 0 }; enum SystrayOpcode { SYSTEM_TRAY_REQUEST_DOCK = 0, SYSTEM_TRAY_BEGIN_MESSAGE = 1, SYSTEM_TRAY_CANCEL_MESSAGE = 2 }; // SystrayWidget::Client SystrayWidget::Client::Client(Window win, uint side) : PWinObj(false), _xembed_version(0), _xembed_flags(0) { setWindow(win); resize(side, side); X11::selectInput(win, PropertyChangeMask); } SystrayWidget::Client::~Client() { } /** * Return true if the client is set to be mapped/visible. */ bool SystrayWidget::Client::isMapped() const { return (_xembed_flags & XEMBED_FLAG_MAPPED) == XEMBED_FLAG_MAPPED; } void SystrayWidget::Client::sendConfigureNotify() { XConfigureEvent ev = {}; ev.type = ConfigureNotify; ev.event = _window; ev.window = _window; ev.x = _gm.x; ev.y = _gm.y; ev.width = _gm.width; ev.height = _gm.height; X11::sendEvent(_window, False, StructureNotifyMask, reinterpret_cast(&ev)); } // SystrayWidget SystrayWidget::SystrayWidget(const PanelWidgetData &data, const PWinObj* parent, const WidgetConfig& cfg) : PanelWidget(data, parent, cfg.getSizeReq(), cfg.getIf()), _owner(None), _owner_atom(0) { // avoid duplicate mappings, only add if base PanelWidget has not if (_if_tfo.isFixed()) { pekwm::observerMapping()->addObserver(this, _observer, 100); } // owner window XSetWindowAttributes attrs = {0}; attrs.event_mask = SubstructureRedirectMask; _owner = X11::createWindow(X11::getRoot(), -1, -1, 1, 1, 0, CopyFromParent, InputOutput, X11::getVisual(), CWEventMask, &attrs); if (_owner == None) { P_ERR("systray: failed to create owner window"); } else { P_TRACE("systray: owner window " << _owner); } if (claimNetSystray()) { notifyClaimedSystray(); } } SystrayWidget::~SystrayWidget() { while (! _clients.empty()) { removeTrayIcon(*_clients.begin(), true); } X11::destroyWindow(_owner); if (_if_tfo.isFixed()) { pekwm::observerMapping()->removeObserver(this, _observer); } } uint SystrayWidget::getRequiredSize(void) const { uint required_size = _theme.getHeight() * numClientsMapped(); P_TRACE("systray: required size " << required_size); return required_size; } void SystrayWidget::move(int x) { P_TRACE("systray: x: " << x << " width: " << getWidth()); PanelWidget::move(x); client_it it = _clients.begin(); for (; it != _clients.end(); ++it) { if ((*it)->isMapped()) { (*it)->move(x, 0); x += _theme.getHeight(); } else { P_TRACE("systray: skip unmapped client " << (*it)->getWindow()); } } } /** * Custom X event handling for systray to support interaction with systray * clients. */ bool SystrayWidget::handleXEvent(XEvent* ev) { P_TRACE("systray: handle event " << ev->type); switch (ev->type) { case DestroyNotify: return handleDestroyNotify(&ev->xdestroywindow); case ClientMessage: return handleClientMessage(&ev->xclient); case PropertyNotify: return handlePropertyNotify(&ev->xproperty); default: return false; } } SystrayWidget::Client* SystrayWidget::addTrayIcon(Window win) { P_TRACE("systray: add tray icon " << win); int x = getX() + (numClientsMapped() * _theme.getHeight()); int y = 0; SystrayWidget::Client* client = new SystrayWidget::Client(win, _theme.getHeight()); readXEmbedInfo(client); X11::reparentWindow(client->getWindow(), _parent->getWindow(), x, y); client->sendConfigureNotify(); if (client->isMapped()) { P_TRACE("systray: mapping client " << client->getWindow()); X11::mapRaised(client->getWindow()); } _clients.push_back(client); sendRequiredSizeChanged(); return client; } /** * Send message to client notifying it about a successful dock request. */ void SystrayWidget::notifyTrayIcon(SystrayWidget::Client* client) { XClientMessageEvent ev = {0}; ev.type = ClientMessage; ev.window = client->getWindow(); ev.message_type = X11::getAtom(XEMBED); ev.format = 32; ev.data.l[0] = CurrentTime; ev.data.l[1] = XEMBED_EMBEDDED_NOTIFY; ev.data.l[2] = std::min(XEMBED_VERSION, client->getXEmbedVersion()); ev.data.l[3] = _parent->getWindow(); ev.data.l[4] = 0; X11::sendEvent(X11::getRoot(), False, NoEventMask, reinterpret_cast(&ev)); } void SystrayWidget::removeTrayIcon(SystrayWidget::Client* client, bool reparent) { P_TRACE("systray: remove tray icon " << client->getWindow()); client_it it = std::find(_clients.begin(), _clients.end(), client); assert(it != _clients.end()); if (reparent) { X11::reparentWindow((*it)->getWindow(), X11::getRoot(), 0 - (*it)->getWidth(), 0 - (*it)->getHeight()); } delete *it; _clients.erase(it); } SystrayWidget::Client* SystrayWidget::findClient(Window win) const { client_cit it = _clients.begin(); for (; it != _clients.end(); ++it) { if ((*it)->getWindow() == win) { return *it; } } return nullptr; } int SystrayWidget::numClientsMapped() const { int num_mapped = 0; client_cit it = _clients.begin(); for (; it != _clients.end(); ++it) { if ((*it)->isMapped()) { num_mapped++; } } return num_mapped; } /** * Claim ownership of _NET_SYSTEM_TRAY_S0, required step to make systray * clients find the current active tray. */ bool SystrayWidget::claimNetSystray() { std::string default_str = std::to_string(X11::getScreenNum()); std::string session_name("_NET_SYSTEM_TRAY_S" + default_str); _owner_atom = X11::getAtomId(session_name); Window owner = X11::getSelectionOwner(_owner_atom); if (owner && owner != _owner) { P_DBG("systray: " << session_name << " already claimed by " << owner << ", not active"); return false; } X11::setSelectionOwner(_owner_atom, _owner); owner = X11::getSelectionOwner(_owner_atom); if (owner == _owner) { P_TRACE("systray: " << _owner << " claimed ownership of " << session_name); return true; } else { P_DBG("systray: failed to claim ownership ownership of " << session_name << ", owned by " << owner); return false; } } /** * Send event to the root window to notify systray clients that a new * systray is available. */ void SystrayWidget::notifyClaimedSystray() { XClientMessageEvent ev = {0}; ev.type = ClientMessage; ev.window = X11::getRoot(); ev.message_type = X11::getAtom(MANAGER); ev.format = 32; ev.data.l[0] = X11::getLastEventTime(); ev.data.l[1] = _owner_atom; ev.data.l[2] = _owner; ev.data.l[3] = 0; ev.data.l[4] = 0; X11::sendEvent(X11::getRoot(), False, StructureNotifyMask, reinterpret_cast(&ev)); } /** * Handle DestroyNotify, removing client if any of the docked clients. */ bool SystrayWidget::handleDestroyNotify(XDestroyWindowEvent* ev) { SystrayWidget::Client* client = findClient(ev->window); if (client == nullptr) { return false; } removeTrayIcon(client, false); sendRequiredSizeChanged(); return true; } /** * Handle ClientMessage if the message type is NET_SYSTEM_TRAY_OPCODE */ bool SystrayWidget::handleClientMessage(XClientMessageEvent* ev) { if (ev->message_type != X11::getAtom(NET_SYSTEM_TRAY_OPCODE)) { return false; } return handleSystemTrayOpcode(ev->data.l[1], ev->data.l[2]); } /** * Handle PropertyEvent if the property is XEMBED_INFO */ bool SystrayWidget::handlePropertyNotify(XPropertyEvent* ev) { Client* client; if (ev->atom != X11::getAtom(XEMBED_INFO) || (client = findClient(ev->window)) == nullptr) { return false; } const bool is_mapped = client->isMapped(); readXEmbedInfo(client); if (is_mapped != client->isMapped()) { if (client->isMapped()) { P_TRACE("systray: unmapping client " << client->getWindow()); X11::unmapWindow(client->getWindow()); } else { P_TRACE("systray: mapping client " << client->getWindow()); X11::mapRaised(client->getWindow()); } sendRequiredSizeChanged(); } return true; } bool SystrayWidget::handleSystemTrayOpcode(long opcode, long win) { switch (opcode) { case SYSTEM_TRAY_REQUEST_DOCK: { P_TRACE("systray: SYSTEM_TRAY_REQUEST_DOCK " << win); SystrayWidget::Client* client = addTrayIcon(win); notifyTrayIcon(client); return true; } case SYSTEM_TRAY_BEGIN_MESSAGE: P_TRACE("systray: SYSTEM_TRAY_BEGIN_MESSAGE " << win); return true; case SYSTEM_TRAY_CANCEL_MESSAGE: P_TRACE("systray: SYSTEM_TRAY_CANCEL_MESSAGE " << win); return true; default: P_DBG("systray: unknown _NET_SYSTEM_TRAY_OPCODE " << opcode); return false; } } void SystrayWidget::readXEmbedInfo(Client* client) { const Atom xembed_info = X11::getAtom(XEMBED_INFO); uchar *data; ulong actual; if (! X11::getProperty(client->getWindow(), xembed_info, xembed_info, 2, &data, &actual)) { P_WARN("systray: failed to read _XEMBED_INFO from " << client->getWindow()); return; } if (actual == 2) { long *ldata = reinterpret_cast(data); P_TRACE("systray: client " << client->getWindow() << " xembed version " << ldata[0] << " xembed flags " << ldata[1]); client->setXEmbedVersion(ldata[0]); client->setFlags(ldata[1]); } else { P_TRACE("systray: client " << client->getWindow() << " _XEMBED_INFO invalid, setting defaults"); client->setXEmbedVersion(0); client->setFlags(XEMBED_FLAG_MAPPED); } X11::free(data); } pekwm-0.4.4/src/panel/Makefile.am0000664000175000017500000000210515126136025012246 bin_PROGRAMS = pekwm_panel pekwm_panel_SOURCES = pekwm_panel.cc pekwm_panel.hh \ ../pekwm_env.cc \ BarWidget.cc BarWidget.hh \ ClientInfo.cc ClientInfo.hh \ ClientListWidget.cc ClientListWidget.hh \ DateTimeWidget.hh \ ExternalCommandData.cc ExternalCommandData.hh \ IconWidget.cc IconWidget.hh \ PanelAction.hh \ PanelConfig.cc PanelConfig.hh \ PanelTheme.cc PanelTheme.hh \ PanelWidget.cc PanelWidget.hh \ SystrayWidget.cc SystrayWidget.hh \ TextFormatter.cc TextFormatter.hh \ TextWidget.cc TextWidget.hh \ VarData.cc VarData.hh \ WidgetFactory.cc WidgetFactory.hh \ WmState.cc WmState.hh pekwm_panel_CXXFLAGS = $(LIB_CFLAGS) $(TK_CFLAGS) -I../lib pekwm_panel_LDADD = ../lib/libpekwm_lib.a ../tk/libpekwm_tk.a $(LIB_LIBS) $(TK_LIBS) scriptsdir = $(pkgdatadir)/scripts scripts_PROGRAMS = pekwm_panel_sysinfo pekwm_panel_sysinfo_SOURCES = pekwm_panel_sysinfo.c if PEKWM_HOST_SUNOS pekwm_panel_sysinfo_LDFLAGS = -lkstat endif EXTRA_DIST = CMakeLists.txt pekwm-0.4.4/src/panel/TextFormatter.hh0000664000175000017500000000405215126136025013346 // // TextFormatter.hh for pekwm // Copyright (C) 2022 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_TEXT_FORMATTER_HH_ #define _PEKWM_PANEL_TEXT_FORMATTER_HH_ #include #include #include "pekwm_panel.hh" #include "VarData.hh" #include "WmState.hh" class TextFormatter { public: typedef std::string(*formatFun)(TextFormatter *tf, const std::string& buf); TextFormatter(VarData& var_data, WmState& wm_state); ~TextFormatter(); VarData *getVarData() { return &_var_data; } WmState *getWmState() { return &_wm_state; } bool referenceWmState() const { return _check_wm_state; } const std::vector &getFields() const { return _fields; } std::string preprocess(const std::string& raw_format); std::string format(const std::string& pp_format); private: std::string format(const std::string& pp_format, formatFun exp); std::string preprocessVar(const std::string& var); std::string expandVar(const std::string& var); static std::string tfPreprocessVar(TextFormatter *tf, const std::string& var) { return tf->preprocessVar(var); } static std::string tfExpandVar(TextFormatter *tf, const std::string& var) { return tf->expandVar(var); } private: VarData& _var_data; WmState& _wm_state; bool _check_wm_state; std::vector _fields; }; class TextFormatObserver { public: TextFormatObserver(VarData& var_data, WmState& wm_state, Observer* observer, const std::string& format); ~TextFormatObserver(); bool isFixed() const { return _tf.getFields().empty() && ! _tf.referenceWmState(); } std::string format() { return _tf.format(_pp_format); } const std::string& getPpFormat() const { return _pp_format; } bool match(Observation* observation); private: TextFormatObserver(const TextFormatObserver&); TextFormatObserver& operator=(const TextFormatObserver&); TextFormatter _tf; Observer* _observer; std::string _pp_format; }; #endif // _PEKWM_PANEL_TEXT_FORMATTER_HH_ pekwm-0.4.4/src/panel/BarWidget.cc0000664000175000017500000000711315126136025012375 // // BarWidget.cc for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "BarWidget.hh" BarWidget::BarWidget(const PanelWidgetData &data, const PWinObj* parent, const WidgetConfig& cfg, const std::string& field, const std::string& field_extra) : PanelWidget(data, parent, cfg.getSizeReq(), cfg.getIf()), _field(field), _field_extra(field_extra), _checker_color(nullptr) { parseConfig(cfg.getCfgSection()); if (! _field_extra.empty()) { _checker_color = X11::getColor("#999999"); } pekwm::observerMapping()->addObserver(&_var_data, this, 100); } BarWidget::~BarWidget() { X11::returnColor(_checker_color); pekwm::observerMapping()->removeObserver(&_var_data, this); } void BarWidget::render(Render &rend, PSurface *surface) { PanelWidget::render(rend, surface); int width = getBarWidth(); int height = getBarHeight(); rend.setColor(_theme.getBarBorder()->pixel); rend.rectangle(getX() + 1, 1, width, height); renderFill(rend, surface, _field, false); if (! _field_extra.empty()) { renderFill(rend, surface, _field_extra, true); } if (! _text.empty()) { PFont *font = _theme.getFont(CLIENT_STATE_UNFOCUSED); renderText(rend, surface, font, getX() + 2, _text, width - 1); } } void BarWidget::renderFill(Render &rend, PSurface *surface, const std::string &field, bool checker) { int width = getBarWidth(); int height = getBarHeight(); float fill_p = getPercent(_var_data.get(field)); int fill = static_cast(fill_p * (height - 1)); int pixel = getBarFill(fill_p); if (checker) { rend.setFillStyle(RENDER_FILL_CHECKER); rend.setColor(_checker_color ? _checker_color->pixel : X11::getWhitePixel()); rend.fill(getX() + 2, 1 + height - fill, width - 1, fill); rend.setFillStyle(RENDER_FILL_SOLID); } else { rend.setColor(pixel); rend.fill(getX() + 2, 1 + height - fill, width - 1, fill); } } int BarWidget::getBarFill(float percent) const { std::vector >::const_reverse_iterator it = _colors.rbegin(); for (; it != _colors.rend(); ++it) { if (it->first <= percent) { break; } } if (it == _colors.rend()) { return _theme.getBarFill()->pixel; } return it->second->pixel; } float BarWidget::getPercent(const std::string& str) const { try { float percent = std::stof(str); if (percent < 0.0) { percent = 0.0; } else if (percent > 100.0) { percent = 100.0; } return percent / 100.0; } catch (std::invalid_argument&) { return 0.0; } } void BarWidget::parseConfig(const CfgParser::Entry* section) { CfgParserKeys keys; keys.add_string("TEXT", _text, ""); section->parseKeyValues(keys.begin(), keys.end()); parseColors(section); } void BarWidget::parseColors(const CfgParser::Entry* section) { CfgParser::Entry *colors = section->findSection("COLORS"); if (colors == nullptr) { return; } CfgParser::Entry::entry_cit it = colors->begin(); for (; it != colors->end(); ++it) { if (! pekwm::ascii_ncase_equal((*it)->getName(), "PERCENT") || ! (*it)->getSection()) { continue; } float percent = getPercent((*it)->getValue()); CfgParser::Entry *color = (*it)->getSection()->findEntry("COLOR"); if (color) { addColor(percent, X11::getColor(color->getValue())); } } } void BarWidget::addColor(float percent, XColor* color) { std::vector >::iterator it = _colors.begin(); for (; it != _colors.end(); ++it) { if (percent < it->first) { break; } } _colors.insert(it, std::pair(percent, color)); } pekwm-0.4.4/src/panel/ClientListWidget.cc0000664000175000017500000001115315126136025013742 // // ClientListWidget.cc for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "ClientListWidget.hh" #include "Debug.hh" #include "String.hh" ClientListWidget::ClientListWidget(const PanelWidgetData &data, const PWinObj* parent, const WidgetConfig& cfg, const std::string& options) : PanelWidget(data, parent, cfg.getSizeReq(), cfg.getIf()), _entry_width(0), _draw_icon(true), _draw_separator(false) { initOptions(options); // high priority, need to update client list _before_ rendering the // widget to avoid stale icon references pekwm::observerMapping()->addObserver(&_wm_state, this, 50); } ClientListWidget::~ClientListWidget(void) { pekwm::observerMapping()->removeObserver(&_wm_state, this); } void ClientListWidget::initOptions(const std::string& options) { std::vector toks; Util::splitString(options, toks, "\t "); std::vector::iterator it(toks.begin()); for (; it != toks.end(); ++it) { if (pekwm::ascii_ncase_equal("separator", *it)) { _draw_separator = true; } if (pekwm::ascii_ncase_equal("noicon", *it)) { _draw_icon = false; } } } void ClientListWidget::notify(Observable* observable, Observation* observation) { if (dynamic_cast(observation) || dynamic_cast(observation) || dynamic_cast(observation) || dynamic_cast(observation)) { _dirty = true; update(); } PanelWidget::notify(observable, observation); } void ClientListWidget::click(int button, int x, int) { if (button != BUTTON1) { return; } Window window = findClientAt(x); if (window == None) { return; } Cardinal timestamp = 0; X11::getCardinal(window, NET_WM_USER_TIME, timestamp); P_TRACE("ClientListWidget activate " << window << " timestamp " << timestamp); XEvent ev; ev.xclient.type = ClientMessage; ev.xclient.serial = 0; ev.xclient.send_event = True; ev.xclient.message_type = X11::getAtom(NET_ACTIVE_WINDOW); ev.xclient.window = window; ev.xclient.format = 32; ev.xclient.data.l[0] = 2; ev.xclient.data.l[1] = timestamp; ev.xclient.data.l[2] = _wm_state.getActiveWindow(); X11::sendEvent(X11::getRoot(), False, SubstructureRedirectMask|SubstructureNotifyMask, &ev); } void ClientListWidget::render(Render &rend, PSurface* surface) { PanelWidget::render(rend, surface); uint height = _theme.getHeight() - 2; std::vector::iterator it = _entries.begin(); for (; it != _entries.end(); ++it) { PImage *icon = _draw_icon ? it->getIcon() : nullptr; int icon_width = icon ? height + 1 : 0; int x = getX() + it->getX() + icon_width; int entry_width = _entry_width - icon_width; if (_draw_separator && (it + 1) != _entries.end()) { PTexture* sep = _theme.getSep(); entry_width -= sep->getWidth(); sep->render(rend, x + entry_width, 0, sep->getWidth(), sep->getHeight()); } PFont *font = _theme.getFont(it->getState()); int icon_x = renderText(rend, surface, font, x, it->getName(), entry_width); icon_x -= icon_width; if (icon) { if (icon->getHeight() > height) { icon->scale(height, height); } int icon_y = (height - icon->getHeight()) / 2; icon->draw(rend, surface, icon_x, icon_y); } } } Window ClientListWidget::findClientAt(int x) { std::vector::iterator it = _entries.begin(); for (; it != _entries.end(); ++it) { if (x >= it->getX() && x <= (it->getX() + _entry_width)) { return it->getWindow(); } } return None; } void ClientListWidget::update(void) { _entries.clear(); createEntries(); // no clients on active workspace, skip rendering and avoid // division by zero. if (_entries.empty()) { _entry_width = getWidth(); } else { _entry_width = getWidth() / _entries.size(); } int x = 0; std::vector::iterator it = _entries.begin(); for (; it != _entries.end(); ++it) { it->setX(x); x += _entry_width; } } void ClientListWidget::createEntries() { uint workspace = _wm_state.getActiveWorkspace(); WmState::client_info_it it = _wm_state.clientsBegin(); for (; it != _wm_state.clientsEnd(); ++it) { if (! (*it)->displayOn(workspace)) { continue; } ClientState state; if ((*it)->getWindow() == _wm_state.getActiveWindow()) { state = CLIENT_STATE_FOCUSED; } else if ((*it)->hidden) { state = CLIENT_STATE_ICONIFIED; } else { state = CLIENT_STATE_UNFOCUSED; } _entries.push_back(Entry((*it)->getName(), state, 0, (*it)->getWindow(), (*it)->getIcon())); } } pekwm-0.4.4/src/panel/PanelAction.hh0000664000175000017500000000156315126136025012737 #ifndef _PANEL_ACTION_HH_ #define _PANEL_ACTION_HH_ #include enum PanelActionType { PANEL_ACTION_EXEC, PANEL_ACTION_PEKWM, PANEL_ACTION_NO }; class PanelAction { public: PanelAction() : _type(PANEL_ACTION_NO) { } PanelAction(PanelActionType type, const std::string ¶m, const std::string &pp_param) : _type(type), _param(param), _pp_param(pp_param) { } PanelAction(const PanelAction &action) : _type(action.getType()), _param(action.getParam()), _pp_param(action.getPpParam()) { } PanelActionType getType() const { return _type; } const std::string &getParam() const { return _param; } const std::string &getPpParam() const { return _pp_param; } private: PanelActionType _type; std::string _param; /** Preprocessed version of param string using TextFormatter. */ std::string _pp_param; }; #endif // _PANEL_ACTION_HH_ pekwm-0.4.4/src/panel/WidgetFactory.cc0000664000175000017500000000462315126136025013303 // // WidgetFactory.cc for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include #include "BarWidget.hh" #include "ClientListWidget.hh" #include "DateTimeWidget.hh" #include "Debug.hh" #include "IconWidget.hh" #include "TextWidget.hh" #include "TextFormatter.hh" #include "SystrayWidget.hh" #include "WidgetFactory.hh" PanelWidget* WidgetFactory::construct(const WidgetConfig& cfg) { PanelWidget *widget = mk(cfg); if (widget && ! cfg.getClicks().empty()) { addClicks(cfg, widget); } return widget; } PanelWidget* WidgetFactory::mk(const WidgetConfig& cfg) { std::string name = cfg.getName(); Util::to_upper(name); if (name == "BAR") { // field can be configured with one extra field, separated by // space. const std::string &field = cfg.getArg(0); if (field.empty()) { USER_WARN("missing required argument to Bar widget"); } else { std::vector toks; Util::splitString(field, toks, " \t", 2); return new BarWidget(_data, _parent, cfg, toks[0], toks.size() == 2 ? toks[1] : ""); } } else if (name == "CLIENTLIST") { const std::string &separator = cfg.getArg(0); return new ClientListWidget(_data, _parent, cfg, separator); } else if (name == "DATETIME") { const std::string &format = cfg.getArg(0); return new DateTimeWidget(_data, _parent, cfg, format); } else if (name == "ICON") { const std::string &field = cfg.getArg(0); return new IconWidget(_data, _parent, cfg, field); } else if (name == "SYSTRAY") { return new SystrayWidget(_data, _parent, cfg); } else if (name == "TEXT") { const std::string &format = cfg.getArg(0); if (format.empty()) { USER_WARN("missing required argument to Text widget"); } else { return new TextWidget(_data, _parent, cfg, format); } } else { USER_WARN("unknown widget " << cfg.getName()); } return nullptr; } void WidgetFactory::addClicks(const WidgetConfig& cfg, PanelWidget* widget) { TextFormatter tf(_data.var_data, _data.wm_state); const std::vector &clicks = cfg.getClicks(); std::vector::const_iterator it(clicks.begin()); for (; it != clicks.end(); ++it) { std::string pp_param = tf.preprocess(it->getParam()); PanelAction action(it->getType(), it->getParam(), pp_param); widget->setButtonAction(it->getButton(), action); } } pekwm-0.4.4/src/panel/SystrayWidget.hh0000664000175000017500000000443215126136025013362 // // SystrayWidget.hh for pekwm // Copyright (C) 2022-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_SYSTRAY_WIDGET_HH_ #define _PEKWM_PANEL_SYSTRAY_WIDGET_HH_ #include #include "pekwm_panel.hh" #include "CfgParser.hh" #include "PanelWidget.hh" #include "../tk/PWinObj.hh" /** * Widget providing a systray area, only one widget is allowed in the panel * configuration. */ class SystrayWidget : public PanelWidget { public: class Client : public PWinObj { public: Client(Window win, uint side); virtual ~Client(); long getXEmbedVersion() const { return _xembed_version; } void setXEmbedVersion(long v) { _xembed_version = v; } bool isMapped() const; void setFlags(long f) { _xembed_flags = f; } void sendConfigureNotify(); private: long _xembed_version; long _xembed_flags; }; typedef std::vector client_vector; typedef client_vector::iterator client_it; typedef client_vector::const_iterator client_cit; SystrayWidget(const PanelWidgetData &data, const PWinObj* parent, const WidgetConfig& cfg); virtual ~SystrayWidget(); virtual const char *getName() const { return "Systray"; } virtual uint getRequiredSize(void) const; virtual void move(int x); virtual bool operator==(Window win) const { if (win == _owner || win == _parent->getWindow()) { return true; } return findClient(win) != nullptr; } virtual bool handleXEvent(XEvent* ev); private: SystrayWidget::Client* addTrayIcon(Window win); void notifyTrayIcon(SystrayWidget::Client* client); void removeTrayIcon(SystrayWidget::Client* client, bool reparent); SystrayWidget::Client* findClient(Window win) const; int numClientsMapped() const; bool claimNetSystray(); void notifyClaimedSystray(); bool handleDestroyNotify(XDestroyWindowEvent* ev); bool handleClientMessage(XClientMessageEvent* ev); bool handlePropertyNotify(XPropertyEvent* ev); bool handleSystemTrayOpcode(long opcode, long win); void readXEmbedInfo(Client* client); private: /** Owner window for _NET_SYSTEM_TRAY_Sn */ Window _owner; /** _NET_SYSTEM_TRAY_Sn atom */ Atom _owner_atom; /** Clients in the systray */ client_vector _clients; }; #endif // _PEKWM_PANEL_SYSTRAY_WIDGET_HH_ pekwm-0.4.4/src/panel/Makefile.in0000664000175000017500000017142715164641454012306 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = pekwm_panel$(EXEEXT) scripts_PROGRAMS = pekwm_panel_sysinfo$(EXEEXT) subdir = src/panel ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(scriptsdir)" PROGRAMS = $(bin_PROGRAMS) $(scripts_PROGRAMS) am__dirstamp = $(am__leading_dot)dirstamp am_pekwm_panel_OBJECTS = pekwm_panel-pekwm_panel.$(OBJEXT) \ ../pekwm_panel-pekwm_env.$(OBJEXT) \ pekwm_panel-BarWidget.$(OBJEXT) \ pekwm_panel-ClientInfo.$(OBJEXT) \ pekwm_panel-ClientListWidget.$(OBJEXT) \ pekwm_panel-ExternalCommandData.$(OBJEXT) \ pekwm_panel-IconWidget.$(OBJEXT) \ pekwm_panel-PanelConfig.$(OBJEXT) \ pekwm_panel-PanelTheme.$(OBJEXT) \ pekwm_panel-PanelWidget.$(OBJEXT) \ pekwm_panel-SystrayWidget.$(OBJEXT) \ pekwm_panel-TextFormatter.$(OBJEXT) \ pekwm_panel-TextWidget.$(OBJEXT) pekwm_panel-VarData.$(OBJEXT) \ pekwm_panel-WidgetFactory.$(OBJEXT) \ pekwm_panel-WmState.$(OBJEXT) pekwm_panel_OBJECTS = $(am_pekwm_panel_OBJECTS) am__DEPENDENCIES_1 = pekwm_panel_DEPENDENCIES = ../lib/libpekwm_lib.a ../tk/libpekwm_tk.a \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) pekwm_panel_LINK = $(CXXLD) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_pekwm_panel_sysinfo_OBJECTS = pekwm_panel_sysinfo.$(OBJEXT) pekwm_panel_sysinfo_OBJECTS = $(am_pekwm_panel_sysinfo_OBJECTS) pekwm_panel_sysinfo_LDADD = $(LDADD) pekwm_panel_sysinfo_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pekwm_panel_sysinfo_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ../$(DEPDIR)/pekwm_panel-pekwm_env.Po \ ./$(DEPDIR)/pekwm_panel-BarWidget.Po \ ./$(DEPDIR)/pekwm_panel-ClientInfo.Po \ ./$(DEPDIR)/pekwm_panel-ClientListWidget.Po \ ./$(DEPDIR)/pekwm_panel-ExternalCommandData.Po \ ./$(DEPDIR)/pekwm_panel-IconWidget.Po \ ./$(DEPDIR)/pekwm_panel-PanelConfig.Po \ ./$(DEPDIR)/pekwm_panel-PanelTheme.Po \ ./$(DEPDIR)/pekwm_panel-PanelWidget.Po \ ./$(DEPDIR)/pekwm_panel-SystrayWidget.Po \ ./$(DEPDIR)/pekwm_panel-TextFormatter.Po \ ./$(DEPDIR)/pekwm_panel-TextWidget.Po \ ./$(DEPDIR)/pekwm_panel-VarData.Po \ ./$(DEPDIR)/pekwm_panel-WidgetFactory.Po \ ./$(DEPDIR)/pekwm_panel-WmState.Po \ ./$(DEPDIR)/pekwm_panel-pekwm_panel.Po \ ./$(DEPDIR)/pekwm_panel_sysinfo.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(pekwm_panel_SOURCES) $(pekwm_panel_sysinfo_SOURCES) DIST_SOURCES = $(pekwm_panel_SOURCES) $(pekwm_panel_sysinfo_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIB_CFLAGS = @LIB_CFLAGS@ LIB_LIBS = @LIB_LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PEKWM_FEATURES = @PEKWM_FEATURES@ PEKWM_SH = @PEKWM_SH@ PEKWM_THEMES = @PEKWM_THEMES@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TK_CFLAGS = @TK_CFLAGS@ TK_LIBS = @TK_LIBS@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libcurl_CFLAGS = @libcurl_CFLAGS@ libcurl_LIBS = @libcurl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ libjpeg_CFLAGS = @libjpeg_CFLAGS@ libjpeg_LIBS = @libjpeg_LIBS@ libpng_CFLAGS = @libpng_CFLAGS@ libpng_LIBS = @libpng_LIBS@ libudev_CFLAGS = @libudev_CFLAGS@ libudev_LIBS = @libudev_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pango_CFLAGS = @pango_CFLAGS@ pango_LIBS = @pango_LIBS@ pangocairo_CFLAGS = @pangocairo_CFLAGS@ pangocairo_LIBS = @pangocairo_LIBS@ pangoxft_CFLAGS = @pangoxft_CFLAGS@ pangoxft_LIBS = @pangoxft_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xext_CFLAGS = @xext_CFLAGS@ xext_LIBS = @xext_LIBS@ xft_CFLAGS = @xft_CFLAGS@ xft_LIBS = @xft_LIBS@ xinerama_CFLAGS = @xinerama_CFLAGS@ xinerama_LIBS = @xinerama_LIBS@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ xrandr_CFLAGS = @xrandr_CFLAGS@ xrandr_LIBS = @xrandr_LIBS@ pekwm_panel_SOURCES = pekwm_panel.cc pekwm_panel.hh \ ../pekwm_env.cc \ BarWidget.cc BarWidget.hh \ ClientInfo.cc ClientInfo.hh \ ClientListWidget.cc ClientListWidget.hh \ DateTimeWidget.hh \ ExternalCommandData.cc ExternalCommandData.hh \ IconWidget.cc IconWidget.hh \ PanelAction.hh \ PanelConfig.cc PanelConfig.hh \ PanelTheme.cc PanelTheme.hh \ PanelWidget.cc PanelWidget.hh \ SystrayWidget.cc SystrayWidget.hh \ TextFormatter.cc TextFormatter.hh \ TextWidget.cc TextWidget.hh \ VarData.cc VarData.hh \ WidgetFactory.cc WidgetFactory.hh \ WmState.cc WmState.hh pekwm_panel_CXXFLAGS = $(LIB_CFLAGS) $(TK_CFLAGS) -I../lib pekwm_panel_LDADD = ../lib/libpekwm_lib.a ../tk/libpekwm_tk.a $(LIB_LIBS) $(TK_LIBS) scriptsdir = $(pkgdatadir)/scripts pekwm_panel_sysinfo_SOURCES = pekwm_panel_sysinfo.c @PEKWM_HOST_SUNOS_TRUE@pekwm_panel_sysinfo_LDFLAGS = -lkstat EXTRA_DIST = CMakeLists.txt all: all-am .SUFFIXES: .SUFFIXES: .c .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/panel/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/panel/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files clean-binPROGRAMS: -$(am__rm_f) $(bin_PROGRAMS) install-scriptsPROGRAMS: $(scripts_PROGRAMS) @$(NORMAL_INSTALL) @list='$(scripts_PROGRAMS)'; test -n "$(scriptsdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(scriptsdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(scriptsdir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(scriptsdir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(scriptsdir)$$dir" || exit $$?; \ } \ ; done uninstall-scriptsPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(scripts_PROGRAMS)'; test -n "$(scriptsdir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(scriptsdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(scriptsdir)" && $(am__rm_f) $$files clean-scriptsPROGRAMS: -$(am__rm_f) $(scripts_PROGRAMS) ../$(am__dirstamp): @$(MKDIR_P) .. @: >>../$(am__dirstamp) ../$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ../$(DEPDIR) @: >>../$(DEPDIR)/$(am__dirstamp) ../pekwm_panel-pekwm_env.$(OBJEXT): ../$(am__dirstamp) \ ../$(DEPDIR)/$(am__dirstamp) pekwm_panel$(EXEEXT): $(pekwm_panel_OBJECTS) $(pekwm_panel_DEPENDENCIES) $(EXTRA_pekwm_panel_DEPENDENCIES) @rm -f pekwm_panel$(EXEEXT) $(AM_V_CXXLD)$(pekwm_panel_LINK) $(pekwm_panel_OBJECTS) $(pekwm_panel_LDADD) $(LIBS) pekwm_panel_sysinfo$(EXEEXT): $(pekwm_panel_sysinfo_OBJECTS) $(pekwm_panel_sysinfo_DEPENDENCIES) $(EXTRA_pekwm_panel_sysinfo_DEPENDENCIES) @rm -f pekwm_panel_sysinfo$(EXEEXT) $(AM_V_CCLD)$(pekwm_panel_sysinfo_LINK) $(pekwm_panel_sysinfo_OBJECTS) $(pekwm_panel_sysinfo_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f ../*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@../$(DEPDIR)/pekwm_panel-pekwm_env.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-BarWidget.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-ClientInfo.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-ClientListWidget.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-ExternalCommandData.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-IconWidget.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-PanelConfig.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-PanelTheme.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-PanelWidget.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-SystrayWidget.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-TextFormatter.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-TextWidget.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-VarData.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-WidgetFactory.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-WmState.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel-pekwm_panel.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_panel_sysinfo.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` pekwm_panel-pekwm_panel.o: pekwm_panel.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-pekwm_panel.o -MD -MP -MF $(DEPDIR)/pekwm_panel-pekwm_panel.Tpo -c -o pekwm_panel-pekwm_panel.o `test -f 'pekwm_panel.cc' || echo '$(srcdir)/'`pekwm_panel.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-pekwm_panel.Tpo $(DEPDIR)/pekwm_panel-pekwm_panel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pekwm_panel.cc' object='pekwm_panel-pekwm_panel.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-pekwm_panel.o `test -f 'pekwm_panel.cc' || echo '$(srcdir)/'`pekwm_panel.cc pekwm_panel-pekwm_panel.obj: pekwm_panel.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-pekwm_panel.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-pekwm_panel.Tpo -c -o pekwm_panel-pekwm_panel.obj `if test -f 'pekwm_panel.cc'; then $(CYGPATH_W) 'pekwm_panel.cc'; else $(CYGPATH_W) '$(srcdir)/pekwm_panel.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-pekwm_panel.Tpo $(DEPDIR)/pekwm_panel-pekwm_panel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pekwm_panel.cc' object='pekwm_panel-pekwm_panel.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-pekwm_panel.obj `if test -f 'pekwm_panel.cc'; then $(CYGPATH_W) 'pekwm_panel.cc'; else $(CYGPATH_W) '$(srcdir)/pekwm_panel.cc'; fi` ../pekwm_panel-pekwm_env.o: ../pekwm_env.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT ../pekwm_panel-pekwm_env.o -MD -MP -MF ../$(DEPDIR)/pekwm_panel-pekwm_env.Tpo -c -o ../pekwm_panel-pekwm_env.o `test -f '../pekwm_env.cc' || echo '$(srcdir)/'`../pekwm_env.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../$(DEPDIR)/pekwm_panel-pekwm_env.Tpo ../$(DEPDIR)/pekwm_panel-pekwm_env.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../pekwm_env.cc' object='../pekwm_panel-pekwm_env.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o ../pekwm_panel-pekwm_env.o `test -f '../pekwm_env.cc' || echo '$(srcdir)/'`../pekwm_env.cc ../pekwm_panel-pekwm_env.obj: ../pekwm_env.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT ../pekwm_panel-pekwm_env.obj -MD -MP -MF ../$(DEPDIR)/pekwm_panel-pekwm_env.Tpo -c -o ../pekwm_panel-pekwm_env.obj `if test -f '../pekwm_env.cc'; then $(CYGPATH_W) '../pekwm_env.cc'; else $(CYGPATH_W) '$(srcdir)/../pekwm_env.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../$(DEPDIR)/pekwm_panel-pekwm_env.Tpo ../$(DEPDIR)/pekwm_panel-pekwm_env.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../pekwm_env.cc' object='../pekwm_panel-pekwm_env.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o ../pekwm_panel-pekwm_env.obj `if test -f '../pekwm_env.cc'; then $(CYGPATH_W) '../pekwm_env.cc'; else $(CYGPATH_W) '$(srcdir)/../pekwm_env.cc'; fi` pekwm_panel-BarWidget.o: BarWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-BarWidget.o -MD -MP -MF $(DEPDIR)/pekwm_panel-BarWidget.Tpo -c -o pekwm_panel-BarWidget.o `test -f 'BarWidget.cc' || echo '$(srcdir)/'`BarWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-BarWidget.Tpo $(DEPDIR)/pekwm_panel-BarWidget.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='BarWidget.cc' object='pekwm_panel-BarWidget.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-BarWidget.o `test -f 'BarWidget.cc' || echo '$(srcdir)/'`BarWidget.cc pekwm_panel-BarWidget.obj: BarWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-BarWidget.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-BarWidget.Tpo -c -o pekwm_panel-BarWidget.obj `if test -f 'BarWidget.cc'; then $(CYGPATH_W) 'BarWidget.cc'; else $(CYGPATH_W) '$(srcdir)/BarWidget.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-BarWidget.Tpo $(DEPDIR)/pekwm_panel-BarWidget.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='BarWidget.cc' object='pekwm_panel-BarWidget.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-BarWidget.obj `if test -f 'BarWidget.cc'; then $(CYGPATH_W) 'BarWidget.cc'; else $(CYGPATH_W) '$(srcdir)/BarWidget.cc'; fi` pekwm_panel-ClientInfo.o: ClientInfo.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-ClientInfo.o -MD -MP -MF $(DEPDIR)/pekwm_panel-ClientInfo.Tpo -c -o pekwm_panel-ClientInfo.o `test -f 'ClientInfo.cc' || echo '$(srcdir)/'`ClientInfo.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-ClientInfo.Tpo $(DEPDIR)/pekwm_panel-ClientInfo.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ClientInfo.cc' object='pekwm_panel-ClientInfo.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-ClientInfo.o `test -f 'ClientInfo.cc' || echo '$(srcdir)/'`ClientInfo.cc pekwm_panel-ClientInfo.obj: ClientInfo.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-ClientInfo.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-ClientInfo.Tpo -c -o pekwm_panel-ClientInfo.obj `if test -f 'ClientInfo.cc'; then $(CYGPATH_W) 'ClientInfo.cc'; else $(CYGPATH_W) '$(srcdir)/ClientInfo.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-ClientInfo.Tpo $(DEPDIR)/pekwm_panel-ClientInfo.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ClientInfo.cc' object='pekwm_panel-ClientInfo.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-ClientInfo.obj `if test -f 'ClientInfo.cc'; then $(CYGPATH_W) 'ClientInfo.cc'; else $(CYGPATH_W) '$(srcdir)/ClientInfo.cc'; fi` pekwm_panel-ClientListWidget.o: ClientListWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-ClientListWidget.o -MD -MP -MF $(DEPDIR)/pekwm_panel-ClientListWidget.Tpo -c -o pekwm_panel-ClientListWidget.o `test -f 'ClientListWidget.cc' || echo '$(srcdir)/'`ClientListWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-ClientListWidget.Tpo $(DEPDIR)/pekwm_panel-ClientListWidget.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ClientListWidget.cc' object='pekwm_panel-ClientListWidget.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-ClientListWidget.o `test -f 'ClientListWidget.cc' || echo '$(srcdir)/'`ClientListWidget.cc pekwm_panel-ClientListWidget.obj: ClientListWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-ClientListWidget.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-ClientListWidget.Tpo -c -o pekwm_panel-ClientListWidget.obj `if test -f 'ClientListWidget.cc'; then $(CYGPATH_W) 'ClientListWidget.cc'; else $(CYGPATH_W) '$(srcdir)/ClientListWidget.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-ClientListWidget.Tpo $(DEPDIR)/pekwm_panel-ClientListWidget.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ClientListWidget.cc' object='pekwm_panel-ClientListWidget.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-ClientListWidget.obj `if test -f 'ClientListWidget.cc'; then $(CYGPATH_W) 'ClientListWidget.cc'; else $(CYGPATH_W) '$(srcdir)/ClientListWidget.cc'; fi` pekwm_panel-ExternalCommandData.o: ExternalCommandData.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-ExternalCommandData.o -MD -MP -MF $(DEPDIR)/pekwm_panel-ExternalCommandData.Tpo -c -o pekwm_panel-ExternalCommandData.o `test -f 'ExternalCommandData.cc' || echo '$(srcdir)/'`ExternalCommandData.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-ExternalCommandData.Tpo $(DEPDIR)/pekwm_panel-ExternalCommandData.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ExternalCommandData.cc' object='pekwm_panel-ExternalCommandData.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-ExternalCommandData.o `test -f 'ExternalCommandData.cc' || echo '$(srcdir)/'`ExternalCommandData.cc pekwm_panel-ExternalCommandData.obj: ExternalCommandData.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-ExternalCommandData.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-ExternalCommandData.Tpo -c -o pekwm_panel-ExternalCommandData.obj `if test -f 'ExternalCommandData.cc'; then $(CYGPATH_W) 'ExternalCommandData.cc'; else $(CYGPATH_W) '$(srcdir)/ExternalCommandData.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-ExternalCommandData.Tpo $(DEPDIR)/pekwm_panel-ExternalCommandData.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ExternalCommandData.cc' object='pekwm_panel-ExternalCommandData.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-ExternalCommandData.obj `if test -f 'ExternalCommandData.cc'; then $(CYGPATH_W) 'ExternalCommandData.cc'; else $(CYGPATH_W) '$(srcdir)/ExternalCommandData.cc'; fi` pekwm_panel-IconWidget.o: IconWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-IconWidget.o -MD -MP -MF $(DEPDIR)/pekwm_panel-IconWidget.Tpo -c -o pekwm_panel-IconWidget.o `test -f 'IconWidget.cc' || echo '$(srcdir)/'`IconWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-IconWidget.Tpo $(DEPDIR)/pekwm_panel-IconWidget.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='IconWidget.cc' object='pekwm_panel-IconWidget.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-IconWidget.o `test -f 'IconWidget.cc' || echo '$(srcdir)/'`IconWidget.cc pekwm_panel-IconWidget.obj: IconWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-IconWidget.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-IconWidget.Tpo -c -o pekwm_panel-IconWidget.obj `if test -f 'IconWidget.cc'; then $(CYGPATH_W) 'IconWidget.cc'; else $(CYGPATH_W) '$(srcdir)/IconWidget.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-IconWidget.Tpo $(DEPDIR)/pekwm_panel-IconWidget.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='IconWidget.cc' object='pekwm_panel-IconWidget.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-IconWidget.obj `if test -f 'IconWidget.cc'; then $(CYGPATH_W) 'IconWidget.cc'; else $(CYGPATH_W) '$(srcdir)/IconWidget.cc'; fi` pekwm_panel-PanelConfig.o: PanelConfig.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-PanelConfig.o -MD -MP -MF $(DEPDIR)/pekwm_panel-PanelConfig.Tpo -c -o pekwm_panel-PanelConfig.o `test -f 'PanelConfig.cc' || echo '$(srcdir)/'`PanelConfig.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-PanelConfig.Tpo $(DEPDIR)/pekwm_panel-PanelConfig.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PanelConfig.cc' object='pekwm_panel-PanelConfig.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-PanelConfig.o `test -f 'PanelConfig.cc' || echo '$(srcdir)/'`PanelConfig.cc pekwm_panel-PanelConfig.obj: PanelConfig.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-PanelConfig.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-PanelConfig.Tpo -c -o pekwm_panel-PanelConfig.obj `if test -f 'PanelConfig.cc'; then $(CYGPATH_W) 'PanelConfig.cc'; else $(CYGPATH_W) '$(srcdir)/PanelConfig.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-PanelConfig.Tpo $(DEPDIR)/pekwm_panel-PanelConfig.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PanelConfig.cc' object='pekwm_panel-PanelConfig.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-PanelConfig.obj `if test -f 'PanelConfig.cc'; then $(CYGPATH_W) 'PanelConfig.cc'; else $(CYGPATH_W) '$(srcdir)/PanelConfig.cc'; fi` pekwm_panel-PanelTheme.o: PanelTheme.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-PanelTheme.o -MD -MP -MF $(DEPDIR)/pekwm_panel-PanelTheme.Tpo -c -o pekwm_panel-PanelTheme.o `test -f 'PanelTheme.cc' || echo '$(srcdir)/'`PanelTheme.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-PanelTheme.Tpo $(DEPDIR)/pekwm_panel-PanelTheme.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PanelTheme.cc' object='pekwm_panel-PanelTheme.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-PanelTheme.o `test -f 'PanelTheme.cc' || echo '$(srcdir)/'`PanelTheme.cc pekwm_panel-PanelTheme.obj: PanelTheme.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-PanelTheme.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-PanelTheme.Tpo -c -o pekwm_panel-PanelTheme.obj `if test -f 'PanelTheme.cc'; then $(CYGPATH_W) 'PanelTheme.cc'; else $(CYGPATH_W) '$(srcdir)/PanelTheme.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-PanelTheme.Tpo $(DEPDIR)/pekwm_panel-PanelTheme.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PanelTheme.cc' object='pekwm_panel-PanelTheme.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-PanelTheme.obj `if test -f 'PanelTheme.cc'; then $(CYGPATH_W) 'PanelTheme.cc'; else $(CYGPATH_W) '$(srcdir)/PanelTheme.cc'; fi` pekwm_panel-PanelWidget.o: PanelWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-PanelWidget.o -MD -MP -MF $(DEPDIR)/pekwm_panel-PanelWidget.Tpo -c -o pekwm_panel-PanelWidget.o `test -f 'PanelWidget.cc' || echo '$(srcdir)/'`PanelWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-PanelWidget.Tpo $(DEPDIR)/pekwm_panel-PanelWidget.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PanelWidget.cc' object='pekwm_panel-PanelWidget.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-PanelWidget.o `test -f 'PanelWidget.cc' || echo '$(srcdir)/'`PanelWidget.cc pekwm_panel-PanelWidget.obj: PanelWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-PanelWidget.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-PanelWidget.Tpo -c -o pekwm_panel-PanelWidget.obj `if test -f 'PanelWidget.cc'; then $(CYGPATH_W) 'PanelWidget.cc'; else $(CYGPATH_W) '$(srcdir)/PanelWidget.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-PanelWidget.Tpo $(DEPDIR)/pekwm_panel-PanelWidget.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PanelWidget.cc' object='pekwm_panel-PanelWidget.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-PanelWidget.obj `if test -f 'PanelWidget.cc'; then $(CYGPATH_W) 'PanelWidget.cc'; else $(CYGPATH_W) '$(srcdir)/PanelWidget.cc'; fi` pekwm_panel-SystrayWidget.o: SystrayWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-SystrayWidget.o -MD -MP -MF $(DEPDIR)/pekwm_panel-SystrayWidget.Tpo -c -o pekwm_panel-SystrayWidget.o `test -f 'SystrayWidget.cc' || echo '$(srcdir)/'`SystrayWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-SystrayWidget.Tpo $(DEPDIR)/pekwm_panel-SystrayWidget.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SystrayWidget.cc' object='pekwm_panel-SystrayWidget.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-SystrayWidget.o `test -f 'SystrayWidget.cc' || echo '$(srcdir)/'`SystrayWidget.cc pekwm_panel-SystrayWidget.obj: SystrayWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-SystrayWidget.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-SystrayWidget.Tpo -c -o pekwm_panel-SystrayWidget.obj `if test -f 'SystrayWidget.cc'; then $(CYGPATH_W) 'SystrayWidget.cc'; else $(CYGPATH_W) '$(srcdir)/SystrayWidget.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-SystrayWidget.Tpo $(DEPDIR)/pekwm_panel-SystrayWidget.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SystrayWidget.cc' object='pekwm_panel-SystrayWidget.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-SystrayWidget.obj `if test -f 'SystrayWidget.cc'; then $(CYGPATH_W) 'SystrayWidget.cc'; else $(CYGPATH_W) '$(srcdir)/SystrayWidget.cc'; fi` pekwm_panel-TextFormatter.o: TextFormatter.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-TextFormatter.o -MD -MP -MF $(DEPDIR)/pekwm_panel-TextFormatter.Tpo -c -o pekwm_panel-TextFormatter.o `test -f 'TextFormatter.cc' || echo '$(srcdir)/'`TextFormatter.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-TextFormatter.Tpo $(DEPDIR)/pekwm_panel-TextFormatter.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TextFormatter.cc' object='pekwm_panel-TextFormatter.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-TextFormatter.o `test -f 'TextFormatter.cc' || echo '$(srcdir)/'`TextFormatter.cc pekwm_panel-TextFormatter.obj: TextFormatter.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-TextFormatter.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-TextFormatter.Tpo -c -o pekwm_panel-TextFormatter.obj `if test -f 'TextFormatter.cc'; then $(CYGPATH_W) 'TextFormatter.cc'; else $(CYGPATH_W) '$(srcdir)/TextFormatter.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-TextFormatter.Tpo $(DEPDIR)/pekwm_panel-TextFormatter.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TextFormatter.cc' object='pekwm_panel-TextFormatter.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-TextFormatter.obj `if test -f 'TextFormatter.cc'; then $(CYGPATH_W) 'TextFormatter.cc'; else $(CYGPATH_W) '$(srcdir)/TextFormatter.cc'; fi` pekwm_panel-TextWidget.o: TextWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-TextWidget.o -MD -MP -MF $(DEPDIR)/pekwm_panel-TextWidget.Tpo -c -o pekwm_panel-TextWidget.o `test -f 'TextWidget.cc' || echo '$(srcdir)/'`TextWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-TextWidget.Tpo $(DEPDIR)/pekwm_panel-TextWidget.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TextWidget.cc' object='pekwm_panel-TextWidget.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-TextWidget.o `test -f 'TextWidget.cc' || echo '$(srcdir)/'`TextWidget.cc pekwm_panel-TextWidget.obj: TextWidget.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-TextWidget.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-TextWidget.Tpo -c -o pekwm_panel-TextWidget.obj `if test -f 'TextWidget.cc'; then $(CYGPATH_W) 'TextWidget.cc'; else $(CYGPATH_W) '$(srcdir)/TextWidget.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-TextWidget.Tpo $(DEPDIR)/pekwm_panel-TextWidget.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TextWidget.cc' object='pekwm_panel-TextWidget.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-TextWidget.obj `if test -f 'TextWidget.cc'; then $(CYGPATH_W) 'TextWidget.cc'; else $(CYGPATH_W) '$(srcdir)/TextWidget.cc'; fi` pekwm_panel-VarData.o: VarData.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-VarData.o -MD -MP -MF $(DEPDIR)/pekwm_panel-VarData.Tpo -c -o pekwm_panel-VarData.o `test -f 'VarData.cc' || echo '$(srcdir)/'`VarData.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-VarData.Tpo $(DEPDIR)/pekwm_panel-VarData.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='VarData.cc' object='pekwm_panel-VarData.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-VarData.o `test -f 'VarData.cc' || echo '$(srcdir)/'`VarData.cc pekwm_panel-VarData.obj: VarData.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-VarData.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-VarData.Tpo -c -o pekwm_panel-VarData.obj `if test -f 'VarData.cc'; then $(CYGPATH_W) 'VarData.cc'; else $(CYGPATH_W) '$(srcdir)/VarData.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-VarData.Tpo $(DEPDIR)/pekwm_panel-VarData.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='VarData.cc' object='pekwm_panel-VarData.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-VarData.obj `if test -f 'VarData.cc'; then $(CYGPATH_W) 'VarData.cc'; else $(CYGPATH_W) '$(srcdir)/VarData.cc'; fi` pekwm_panel-WidgetFactory.o: WidgetFactory.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-WidgetFactory.o -MD -MP -MF $(DEPDIR)/pekwm_panel-WidgetFactory.Tpo -c -o pekwm_panel-WidgetFactory.o `test -f 'WidgetFactory.cc' || echo '$(srcdir)/'`WidgetFactory.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-WidgetFactory.Tpo $(DEPDIR)/pekwm_panel-WidgetFactory.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WidgetFactory.cc' object='pekwm_panel-WidgetFactory.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-WidgetFactory.o `test -f 'WidgetFactory.cc' || echo '$(srcdir)/'`WidgetFactory.cc pekwm_panel-WidgetFactory.obj: WidgetFactory.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-WidgetFactory.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-WidgetFactory.Tpo -c -o pekwm_panel-WidgetFactory.obj `if test -f 'WidgetFactory.cc'; then $(CYGPATH_W) 'WidgetFactory.cc'; else $(CYGPATH_W) '$(srcdir)/WidgetFactory.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-WidgetFactory.Tpo $(DEPDIR)/pekwm_panel-WidgetFactory.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WidgetFactory.cc' object='pekwm_panel-WidgetFactory.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-WidgetFactory.obj `if test -f 'WidgetFactory.cc'; then $(CYGPATH_W) 'WidgetFactory.cc'; else $(CYGPATH_W) '$(srcdir)/WidgetFactory.cc'; fi` pekwm_panel-WmState.o: WmState.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-WmState.o -MD -MP -MF $(DEPDIR)/pekwm_panel-WmState.Tpo -c -o pekwm_panel-WmState.o `test -f 'WmState.cc' || echo '$(srcdir)/'`WmState.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-WmState.Tpo $(DEPDIR)/pekwm_panel-WmState.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WmState.cc' object='pekwm_panel-WmState.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-WmState.o `test -f 'WmState.cc' || echo '$(srcdir)/'`WmState.cc pekwm_panel-WmState.obj: WmState.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -MT pekwm_panel-WmState.obj -MD -MP -MF $(DEPDIR)/pekwm_panel-WmState.Tpo -c -o pekwm_panel-WmState.obj `if test -f 'WmState.cc'; then $(CYGPATH_W) 'WmState.cc'; else $(CYGPATH_W) '$(srcdir)/WmState.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_panel-WmState.Tpo $(DEPDIR)/pekwm_panel-WmState.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WmState.cc' object='pekwm_panel-WmState.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_panel_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_panel-WmState.obj `if test -f 'WmState.cc'; then $(CYGPATH_W) 'WmState.cc'; else $(CYGPATH_W) '$(srcdir)/WmState.cc'; fi` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(scriptsdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) -$(am__rm_f) ../$(DEPDIR)/$(am__dirstamp) -$(am__rm_f) ../$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-scriptsPROGRAMS \ mostlyclean-am distclean: distclean-am -rm -f ../$(DEPDIR)/pekwm_panel-pekwm_env.Po -rm -f ./$(DEPDIR)/pekwm_panel-BarWidget.Po -rm -f ./$(DEPDIR)/pekwm_panel-ClientInfo.Po -rm -f ./$(DEPDIR)/pekwm_panel-ClientListWidget.Po -rm -f ./$(DEPDIR)/pekwm_panel-ExternalCommandData.Po -rm -f ./$(DEPDIR)/pekwm_panel-IconWidget.Po -rm -f ./$(DEPDIR)/pekwm_panel-PanelConfig.Po -rm -f ./$(DEPDIR)/pekwm_panel-PanelTheme.Po -rm -f ./$(DEPDIR)/pekwm_panel-PanelWidget.Po -rm -f ./$(DEPDIR)/pekwm_panel-SystrayWidget.Po -rm -f ./$(DEPDIR)/pekwm_panel-TextFormatter.Po -rm -f ./$(DEPDIR)/pekwm_panel-TextWidget.Po -rm -f ./$(DEPDIR)/pekwm_panel-VarData.Po -rm -f ./$(DEPDIR)/pekwm_panel-WidgetFactory.Po -rm -f ./$(DEPDIR)/pekwm_panel-WmState.Po -rm -f ./$(DEPDIR)/pekwm_panel-pekwm_panel.Po -rm -f ./$(DEPDIR)/pekwm_panel_sysinfo.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-scriptsPROGRAMS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ../$(DEPDIR)/pekwm_panel-pekwm_env.Po -rm -f ./$(DEPDIR)/pekwm_panel-BarWidget.Po -rm -f ./$(DEPDIR)/pekwm_panel-ClientInfo.Po -rm -f ./$(DEPDIR)/pekwm_panel-ClientListWidget.Po -rm -f ./$(DEPDIR)/pekwm_panel-ExternalCommandData.Po -rm -f ./$(DEPDIR)/pekwm_panel-IconWidget.Po -rm -f ./$(DEPDIR)/pekwm_panel-PanelConfig.Po -rm -f ./$(DEPDIR)/pekwm_panel-PanelTheme.Po -rm -f ./$(DEPDIR)/pekwm_panel-PanelWidget.Po -rm -f ./$(DEPDIR)/pekwm_panel-SystrayWidget.Po -rm -f ./$(DEPDIR)/pekwm_panel-TextFormatter.Po -rm -f ./$(DEPDIR)/pekwm_panel-TextWidget.Po -rm -f ./$(DEPDIR)/pekwm_panel-VarData.Po -rm -f ./$(DEPDIR)/pekwm_panel-WidgetFactory.Po -rm -f ./$(DEPDIR)/pekwm_panel-WmState.Po -rm -f ./$(DEPDIR)/pekwm_panel-pekwm_panel.Po -rm -f ./$(DEPDIR)/pekwm_panel_sysinfo.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-scriptsPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-binPROGRAMS clean-generic clean-scriptsPROGRAMS \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am \ install-scriptsPROGRAMS install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-binPROGRAMS uninstall-scriptsPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% pekwm-0.4.4/src/panel/TextFormatter.cc0000664000175000017500000001016515126136025013336 // // TextFormatter.cc for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "Charset.hh" #include "TextFormatter.hh" #include /** empty string, used as default return value. */ static std::string _empty_string; TextFormatter::TextFormatter(VarData& var_data, WmState& wm_state) : _var_data(var_data), _wm_state(wm_state), _check_wm_state(false) { } TextFormatter::~TextFormatter(void) { } /** * pre process format string for use with the format command, expands * environment variables and other static data. */ std::string TextFormatter::preprocess(const std::string& raw_format) { return format(raw_format, TextFormatter::tfPreprocessVar); } /** * format previously pre-processed format string expanding external * command data and wm state. */ std::string TextFormatter::format(const std::string& pp_format) { return format(pp_format, TextFormatter::tfExpandVar); } std::string TextFormatter::format(const std::string& pp_format, formatFun exp) { static std::set var_end_chars; if (var_end_chars.empty()) { var_end_chars.insert('\''); var_end_chars.insert('"'); } std::string formatted; bool in_escape = false, in_var = false; Charset::Utf8Iterator it(pp_format); std::string buf; for (; it.ok(); ++it) { if (in_escape) { buf += *it; in_escape = false; } else if (it == '\\') { in_escape = true; } else if (in_var && it.charLen() == 1 && (isspace((*it)[0]) || var_end_chars.count((*it)[0]) != 0)) { formatted += exp(this, buf); buf = *it; in_var = false; } else if (! in_var && it == '%') { if (! buf.empty()) { formatted += buf; buf = _empty_string; } in_var = true; } else { buf += *it; } } if (! buf.empty()) { if (in_var) { formatted += exp(this, buf); } else { formatted += buf; } } return formatted; } std::string TextFormatter::preprocessVar(const std::string& buf) { if (buf.empty()) { return "%"; } switch (buf[0]) { case '_': { return Util::getEnv(buf.substr(1)); } case ':': _check_wm_state = true; return "%" + buf; default: _fields.push_back(buf); return "%" + buf; } } std::string TextFormatter::expandVar(const std::string& buf) { if (buf.empty()) { return _empty_string; } if (buf[0] == ':') { // window manager state variable if (buf == ":CLIENT_NAME:") { Window win = _wm_state.getActiveWindow(); ClientInfo *client_info = _wm_state.findClientInfo(win); return client_info ? client_info->getName() : _empty_string; } else if (buf == ":WORKSPACE_NUMBER:") { return std::to_string( _wm_state.getActiveWorkspace() + 1); } else if (buf == ":WORKSPACE_NAME:") { return _wm_state.getWorkspaceName( _wm_state.getActiveWorkspace()); } return _empty_string; } // external command data return _var_data.get(buf); } TextFormatObserver::TextFormatObserver(VarData& var_data, WmState& wm_state, Observer *observer, const std::string& format) : _tf(var_data, wm_state), _observer(observer), _pp_format(_tf.preprocess(format)) { if (! _tf.getFields().empty()) { pekwm::observerMapping()->addObserver( _tf.getVarData(), _observer, 100); } if (_tf.referenceWmState()) { pekwm::observerMapping()->addObserver( _tf.getWmState(), _observer, 100); } } TextFormatObserver::~TextFormatObserver() { if (_tf.referenceWmState()) { pekwm::observerMapping()->removeObserver( _tf.getWmState(), _observer); } if (! _tf.getFields().empty()) { pekwm::observerMapping()->removeObserver( _tf.getVarData(), _observer); } } /** * Check if the observation matches any of the observed fields. */ bool TextFormatObserver::match(Observation *observation) { if (isFixed()) { return false; } FieldObservation *fo = dynamic_cast(observation); if (fo != nullptr) { const std::vector &fields = _tf.getFields(); std::vector::const_iterator it(fields.begin()); for (; it != fields.end(); ++it) { if (*it == fo->getField()) { return true; } } } return false; } pekwm-0.4.4/src/panel/ExternalCommandData.hh0000664000175000017500000000346215126136025014415 // // ExternalCommandData.hh for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_EXTERNAL_COMMAND_DATA_HH_ #define _PEKWM_PANEL_EXTERNAL_COMMAND_DATA_HH_ #include #include #include "pekwm_panel.hh" #include "Observable.hh" #include "PanelConfig.hh" #include "VarData.hh" /** * Collection of data from external commands. * * Commands output is collected in the below format at the specified * interval. * * key data * */ class ExternalCommandData : public Observable { public: class CommandProcess { public: CommandProcess(const std::string& command, uint interval_s, const std::string& assign); ~CommandProcess(); int getFd() const { return _fd; } pid_t getPid() const { return _pid; } std::string& getBuf() { return _buf; } const std::string& getAssign() const { return _assign; } bool start(); bool checkInterval(struct timespec *now) { return now->tv_sec >= _next_interval.tv_sec; } void reset(); private: std::string _command; uint _interval_s; std::string _assign; struct timespec _next_interval; pid_t _pid; int _fd; std::string _buf; }; ExternalCommandData(const PanelConfig& cfg, VarData& var_data); virtual ~ExternalCommandData(); void refresh(fdFun addFd, void *opaque); bool input(int fd); void done(pid_t pid, fdFun removeFd, void *opaque); protected: void append(std::string &buf, const char *data, size_t size, const std::string &assign); void parseOutput(const std::string& buf); void parseLine(const std::string& line); private: const PanelConfig& _cfg; VarData& _var_data; std::vector _command_processes; }; #endif // _PEKWM_PANEL_EXTERNAL_COMMAND_DATA_HH_ pekwm-0.4.4/src/panel/VarData.hh0000664000175000017500000000161115126136025012056 // // VarData.hh for pekwm // Copyright (C) 2022-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_VAR_DATA_HH_ #define _PEKWM_PANEL_VAR_DATA_HH_ #include #include #include "Observable.hh" class FieldObservation : public Observation { public: FieldObservation(const std::string& field); virtual ~FieldObservation(void); const std::string& getField(void) const { return _field; } private: std::string _field; }; /** * Variable data storage, used by WmState and ExternalCommandData to * store and notify data. */ class VarData : public Observable { public: const std::string& get(const std::string& field) const; void set(const std::string& field, const std::string& value); private: std::map _vars; }; #endif // _PEKWM_PANEL_VAR_DATA_HH_ pekwm-0.4.4/src/panel/pekwm_panel.hh0000664000175000017500000000304415126136025013040 // // pekwm_panel.hh for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_HH_ #define _PEKWM_PANEL_HH_ #include #include "Observable.hh" #include "Types.hh" #define DEFAULT_PLACEMENT PANEL_TOP typedef void(*fdFun)(int fd, void *opaque); /** * Client state, used for selecting correct theme data for the client * list. */ enum ClientState { CLIENT_STATE_FOCUSED, CLIENT_STATE_UNFOCUSED, CLIENT_STATE_ICONIFIED, CLIENT_STATE_NO }; /** * Widget size unit. */ enum WidgetUnit { WIDGET_UNIT_PIXELS, WIDGET_UNIT_PERCENT, WIDGET_UNIT_REQUIRED, WIDGET_UNIT_REST, WIDGET_UNIT_TEXT_WIDTH }; /** * Panel placement. */ enum PanelPlacement { PANEL_TOP, PANEL_BOTTOM }; /** * Size request for widget. */ class SizeReq { public: SizeReq(const std::string &text) : _unit(WIDGET_UNIT_TEXT_WIDTH), _size(0), _text(text) { } SizeReq(const SizeReq& size_req) : _unit(size_req._unit), _size(size_req._size), _text(size_req._text) { } SizeReq(WidgetUnit unit, uint size) : _unit(unit), _size(size) { } enum WidgetUnit getUnit(void) const { return _unit; } uint getSize(void) const { return _size; } const std::string& getText(void) const { return _text; } private: WidgetUnit _unit; uint _size; std::string _text; }; /** * Notification sent when the required size of a widget is changed. */ class RequiredSizeChanged : public Observation { }; #endif // _PEKWM_PANEL_HH_ pekwm-0.4.4/src/panel/ClientInfo.hh0000664000175000017500000000205715126136025012573 // // ClientInfo.hh for pekwm // Copyright (C) 2022-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_CLIENT_INFO_HH #define _PEKWM_PANEL_CLIENT_INFO_HH #include "../tk/PImage.hh" #include "../tk/PImageIcon.hh" #include "../tk/X11Util.hh" class ClientInfo : public NetWMStates { public: ClientInfo(Window window); virtual ~ClientInfo(void); Window getWindow(void) const { return _window; } const std::string& getName(void) const { return _name; } const Geometry& getGeometry(void) const { return _gm; } PImage *getIcon(void) const { return _icon; } bool displayOn(uint workspace) const { return sticky || this->_workspace == workspace; } bool handlePropertyNotify(XPropertyEvent *ev); private: std::string readName(void); Geometry readGeometry(void) { return Geometry(); } uint readWorkspace(void); private: Window _window; std::string _name; Geometry _gm; uint _workspace; PImageIcon *_icon; }; #endif // _PEKWM_PANEL_CLIENT_INFO_HH pekwm-0.4.4/src/panel/PanelConfig.cc0000664000175000017500000001570715126136025012722 // // PanelConfig.cc for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "Debug.hh" #include "PanelConfig.hh" #include "../tk/ThemeUtil.hh" #include "../tk/TkGlobals.hh" /** empty string, used as default return value. */ static std::string _empty_string; static Util::StringTo panel_placement_map[] = {{"TOP", PANEL_TOP}, {"BOTTOM", PANEL_BOTTOM}, {nullptr, PANEL_TOP}}; // WidgetConfig WidgetConfig::WidgetConfig(const std::string& name, const std::vector& args, const std::string& if_, const SizeReq& size_req, uint interval_s, const std::vector &clicks, const CfgParser::Entry* section) : _name(name), _args(args), _if(if_), _size_req(size_req), _interval_s(interval_s), _clicks(clicks), _section(nullptr) { if (section) { _section = new CfgParser::Entry(*section); } } WidgetConfig::WidgetConfig(const WidgetConfig& cfg) : _name(cfg._name), _args(cfg._args), _if(cfg._if), _size_req(cfg._size_req), _interval_s(cfg._interval_s), _clicks(cfg._clicks) { if (cfg._section) { _section = new CfgParser::Entry(*cfg._section); } else { _section = nullptr; } } WidgetConfig::~WidgetConfig() { delete _section; } WidgetConfig& WidgetConfig::operator=(const WidgetConfig& rhs) { if (this == &rhs) { return *this; } delete _section; _name = rhs._name; _args = rhs._args; _if = rhs._if; _size_req = rhs._size_req; _interval_s = rhs._interval_s; _clicks = rhs._clicks; if (rhs._section) { _section = new CfgParser::Entry(*rhs._section); } else { _section = nullptr; } return *this; } const std::string& WidgetConfig::getArg(uint arg) const { return arg < _args.size() ? _args[arg] : _empty_string; } // CommandConfig CommandConfig::CommandConfig(const std::string& command, uint interval_s, const std::string &assign) : _command(command), _interval_s(interval_s), _assign(assign) { } CommandConfig::~CommandConfig(void) { } // PanelConfig PanelConfig::PanelConfig() : _placement(DEFAULT_PLACEMENT), _head(-1) { } PanelConfig::~PanelConfig() { } bool PanelConfig::load(const std::string &panel_file) { CfgParserOpt opt(pekwm::configScriptPath()); CfgParser cfg(opt); if (! cfg.parse(panel_file, CfgParserSource::SOURCE_FILE, true)) { return false; } CfgParser::Entry *root = cfg.getEntryRoot(); loadPanel(root->findSection("PANEL")); loadCommands(root->findSection("COMMANDS")); loadWidgets(root->findSection("WIDGETS")); _refresh_interval_s = calculateRefreshIntervalS(); return true; } void PanelConfig::loadPanel(CfgParser::Entry *section) { if (section == nullptr) { return; } std::string placement; CfgParserKeys keys; keys.add_string("PLACEMENT", placement, "TOP"); keys.add_numeric("HEAD", _head, -1); section->parseKeyValues(keys.begin(), keys.end()); keys.clear(); _placement = Util::StringToGet(panel_placement_map, placement); } void PanelConfig::loadCommands(CfgParser::Entry *section) { _commands.clear(); if (section == nullptr) { return; } CfgParser::Entry::entry_cit it = section->begin(); for (; it != section->end(); ++it) { uint interval = UINT_MAX; std::string assign; if ((*it)->getSection()) { CfgParserKeys keys; keys.add_numeric("INTERVAL", interval, UINT_MAX); keys.add_string("ASSIGN", assign); (*it)->getSection()->parseKeyValues(keys.begin(), keys.end()); keys.clear(); } _commands.push_back(CommandConfig((*it)->getValue(), interval, assign)); } } void PanelConfig::loadWidgets(CfgParser::Entry *section) { _widgets.clear(); if (section == nullptr) { return; } CfgParser::Entry::entry_cit it = section->begin(); for (; it != section->end(); ++it) { uint interval = UINT_MAX; std::string if_; std::string size = "REQUIRED"; std::vector clicks; CfgParser::Entry *w_section = (*it)->getSection(); if (w_section) { CfgParserKeys keys; keys.add_numeric("INTERVAL", interval, UINT_MAX); keys.add_string("SIZE", size, "REQUIRED"); keys.add_string("IF", if_, ""); w_section->parseKeyValues(keys.begin(), keys.end()); keys.clear(); loadWidgetClicks(w_section, clicks); } SizeReq size_req = parseSize(size); addWidget((*it)->getName(), if_, size_req, interval, (*it)->getValue(), clicks, w_section); } } void PanelConfig::loadWidgetClicks(CfgParser::Entry *section, std::vector &clicks) { std::string exec, pekwm_action; CfgParserKeys keys; keys.add_string("EXEC", exec, ""); keys.add_string("PEKWMACTION", pekwm_action, ""); CfgParser::Entry::entry_cit it = section->begin(); for (; it != section->end(); ++it) { if (! (*it)->getSection() || ! (*(*it) == "CLICK")) { continue; } int button = std::atoi((*it)->getValue().c_str()); CfgParser::Entry *section = (*it)->getSection(); section->parseKeyValues(keys.begin(), keys.end()); if (! exec.empty() && pekwm_action.empty()) { clicks.push_back( WidgetConfigClick(button, PANEL_ACTION_EXEC, exec)); } else if (! pekwm_action.empty() && exec.empty()) { clicks.push_back( WidgetConfigClick(button, PANEL_ACTION_PEKWM, pekwm_action)); } } } void PanelConfig::addWidget(const std::string& name, const std::string& if_, const SizeReq& size_req, uint interval, const std::string& args_str, const std::vector &clicks, const CfgParser::Entry* section) { std::vector args; if (! args_str.empty()) { args.push_back(args_str); } _widgets.push_back(WidgetConfig(name, args, if_, size_req, interval, clicks, section)); } SizeReq PanelConfig::parseSize(const std::string& size) { std::vector toks; Util::splitString(size, toks, " \t", 2); if (toks.size() == 1) { if (pekwm::ascii_ncase_equal("REQUIRED", toks[0])) { return SizeReq(WIDGET_UNIT_REQUIRED, 0); } else if (toks[0] == "*") { return SizeReq(WIDGET_UNIT_REST, 0); } } else if (toks.size() == 2) { if (pekwm::ascii_ncase_equal("PIXELS", toks[0])) { return SizeReq(WIDGET_UNIT_PIXELS, ThemeUtil::parsePixel(1.0, toks[1], 0)); } else if (pekwm::ascii_ncase_equal("PERCENT", toks[0])) { return SizeReq(WIDGET_UNIT_PERCENT, std::stoi(toks[1])); } else if (pekwm::ascii_ncase_equal("TEXTWIDTH", toks[0])) { return SizeReq(toks[1]); } } USER_WARN("failed to parse size: " << size); return SizeReq(WIDGET_UNIT_REQUIRED, 0); } uint PanelConfig::calculateRefreshIntervalS(void) const { uint min = UINT_MAX; command_config_vector::const_iterator it = _commands.begin(); for (; it != _commands.end(); ++it) { if (it->getIntervalS() < min) { min = it->getIntervalS(); } } std::vector::const_iterator w_it = _widgets.begin(); for (; w_it != _widgets.end(); ++w_it) { if (w_it->getIntervalS() < min) { min = w_it->getIntervalS(); } } return min; } pekwm-0.4.4/src/panel/pekwm_panel_sysinfo.c0000664000175000017500000003003315126136025014433 /* * pekwm_panel_sysinfo.c for pekwm * Copyright (C) 2025 Claes Nästén * * This program is licensed under the GNU GPL. * See the LICENSE file for more information. */ #include #include #include #include #include #include /* time-conversion constants. */ #define SEC_PER_YEAR 31536000 #define SEC_PER_DAY 86400 #define SEC_PER_HOUR 3600 #define SEC_PER_MIN 60 /* platform independent system information data. */ struct pekwm_panel_sysinfo { unsigned long uptime; float load1; float load5; float load15; unsigned long ram_kb; unsigned long free_ram_kb; unsigned long cache_ram_kb; unsigned long swap_kb; unsigned long free_swap_kb; unsigned short num_procs; }; #if defined(__linux__) || defined(UNITTEST) struct linux_meminfo_map { const char *key; unsigned long *value; }; static void _linux_read_proc_meminfo(struct pekwm_panel_sysinfo *info, FILE *fp) { const char *expected_end = " kB\n"; struct linux_meminfo_map mi_map[] = { {"MemTotal", &info->ram_kb}, {"MemFree", &info->free_ram_kb}, {"Cached", &info->cache_ram_kb}, {"SwapTotal", &info->swap_kb}, {"SwapFree", &info->free_swap_kb}, {NULL, NULL} }; char line[64]; while (fgets(line, sizeof(line), fp) != NULL) { char *pos = strchr(line, ':'); if (pos == NULL) { continue; } *pos = '\0'; char *endptr; long value = strtol(pos + 1, &endptr, 10); if (strcmp(endptr, expected_end) == 0) { for (int i = 0; mi_map[i].key; i++) { if (strcmp(mi_map[i].key, line) == 0) { *mi_map[i].value = value; break; } } } } } #endif /* defined(__linux__) || defined(UNITTEST) */ #ifdef __linux__ #include #include #include static unsigned long _to_kb(unsigned int mem_unit, unsigned long value) { return (value * mem_unit) / 1024; } static float _to_load(unsigned long value) { return (float)value / (1 << SI_LOAD_SHIFT); } static int _read_sysinfo(struct pekwm_panel_sysinfo *info) { struct sysinfo sinfo; int err = sysinfo(&sinfo); if (err) { return err; } info->uptime = sinfo.uptime; info->load1 = _to_load(sinfo.loads[0]); info->load5 = _to_load(sinfo.loads[1]); info->load15 = _to_load(sinfo.loads[2]); info->ram_kb = _to_kb(sinfo.mem_unit, sinfo.totalram); info->free_ram_kb = _to_kb(sinfo.mem_unit, sinfo.freeram); info->cache_ram_kb = _to_kb(sinfo.mem_unit, sinfo.bufferram); info->swap_kb = _to_kb(sinfo.mem_unit, sinfo.totalswap); info->free_swap_kb = _to_kb(sinfo.mem_unit, sinfo.freeswap); info->num_procs = sinfo.procs; /* read after sysinfo, overwriting information from sysinfo with * /proc/meminfo information if /proc is available. */ FILE *fp = fopen("/proc/meminfo", "r"); if (fp) { _linux_read_proc_meminfo(info, fp); fclose(fp); } return 0; } #else /* ! __linux__ */ #ifdef __sun__ #include #include #include static long _pagesize_kb = 0; static float _to_load(unsigned long value) { return (float)value / 256; } static kstat_t* _kstat_lookup_read(kstat_ctl_t *kc, char *module, int id, char *name) { kstat_t *ksp = kstat_lookup(kc, module, id, name); if (ksp) { kid_t id = kstat_read(kc, ksp, NULL); if (id != -1) { return ksp; } } return NULL; } static uint32_t _kstat_data_ui32(kstat_t *ksp, char *name) { kstat_named_t *val = kstat_data_lookup(ksp, name); if (val && val->data_type == KSTAT_DATA_UINT32) { return val->value.ui32; } return 0; } static uint64_t _kstat_data_ui64(kstat_t *ksp, char *name) { kstat_named_t *val = kstat_data_lookup(ksp, name); if (val && val->data_type == KSTAT_DATA_UINT64) { return val->value.ui64; } return 0; } static void _read_sysinfo_kstat(struct pekwm_panel_sysinfo *info, kstat_ctl_t *kc) { kstat_t *ksp; ksp = _kstat_lookup_read(kc, "unix", 0, "system_misc"); if (ksp) { kstat_named_t *val; time_t boot_time = _kstat_data_ui32(ksp, "boot_time"); if (boot_time != 0) { info->uptime = time(NULL) - boot_time; } info->load1 = _to_load(_kstat_data_ui32(ksp, "avenrun_1min")); info->load5 = _to_load(_kstat_data_ui32(ksp, "avenrun_5min")); info->load15 = _to_load(_kstat_data_ui32(ksp, "avenrun_15min")); info->num_procs = _kstat_data_ui32(ksp, "nproc"); } ksp = _kstat_lookup_read(kc, "unix", 0, "system_pages"); if (ksp) { info->ram_kb = _kstat_data_ui64(ksp, "physmem") * _pagesize_kb; info->free_ram_kb = _kstat_data_ui64(ksp, "pagesfree") * _pagesize_kb; } } static int _read_sysinfo(struct pekwm_panel_sysinfo *info) { if (_pagesize_kb == 0) { _pagesize_kb = sysconf(_SC_PAGESIZE) / 1024; } kstat_ctl_t *kc = kstat_open(); if (kc == NULL) { perror("ERROR: kstat_open: "); return -1; } _read_sysinfo_kstat(info, kc); /* not using kstat to read unix:0:vminfo:swap_avail and * unix:0:vminfo:swap_free, seemingly raw stats that I have not * figured out how to read, use swapctl instead. */ swaptbl_t *swt = malloc(sizeof(swaptbl_t) + sizeof(swapent_t) * 16); if (swt) { swt->swt_n = 16; int n = swapctl(SC_LIST, swt); for (int i = 0; i < n; i++) { swapent_t *ste = &swt->swt_ent[i]; info->swap_kb += ste->ste_pages * _pagesize_kb; info->free_swap_kb += ste->ste_free * _pagesize_kb; } free(swt); } /* needs to be kept aorund for the swapctl call */ kstat_close(kc); return 0; } #else /* !__sun__ */ #ifdef __NetBSD__ #include #include #include #include #include #include static int _read_sysinfo(struct pekwm_panel_sysinfo *info) { int mib[6]; size_t size; mib[0] = CTL_KERN; mib[1] = KERN_BOOTTIME; struct timespec boottime = {0}; size = sizeof(boottime); if (! sysctl(mib, 2, &boottime, &size, NULL, 0)) { info->uptime = time(NULL) - boottime.tv_sec; } mib[1] = KERN_PROC2; mib[2] = KERN_PROC_ALL; mib[3] = 0; /* process selector, unused */ mib[4] = sizeof(struct kinfo_proc2); mib[5] = 0; /* number of kinfo_proc2 to return */ size = 0; if (! sysctl(mib, 6, NULL, &size, NULL, 0)) { info->num_procs = size / sizeof(struct kinfo_proc2); } struct uvmexp_sysctl uvmexp = {0}; mib[0] = CTL_VM; mib[1] = VM_UVMEXP2; size = sizeof(uvmexp); if (! sysctl(mib, 2, &uvmexp, &size, NULL, 0)) { int pagesize_kb = uvmexp.pagesize / 1024; info->ram_kb = uvmexp.npages * pagesize_kb; info->free_ram_kb = uvmexp.free * pagesize_kb; info->cache_ram_kb = uvmexp.filepages * pagesize_kb; info->swap_kb = uvmexp.swpages * pagesize_kb; info->free_swap_kb = info->swap_kb - (uvmexp.swpgonly * pagesize_kb); } mib[1] = VM_LOADAVG; struct loadavg loadavg = {0}; size = sizeof(loadavg); if (! sysctl(mib, 2, &loadavg, &size, NULL, 0)) { info->load1 = ((float)loadavg.ldavg[0]) / loadavg.fscale; info->load5 = ((float)loadavg.ldavg[1]) / loadavg.fscale; info->load15 = ((float)loadavg.ldavg[2]) / loadavg.fscale; } return 0; } #else /* !__NetBSD__ */ #ifdef __FreeBSD__ #include #include #include #include #include #include static int _pagesize_kb = 0; static int _read_sysinfo(struct pekwm_panel_sysinfo *info) { if (_pagesize_kb == 0) { _pagesize_kb = sysconf(_SC_PAGESIZE) / 1024; } double loadavg[3]; if (getloadavg(loadavg, 3) == 3) { info->load1 = loadavg[0]; info->load5 = loadavg[1]; info->load15 = loadavg[2]; } int mib[6]; size_t len; mib[0] = CTL_KERN; mib[1] = KERN_BOOTTIME; struct timeval boottime = {0}; len = sizeof(boottime); if (! sysctl(mib, 2, &boottime, &len, NULL, 0)) { info->uptime = time(NULL) - boottime.tv_sec; } mib[1] = KERN_PROC; mib[2] = KERN_PROC_ALL; len = 0; if (sysctl(mib, 3, NULL, &len, NULL, 0) >= 0) { info->num_procs = len / sizeof(struct kinfo_proc); } info->ram_kb = sysconf(_SC_PHYS_PAGES) * _pagesize_kb; mib[0] = CTL_VM; mib[1] = VM_TOTAL; struct vmtotal vmt; len = sizeof(vmt); if (! sysctl(mib, 2, &vmt, &len, NULL, 0)) { info->free_ram_kb = vmt.t_free * _pagesize_kb; } // info->swap_kb = 0; // info->free_swap_kb = 0; return 0; } #else /* !__FreeBSD__ */ #ifdef __OpenBSD__ #include #include #include #include #include #include #include static int _read_sysinfo(struct pekwm_panel_sysinfo *info) { size_t size; int mib[6]; int pagesize_kb = sysconf(_SC_PAGESIZE) / 1024; double loadavg[3]; if (getloadavg(loadavg, 3) == 3) { info->load1 = loadavg[0]; info->load5 = loadavg[1]; info->load15 = loadavg[2]; } mib[0] = CTL_KERN; mib[1] = KERN_BOOTTIME; struct timespec boottime = {0}; size = sizeof(boottime); if (! sysctl(mib, 2, &boottime, &size, NULL, 0)) { info->uptime = time(NULL) - boottime.tv_sec; } mib[1] = KERN_PROC; mib[2] = KERN_PROC_ALL; mib[3] = 0; /* process selector, unused */ mib[4] = sizeof(struct kinfo_proc); mib[5] = 0; /* number of kinfo_proc to return */ size = 0; if (! sysctl(mib, 6, NULL, &size, NULL, 0)) { info->num_procs = size / sizeof(struct kinfo_proc); } mib[0] = CTL_HW; mib[1] = HW_PHYSMEM64; uint64_t physmem = 0; size = sizeof(physmem); if (! sysctl(mib, 2, &physmem, &size, NULL, 0)) { info->ram_kb = physmem / 1024; } struct uvmexp uvmexp; mib[0] = CTL_VM; mib[1] = VM_UVMEXP; size = sizeof(uvmexp); if (! sysctl(mib, 2, &uvmexp, &size, NULL, 0)) { int pagesize_kb = uvmexp.pagesize / 1024; info->swap_kb = uvmexp.swpages * pagesize_kb; info->free_swap_kb = info->swap_kb - (uvmexp.swpgonly * pagesize_kb); mib[0] = CTL_VM; mib[1] = VM_METER; struct vmtotal vmtotal; size = sizeof(vmtotal); if (! sysctl(mib, 2, &vmtotal, &size, NULL, 0)) { info->free_ram_kb = vmtotal.t_free * pagesize_kb; } } mib[0] = CTL_VFS; mib[1] = VFS_GENERIC; mib[2] = VFS_BCACHESTAT; struct bcachestats bcstats; size = sizeof(bcstats); if (! sysctl(mib, 3, &bcstats, &size, NULL, 0)) { info->cache_ram_kb = bcstats.numbufpages * pagesize_kb; } return 0; } #else /* ! __OpenBSD__ */ static int _read_sysinfo(struct pekwm_panel_sysinfo *info) { fprintf(stderr, "ERROR: unsupported platform\n"); return 1; } #endif /* __OpenBSD__ */ #endif /* __FreeBSD__ */ #endif /* __NetBSD__ */ #endif /* __sun__ */ #endif /* __linux__ */ static unsigned int _to_percent(unsigned long total, unsigned long avail) { if (total == 0.0) { return 0; } unsigned long used = total - avail; return (int) (((float)used / total) * 100.0); } static void _to_elapsed_time(unsigned long seconds) { unsigned long s_per[] = { SEC_PER_YEAR, SEC_PER_DAY, SEC_PER_HOUR, SEC_PER_MIN }; const char c_per[] = { 'y', 'd', 'h', 'm' }; for (size_t i = 0; i < sizeof(s_per)/sizeof(s_per[0]); i++) { if (seconds > s_per[i]) { int per = seconds / s_per[i]; seconds %= s_per[i]; printf("%d%c", per, c_per[i]); } } printf("%lus", seconds); } static void _print_sysinfo(struct pekwm_panel_sysinfo *info) { printf("sysinfo_uptime %lu\n", info->uptime); printf("sysinfo_uptime_hr "); _to_elapsed_time(info->uptime); printf("\n"); printf("sysinfo_load1 %.2f\n", info->load1); printf("sysinfo_load5 %.2f\n", info->load5); printf("sysinfo_load15 %.2f\n", info->load15); printf("sysinfo_mem_total %lu\n", info->ram_kb); printf("sysinfo_mem_free %lu\n", info->free_ram_kb); unsigned long free_ram_ec_kb = info->free_ram_kb + info->cache_ram_kb; printf("sysinfo_mem_free_ec %lu\n", free_ram_ec_kb); printf("sysinfo_mem_percent %u\n", _to_percent(info->ram_kb, info->free_ram_kb)); printf("sysinfo_mem_percent_ec %u\n", _to_percent(info->ram_kb, free_ram_ec_kb)); printf("sysinfo_mem_cache %lu\n", info->cache_ram_kb); printf("sysinfo_mem_cache_percent %u\n", _to_percent(info->ram_kb, info->ram_kb - info->cache_ram_kb)); printf("sysinfo_swap_total %lu\n", info->swap_kb); printf("sysinfo_swap_free %lu\n", info->free_swap_kb); printf("sysinfo_swap_percent %u\n", _to_percent(info->swap_kb, info->free_swap_kb)); printf("sysinfo_numproc %u\n", info->num_procs); } #ifndef UNITTEST int main(int argc, char *argv[]) { struct pekwm_panel_sysinfo info = {0}; int err = _read_sysinfo(&info); if (! err) { _print_sysinfo(&info); } return 0; } #endif /* UNITTEST */ pekwm-0.4.4/src/panel/PanelTheme.cc0000664000175000017500000001207715126136025012554 // // PanelTheme.cc for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "Debug.hh" #include "PanelTheme.hh" #include "../tk/FontHandler.hh" #include "../tk/ImageHandler.hh" #include "../tk/TextureHandler.hh" #include "../tk/ThemeUtil.hh" #define DEFAULT_BACKGROUND "SolidRaised #ffffff #eeeeee #cccccc" #define DEFAULT_HEIGHT 24 #define DEFAULT_SEPARATOR "Solid #aaaaaa 1x24" #define DEFAULT_COLOR "#000000" #define DEFAULT_FONT "Sans-12" #define DEFAULT_FONT_FOC DEFAULT_FONT ":weight=bold" #define DEFAULT_FONT_ICO DEFAULT_FONT ":slant=talic" #define DEFAULT_BAR_BORDER "black" #define DEFAULT_BAR_FILL "grey50" PanelTheme::PanelTheme() : _height(0), _loaded(false), _background(nullptr), _background_opacity(255), _sep(nullptr), _handle(nullptr), _bar_border(nullptr), _bar_fill(nullptr) { memset(_fonts, 0, sizeof(_fonts)); memset(_colors, 0, sizeof(_colors)); } PanelTheme::~PanelTheme() { unload(); } void PanelTheme::load(const std::string &theme_dir, const std::string& theme_path) { unload(); CfgParser theme(CfgParserOpt("")); if (! ThemeUtil::load(theme, theme_dir, theme_path, true)) { check(); return; } CfgParser::Entry *section = theme.getEntryRoot()->findSection("PANEL"); if (section == nullptr) { check(); return; } std::string background, separator, handle, bar_border, bar_fill; uint opacity; ThemeUtil::CfgParserKeys keys(pekwm::textureHandler()->getScale()); keys.add_string("BACKGROUND", background, DEFAULT_BACKGROUND); keys.add_numeric("BACKGROUNDOPACITY", opacity, 100, 0, 100); keys.add_pixels("HEIGHT", _height, DEFAULT_HEIGHT); keys.add_string("SEPARATOR", separator, DEFAULT_SEPARATOR); keys.add_string("HANDLE", handle, ""); keys.add_string("BARBORDER", bar_border, DEFAULT_BAR_BORDER); keys.add_string("BARFILL", bar_fill, DEFAULT_BAR_FILL); section->parseKeyValues(keys.begin(), keys.end()); keys.clear(); ImageHandler *ih = pekwm::imageHandler(); ih->path_clear(); ih->path_push_back(theme_dir + "/"); TextureHandler *th = pekwm::textureHandler(); _background = th->getTexture(background); if (opacity == 100) { _background_opacity = 255; } else { _background_opacity = static_cast(255.0 * static_cast(opacity) / 100.0); } _sep = th->getTexture(separator); if (! handle.empty()) { _handle = th->getTexture(handle); } _bar_border = X11::getColor(bar_border); _bar_fill = X11::getColor(bar_fill); loadState(section->findSection("FOCUSED"), CLIENT_STATE_FOCUSED); loadState(section->findSection("UNFOCUSED"), CLIENT_STATE_UNFOCUSED); loadState(section->findSection("ICONIFIED"), CLIENT_STATE_ICONIFIED); check(); } void PanelTheme::unload() { if (! _loaded) { return; } _height = 0; X11::returnColor(_bar_border); X11::returnColor(_bar_fill); TextureHandler *th = pekwm::textureHandler(); if (_handle) { th->returnTexture(&_handle); } th->returnTexture(&_sep); th->returnTexture(&_background); FontHandler *fh = pekwm::fontHandler(); for (int i = 0; i < CLIENT_STATE_NO; i++) { fh->returnFont(&_fonts[i]); fh->returnColor(&_colors[i]); } _loaded = false; } void PanelTheme::loadState(CfgParser::Entry *section, ClientState state) { if (section == nullptr) { return; } std::string font, color; CfgParserKeys keys; keys.add_string("FONT", font, DEFAULT_FONT); keys.add_string("COLOR", color, "#000000"); section->parseKeyValues(keys.begin(), keys.end()); keys.clear(); _fonts[state] = pekwm::fontHandler()->getFont(font); _colors[state] = pekwm::fontHandler()->getColor(color); } /** * Add configured path to image load path for looking up icons. */ void PanelTheme::setIconPath(const std::string& config_path, const std::string& theme_path) { ImageHandler *ih = pekwm::imageHandler(); ih->path_push_back(DATADIR "/pekwm/icons/"); ih->path_push_back(config_path); ih->path_push_back(theme_path); } /** * Get font and update color (same font will be shared) */ PFont* PanelTheme::getFont(ClientState state) const { PFont* font = _fonts[state]; font->setColor(_colors[state]); return font; } void PanelTheme::check() { if (_height == 0) { float scale = pekwm::textureHandler()->getScale(); _height = ThemeUtil::scaledPixelValue(scale, DEFAULT_HEIGHT); } FontHandler *fh = pekwm::fontHandler(); for (int i = 0; i < CLIENT_STATE_NO; i++) { if (_fonts[i] == nullptr) { P_TRACE("setting default font[" << i << "]"); _fonts[i] = fh->getFont(DEFAULT_FONT "#Center"); } if (_colors[i] == nullptr) { P_TRACE("setting default color[" << i << "]"); _colors[i] = fh->getColor(DEFAULT_COLOR); } } TextureHandler *th = pekwm::textureHandler(); if (_background == nullptr) { _background = th->getTexture(DEFAULT_BACKGROUND); } if (_sep == nullptr) { _sep = th->getTexture(DEFAULT_SEPARATOR); } _background->setOpacity(_background_opacity); if (_bar_border == nullptr) { _bar_border = X11::getColor(DEFAULT_BAR_BORDER); } if (_bar_fill == nullptr) { _bar_fill = X11::getColor(DEFAULT_BAR_FILL); } _loaded = true; } pekwm-0.4.4/src/panel/ClientInfo.cc0000664000175000017500000000312215126136025012553 // // ClientInfo.cc for pekwm // Copyright (C) 2022-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "ClientInfo.hh" #include "Debug.hh" #include "X11.hh" /** empty string, used as default return value. */ static std::string _empty_string; ClientInfo::ClientInfo(Window window) : _window(window), _name(readName()), _gm(readGeometry()), _workspace(readWorkspace()), _icon(PImageIcon::newFromWindow(window)) { X11::selectInput(_window, PropertyChangeMask); X11Util::readEwmhStates(_window, *this); } ClientInfo::~ClientInfo(void) { if (_icon) { delete _icon; } } bool ClientInfo::handlePropertyNotify(XPropertyEvent *ev) { if (ev->atom == X11::getAtom(NET_WM_NAME) || ev->atom == XA_WM_NAME) { _name = readName(); } else if (ev->atom == X11::getAtom(NET_WM_DESKTOP)) { _workspace = readWorkspace(); } else if (ev->atom == X11::getAtom(STATE)) { X11Util::readEwmhStates(_window, *this); } else { return false; } return true; } std::string ClientInfo::readName(void) { std::string name; if (X11::getUtf8String(_window, NET_WM_VISIBLE_NAME, name)) { return name; } if (X11::getUtf8String(_window, NET_WM_NAME, name)) { return name; } if (X11::getTextProperty(_window, XA_WM_NAME, name)) { return name; } return _empty_string; } uint ClientInfo::readWorkspace(void) { Cardinal workspace; if (! X11::getCardinal(_window, NET_WM_DESKTOP, workspace)) { P_TRACE("failed to read _NET_WM_DESKTOP on " << _window << " using 0"); return 0; } return workspace; } pekwm-0.4.4/src/panel/DateTimeWidget.hh0000664000175000017500000000317415126136025013402 // // DateTimeWidget.hh for pekwm // Copyright (C) 2022 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_DATE_TIME_WIDGET_HH_ #define _PEKWM_PANEL_DATE_TIME_WIDGET_HH_ #include #include "PanelTheme.hh" #include "PanelWidget.hh" /** * Current Date/Time formatted using strftime. */ class DateTimeWidget : public PanelWidget { public: DateTimeWidget(const PanelWidgetData &data, const PWinObj* parent, const WidgetConfig& cfg, const std::string &format) : PanelWidget(data, parent, cfg.getSizeReq(), cfg.getIf()), _format(format) { if (_format.empty()) { _format = "%Y-%m-%d %H:%M"; } } virtual const char *getName() const { return "DateTime"; } virtual uint getRequiredSize(void) const { std::string stime; formatNow(stime); PFont *font = _theme.getFont(CLIENT_STATE_UNFOCUSED); return font->getWidth(" " + stime + " "); } virtual void render(Render &rend, PSurface *surface) { PanelWidget::render(rend, surface); std::string stime; formatNow(stime); stime.insert(stime.begin(), ' '); PFont *font = _theme.getFont(CLIENT_STATE_UNFOCUSED); renderText(rend, surface, font, getX(), stime, getWidth()); // always treat date time as dirty, requires redraw up to // every second. _dirty = true; } private: void formatNow(std::string &res) const { time_t now = time(NULL); struct tm tm; localtime_r(&now, &tm); char buf[64]; strftime(buf, sizeof(buf), _format.c_str(), &tm); res = buf; } private: std::string _format; }; #endif // _PEKWM_PANEL_DATE_TIME_WIDGET_HH_ pekwm-0.4.4/src/panel/WmState.cc0000664000175000017500000001273115126136025012113 // // WmState.cc for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "Debug.hh" #include "WmState.hh" /** empty string, used as default return value. */ static std::string _empty_string; WmState::WmState(VarData& var_data) : _var_data(var_data), _active_window(None), _workspace(0) { } WmState::~WmState() { std::vector::iterator it = _clients.begin(); for (; it != _clients.end(); ++it) { delete *it; } } void WmState::read(void) { readActiveWorkspace(); readActiveWindow(); readClientList(); readDesktopNames(); readRootProperties(); pekwm::observerMapping()->notifyObservers(this, nullptr); } const std::string& WmState::getWorkspaceName(uint num) const { if (num < _desktop_names.size()) { return _desktop_names[num]; } return _empty_string; } ClientInfo* WmState::findClientInfo(Window win) const { return findClientInfo(win, _clients); } bool WmState::handlePropertyNotify(XPropertyEvent *ev) { bool updated = false; Observation *observation = nullptr; P_DBG("XPropertyEvent window: " << ev->window << " (root: " << (ev->window == X11::getRoot()) << ") atom: " << ev->atom); if (ev->window == X11::getRoot()) { if (ev->atom == X11::getAtom(NET_CURRENT_DESKTOP)) { updated = readActiveWorkspace(); if (updated) { observation = &_active_workspace_changed; } } else if (ev->atom == X11::getAtom(NET_ACTIVE_WINDOW)) { updated = readActiveWindow(); if (updated) { observation = &_active_window_changed; } } else if (ev->atom == X11::getAtom(NET_CLIENT_LIST)) { updated = readClientList(); if (updated) { observation = &_client_list_changed; } } else if (ev->atom == X11::getAtom(XROOTPMAP_ID)) { observation = &_xrootpmap_id_changed; } else { updated = readRootProperty(ev->atom); if (updated) { observation = &_wm_state_observation; } } } else { ClientInfo *client_info = findClientInfo(ev->window, _clients); if (client_info != nullptr) { updated = client_info->handlePropertyNotify(ev); if (updated) { observation = &_client_state_changed; } } } if (updated || observation) { pekwm::observerMapping()->notifyObservers(this, observation); } return updated; } ClientInfo* WmState::findClientInfo(Window win, const std::vector &clients) const { std::vector::const_iterator it = clients.begin(); for (; it != clients.end(); ++it) { if ((*it)->getWindow() == win) { return *it; } } return nullptr; } ClientInfo* WmState::popClientInfo(Window win, std::vector &clients) { std::vector::iterator it = clients.begin(); for (; it != clients.end(); ++it) { if ((*it)->getWindow() == win) { ClientInfo *client_info = *it; clients.erase(it); return client_info; } } return nullptr; } bool WmState::readActiveWorkspace(void) { Cardinal workspace; if (! X11::getCardinal(X11::getRoot(), NET_CURRENT_DESKTOP, workspace)) { P_TRACE("failed to read _NET_CURRENT_DESKTOP, setting to 0"); _workspace = 0; return false; } _workspace = workspace; return true; } bool WmState::readActiveWindow(void) { if (! X11::getWindow(X11::getRoot(), NET_ACTIVE_WINDOW, _active_window)) { P_TRACE("failed to read _NET_ACTIVE_WINDOW, setting to None"); _active_window = None; return false; } return true; } bool WmState::readClientList(void) { client_info_vector old_clients(_clients); _clients.clear(); ulong actual; Window *windows; bool updated = false; if (X11::getProperty(X11::getRoot(), X11::getAtom(NET_CLIENT_LIST), XA_WINDOW, 0, reinterpret_cast(&windows), &actual)) { P_TRACE("read _NET_CLIENT_LIST, " << actual << " windows"); for (uint i = 0; i < actual; i++) { ClientInfo *client_info = popClientInfo(windows[i], old_clients); if (client_info == nullptr) { updated = true; _clients.push_back(new ClientInfo(windows[i])); } else { _clients.push_back(client_info); } } X11::free(windows); } client_info_it it = old_clients.begin(); for (; it != old_clients.end(); ++it) { updated = true; delete *it; } return updated; } bool WmState::readDesktopNames(void) { _desktop_names.clear(); uchar *data; ulong data_length; if (! X11::getProperty(X11::getRoot(), X11::getAtom(NET_DESKTOP_NAMES), X11::getAtom(UTF8_STRING), 0, &data, &data_length)) { return false; } char *name = reinterpret_cast(data); for (ulong i = 0; i < data_length; ) { _desktop_names.push_back(name); int name_len = strlen(name); i += name_len + 1; name += name_len + 1; } X11::free(data); return true; } void WmState::readRootProperties(void) { std::vector atoms; if (! X11::listProperties(X11::getRoot(), atoms)) { return; } std::vector::iterator it = atoms.begin(); for (; it != atoms.end(); ++it) { readRootProperty(*it); } } bool WmState::readRootProperty(Atom atom) { bool res = false; const std::string& name = getAtomName(atom); if (name.size() > 0) { std::string value; if (X11::getStringId(X11::getRoot(), atom, value)) { _var_data.set("ATOM_" + name, value); res = true; } } return res; } const std::string& WmState::getAtomName(Atom atom) { std::map::iterator it = _atom_names.find(atom); if (it != _atom_names.end()) { return it->second; } _atom_names[atom] = X11::getAtomIdString(atom); return _atom_names[atom]; } pekwm-0.4.4/src/panel/ExternalCommandData.cc0000664000175000017500000001117015126136025014376 // // ExternalCommandData.cc for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "Debug.hh" #include "ExternalCommandData.hh" extern "C" { #include #include #include } // ExternalCommandData::CommandProcess ExternalCommandData::CommandProcess::CommandProcess(const std::string& command, uint interval_s, const std::string& assign) : _command(command), _interval_s(interval_s), _assign(assign), _pid(-1), _fd(-1) { // set next interval to last second to ensure immediate // execution int ret = clock_gettime(CLOCK_MONOTONIC, &_next_interval); assert(ret == 0); _next_interval.tv_sec--; } ExternalCommandData::CommandProcess::~CommandProcess() { reset(); } bool ExternalCommandData::CommandProcess::start() { int fd[2]; int ret = pipe(fd); if (ret == -1) { P_ERR("pipe failed due to: " << strerror(errno)); return false; } _pid = fork(); if (_pid == -1) { close(fd[0]); close(fd[1]); P_ERR("fork failed due to: " << strerror(errno)); return false; } else if (_pid == 0) { // child, dup write end of file descriptor to // stdout dup2(fd[1], STDOUT_FILENO); close(fd[0]); close(fd[1]); char *argv[4]; argv[0] = strdup(PEKWM_SH); argv[1] = strdup("-c"); argv[2] = strdup(_command.c_str()); argv[3] = NULL; execvp(argv[0], argv); P_ERR("failed to execute: " << _command); close(STDOUT_FILENO); exit(1); } // parent, close write end just going to read _fd = fd[0]; close(fd[1]); Util::setNonBlock(_fd); if (Debug::isLevel(Debug::LEVEL_TRACE)) { P_TRACE("pid " << _pid << " started with fd " << _fd << " for command " << _command); } return true; } void ExternalCommandData::CommandProcess::reset(void) { _pid = -1; if (_fd != -1) { close(_fd); } _fd = -1; _buf = ""; int ret = clock_gettime(CLOCK_MONOTONIC, &_next_interval); assert(ret == 0); _next_interval.tv_sec += _interval_s; } // ExternalCommandData ExternalCommandData::ExternalCommandData(const PanelConfig& cfg, VarData& var_data) : _cfg(cfg), _var_data(var_data) { PanelConfig::command_config_it it = _cfg.commandsBegin(); for (; it != _cfg.commandsEnd(); ++it) { _command_processes.push_back( CommandProcess(it->getCommand(), it->getIntervalS(), it->getAssign())); } } ExternalCommandData::~ExternalCommandData(void) { } void ExternalCommandData::refresh(fdFun addFd, void *opaque) { struct timespec now; int ret = clock_gettime(CLOCK_MONOTONIC, &now); assert(ret == 0); std::vector::iterator it = _command_processes.begin(); for (; it != _command_processes.end(); ++it) { if (it->getPid() == -1 && it->checkInterval(&now) && it->start()) { addFd(it->getFd(), opaque); } } } bool ExternalCommandData::input(int fd) { char buf[1024]; ssize_t nread = read(fd, buf, sizeof(buf)); if (nread < 1) { if (nread == -1) { P_TRACE("failed to read from " << fd << ": " << strerror(errno)); } return false; } std::vector::iterator it = _command_processes.begin(); for (; it != _command_processes.end(); ++it) { if (it->getFd() == fd) { append(it->getBuf(), buf, nread, it->getAssign()); break; } } return true; } void ExternalCommandData::done(pid_t pid, fdFun removeFd, void *opaque) { std::vector::iterator it = _command_processes.begin(); for (; it != _command_processes.end(); ++it) { if (it->getPid() == pid) { while (input(it->getFd())) { // read data left in pipe if any } parseOutput(it->getBuf()); removeFd(it->getFd(), opaque); // clean up state, resetting timer and pid/fd it->reset(); break; } } } void ExternalCommandData::append(std::string &buf, const char *data, size_t size, const std::string &assign) { buf.append(data, data + size); size_t pos = buf.find('\n'); while (pos != std::string::npos) { std::string line = buf.substr(0, pos); if (assign.empty()) { parseLine(line); } else if (! line.empty()) { _var_data.set(assign, line); } buf.erase(0, pos + 1); pos = buf.find('\n'); } } void ExternalCommandData::parseOutput(const std::string& buf) { std::vector lines; Util::splitString(buf, lines, "\n"); std::vector::iterator it = lines.begin(); for (; it != lines.end(); ++it) { parseLine(*it); } } void ExternalCommandData::parseLine(const std::string& line) { std::vector field_value; if (Util::splitString(line, field_value, " \t", 2) == 2) { _var_data.set(field_value[0], field_value[1]); } } pekwm-0.4.4/src/panel/PanelConfig.hh0000664000175000017500000001146215126136025012726 // // PanelConfig.hh for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_PANEL_CONFIG_HH_ #define _PEKWM_PANEL_PANEL_CONFIG_HH_ #include #include #include "pekwm_panel.hh" #include "CfgParser.hh" #include "PanelAction.hh" extern "C" { #ifdef PEKWM_HAVE_SYS_LIMITS_H #include #else // ! PEKWM_HAVE_SYS_LIMITS_H #include #endif // PEKWM_HAVE_SYS_LIMITS_H } class WidgetConfigClick { public: WidgetConfigClick(int button, PanelActionType type, const std::string ¶m) : _button(button), _type(type), _param(param) { } int getButton() const { return _button; } PanelActionType getType() const { return _type; } const std::string &getParam() const { return _param; } private: int _button; PanelActionType _type; std::string _param; }; /** * Widgets to display. */ class WidgetConfig { public: WidgetConfig(const std::string& name, const std::vector& args, const std::string& if_, const SizeReq& size_req, uint interval_s, const std::vector &clicks, const CfgParser::Entry* section = nullptr); WidgetConfig(const WidgetConfig& cfg); ~WidgetConfig(); WidgetConfig& operator=(const WidgetConfig&); const std::string& getName(void) const { return _name; } const std::string& getArg(uint arg) const; const std::string& getIf() const { return _if; } const SizeReq& getSizeReq(void) const { return _size_req; } uint getIntervalS(void) const { return _interval_s; } const std::vector &getClicks() const { return _clicks; } const CfgParser::Entry* getCfgSection(void) const { return _section; } private: /** Widget type name. */ std::string _name; /** Widget arguments (if any). */ std::vector _args; /** Condition that needs to evaluate to true to display the widget. */ std::string _if; /** Requested size of widget. */ SizeReq _size_req; /** Refresh interval of widgets, set to UINT_MAX for non time based widgets. */ uint _interval_s; /** Button click -> action map. */ std::vector _clicks; /** Configuration section, accessible for widget-specific configuration. */ CfgParser::Entry* _section; }; /** * Configuration for commands to be run at given intervals to * collect data. */ class CommandConfig { public: CommandConfig(const std::string& command, uint interval_s, const std::string& assign); ~CommandConfig(); const std::string& getCommand() const { return _command; } uint getIntervalS() const { return _interval_s; } const std::string& getAssign() const { return _assign; } private: /** Command to run (using the shell) */ std::string _command; /** Interval between runs, not including run time. */ uint _interval_s; /** If non-empty, assign all line output to variable. */ std::string _assign; }; /** * Configuration for panel, read from ~/.pekwm/panel by default. */ class PanelConfig { public: typedef std::vector command_config_vector; typedef command_config_vector::const_iterator command_config_it; typedef std::vector widget_config_vector; typedef widget_config_vector::const_iterator widget_config_it; PanelConfig(); ~PanelConfig(); bool load(const std::string &panel_file); PanelPlacement getPlacement(void) const { return _placement; } int getHead(void) const { return _head; } uint getRefreshIntervalS(void) const { return _refresh_interval_s; } command_config_it commandsBegin(void) const { return _commands.begin(); } command_config_it commandsEnd(void) const { return _commands.end(); } widget_config_it widgetsBegin(void) const { return _widgets.begin(); } widget_config_it widgetsEnd(void) const { return _widgets.end(); } private: void loadPanel(CfgParser::Entry *section); void loadCommands(CfgParser::Entry *section); void loadWidgets(CfgParser::Entry *section); void loadWidgetClicks(CfgParser::Entry *section, std::vector &clicks); void addWidget(const std::string& name, const std::string& if_, const SizeReq& size_req, uint interval, const std::string& args_str, const std::vector &clicks, const CfgParser::Entry* section); SizeReq parseSize(const std::string& size); uint calculateRefreshIntervalS(void) const; private: /** Position of panel. */ PanelPlacement _placement; /** Panel head, -1 for stretch all heads which is default. */ int _head; /** List of commands to run. */ command_config_vector _commands; /** List of widgets to instantiate. */ std::vector _widgets; /** At what given interval is refresh required at a minimum. */ uint _refresh_interval_s; }; #endif // _PEKWM_PANEL_PANEL_CONFIG_HH_ pekwm-0.4.4/src/panel/PanelWidget.cc0000664000175000017500000000576415126136025012742 // // PanelWidget.cc for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "Cond.hh" #include "Debug.hh" #include "PanelWidget.hh" #include "TextFormatter.hh" static RequiredSizeChanged _required_size_changed; PanelWidget::PanelWidget(const PanelWidgetData &data, const PWinObj* parent, const SizeReq& size_req, const std::string& if_) : _os(data.os), _observer(data.observer), _theme(data.theme), _var_data(data.var_data), _wm_state(data.wm_state), _parent(parent), _dirty(true), _if_tfo(_var_data, _wm_state, this, if_), _x(0), _rx(0), _width(0), _size_req(size_req), _cond_true(Cond::eval(_if_tfo.format())) { if (! _if_tfo.isFixed()) { pekwm::observerMapping()->addObserver(this, _observer, 100); } } PanelWidget::~PanelWidget() { if (! _if_tfo.isFixed()) { pekwm::observerMapping()->removeObserver(this, _observer); } } void PanelWidget::notify(Observable *, Observation *observation) { if (_if_tfo.match(observation)) { bool cond_true = Cond::eval(_if_tfo.format()); if (_cond_true != cond_true) { _dirty = true; _cond_true = cond_true; sendRequiredSizeChanged(); } } } /** * Assign the given action for button clicks on the given button. */ void PanelWidget::setButtonAction(int button, const PanelAction &action) { _button_actions[button] = action; } void PanelWidget::move(int x) { _x = x; _rx = x + _width; } void PanelWidget::click(int button, int, int) { std::map::iterator it(_button_actions.find(button)); if (it != _button_actions.end()) { runAction(it->second); } } int PanelWidget::renderText(Render &rend, PSurface *surface, PFont *font, int x, const std::string& text, uint max_width) { int y = (_theme.getHeight() - font->getHeight()) / 2; uint width_used; return font->draw(surface, x, y, text, width_used, max_width, PFont::FONT_TRIM_MIDDLE); } void PanelWidget::sendRequiredSizeChanged() { _dirty = true; pekwm::observerMapping()->notifyObservers(this, &_required_size_changed); } void PanelWidget::runAction(const PanelAction &action) { TextFormatter tf(_var_data, _wm_state); std::string command = tf.format(action.getPpParam()); if (action.getType() == PANEL_ACTION_EXEC) { runActionExec(action.getParam(), command); } else { runActionPekwm(action.getParam(), command); } } void PanelWidget::runActionExec(const std::string ¶m, const std::string &command) { P_TRACE("PanelWidget action exec " << param << " command " << command); if (command.size() > 0) { std::vector args = StringUtil::shell_split(command); _os->processExec(args); } } void PanelWidget::runActionPekwm(const std::string ¶m, const std::string &command) { P_TRACE("PanelWidget action pekwm " << param << " command " << command); std::vector args; args.push_back(BINDIR "/pekwm_ctrl"); args.push_back(command); _os->processExec(args); } pekwm-0.4.4/src/panel/TextWidget.cc0000664000175000017500000000343515126136025012620 // // TextWidget.cc for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "TextFormatter.hh" #include "TextWidget.hh" TextWidget::TextWidget(const PanelWidgetData &data, const PWinObj* parent, const WidgetConfig& cfg, const std::string& format) : PanelWidget(data, parent, cfg.getSizeReq(), cfg.getIf()), _tfo(_var_data, _wm_state, this, format) { parseText(cfg.getCfgSection()); } TextWidget::~TextWidget() { } void TextWidget::notify(Observable *observable, Observation *observation) { if (_dirty) { return; } FieldObservation *fo = dynamic_cast(observation); _dirty = fo == nullptr || _tfo.match(observation); PanelWidget::notify(observable, observation); } uint TextWidget::getRequiredSize(void) const { if (_tfo.isFixed()) { // no variables that will be expanded after the widget has // been created, use width of _pp_format. PFont *font = _theme.getFont(CLIENT_STATE_UNFOCUSED); return font->getWidth(" " + _tfo.getPpFormat() + " "); } // variables will be expanded, no way to know how much space will // be required. return 0; } void TextWidget::render(Render &rend, PSurface *surface) { PanelWidget::render(rend, surface); PFont *font = _theme.getFont(CLIENT_STATE_UNFOCUSED); std::string text(_tfo.format()); if (_transform.is_match_ok()) { _transform.ed_s(text); } renderText(rend, surface, font, getX(), text, getWidth()); } void TextWidget::parseText(const CfgParser::Entry* section) { std::string transform; CfgParserKeys keys; keys.add_string("TRANSFORM", transform); section->parseKeyValues(keys.begin(), keys.end()); keys.clear(); if (transform.size() > 0) { _transform.parse_ed_s(transform); } } pekwm-0.4.4/src/panel/IconWidget.cc0000664000175000017500000001143015126136025012556 // // IconWidget.cc for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "Charset.hh" #include "Debug.hh" #include "IconWidget.hh" #include "TextFormatter.hh" #include "../tk/ImageHandler.hh" #include "../tk/TextureHandler.hh" IconWidget::IconWidget(const PanelWidgetData &data, const PWinObj* parent, const WidgetConfig& cfg, const std::string& field) : PanelWidget(data, parent, cfg.getSizeReq(), cfg.getIf()), _field(field), _scale(false), _icon(nullptr), _icon_scaled(nullptr) { parseIcon(cfg.getCfgSection()); pekwm::observerMapping()->addObserver(&_var_data, this, 100); load(); } IconWidget::~IconWidget() { pekwm::observerMapping()->removeObserver(&_var_data, this); if (_icon) { pekwm::imageHandler()->returnImage(_icon); } delete _icon_scaled; } void IconWidget::notify(Observable *observable, Observation *observation) { FieldObservation *fo = dynamic_cast(observation); if (fo != nullptr && fo->getField() == _field) { _dirty = true; load(); } PanelWidget::notify(observable, observation); } uint IconWidget::getRequiredSize() const { if (_scale || _icon == nullptr) { return _theme.getHeight(); } return _icon->getWidth() + 2; } void IconWidget::scaleChanged() { // reload icon as the scaling is applied when the icon is loaded and // will affect the required size load(); } void IconWidget::render(Render& rend, PSurface* surface) { PanelWidget::render(rend, surface); if (_icon == nullptr) { // do nothing, no icon to render P_TRACE("IconWidget render " << _name << _ext << ", no icon loaded"); } else if (_scale) { renderScaled(rend, surface); } else { renderFixed(rend, surface); } } void IconWidget::renderFixed(Render& rend, PSurface* surface) { uint height, width; uint height_avail = _theme.getHeight() - 2; if (_icon->getHeight() > height_avail) { float aspect = (float) height_avail / _icon->getHeight(); height = height_avail; width = static_cast(_icon->getWidth() * aspect); } else { height = _icon->getHeight(); width = _icon->getWidth(); } P_TRACE("IconWidget render " << _icon_name << " " << width << "x" << height << " (fixed)"); scaleImage(width, height); _icon_scaled->draw(rend, surface, getX() + 1, (height_avail - height) / 2, width, height); } void IconWidget::renderScaled(Render& rend, PSurface* surface) { uint side = _theme.getHeight() - 2; P_TRACE("IconWidget render " << _icon_name << " " << side << "x" << side << " (scaled)"); scaleImage(side, side); _icon_scaled->draw(rend, surface, getX() + 1, 1, side, side); } void IconWidget::load() { std::string value; if (! _field.empty()) { value = Charset::toSystem(_var_data.get(_field)); } if (_transform.is_match_ok()) { _transform.ed_s(value); } std::string image = _name + "-" + value + _ext; if (value.empty() || ! loadImage(image)) { loadImage(_name + _ext); } } bool IconWidget::loadImage(const std::string& icon_name) { float scale = pekwm::textureHandler()->getScale(); if (_icon_name == icon_name && _icon_scale == scale) { return true; } ImageHandler *ih = pekwm::imageHandler(); if (_icon) { ih->returnImage(_icon); } _icon = ih->getImage(icon_name); if (_icon) { _icon_name = icon_name; P_TRACE("IconWidget loaded " << _icon_name << " " << _icon->getWidth() << "x" << _icon->getHeight()); } else { _icon_name = ""; } // delete cache whenever a new image is loaded (or fails to do so) delete _icon_scaled; _icon_scaled = nullptr; _icon_scale = scale; return _icon != nullptr; } void IconWidget::parseIcon(const CfgParser::Entry* section) { std::string name, transform, exec; CfgParserKeys keys; keys.add_string("ICON", name); keys.add_string("TRANSFORM", transform); keys.add_bool("SCALE", _scale); keys.add_string("EXEC", exec); section->parseKeyValues(keys.begin(), keys.end()); keys.clear(); size_t pos = name.find_last_of("."); if (pos == std::string::npos) { _name = name; } else { _name = name.substr(0, pos); _ext = name.substr(pos, name.size() - pos); } if (transform.size() > 0) { _transform.parse_ed_s(transform); } // legacy Exec configuration, now equal to Click = "1" { Exec = "..." } if (! exec.empty()) { TextFormatter tf(_var_data, _wm_state); std::string pp_exec = tf.preprocess(exec); PanelAction action(PANEL_ACTION_EXEC, exec, pp_exec); setButtonAction(1, action); } // inital load of image to get size request right load(); } void IconWidget::scaleImage(uint width, uint height) { if (_icon_scaled == nullptr || _icon_scaled->getWidth() != width || _icon_scaled->getHeight() != height) { delete _icon_scaled; _icon_scaled = new PImage(_icon); _icon_scaled->scale(width, height); } } pekwm-0.4.4/src/panel/VarData.cc0000664000175000017500000000203015126136025012040 // // VarData.cc for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "VarData.hh" /** empty string, used as default return value. */ static std::string _empty_string; FieldObservation::FieldObservation(const std::string& field) : _field(field) { } FieldObservation::~FieldObservation(void) { } const std::string& VarData::get(const std::string& field) const { std::map::const_iterator it = _vars.find(field); return it == _vars.end() ? _empty_string : it->second; } void VarData::set(const std::string& field, const std::string& value) { // update the value in the map before notifying in case the // value is read by the obvserver std::map::iterator it = _vars.find(field); if (it == _vars.end() || it->second != value) { _vars[field] = value; FieldObservation field_obs(field); pekwm::observerMapping()->notifyObservers(this, &field_obs); } } pekwm-0.4.4/src/panel/IconWidget.hh0000664000175000017500000000335315126136025012575 // // IconWidget.hh for pekwm // Copyright (C) 2022-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PANEL_ICON_WIDGET_HH_ #define _PEKWM_PANEL_ICON_WIDGET_HH_ #include "pekwm_panel.hh" #include "PanelWidget.hh" #include "RegexString.hh" #include "../tk/PImage.hh" /** * Display icon based on value from external command. */ class IconWidget : public PanelWidget { public: IconWidget(const PanelWidgetData &data, const PWinObj* parent, const WidgetConfig& cfg, const std::string& field); virtual ~IconWidget(void); virtual const char *getName() const { return "Icon"; } virtual void notify(Observable *, Observation *observation); virtual uint getRequiredSize(void) const; virtual void scaleChanged(); virtual void render(Render& rend, PSurface* surface); private: void renderFixed(Render& rend, PSurface* surface); void renderScaled(Render& rend, PSurface* surface); void load(); bool loadImage(const std::string& icon_name); void parseIcon(const CfgParser::Entry* section); void scaleImage(uint width, uint height); private: std::string _field; /** icon name, no file extension. */ std::string _name; /** file extension. */ std::string _ext; /** Regex transform of observed field */ RegexString _transform; /** If true, scale icon square to fit panel height */ bool _scale; /** current loaded icon, matching _icon_name. */ PImage* _icon; /** scale at which icon was loaded in, used to invalidate in case scale * changes. */ float _icon_scale; /** current loaded icon name. */ std::string _icon_name; /** loaded icon, scaled to fit panel theme size. */ PImage* _icon_scaled; }; #endif // _PEKWM_PANEL_ICON_WIDGET_HH_ pekwm-0.4.4/src/CMakeLists.txt0000664000175000017500000000101015126136025011645 cmake_minimum_required(VERSION 3.10) configure_file(${CMAKE_SOURCE_DIR}/CMake/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) add_subdirectory(lib) add_subdirectory(bg) if (CMAKE_BUILD_TYPE MATCHES Debug) add_subdirectory(cfg) endif (CMAKE_BUILD_TYPE MATCHES Debug) add_subdirectory(ctrl) add_subdirectory(dialog) add_subdirectory(panel) add_subdirectory(sys) add_subdirectory(tk) if (ENABLE_IMAGE_PNG AND PNG_FOUND) add_subdirectory(screenshot) endif (ENABLE_IMAGE_PNG AND PNG_FOUND) add_subdirectory(wm) pekwm-0.4.4/src/pekwm_env.hh0000664000175000017500000000060015126136025011425 // // pekwm_env.hh for pekwm // Copyright (C) 2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_ENV_HH_ #define _PEKWM_ENV_HH_ #include void initEnv(bool override); void initEnvConfig(const std::string& cfg_path, const std::string& cfg_file); #endif // _PEKWM_ENV_HH_ pekwm-0.4.4/src/wm/0000775000175000017500000000000015164641623007627 5pekwm-0.4.4/src/wm/Config.cc0000664000175000017500000010760515126136025011265 // // Config.cc for pekwm // Copyright (C) 2023-2025 Claes Nästén // Copyright (C) 2002-2021 the pekwm development team // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include "Config.hh" #include "Compat.hh" #include "Debug.hh" #include "Util.hh" #include "Workspaces.hh" #include "X11.hh" // for DPY in keyconfig code #include "pekwm_env.hh" #include "tk/CfgUtil.hh" #include "tk/Hooks.hh" #include "tk/PFont.hh" #include "tk/TkGlobals.hh" #include extern "C" { #include #include #include } static Util::StringTo action_access_mask_map[] = {{"MOVE", ACTION_ACCESS_MOVE}, {"RESIZE", ACTION_ACCESS_RESIZE}, {"ICONIFY", ACTION_ACCESS_ICONIFY}, {"SHADE", ACTION_ACCESS_SHADE}, {"STICK", ACTION_ACCESS_STICK}, {"MAXIMIZEHORIZONTAL", ACTION_ACCESS_MAXIMIZE_HORZ}, {"MAXIMIZEVERTICAL", ACTION_ACCESS_MAXIMIZE_VERT}, {"FULLSCREEN", ACTION_ACCESS_FULLSCREEN}, {"SETWORKSPACE", ACTION_ACCESS_CHANGE_DESKTOP}, {"CLOSE", ACTION_ACCESS_CLOSE}, {nullptr, ACTION_ACCESS_NO}}; static Util::StringTo moveresize_map[] = {{"MOVEHORIZONTAL", MOVE_HORIZONTAL}, {"MOVEVERTICAL", MOVE_VERTICAL}, {"RESIZEHORIZONTAL", RESIZE_HORIZONTAL}, {"RESIZEVERTICAL", RESIZE_VERTICAL}, {"MOVESNAP", MOVE_SNAP}, {"CANCEL", MOVE_CANCEL}, {"END", MOVE_END}, {nullptr, NO_MOVERESIZE_ACTION}}; static Util::StringTo inputdialog_map[] = {{"INSERT", INPUT_INSERT}, {"ERASE", INPUT_REMOVE}, {"CLEAR", INPUT_CLEAR}, {"CLEARFROMCURSOR", INPUT_CLEARFROMCURSOR}, {"CLEARTOCURSOR", INPUT_CLEARTOCURSOR}, {"EXEC", INPUT_EXEC}, {"CLOSE", INPUT_CLOSE}, {"COMPLETE", INPUT_COMPLETE}, {"COMPLETEABORT", INPUT_COMPLETE_ABORT}, {"CURSNEXT", INPUT_CURS_NEXT}, {"CURSPREV", INPUT_CURS_PREV}, {"CURSEND", INPUT_CURS_END}, {"CURSBEGIN", INPUT_CURS_BEGIN}, {"HISTNEXT", INPUT_HIST_NEXT}, {"HISTPREV", INPUT_HIST_PREV}, {nullptr, INPUT_NO_ACTION}}; static Util::StringTo mouse_event_map[] = {{"BUTTONPRESS", MOUSE_EVENT_PRESS}, {"BUTTONRELEASE", MOUSE_EVENT_RELEASE}, {"DOUBLECLICK", MOUSE_EVENT_DOUBLE}, {"MOTION", MOUSE_EVENT_MOTION}, {"ENTER", MOUSE_EVENT_ENTER}, {"LEAVE", MOUSE_EVENT_LEAVE}, {"ENTERMOVING", MOUSE_EVENT_ENTER_MOVING}, {"MOTIONPRESSED", MOUSE_EVENT_MOTION_PRESSED}, {nullptr, MOUSE_EVENT_NO}}; static Util::StringTo menu_action_map[] = {{"NEXTITEM", ACTION_MENU_NEXT}, {"PREVITEM", ACTION_MENU_PREV}, {"GOTOITEM", ACTION_MENU_GOTO}, {"SELECT", ACTION_MENU_SELECT}, {"ENTERSUBMENU", ACTION_MENU_ENTER_SUBMENU}, {"LEAVESUBMENU", ACTION_MENU_LEAVE_SUBMENU}, {"CLOSE", ACTION_CLOSE}, {nullptr, ACTION_NO}}; static Util::StringTo harbour_placement_map[] = {{"TOP", TOP}, {"LEFT", LEFT}, {"RIGHT", RIGHT}, {"BOTTOM", BOTTOM}, {nullptr, NO_HARBOUR_PLACEMENT}}; static Util::StringTo harbour_orientation_map[] = {{"TOPTOBOTTOM", TOP_TO_BOTTOM}, {"LEFTTORIGHT", TOP_TO_BOTTOM}, {"BOTTOMTOTOP", BOTTOM_TO_TOP}, {"RIGHTTOLEFT", BOTTOM_TO_TOP}, {nullptr, NO_ORIENTATION}}; static Util::StringTo curr_head_selector_map[] = {{"CURSOR", CURR_HEAD_SELECTOR_CURSOR}, {"FOCUSEDWINDOW", CURR_HEAD_SELECTOR_FOCUSED_WINDOW}, {nullptr, CURR_HEAD_SELECTOR_NO}}; static Util::StringTo on_close_focus_raise_map[] = {{"NEVER", ON_CLOSE_FOCUS_RAISE_NEVER}, {"ALWAYS", ON_CLOSE_FOCUS_RAISE_ALWAYS}, {"IFCOVERED", ON_CLOSE_FOCUS_RAISE_IF_COVERED}, {nullptr, ON_CLOSE_FOCUS_RAISE_ALWAYS}}; static Util::StringTo warp_on_map[] = {{"FOCUSCHANGE", WARP_ON_FOCUS_CHANGE}, {"NEW", WARP_ON_NEW}, {nullptr, WARP_ON_NO}}; static Util::StringTo debug_level_map[] = {{"ERR", Debug::LEVEL_ERR}, {"WARN", Debug::LEVEL_WARN}, {"INFO", Debug::LEVEL_INFO}, {"DEBUG", Debug::LEVEL_DEBUG}, {"TRACE", Debug::LEVEL_TRACE}, {nullptr, Debug::LEVEL_WARN}}; /** * Parse width and height limits. */ bool SizeLimits::parse(const std::string &minimum, const std::string &maximum) { return (parseLimit(minimum, _limits[WIDTH_MIN], _limits[HEIGHT_MIN]) && parseLimit(maximum, _limits[WIDTH_MAX], _limits[HEIGHT_MAX])); } /** * Parse single limit. */ bool SizeLimits::parseLimit(const std::string &limit, uint &min, uint &max) { bool status = false; std::vector tokens; if ((Util::splitString(limit, tokens, "x", 2, true)) == 2) { min = strtol(tokens[0].c_str(), 0, 10); max = strtol(tokens[1].c_str(), 0, 10); status = true; } else { min = 0; max = 0; } return status; } Config::Config() : _debug_file("/dev/null"), _debug_level(Debug::LEVEL_WARN), _moveresize_edgeattract(0), _moveresize_edgeresist(0), _moveresize_woattract(0), _moveresize_woresist(0), _moveresize_opaquemove(0), _moveresize_opaqueresize(0), _screen_scale(1.0), _screen_scale_override(0.0), _screen_theme_background(true), _screen_workspaces(4), _screen_workspaces_back_and_forth(true), _screen_workspaces_per_row(0), _screen_edge_indent(false), _screen_doubleclicktime(250), _screen_fullscreen_above(true), _screen_fullscreen_detect(true), _screen_showframelist(true), _screen_show_status_window(true), _screen_show_status_window_on_root(false), _screen_show_client_id(false), _screen_show_workspace_indicator(500), _screen_workspace_indicator_scale(16), _screen_workspace_indicator_opacity(EWMH_OPAQUE_WINDOW), _screen_place_new(true), _screen_focus_new(false), _screen_focus_new_child(true), _screen_on_close_focus_stacking(false), _screen_on_close_focus_raise(ON_CLOSE_FOCUS_RAISE_ALWAYS), _screen_focus_steal_protect(0), _screen_honour_randr(true), _screen_honour_aspectratio(true), _screen_curr_head_selector(CURR_HEAD_SELECTOR_CURSOR), _screen_default_font_x11(false), _screen_placement_row(false), _screen_placement_ltr(true), _screen_placement_ttb(true), _screen_placement_offset_x(0), _screen_placement_offset_y(0), _screen_client_unique_name(true), _screen_client_unique_name_pre(" #"), _screen_client_unique_name_post(""), _screen_report_all_clients(false), _screen_warp_pointer_on(0), _menu_select_mask(0), _menu_enter_mask(0), _menu_exec_mask(0), _menu_display_icons(true), _menu_focus_opacity(EWMH_OPAQUE_WINDOW), _menu_unfocus_opacity(EWMH_OPAQUE_WINDOW), _cmd_dialog_history_unique(true), _cmd_dialog_history_size(1024), _cmd_dialog_history_save_interval(16), _harbour_da_min_s(0), _harbour_da_max_s(0), _harbour_ontop(true), _harbour_maximize_over(false), _harbour_placement(TOP), _harbour_orientation(TOP_TO_BOTTOM), _harbour_head_nr(0), _harbour_opacity(EWMH_OPAQUE_WINDOW), _sys_enabled(true) { for (uint i = 0; i <= SCREEN_EDGE_NO; ++i) { _screen_edge_sizes.push_back(0); } // fill the mouse action map for (uint i = 0; i <= MOUSE_ACTION_LIST_NO; i++) { MouseActionListName maln = static_cast(i); _mouse_action_map[maln] = new std::vector(); } } Config::~Config(void) { mouse_action_map::iterator it = _mouse_action_map.begin(); for (; it != _mouse_action_map.end(); ++it) { delete it->second; } } //! @brief Tries to load config_file, ~/.pekwm/config, SYSCONFDIR/config bool Config::load(const std::string &config_file) { if (! _cfg_files.requireReload(config_file)) { return false; } CfgParser cfg(CfgParserOpt("")); std::string cfg_dir; _config_file = config_file; bool success = tryHardLoadConfig(cfg, _config_file, cfg_dir); // Make sure config is reloaded next time as content is dynamically // generated from the configuration file. if (! success || cfg.isDynamicContent()) { _cfg_files.clear(); } else { _cfg_files = cfg.getCfgFiles(); } if (! success) { USER_WARN("unable to load configuration files"); return false; } // Update PEKWM_CONFIG_FILE environment if needed (to reflect active // file) std::string cfg_env = Util::getEnv("PEKWM_CONFIG_FILE"); if (cfg_env.size() == 0 || _config_file.compare(cfg_env) != 0) { initEnvConfig(cfg_dir, _config_file); } CfgParser::Entry *section; // Get other config files dests. section = cfg.getEntryRoot()->findSection("FILES"); if (section) { loadFiles(section); } // Parse moving / resizing options. section = cfg.getEntryRoot()->findSection("MOVERESIZE"); if (section) { loadMoveResize(section); } // Screen, important stuff such as number of workspaces section = cfg.getEntryRoot()->findSection("SCREEN"); if (section) { loadScreen(section); } // Load after Screen, as it overrides _screen_theme_background if a // custom background is set. section = cfg.getEntryRoot()->findSection("THEME"); if (section) { loadTheme(section); } section = cfg.getEntryRoot()->findSection("MENU"); if (section) { loadMenu(section); } section = cfg.getEntryRoot()->findSection("CMDDIALOG"); if (section) { loadCmdDialog(section); } section = cfg.getEntryRoot()->findSection("HARBOUR"); if (section) { loadHarbour(section); } section = cfg.getEntryRoot()->findSection("SYS"); if (section) { loadSys(section); } section = cfg.getEntryRoot()->findSection("DEBUG"); if (section) { loadDebug(section); } pekwm::hooks()->load(cfg.getEntryRoot()->findSection("HOOKS")); return true; } //! @brief Loads file section of configuration //! @param section Pointer to FILES section. void Config::loadFiles(CfgParser::Entry *section) { if (! section) { return; } CfgParserKeys keys; keys.add_path("KEYS", _files_keys, SYSCONFDIR "/keys"); keys.add_path("MOUSE", _files_mouse, SYSCONFDIR "/mouse"); keys.add_path("MENU", _files_menu, SYSCONFDIR "/menu"); keys.add_path("START", _files_start, SYSCONFDIR "/start"); keys.add_path("AUTOPROPS", _files_autoprops, SYSCONFDIR "/autoproperties"); keys.add_path("THEME", _files_theme, DATADIR "/pekwm/themes/default"); keys.add_string("THEMEVARIANT", _files_theme_variant); keys.add_path("ICONS", _files_icon_path, DATADIR "/pekwm/icons"); std::string config_script_path; keys.add_path("SCRIPTS", config_script_path, CfgUtil::getDefaultScriptsDir()); section->parseKeyValues(keys.begin(), keys.end()); pekwm::setConfigScriptPath(config_script_path); keys.clear(); } //! @brief Loads MOVERESIZE section of main configuration //! @param section Pointer to MOVERESIZE section. void Config::loadMoveResize(CfgParser::Entry *section) { if (! section) { return; } CfgParserKeys keys; keys.add_numeric("EDGEATTRACT", _moveresize_edgeattract, 0, 0); keys.add_numeric("EDGERESIST", _moveresize_edgeresist, 0, 0); keys.add_numeric("WINDOWATTRACT", _moveresize_woattract, 0, 0); keys.add_numeric("WINDOWRESIST", _moveresize_woresist, 0, 0); keys.add_bool("OPAQUEMOVE", _moveresize_opaquemove); keys.add_bool("OPAQUERESIZE", _moveresize_opaqueresize); section->parseKeyValues(keys.begin(), keys.end()); keys.clear(); } /** * Loads SCREEN section of main configuration. */ bool Config::loadScreen(CfgParser::Entry *section) { if (! section) { return false; } // Parse data std::string edge_size, workspace_names, trim_title, curr_head_selector; CfgParserKeys keys; keys.add_numeric("SCALE", _screen_scale, 1.0); keys.add_bool("THEMEBACKGROUND", _screen_theme_background, true); keys.add_numeric("WORKSPACES", _screen_workspaces, 4, 1); keys.add_numeric("WORKSPACESPERROW", _screen_workspaces_per_row, 0, 0); keys.add_bool("WORKSPACESBACKANDFORTH", _screen_workspaces_back_and_forth, true); keys.add_string("WORKSPACENAMES", workspace_names); keys.add_string("EDGESIZE", edge_size); keys.add_bool("EDGEINDENT", _screen_edge_indent); keys.add_numeric("DOUBLECLICKTIME", _screen_doubleclicktime, 250, 0); keys.add_string("TRIMTITLE", trim_title); keys.add_bool("FULLSCREENABOVE", _screen_fullscreen_above, true); keys.add_bool("FULLSCREENDETECT", _screen_fullscreen_detect, true); keys.add_bool("SHOWFRAMELIST", _screen_showframelist); keys.add_bool("SHOWSTATUSWINDOW", _screen_show_status_window); keys.add_bool("SHOWSTATUSWINDOWCENTEREDONROOT", _screen_show_status_window_on_root, false); keys.add_bool("SHOWCLIENTID", _screen_show_client_id); keys.add_numeric("SHOWWORKSPACEINDICATOR", _screen_show_workspace_indicator, 500, 0); keys.add_numeric("WORKSPACEINDICATORSCALE", _screen_workspace_indicator_scale, 16, 2); keys.add_numeric("WORKSPACEINDICATOROPACITY", _screen_workspace_indicator_opacity, 100, 0, 100); keys.add_bool("PLACENEW", _screen_place_new); keys.add_bool("FOCUSNEW", _screen_focus_new); keys.add_bool("FOCUSNEWCHILD", _screen_focus_new_child, true); keys.add_bool("ONCLOSEFOCUSSTACKING", _screen_on_close_focus_stacking, false); std::string on_close_focus_raise; keys.add_string("ONCLOSEFOCUSRAISE", on_close_focus_raise, "ALWAYS"); keys.add_numeric("FOCUSSTEALPROTECT", _screen_focus_steal_protect, 0); keys.add_bool("HONOURRANDR", _screen_honour_randr, true); keys.add_bool("HONOURASPECTRATIO", _screen_honour_aspectratio, true); keys.add_string("CURRHEADSELECTOR", curr_head_selector, "CURSOR"); keys.add_bool("FONTDEFAULTX11", _screen_default_font_x11, false); keys.add_string("FONTCHARSETOVERRIDE", _screen_font_charset_override); keys.add_bool("REPORTALLCLIENTS", _screen_report_all_clients, false); std::string warp_pointer_on; keys.add_string("WARPPOINTERON", warp_pointer_on, ""); section->parseKeyValues(keys.begin(), keys.end()); keys.clear(); PFont::setTrimString(trim_title); // Convert opacity from percent to absolute value CONV_OPACITY(_screen_workspace_indicator_opacity); int edge_size_all = 0; _screen_edge_sizes.clear(); if (edge_size.size()) { std::vector sizes; if (Util::splitString(edge_size, sizes, " \t", 4) == 4) { std::vector::iterator it = sizes.begin(); for (; it != sizes.end(); ++it) { _screen_edge_sizes.push_back(std::stoi(*it)); } } else { edge_size_all = strtol(edge_size.c_str(), 0, 10); } } for (uint i = 0; i < SCREEN_EDGE_NO; ++i) { _screen_edge_sizes.push_back(edge_size_all); } // Add SCREEN_EDGE_NO to the list for safety _screen_edge_sizes.push_back(0); // Workspace names _screen_workspace_names.clear(); std::vector vs; if (Util::splitString(workspace_names, vs, ";", 0, true)) { std::vector::iterator vs_it = vs.begin(); for (; vs_it != vs.end(); ++vs_it) { _screen_workspace_names.push_back(*vs_it); } } _screen_curr_head_selector = Util::StringToGet(curr_head_selector_map, curr_head_selector); _screen_on_close_focus_raise = Util::StringToGet(on_close_focus_raise_map, on_close_focus_raise); _screen_warp_pointer_on = 0; vs.clear(); if (Util::splitString(warp_pointer_on, vs, " \t", 0)) { std::vector::iterator vs_it = vs.begin(); for (; vs_it != vs.end(); ++vs_it) { _screen_warp_pointer_on |= Util::StringToGet(warp_on_map, *vs_it); } } CfgParser::Entry *sub = section->findSection("PLACEMENT"); loadScreenPlacement(sub); sub = section->findSection("UNIQUENAMES"); if (sub) { keys.add_bool("SETUNIQUE", _screen_client_unique_name); keys.add_string("PRE", _screen_client_unique_name_pre); keys.add_string("POST", _screen_client_unique_name_post); sub->parseKeyValues(keys.begin(), keys.end()); keys.clear(); } return true; } /** * Load Placement sub section of the Screen section. */ void Config::loadScreenPlacement(CfgParser::Entry *section) { if (section == nullptr) { return; } CfgParser::Entry *value = section->findEntry("MODEL"); if (value) { std::vector tok; Util::splitString(value->getValue(), tok, " \t"); Workspaces::setLayoutModels(tok); } CfgParser::Entry *sub = section->findSection("SMART"); if (sub) { CfgParserKeys keys; keys.add_bool("ROW", _screen_placement_row); keys.add_bool("LEFTTORIGHT", _screen_placement_ltr); keys.add_bool("TOPTOBOTTOM", _screen_placement_ttb); keys.add_numeric("OFFSETX", _screen_placement_offset_x, 0, 0); keys.add_numeric("OFFSETY", _screen_placement_offset_y, 0, 0); sub->parseKeyValues(keys.begin(), keys.end()); keys.clear(); } } //! @brief Loads the MENU section of the main configuration //! @param section Pointer to MENU section void Config::loadMenu(CfgParser::Entry *section) { if (! section) { return; } CfgParserKeys keys; std::string value_select, value_enter, value_exec; keys.add_string("SELECT", value_select, "MOTION", 0); keys.add_string("ENTER", value_enter, "BUTTONPRESS", 0); keys.add_string("EXEC", value_exec, "BUTTONRELEASE", 0); keys.add_bool("DISPLAYICONS", _menu_display_icons, true); keys.add_numeric("FOCUSOPACITY", _menu_focus_opacity, 100, 0, 100); keys.add_numeric("UNFOCUSOPACITY", _menu_unfocus_opacity, 100, 0, 100); section->parseKeyValues(keys.begin(), keys.end()); keys.clear(); _menu_select_mask = getMenuMask(value_select); _menu_enter_mask = getMenuMask(value_enter); _menu_exec_mask = getMenuMask(value_exec); // Parse icon size limits CfgParser::Entry::entry_cit it(section->begin()); for (; it != section->end(); ++it) { if (*(*it) == "ICONS") { loadMenuIcons((*it)->getSection()); } } // Convert opacity from percent to absolute value CONV_OPACITY(_menu_focus_opacity); CONV_OPACITY(_menu_unfocus_opacity); } /** * Load Icon size limits for menu. */ void Config::loadMenuIcons(CfgParser::Entry *section) { if (! section || ! section->getValue().size()) { return; } CfgParserKeys keys; std::string minimum, maximum; keys.add_string("MINIMUM", minimum, "16x16", 3); keys.add_string("MAXIMUM", maximum, "16x16", 3); section->parseKeyValues(keys.begin(), keys.end()); keys.clear(); SizeLimits limits; if (limits.parse(minimum, maximum)) { _menu_icon_limits[section->getValue()] = limits; } } /** * Load configuration from CmdDialog section. */ void Config::loadCmdDialog(CfgParser::Entry *section) { if (! section) { return; } CfgParserKeys keys; keys.add_bool("HISTORYUNIQUE", _cmd_dialog_history_unique); keys.add_numeric("HISTORYSIZE", _cmd_dialog_history_size, 1024, 1); keys.add_path("HISTORYFILE", _cmd_dialog_history_file, Util::getConfigDir() + "/history"); keys.add_numeric("HISTORYSAVEINTERVAL", _cmd_dialog_history_save_interval, 16, 0); section->parseKeyValues(keys.begin(), keys.end()); keys.clear(); } //! @brief Loads the HARBOUR section of the main configuration void Config::loadHarbour(CfgParser::Entry *section) { if (! section) { return; } CfgParserKeys keys; std::string value_placement, value_orientation; keys.add_bool("ONTOP", _harbour_ontop, true); keys.add_bool("MAXIMIZEOVER", _harbour_maximize_over, false); keys.add_numeric("HEAD", _harbour_head_nr, 0, 0); keys.add_string("HEADNAME", _harbour_head, "", 0); keys.add_string("PLACEMENT", value_placement, "RIGHT", 0); keys.add_string("ORIENTATION", value_orientation, "TOPTOBOTTOM", 0); keys.add_numeric("OPACITY", _harbour_opacity, 100, 0, 100); keys.add_numeric("OPACITY", _harbour_opacity, 100, 0, 100); section->parseKeyValues(keys.begin(), keys.end()); keys.clear(); // Convert opacity from percent to absolute value CONV_OPACITY(_harbour_opacity); _harbour_placement = Util::StringToGet(harbour_placement_map, value_placement); _harbour_orientation = Util::StringToGet(harbour_orientation_map, value_orientation); if (_harbour_placement == NO_HARBOUR_PLACEMENT) { _harbour_placement = RIGHT; } if (_harbour_orientation == NO_ORIENTATION) { _harbour_orientation = TOP_TO_BOTTOM; } CfgParser::Entry *sub = section->findSection("DOCKAPP"); if (sub) { keys.add_numeric("SIDEMIN", _harbour_da_min_s, 64, 0); keys.add_numeric("SIDEMAX", _harbour_da_max_s, 64, 0); sub->parseKeyValues(keys.begin(), keys.end()); keys.clear(); } } bool Config::loadSys(CfgParser::Entry *section) { if (! section) { return false; } CfgParserKeys keys; keys.add_bool("ENABLE", _sys_enabled, true); section->parseKeyValues(keys.begin(), keys.end()); return true; } /** * Load the Debug section of pekwm configuration. */ bool Config::loadDebug(CfgParser::Entry *section) { if (! section) { return false; } CfgParserKeys keys; std::string debug_level_str; keys.add_path("FILE", _debug_file, "/dev/null"); keys.add_string("LEVEL", debug_level_str); section->parseKeyValues(keys.begin(), keys.end()); _debug_level = Util::StringToGet(debug_level_map, debug_level_str); Debug::setLevel(_debug_level); Debug::setLogFile(_debug_file); return true; } /** * Load the Theme section of pekwm configuration, overrides and other styling * options. */ bool Config::loadTheme(CfgParser::Entry *section) { if (! section) { return false; } CfgParserKeys keys; keys.add_string("BACKGROUNDOVERRIDE", _theme_background_override); section->parseKeyValues(keys.begin(), keys.end()); if (! _theme_background_override.empty()) { // ensure background is set when using override _screen_theme_background = true; } return true; } ActionAccessMask Config::getActionAccessMask(const std::string &name) { return Util::StringToGet(action_access_mask_map, name); } bool Config::parseActionAccessMask(const std::string &action_mask, uint &mask) { mask = ACTION_ACCESS_NO; std::vector tok; if (Util::splitString(action_mask, tok, " \t")) { std::vector::iterator it = tok.begin(); for (; it != tok.end(); ++it) { mask |= getActionAccessMask(*it); } } return true; } bool Config::parseMoveResizeAction(const std::string &action_string, Action &action) { std::vector tok; // Chop the string up separating the actions. if (! Util::splitString(action_string, tok, " \t", 2)) { return false; } action.setAction(Util::StringToGet(moveresize_map, tok[0])); if (action.getAction() == NO_MOVERESIZE_ACTION) { USER_WARN("Unknown move/resize action: " << tok[0]); return false; } if (tok.size() == 2) { // Got enough tok for a paremeter switch (action.getAction()) { case MOVE_HORIZONTAL: case MOVE_VERTICAL: case RESIZE_HORIZONTAL: case RESIZE_VERTICAL: { char *endptr = nullptr; action.setParamI(0, strtol(tok[1].c_str(), &endptr, 10)); if (endptr && *endptr == '%') { action.setParamI(1, UNIT_PERCENT); } else { action.setParamI(1, UNIT_PIXEL); } break; } case MOVE_SNAP: default: // Do nothing. break; } } return true; } bool Config::parseMoveResizeActions(const std::string &action_string, ActionEvent& ae) { std::vector tok; std::vector::iterator it; Action action; // reset the action event ae.action_list.clear(); // chop the string up separating the actions if (Util::splitString(action_string, tok, ";")) { for (it = tok.begin(); it != tok.end(); ++it) { if (parseMoveResizeAction(*it, action)) { ae.action_list.push_back(action); action.clear(); } } return true; } return false; } //! @brief Parses MoveResize Event. bool Config::parseMoveResizeEvent(CfgParser::Entry *section, ActionEvent& ae) { if (! section->getValue().size ()) { return false; } if (ActionConfig::parseKey(section->getValue(), ae.mod, ae.sym)) { CfgParser::Entry *value = section->getSection()->findEntry("ACTIONS"); if (value) { return parseMoveResizeActions(value->getValue(), ae); } } return false; } bool Config::parseInputDialogAction(const std::string &val, Action &action) { action.setAction(Util::StringToGet(inputdialog_map, val)); return (action.getAction() != INPUT_NO_ACTION); } bool Config::parseInputDialogActions(const std::string &actions, ActionEvent &ae) { std::vector tok; std::vector::iterator it; Action action; std::string::size_type first, last; // reset the action event ae.action_list.clear(); // chop the string up separating the actions if (Util::splitString(actions, tok, ";")) { for (it = tok.begin(); it != tok.end(); ++it) { first = (*it).find_first_not_of(" \t\n"); if (first == std::string::npos) continue; last = (*it).find_last_not_of(" \t\n"); (*it) = (*it).substr(first, last-first+1); if (parseInputDialogAction(*it, action)) { ae.action_list.push_back(action); action.clear(); } } return true; } return false; } //! @brief Parses InputDialog Event. bool Config::parseInputDialogEvent(CfgParser::Entry *section, ActionEvent &ae) { if (! section->getValue().size()) { return false; } if (ActionConfig::parseKey(section->getValue(), ae.mod, ae.sym)) { CfgParser::Entry *value = section->getSection()->findEntry("ACTIONS"); if (value) { return parseInputDialogActions(value->getValue(), ae); } } return false; } /** * Get mask for handling menu events. */ uint Config::getMenuMask(const std::string &mask) { uint mask_return = 0; std::vector tok; Util::splitString(mask, tok, " \t"); std::vector::iterator it = tok.begin(); for (; it != tok.end(); ++it) { uint val = Util::StringToGet(mouse_event_map, *it); if (val != MOUSE_EVENT_NO) { mask_return |= val; } } return mask_return; } unsigned int Config::getMenuIconLimit(unsigned int value, SizeLimitType limit, const std::string &name) const { unsigned int limit_val = 0; std::map::const_iterator it = _menu_icon_limits.find(name); if (it == _menu_icon_limits.end()) { if (name == "DEFAULT") { limit_val = 16; } else { limit_val = getMenuIconLimit(value, limit, "DEFAULT"); } } else { limit_val = it->second.get(limit); } return limit_val ? limit_val : value; } bool Config::parseMenuAction(const std::string &action_string, Action &action) { std::vector tok; // chop the string up separating the actions if (Util::splitString(action_string, tok, " \t", 2)) { action.setAction(Util::StringToGet(menu_action_map, tok[0])); if (action.getAction() == ACTION_MENU_GOTO) { int idx = stoi_safe(tok[1], -1); if (idx > 0) { action.setParamI(0, idx - 1); } else { action.setAction(ACTION_NO); } } } return action.getAction() != ACTION_NO; } bool Config::parseMenuActions(const std::string &actions, ActionEvent &ae) { std::vector tok; std::vector::iterator it; Action action; // reset the action event ae.action_list.clear(); // chop the string up separating the actions if (Util::splitString(actions, tok, ";", 0, false, '\\')) { for (it = tok.begin(); it != tok.end(); ++it) { if (parseMenuAction(*it, action)) { ae.action_list.push_back(action); action.clear(); } } return true; } return false; } //! @brief Parses MenuEvent. bool Config::parseMenuEvent(CfgParser::Entry *section, ActionEvent& ae) { if (! section->getValue().size()) { return false; } if (ActionConfig::parseKey(section->getValue(), ae.mod, ae.sym)) { CfgParser::Entry *value = section->getSection()->findEntry("ACTIONS"); if (value) { return parseMenuActions(value->getValue(), ae); } } return false; } /** * Load main configuration file, priority as follows: * * 1. Load command line specified file or ~/.pekwm/config if none specified * 2. Copy configuration files to dirname of file in step 1 * 3. Load system configuration */ bool Config::tryHardLoadConfig(CfgParser &cfg, std::string &file, std::string &cfg_dir) { bool success = false; // If a command line if (file.size()) { cfg_dir = Util::getDir(file); } else { cfg_dir = Util::getConfigDir(); file = cfg_dir + "/config"; } success = cfg.parse(file, CfgParserSource::SOURCE_FILE, true); // Copy config files to cfg_dir and try loading file again. if (! success) { copyConfigFiles(cfg_dir); success = cfg.parse(file, CfgParserSource::SOURCE_FILE, true); } // Failed to load file, fall back to using system config files if (! success) { file = std::string(SYSCONFDIR "/config"); success = cfg.parse(file, CfgParserSource::SOURCE_FILE, true); } return success; } /** * Populate cfg_dir with config files from system directory. */ void Config::copyConfigFiles(const std::string &cfg_dir) { const char *files[] = { "autoproperties", "config", "keys", "menu", "mouse", "start", "vars", nullptr }; if (! ensureConfigDirExists(cfg_dir)) { return; } struct stat sb; std::string sys_dir(SYSCONFDIR); for (int i = 0; files[i] != nullptr; i++) { std::string dst_file = cfg_dir + "/" + files[i]; if (stat(dst_file.c_str(), &sb)) { std::string src_file = sys_dir + "/" + files[i]; std::cout << "COPY " << src_file << " TO " << dst_file << std::endl; Util::copyTextFile(src_file, dst_file); } } // ensure themes directory exists std::string themes_dir = cfg_dir + std::string("/themes"); if (stat(themes_dir.c_str(), &sb)) { mkdir(themes_dir.c_str(), 0700); } } /** * Ensure that the provided configuration directory exists and is writable. */ bool Config::ensureConfigDirExists(const std::string &cfg_dir) { // Ensure that cfg_dir exists and is a directory struct stat sb; if (stat(cfg_dir.c_str(), &sb)) { if (mkdir(cfg_dir.c_str(), 0700)) { USER_WARN("unable to create the config directory " << cfg_dir << ". can not copy config files"); return false; } stat(cfg_dir.c_str(), &sb); } else if (! S_ISDIR(sb.st_mode)) { USER_WARN(cfg_dir << " already exists and is not a directory." << " can not copy config files"); return false; } // Ensure that the config directory has write end execute bits set. bool cfg_dir_ok = false; if (getuid() == sb.st_uid) { if ((sb.st_mode&(S_IWUSR|S_IXUSR)) == (S_IWUSR|S_IXUSR)) { cfg_dir_ok = true; } } if (! cfg_dir_ok && getgid() == sb.st_gid) { if ((sb.st_mode&(S_IWGRP|S_IXGRP)) == (S_IWGRP|S_IXGRP)) { cfg_dir_ok = true; } } if (! cfg_dir_ok) { if ((sb.st_mode&(S_IWOTH|S_IXOTH)) == (S_IWOTH|S_IXOTH)) { cfg_dir_ok = true; } else { USER_WARN("no write on " << cfg_dir << " directory." << " can not copy config files"); return false; } } return cfg_dir_ok; } /** * Parses mouse configuration file. */ bool Config::loadMouseConfig(const std::string &mouse_file) { if (! _cfg_files_mouse.requireReload(mouse_file)) { return false; } CfgParser mouse_cfg(pekwm::configScriptPath()); if (! mouse_cfg.parse(mouse_file, CfgParserSource::SOURCE_FILE, true) && ! mouse_cfg.parse(SYSCONFDIR "/mouse", CfgParserSource::SOURCE_FILE, true)) { _cfg_files_mouse.clear(); return false; } if (mouse_cfg.isDynamicContent()) { _cfg_files_mouse.clear(); } else { _cfg_files_mouse = mouse_cfg.getCfgFiles(); } // Make sure old actions get unloaded. mouse_action_map::iterator it = _mouse_action_map.begin(); for (; it != _mouse_action_map.end(); ++it) { it->second->clear(); } CfgParser::Entry *section; section = mouse_cfg.getEntryRoot()->findSection("FRAMETITLE"); if (section) { parseButtons(section, _mouse_action_map[MOUSE_ACTION_LIST_TITLE_FRAME], nullptr, FRAME_OK); } section = mouse_cfg.getEntryRoot()->findSection("OTHERTITLE"); if (section) { parseButtons(section, _mouse_action_map[MOUSE_ACTION_LIST_TITLE_OTHER], nullptr, FRAME_OK); } section = mouse_cfg.getEntryRoot()->findSection("CLIENT"); if (section) { parseButtons(section, _mouse_action_map[MOUSE_ACTION_LIST_CHILD_FRAME], &_client_mouse_action_buttons, CLIENT_OK); } section = mouse_cfg.getEntryRoot()->findSection("ROOT"); if (section) { parseButtons(section, _mouse_action_map[MOUSE_ACTION_LIST_ROOT], nullptr, ROOTCLICK_OK); } section = mouse_cfg.getEntryRoot()->findSection("MENU"); if (section) { parseButtons(section, _mouse_action_map[MOUSE_ACTION_LIST_MENU], nullptr, FRAME_OK); } section = mouse_cfg.getEntryRoot()->findSection("OTHER"); if (section) { parseButtons(section, _mouse_action_map[MOUSE_ACTION_LIST_OTHER], nullptr, FRAME_OK); } section = mouse_cfg.getEntryRoot()->findSection("SCREENEDGE"); if (section) { CfgParser::Entry::entry_cit edge_it(section->begin()); for (; edge_it != section->end(); ++edge_it) { uint pos = ActionConfig::getDirection( (*edge_it)->getName()); if (pos != SCREEN_EDGE_NO) { parseButtons((*edge_it)->getSection(), getEdgeListFromPosition(pos), nullptr, SCREEN_EDGE_OK); } } } section = mouse_cfg.getEntryRoot()->findSection("BORDER"); if (section) { CfgParser::Entry::entry_cit border_it(section->begin()); for (; border_it != section->end(); ++border_it) { uint pos = ActionConfig::getBorderPos( (*border_it)->getName()); if (pos != BORDER_NO_POS) { parseButtons((*border_it)->getSection(), getBorderListFromPosition(pos), nullptr, FRAME_BORDER_OK); } } } return true; } static void mouseButtonsAdd(std::vector* buttons, uint button, uint mod) { if (buttons == nullptr) { return; } std::vector::iterator bit = buttons->begin(); for (; bit != buttons->end(); ++bit) { if (bit->button == button) { std::vector::iterator mit = bit->mods.begin(); for (; mit != bit->mods.end(); ++mit) { if (*mit == mod) { return; } } bit->mods.push_back(mod); return; } } buttons->push_back(BoundButton(button, mod)); } /** * Parses mouse config section, like FRAME */ void Config::parseButtons(CfgParser::Entry *section, std::vector* mouse_list, std::vector* mouse_buttons, ActionOk action_ok) { if (! section || ! mouse_list) { return; } ActionEvent ae; CfgParser::Entry *value; CfgParser::Entry::entry_cit it(section->begin()); for (; it != section->end(); ++it) { if (! (*it)->getSection()) { continue; } ae.type = Util::StringToGet(mouse_event_map, (*it)->getName()); if (ae.type == MOUSE_EVENT_NO) { continue; } if (ae.type == MOUSE_EVENT_MOTION) { value = (*it)->getSection()->findEntry("THRESHOLD"); if (value) { ae.threshold = std::stoi(value->getValue()); } else { ae.threshold = 0; } } if (ActionConfig::parseActionEvent((*it), ae, action_ok, true)) { mouse_list->push_back(ae); mouseButtonsAdd(mouse_buttons, ae.sym, ae.mod); } } } // frame border configuration std::vector* Config::getBorderListFromPosition(uint pos) { std::vector *ret = 0; switch (pos) { case BORDER_TOP_LEFT: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_TL]; break; case BORDER_TOP: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_T]; break; case BORDER_TOP_RIGHT: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_TR]; break; case BORDER_LEFT: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_L]; break; case BORDER_RIGHT: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_R]; break; case BORDER_BOTTOM_LEFT: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_BL]; break; case BORDER_BOTTOM: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_B]; break; case BORDER_BOTTOM_RIGHT: ret = _mouse_action_map[MOUSE_ACTION_LIST_BORDER_BR]; break; } return ret; } std::vector* Config::getEdgeListFromPosition(uint pos) { std::vector *ret = 0; switch (pos) { case SCREEN_EDGE_TOP: ret = _mouse_action_map[MOUSE_ACTION_LIST_EDGE_T]; break; case SCREEN_EDGE_BOTTOM: ret = _mouse_action_map[MOUSE_ACTION_LIST_EDGE_B]; break; case SCREEN_EDGE_LEFT: ret = _mouse_action_map[MOUSE_ACTION_LIST_EDGE_L]; break; case SCREEN_EDGE_RIGHT: ret = _mouse_action_map[MOUSE_ACTION_LIST_EDGE_R]; break; }; return ret; } /** * Parses a string which contains two opacity values */ bool Config::parseOpacity(const std::string& value, uint &focused, uint &unfocused) { std::vector tokens; switch ((Util::splitString(value, tokens, " ,", 2))) { case 2: focused = std::atoi(tokens[0].c_str()); unfocused = std::atoi(tokens[1].c_str()); break; case 1: focused = unfocused = std::atoi(tokens[0].c_str()); break; default: return false; } CONV_OPACITY(focused); CONV_OPACITY(unfocused); return true; } int Config::getHarbourHead(void) const { if (_harbour_head.empty()) { return _harbour_head_nr; } int head = X11::findHeadByName(_harbour_head); if (head == -1) { // fallback to primary head, which should always be valid head = X11::findHeadByName("PRIMARY"); } return head; } pekwm-0.4.4/src/wm/PWinObjReference.hh0000664000175000017500000000275515126136025013221 // // PWinObjReference.hh for pekwm // Copyright (C) 2009-2023 Claes Nästen // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PWINOBJREFERENCE_HH_ #define _PEKWM_PWINOBJREFERENCE_HH_ #include "config.h" #include "Observable.hh" #include "tk/PWinObj.hh" /** * Observer with a reference to a PWinObj. */ class PWinObjReference : public Observer { public: PWinObjReference(PWinObj *wo_ref=nullptr) : _wo_ref(wo_ref) { updateObserver(nullptr, wo_ref); } virtual ~PWinObjReference(void) { updateObserver(_wo_ref, nullptr); } /** Notify about reference update, unset the reference. */ virtual void notify(Observable *observable, Observation *observation) { if (observation == &PWinObj::pwin_obj_deleted && observable == _wo_ref) { _wo_ref = nullptr; } } /** Returns the PWinObj reference. */ PWinObj *getWORef(void) const { return _wo_ref; } /** Sets the PWinObj reference and add this as an observer. */ virtual void setWORef(PWinObj *wo_ref) { if (_wo_ref != wo_ref) { updateObserver(_wo_ref, wo_ref); _wo_ref = wo_ref; } } void updateObserver(PWinObj* old_ref, PWinObj* new_ref) { ObserverMapping* om = pekwm::observerMapping(); if (old_ref != nullptr) { om->removeObserver(old_ref, this); } if (new_ref != nullptr) { om->addObserver(new_ref, this, 100); } } private: /** Window object reference. */ PWinObj *_wo_ref; }; #endif // _PEKWM_PWINOBJREFERENCE_HH_ pekwm-0.4.4/src/wm/DockApp.cc0000664000175000017500000001550415126136025011375 // // DockApp.cc for pekwm // Copyright (C) 2021-2022 Claes Nästén // Copyright (C) 2003-2020 the pekwm development team // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include "DockApp.hh" #include "Charset.hh" #include "Config.hh" #include "X11.hh" #include "PDecor.hh" #include "AutoProperties.hh" #include "tk/PTexture.hh" #include "tk/PWinObj.hh" #include "tk/Theme.hh" extern "C" { #include } const uint DOCKAPP_DEFAULT_SIDE = 64; const uint DOCKAPP_BORDER_WIDTH = 2; //! @brief DockApp constructor DockApp::DockApp(Window win) : PWinObj(false), _dockapp_window(win), _client_window(win), _icon_window(None), _position(0), _background(None), _is_alive(true) { Config *cfg = pekwm::config(); // PWinObj attributes. _type = WO_DOCKAPP; _iconified = true; // We set ourself iconified for workspace switching. _sticky = true; // First, we need to figure out which window that actually belongs to // the dockapp. This we do by checking if it has the IconWindowHint // set in it's WM Hint. XWMHints wm_hints; if (X11::getWMHints(_dockapp_window, wm_hints) && (wm_hints.flags&IconWindowHint) && (wm_hints.icon_window != None)) { // hide the _client_window window, as it will not be used X11::unmapWindow(_client_window); _icon_window = wm_hints.icon_window; _dockapp_window = wm_hints.icon_window; } // Setup size after detected the window to use XWindowAttributes attr; if (X11::getWindowAttributes(_dockapp_window, attr)) { _c_gm.width = attr.width; _c_gm.height = attr.height; _gm.width = attr.width; _gm.height = attr.height; } else { if (cfg->getHarbourDAMinSide() > 0) { _c_gm.width = cfg->getHarbourDAMinSide(); _c_gm.height = cfg->getHarbourDAMinSide(); } else { _c_gm.width = DOCKAPP_DEFAULT_SIDE - DOCKAPP_BORDER_WIDTH * 2; _c_gm.height = DOCKAPP_DEFAULT_SIDE - DOCKAPP_BORDER_WIDTH * 2; } _gm.width = _c_gm.width; _gm.height = _c_gm.height; } // make sure size is valid and position the dockapp updateSize(); // create parent window which is going to hold the border _window = X11::createWmWindow(X11::getRoot(), _gm.x, _gm.y, _gm.width, _gm.height, InputOutput, SubstructureRedirectMask|ButtonPressMask| ButtonMotionMask); // initial makeup repaint(); XSetWindowBorderWidth(X11::getDpy(), _dockapp_window, 0); // move the dockapp to it's new parent, making sure we don't // get any UnmapEvents X11::selectInput(_dockapp_window, NoEventMask); XReparentWindow(X11::getDpy(), _dockapp_window, _window, _c_gm.x, _c_gm.y); X11::selectInput(_dockapp_window, SubstructureNotifyMask); readClassHint(); readAutoProperties(); } //! @brief DockApp destructor DockApp::~DockApp(void) { // if the client still is alive, we should reparent it to the root // window, else we don't have to care about that. if (_is_alive) { X11::grabServer(); if (_icon_window != None) { X11::unmapWindow(_icon_window); } // move the dockapp back to the root window, making sure we // don't get any UnmapEvents X11::selectInput(_dockapp_window, NoEventMask); XReparentWindow(X11::getDpy(), _dockapp_window, X11::getRoot(), _gm.x, _gm.y); X11::mapWindow(_client_window); X11::ungrabServer(false); } X11::freePixmap(_background); X11::destroyWindow(_window); } // START - PWinObj interface. //! @brief Maps the DockApp void DockApp::mapWindow(void) { if (_mapped) { return; } _mapped = true; X11::selectInput(_dockapp_window, NoEventMask); X11::mapWindow(_window); X11::mapWindow(_dockapp_window); X11::selectInput(_dockapp_window, StructureNotifyMask|SubstructureNotifyMask); } //! @brief Unmaps the DockApp void DockApp::unmapWindow(void) { if (! _mapped) { return; } _mapped = false; X11::selectInput(_dockapp_window, NoEventMask); X11::unmapWindow(_dockapp_window); X11::unmapWindow(_window); X11::selectInput(_dockapp_window, StructureNotifyMask|SubstructureNotifyMask); } // END - PWinObj interface. //! @brief Kills the DockApp void DockApp::kill(void) { XKillClient(X11::getDpy(), _dockapp_window); } //! @brief Resizes the DockApp, size excludes the border. //! @todo Make sure it's inside the screen! void DockApp::resize(uint width, uint height) { if ((_c_gm.width == width) && (_c_gm.height == height)) { return; } _c_gm.width = width; _c_gm.height = height; updateSize(); X11::moveResizeWindow(_window, _gm.x, _gm.y, _gm.width, _gm.height); X11::moveResizeWindow(_dockapp_window, _c_gm.x, _c_gm.y, _c_gm.width, _c_gm.height); repaint(); } //! @brief Loads the current theme and repaints the DockApp. void DockApp::loadTheme(void) { // Note, here we are going to check if the DockApp borderwidth have // changed etc in the future but for now we'll only have to repaint it repaint(); } //! @brief Repaints the DockApp's background. void DockApp::repaint(void) { X11::freePixmap(_background); _background = X11::createPixmap(_gm.width, _gm.height); Theme::HarbourData *hd = pekwm::theme()->getHarbourData(); hd->getTexture()->render(_background, 0, 0, _gm.width, _gm.height); X11::setWindowBackgroundPixmap(_window, _background); X11::clearWindow(_window); } //! @brief Validates geometry and centers the window void DockApp::updateSize(void) { // resize the window holding the dockapp _gm.width = _c_gm.width + DOCKAPP_BORDER_WIDTH * 2; _gm.height = _c_gm.height + DOCKAPP_BORDER_WIDTH * 2; // resize validateSize(); // position the dockapp _c_gm.x = (_gm.width - _c_gm.width) / 2; _c_gm.y = (_gm.height - _c_gm.height) / 2; } //! @brief Makes sure DockApp conforms to SideMin and SideMax void DockApp::validateSize(void) { Config *cfg = pekwm::config(); // convenience if (cfg->getHarbourDAMinSide() > 0) { if (_gm.width < static_cast(cfg->getHarbourDAMinSide())) { _gm.width = cfg->getHarbourDAMinSide(); } if (_gm.height < static_cast(cfg->getHarbourDAMinSide())) { _gm.height = cfg->getHarbourDAMinSide(); } } if (cfg->getHarbourDAMaxSide() > 0) { if (_gm.width > static_cast(cfg->getHarbourDAMaxSide())) { _gm.width = cfg->getHarbourDAMaxSide(); } if (_gm.height > static_cast(cfg->getHarbourDAMaxSide())) { _gm.height = cfg->getHarbourDAMaxSide(); } } } //! @brief Reads XClassHint of client. void DockApp::readClassHint(void) { XClassHint x_class_hint; if (XGetClassHint(X11::getDpy(), _client_window, &x_class_hint)) { _class_hint.h_name = x_class_hint.res_name; _class_hint.h_class = x_class_hint.res_class; X11::free(x_class_hint.res_name); X11::free(x_class_hint.res_class); } } //! @brief Reads DockApp AutoProperties. void DockApp::readAutoProperties(void) { DockAppProperty *prop = pekwm::autoProperties()->findDockAppProperty(_class_hint); if (prop) { _position = prop->getPosition(); } } pekwm-0.4.4/src/wm/Globals.cc0000664000175000017500000001165115126136025011436 // // Globals.cc for pekwm // Copyright (C) 2021-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "pekwm.hh" #include "ActionHandler.hh" #include "AutoProperties.hh" #include "Config.hh" #include "Harbour.hh" #include "ManagerWindows.hh" #include "KeyGrabber.hh" #include "StatusWindow.hh" #include "Timeouts.hh" #include "tk/FontHandler.hh" #include "tk/Hooks.hh" #include "tk/ImageHandler.hh" #include "tk/TextureHandler.hh" #include "tk/Theme.hh" static bool s_is_starting = true; static ObserverMapping* _observer_mapping = nullptr; static ActionHandler* _action_handler = nullptr; static AutoProperties* _auto_properties = nullptr; static Config* _config = nullptr; static std::string _config_script_path; static FontHandler* _font_handler = nullptr; static Harbour* _harbour = nullptr; static HintWO* _hint_wo = nullptr; static Hooks* _hooks = nullptr; static ImageHandler* _image_handler = nullptr; static KeyGrabber* _key_grabber = nullptr; static RootWO* _root_wo = nullptr; static StatusWindow* _status_window = nullptr; static TextureHandler* _texture_handler = nullptr; static Theme* _theme = nullptr; static Timeouts _timeouts; namespace pekwm { void initNoDisplay(void) { _observer_mapping = new ObserverMapping(); _config = new Config(); } void cleanupNoDisplay(void) { delete _observer_mapping; delete _config; _config = nullptr; } bool init(AppCtrl* app_ctrl, EventLoop* event_loop, Os *os, Display* dpy, const std::string& config_file, bool replace, bool synchronous, bool standalone) { initNoDisplay(); // configuration parsing require X11 to get atom and // resource variables expanded properly X11::init(dpy, synchronous, true); // used by config _hooks = new Hooks(os); _config = new Config(); _config->load(config_file); _config->loadMouseConfig(_config->getMouseConfigFile()); // setup options in X11 from configuration as a second // pass X11::setHonourRandr(_config->isHonourRandr()); _hint_wo = new HintWO(X11::getRoot()); if (! _hint_wo->claimDisplay(replace)) { delete _config; _config = nullptr; delete _hint_wo; _hint_wo = nullptr; X11::destruct(); return false; } // Create root PWinObj _root_wo = new RootWO(X11::getRoot(), _hint_wo, _config, standalone); PWinObj::setRootPWinObj(_root_wo); _key_grabber = new KeyGrabber(); _key_grabber->load(_config->getKeyFile()); _key_grabber->grabKeys(X11::getRoot()); X11::setString(X11::getRoot(), PEKWM_THEME_SCALE, std::to_string(_config->getScreenScale())); _font_handler = new FontHandler(_config->getScreenScale(), _config->isDefaultFontX11(), _config->getFontCharsetOverride()); _image_handler = new ImageHandler(_config->getScreenScale()); _texture_handler = new TextureHandler(_config->getScreenScale()); _theme = new Theme(_font_handler, _image_handler, _texture_handler, _config->getThemeFile(), _config->getThemeVariant(), true); _auto_properties = new AutoProperties(_image_handler); _auto_properties->load(); _harbour = new Harbour(_config, _auto_properties, _root_wo); _status_window = new StatusWindow(_theme); _action_handler = new ActionHandler(app_ctrl, event_loop, os); return true; } void cleanup(void) { delete _action_handler; delete _harbour; delete _status_window; delete _theme; delete _texture_handler; delete _image_handler; delete _font_handler; delete _key_grabber; delete _auto_properties; delete _root_wo; PWinObj::setRootPWinObj(nullptr); delete _hint_wo; delete _hooks; X11::destruct(); cleanupNoDisplay(); } ActionHandler* actionHandler(void) { return _action_handler; } AutoProperties* autoProperties(void) { return _auto_properties; } Config* config(void) { return _config; } void setConfig(Config* config) { delete _config; _config = config; } const std::string& configScriptPath(void) { return _config_script_path; } void setConfigScriptPath(const std::string& config_script_path) { _config_script_path = config_script_path; } FontHandler* fontHandler(void) { return _font_handler; } Harbour* harbour(void) { return _harbour; } Hooks* hooks() { return _hooks; } RootWO* rootWo(void) { return _root_wo; } void setRootWO(RootWO* root_wo) { delete _root_wo; _root_wo = root_wo; } ImageHandler* imageHandler(void) { return _image_handler; } KeyGrabber* keyGrabber(void) { return _key_grabber; } ObserverMapping* observerMapping(void) { return _observer_mapping; } StatusWindow* statusWindow(void) { return _status_window; } TextureHandler* textureHandler(void) { return _texture_handler; } Theme* theme(void) { return _theme; } bool isStarting(void) { return s_is_starting; } void setStarted(void) { s_is_starting = false; } Timeouts *timeouts() { return &_timeouts; } } pekwm-0.4.4/src/wm/Workspaces.cc0000664000175000017500000010540115126136025012171 // // Workspaces.cc for pekwm // Copyright (C) 2002-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include "Compat.hh" #include "Debug.hh" #include "Workspaces.hh" #include "Config.hh" #include "Frame.hh" #include "Client.hh" // For isSkip() #include "ManagerWindows.hh" #include "WinLayouter.hh" #include "WorkspaceIndicator.hh" #include "X11.hh" #include "tk/PWinObj.hh" #include #include #ifdef PEKWM_HAVE_LIMITS #include #endif // PEKWM_HAVE_LIMITS extern "C" { #include #include #include // for XA_WINDOW } static inline bool isFocusable(PWinObj *wo) { return wo && wo->isMapped() && wo->isFocusable(); } // Workspace Workspace::Workspace(void) : _last_focused(nullptr) { } Workspace::Workspace(const Workspace &w) : _name(w._name), _last_focused(w._last_focused) { } Workspace::~Workspace(void) { } Workspace &Workspace::operator=(const Workspace &w) { _name = w._name; _last_focused = w._last_focused; return *this; } /** * Return last focused window object, checks that the object still * exists and is mapped and focusable before returning it. */ PWinObj* Workspace::getLastFocused(bool verify) const { if (! verify || _last_focused == nullptr) { return _last_focused; } if (PWinObj::windowObjectExists(_last_focused) && isFocusable(_last_focused)) { return _last_focused; } return nullptr; } /** * Set last focused window object for workspace. */ void Workspace::setLastFocused(PWinObj* wo) { _last_focused = wo; } // Workspaces uint Workspaces::_active; uint Workspaces::_previous; uint Workspaces::_per_row; std::vector Workspaces::_layout_models; std::vector Workspaces::_wobjs; std::vector Workspaces::_workspaces; std::vector Workspaces::_mru; WorkspaceIndicator* Workspaces::_workspace_indicator = nullptr; Workspaces::win_layouter_map Workspaces::_win_layouters; void Workspaces::init() { int type_i = 1; while (type_i != static_cast(WIN_LAYOUTER_NO)) { enum WinLayouterType type = static_cast(type_i); _win_layouters[type] = mkWinLayouter(type); assert(_win_layouters[type]); type_i <<= 1; } } void Workspaces::cleanup() { clearLayoutModels(); delete _workspace_indicator; std::map::iterator it(_win_layouters.begin()); for (; it != _win_layouters.end(); ++it) { delete it->second; } _win_layouters.clear(); X11::deleteProperty(X11::getRoot(), NET_CLIENT_LIST); X11::deleteProperty(X11::getRoot(), NET_CLIENT_LIST_STACKING); X11::deleteProperty(X11::getRoot(), PEKWM_CLIENT_LIST); } /** * Sets total amount of workspaces to number */ bool Workspaces::setSize(uint number) { if (number < 1) { number = 1; } if (number == _workspaces.size()) { return false; } uint before = _workspaces.size(); if (_active >= number) { _active = number - 1; } if (_previous >= number) { _previous = number - 1; } _workspaces.resize(number); for (uint i = before; i < number; ++i) { _workspaces[i].setName(getWorkspaceName(i)); } // Tell the rest of the world how many workspaces we have. X11::setCardinal(X11::getRoot(), NET_NUMBER_OF_DESKTOPS, static_cast(number)); // make sure we aren't on an non-existent workspace if (number <= _active) { setWorkspace(number - 1, true); } return true; } /** * Set workspace names. */ void Workspaces::setNames(void) { std::vector::size_type i = 0; std::vector::size_type num_workspaces = _workspaces.size(); for (; i < num_workspaces; ++i) { _workspaces[i].setName(pekwm::config()->getWorkspaceName(i)); } } /** * Set layout models from provided string vector. */ void Workspaces::setLayoutModels(const std::vector &models) { clearLayoutModels(); std::vector::const_iterator it(models.begin()); for (; it != models.end(); ++it) { enum WinLayouterType type = win_layouter_type_from_string(*it); if (type != WIN_LAYOUTER_NO) { _layout_models.push_back(_win_layouters[type]); assert(_layout_models.back()); } } } void Workspaces::clearLayoutModels(void) { _layout_models.clear(); } /** * Activates Workspace workspace (or previous if back_and_forth is true) and * update EWMH hints. * * @param num Workspace to activate * @param back_and_forth If true, and the workspace being activated is the * current one instead go to the previously active one. * @param focus whether or not to focus a window after switch * @return true if workspace was changed, else false. */ bool Workspaces::setWorkspace(uint num, bool focus, bool back_and_forth) { if (num >= _workspaces.size()) { return false; } else if (num == _active) { if (! back_and_forth || _active == _previous) { return false; } num = _previous; } X11::grabServer(); PWinObj *wo = PWinObj::getFocusedPWinObj(); // Make sure that sticky windows gets unfocused on workspace change, // it will be set back after switch is done. if (wo) { if (wo->isType(PWinObj::WO_CLIENT)) { wo->getParent()->setFocused(false); } else { wo->setFocused(false); } } // Save the focused window object setLastFocused(_active, wo); PWinObj::setFocusedPWinObj(nullptr); pekwm::rootWo()->giveInputFocus(); // switch workspace hideAll(_active); X11::setCardinal(X11::getRoot(), NET_CURRENT_DESKTOP, num); _previous = _active; _active = num; unhideAll(num, focus); X11::ungrabServer(true); showWorkspaceIndicator(); return true; } void Workspaces::showWorkspaceIndicator(void) { int timeout = pekwm::config()->getShowWorkspaceIndicator(); if (timeout < 1) { return; } WorkspaceIndicator *wsi = getWorkspaceIndicator(); wsi->render(); wsi->mapWindowRaised(); PWinObj::setSkipEnterAfter(wsi); TimeoutAction action(ACTION_HIDE_WORKSPACE_INDICATOR, timeout); pekwm::timeouts()->replace(action); } void Workspaces::hideWorkspaceIndicator(void) { getWorkspaceIndicator()->unmapWindow(); } bool Workspaces::gotoWorkspace(uint direction, bool focus, bool warp) { uint workspace; int dir = 0; // Using a bool flag to detect changes due to special workspaces such // as PREV bool switched = true; bool back_and_forth = false; uint per_row = pekwm::config()->getWorkspacesPerRow(); uint cur_row = getRow(), row_min = getRowMin(), row_max = getRowMax(); switch (direction) { case WORKSPACE_LEFT: case WORKSPACE_PREV: dir = 1; if (_active > row_min) { workspace = _active - 1; } else if (direction == WORKSPACE_PREV) { workspace = row_max; } else { switched = false; } break; case WORKSPACE_PREV_N: case WORKSPACE_LEFT_N: dir = 1; if (_active > 0) { workspace = _active - 1; } else if (direction == WORKSPACE_PREV_N) { workspace = _workspaces.size() - 1; } else { switched = false; } break; case WORKSPACE_NEXT: case WORKSPACE_RIGHT: dir = 2; if (_active < row_max) { workspace = _active + 1; } else if (direction == WORKSPACE_NEXT) { workspace = row_min; } else { switched = false; } break; case WORKSPACE_NEXT_N: case WORKSPACE_RIGHT_N: dir = 2; if (_active < (_workspaces.size() - 1)) { workspace = _active + 1; } else if (direction == WORKSPACE_NEXT_N) { workspace = 0; } else { switched = false; } break; case WORKSPACE_PREV_V: case WORKSPACE_UP: dir = -1; if (_active >= per_row) { workspace = _active - per_row; } else if (direction == WORKSPACE_PREV_V) { // Bottom left workspace = _workspaces.size() - per_row; // Add column workspace += _active - cur_row * per_row; } else { switched = false; } break; case WORKSPACE_NEXT_V: case WORKSPACE_DOWN: dir = -2; if (_active + per_row < _workspaces.size()) { workspace = _active + per_row; } else if (direction == WORKSPACE_NEXT_V) { workspace = _active - cur_row * per_row; } else { switched = false; } break; case WORKSPACE_LAST: workspace = _previous; switched = _active != workspace; break; default: workspace = direction; switched = _active != workspace; back_and_forth = pekwm::config()->isWorkspacesBackAndForth(); } if (switched || back_and_forth) { if (warp) { warpToWorkspace(workspace, dir); } else { switched = setWorkspace(workspace, focus, back_and_forth); } } return switched; } bool Workspaces::warpToWorkspace(uint num, int dir) { if (num == _active || num >= _workspaces.size()) { return false; } int x, y; X11::getMousePosition(x, y); Config* cfg = pekwm::config(); if (dir != 0) { int edge_size; switch(dir) { case 1: edge_size = cfg->getScreenEdgeSize(SCREEN_EDGE_LEFT); x = X11::getWidth() - std::max(edge_size + 2, 2); break; case 2: edge_size = cfg->getScreenEdgeSize(SCREEN_EDGE_RIGHT); x = std::max(edge_size + 2, 2); break; case -1: edge_size = cfg->getScreenEdgeSize(SCREEN_EDGE_BOTTOM); y = X11::getHeight() - std::max(edge_size + 2, 2); break; case -2: edge_size = cfg->getScreenEdgeSize(SCREEN_EDGE_TOP); y = std::max(edge_size + 2, 2); break; } // warp pointer X11::warpPointer(x, y); } // set workpsace setWorkspace(num, true); return true; } void Workspaces::fixStacking(PWinObj *pwo) { const_iterator it = find(pwo); if (it == _wobjs.end()) { return; } if (++it == _wobjs.end()) { X11::raiseWindow(pwo->getWindow()); } else { std::vector winlist; winlist.push_back((*it)->getWindow()); winlist.push_back(pwo->getWindow()); X11::stackWindows(winlist); } } /** * Place window based on the current placement model. */ void Workspaces::layout(Frame *frame, Window parent, int win_layouter_types) { if (frame == nullptr) { return; } frame->updateDecor(); // Collect the information which head has a fullscreen window. To be // conservative for now we ignore fullscreen windows on the desktop or // normal layer, because it might be a file manager in desktop mode, // for example. std::vector fsHead(X11::getNumHeads(), false); Workspaces::const_iterator it(Workspaces::begin()), w_end(Workspaces::end()); for (; it != w_end; ++it) { if ((*it)->isMapped() && (*it)->isType(PWinObj::WO_FRAME)) { Client *client = static_cast(*it)->getActiveClient(); if (client && client->isFullscreen() && client->getLayer()>LAYER_NORMAL) { fsHead[client->getHead()] = true; } } } // Try to place the window Geometry gm; CurrHeadSelector chs = pekwm::config()->getCurrHeadSelector(); int head_nr = X11Util::getCurrHead(chs); // update pointer position cache, used in layout models. int ptr_x, ptr_y; X11::getMousePosition(ptr_x, ptr_y); Generator::RangeWrap range(head_nr, X11::getNumHeads()); for (; ! range.is_end(); ++range) { if (! fsHead[*range]) { pekwm::rootWo()->getHeadInfoWithEdge(*range, gm); if (layoutOnHead(frame, win_layouter_types, parent, gm, ptr_x, ptr_y)) { return; } } } // Failed to place the window, so put it in the top-left corner // trying to avoid heads with a fullscreen window on it. for (range.reset(); ! range.is_end(); ++range) { if (! fsHead[*range]) { break; } } pekwm::rootWo()->getHeadInfoWithEdge(*range, gm); frame->move(gm.x, gm.y); } bool Workspaces::layoutOnHead(PWinObj *wo, int win_layouter_types, Window parent, const Geometry &gm, int ptr_x, int ptr_y) { if (win_layouter_types) { return layoutOnHeadTypes(wo, win_layouter_types, parent, gm, ptr_x, ptr_y); } std::vector::iterator it(_layout_models.begin()); for (; it != _layout_models.end(); ++it) { if ((*it)->layout(wo, parent, gm, ptr_x, ptr_y)) { return true; } } return false; } /** * Place PWinObj on the given head using win_layouter_types instead of the * globally configured types. */ bool Workspaces::layoutOnHeadTypes(PWinObj *wo, int win_layouter_types, Window parent, const Geometry &gm, int ptr_x, int ptr_y) { enum WinLayouterType type; do { type = static_cast( win_layouter_types & WIN_LAYOUTER_MASK); win_layouter_map::iterator it(_win_layouters.find(type)); if (it != _win_layouters.end() && it->second->layout(wo, parent, gm, ptr_x, ptr_y)) { return true; } win_layouter_types >>= WIN_LAYOUTER_SHIFT; } while (win_layouter_types); return false; } /** * Adds a PWinObj to the stacking list. Assumes that wo is not in _wobjs * already. * @param wo PWinObj to insert * @param raise Whether to insert at the bottom or top of the layer * (defaults to true). */ void Workspaces::insert(PWinObj *wo, bool raise) { PWinObj *top_obj = 0; Frame *wo_frame = dynamic_cast(wo); iterator it; if (! raise && wo_frame && wo_frame->getTransFor() && wo_frame->getTransFor()->getLayer() == wo_frame->getLayer()) { // Lower only to the top of the transient_for window. it = find(wo_frame->getTransFor()->getParent()); ++it; top_obj = it!=_wobjs.end() ? *it : nullptr; } else { it = _wobjs.begin(); for (; it != _wobjs.end(); ++it) { if (raise) { // If raising, make sure the inserted wo gets // below the first window in the next layer. if ((*it)->getLayer() > wo->getLayer()) { top_obj = *it; break; } } else if (wo->getLayer() <= (*it)->getLayer()) { // If lowering, put the window below the first // window with the same level. top_obj = *it; break; } } } _wobjs.insert(it, wo); std::vector winstack; winstack.reserve(3); winstack.push_back(wo); if (wo_frame && wo_frame->hasTrans()) { std::vector::const_iterator t_it; for (it = _wobjs.begin(); *it != wo;) { Frame *frame = dynamic_cast(*it); if (frame) { t_it = std::find(wo_frame->getTransBegin(), wo_frame->getTransEnd(), frame->getActiveClient()); if (t_it != wo_frame->getTransEnd()) { winstack.push_back(frame); it = _wobjs.erase(it); continue; } } ++it; } it = find(wo); ++it; _wobjs.insert(it, winstack.begin()+1, winstack.end()); } if (top_obj) { winstack.push_back(top_obj); } else { X11::raiseWindow(winstack.back()->getWindow()); } std::vector wins; std::vector::reverse_iterator wit(winstack.rbegin()); for (; wit != winstack.rend(); ++wit) { wins.push_back((*wit)->getWindow()); } X11::stackWindows(wins); } //! @brief Removes a PWinObj from the stacking list. void Workspaces::remove(const PWinObj* wo) { iterator it_wo(_wobjs.begin()); for (;it_wo != _wobjs.end();) { if (wo == *it_wo) { it_wo = _wobjs.erase(it_wo); } else { ++it_wo; } } // remove from last focused std::vector::iterator it = _workspaces.begin(); for (; it != _workspaces.end(); ++it) { if (wo == it->getLastFocused(false)) { it->setLastFocused(nullptr); } } } //! @brief Hides all non-sticky Frames on the workspace. void Workspaces::hideAll(uint workspace) { const_iterator it(_wobjs.begin()); for (; it != _wobjs.end(); ++it) { if (! ((*it)->isSticky()) && ! (*it)->isHidden() && ((*it)->getWorkspace() == workspace)) { (*it)->unmapWindow(); } } } //! @brief Unhides all hidden PWinObjs on the workspace. void Workspaces::unhideAll(uint workspace, bool focus) { const_iterator it(_wobjs.begin()); for (; it != _wobjs.end(); ++it) { if (! (*it)->isMapped() && ! (*it)->isIconified() && ! (*it)->isHidden() && ((*it)->getWorkspace() == workspace)) { (*it)->mapWindow(); // don't restack ontop windows if ((*it)->isType(PWinObj::WO_FRAME)) { static_cast(*it)->updateDecor(); } } } if (focus) { // Try to focus last focused window and if that // fails, get the top-most Frame if any and give it // focus. PWinObj *wo = _workspaces[workspace].getLastFocused(true); if (wo == nullptr) { wo = getTopFocusableWO(PWinObj::WO_FRAME); } if (wo) { // Render as focused if (wo->isType(PWinObj::WO_CLIENT)) { wo->getParent()->setFocused(true); } else { wo->setFocused(true); } // Get the active child if a frame, to get // correct focus behavior if (wo->isType(PWinObj::WO_FRAME)) { wo = static_cast(wo)->getActiveChild(); } // Focus giveInputFocus(wo); PWinObj::setFocusedPWinObj(wo); // update the MRU list if (wo->isType(PWinObj::WO_CLIENT)) { Frame *frame = static_cast(wo->getParent()); addToMRUFront(frame); } } // If focusing fails, focus the root window. if (! PWinObj::getFocusedPWinObj() || ! PWinObj::getFocusedPWinObj()->isMapped()) { PWinObj::getRootPWinObj()->giveInputFocus(); } } } /** * Raises a PWinObj and restacks windows. * * @return true if windows were restacked, else false. */ bool Workspaces::raise(PWinObj* wo) { iterator it = find(wo); if (it == _wobjs.end()) { return false; } if (handleFullscreenBeforeRaise(wo)) { it = find(wo); } _wobjs.erase(it); insert(wo, true /* raise */); return true; } /** * Swap position of wo_under and wo_over in the stacking order making wo_over * placed above wo_under. * * @return true if stacking was changed, false if objects belong to different * layers. */ bool Workspaces::swapInStack(PWinObj* wo_under, PWinObj* wo_over) { if (wo_under->getLayer() != wo_under->getLayer()) { P_TRACE("not swapping in stack, not on the same layer"); return false; } iterator it_under = find(wo_under); assert(it_under != _wobjs.end()); iterator it_over = find(wo_over); assert(it_over != _wobjs.end()); *it_under = wo_over; *it_over = wo_under; stackAt(it_over); stackAt(it_under); return true; } /** * Move wo_under in the stack and place it above wo. */ bool Workspaces::stackAbove(PWinObj* wo_under, PWinObj* wo) { if (wo_under->getLayer() != wo->getLayer()) { P_TRACE("not stacking above, not on the same layer"); return false; } iterator it_under = find(wo_under); assert(it_under != _wobjs.end()); _wobjs.erase(it_under); iterator it = find(wo); assert(it != _wobjs.end()); it_under = _wobjs.insert(it + 1, wo_under); stackAt(it_under); return true; } /** * Get iterator for PWinObj from _wobjs. */ Workspaces::iterator Workspaces::find(const PWinObj *wo) { return std::find(_wobjs.begin(), _wobjs.end(), wo); } void Workspaces::stackAt(iterator it) { iterator it_above = it + 1; if (it_above == _wobjs.end()) { X11::raiseWindow((*it)->getWindow()); } else { std::vector wins; wins.push_back((*it_above)->getWindow()); wins.push_back((*it)->getWindow()); X11::stackWindows(wins); } } /** * Handles fullscreen windows when raising a window: if a normal * window is raised, fullscreen windows on LAYER_ABOVE_DOCK are * lowered. If a fullscreen window is raised, bring it back to * LAYER_ABOVE_DOCK. * * @return true if _wobjs iterators may be invalid */ bool Workspaces::handleFullscreenBeforeRaise(PWinObj* wo) { if (!pekwm::config()->isFullscreenAbove() || wo->getLayer() == LAYER_DESKTOP || wo->getLayer() >= LAYER_ABOVE_DOCK) { return false; } if (wo->isFullscreen()) { // Fullscreen windows may have been removed from // LAYER_ABOVE_DOCK by lowerFullscreenWindows(). Raise it back // to LAYER_ABOVE_DOCK wo->setLayer(LAYER_ABOVE_DOCK); return false; } // Move all mapped fullscreen windows at LAYER_ABOVE_DOCK back // to wo->getLayer() in order for "wo" to be visible. // // Since restacking is done one by one, this could lead to // some flickering, but quite minimmum. return lowerFullscreenWindows(wo->getLayer()); } /** * Move all windows above new_layer back to new_layer and restack one * by one, from bottom to top. * * Since the top fullscreen window should hide everything else, * multiple restacking operations shouldn't produce any flickering * until the top one is restacked, which may show a few more windows * on top of it. * * @param new_layer the new layer for fullscreen windows * @return true if _wobjs iterators may be invalid */ bool Workspaces::lowerFullscreenWindows(Layer new_layer) { std::vector fs_wobjs; // Note, fullscreen windows are typically only in // LAYER_ABOVE_DOCK. However, a call to lowerFullscreenWindows() // with new_layer == LAYER_ONTOP could put fullscreen windows // there, so we need to check all layers above new_layer, not just // LAYER_ABOVE_DOCK. iterator wo = _wobjs.begin(); for (; wo != _wobjs.end(); ++wo) { if ((*wo)->getLayer() > new_layer && (*wo)->isMapped() && (*wo)->isFullscreen()) { fs_wobjs.push_back(*wo); (*wo)->setLayer(new_layer); } } for (wo = fs_wobjs.begin(); wo != fs_wobjs.end(); ++wo) { // We could have erased these windows in the first for loop, // which could reduce a couple of std::find() calls. // // But we want the higher fullscreen windows to _stay_ in // _wobjs, so that they can be the (top_obj) anchor point for // restacking. And since that anchor is most likely fullscreen // and hides everything else, no flickering. iterator it = find(*wo); if (it != _wobjs.end()) { _wobjs.erase(it); insert(*wo, true); } } return !fs_wobjs.empty(); } /** * Lower a PWinObj and restacks windows. * * @return true if lowered, else false. */ bool Workspaces::lower(PWinObj* wo) { iterator it = find(wo); if (it == _wobjs.end()) { return false; } _wobjs.erase(it); insert(wo, false /* lower, raise is false */); return true; } /** * Restack wo relative to sibling using detail as position. */ void Workspaces::restack(PWinObj* wo, PWinObj* sibling, long detail) { bool restacked; if (sibling) { restacked = restackSibling(wo, sibling, detail); } else { restacked = restack(wo, detail); } if (restacked) { updateClientStackingList(); } } bool Workspaces::restack(PWinObj *wo, long detail) { switch (detail) { case Above: return raise(wo); case Below: return lower(wo); case TopIf: return restackTopIf(wo); case BottomIf: return restackBottomIf(wo); case Opposite: if (restackTopIf(wo)) { return true; } return restackBottomIf(wo); default: P_TRACE("unsupported detail " << detail << " in " "_NET_RESTACK_WINDOW request"); return false; } } /** * If any sibling occludes the window, the window is placed at * the top of the stack (for that layer). */ bool Workspaces::restackTopIf(PWinObj *wo) { for (iterator it = find(wo) + 1; it < _wobjs.end(); ++it) { if ((*it)->getLayer() != wo->getLayer()) { break; } else if (isOccluding((*it), wo)) { raise(wo); return true; } } return false; } /** * If the window occludes any sibling, the window is placed at the bottom of the * stack (for that layer). */ bool Workspaces::restackBottomIf(PWinObj *wo) { for (iterator it = find(wo) - 1; it >= _wobjs.begin(); --it) { if ((*it)->getLayer() != wo->getLayer()) { break; } else if (isOccluding(wo, (*it))) { lower(wo); return true; } } return false; } bool Workspaces::restackSibling(PWinObj *wo, PWinObj *sibling, long detail) { switch (detail) { case Above: return stackAbove(wo, sibling); case Below: return stackAbove(sibling, wo); case TopIf: if (isOccluding(sibling, wo)) { return raise(wo); } return false; case BottomIf: if (isOccluding(wo, sibling)) { return lower(wo); } return false; case Opposite: if (isOccluding(wo, sibling)) { return swapInStack(wo, sibling); } else if (isOccluding(sibling, wo)) { return swapInStack(sibling, wo); } return false; default: P_TRACE("unsupported detail " << detail << " in " "_NET_RESTACK_WINDOW request"); return false; } } /** * Check if wo is above in the stacking order and has any part of * it's geometry in the area of sibling. */ bool Workspaces::isOccluding(const PWinObj* wo, const PWinObj* sibling) { iterator it_wo = find(wo); iterator it_sibling = find(sibling); if (it_wo == _wobjs.end() || it_sibling == _wobjs.end()) { return false; } else if (!wo->isMapped()) { // can't occlude if it is not mapped return false; } return it_wo > it_sibling && sibling->getGeometry().isOverlap(wo->getGeometry()); } PWinObj* Workspaces::getLastFocused(uint workspace) { if (workspace >= _workspaces.size()) { return nullptr; } return _workspaces[workspace].getLastFocused(true); } void Workspaces::setLastFocused(uint workspace, PWinObj* wo) { if (workspace >= _workspaces.size()) { return; } _workspaces[workspace].setLastFocused(wo); } /** * Create name for workspace number, use the configured name if set else the * number + 1 as a string is used. */ std::string Workspaces::getWorkspaceName(uint num) { const std::string &name = pekwm::config()->getWorkspaceName(num); if (name.empty()) { return std::to_string(num + 1); } return name; } // MISC METHODS /** * Returns the first focusable PWinObj with the highest stacking. */ PWinObj* Workspaces::getTopFocusableWO(uint type_mask) { reverse_iterator r_it = _wobjs.rbegin(); for (; r_it != _wobjs.rend(); ++r_it) { if (isFocusable(*r_it) && ((*r_it)->getType()&type_mask)) { return *r_it; } } return nullptr; } /** * Builds a list of all clients in stacking order, clients in the same * frame come after each other. */ void Workspaces::buildClientList(std::vector &windows, bool report_all) { Frame *frame; Client *client, *client_active; iterator it_f; const_iterator it_c; for (it_f = _wobjs.begin(); it_f != _wobjs.end(); ++it_f) { if (! (*it_f)->isType(PWinObj::WO_FRAME)) { continue; } frame = static_cast(*it_f); client_active = frame->getActiveClient(); if (report_all) { for (it_c = frame->begin(); it_c != frame->end(); ++it_c) { client = dynamic_cast(*it_c); if (client && client != client_active && ! client->isSkip(SKIP_TASKBAR)) { windows.push_back(client->getWindow()); } } } if (client_active && ! client_active->isSkip(SKIP_TASKBAR)) { windows.push_back(client_active->getWindow()); } } } /** * Updates EWMH and pekwm client list hints. */ void Workspaces::updateClientList(void) { bool report_all = pekwm::config()->isReportAllClients(); std::vector windows; buildClientList(windows, report_all); // previously, the lists where unset when they ended up empty // however some applications does not support this, one // example being tint2 on Debian Stretch X11::setWindows(X11::getRoot(), NET_CLIENT_LIST, windows); X11::setWindows(X11::getRoot(), NET_CLIENT_LIST_STACKING, windows); if (! report_all) { windows.clear(); buildClientList(windows, true); } X11::setWindows(X11::getRoot(), PEKWM_CLIENT_LIST, windows); } /** * Updates the Ewmh Stacking list hint. */ void Workspaces::updateClientStackingList(void) { bool report_all = pekwm::config()->isReportAllClients(); std::vector windows; buildClientList(windows, report_all); P_TRACE("updating _NET_CLIENT_LIST_STACKING with " << windows.size() << " window(s)"); X11::setWindows(X11::getRoot(), NET_CLIENT_LIST_STACKING, windows); } /** * Make sure window is inside screen boundaries. If window is in * fullscreen mode or maximized, resize to make sure it covers the new * screen. */ void Workspaces::placeWoInsideScreen(PWinObj *wo) { Geometry gm_before(wo->getX(), wo->getY(), wo->getWidth(), wo->getHeight()); Geometry gm_after(gm_before); Strut *strut = 0; bool maximized_virt = false; bool maximized_horz = false; if (wo->isType(PWinObj::WO_FRAME)) { Client *client = static_cast(wo)->getActiveClient(); if (client) { strut = client->getStrut(); maximized_virt = client->isMaximizedVert(); maximized_horz = client->isMaximizedHorz(); } } pekwm::rootWo()->placeInsideScreen(gm_after, strut, wo->isFullscreen(), maximized_virt, maximized_horz); if (gm_before != gm_after) { wo->moveResize(gm_after.x, gm_after.y, gm_after.width, gm_after.height); } } void Workspaces::giveInputFocus(PWinObj *wo, bool force) { if (wo->isFocusable()) { // check for current focused window object, warping to an // already focused window is confusing. if ((force || ! wo->isFocused()) && pekwm::config()->isWarpPointerOn(WARP_ON_FOCUS_CHANGE) && wo != pekwm::rootWo()) { wo->warpPointer(); } wo->giveInputFocus(); } } /** * Searches for a PWinObj to focus, and then gives it input focus */ void Workspaces::findWOAndFocus(PWinObj *search) { PWinObj *focus = nullptr; if (PWinObj::windowObjectExists(search) && isFocusable(search)) { focus = search; } else { // search window object didn't exist, find candidate bool stacking = pekwm::config()->isOnCloseFocusStacking(); focus = findWOAndFocusFind(stacking); } if (focus) { giveInputFocus(focus); findWOAndFocusRaise(focus); } else if (! PWinObj::getFocusedPWinObj()) { pekwm::rootWo()->giveInputFocus(); pekwm::rootWo()->setEwmhActiveWindow(None); } } void Workspaces::findWOAndFocusRaise(PWinObj *wo) { switch (pekwm::config()->getOnCloseFocusRaise()) { case ON_CLOSE_FOCUS_RAISE_ALWAYS: wo->raise(); break; case ON_CLOSE_FOCUS_RAISE_IF_COVERED: { uint percent = overlapPercent(wo); if (percent > 50) { P_TRACE("raising " << wo << " " << percent << "% overlap"); wo->raise(); } else { P_TRACE("NOT raising " << wo << " " << percent << "% overlap"); } break; } default: // do nothing break; }; } PWinObj* Workspaces::findWOAndFocusFind(bool stacking) { if (!stacking) { PWinObj *wo = findWOAndFocusMRU(); if (wo != nullptr) { return wo; } } return findWOAndFocusStacking(); } PWinObj* Workspaces::findWOAndFocusStacking() { std::vector::reverse_iterator it(_wobjs.rbegin()); for (; it != _wobjs.rend(); ++it) { if (! isFocusable(*it) || ! (*it)->isType(PWinObj::WO_FRAME)) { continue; } switch ((*it)->getWinType()) { case WINDOW_TYPE_DESKTOP: case WINDOW_TYPE_UTILITY: case WINDOW_TYPE_DIALOG: case WINDOW_TYPE_NORMAL: return *it; default: /* do nothing */ break; } } return nullptr; } PWinObj* Workspaces::findWOAndFocusMRU() { std::vector::iterator it(_mru.begin()); for (; it != _mru.end(); ++it) { if (isFocusable(*it)) { return *it; } } return nullptr; } /** * Calculate how many percentage of PWinObj is covered by windows above it. */ uint Workspaces::overlapPercent(PWinObj *wo) { iterator it = find(wo); assert(it != _wobjs.end()); GeometryOverlap overlap(wo->getGeometry()); for (++it; it != _wobjs.end(); ++it) { if ((*it)->isMapped() && (*it)->isType(PWinObj::WO_FRAME)) { overlap.addOverlap((*it)->getGeometry()); } } return overlap.getOverlapPercent(); } /** * Find window object under the mouse, favouring higher stacked * windows over window below it */ PWinObj* Workspaces::findUnderPointer(void) { int x, y; X11::getMousePosition(x, y); reverse_iterator it; for (it = _wobjs.rbegin(); it != _wobjs.rend(); ++it) { if (isFocusable(*it) && (*it)->isUnder(x, y)) { return *it; } } return nullptr; } /** * wo PWinObj to originate from when searching * * @param dir Direction to search * @param skip Bitmask for skipping window objects, defaults to 0 */ PWinObj* Workspaces::findDirectional(PWinObj *wo, DirectionType dir, uint skip) { // search from the frame not client, if client if (wo->isType(PWinObj::WO_CLIENT)) { wo = static_cast(wo)->getParent(); } PWinObj *found_wo = 0; uint score, score_min; int wo_main, wo_sec; int diff_main, diff_pos; score_min = std::numeric_limits::max(); // init wo variables if ((dir == DIRECTION_UP) || (dir == DIRECTION_DOWN)) { wo_main = wo->getY() + wo->getHeight() / 2; wo_sec = wo->getX() + wo->getWidth() / 2; } else { wo_main = wo->getX() + wo->getWidth() / 2; wo_sec = wo->getY() + wo->getHeight() / 2; } const_iterator it(_wobjs.begin()); for (; it != _wobjs.end(); ++it) { if ((wo == (*it)) || ! ((*it)->isMapped())) { continue; // skip ourselves and unmapped wo's } if (! (*it)->isType(PWinObj::WO_FRAME) || static_cast(*it)->isSkip(skip)) { continue; // only include frames and not having skip set } // check main direction, making sure it's at the right side we // check against the middle of the window as it gives a saner // feeling than the edges IMHO switch (dir) { case DIRECTION_UP: diff_main = wo_main - ((*it)->getY() + (*it)->getHeight() / 2); diff_pos = wo->getY() - (*it)->getY(); break; case DIRECTION_DOWN: diff_main = ((*it)->getY() + (*it)->getHeight() / 2) - wo_main; diff_pos = (*it)->getBY() - wo->getBY(); break; case DIRECTION_LEFT: diff_main = wo_main - ((*it)->getX() + (*it)->getWidth() / 2); diff_pos = wo->getX() - (*it)->getX(); break; case DIRECTION_RIGHT: diff_main = ((*it)->getX() + (*it)->getWidth() / 2) - wo_main; diff_pos = (*it)->getRX() - wo->getRX(); break; default: return 0; // no direction to search } if (diff_main < 0) { continue; // wrong direction } else if (diff_pos <= 0) { continue; // no difference in direction } score = diff_main; if ((dir == DIRECTION_UP) || (dir == DIRECTION_DOWN)) { if ((wo_sec < (*it)->getX()) || (wo_sec > (*it)->getRX())) { score += X11::getHeight() / 2; } score += abs (static_cast( wo_sec - ((*it)->getX () + (*it)->getWidth () / 2))); } else { if ((wo_sec < (*it)->getY()) || (wo_sec > (*it)->getBY())) { score += X11::getWidth() / 2; } score += abs(static_cast( wo_sec - ((*it)->getY () + (*it)->getHeight () / 2))); } if (score < score_min) { found_wo = *it; score_min = score; } } return found_wo; } /** * Finds the next frame in the list * * @param frame Frame to search from * @param mapped Match only agains mapped frames * @param mask Defaults to 0 */ Frame* Workspaces::getNextFrame(Frame* frame, bool mapped, uint mask) { if (! frame || (Frame::frame_size() < 2)) { return nullptr; } Frame *next_frame = nullptr; Frame::frame_cit f_it = std::find(Frame::frame_begin(), Frame::frame_end(), frame); if (f_it != Frame::frame_end()) { Frame::frame_cit n_it(f_it); if (++n_it == Frame::frame_end()) { n_it = Frame::frame_begin(); } while (! next_frame && n_it != f_it) { if (! (*n_it)->isSkip(mask) && (! mapped || (*n_it)->isMapped())) { next_frame = (*n_it); } if (++n_it == Frame::frame_end()) { n_it = Frame::frame_begin(); } } } return next_frame; } /** * Finds the previous frame in the list * * @param frame Frame to search from * @param mapped Match only agains mapped frames * @param mask Defaults to 0 */ Frame* Workspaces::getPrevFrame(Frame* frame, bool mapped, uint mask) { if (! frame || Frame::frame_size() < 2) { return nullptr; } Frame *prev_frame = nullptr; Frame::frame_cit f_it = std::find(Frame::frame_begin(), Frame::frame_end(), frame); if (f_it != Frame::frame_end()) { Frame::frame_cit n_it(f_it); if (n_it == Frame::frame_begin()) { n_it = Frame::frame_end(); } --n_it; while (! prev_frame && (n_it != f_it)) { if (! (*n_it)->isSkip(mask) && (! mapped || (*n_it)->isMapped())) { prev_frame = (*n_it); } if (n_it == Frame::frame_begin()) { n_it = Frame::frame_end(); } --n_it; } } return prev_frame; } pekwm-0.4.4/src/wm/WORefMenu.cc0000664000175000017500000000265615126136025011667 // // WORefMenu.cc for pekwm // Copyright (C) 2004-2024 Claes Nästen // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include "PDecor.hh" #include "PMenu.hh" #include "WORefMenu.hh" #include "Client.hh" #include "tk/PWinObj.hh" /** * WORefMenu constructor * @param theme Pointer to Theme * @param title Title of menu * @param name Name of menu * @param decor_name Name of decor, defaults to MENU */ WORefMenu::WORefMenu(const std::string &title, const std::string &name, const std::string &decor_name) : PMenu(title, name, decor_name), PWinObjReference(nullptr), _title_base(title), _title_pre(" ["), _title_post("]") { } WORefMenu::~WORefMenu(void) { } /** * When notified, unmap all windows as window menu refers to object * being removed. */ void WORefMenu::notify(Observable *observable, Observation *observation) { PWinObjReference::notify(observable, observation); unmapAll(); } /** * Sets the reference and updates the title */ void WORefMenu::setWORef(PWinObj *wo_ref) { PWinObjReference::setWORef(wo_ref); std::string title(_title_base); // if of client type, add the clients named to the title if (wo_ref && (wo_ref->getType() == PWinObj::WO_CLIENT)) { Client *client = static_cast(wo_ref); title += _title_pre + client->getTitle()->getVisible() + _title_post; } setTitle(title); } pekwm-0.4.4/src/wm/pekwm.cc0000664000175000017500000001315315126136025011175 // // pekwm.cc for pekwm // Copyright (C) 2021-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include "Compat.hh" #include "pekwm_env.hh" #include #include extern "C" { #include #include #include #include #include #include } static int child_signal = 0; static void sigHandler(int signal) { switch (signal) { case SIGHUP: case SIGINT: case SIGTERM: child_signal = signal; break; } } static int waitPid(pid_t pid) { int ret; while (waitpid(pid, &ret, 0) == -1 && errno == EINTR) { if (child_signal) { kill(pid, child_signal); child_signal = 0; } } if (WIFEXITED(ret)) { return WEXITSTATUS(ret); } return ret; } static char** mkArgv(const std::vector& argv_in) { char **argv = new char*[argv_in.size() + 1]; if (argv == nullptr) { exit(1); } int i = 0; std::vector::const_iterator it(argv_in.begin()); for (; it != argv_in.end(); ++it) { argv[i] = new char[it->size() + 1]; memcpy(argv[i++], it->c_str(), it->size() + 1); } argv[i] = nullptr; return argv; } static char** mkRestartArgv(char **argv) { std::vector restart_argv; for (int i = 0; argv[i] != nullptr; i++) { restart_argv.push_back(argv[i]); } restart_argv.push_back("--skip-start"); return mkArgv(restart_argv); } static bool promptForRestart(const std::string& pekwm_dialog) { pid_t pid = fork(); if (pid == 0) { std::vector argv_in; argv_in.push_back(pekwm_dialog); argv_in.push_back("-o"); argv_in.push_back("Restart"); argv_in.push_back("-o"); argv_in.push_back("Exit"); argv_in.push_back("-t"); argv_in.push_back("pekwm stopped unexpectedly"); argv_in.push_back("-r"); char **argv = mkArgv(argv_in); execvp(argv[0], argv); delete[] argv; exit(1); } else if (pid == -1) { return false; } else { return waitPid(pid) == 0; } } static int handleOkResult(char *path, char **argv, int read_fd) { char buf[1024] = {0}; if (read(read_fd, buf, sizeof(buf) - 1) == -1) { std::cerr << "failed to read pekwm_wm result due to: " << strerror(errno) << std::endl; } close(read_fd); if (strncmp("stop", buf, 4) == 0) { return 0; } if (strncmp("error", buf, 5) == 0) { return 1; } if (strncmp("restart ", buf, 8) == 0) { std::string command = std::string(buf + 8); if (command.empty()) { char **restart_argv = mkRestartArgv(argv); execvp(path, restart_argv); delete[] restart_argv; } else { command = "exec " + command; execl(PEKWM_SH, PEKWM_SH , "-c", command.c_str(), (void*) 0); } std::cerr << "failed to run restart command: " << command << std::endl; } return 1; } static int handleUnexpectedResult(char *path, char **argv, int read_fd) { close(read_fd); // run pekwm_dialog and wait for answer on to restart or not std::string pekwm_dialog = std::string(path) + "_dialog"; if (promptForRestart(pekwm_dialog)) { char **restart_argv = mkRestartArgv(argv); execvp(path, restart_argv); delete[] restart_argv; std::cerr << "failed to restart pekwm" << std::endl; exit(1); } std::cerr << "not restarting after crash" << std::endl; return 1; } /** * Main function of pekwm */ int main(int argc, char **argv) { initEnv(true); if (argc > 1 && strcmp("--standalone", argv[1]) == 0) { std::cerr << "--standalone only supported using pekwm_wm" << std::endl; return 1; } // Limit (on OpenBSD) to standard input, file system reads and // fork-exec to spawn actual pekwm_wm. pledge_x("stdio rpath proc exec", NULL); // Get the pekwm_wm command by appending _wm to the path to ensure // the correct pekwm_wm is used when running from a non-installed // location. std::string pekwm_wm = std::string(argv[0]) + "_wm"; // Setup environment, DISPLAY is set to make RestartOther work as // expected re-using the display from the --display argument. // // PEKWM_CONFIG_FILE is set as an environment to make pekwm_dialog // catch the correct configuration file. std::vector wm_argv; wm_argv.push_back(pekwm_wm); for (int i = 1; i < argc; i++) { if ((strcmp("--display", argv[i]) == 0) && ((i + 1) < argc)) { setenv("DISPLAY", argv[++i], 1); } else if ((strcmp("--config", argv[i]) == 0) && ((i + 1) < argc)) { setenv("PEKWM_CONFIG_FILE", argv[++i], 1); } else { wm_argv.push_back(argv[i]); } } // Run the window manager inside a child process to avoid stopping // the X11 server on a crash, instead just restart int fd[2]; if (pipe(fd) == -1) { std::cerr << "Failed to create pipe for communicating with " << " pekwm_wm process" << std::endl; return 1; } int ret = 1; pid_t pid = fork(); if (pid == 0) { // close reading end on child close(fd[0]); wm_argv.insert(wm_argv.begin() + 1, "--fd"); wm_argv.insert(wm_argv.begin() + 2, std::to_string(fd[1])); char **c_wm_argv = mkArgv(wm_argv); execvp(c_wm_argv[0], c_wm_argv); delete[] c_wm_argv; std::cerr << "Failed to execute: " << pekwm_wm << std::endl; exit(1); } else if (pid == -1) { std::cerr << "Failed to fork: " << strerror(errno) << std::endl; } else { // close writing end on parent close(fd[1]); struct sigaction act; act.sa_handler = sigHandler; act.sa_mask = sigset_t(); act.sa_flags = SA_NOCLDSTOP | SA_NODEFER; sigaction(SIGHUP, &act, 0); sigaction(SIGTERM, &act, 0); sigaction(SIGINT, &act, 0); ret = waitPid(pid); if (ret == 0) { ret = handleOkResult(argv[0], argv, fd[0]); } else { ret = handleUnexpectedResult(argv[0], argv, fd[0]); } } return ret; } pekwm-0.4.4/src/wm/Client.cc0000664000175000017500000013235715164641301011300 // // Client.cc for pekwm // Copyright (C) 2002-2025 Claes Nästén // // client.cc for aewm++ // Copyright (C) 2000 Frank Hale // http://sapphire.sourceforge.net/ // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include #include #include extern "C" { #include #include #include #include } #include "Charset.hh" #include "Compat.hh" #include "Container.hh" #include "Debug.hh" #include "PDecor.hh" // PDecor::TitleItem #include "Client.hh" #include "ClientMgr.hh" #include "Config.hh" #include "KeyGrabber.hh" #include "AutoProperties.hh" #include "Frame.hh" #include "Workspaces.hh" #include "ManagerWindows.hh" #include "X11.hh" #include "tk/TextureHandler.hh" #include "tk/ImageHandler.hh" #include "tk/PWinObj.hh" #include "tk/PImageIcon.hh" #include "tk/X11Util.hh" std::ostream& operator<<(std::ostream& os, const ClassHint &ch) { os << "ClassHint " << Charset::toSystem(ch.h_name) << "," << Charset::toSystem(ch.h_class); return os; } ClassHint::ClassHint(void) { } ClassHint::ClassHint(const std::string &n_h_name, const std::string &n_h_class, const std::string &n_h_role, const std::string &n_title, const std::string &n_group) : h_name(n_h_name), h_class(n_h_class), h_role(n_h_role), title(n_title), group(n_group) { } ClassHint::~ClassHint(void) { } ClassHint& ClassHint::operator=(const ClassHint& rhs) { h_name = rhs.h_name; h_class = rhs.h_class; h_role = rhs.h_role; title = rhs.title; group = rhs.group; return *this; } bool ClassHint::operator==(const ClassHint& rhs) const { if (group.size() > 0) { if (group == rhs.group) { return true; } } else if ((h_name == rhs.h_name) && (h_class == rhs.h_class) && (h_role == rhs.h_role)) { return true; } return false; } const long Client::_clientEventMask = \ PropertyChangeMask|StructureNotifyMask|FocusChangeMask|KeyPressMask; std::vector Client::_clients; std::vector Client::_clientids; Client::Client(Window new_client, ClientInitConfig &initConfig, bool is_new) : PWinObj(true), _id(0), _size(0), _transient_for(nullptr), _strut(nullptr), _icon(nullptr), _pid(0), _is_remote(false), _window_type(WINDOW_TYPE_NORMAL), _alive(false), _marked(false), _send_focus_message(false), _send_close_message(false), _wm_hints_input(true), _cfg_request_lock(false), _extended_net_name(false) { // PWinObj attributes, required by validate etc. _window = new_client; _type = WO_CLIENT; // Construct the client X11::grabServer(); if (! validate() || ! getAndUpdateWindowAttributes()) { X11::ungrabServer(true); return; } // Get unique Client id _id = findClientID(); _title.setId(_id); _title.infoAdd(PDecor::TitleItem::INFO_ID); if (X11::hasExtensionShape()) { X11::shapeSelectInput(_window, ShapeNotifyMask); int isShaped; X11::shapeQuery(_window, &isShaped); _shape_bounding = isShaped; } X11::saveSetAdd(_window); XSetWindowBorderWidth(X11::getDpy(), _window, 0); // Load the Class hint before loading the autoprops and // getting client title as we search for TitleRule in the autoprops readClassRoleHints(); getWMNormalHints(); readName(); // cyclic dependency, getting the name requires quiering autoprops _class_hint.title = _title.getReal(); // Get Autoproperties before EWMH as we need the cfg_deny // property, however the _transient hint needs to be setup to // avoid auto-grouping to be to greedy. getTransientForHint(); AutoProperty *ap = readAutoprops(pekwm::isStarting() ? APPLY_ON_START : APPLY_ON_NEW); readHints(); // We need to set the state before acquiring a frame, // so that Frame's state can match the state of the Client. setInitialState(); initConfig.parent_is_new = findOrCreateFrame(ap); // Grab keybindings and mousebutton actions pekwm::keyGrabber()->grabKeys(_window); grabButtons(); updateEwmhStates(); X11::ungrabServer(true); setClientInitConfig(initConfig, is_new, ap); _alive = true; findAndRaiseIfTransient(); // Finished creating the client, so now adding it to the client list. woListAdd(this); _wo_map[_window] = this; _clients.push_back(this); P_TRACE(this << " client " << _title.getReal() << " constructed for " << "window " << FMT_HEX(_window)); } //! @brief Client destructor Client::~Client(void) { while (! _transients.empty()) { _transients[0]->setTransientFor(nullptr); } setTransientFor(nullptr); _wo_map.erase(_window); woListRemove(this); _clients.erase(std::remove(_clients.begin(), _clients.end(), this), _clients.end()); returnClientID(_id); X11::grabServer(); // removes gravity and moves it back to root if we are alive bool focus = false; if (_parent && (_parent->getType() == PWinObj::WO_FRAME)) { focus = _parent->isFocused(); static_cast(_parent)->removeChild(this); } // Focus the parent if we had focus before if (focus && _transient_for) { Frame *trans_frame = static_cast(_transient_for->getParent()); if (trans_frame->getActiveChild() == _transient_for) { // Do not use Workspaces::giveInputFocus here to avoid // pointer warping when returning the focus to the // parent window trans_frame->giveInputFocus(); } } // Clean up if the client still is alive, it'll be dead all times // except when we exit pekwm if (_alive) { X11::ungrabButton(AnyButton, AnyModifier, _window); pekwm::keyGrabber()->ungrabKeys(_window); PWinObj::mapWindow(); } X11::saveSetRemove(_window); // free names and size hint if (_size) { X11::free(_size); } removeStrutHint(); if (_icon) { PTexture *icon = _icon; pekwm::textureHandler()->returnTexture(&icon); } X11::ungrabServer(true); P_TRACE(this << " client for window " << FMT_HEX(_window) << " destructed"); } /** * Read basic window attributes including geometry and update the * window attributes being listened to. Returns false if the client * disappears during the check. */ bool Client::getAndUpdateWindowAttributes(void) { XWindowAttributes attr; if (! XGetWindowAttributes(X11::getDpy(), _window, &attr)) { return false; } _gm.x = attr.x; _gm.y = attr.y; _gm.width = attr.width; _gm.height = attr.height; _cmap = attr.colormap; _size = XAllocSizeHints(); XSetWindowAttributes sattr; sattr.event_mask = PropertyChangeMask|StructureNotifyMask|FocusChangeMask; sattr.do_not_propagate_mask = ButtonPressMask|ButtonReleaseMask|ButtonMotionMask; // We don't want these masks to be propagated down to the frame X11::changeWindowAttributes(_window, CWEventMask|CWDontPropagate, sattr); return true; } /** * Find frame for client based on tagging, hints and * autoproperties. Create a new one if not found and add the client. * * \return true if a new find was created. */ bool Client::findOrCreateFrame(AutoProperty *autoproperty) { bool parent_is_new = false; if (! _parent) { _parent = findTaggedFrame(); if (! _parent) { _parent = findPreviousFrame(); } } // Apply Autoproperties again to override EWMH state. It's done twice as // we need the cfg_deny property when reading the EWMH state. if (autoproperty != 0) { applyAutoprops(autoproperty); if (! _parent) { findAutoGroupFrame(autoproperty); } } // if we don't have a frame already, create a new one if (! _parent) { parent_is_new = true; _parent = new Frame(this, autoproperty); } return parent_is_new; } /** * Find from client from for the currently tagged client. */ PWinObj* Client::findTaggedFrame(void) { if (pekwm::isStarting()) { return nullptr; } // Check for tagged frame Frame *frame = Frame::getTagFrame(); if (frame && frame->isMapped()) { frame->addChild(this); if (! Frame::getTagBehind()) { frame->activateChild(this); } } return frame; } /** * Find frame for client on PEKWM_FRAME_ID hint. */ PWinObj* Client::findPreviousFrame(void) { if (! pekwm::isStarting()) { return nullptr; } Cardinal id; if (X11::getCardinal(_window, PEKWM_FRAME_ID, id)) { Frame *frame = Frame::findFrameFromID(id); if (frame) { frame->addChildOrdered(this); if (getPekwmFrameActive()) { frame->activateChild(this); } } return frame; } return nullptr; } /** * Find frame for client based on autoproperties. */ bool Client::findAutoGroupFrame(AutoProperty *autoproperty) { if (autoproperty->group_size < 0) { return false; } Frame *frame = ClientMgr::findGroup(autoproperty); if (frame) { frame->addChild(this); if (! autoproperty->group_behind) { frame->activateChild(this); } if (autoproperty->group_raise) { frame->raise(); } } return _parent != 0; } /** * Get the client state and set iconified and mapped flags. */ void Client::setInitialState(void) { // Set state either specified in hint ulong initial_state = getWMHints(); if (getWmState() == IconicState) { _iconified = true; } if (_iconified || initial_state == IconicState) { _iconified = true; _mapped = true; unmapWindow(); } else { setWmState(initial_state); } } /** * Ensure the Client is (un) mapped and give input focus if requested. */ void Client::setClientInitConfig(ClientInitConfig &initConfig, bool is_new, AutoProperty *prop) { initConfig.map = (! _iconified && _parent->isMapped()); initConfig.focus = false; if (is_new && _parent->isMapped()) { initConfig.focus = initFocus(prop); } } bool Client::initFocus(AutoProperty *prop) { bool focus = pekwm::config()->isFocusNew(); // focus client, even if not focusing new clients, if it is transient // for the currently focused window. if (! focus && _transient_for) { focus = _transient_for->isFocused() && pekwm::config()->isFocusNewChild(); } Cardinal init_time; if (X11::getCardinal(_window, NET_WM_USER_TIME, init_time) && init_time == 0) { // Setting _NET_WM_USER_TIME to 0 indicates that the window // should not be given input focus. P_TRACE(_window << " _NET_WM_USER_TIME set to 0, not giving " "input focus on create"); focus = false; } // overwrite focus if set in the auto property if (prop && prop->isMask(AP_FOCUS_NEW)) { P_TRACE(_window << " overriding focus " << focus << " with " " property focus " << prop->focus_new); focus = prop->focus_new; } return focus; } /** * Re-lookup transient client if window is set but not client, raise over * transient for window if found/set. */ void Client::findAndRaiseIfTransient(void) { if (_transient_for_window != None && ! _transient_for) { getTransientForHint(); } if (_transient_for) { // Ensure layer is at least as high as the parent if (_transient_for->getLayer() > getLayer()) { setLayer(_transient_for->getLayer()); updateParentLayerAndRaiseIfActive(); } } } // START - PWinObj interface. /** * Map client window and update window manager hints. */ void Client::mapWindow(void) { if (_mapped) { return; } if (_iconified) { _iconified = false; setWmState(NormalState); updateEwmhStates(); } if(! _transient_for) { mapOrUnmapTransients(_window, false); } X11::selectInput(_window, NoEventMask); PWinObj::mapWindow(); X11::selectInput(_window, _clientEventMask); } /** * Unmap client window and update window manager hints. */ void Client::unmapWindow() { if (! _mapped) { return; } if (_iconified) { setWmState(IconicState); updateEwmhStates(); } X11::selectInput(_window, NoEventMask); PWinObj::unmapWindow(); X11::selectInput(_window, _clientEventMask); } //! @brief Iconifies the client and adds it to the iconmenu void Client::iconify(void) { if (_iconified) { return; } _iconified = true; if (! _transient_for) { mapOrUnmapTransients(_window, true); } unmapWindow(); } /** * Toggle sticky state. */ void Client::toggleSticky() { PWinObj::toggleSticky(); updateEwmhStates(); } //! @brief Update the position variables. void Client::move(int x, int y) { bool request = ((_gm.x != x) || (_gm.y != y)); _gm.x = x; _gm.y = y; if (request) { configureRequestSend(); } } //! @brief Resizes the client window to specified size. void Client::resize(uint width, uint height) { bool request = ((_gm.width != width) || (_gm.height != height)); PWinObj::resize(width, height); if (request) { configureRequestSend(); } } //! @brief Move and resizes the client window to specified size. void Client::moveResize(int x, int y, uint width, uint height) { bool request = ((_gm.x != x) || (_gm.y != y) || (_gm.width != width) || (_gm.height != height)); _gm.x = x; _gm.y = y; PWinObj::resize(width, height); if (request) { configureRequestSend(); } } //! @brief Sets the workspace and updates the _NET_WM_DESKTOP hint. void Client::setWorkspace(uint workspace) { if (workspace != NET_WM_STICKY_WINDOW) { if (workspace >= Workspaces::size()) { workspace = Workspaces::size() - 1; } _workspace = workspace; Cardinal ws_card = _sticky ? NET_WM_STICKY_WINDOW : _workspace; X11::setCardinal(_window, NET_WM_DESKTOP, ws_card); } } /** * Give input focus to client (if _wm_hints_input is true) and clears demands * attention if set. */ void Client::giveInputFocus() { Frame *frame; if (demandsAttention() && (frame = static_cast(_parent))) { setDemandsAttention(false); frame->decrAttention(); } if (_wm_hints_input) { PWinObj::giveInputFocus(); } sendTakeFocusMessage(); } void Client::warpPointer() { Frame *frame = static_cast(_parent); if (frame) { frame->warpPointer(); } else { PWinObj::warpPointer(); } } //! @brief Reparents and sets _parent member, filtering unmap events void Client::reparent(PWinObj *parent, int x, int y) { X11::selectInput(_window, NoEventMask); PWinObj::reparent(parent, x, y); _gm.x = parent->getX() + x; _gm.y = parent->getY() + y; X11::selectInput(_window, PropertyChangeMask|StructureNotifyMask| FocusChangeMask); } const ActionEvent* Client::handleMapRequest(XMapRequestEvent *ev) { if (_parent && dynamic_cast(_parent)) { dynamic_cast(_parent)->deiconify(); } return 0; } const ActionEvent* Client::handleUnmapEvent(XUnmapEvent *ev) { if ((ev->window != ev->event) && (ev->send_event != true)) { return 0; } // The window might not exist any more, so just ignore the errors. setXErrorsIgnore(true); // ICCCM 4.1.4 advices the window manager to trigger the transition to // Withdrawn state on real and synthetic UnmapNotify events. setWmState(WithdrawnState); // Extended Window Manager Hints 1.3 specifies that a window manager // should remove the _NET_WM_STATE property when a window is withdrawn. X11::unsetProperty(_window, STATE); // Extended Window Manager Hints 1.3 specifies that a window manager // should remove the _NET_WM_DESKTOP property when a window is // withdrawn. (to allow legacy applications to reuse a withdrawn // window) X11::unsetProperty(_window, NET_WM_DESKTOP); _alive = false; delete this; setXErrorsIgnore(false); return 0; } // END - PWinObj interface. #ifdef PEKWM_HAVE_SHAPE void Client::handleShapeEvent(XShapeEvent *ev) { if (ev->kind == ShapeBounding) { _shape_bounding = ev->shaped; } else { return; } if (_parent) { static_cast(_parent)->handleShapeEvent(ev); } } #endif // PEKWM_HAVE_SHAPE // START - Observer interface void Client::notify(Observable *observable, Observation *observation) { LayerObservation* layer_observation = dynamic_cast(observation); if (layer_observation && layer_observation->layer > getLayer()) { setLayer(layer_observation->layer); updateParentLayerAndRaiseIfActive(); } } // END - Observer interface //! @brief Finds the Client which holds the Window w. //! @param win Window to search for. //! @return Pointer to the client if found, else 0 Client* Client::findClient(Window win) { // Validate input window. if ((win == None) || (win == X11::getRoot())) { return 0; } client_it it = _clients.begin(); for (; it != _clients.end(); ++it) { if (win == (*it)->getWindow() || ((*it)->getParent() && (*((*it)->getParent()) == win))) { return *it; } } return nullptr; } //! @brief Finds the Client of Window win. //! @param win Window to search for. Client* Client::findClientFromWindow(Window win) { // Validate input window. if (! win || win == X11::getRoot()) { return 0; } client_it it = _clients.begin(); for (; it != _clients.end(); ++it) { if (win == (*it)->getWindow()) { return *it; } } return nullptr; } //! @brief Finds Client with id. //! @param id ID to search for. //! @return Client if found, else 0. Client* Client::findClientFromID(uint id) { client_it it = _clients.begin(); for (; it != _clients.end(); ++it) { if ((*it)->getClientID() == id) { return *it; } } return nullptr; } /** * Insert all clients with the transient for set to win. */ void Client::findFamilyFromWindow(std::vector &client_list, Window win) { client_it it = _clients.begin(); for (; it != _clients.end(); ++it) { if ((*it)->getTransientForClientWindow() == win) { client_list.push_back(*it); } } } /** * (Un)Maps all windows having transient_for set to win */ void Client::mapOrUnmapTransients(Window win, bool hide) { std::vector client_list; findFamilyFromWindow(client_list, win); client_it it = client_list.begin(); for (; it != client_list.end(); ++it) { PWinObj* parent = (*it)->getParent(); if (static_cast(parent)->getActiveChild() == *it) { if (hide) { (*it)->getParent()->iconify(); } else { (*it)->getParent()->mapWindow(); } } } } /** * Checks if the window has any Destroy or Unmap notifys. */ bool Client::validate(void) { X11::sync(False); XEvent ev; if (X11::checkTypedWindowEvent(_window, DestroyNotify, &ev) || X11::checkTypedWindowEvent(_window, UnmapNotify, &ev)) { XPutBackEvent(X11::getDpy(), &ev); return false; } return true; } //! @brief Checks if the window has attribute IsViewable set bool Client::isViewable(void) { XWindowAttributes attr; XGetWindowAttributes(X11::getDpy(), _window, &attr); return (attr.map_state == IsViewable); } /** * Grab all mouse button actions on the client excluding the events * without a modifier. */ void Client::grabButtons(void) { // make sure all previous grabs are removed X11::ungrabButton(AnyButton, AnyModifier, _window); Config *cfg = pekwm::config(); std::vector *actions = cfg->getMouseActionList(MOUSE_ACTION_LIST_CHILD_FRAME); std::vector::iterator it = actions->begin(); const uint mask = ButtonPressMask|ButtonReleaseMask; for (; it != actions->end(); ++it) { if (it->isButtonEvent()) { // not grabbing actions without modifier, will be // grabbed by the Frame code and replied from there if (it->isAnyModifier()) { continue; } X11Util::grabButton(it->sym, it->mod, mask, _window, GrabModeAsync); } else if (it->type == MOUSE_EVENT_MOTION) { const uint motion_mask = mask|ButtonMotionMask; X11Util::grabButton(it->sym, it->mod, motion_mask, _window, GrabModeAsync); } } } //! @brief Sets CfgDeny state on Client void Client::setStateCfgDeny(StateAction sa, uint deny) { if (! ActionUtil::needToggle(sa, _state.cfg_deny&deny)) { return; } if (_state.cfg_deny&deny) { _state.cfg_deny &= ~deny; } else { _state.cfg_deny |= deny; } } /** * Read "all" hints required during creation of Client. */ void Client::readHints(void) { readMwmHints(); readEwmhHints(); readPekwmHints(); readIcon(); readClientPid(); readClientRemote(); getWMProtocols(); } /** * Read the WM_CLASS hint and set information on the _class_hint used * in matching auto properties. */ void Client::readClassRoleHints(void) { // class hint X11::ClassHint class_hint; if (X11::getClassHint(_window, class_hint)) { _class_hint.h_name = class_hint.getName(); _class_hint.h_class = class_hint.getClass(); } // wm window role std::string role; X11::getString(_window, WM_WINDOW_ROLE, role); _class_hint.h_role = role; } //! @brief Loads the Clients state from EWMH atoms. void Client::readEwmhHints(void) { // which workspace do we belong to? Cardinal workspace = -1; X11::getCardinal(_window, NET_WM_DESKTOP, workspace); if (workspace < 0) { _workspace = Workspaces::getActive(); X11::setCardinal(_window, NET_WM_DESKTOP, _workspace); } else { _workspace = workspace; } updateWinType(true); // Apply autoproperties for window type AutoProperty *auto_property = pekwm::autoProperties()->findWindowTypeProperty(_window_type); if (auto_property) { applyAutoprops(auto_property); } // The _NET_WM_STATE overrides the _NET_WM_TYPE NetWMStates win_states; if (X11Util::readEwmhStates(_window, win_states)) { if (win_states.hidden && ! isCfgDeny(CFG_DENY_STATE_HIDDEN)) { _iconified = true; } if (win_states.shaded) _state.shaded = true; if (win_states.max_vert && ! isCfgDeny(CFG_DENY_STATE_MAXIMIZED_VERT)) { _state.maximized_vert = true; } if (win_states.max_horz && ! isCfgDeny(CFG_DENY_STATE_MAXIMIZED_HORZ)) { _state.maximized_horz = true; } if (win_states.skip_taskbar) _state.skip |= SKIP_TASKBAR; if (win_states.skip_pager) _state.skip |= SKIP_PAGER; if (win_states.sticky) _sticky = true; if (win_states.above && ! isCfgDeny(CFG_DENY_STATE_ABOVE)) { setLayer(LAYER_ABOVE_DOCK); } if (win_states.below && ! isCfgDeny(CFG_DENY_STATE_BELOW)) { setLayer(LAYER_BELOW); } if (win_states.fullscreen && ! isCfgDeny(CFG_DENY_STATE_FULLSCREEN)) { _state.fullscreen = true; } _state.demands_attention = win_states.demands_attention; } readStrutHint(); } /** * Loads the Clients state from MWM atoms. */ void Client::readMwmHints(void) { MwmHints mwm_hints; if (! X11Util::readMwmHints(_window, mwm_hints)) { return; } if (mwm_hints.flags&MWM_HINTS_FUNCTIONS) { bool state = ! (mwm_hints.functions&MWM_FUNC_ALL); #define IS_MWM_FUNC(flag) (mwm_hints.functions&(flag)) ? state : !state; _actions.resize = IS_MWM_FUNC(MWM_FUNC_RESIZE); _actions.move = IS_MWM_FUNC(MWM_FUNC_MOVE); _actions.iconify = IS_MWM_FUNC(MWM_FUNC_ICONIFY); _actions.close = IS_MWM_FUNC(MWM_FUNC_CLOSE); _actions.maximize_vert = IS_MWM_FUNC(MWM_FUNC_MAXIMIZE); _actions.maximize_horz = IS_MWM_FUNC(MWM_FUNC_MAXIMIZE); #undef IS_MWM_FUNC } // Check decoration flags if (mwm_hints.flags & MWM_HINTS_DECORATIONS) { if (mwm_hints.decorations & MWM_DECOR_ALL) { setTitlebar(true); setBorder(true); } else { if (! (mwm_hints.decorations & MWM_DECOR_TITLE)) { setTitlebar(false); } if (! (mwm_hints.decorations & MWM_DECOR_BORDER)) { setBorder(false); } // Do not handle HANDLE, MENU, ICONFIY or MAXIMIZE. // Maybe one should set the allowed actions for the // client based on this but that might be annoying so // ignoring these. } } } //! @brief Reads non-standard pekwm hints void Client::readPekwmHints(void) { Cardinal value; std::string str; // Get decor state if (X11::getCardinal(_window, PEKWM_FRAME_DECOR, value)) { _state.decor = value; } // Get skip state if (X11::getCardinal(_window, PEKWM_FRAME_SKIP, value)) { _state.skip = value; } // Get custom title if (X11::getUtf8String(_window, PEKWM_TITLE, str)) { _title.setUser(str); } _state.initial_frame_order = getPekwmFrameOrder(); } /** * Read _NET_WM_ICON from client window. */ void Client::readIcon(void) { PImage *image = PImageIcon::newFromWindow(_window); if (image) { if (_icon) { _icon->setImage(image); } else { _icon = new PTextureImage(image); pekwm::textureHandler()->referenceTexture(_icon); } } else { delete image; if (_icon) { PTexture *icon = _icon; pekwm::textureHandler()->returnTexture(&icon); } } } /** * Match current client against list of autoproperties. * * @param type Match type, defaults to APPLY_ON_ALWAYS. * @return AutoProperty if any is found, else nullptr. */ AutoProperty* Client::readAutoprops(ApplyOn type) { AutoProperties *aps = pekwm::autoProperties(); AutoProperty *property = aps->findAutoProperty(_class_hint, Workspaces::getActive(), type); if (property) { P_DBG("auto property found for client " << _class_hint); // Make sure transient state matches if (isTransient() ? property->isApplyOn( APPLY_ON_TRANSIENT|APPLY_ON_TRANSIENT_ONLY) : ! property->isApplyOn(APPLY_ON_TRANSIENT_ONLY)) { applyAutoprops(property); } else { property = nullptr; } } else { P_DBG("no auto property found for client " << _class_hint); } return property; } //! @brief Applies AutoPropery to this Client. void Client::applyAutoprops(AutoProperty *ap) { // Set the correct group of the window _class_hint.group = ap->group_name; // We only apply grouping if it's a new client or if we are restarting // and have APPLY_ON_START set if (ap->isMask(AP_STICKY)) { _sticky = ap->sticky; } if (ap->isMask(AP_SHADED)) { _state.shaded = ap->shaded; } if (ap->isMask(AP_MAXIMIZED_VERTICAL)) { _state.maximized_vert = ap->maximized_vertical; } if (ap->isMask(AP_MAXIMIZED_HORIZONTAL)) { _state.maximized_horz = ap->maximized_horizontal; } if (ap->isMask(AP_FULLSCREEN)) { _state.fullscreen = ap->fullscreen; } if (ap->isMask(AP_ICONIFIED)) { _iconified = ap->iconified; } if (ap->isMask(AP_TITLEBAR)) { setTitlebar(ap->titlebar); } if (ap->isMask(AP_BORDER)) { setBorder(ap->border); } if (ap->isMask(AP_LAYER) && (ap->layer <= LAYER_MENU)) { setLayer(ap->layer); } if (ap->isMask(AP_SKIP)) { _state.skip = ap->skip; } if (ap->isMask(AP_FOCUSABLE)) { _focusable = ap->focusable; } if (ap->isMask(AP_WORKSPACE)) { _workspace = ap->workspace; } if (ap->isMask(AP_CFG_DENY)) { _state.cfg_deny = ap->cfg_deny; } if (ap->isMask(AP_ALLOWED_ACTIONS)) { applyActionAccessMask(ap->allowed_actions, true); } if (ap->isMask(AP_DISALLOWED_ACTIONS)) { applyActionAccessMask(ap->disallowed_actions, false); } if (ap->isMask(AP_OPACITY)) { setOpacity(ap->focus_opacity, ap->unfocus_opacity); } if (ap->isMask(AP_ICON)) { P_TRACE("set _NET_WM_ICON on " << _window); ap->icon->setOnWindow(_window); } } void Client::applyActionAccessMask(uint mask, bool value) { if (mask & ACTION_ACCESS_MOVE) { _actions.move = value; } if (mask & ACTION_ACCESS_RESIZE) { _actions.resize = value; } if (mask & ACTION_ACCESS_ICONIFY) { _actions.iconify = value; } if (mask & ACTION_ACCESS_SHADE) { _actions.shade = value; } if (mask & ACTION_ACCESS_STICK) { _actions.stick = value; } if (mask & ACTION_ACCESS_MAXIMIZE_HORZ) { _actions.maximize_horz = value; } if (mask & ACTION_ACCESS_MAXIMIZE_VERT) { _actions.maximize_vert = value; } if (mask & ACTION_ACCESS_FULLSCREEN) { _actions.fullscreen = value; } if (mask & ACTION_ACCESS_CHANGE_DESKTOP) { _actions.change_ws = value; } if (mask & ACTION_ACCESS_CLOSE) { _actions.close = value; } } /** * Read _NET_WM_PID. */ void Client::readClientPid(void) { X11::getCardinal(_window, NET_WM_PID, _pid); } /** * Read WM_CLIENT_MACHINE and check against local hostname and set * _is_remote if it does not match. */ void Client::readClientRemote(void) { std::string client_machine; if (X11::getTextProperty(_window, XA_WM_CLIENT_MACHINE, client_machine)) { _is_remote = Util::getHostname() != client_machine; } } //! @brief Finds free Client ID. //! @return First free Client ID. uint Client::findClientID(void) { uint id = 0; if (_clientids.size()) { // Check for used Frame IDs id = _clientids.back(); _clientids.pop_back(); } else { // No free, get next number (Client is not in list when this is // called.) id = _clients.size() + 1; } return id; } //! @brief Returns Client ID to used client id list. //! @param id ID to return. void Client::returnClientID(uint id) { std::vector::iterator it = _clientids.begin(); for (; it != _clientids.end() && id < *it; ++it) ; _clientids.insert(it, id); } /** * Tries to get the NET_WM name, else fall back to WM_NAME */ void Client::readName(void) { // Read title, bail out if it fails. std::string title; if (! X11::getUtf8String(_window, NET_WM_NAME, title) && ! X11::getTextProperty(_window, XA_WM_NAME, title)) { return; } // Mirror it on the visible _title.setCustom(""); _title.setCount(titleFindID(title)); _title.setReal(title); // Apply title rules and find unique name, doesn't apply on // user-set titles if (titleApplyRule(title)) { _title.setCustom(title); X11::setUtf8String(_window, NET_WM_VISIBLE_NAME, title); } else { X11::unsetProperty(_window, NET_WM_VISIBLE_NAME); } } //! @brief Searches for an TitleRule and if found, applies it //! @param title Title to apply rule on. //! @return true if rule was applied, else false. bool Client::titleApplyRule(std::string &title) { _class_hint.title = title; TitleProperty *data = pekwm::autoProperties()->findTitleProperty(_class_hint); if (data) { return data->getTitleRule().ed_s(title); } else { return false; } } //! @brief Searches for a unique ID within Clients having the same title //! @param title Title of client to find ID for. //! @return Number of clients with that id. uint Client::titleFindID(const std::string &title) { // Do not search for unique IDs if it is not enabled. if (! pekwm::config()->getClientUniqueName()) { return 0; } uint id_found = 0; std::vector ids_used; client_it it = _clients.begin(); for (; it != _clients.end(); ++it) { if (*it != this) { if ((*it)->getTitle()->getReal() == title) { int count = (*it)->getTitle()->getCount(); ids_used.push_back(count); } } } // more than one client having this name if (ids_used.size() > 0) { std::sort(ids_used.begin(), ids_used.end()); std::vector::iterator ui_it(ids_used.begin()); for (uint i = 0; ui_it != ids_used.end(); ++i, ++ui_it) { if (i < *ui_it) { id_found = i; break; } } if (ui_it == ids_used.end()) { id_found = ids_used.size(); } } return id_found; } //! @brief Sets the WM_STATE of the client to state //! @param state State to set. void Client::setWmState(ulong state) { ulong data[2]; data[0] = state; data[1] = None; // No Icon X11::changeProperty(_window, X11::getAtom(WM_STATE), X11::getAtom(WM_STATE), 32, PropModeReplace, reinterpret_cast(data), 2); } // If we can't find a wm_state we're going to have to assume // Withdrawn. This is not exactly optimal, since we can't really // distinguish between the case where no WM has run yet and when the // state was explicitly removed (Clients are allowed to either set the // atom to Withdrawn or just remove it... yuck.) long Client::getWmState(void) { Atom real_type; int real_format; long state = WithdrawnState; ulong items_read, items_left; uchar *udata; int status = XGetWindowProperty(X11::getDpy(), _window, X11::getAtom(WM_STATE), 0L, 2L, False, X11::getAtom(WM_STATE), &real_type, &real_format, &items_read, &items_left, &udata); if ((status == Success) && items_read) { long *data = reinterpret_cast(udata); state = *data; X11::free(udata); } return state; } //! @brief Send XConfigureEvent, letting the client know about changes void Client::configureRequestSend(void) { if (_cfg_request_lock) { return; } XConfigureEvent e; e.type = ConfigureNotify; e.event = _window; e.window = _window; e.x = _gm.x; e.y = _gm.y; e.width = _gm.width; e.height = _gm.height; e.border_width = 0; e.above = None; e.override_redirect = False; X11::sendEvent(_window, False, StructureNotifyMask, reinterpret_cast(&e)); } //! @brief Send a TAKE_FOCUS client message to the client (if requested by it). void Client::sendTakeFocusMessage(void) { if (! _send_focus_message) { return; } XEvent ev; X11::changeProperty(X11::getRoot(), XA_PRIMARY, XA_STRING, 8, PropModeAppend, 0, 0); XWindowEvent(X11::getDpy(), X11::getRoot(), PropertyChangeMask, &ev); X11::setLastEventTime(ev.xproperty.time); X11::sendEvent(_window, _window, X11::getAtom(WM_PROTOCOLS), NoEventMask, X11::getAtom(WM_TAKE_FOCUS), X11::getLastEventTime()); } /** * Toggles the clients always on top state */ void Client::alwaysOnTop(bool top) { setLayer(top ? LAYER_ONTOP : LAYER_NORMAL); updateEwmhStates(); } /** * Toggles the clients always below state. */ void Client::alwaysBelow(bool below) { setLayer(below ? LAYER_BELOW : LAYER_NORMAL); updateEwmhStates(); } //! @brief Sets the skip state, and updates the _PEKWM_FRAME_SKIP atom void Client::setSkip(uint skip) { _state.skip = skip; X11::setCardinal(_window, PEKWM_FRAME_SKIP, _state.skip); } std::string Client::getAPDecorName() { AutoProperties *props = pekwm::autoProperties(); AutoProperty *ap = props->findAutoProperty(getClassHint()); if (ap && ap->isMask(AP_DECOR)) { return ap->frame_decor; } ap = props->findWindowTypeProperty(getWinType()); if (ap && ap->isMask(AP_DECOR)) { return ap->frame_decor; } DecorProperty *dp = props->findDecorProperty(getClassHint()); if (dp) { return dp->getName(); } return ""; } //! @brief Sends an WM_DELETE message to the client, else kills it. void Client::close(void) { // Check for DisallowedActions="Close". if (! allowClose()) { return; } if (_send_close_message) { X11::sendEvent(_window, _window, X11::getAtom(WM_PROTOCOLS), NoEventMask, X11::getAtom(WM_DELETE_WINDOW), CurrentTime); } else { kill(); } } //! @brief Kills the client using XKillClient void Client::kill(void) { XKillClient(X11::getDpy(), _window); } /** * Get the closest size confirming to the PAspect and PResizeInc. * * @param r_w Pointer to put the new width in * @param r_h Pointer to put the new height in * @param w Width to calculate from * @param h Height to calculate from * @return true if width/height have changed */ bool Client::getAspectSize(uint *r_w, uint *r_h, uint w, uint h) { XSizeHints size = getActiveSizeHints(); // see ICCCM 4.1.2.3 for PAspect and {min,max}_aspect bool incr; if (size.flags & PAspect && pekwm::config()->isHonourAspectRatio()) { // shorthand const uint amin_x = size.min_aspect.x; const uint amin_y = size.min_aspect.y; const uint amax_x = size.max_aspect.x; const uint amax_y = size.max_aspect.y; uint base_w = 0, base_h = 0; // If PBaseSize is specified, base_{width,height} should be // subtracted before checking the aspect ratio // (c.f. ICCCM). The additional checks avoid underflows in w // and h. Keep in mind that size.base_{width,height} are // guaranteed to be non-negative by getWMNormalHints(). if (size.flags & PBaseSize) { if (static_cast(size.base_width) < w) { base_w = size.base_width; w -= base_w; } if (static_cast(size.base_height) < h) { base_h = size.base_height; h -= base_h; } } double tmp; // Ensure: min_aspect.x/min_aspect.y <= w/h <= // max_aspect.x/max_aspect.y if (w * amin_y < h * amin_x) { tmp = ((double)(w * amin_x + h * amin_y)) / ((double)(amin_x * amin_x + amin_y * amin_y)); w = static_cast(amin_x * tmp) + base_w; h = static_cast(amin_y * tmp) + base_h; } else if (w * amax_y > amax_x * h) { tmp = ((double)(w * amax_x + h * amax_y)) / ((double)(amax_x * amax_x + amax_y * amax_y)); w = static_cast(amax_x * tmp) + base_w; h = static_cast(amax_y * tmp) + base_h; } incr = false; } else { incr = true; } return getIncSize(size, r_w, r_h, w, h, incr); } /** * Get the size closest to the ResizeInc incrementer * * @param size Size hints to use for calculation. * @param r_w Pointer to put the new width in * @param r_h Pointer to put the new height in * @param w Width to calculate from * @param h Height to calculate from * @param incr Increase w, h to match increments if true, else decrease. */ bool Client::getIncSize(const XSizeHints& size, uint *r_w, uint *r_h, uint w, uint h, bool incr) { if (size.flags&PResizeInc) { uint basex = (size.flags&PBaseSize) ? size.base_width : (size.flags&PMinSize) ? size.min_width : 0; uint basey = (size.flags&PBaseSize) ? size.base_height : (size.flags&PMinSize) ? size.min_height : 0; if (w < basex || h < basey) { basex=basey=0; } uint dw = (w - basex) % size.width_inc; uint dh = (h - basey) % size.height_inc; *r_w = w - dw + ((incr && dw)?size.width_inc:0); *r_h = h - dh + ((incr && dh)?size.height_inc:0); return true; } *r_w = w; *r_h = h; return false; } // This happens when a window is iconified and destroys itself. An // Unmap event wouldn't happen in that case because the window is // already unmapped. void Client::handleDestroyEvent(XDestroyWindowEvent *e) { _alive = false; delete this; } void Client::handleColormapChange(XColormapEvent *e) { if (e->c_new) { _cmap = e->colormap; XInstallColormap(X11::getDpy(), _cmap); } } /** * Set _NET_WM_STATE based on the current state. */ void Client::updateEwmhStates() { std::vector states; #if 0 // modal state not supported if (false) { states.push_back(X11::getAtom(STATE_MODAL)); } #endif if (_sticky) { states.push_back(X11::getAtom(STATE_STICKY)); } if (_state.maximized_vert) { states.push_back(X11::getAtom(STATE_MAXIMIZED_VERT)); } if (_state.maximized_horz) { states.push_back(X11::getAtom(STATE_MAXIMIZED_HORZ)); } if (_state.shaded) { states.push_back(X11::getAtom(STATE_SHADED)); } if (isSkip(SKIP_TASKBAR)) { states.push_back(X11::getAtom(STATE_SKIP_TASKBAR)); } if (isSkip(SKIP_PAGER)) { states.push_back(X11::getAtom(STATE_SKIP_PAGER)); } if (_iconified) { states.push_back(X11::getAtom(STATE_HIDDEN)); } if (_state.fullscreen) { states.push_back(X11::getAtom(STATE_FULLSCREEN)); } if (getLayer() == LAYER_ABOVE_DOCK) { states.push_back(X11::getAtom(STATE_ABOVE)); } if (getLayer() == LAYER_BELOW) { states.push_back(X11::getAtom(STATE_BELOW)); } X11::setAtoms(_window, STATE, Container::type_data(states), states.size()); } void Client::updateWinType(bool set) { // try to figure out what kind of window we are and alter it // accordingly int items; void *data = X11::getEwmhPropData(_window, WINDOW_TYPE, XA_ATOM, items); if (data) { Atom *atoms = static_cast(data); _window_type = findWinType(atoms, items); X11::free(atoms); } else { _window_type = WINDOW_TYPE; } // Set window type to WINDOW_TYPE_NORMAL if it did not match if (_window_type == WINDOW_TYPE) { _window_type = WINDOW_TYPE_NORMAL; if (set) { X11::setAtom(_window, WINDOW_TYPE, WINDOW_TYPE_NORMAL); } } } AtomName Client::findWinType(const Atom* atoms, int items) { for (int i = 0; i < items; ++i) { if (atoms[i] == X11::getAtom(WINDOW_TYPE_DESKTOP)) { return WINDOW_TYPE_DESKTOP; } else if (atoms[i] == X11::getAtom(WINDOW_TYPE_DOCK)) { return WINDOW_TYPE_DOCK; } else if (atoms[i] == X11::getAtom(WINDOW_TYPE_TOOLBAR)) { return WINDOW_TYPE_TOOLBAR; } else if (atoms[i] == X11::getAtom(WINDOW_TYPE_MENU)) { return WINDOW_TYPE_MENU; } else if (atoms[i] == X11::getAtom(WINDOW_TYPE_UTILITY)) { return WINDOW_TYPE_UTILITY; } else if (atoms[i] == X11::getAtom(WINDOW_TYPE_DIALOG)) { return WINDOW_TYPE_DIALOG; } else if (atoms[i] == X11::getAtom(WINDOW_TYPE_SPLASH)) { return WINDOW_TYPE_SPLASH; } else if (atoms[i] == X11::getAtom(WINDOW_TYPE_DROPDOWN_MENU)) { return WINDOW_TYPE_DROPDOWN_MENU; } else if (atoms[i] == X11::getAtom(WINDOW_TYPE_POPUP_MENU)) { return WINDOW_TYPE_POPUP_MENU; } else if (atoms[i] == X11::getAtom(WINDOW_TYPE_TOOLTIP)) { return WINDOW_TYPE_TOOLTIP; } else if (atoms[i] == X11::getAtom(WINDOW_TYPE_NOTIFICATION)) { return WINDOW_TYPE_NOTIFICATION; } else if (atoms[i] == X11::getAtom(WINDOW_TYPE_COMBO)) { return WINDOW_TYPE_COMBO; } else if (atoms[i] == X11::getAtom(WINDOW_TYPE_DND)) { return WINDOW_TYPE_DND; } else if (atoms[i] == X11::getAtom(WINDOW_TYPE_NORMAL)) { return WINDOW_TYPE_NORMAL; } } return WINDOW_TYPE; } /** * Read WM Hints, return the initial state of the window. */ ulong Client::getWMHints(void) { ulong initial_state = NormalState; XWMHints hints; if (X11::getWMHints(_window, hints)) { // get the input focus mode if (hints.flags&InputHint) { _wm_hints_input = hints.input; } // Get initial state of the window if (hints.flags&StateHint) { initial_state = hints.initial_state; } setDemandsAttention(hints.flags&XUrgencyHint); } return initial_state; } void Client::getWMNormalHints(void) { long dummy; XGetWMNormalHints(X11::getDpy(), _window, _size, &dummy); // let's do some sanity checking if (_size->flags&PBaseSize) { if (_size->base_width < 1 || _size->base_height < 1) { _size->base_width = _size->base_height = 0; _size->flags &= ~PBaseSize; } } if (_size->flags&PAspect) { if (_size->min_aspect.x < 1 || _size->min_aspect.y < 1 || _size->max_aspect.x < 1 || _size->max_aspect.y < 1) { _size->min_aspect.x = _size->min_aspect.y = 0; _size->max_aspect.x = _size->max_aspect.y = 0; _size->flags &= ~PAspect; } } if (_size->flags&PResizeInc) { if (_size->width_inc < 1 || _size->height_inc < 1) { _size->width_inc = 0; _size->height_inc = 0; _size->flags &= ~PResizeInc; } } if (_size->flags & PMaxSize) { if (_size->max_width < 1 || _size->max_height < 1 || ((_size->flags & PMinSize) && (_size->max_width < _size->min_width || _size->max_height < _size->min_height) )) { _size->max_width = 0; _size->max_height = 0; _size->flags &= ~PMaxSize; } } } void Client::getWMProtocols(void) { int count; Atom *protocols; if (! XGetWMProtocols(X11::getDpy(), _window, &protocols, &count)) { return; } for (int i = 0; i < count; ++i) { if (protocols[i] == X11::getAtom(WM_TAKE_FOCUS)) { _send_focus_message = true; } else if (protocols[i] == X11::getAtom(WM_DELETE_WINDOW)) { _send_close_message = true; } } X11::free(protocols); } /** * Read WM_TRANSIENT_FOR hint. */ void Client::getTransientForHint(void) { _transient_for_window = None; Client *transient_for = nullptr; XGetTransientForHint(X11::getDpy(), _window, &_transient_for_window); if (_transient_for_window != None) { if (_transient_for_window == _window) { P_ERR(this << " client set transient hint for itself"); _transient_for_window = None; } else { transient_for = findClientFromWindow(_transient_for_window); P_TRACE(this << " transient for " << _transient_for_window << " client " << transient_for); } } setTransientFor(transient_for); } void Client::setTransientFor(Client *transient_for) { if (_transient_for == transient_for) { return; } P_TRACE(this << " transient for changed from " << _transient_for << " to " << transient_for); if (_transient_for) { _transient_for->removeTransient(this); } if (transient_for) { transient_for->addTransient(this); } _transient_for = transient_for; } void Client::addTransient(Client *transient) { P_TRACE(this << " add transient: " << transient); assert(transient != this); _transients.push_back(transient); } void Client::removeTransient(Client *transient) { P_TRACE(this << " remove transient: " << transient); assert(transient != this); _transients.erase(std::remove(_transients.begin(), _transients.end(), transient), _transients.end()); } void Client::updateParentLayerAndRaiseIfActive(void) { Frame *frame = static_cast(getParent()); if (frame->getActiveChild() == this) { frame->setLayer(getLayer()); frame->raise(); } } /** Read the NET_WM_STRUT hint from the client window if any, adding it to the global list of struts if the client does not have Strut in it's CfgDeny. */ void Client::readStrutHint() { // Clear out old strut, well re-add if a new one is found. removeStrutHint(); int num = 0; void* data = X11::getEwmhPropData(_window, NET_WM_STRUT, XA_CARDINAL, num); if (data) { if (num == STRUT_SIZE) { long *l = static_cast(data); _strut = new Strut(l[STRUT_LEFT], l[STRUT_RIGHT], l[STRUT_TOP], l[STRUT_BOTTOM]); if (! isCfgDeny(CFG_DENY_STRUT)) { pekwm::rootWo()->addStrut(_strut); } } else { P_WARN("invalid _NET_WM_STRUT size, expected " << STRUT_SIZE << " got " << num); } X11::free(data); } } /** Free resources used by the clients strut hint if any and unregister it from the screen if Strut is not in it's CfgDeny. */ void Client::removeStrutHint(void) { if ( _strut) { if (! isCfgDeny(CFG_DENY_STRUT)) { pekwm::rootWo()->removeStrut(_strut); } delete _strut; _strut = nullptr; } } /** * Get _PEKWM_FRAME_ORDER hint from client, return < 0 on failure. */ long Client::getPekwmFrameOrder(void) { Cardinal num = -1; X11::getCardinal(_window, PEKWM_FRAME_ORDER, num); return num; } /** * Update _PEKWM_FRAME_ORDER hint on client window. */ void Client::setPekwmFrameOrder(long num) { X11::setCardinal(_window, PEKWM_FRAME_ORDER, num); } /** * Get _PEKWM_FRAME_ACTIVE hint from client window, return true if * client is treated as active. */ bool Client::getPekwmFrameActive(void) { Cardinal act = 0; return (X11::getCardinal(_window, PEKWM_FRAME_ACTIVE, act) && act == 1); } /** * Set _PEKWM_FRAME_ACTIVE hint on client window. */ void Client::setPekwmFrameActive(bool act) { X11::setCardinal(_window, PEKWM_FRAME_ACTIVE, act ? 1 : 0); } /** * Update the environment with CLIENT_PID and CLIENT_WINDOW. */ void Client::setClientEnvironment(Client *client) { if (client) { int client_pid = client->isRemote() ? -1 : client->getPid(); Util::setEnv("CLIENT_PID", std::to_string(client_pid)); Util::setEnv("CLIENT_WINDOW", std::to_string(client->getWindow())); } else { Util::setEnv("CLIENT_PID", ""); Util::setEnv("CLIENT_WINDOW", ""); } } pekwm-0.4.4/src/wm/CMakeLists.txt0000664000175000017500000000255615126136025012310 cmake_minimum_required(VERSION 3.10) set(wm_SOURCES ActionHandler.cc ActionMenu.cc AutoProperties.cc Completer.cc Client.cc ClientMgr.cc CmdDialog.cc Config.cc DockApp.cc FocusToggleEventHandler.cc Frame.cc FrameListMenu.cc Globals.cc GroupingDragEventHandler.cc Harbour.cc InputDialog.cc KeyGrabber.cc KeyboardMoveResizeEventHandler.cc ManagerWindows.cc MenuHandler.cc MoveEventHandler.cc PDecor.cc PMenu.cc ResizeEventHandler.cc StatusWindow.cc SearchDialog.cc ThemeGm.cc WORefMenu.cc WindowManager.cc WinLayouter.cc Workspaces.cc WorkspaceIndicator.cc WmUtil.cc) add_library(wm STATIC ${wm_SOURCES}) target_include_directories(wm PUBLIC ${common_INCLUDE_DIRS} ${PROJECT_BINARY_DIR}/src ${PROJECT_SOURCE_DIR}/src) add_executable(pekwm pekwm.cc ../pekwm_env.cc ../lib/Compat.cc) target_compile_definitions(pekwm PUBLIC PEKWM_SH="${SH}") target_include_directories(pekwm PUBLIC ${PROJECT_BINARY_DIR}/src ${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/src/lib) install(TARGETS pekwm DESTINATION bin) add_executable(pekwm_wm pekwm_wm.cc ../pekwm_env.cc) target_include_directories(pekwm_wm PUBLIC ${common_INCLUDE_DIRS}) target_link_libraries(pekwm_wm wm tk lib ${common_LIBRARIES}) install(TARGETS pekwm_wm DESTINATION bin) pekwm-0.4.4/src/wm/PDecor.cc0000664000175000017500000015263715126136025011241 // // PDecor.cc for pekwm // Copyright (C) 2021-2025 Claes Nästén // Copyright (C) 2004-2020 the pekwm development team // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include #include extern "C" { #include #include } #include "Charset.hh" #include "Compat.hh" #include "Config.hh" #include "Debug.hh" #include "PDecor.hh" #include "ActionHandler.hh" #include "ManagerWindows.hh" #include "StatusWindow.hh" #include "KeyGrabber.hh" #include "Workspaces.hh" #include "X11.hh" #include "tk/PFont.hh" #include "tk/PPixmapSurface.hh" #include "tk/PTexture.hh" #include "tk/PTexturePlain.hh" #include "tk/PWinObj.hh" #include "tk/Theme.hh" #include "tk/X11Util.hh" // PDecor::Button //! @brief PDecor::Button constructor PDecor::Button::Button(PWinObj *parent, Theme::PDecorButtonData *data, uint width, uint height) : PWinObj(true), _data(data), _state(BUTTON_STATE_UNFOCUSED), _left(_data->isLeft()) { _parent = parent; _gm.width = width; _gm.height = height; _window = X11::createWmWindow(_parent->getWindow(), -_gm.width, -_gm.height, _gm.width, _gm.height, InputOutput, EnterWindowMask|LeaveWindowMask); setState(_state); } //! @brief PDecor::Button destructor PDecor::Button::~Button(void) { X11::destroyWindow(_window); } //! @brief Searches the PDecorButtonData for an action matching ev const ActionEvent* PDecor::Button::findAction(XButtonEvent *ev) { std::vector::iterator it = _data->begin(); for (; it != _data->end(); ++it) { if (it->mod == ev->state && it->sym == ev->button) return &(*it); } return nullptr; } //! @brief Sets the state of the button void PDecor::Button::setState(ButtonState state) { if (state == BUTTON_STATE_NO) { return; } // Only update if we don't hoover, we want to be able to turn back if (state != BUTTON_STATE_HOVER) { _state = state; } PTexture *tex = _data->getTexture(state); if (tex) { tex->setBackground(_window, 0, 0, _gm.width, _gm.height); if (X11::hasExtensionShape() && _data->setShape()) { bool need_free; Pixmap shape = tex->getMask(0, 0, need_free); if (shape != None) { X11::shapeSetMask(_window, ShapeBounding, shape); if (need_free) { X11::freePixmap(shape); } } else { XRectangle rect = {0 /* x */, 0 /* y */, static_cast(_gm.width), static_cast(_gm.height)}; X11::shapeSetRect(_window, &rect); } } X11::clearWindow(_window); } } PDecor::TitleItem::TitleItem(void) : _count(0), _id(0), _info(0), _width(0) { } void PDecor::TitleItem::infoAdd(enum Info info) { _info |= info; } void PDecor::TitleItem::infoRemove(enum Info info) { _info &= ~info; } bool PDecor::TitleItem::infoIs(enum Info info) { return (_info&info); } //! @brief Update visible version of title void PDecor::TitleItem::updateVisible(void) { // Start with empty string _visible = ""; // Add client info to title if ((_info != 0) && ((_info != INFO_ID) || pekwm::config()->isShowClientID())) { _visible.append("["); if (infoIs(INFO_ID) && pekwm::config()->isShowClientID()) { _visible.append(std::to_string(_id)); } if (infoIs(INFO_MARKED)) { _visible.append("M"); } _visible.append("] "); } // Add title if (_user.size() > 0) { _visible.append(_user); } else if (_custom.size() > 0) { _visible.append(_custom); } else { _visible.append(_real); } // Add client number to title if (_count > 0) { _visible.append(pekwm::config()->getClientUniqueNamePre()); _visible.append(std::to_string(_count)); _visible.append(pekwm::config()->getClientUniqueNamePost()); } } // PDecor const std::string PDecor::DEFAULT_DECOR_NAME = "DEFAULT"; const std::string PDecor::DEFAULT_DECOR_NAME_BORDERLESS = "BORDERLESS"; const std::string PDecor::DEFAULT_DECOR_NAME_TITLEBARLESS = "TITLEBARLESS"; const std::string PDecor::DEFAULT_DECOR_NAME_ATTENTION = "ATTENTION"; std::vector PDecor::_pdecors; //! @brief PDecor constructor //! @param dpy Display //! @param decor_name String, if not DEFAULT_DECOR_NAME sets _decor_name_saved PDecor::PDecor(const Window child_window, bool override_redirect, bool init, const std::string &decor_name) : PWinObj(true), ThemeGm(nullptr), _decor_name(decor_name), _child(0), _button(0), _button_press_win(None), _decor_cfg_child_move_overloaded(false), _decor_cfg_bpr_replay_pointer(false), _decor_cfg_bpr_al_child(MOUSE_ACTION_LIST_CHILD_OTHER), _decor_cfg_bpr_al_title(MOUSE_ACTION_LIST_TITLE_OTHER), _data(nullptr), _fill_state(0), _edge_filled(NO_EDGE), _skip(0), _border(true), _titlebar(true), _shaded(false), _attention(0), _need_shape(false), _real_height(1), _title_wo(true), _title_active(0), _titles_left(0), _titles_right(1) { if (init) { this->init(child_window, override_redirect); } _pdecors.push_back(this); } void PDecor::init(Window child_window, bool override_redirect) { if (_decor_name.empty()) { _decor_name = getDecorName(); } if (_decor_name != PDecor::DEFAULT_DECOR_NAME) { _decor_name_saved = _decor_name; } setDataFromDecorName(_decor_name); CreateWindowParams window_params(override_redirect); createParentWindow(window_params, child_window); createTitle(window_params); createBorder(window_params); // sets buttons etc up loadDecor(); // map title and border windows X11::mapSubwindows(_window); } /** * Create window attributes */ void PDecor::createParentWindow(CreateWindowParams ¶ms, Window child_window) { params.mask = CWOverrideRedirect|CWEventMask|CWBorderPixel|CWBackPixel; params.depth = CopyFromParent; params.visual = CopyFromParent; params.attr.border_pixel = X11::getBlackPixel(); params.attr.background_pixel = X11::getBlackPixel(); if (child_window != None) { XWindowAttributes attr; if (X11::getWindowAttributes(child_window, attr) && 32 != X11::getDepth() && attr.depth == 32) { params.mask |= CWColormap; params.depth = attr.depth; params.visual = attr.visual; params.attr.colormap = XCreateColormap(X11::getDpy(), X11::getRoot(), params.visual, AllocNone); } } params.attr.event_mask = ButtonPressMask|ButtonReleaseMask| ButtonMotionMask|EnterWindowMask|SubstructureRedirectMask| SubstructureNotifyMask; _window = X11::createWindow(X11::getRoot(), _gm.x, _gm.y, _gm.width, _gm.height, 0, params.depth, InputOutput, params.visual, params.mask, ¶ms.attr); if (params.mask & CWColormap) { XFreeColormap(X11::getDpy(), params.attr.colormap); params.depth = X11::getDepth(); params.visual = X11::getVisual(); params.attr.colormap = X11::getColormap(); } } /** * Create title window. */ void PDecor::createTitle(CreateWindowParams ¶ms) { params.attr.event_mask = ButtonPressMask|ButtonReleaseMask| ButtonMotionMask|EnterWindowMask; Window title = X11::createWindow(_window, bdLeft(this), bdTop(this), 1, 1, 0, params.depth, InputOutput, params.visual, params.mask, ¶ms.attr); _title_wo.setWindow(title); addChildWindow(_title_wo.getWindow()); _title_wo.mapWindow(); } /** * Create border windows */ void PDecor::createBorder(CreateWindowParams ¶ms) { params.attr.event_mask = ButtonPressMask|ButtonReleaseMask| ButtonMotionMask|EnterWindowMask; for (uint i = 0; i < BORDER_NO_POS; ++i) { params.attr.cursor = X11::getCursor(CursorType(i)); _border_win[i] = X11::createWindow(_window, -1, -1, 1, 1, 0, params.depth, InputOutput, params.visual, params.mask|CWCursor, ¶ms.attr); addChildWindow(_border_win[i]); } } //! @brief PDecor destructor PDecor::~PDecor(void) { _pdecors.erase(std::remove(_pdecors.begin(), _pdecors.end(), this), _pdecors.end()); while (! _children.empty()) { PDecor::removeChild(_children.back(), false); } // Make things look smoother, buttons will be noticed as deleted // otherwise. Using X call directly to avoid re-drawing and other // special features not required when removing the window. X11::unmapWindow(_window); // free buttons unloadDecor(); removeChildWindow(_title_wo.getWindow()); X11::destroyWindow(_title_wo.getWindow()); for (uint i = 0; i < BORDER_NO_POS; ++i) { removeChildWindow(_border_win[i]); X11::destroyWindow(_border_win[i]); } X11::destroyWindow(_window); } // START - PWinObj interface. //! @brief Map decor and all children void PDecor::mapWindow(void) { if (! _mapped) { PWinObj::mapWindow(); std::vector::iterator it = _children.begin(); for (; it != _children.end(); ++it) { (*it)->mapWindow(); } } } //! @brief Maps the window raised void PDecor::mapWindowRaised(void) { if (_mapped) { return; } mapWindow(); raise(); // XMapRaised wouldn't preserver layers } //! @brief Unmaps decor and all children void PDecor::unmapWindow(void) { if (_mapped) { PWinObj::unmapWindow(); std::vector::iterator it = _children.begin(); for (; it != _children.end(); ++it) { if (_iconified) { (*it)->iconify(); } else { (*it)->unmapWindow(); } } } } //! @brief Moves the decor void PDecor::move(int x, int y) { // update real position PWinObj::move(x, y); if (_child && (_decor_cfg_child_move_overloaded)) { _child->move(x + bdLeft(this), y + bdTop(this) + titleHeight(this)); } } //! @brief Resizes the decor, and active child if any void PDecor::resize(uint width, uint height) { // If shaded, don't resize to the size specified just update width // and set _real_height to height if (_shaded) { _real_height = height; height = titleHeight(this); // Shading in non full width title mode will make border go away if (! _data->getTitleWidthMin()) { height += bdTop(this) + bdBottom(this); } } PWinObj::resize(width, height); // Update size before moving and shaping the rest as shaping // depends on the child window if (_child) { _child->resize(getChildWidth(), getChildHeight()); } // place / resize title and border resizeTitle(); placeBorder(); // Set and apply shape on window, all parts of the border can now // be shaped. setBorderShape(); applyBorderShape(); renderTitle(); renderBorder(); } void PDecor::moveResize(const Geometry &gm, int gm_mask) { if (gm_mask & (X_VALUE|Y_VALUE)) { if (gm_mask & X_VALUE) { _gm.x = gm.x; } if (gm_mask & Y_VALUE) { _gm.y = gm.y; } move(_gm.x, _gm.y); } if (gm_mask & (WIDTH_VALUE|HEIGHT_VALUE)) { if (gm_mask & WIDTH_VALUE) { _gm.width = gm.width; } if (gm_mask & HEIGHT_VALUE) { _gm.height = gm.height; } clearFillStateAfterResize(); resize(_gm.width, _gm.height); } } //! @brief Move and resize window. void PDecor::moveResize(int x, int y, uint width, uint height) { // If shaded, don't resize to the size specified just update width // and set _real_height to height if (_shaded) { _real_height = height; height = titleHeight(this); // Shading in non full width title mode will make border go away if (! _data->getTitleWidthMin()) { height += bdTop(this) + bdBottom(this); } } PWinObj::moveResize(x, y, width, height); // Update size before moving and shaping the rest as shaping // depends on the child window if (_child) { _child->moveResize(x + bdLeft(this), y + bdTop(this) + titleHeight(this), getChildWidth(), getChildHeight()); // The client window may have its window gravity set to // something different than NorthWestGravity (see Xlib manual // chapter 3.2.3). Therefore the X server may not move its top // left corner along with the decoration. We correct these // cases by calling alignChild(). It is called only for _child // and not all members of _children, because activateChild.*() // does it itself. alignChild(_child); } // Place and resize title and border resizeTitle(); placeBorder(); // Apply shape on window, all parts of the border can now be shaped. setBorderShape(); applyBorderShape(); renderTitle(); renderBorder(); } void PDecor::resizeTitle(void) { if (titleHeight(this)) { _title_wo.resize(calcTitleWidth(), titleHeight(this)); calcTabsWidth(); } // place buttons, also updates title information placeButtons(); } //! @brief Raises the window, taking _layer into account void PDecor::raise(void) { Workspaces::raise(this); if (_type == PWinObj::WO_FRAME) { Workspaces::updateClientStackingList(); } } //! @brief Lowers the window, taking _layer into account void PDecor::lower(void) { Workspaces::lower(this); if (_type == PWinObj::WO_FRAME) { Workspaces::updateClientStackingList(); } } void PDecor::setFocused(bool focused) { if (_focused != focused) { // save repaints PWinObj::setFocused(focused); renderTitle(); renderButtons(); renderBorder(); setBorderShape(); applyBorderShape(); } } void PDecor::setWorkspace(uint workspace) { if (workspace != NET_WM_STICKY_WINDOW) { if (workspace >= Workspaces::size()) { P_LOG("this == " << this << " workspace == " << workspace << " >= number of workspaces == " << Workspaces::size()); workspace = Workspaces::size() - 1; } _workspace = workspace; } std::vector::iterator it = _children.begin(); for (; it != _children.end(); ++it) { (*it)->setWorkspace(workspace); } if (! _mapped && ! _iconified) { if (_sticky || (_workspace == Workspaces::getActive())) { mapWindow(); } } else if (! _sticky && (_workspace != Workspaces::getActive())) { unmapWindow(); } } /** * Gives decor input focus, fails if not mapped or not visible */ void PDecor::giveInputFocus() { if (_mapped && _child) { _child->giveInputFocus(); } else { P_LOG("this == " << this << " - reverting to root"); PWinObj::getRootPWinObj()->giveInputFocus(); } } void PDecor::warpPointer() { int warp_x = _gm.x + bdLeft(this) + 1; int warp_y = _gm.y + bdTop(this) + titleHeight(this) + 1; int x, y; X11::queryRootPointer(x, y); if (x > warp_x && x < _gm.rx() && y > warp_y && y < _gm.by()) { // cursor already inside, skip warping } else { X11::warpPointer(warp_x, warp_y); } } /** * Handle button press events. */ const ActionEvent* PDecor::handleButtonPress(XButtonEvent *ev) { X11::stripStateModifiers(&ev->state); X11::stripButtonModifiers(&ev->state); // Try to do something about frame buttons _button = findButton(ev->subwindow); if (_button) { return handleButtonPressButton(ev, _button); } return handleButtonPressDecor(ev); } const ActionEvent* PDecor::handleButtonPressDecor(XButtonEvent *ev) { // Allow us to get clicks from anywhere on the window. if (_decor_cfg_bpr_replay_pointer && ev->window == _window) { X11::allowEvents(ReplayPointer, CurrentTime); } std::vector *actions = nullptr; Config *cfg = pekwm::config(); if (ev->window == _child->getWindow() || (ev->state == 0 && ev->subwindow == _child->getWindow())) { // press on the child window (not the actual decor), if the // match was against the subwindow the check against zero // state is required to avoid duplicate actions to trigger. _button_press_win = _child->getWindow(); actions = cfg->getMouseActionList(_decor_cfg_bpr_al_child); } else if (_title_wo == ev->window) { // press on the decor title _button_press_win = ev->window; actions = cfg->getMouseActionList(_decor_cfg_bpr_al_title); } else { // press on decor border, default case. Try both window and // sub-window. uint pos = getBorderPosition(ev->window); if (pos != BORDER_NO_POS) { _button_press_win = ev->window; actions = cfg->getBorderListFromPosition(pos); } } return actions ? ActionHandler::findMouseAction(ev->button, ev->state, MOUSE_EVENT_PRESS, actions) : nullptr; } /** * Handle button press events pressing decor buttons. */ const ActionEvent* PDecor::handleButtonPressButton(XButtonEvent *ev, PDecor::Button *button) { // Keep track of pressed button. _button->setState(BUTTON_STATE_PRESSED); const ActionEvent *ae = _button->findAction(ev); // if the button is used for resizing, we don't want to wait for release if (ae && ae->isOnlyAction(ACTION_RESIZE)) { _button->setState(_focused ? BUTTON_STATE_FOCUSED : BUTTON_STATE_UNFOCUSED); _button = nullptr; } else { ae = nullptr; } return ae; } /** * Handle button release events. */ const ActionEvent* PDecor::handleButtonRelease(XButtonEvent *ev) { // Remove state modifiers from event X11::stripStateModifiers(&ev->state); X11::stripButtonModifiers(&ev->state); // handle titlebar buttons if (_button) { return handleButtonReleaseButton(ev, _button); } return handleButtonReleaseDecor(ev); } const ActionEvent* PDecor::handleButtonReleaseDecor(XButtonEvent *ev) { // ensure that the button was released on the same window as it // was pressed on to allow button release events to be triggered if (ev->window != _button_press_win && ev->subwindow != _button_press_win) { return nullptr; } MouseEventType mb = MOUSE_EVENT_RELEASE; std::vector *actions = nullptr; Config *cfg = pekwm::config(); if (ev->window == _child->getWindow() || (ev->state == 0 && ev->subwindow == _child->getWindow())) { // release on the child window (not the actual decor), if the // match was against the subwindow the check against zero // state is required to avoid duplicate actions to trigger. actions = cfg->getMouseActionList(_decor_cfg_bpr_al_child); } else if (_title_wo == ev->window) { // handle release on the decor title, checking double clicks // first. if (X11::isDoubleClick(ev->window, ev->button - 1, ev->time, cfg->getDoubleClickTime())) { X11::setLastClickID(ev->window); X11::setLastClickTime(ev->button - 1, 0); mb = MOUSE_EVENT_DOUBLE; } else { X11::setLastClickID(ev->window); X11::setLastClickTime(ev->button - 1, ev->time); } actions = cfg->getMouseActionList(_decor_cfg_bpr_al_title); } else { // release on the decor border, check subwindow then window. uint pos = getBorderPosition(ev->window); if (pos != BORDER_NO_POS && (_button_press_win == ev->window)) { actions = cfg->getBorderListFromPosition(pos); } } return actions ? ActionHandler::findMouseAction(ev->button, ev->state, mb, actions) : nullptr; } /** * Handle button release events when button is in pressed state. */ const ActionEvent* PDecor::handleButtonReleaseButton(XButtonEvent *ev, PDecor::Button *button) { // First restore the pressed buttons state _button->setState(_focused ? BUTTON_STATE_FOCUSED : BUTTON_STATE_UNFOCUSED); const ActionEvent *ae = nullptr; // Then see if the button was released over ( to execute an action ) if (*_button == ev->subwindow) { ae = _button->findAction(ev); // This is a hack to avoid resizing on both press and release if (ae && ae->isOnlyAction(ACTION_RESIZE)) { ae = nullptr; } } _button = nullptr; return ae; } const ActionEvent* PDecor::handleMotionEvent(XMotionEvent *ev) { uint button = X11::getButtonFromState(ev->state); std::vector *malo = pekwm::config()->getMouseActionList(MOUSE_ACTION_LIST_OTHER); return ActionHandler::findMouseAction(button, ev->state, MOUSE_EVENT_MOTION, malo); } /** * Handle enter event, find action and toggle hoover state if enter * was on a button. */ const ActionEvent* PDecor::handleEnterEvent(XCrossingEvent *ev) { PDecor::Button *button = findButton(ev->window); if (button) { button->setState(BUTTON_STATE_HOVER); } std::vector *malo = pekwm::config()->getMouseActionList(MOUSE_ACTION_LIST_OTHER); return ActionHandler::findMouseAction(BUTTON_ANY, ev->state, MOUSE_EVENT_ENTER, malo); } /** * Handle leave event, find action and toggle hoover state if leave * was from a button. */ const ActionEvent* PDecor::handleLeaveEvent(XCrossingEvent *ev) { PDecor::Button *button = findButton(ev->window); if (button) { button->setState(button->getState()); } std::vector *malo = pekwm::config()->getMouseActionList(MOUSE_ACTION_LIST_OTHER); return ActionHandler::findMouseAction(BUTTON_ANY, ev->state, MOUSE_EVENT_LEAVE, malo); } bool PDecor::operator==(const Window &window) { return _window == window || _title_wo == window || findButton(window) || getBorderPosition(window) != BORDER_NO_POS || (_child ? *_child == window : false); } bool PDecor::operator!=(const Window &window) { return !(*this == window); } // END - PWinObj interface. //! @brief Adds a children in another decor to this decor void PDecor::addDecor(PDecor *decor) { if (this == decor) { P_LOG("this == decor (" << this << ")"); return; } std::vector::const_iterator it = decor->begin(); for (; it != decor->end(); ++it) { addChild(*it); (*it)->setWorkspace(_workspace); } decor->_children.clear(); delete decor; } //! @return True on decor change, False if decor unchanged bool PDecor::updateDecor(void) { std::string name = getDecorName(); if (! _decor_name_saved.empty()) { _decor_name_saved = name; return false; } if (_decor_name == name) { return false; } _decor_name = name; loadDecor(); return true; } //! @brief Sets override decor name void PDecor::setDecorOverride(StateAction sa, const std::string &name) { if (sa == STATE_SET || (sa == STATE_TOGGLE && _decor_name_saved.empty())) { if (_decor_name_saved.empty()) { _decor_name_saved = _decor_name; } if (_decor_name != name) { _decor_name = name; loadDecor(); } } else if (! _decor_name_saved.empty()) { _decor_name = _decor_name_saved; _decor_name_saved = ""; loadDecor(); } } //! @brief Load and update decor. void PDecor::loadDecor(void) { unloadDecor(); setDataFromDecorName(_decor_name); // Load decor. std::vector::const_iterator b_it = _data->buttonBegin(); for (; b_it != _data->buttonEnd(); ++b_it) { uint width = std::max(static_cast(1), (*b_it)->getWidth() ? (*b_it)->getWidth() : titleHeight(this)); uint height = std::max(static_cast(1), (*b_it)->getHeight() ? (*b_it)->getHeight() : titleHeight(this)); _buttons.push_back(new PDecor::Button(&_title_wo, *b_it, width, height)); _buttons.back()->mapWindow(); addChildWindow(_buttons.back()->getWindow()); } if (! _data->getTitleHeight() && ! _data->isTitleHeightAdapt()) { _title_wo.unmapWindow(); } else { _title_wo.mapWindow(); } // Update title position. if (_data->getTitleWidthMin() == 0) { _title_wo.move(titleLeftOffset(this), bdTop(this)); _need_shape = false; } else { _title_wo.move(0, 0); _need_shape = true; } // Update child positions. std::vector::iterator c_it = _children.begin(); for (; c_it != _children.end(); ++c_it) { alignChild(*c_it); } // Make sure it gets rendered correctly. _focused = ! _focused; setFocused(! _focused); // Update the dimension of the frame. if (_child) { resizeChild(_child->getWidth(), _child->getHeight()); } // Child theme change. loadTheme(); // notify on decor change. decorUpdated(); } void PDecor::setDataFromDecorName(const std::string &decor_name) { _data = pekwm::theme()->getPDecorData(_decor_name); if (! _data) { _data = pekwm::theme()->getPDecorData(DEFAULT_DECOR_NAME); } setData(_data); P_LOG_IF(!_data, "_data == 0"); } //! @brief Frees resources used by PDecor. void PDecor::unloadDecor(void) { // Set active button to 0 as it can not be valid after deleting // the current buttons. _button = 0; std::vector::iterator it = _buttons.begin(); for (; it != _buttons.end(); ++it) { removeChildWindow((*it)->getWindow()); delete *it; } _buttons.clear(); } PDecor::Button* PDecor::findButton(Window win) { if (win == None) { return nullptr; } std::vector::iterator it = _buttons.begin(); for (; it != _buttons.end(); ++it) { if (*(*it) == win) { return *it; } } return nullptr; } /** * Returns height of PDecor ignoring shaded state. */ uint PDecor::getRealHeight(void) const { return (_shaded ? _real_height : _gm.height); } /** * Returns width of child container. */ uint PDecor::getChildWidth(void) const { if ((bdLeft(this) + bdRight(this)) >= _gm.width) { return 1; } return (_gm.width - bdLeft(this) - bdRight(this)); } /** * Returns height of child container. */ uint PDecor::getChildHeight(void) const { if (decorHeight(this) >= getRealHeight()) { return 1; } return getRealHeight() - decorHeight(this); } PWinObj* PDecor::getChildFromPos(int x) { if (_children.empty() || _children.size() != _titles.size()) { return 0; } if (_children.size() == 1) return _children.front(); if (x < static_cast(_titles_left)) { return _children.front(); } else if (x > static_cast(_title_wo.getWidth() - _titles_right)) { return _children.back(); } PTexture *t_sep = _data->getTextureSeparator(getFocusedState(false)); uint sepw = t_sep?t_sep->getWidth():0; uint pos = _titles_left, xx = x; for (uint i = 0; i < _titles.size(); ++i) { if (xx >= pos && xx <= pos + _titles[i]->getWidth() + sepw) { return _children[i]; } pos += _titles[i]->getWidth() + sepw; } return 0; } //! @brief Moves making the child be positioned at x y void PDecor::moveChild(int x, int y) { move(x - bdLeft(this), y - bdTop(this) - titleHeight(this)); } //! @brief Resizes the decor, giving width x height space for the child void PDecor::resizeChild(uint width, uint height) { resize(width + bdLeft(this) + bdRight(this), height + bdTop(this) + bdBottom(this) + titleHeight(this)); } //! @brief Sets border state of the decor bool PDecor::setBorder(StateAction sa) { if (! ActionUtil::needToggle(sa, _border)) { return _border; } // If we are going to remove the border, we need to check carefully // that we don't try to make the window disappear. if (! _border) { _border = true; } else if (! _shaded || _titlebar) { _border = false; } restackBorder(); if (updateDecor()) { // updateDecorName returns true, decor already loaded no need // to notify decorUpdated } else if (_child) { resizeChild(_child->getWidth(), _child->getHeight()); } decorUpdated(); return _border; } //! @brief Sets titlebar state of the decor bool PDecor::setTitlebar(StateAction sa) { if (! ActionUtil::needToggle(sa, _titlebar)) { return _titlebar; } // If we are going to remove the titlebar, we need to check carefully // that we don't try to make the window disappear. if (! _titlebar) { _title_wo.mapWindow(); _titlebar = true; } else if (! _shaded || _border) { _title_wo.unmapWindow(); _titlebar = false; } if (updateDecor()) { // updateDecorName returns true, decor already loaded no need // to notify decorUpdated } else if (_child) { alignChild(_child); resizeChild(_child->getWidth(), _child->getHeight()); } decorUpdated(); return _titlebar; } //! @brief Adds a child to the decor, reparenting the window void PDecor::addChild(PWinObj *child, std::vector::iterator *it) { child->reparent(this, bdLeft(this), bdTop(this) + titleHeight(this)); if (it == 0) { _children.push_back(child); } else { _children.insert(*it, child); } updatedChildOrder(); // Sync focused state if it is the first child, the child will be // activated later on. If there are children here already fit the // child into the decor. if (_children.size() == 1) { _focused = ! _focused; setFocused(! _focused); } else { alignChild(child); child->resize(getChildWidth(), getChildHeight()); } } //! @brief Removes PWinObj from this PDecor. //! @param child PWinObj to remove from the this PDecor. //! @param do_delete Wheter to call delete this when empty. (Defaults to true) void PDecor::removeChild(PWinObj *child, bool do_delete) { child->reparent(PWinObj::getRootPWinObj(), _gm.x + bdLeft(this), _gm.y + bdTop(this) + titleHeight(this)); std::vector::iterator it = std::find(_children.begin(), _children.end(), child); if (it == _children.end()) { P_LOG("this == " << this << " child == " << child << " - child not in _child_list, bailing out"); return; } it = _children.erase(it); if (! _children.empty()) { if (_child == child) { if (it == _children.end()) { --it; } activateChild(*it); } updatedChildOrder(); } else if (do_delete) { delete this; // no children, and we don't want empty PDecors } } //! @brief Activates the child, updating size and position void PDecor::activateChild(PWinObj *child) { // sync state _focusable = child->isFocusable(); alignChild(child); // place correct acording to border and title child->resize(getChildWidth(), getChildHeight()); child->raise(); _child = child; restackBorder(); updatedChildOrder(); } void PDecor::getDecorInfo(char *buf, uint size, const Geometry& gm) { snprintf(buf, size, "%ux%u+%d+%d", gm.width, gm.height, gm.x, gm.y); } void PDecor::activateChildNum(uint num) { if (num >= _children.size()) { P_LOG("this == " << this << " num == " << num << " >= _children.size() == " << _children.size()); return; } activateChild(_children[num]); } void PDecor::activateChildRel(int off) { std::vector::size_type cur=0, num_children = _children.size(); for (; cur < num_children; ++cur) { if (_child == _children[cur]) { break; } } if (cur == num_children) { _child = _children.front(); cur = 0; } off = (off+signed(cur))%signed(num_children); if (off < 0) { off += num_children; } activateChild(_children[off]); } //! @brief Moves the current child off steps //! @param off - for left and + for right void PDecor::moveChildRel(int off) { std::vector::size_type idx=0, num_children = _children.size(); for (; idx < num_children; ++idx) { if (_child == _children[idx]) { break; } } if (idx == num_children) { if (_children.empty()) { P_ERR("_children is empty! off == " << off << " Please report."); return; } _child = _children.front(); idx = 0; } off = (off+idx)%num_children; if (off < 0) { off += num_children; } _children.erase(std::remove(_children.begin(), _children.end(), _child), _children.end()); _children.insert(_children.begin()+off, _child); updatedChildOrder(); } //! @brief Sets shaded state bool PDecor::setShaded(StateAction sa) { if (! ActionUtil::needToggle(sa, _shaded)) { return _shaded; } // If we are going to shade the window, we need to check carefully // that we don't try to make the window disappear. if (_shaded) { _gm.height = _real_height; _shaded = false; // If we have a titlebar OR border (border will only be // visible in full-width mode only) } else if (_titlebar || (_border && ! _data->getTitleWidthMin())) { _real_height = _gm.height; _gm.height = titleHeight(this); // Shading in non full width title mode (border not visible) if (! _data->getTitleWidthMin()) { _gm.height += bdTop(this) + bdBottom(this); } _shaded = true; } setBorderShape(); placeBorder(); restackBorder(); PWinObj::resize(_gm.width, _gm.height); return _shaded; } /** * Returns the name of the decor for the current titlebar/border state. */ std::string PDecor::getDecorName(void) { if (_attention) { return DEFAULT_DECOR_NAME_ATTENTION; } if (_titlebar && _border) { return DEFAULT_DECOR_NAME; } if (_border) { return DEFAULT_DECOR_NAME_TITLEBARLESS; } return DEFAULT_DECOR_NAME_BORDERLESS; } //! @brief Remove iconified state. void PDecor::deiconify(void) { if (_iconified) { if (_workspace == Workspaces::getActive()) { mapWindow(); } _iconified = false; } } /** * Render main background, tabs and title text onto a Pixmap that is later * used as the background for the titlebar window. */ void PDecor::renderTitle(void) { if (! titleHeight(this)) { return; } if (_data->getTitleWidthMin()) { resizeTitle(); applyBorderShape(); // update title shape } else { calcTabsWidth(); } FocusedState fstate = getFocusedState(false); PPixmapSurface title_bg(_title_wo.getWidth(), _title_wo.getHeight()); PTexture *t_main = _data->getTextureMain(fstate); t_main->render(&title_bg, 0, 0, _title_wo.getWidth(), _title_wo.getHeight()); uint x = _titles_left; uint pad_horiz = _data->getPad(PAD_LEFT) + _data->getPad(PAD_RIGHT); uint num_titles = _titles.size(); for (uint i = 0; i < num_titles; ++i) { FocusedState fstate_sel = getFocusedState(_title_active == i); PTexture *tab = _data->getTextureTab(fstate_sel); tab->render(&title_bg, x, 0, _titles[i]->getWidth(), _title_wo.getHeight()); PFont *font = getFont(fstate_sel); font->setColor(_data->getFontColor(fstate_sel)); PFont::TrimType trim = PFont::FONT_TRIM_MIDDLE; if (_titles[i]->isCustom() || _titles[i]->isUserSet()) { trim = PFont::FONT_TRIM_END; } PTexture *title = _data->getTextureTitle(fstate_sel); uint width_used; if (title) { renderTitleTextBackground(title_bg, font, x, _titles[i]->getWidth(), _titles[i]->getVisible(), trim, title); } font->draw(&title_bg, x + _data->getPad(PAD_LEFT), _data->getPad(PAD_UP), _titles[i]->getVisible(), width_used, _titles[i]->getWidth() - pad_horiz, trim); x += _titles[i]->getWidth(); if (num_titles > 1 && i < (num_titles - 1)) { PTexture *t_sep = _data->getTextureSeparator(fstate); t_sep->render(&title_bg, x, 0, 0, 0); x += t_sep->getWidth(); } } X11::setWindowBackgroundPixmap(_title_wo.getWindow(), title_bg.getDrawable()); X11::clearWindow(_title_wo.getWindow()); } void PDecor::renderTitleTextBackground(PPixmapSurface &title_bg, PFont *font, int x, uint width, const std::string &text, PFont::TrimType trim, PTexture *tex) { uint pad_horiz = _data->getPad(PAD_LEFT) + _data->getPad(PAD_RIGHT); // get X offset and width used by title text, not rendering the text uint width_used; int title_x = font->draw(&title_bg, x, 0, text, width_used, width - pad_horiz, trim, false); tex->render(&title_bg, title_x, 0, width_used + pad_horiz, _title_wo.getHeight()); } void PDecor::renderButtons(void) { std::vector::iterator it = _buttons.begin(); for (; it != _buttons.end(); ++it) { (*it)->setState(_focused ? BUTTON_STATE_FOCUSED : BUTTON_STATE_UNFOCUSED); } } void PDecor::renderBorder(void) { if (! _data || ! _border) { return; } uint width, height; FocusedState state = getFocusedState(false); for (int i=0; i < BORDER_NO_POS; ++i) { BorderPosition bp = static_cast(i); PTexture *tex = _data->getBorderTexture(state, bp); getBorderSize(static_cast(i), width, height); tex->setBackground(_border_win[i], 0, 0, width, height); X11::clearWindow(_border_win[i]); } } //! @brief Sets shape on the border windows. void PDecor::setBorderShape(void) { if (! _data) { return; } #ifdef PEKWM_HAVE_SHAPE Pixmap pix; bool do_free; unsigned int width, height; PTexture *tex; FocusedState state = getFocusedState(false); XRectangle rect = {0, 0, 0, 0}; for (int i=0; i < BORDER_NO_POS; ++i) { // Get the size of the border at position getBorderSize(static_cast(i), width, height); tex = _data->getBorderTexture(state, static_cast(i)); pix = tex->getMask(width, height, do_free); if (pix != None) { _need_shape = true; X11::shapeSetMask(_border_win[i], ShapeBounding, pix); if (do_free) { X11::freePixmap(pix); } } else { rect.width = width; rect.height = height; X11::shapeSetRect(_border_win[i], &rect); } } #endif // PEKWM_HAVE_SHAPE } void PDecor::checkSnap(PWinObj *skip_wo, Geometry &gm) { Config *cfg = pekwm::config(); if (cfg->getWOAttract() > 0 || cfg->getWOResist() > 0) { checkWOSnap(skip_wo, gm); } if (cfg->getEdgeAttract() > 0 || cfg->getEdgeResist() > 0) { checkEdgeSnap(gm); } } inline bool isBetween(int x1, int x2, int t1, int t2) { if (x1 > t1) { if (x1 < t2) { return true; } } else if (x2 > t1) { return true; } return false; } //! @todo PDecor/PWinObj doesn't have _skip property void PDecor::checkWOSnap(const PWinObj *skip_wo, Geometry &gm) { PDecor *decor; Geometry orig_gm = gm; int x = gm.x + gm.width; int y = gm.y + gm.height; int attract = pekwm::config()->getWOAttract(); int resist = pekwm::config()->getWOResist(); bool snapped; std::vector::reverse_iterator it = _wo_list.rbegin(); for (; it != _wo_list.rend(); ++it) { if (((*it) == skip_wo) || ! (*it)->isMapped() || ((*it)->getType() != PWinObj::WO_FRAME)) { continue; } // Skip snapping, only valid on PDecor and up. decor = dynamic_cast(*it); if (decor && decor->isSkip(SKIP_SNAP)) { continue; } snapped = false; // check snap if ((x >= ((*it)->getX() - attract)) && (x <= ((*it)->getX() + resist))) { if (isBetween(gm.y, y, (*it)->getY(), (*it)->getBY())) { gm.x = (*it)->getX() - orig_gm.width; snapped = true; } } else if ((gm.x >= signed((*it)->getRX() - resist)) && (gm.x <= signed((*it)->getRX() + attract))) { if (isBetween(gm.y, y, (*it)->getY(), (*it)->getBY())) { gm.x = (*it)->getRX(); snapped = true; } } if (y >= ((*it)->getY() - attract) && (y <= (*it)->getY() + resist)) { if (isBetween(gm.x, x, (*it)->getX(), (*it)->getRX())) { gm.y = (*it)->getY() - orig_gm.height; if (snapped) break; } } else if ((gm.y >= signed((*it)->getBY() - resist)) && (gm.y <= signed((*it)->getBY() + attract))) { if (isBetween(gm.x, x, (*it)->getX(), (*it)->getRX())) { gm.y = (*it)->getBY(); if (snapped) break; } } } } //! @brief Snaps decor agains head edges. Only updates _gm, no real move. //! @todo Add support for checking for harbour and struts void PDecor::checkEdgeSnap(Geometry &gm) { int attract = pekwm::config()->getEdgeAttract(); int resist = pekwm::config()->getEdgeResist(); Geometry head; pekwm::rootWo()->getHeadInfoWithEdge(X11::getNearestHead(gm.x, gm.y), head); if ((gm.x >= (head.x - resist)) && (gm.x <= (head.x + attract))) { gm.x = head.x; } else if ((gm.x + gm.width) >= (head.x + head.width - attract) && ((gm.x + gm.width) <= (head.x + head.width + resist))) { gm.x = head.x + head.width - gm.width; } if ((gm.y >= (head.y - resist)) && (gm.y <= (head.y + attract))) { gm.y = head.y; } else if (((gm.y + gm.height) >= (head.y + head.height - attract)) && ((gm.y + gm.height) <= (head.y + head.height + resist))) { gm.y = head.y + head.height - gm.height; } } /** * Move child into position with regards to title and border. */ void PDecor::alignChild(PWinObj *child) { if (child) { X11::moveWindow(child->getWindow(), bdLeft(this), bdTop(this) + titleHeight(this)); } } /** * Draws outline for the provided geometry, if shaded is non-zero use * that as height instead of gm.height */ void PDecor::drawOutline(const Geometry &gm, uint shaded) { XDrawRectangle(X11::getDpy(), X11::getRoot(), pekwm::theme()->getInvertGC(), gm.x, gm.y, gm.width, shaded ? shaded : gm.height); } //! @brief Places decor buttons void PDecor::placeButtons(void) { _titles_left = 0; _titles_right = 0; std::vector::iterator it = _buttons.begin(); for (; it != _buttons.end(); ++it) { if ((*it)->isLeft()) { (*it)->move(_titles_left, 0); _titles_left += (*it)->getWidth(); } else { _titles_right += (*it)->getWidth(); (*it)->move(_title_wo.getWidth() - _titles_right, 0); } } } //! @brief Places border windows void PDecor::placeBorder(void) { // if we have tab min == 0 then we have full width title and place the // border ontop, else we put the border under the title uint bt_off = (_data->getTitleWidthMin() > 0) ? titleHeight(this) : 0; if (bdTop(this) > 0) { X11::moveResizeWindow(_border_win[BORDER_TOP], bdTopLeft(this), bt_off, _gm.width - bdTopLeft(this) - bdTopRight(this), bdTop(this)); X11::moveResizeWindow(_border_win[BORDER_TOP_LEFT], 0, bt_off, bdTopLeft(this), bdTopLeftHeight(this)); X11::moveResizeWindow(_border_win[BORDER_TOP_RIGHT], _gm.width - bdTopRight(this), bt_off, bdTopRight(this), bdTopRightHeight(this)); if (bdLeft(this)) { X11::moveResizeWindow(_border_win[BORDER_LEFT], 0, bdTopLeftHeight(this) + bt_off, bdLeft(this), _gm.height - bdTopLeftHeight(this) - bdBottomLeftHeight(this)); } if (bdRight(this)) { X11::moveResizeWindow(_border_win[BORDER_RIGHT], _gm.width - bdRight(this), bdTopRightHeight(this) + bt_off, bdRight(this), _gm.height - bdTopRightHeight(this) - bdBottomRightHeight(this)); } } else { if (bdLeft(this)) { X11::moveResizeWindow(_border_win[BORDER_LEFT], 0, titleHeight(this), bdLeft(this), _gm.height - titleHeight(this) - bdBottom(this)); } if (bdRight(this)) { X11::moveResizeWindow(_border_win[BORDER_RIGHT], _gm.width - bdRight(this), titleHeight(this), bdRight(this), _gm.height - titleHeight(this) - bdBottom(this)); } } if (bdBottom(this)) { X11::moveResizeWindow(_border_win[BORDER_BOTTOM], bdBottomLeft(this), _gm.height - bdBottom(this), _gm.width - bdBottomLeft(this) - bdBottomRight(this), bdBottom(this)); X11::moveResizeWindow(_border_win[BORDER_BOTTOM_LEFT], 0, _gm.height - bdBottomLeftHeight(this), bdBottomLeft(this), bdBottomLeftHeight(this)); X11::moveResizeWindow(_border_win[BORDER_BOTTOM_RIGHT], _gm.width - bdBottomRight(this), _gm.height - bdBottomRightHeight(this), bdBottomRight(this), bdBottomRightHeight(this)); } applyBorderShape(); } #ifdef PEKWM_HAVE_SHAPE /** * Apply shaping on the window based on the shape of the client and * the borders. */ void PDecor::applyBorderShape(int kind) { bool client_shape = _child ? _child->hasShapeRegion() : false; if ((_need_shape && kind == ShapeBounding) || client_shape) { if (_shaded) { applyBorderShapeShaded(kind); } else { applyBorderShapeNormal(kind, client_shape); } } else { // Reinstate default region X11::shapeSetMask(_window, kind, None); } } void PDecor::applyBorderShapeNormal(int kind, bool client_shape) { Window shape = X11::createWmWindow(X11::getRoot(), 0, 0, _gm.width, _gm.height, InputOutput, None); if (_child) { X11::shapeCombine(shape, kind, bdLeft(this), bdTop(this) + titleHeight(this), _child->getWindow(), ShapeSet); } // Apply border shapek, shaped clients do not display a border if (_border && ! client_shape) { applyBorderShapeBorder(kind, shape); } if (_titlebar) { X11::shapeCombine(shape, kind, _title_wo.getX(), _title_wo.getY(), _title_wo.getWindow(), ShapeUnion); } // The borders might extend beyond the window area // (causing artifacts under xcompmgr), so we cut the shape // down to the original window size. XRectangle rect_square = { 0, 0, static_cast(_gm.width), static_cast(_gm.height) }; X11::shapeIntersectRect(shape, &rect_square); X11::shapeCombine(_window, kind, 0, 0, shape, ShapeSet); X11::destroyWindow(shape); } void PDecor::applyBorderShapeShaded(int kind) { Window shape; if (_data->getTitleWidthMin()) { shape = X11::createWmWindow(X11::getRoot(), 0, 0, _title_wo.getWidth(), _title_wo.getHeight(), InputOutput, None); } else { shape = X11::createWmWindow(X11::getRoot(), 0, 0, _gm.width, _gm.height, InputOutput, None); if (_border) { applyBorderShapeBorder(kind, shape); } } X11::shapeCombine(_window, kind, 0, 0, shape, ShapeSet); X11::destroyWindow(shape); } void PDecor::applyBorderShapeBorder(int kind, Window shape) { uint bd_top_offset = bdTopOffset(this); if (bdTop(this) > 0) { X11::shapeCombine(shape, kind, 0, bd_top_offset, _border_win[BORDER_TOP_LEFT], ShapeUnion); X11::shapeCombine(shape, kind, bdTopLeft(this), bd_top_offset, _border_win[BORDER_TOP], ShapeUnion); X11::shapeCombine(shape, kind, _gm.width - bdTopRight(this), bd_top_offset, _border_win[BORDER_TOP_RIGHT], ShapeUnion); } bool use_bt_off = bd_top_offset || bdTop(this); if (bdLeft(this) > 0) { X11::shapeCombine(shape, kind, 0, use_bt_off ? bd_top_offset + bdTopLeftHeight(this) : titleHeight(this), _border_win[BORDER_LEFT], ShapeUnion); } if (bdRight(this) > 0) { X11::shapeCombine(shape, kind, _gm.width - bdRight(this), use_bt_off ? bd_top_offset + bdTopRightHeight(this) : titleHeight(this), _border_win[BORDER_RIGHT], ShapeUnion); } if (bdBottom(this) > 0) { X11::shapeCombine(shape, kind, 0, _gm.height - bdBottomLeftHeight(this), _border_win[BORDER_BOTTOM_LEFT], ShapeUnion); X11::shapeCombine(shape, kind, bdBottomLeft(this), _gm.height - bdBottom(this), _border_win[BORDER_BOTTOM], ShapeUnion); X11::shapeCombine(shape, kind, _gm.width - bdBottomRight(this), _gm.height - bdBottomRightHeight(this), _border_win[BORDER_BOTTOM_RIGHT], ShapeUnion); } } #endif // PEKWM_HAVE_SHAPE //! @brief Restacks child, title and border windows. void PDecor::restackBorder(void) { std::vector windows; // Only put the Child over if not shaded. if (_child && ! _shaded) { windows.push_back(_child->getWindow()); } // Add title if any if (_titlebar) { windows.push_back(_title_wo.getWindow()); } // Add border windows for (int i = 0; i < BORDER_NO_POS; ++i) { windows.push_back(_border_win[i]); } // Raise the top window so actual restacking is done. X11::raiseWindow(windows[0]); X11::stackWindows(windows); } /** * Get size of border at position. * * @param pos Position to get size for. * @param width Width of border at position. * @param height Height of border at position. */ void PDecor::getBorderSize(BorderPosition pos, uint &width, uint &height) { FocusedState state = getFocusedState(false); // convenience switch (pos) { case BORDER_TOP_LEFT: case BORDER_TOP_RIGHT: case BORDER_BOTTOM_LEFT: case BORDER_BOTTOM_RIGHT: width = _data->getBorderTexture(state, pos)->getWidth(); height = _data->getBorderTexture(state, pos)->getHeight(); break; case BORDER_TOP: if ((bdTopLeft(this) + bdTopRight(this)) < _gm.width) { width = _gm.width - bdTopLeft(this) - bdTopRight(this); } else { width = 1; } height = _data->getBorderTexture(state, pos)->getHeight(); break; case BORDER_BOTTOM: if ((bdBottomLeft(this) + bdBottomRight(this)) < _gm.width) { width = _gm.width - bdBottomLeft(this) - bdBottomRight(this); } else { width = 1; } height = _data->getBorderTexture(state, pos)->getHeight(); break; case BORDER_LEFT: width = _data->getBorderTexture(state, pos)->getWidth(); if ((bdTopLeftHeight(this) + bdBottomLeftHeight(this)) < _gm.height) { height = _gm.height - bdTopLeftHeight(this) - bdBottomLeftHeight(this); } else { height = 1; } break; case BORDER_RIGHT: width = _data->getBorderTexture(state, pos)->getWidth(); if ((bdTopRightHeight(this) + bdBottomRightHeight(this)) < _gm.height) { height = _gm.height - bdTopRightHeight(this) - bdBottomRightHeight(this); } else { height = 1; } break; default: P_LOG("this == " << this << " - invalid border position"); width = 1; height = 1; break; }; } /** * Calculate width of title, if width min is 0 use the full available * size minus borders. Else get width from content. */ uint PDecor::calcTitleWidth(void) { if (_data->getTitleWidthMin() != 0) { return std::max(static_cast(1), calcTitleWidthDynamic()); } uint width = _gm.width; uint title_offsets = titleLeftOffset(this) + titleRightOffset(this); if (width > title_offsets) { width -= title_offsets; } return std::max(static_cast(1), width); } uint PDecor::calcTitleWidthDynamic(void) { FocusedState fs = getFocusedState(false); uint width = 0; PFont *font = getFont(fs); if (_data->isTitleWidthSymetric()) { // Symetric mode, get max tab width, multiply with number // of tabs std::vector::iterator it = _titles.begin(); uint width_max = 0; for (; it != _titles.end(); ++it) { width = font->getWidth((*it)->getVisible()); if (width > width_max) { width_max = width; } } width = width_max + _data->getPad(PAD_LEFT) + _data->getPad(PAD_RIGHT); width *= _titles.size(); } else { // Asymetric mode, get individual widths std::vector::iterator it = _titles.begin(); for (; it != _titles.end(); ++it) { width += font->getWidth((*it)->getVisible()) + _data->getPad(PAD_LEFT) + _data->getPad(PAD_RIGHT); } } // Add width of separators and buttons width += (_titles.size() - 1) * _data->getTextureSeparator(fs)->getWidth(); width += _titles_left + _titles_right; // Validate sizes, make sure it is not less than width min // pixels and more than width max percent. if (width < static_cast(_data->getTitleWidthMin())) { width = _data->getTitleWidthMin(); } uint max_width = _gm.width * _data->getTitleWidthMax() / 100; if (width > max_width) { width = max_width; } return width; } /** * Calculate tab width, wrapper to choose correct algorithm.. */ void PDecor::calcTabsWidth(void) { if (! _titles.size()) { return; } if (_data->isTitleWidthSymetric()) { calcTabsWidthSymetric(); } else { calcTabsWidthAsymetric(); } } /** * Get available tabs width and average width of a single tab. * * @param width_avail Number of pixels available in the titlebar. * @param tab_width Width in pixels to use for one tab. * @param off Number of pixels left with tab_width pixels wide tabs. */ void PDecor::calcTabsGetAvailAndTabWidth(uint& width_avail, uint& tab_width, int &off) { // Calculate width width_avail = _title_wo.getWidth(); // Remove spacing if enough space is available if (width_avail > (_titles_left + _titles_right)) { width_avail -= _titles_left + _titles_right; } // Remove separators if enough space is available FocusedState fs = getFocusedState(false); uint sep_width = (_titles.size() - 1) * _data->getTextureSeparator(fs)->getWidth(); if (width_avail > sep_width) { width_avail -= sep_width; } tab_width = width_avail / _titles.size(); off = width_avail % _titles.size(); } //! @brief Calculate tab width symetric, sets up _titles widths. void PDecor::calcTabsWidthSymetric(void) { int off; uint width_avail, tab_width; calcTabsGetAvailAndTabWidth(width_avail, tab_width, off); // Assign width to elements std::vector::iterator it = _titles.begin(); for (; it != _titles.end(); ++it) { (*it)->setWidth(tab_width + ((off-- > 0) ? 1 : 0)); } } /** * Calculate tab width asymmetrically. This is done with the following * priority: * * 1. Give tabs their required width, if it fits this is complete. * 2. Tabs did not fit, calculate average width. * 3. Add width of tabs requiring less space to average. * 4. Re-assign width equally to tabs using more than average. */ void PDecor::calcTabsWidthAsymetric(void) { int off; uint width_avail, tab_width; calcTabsGetAvailAndTabWidth(width_avail, tab_width, off); // Convenience PFont *font = getFont(getFocusedState(false)); // 1. give tabs their required width. uint width_total = 0; std::vector::iterator it = _titles.begin(); for (; it != _titles.end(); ++it) { // This should set the tab width to be only the size needed uint width = font->getWidth((*it)->getVisible().c_str()) + _data->getPad(PAD_LEFT) + _data->getPad(PAD_RIGHT) + ((off-- > 0) ? 1 : 0); width_total += width; (*it)->setWidth(width); } if (width_total > width_avail) { calcTabsWidthAsymetricShrink(width_avail, tab_width); } else if (width_total < static_cast(_data->getTitleWidthMin())) { calcTabsWidthAsymetricGrow(width_avail, width_total, tab_width); } } /** * This is called to shrink the tabs that are over the tab_width in * order to make room for all */ void PDecor::calcTabsWidthAsymetricShrink(uint width_avail, uint tab_width) { // 2. Tabs did not fit uint tabs_left = _titles.size(); std::vector::iterator it = _titles.begin(); for (; it != _titles.end(); ++it) { if ((*it)->getWidth() >= tab_width) { continue; } // 3. Add width of tabs requiring less space than the // the average tabs_left--; width_avail -= (*it)->getWidth(); } // 4. Re-assign width equally to tabs using more than average tab_width = width_avail / tabs_left; uint off = width_avail % tabs_left; for (it = _titles.begin(); it != _titles.end(); ++it) { if ((*it)->getWidth() < tab_width) { continue; } (*it)->setWidth(tab_width + ((off-- > 0) ? 1 : 0)); } } /** * This is called when tabs in the decor are using less space than * width min, grow tabs that are smaller than the average. */ void PDecor::calcTabsWidthAsymetricGrow(uint width_avail, uint width_total, uint tab_width) { // 2. Tabs did fit with extra space left over uint tabs = 0; std::vector::iterator it = _titles.begin(); for (; it != _titles.end(); ++it) { if ((*it)->getWidth() >= tab_width) { continue; } // 3. Sum width of tabs requiring less space than the the // average tabs++; width_total -= (*it)->getWidth(); } // 4. Re-assign width equally to tabs using less than average if (tabs) { uint grow_tab_width = (width_avail - width_total) / tabs; uint off = grow_tab_width % tabs; for (it = _titles.begin(); it != _titles.end(); ++it) { if ((*it)->getWidth() >= tab_width) { continue; } (*it)->setWidth(grow_tab_width + ((off-- > 0) ? 1 : 0)); } } } pekwm-0.4.4/src/wm/ActionMenu.hh0000664000175000017500000000401415126136025012122 // // ActionMenu.hh for pekwm // Copyright (C) 2002-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_ACTIONMENU_HH_ #define _PEKWM_ACTIONMENU_HH_ #include "config.h" #include "pekwm.hh" #include "CfgParser.hh" #include "WORefMenu.hh" #include "tk/Action.hh" // For ActionOk #include class ActionHandler; class ActionMenu : public WORefMenu { public: ActionMenu(MenuType type, ActionHandler *act, const std::string &title, const std::string &name, const std::string &decor_name = "MENU"); virtual ~ActionMenu(void); // START - PWinObj interface. virtual void mapWindow(void); virtual void unmapWindow(void); // END - PWinObj interface. virtual void handleItemExec(PMenu::Item *item); virtual void insert(PMenu::Item *item); virtual void insert(std::vector::iterator at, PMenu::Item *item); virtual void insert(const std::string &name, bool parse_name, PWinObj *wo_ref = nullptr, PTexture *icon = nullptr); virtual void insert(const std::string &name, bool parse_name, const ActionEvent &ae, PWinObj *wo_ref = nullptr, PTexture *icon = nullptr); virtual void reload(CfgParser::Entry *section); virtual void remove(PMenu::Item *item); virtual void removeAll(void); protected: uint rebuildDynamic(void); void removeDynamic(void); virtual CfgParser::Entry* runDynamic(CfgParser& parser, const std::string& src); private: void parse(CfgParser::Entry *section, PMenu::Item *parent=0); PMenu::Item* parseSubmenu(CfgParser::Entry *section, PMenu::Item* parent, const std::string& title); PMenu::Item* parseItem(CfgParser::Entry *section, PMenu::Item* parent); PTexture *getIcon(CfgParser::Entry *value); private: ActionHandler *_act; ActionOk _action_ok; std::vector::size_type _insert_at; /** Set to true if any of the entries in the menu is dynamic. */ bool _has_dynamic; }; #endif // _PEKWM_ACTIONMENU_HH_ pekwm-0.4.4/src/wm/WindowManager.hh0000664000175000017500000001151715126226753012640 // // WindowManager.hh for pekwm // Copyright (C) 2003-2025 Claes Nästén // // windowmanager.hh for aewm++ // Copyright (C) 2000 Frank Hale // http://sapphire.sourceforge.net/ // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_WINDOWMANAGER_HH_ #define _PEKWM_WINDOWMANAGER_HH_ #include "config.h" #include "pekwm.hh" #include "AppCtrl.hh" #include "Client.hh" #include "EventHandler.hh" #include "EventLoop.hh" #include "ManagerWindows.hh" #include "Os.hh" #include "tk/Action.hh" #include "tk/PWinObj.hh" #include #include class WindowManager : public AppCtrl, public EventLoop { public: static WindowManager *start(const std::string &bin_dir, const std::string &config_file, bool replace, bool skip_start, bool synchronous, bool standalone); virtual ~WindowManager(); void doEventLoop(void); // START - AppCtrl interface. virtual void reload(void) { _reload = true; } virtual void restart(void) { restart(""); } virtual void restart(std::string command); virtual void shutdown(void) { _shutdown = true; } // END - AppCtrl interface. inline bool shallRestart(void) const { return _restart; } inline const std::string &getRestartCommand(void) const { return _restart_command; } bool isEventHandler() const { return _event_handler != nullptr; } void setEventHandler(EventHandler *event_handler) { if (_event_handler) { delete _event_handler; } _event_handler = event_handler; } // public event handlers used when doing grabbed actions void handleKeyEvent(XKeyEvent *ev); void handleButtonPressEvent(XButtonEvent *ev); void handleButtonReleaseEvent(XButtonEvent *ev); bool setScale(double old_scale, double new_scale, bool reload=true); protected: WindowManager(const std::string &bin_dir, Os *os, bool standalone); void handlePekwmCmd(XClientMessageEvent *ev); bool recvPekwmCmd(XClientMessageEvent *ev); void startBackground(const std::string& theme_dir, const std::string& texture); void stopBackground(); bool startSys(); void stopSys(); void writeSysCommand(const std::string &cmd); private: void setupDisplay(); void scanWindows(void); void execStartFile(bool skip_start); void handleSignals(void); void doReload(void); void doReloadConfig(bool &scale_changed); void doReloadTheme(bool force=false); void doReloadThemeDecors(void); void doReloadMouse(void); void doReloadKeygrabber(bool force=false); void doReloadAutoproperties(void); void doReloadHarbour(void); void doReloadResources(void); bool isResourcesChanged(void); void cleanup(void); // screen edge related void screenEdgeCreate(void); void screenEdgeResize(void); void screenEdgeMapUnmap(void); bool getEvent(XEvent &ev); void handleEvent(XEvent &ev); bool handleEventHandlerEvent(XEvent &ev); PWinObj *updateWoForFrameClick(XButtonEvent *ev, PWinObj *orig_wo); void handleMapRequestEvent(XMapRequestEvent *ev); void handleUnmapEvent(XUnmapEvent *ev); void handleDestroyWindowEvent(XDestroyWindowEvent *ev); void handleConfigureRequestEvent(XConfigureRequestEvent *ev); void handleClientMessageEvent(XClientMessageEvent *ev); void handleNetRestackWindow(XClientMessageEvent *ev); void handleNetRequestFrameExtents(Window win); void handleColormapEvent(XColormapEvent *ev); void handlePropertyEvent(XPropertyEvent *ev); void handleMappingEvent(XMappingEvent *ev); void handleExposeEvent(XExposeEvent *ev); void handleMotionEvent(XMotionEvent *ev); void handleEnterNotify(XCrossingEvent *ev); void handleLeaveNotify(XCrossingEvent *ev); void handleFocusInEvent(XFocusChangeEvent *ev); void handleKeyEventAction(XKeyEvent *ev, const ActionEvent *ae, PWinObj *wo, PWinObj *wo_orig); void readDesktopNamesHint(void); // private methods for the hints void initHints(void); Client *createClient(Window window, bool is_new); void showDialog(const std::string &title, const std::string &msg); protected: /** OS interface for process handling etc. */ Os *_os; /** pekwm_cmd buffer for commands that do not fit in 20 bytes. */ std::string _pekwm_cmd_buf; private: std::string _bin_dir; bool _standalone; bool _shutdown; //!< Set to wheter we want to shutdown. bool _reload; //!< Set to wheter we want to reload. bool _restart; std::string _restart_command; std::string _bg_args; OsSelect *_select; /** PID of the pekwm_bg helper */ pid_t _bg_pid; /** ChildProcess for the pekwm_sys helper */ ChildProcess *_sys_process; EventHandler *_event_handler; EdgeWO *_screen_edges[4]; /** * If set to true, skip next enter event. Used in conjunction with * PWinObj::setSkipEnterAfter to skip "leave" events caused by * internal windows such as status dialog. */ bool _skip_enter; }; namespace pekwm { WindowManager *windowManager(); } #endif // _PEKWM_WINDOWMANAGER_HH_ pekwm-0.4.4/src/wm/KeyGrabber.hh0000664000175000017500000000523615126136025012104 // // KeyGrabber.hh for pekwm // Copyright (C) 2003-2020 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_KEYGRABBER_HH_ #define _PEKWM_KEYGRABBER_HH_ #include "config.h" #include "pekwm.hh" #include "CfgParser.hh" #include "tk/Action.hh" #include "tk/PWinObj.hh" #include extern "C" { #include } //! @brief Key grabbing and matching routines with key chain support. class KeyGrabber { public: //! @brief Key chain state information. class Chain { public: Chain(uint mod, uint key); ~Chain(void); void unload(void); //! @brief Returns modifier state Chain represents. inline uint getMod(void) const { return _mod; } //! @brief Returns key state Chain represents. inline uint getKey(void) const { return _key; } //! @brief Returns vector of Chains that follows. const std::vector &getChains(void) const { return _chains; } //! @brief Returns vector of Keys in chain. const std::vector &getKeys(void) const { return _keys; } //! @brief Adds chain to Chain vector. inline void addChain(Chain *chain) { _chains.push_back(chain); } //! @brief Adds action to Key vector. inline void addAction(const ActionEvent &key) { _keys.push_back(key); } Chain *findChain(XKeyEvent *ev, bool &matched); ActionEvent *findAction(XKeyEvent *ev, bool &matched); private: uint _mod, _key; std::vector _chains; std::vector _keys; }; KeyGrabber(void); ~KeyGrabber(void); bool load(const std::string &file, bool force=false); void grabKeys(Window win); void ungrabKeys(Window win); ActionEvent *findAction(XKeyEvent *ev, PWinObj::Type type, bool &matched); ActionEvent *findMoveResizeAction(XKeyEvent *ev); private: ActionEvent* findActionGrabbed(KeyGrabber::Chain* sub_chain, bool& matched); private: void grabKey(Window win, uint mod, uint key); void parseGlobalChain(CfgParser::Entry *section, KeyGrabber::Chain *chain); void parseMoveResizeChain(CfgParser::Entry *section, KeyGrabber::Chain *chain); void parseInputDialogChain(CfgParser::Entry *section, KeyGrabber::Chain *chain); void parseMenuChain(CfgParser::Entry *section, KeyGrabber::Chain *chain); ActionEvent *findAction(XKeyEvent *ev, KeyGrabber::Chain *chain, bool &matched); TimeFiles _cfg_files; KeyGrabber::Chain _menu_chain; KeyGrabber::Chain _global_chain; KeyGrabber::Chain _moveresize_chain; KeyGrabber::Chain _input_dialog_chain; uint _num_lock; uint _scroll_lock; }; namespace pekwm { KeyGrabber* keyGrabber(); } #endif // _PEKWM_KEYGRABBER_HH_ pekwm-0.4.4/src/wm/SearchDialog.cc0000664000175000017500000000761615126136025012406 // // SearchDialog.cc for pekwm // Copyright (C) 2009-2020 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include "SearchDialog.hh" #include "Client.hh" #include "RegexString.hh" #include #include /** * SearchDialog constructor. */ SearchDialog::SearchDialog() : InputDialog("Search"), _result_menu(0) { _type = PWinObj::WO_SEARCH_DIALOG; // Set up ActionEvent ae().action_list.back().setAction(ACTION_GOTO_CLIENT); // Set up menu for displaying results _result_menu = new PMenu("", ""); _result_menu->reparent(this, bdLeft(this), bdTop(this) + titleHeight(this) + _text_wo.getHeight()); _result_menu->setLayer(LAYER_DESKTOP); // Ignore when placing _result_menu->setSticky(STATE_SET); _result_menu->setBorder(STATE_UNSET); _result_menu->setTitlebar(STATE_UNSET); _result_menu->setFocusable(false); _result_menu->mapWindow(); } /** * SearchDialog destructor. */ SearchDialog::~SearchDialog(void) { delete _result_menu; } /** * Run when INPUT_EXEC is entered in the dialog giving the selected * Client focus if any. */ ActionEvent* SearchDialog::exec(void) { // InputDialog::close() may have overwritten our action. ae().action_list.back().setAction(ACTION_GOTO_CLIENT); PWinObj *wo_ref = 0; if (_result_menu->getItemCurr()) { wo_ref = _result_menu->getItemCurr()->getWORef(); } setWORef(wo_ref); return &(ae()); } /** * Called whenever the buffer has changed. Updates the displayed clients. */ void SearchDialog::bufChanged(void) { InputDialog::bufChanged(); findClients(str()); } /** * Focus next item in result menu. */ void SearchDialog::histNext(void) { _result_menu->selectItemRel(1); } /** * Focus previous item in result menu. */ void SearchDialog::histPrev(void) { _result_menu->selectItemRel(-1); } /** * Update size making sure result menu fits. */ void SearchDialog::updateSize(const Geometry &head) { InputDialog::updateSize(head); _result_menu->setMenuWidth(_text_wo.getWidth()); } /** * Search list of clients for matching titles. * * @param search Regexp to search, case insensitive * @return Number of matches */ uint SearchDialog::findClients(const std::string &search) { // Do nothing if search has not changed. if (_previous_search == search) { return _result_menu->size(); } _previous_search = search; _result_menu->removeAll(); if (search.size() > 0) { RegexString search_re("/" + search + "/i"); if (! search_re.is_match_ok()) { return 0; } std::vector matches; Client::client_cit it(Client::client_begin()); for (; it != Client::client_end(); ++it) { if ((*it)->isFocusable() && ! (*it)->isSkip(SKIP_FOCUS_TOGGLE) && search_re == (*it)->getTitle()->getReal()) { matches.push_back(*it); } } for (it = matches.begin(); it != matches.end(); ++it) { _result_menu->insert((*it)->getTitle()->getVisible(), false, *it, (*it)->getIcon()); } } // Rebuild menu and make room for it _result_menu->buildMenu(); Geometry head; X11::getHeadInfo(getHead(), head); unsigned int width, height; getInputSize(head, width, height); if (_result_menu->size()) { resizeChild(_text_wo.getWidth(), height + _result_menu->getHeight()); X11::raiseWindow(_result_menu->getWindow()); // Render first item as selected, needs to be done after // map/raise. _result_menu->selectItemNum(0); } else { resizeChild(_text_wo.getWidth(), height); X11::lowerWindow(_result_menu->getWindow()); } return 0; } /** * Unmap window and clear buffer, result menu and window reference. */ void SearchDialog::unmapWindow(void) { if (_mapped) { InputDialog::unmapWindow(); setWORef(0); bufClear(); // Clear the menu and hide it. X11::clearWindow(_result_menu->getWindow()); _previous_search = ""; X11::lowerWindow(_result_menu->getWindow()); } } pekwm-0.4.4/src/wm/MenuHandler.hh0000664000175000017500000000332015126136025012261 // // MenuHandler.hh for pekwm // Copyright (C) 2009-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_MENUHANDLER_HH_ #define _PEKWM_MENUHANDLER_HH_ #include "config.h" #include #include #include "PMenu.hh" class Theme; class ActionHandler; /** * Menu manager, creates, reloads and delete menus. */ class MenuHandler { public: typedef std::map menu_map; typedef menu_map::iterator menu_map_it; typedef menu_map::const_iterator menu_map_cit; static PMenu *getMenu(const std::string &name); /** * Return list with names of loaded menus. */ static std::vector getMenuNames(void) { std::vector menu_names; menu_map_cit it = _menu_map.begin(); for (; it != _menu_map.end(); ++it) { menu_names.push_back(it->second->getName()); } return menu_names; } static void hideAllMenus(void) { menu_map_it it = _menu_map.begin(); for (; it != _menu_map.end(); ++it) { it->second->unmapAll(); } } static void reloadMenus(ActionHandler *act); static void deleteMenus(void); private: static PMenu *createMenu(ActionHandler *act, const std::string &name); static bool loadMenuConfig(const std::string &menu_file, CfgParser &menu_cfg); static void createMenusLoadConfiguration(ActionHandler *act); static void reloadStandaloneMenus(ActionHandler *act, CfgParser::Entry *section); static TimeFiles _cfg_files; /** Set to true when menus have been loaded from the configuration. */ static bool _config_loaded; /** Map from menu name to menu */ static std::map _menu_map; }; #endif // _PEKWM_MENUHANDLER_HH_ pekwm-0.4.4/src/wm/ResizeEventHandler.cc0000664000175000017500000001422715126136025013616 // // ResizeEvenHandler.cc for pekwm // Copyright (C) 2022 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "Debug.hh" #include "ResizeEventHandler.hh" ResizeEventHandler::ResizeEventHandler(Config *cfg, Frame* frame, Client *client, bool left, bool x, bool top, bool y) : _cfg(cfg), _outline(! pekwm::config()->getOpaqueResize()), _init(false), _frame(frame), _client(client), _left(left), _x(x), _top(top), _y(y) { frame->getGeometry(_gm); frame->getGeometry(_old_gm); _frame_shaded = frame->isShaded() ? _gm.height : 0; pekwm::observerMapping()->addObserver(frame, this, 100); pekwm::observerMapping()->addObserver(client, this, 100); } ResizeEventHandler::~ResizeEventHandler(void) { if (_frame) { pekwm::observerMapping()->removeObserver(_frame, this); } if (_client) { pekwm::observerMapping()->removeObserver(_client, this); } stopResize(); } void ResizeEventHandler::notify(Observable *observable, Observation *observation) { if (observation != &PWinObj::pwin_obj_deleted) { return; } if (observable == _frame) { P_TRACE("frame " << _frame << " lost while grouping drag"); _frame = nullptr; } if (observable == _client) { P_TRACE("client " << _client << " lost while grouping drag"); _client = nullptr; } } bool ResizeEventHandler::initEventHandler(void) { if (! _frame || _frame->isShaded() || ! _client || ! _client->allowResize() || ! X11::grabPointer(X11::getRoot(), ButtonMotionMask|ButtonReleaseMask, CURSOR_RESIZE)) { return false; } _frame->setStateFullscreen(STATE_UNSET); // the basepoint of our window _click_x = _left ? (_gm.x + _gm.width) : _gm.x; _click_y = _top ? (_gm.y + _gm.height) : _gm.y; // offset used relative to events int pointer_x = _gm.x; int pointer_y = _gm.y; X11::getMousePosition(pointer_x, pointer_y); _offset_x = (_left ? _gm.x : (_gm.x + _gm.width)) - pointer_x; _offset_y = (_top ? _gm.y : (_gm.y + _gm.height)) - pointer_y; updateStatusWindow(true); // grab server to avoid traces of invert draws if (_outline) { X11::grabServer(); drawOutline(); } _init = true; return true; } EventHandler::Result ResizeEventHandler::handleButtonPressEvent(XButtonEvent*) { // mark as processed disabling wm processing of these events. return EventHandler::EVENT_PROCESSED; } EventHandler::Result ResizeEventHandler::handleButtonReleaseEvent(XButtonEvent*) { return stopResize(); } EventHandler::Result ResizeEventHandler::handleExposeEvent(XExposeEvent*) { return EventHandler::EVENT_SKIP; } EventHandler::Result ResizeEventHandler::handleKeyEvent(XKeyEvent*) { // mark as processed disabling wm processing of these events. return EventHandler::EVENT_PROCESSED; } EventHandler::Result ResizeEventHandler::handleMotionNotifyEvent(XMotionEvent *ev) { if (! _frame || ! _client) { return stopResize(); } // flush all pointer motion, no need to redraw and redraw. X11::removeMotionEvents(); // clear previous otline before updating the geometry drawOutline(); int new_x = _x ? _offset_x + ev->x : 0; int new_y = _y ? _offset_y + ev->y : 0; recalcResizeDrag(new_x, new_y); updateStatusWindow(false); if (! _outline && _old_gm != _gm) { // only updated when needed when in opaque mode _frame->moveResize(_gm.x, _gm.y, _gm.width, _gm.height); } _old_gm = _gm; drawOutline(); return EventHandler::EVENT_PROCESSED; } EventHandler::Result ResizeEventHandler::stopResize(void) { if (_init) { if (_cfg->isShowStatusWindow()) { pekwm::statusWindow()->unmapWindow(); } X11::ungrabPointer(); drawOutline(); if (_frame) { // Make sure the state isn't set to maximized after // the Frame has been resized. _frame->clearFillStateAfterResize(); if (_outline) { _frame->moveResize(_gm.x, _gm.y, _gm.width, _gm.height); } } if (_outline) { X11::ungrabServer(true); } _init = false; } return EventHandler::EVENT_STOP_SKIP; } void ResizeEventHandler::drawOutline(void) { if (_outline) { PDecor::drawOutline(_gm, _frame_shaded); } } void ResizeEventHandler::updateStatusWindow(bool map) { if (! _cfg->isShowStatusWindow()) { return; } char buf[128]; _frame->getDecorInfo(buf, 128, _gm); StatusWindow *sw = pekwm::statusWindow(); Geometry *sw_gm = _cfg->isShowStatusWindowOnRoot() ? nullptr : &_gm; if (map) { // draw before map to avoid resize after the window is mapped. sw->draw(buf, true, sw_gm); sw->mapWindowRaised(); } sw->draw(buf, true, sw_gm); } /** * Updates the width, height of the frame when resizing it. */ void ResizeEventHandler::recalcResizeDrag(int nx, int ny) { if (_left) { if (nx >= signed(_click_x - _frame->decorWidth(_frame))) { nx = _click_x - _frame->decorWidth(_frame) - 1; } } else if (nx <= signed(_click_x + _frame->decorWidth(_frame))) { nx = _click_x + _frame->decorWidth(_frame) + 1; } if (_top) { if (ny >= signed(_click_y - _frame->decorHeight(_frame))) { ny = _click_y - _frame->decorHeight(_frame) - 1; } } else if (ny <= signed(_click_y + _frame->decorHeight(_frame))) { ny = _click_y + _frame->decorHeight(_frame) + 1; } if (_x) { _gm.width = _left ? (_click_x - nx) : (nx - _click_x); } _gm.width -= _frame->decorWidth(_frame); if (_y) { _gm.height = _top ? (_click_y - ny) : (ny - _click_y); } _gm.height -= _frame->decorHeight(_frame); _client->getAspectSize(&_gm.width, &_gm.height, _gm.width, _gm.height); ensureWithinXSizeHints(_gm.width, _gm.height); _gm.width += _frame->decorWidth(_frame); _gm.height += _frame->decorHeight(_frame); _gm.x = _left ? (_click_x - _gm.width) : _click_x; _gm.y = _top ? (_click_y - _gm.height) : _click_y; } void ResizeEventHandler::ensureWithinXSizeHints(uint &width, uint &height) { XSizeHints hints = _client->getActiveSizeHints(); if (hints.flags & PMinSize) { if (signed(width) < hints.min_width) { width = hints.min_width; } if (signed(height) < hints.min_height) { height = hints.min_height; } } if (hints.flags & PMaxSize) { if (signed(width) > hints.max_width) { width = hints.max_width; } if (signed(height) > hints.max_height) { height = hints.max_height; } } } pekwm-0.4.4/src/wm/Frame.hh0000664000175000017500000001555015126136025011121 // // Frame.hh for pekwm // Copyright (C) 2003-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_FRAME_HH_ #define _PEKWM_FRAME_HH_ #include "config.h" #include "pekwm.hh" #include "PDecor.hh" #include "Client.hh" #include "tk/Action.hh" class PWinObj; class Strut; class AutoProperty; #include class Frame : public PDecor { public: typedef std::vector frame_vec; typedef frame_vec::iterator frame_it; typedef frame_vec::const_iterator frame_cit; Frame(Client *client, AutoProperty *ap); virtual ~Frame(void); // START - PWinObj interface. virtual AtomName getWinType() const; virtual void iconify(void); virtual void toggleSticky(); virtual void setWorkspace(unsigned int workspace); virtual void setLayer(Layer layer); virtual const ActionEvent *handleMotionEvent(XMotionEvent *ev); virtual const ActionEvent *handleEnterEvent(XCrossingEvent *ev); virtual const ActionEvent *handleLeaveEvent(XCrossingEvent *ev); virtual const ActionEvent *handleMapRequest(XMapRequestEvent *ev); virtual const ActionEvent *handleUnmapEvent(XUnmapEvent *ev); // END - PWinObj interface. #ifdef PEKWM_HAVE_SHAPE void handleShapeEvent(XShapeEvent *ev); #endif // PEKWM_HAVE_SHAPE // START - PDecor interface. virtual bool allowMove(void) const; virtual void addChild(PWinObj *child, std::vector::iterator *it = 0); virtual void removeChild(PWinObj *child, bool do_delete = true); virtual void activateChild(PWinObj *child); virtual void updatedChildOrder(void); virtual void updatedActiveChild(void); virtual void getDecorInfo(char *buf, uint size, const Geometry& gm); virtual void giveInputFocus(void); virtual bool setShaded(StateAction sa); virtual void setSkip(uint skip); virtual void clearFillStateAfterResize(); // END - PDecor interface. Client *getActiveClient() const; void addChildOrdered(Client *child); static Frame *findFrameFromID(uint id); // START - Iterators static uint frame_size(void) { return _frames.size(); } static frame_cit frame_begin(void) { return _frames.begin(); } static frame_cit frame_end(void) { return _frames.end(); } static frame_vec::reverse_iterator frame_rbegin(void) { return _frames.rbegin(); } static frame_vec::reverse_iterator frame_rend(void) { return _frames.rend(); } Client *getTransFor(void) const { return _client?_client->getTransientForClient():0; } bool hasTrans(void) const { return _client && _client->hasTransients(); } // Call getTransBegin() only (!) if hasTrans() == true. std::vector::const_iterator getTransBegin(void) const { return _client->getTransientsBegin(); } // Call getTransEnd() only (!) if hasTrans() == true. std::vector::const_iterator getTransEnd(void) const { return _client->getTransientsEnd(); } // END - Iterator inline uint getId(void) const { return _id; } void setId(uint id); Frame *detachClient(Client *client, int x, int y); const ClassHint& getClassHint() const { return _class_hint; } void setGeometry(const std::string& geometry, int head=-1, bool honour_strut=false); const Geometry &getOldGeometry() const { return _old_gm; } void setOldGeometry(const Geometry &gm) { _old_gm = gm; } void growDirection(uint direction); void moveToHead(const std::string& arg); void moveToHead(int head_nr); void updateInactiveChildInfo(void); // state actions void setStateMaximized(StateAction sa, bool horz, bool vert, bool fill); void setStateFullscreen(StateAction sa); void setStateSticky(StateAction sa); void setStateAlwaysOnTop(StateAction sa); void setStateAlwaysBelow(StateAction sa); void setStateDecorBorder(StateAction sa); void setStateDecorTitlebar(StateAction sa); void setStateIconified(StateAction sa); void setStateTagged(StateAction sa, bool behind); void setStateSkip(StateAction sa, uint skip); void setStateTitle(StateAction sa, Client *client, const std::string &title); void setStateMarked(StateAction sa, Client *client); void setStateOpaque(StateAction sa); void close(void); void readAutoprops(ApplyOn type = APPLY_ON_RELOAD); bool fixGeometry(void); // client message handling void handleConfigureRequest(XConfigureRequestEvent *ev, Client *client); const ActionEvent *handleClientMessage(XClientMessageEvent *ev, Client *client); void handlePropertyChange(XPropertyEvent *ev, Client *client); static Frame *getTagFrame(void) { return _tag_frame; } static bool getTagBehind(void) { return _tag_behind; } static void resetFrameIDs(void); protected: // used for testing Frame(void); // BEGIN - PDecor interface virtual void decorUpdated(void); virtual std::string getDecorName(void); // END - PDecor interface static void applyGeometry(Geometry &gm, const Geometry &ap_gm, int mask); static void applyGeometry(Geometry &gm, const Geometry &ap_gm, int mask, const Geometry &screen_gm); private: Frame(const Frame&); Frame& operator=(const Frame&); void grabButtons(void); void handleClientStateMessage(XClientMessageEvent *ev, Client *client); static bool getStateActionFromMessage(XClientMessageEvent *ev, StateAction &sa); void handleStateAtom(StateAction sa, Atom atom, Client *client); void handleCurrentClientStateAtom(StateAction sa, Atom atom, Client *client); bool isRequestGeometryFullscreen(XConfigureRequestEvent *ev); void getMaxBounds(int &max_x,int &max_r, int &max_y, int &max_b); void calcSizeInCells(uint &width, uint &height, const Geometry& gm); void setGravityPosition(int gravity, int &x, int &y, int diff_w, int diff_h); void downSize(Geometry &gm, bool keep_x, bool keep_y); void handleTitleChange(Client *client, bool read_name); void getState(Client *cl); void applyState(Client *cl); void setFrameExtents(Client *cl); void setupAPGeometry(Client *client, AutoProperty *ap); void workspacesInsert(); void workspacesRemove(); static uint findFrameID(void); static void returnFrameID(uint id); private: uint _id; // unique id of the frame Client *_client; // to skip all the casts from PWinObj ClassHint _class_hint; // frame information used when maximizing / going fullscreen Geometry _old_gm; uint _non_fullscreen_decor_state; Layer _non_fullscreen_layer; static frame_vec _frames; //!< Vector of all Frames. static std::vector _frameid_list; //!< Vector of free Frame IDs. static ActionEvent _ae_move; static ActionEvent _ae_resize; static ActionEvent _ae_move_resize; // Tagging, static as only one Frame can be tagged static Frame *_tag_frame; //!< Pointer to tagged frame. static bool _tag_behind; //!< Tagging actions will set behind. // EWMH static const int NET_WM_STATE_REMOVE = 0; // remove/unset property static const int NET_WM_STATE_ADD = 1; // add/set property static const int NET_WM_STATE_TOGGLE = 2; // toggle property }; #endif // _PEKWM_FRAME_HH_ pekwm-0.4.4/src/wm/CmdDialog.cc0000664000175000017500000000666715126136025011711 // // CmdDialog.cc for pekwm // Copyright (C) 2023 Claes Nästén // Copyright (C) 2004-2015 the pekwm development team // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include #include extern "C" { #include #include // XLookupString #include } #include "Charset.hh" #include "CmdDialog.hh" #include "Config.hh" #include "tk/PWinObj.hh" /** * CmdDialog constructor, init and load history file. * * @todo Make size configurable. */ CmdDialog::CmdDialog() : InputDialog("Enter command"), _pos_on_complete(0), _exec_count(0) { _type = PWinObj::WO_CMD_DIALOG; if (pekwm::config()->getCmdDialogHistoryFile().size() > 0) { loadHistory(pekwm::config()->getCmdDialogHistoryFile()); } } /** * CmdDialog de-structor, clean up and save history file. */ CmdDialog::~CmdDialog(void) { if (pekwm::config()->getCmdDialogHistoryFile().size() > 0) { saveHistory(pekwm::config()->getCmdDialogHistoryFile()); } } /** * Parses _buf and tries to generate an ActionEvent * @return Pointer to ActionEvent. */ ActionEvent* CmdDialog::exec(void) { Config *cfg = pekwm::config(); // Update history addHistory(str(), cfg->isCmdDialogHistoryUnique(), static_cast(cfg->getCmdDialogHistorySize())); // Persist changes if (cfg->getCmdDialogHistorySaveInterval() > 0 && cfg->getCmdDialogHistoryFile().size() > 0 && ++_exec_count > cfg->getCmdDialogHistorySaveInterval()) { saveHistory(cfg->getCmdDialogHistoryFile()); _exec_count = 0; } // Check if it is a valid Action, if not assume it is a shell // command and try to execute it. if (! ActionConfig::parseAction(str(), ae().action_list.back(), KEYGRABBER_OK)) { ae().action_list.back().setAction(ACTION_EXEC); ae().action_list.back().setParamS(str()); } return &(ae()); } /** * Map window, overloaded to refresh completions. */ void CmdDialog::mapWindow(void) { InputDialog::mapWindow(); _completer.refresh(); } /** * Unmaps window, overloaded to clear buffer and unset reference. */ void CmdDialog::unmapWindow(void) { if (_mapped) { InputDialog::unmapWindow(); setWORef(0); buf().clear(); _completer.clear(); } } /** * Tab completion, complete word at cursor position. */ void CmdDialog::complete(void) { // Find completion if changed since last time. if (str() != _buf_on_complete_result) { InputDialog::complete(); _complete_list = _completer.find_completions(str(), buf().pos()); _complete_it = _complete_list.begin(); } if (_complete_list.size()) { uint pos = buf().pos(); std::string val = _completer.do_complete(_buf_on_complete, pos, _complete_list, _complete_it); buf().setBuf(val); buf().setPos(pos); _buf_on_complete_result = val; } } /** * Restore buffer and clear completion buffers. */ void CmdDialog::completeAbort(void) { if (_buf_on_complete.size()) { buf().setBuf(_buf_on_complete); buf().setPos(_pos_on_complete); } completeReset(); } /** * Clear the completion buffer. */ void CmdDialog::completeReset(void) { _buf_on_complete = ""; _buf_on_complete_result = ""; _pos_on_complete = 0; } /** * Map CmdDialog centered on wo_ref is specified, else _wo_ref. */ void CmdDialog::mapCentered(const std::string &buf, const Geometry &geom, PWinObj *wo_ref) { if (wo_ref != 0) { setWORef(wo_ref); } InputDialog::mapCentered(buf, geom, wo_ref); } pekwm-0.4.4/src/wm/Workspaces.hh0000664000175000017500000001524715126136025012213 // // Workspaces.hh for pekwm // Copyright (C) 2002-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_WORKSPACES_HH_ #define _PEKWM_WORKSPACES_HH_ #include "config.h" #include #include "pekwm.hh" #include "WinLayouter.hh" #include "WorkspaceIndicator.hh" class PWinObj; class Frame; class Workspace { public: Workspace(void); Workspace(const Workspace &w); ~Workspace(void); Workspace &operator=(const Workspace &w); inline const std::string &getName() const { if (! _name_override.empty()) { return _name_override; } return _name; } inline void setName(const std::string &name) { _name = name; } inline void setNameOverride(const std::string &name) { _name_override = name; } PWinObj* getLastFocused(bool verify) const; void setLastFocused(PWinObj* wo); private: std::string _name; std::string _name_override; PWinObj *_last_focused; }; class Workspaces { public: typedef std::vector::iterator iterator; typedef std::vector::const_iterator const_iterator; typedef std::vector::reverse_iterator reverse_iterator; typedef std::vector::const_reverse_iterator const_reverse_iterator; typedef std::map win_layouter_map; static void init(); static void cleanup(); static inline iterator begin(void) { return _wobjs.begin(); } static inline iterator end(void) { return _wobjs.end(); } static inline reverse_iterator rbegin(void) { return _wobjs.rbegin(); } static inline reverse_iterator rend(void) { return _wobjs.rend(); } static inline uint size(void) { return _workspaces.size(); } static inline uint getActive(void) { return _active; } static inline uint getPrevious(void) { return _previous; } static uint getRow(int active = -1) { if (active < 0) { active = _active; } return _per_row ? (active / _per_row) : 0; } static uint getRowMin(void) { return _per_row ? (getRow() * _per_row) : 0; } static uint getRowMax(void) { return _per_row ? (getRowMin() + _per_row - 1) : size() - 1; } static uint getRows(void) { if (! _per_row) { return 1; } return size() / _per_row + ((size() % _per_row) ? 1 : 0); } static uint getPerRow(void) { return _per_row ? _per_row : size(); } static bool setSize(uint number); static void setPerRow(uint per_row) { _per_row = per_row; } static void setNames(void); static void setLayoutModels(const std::vector &models); static bool setWorkspace(uint num, bool focus, bool back_and_forth=false); static bool gotoWorkspace(uint direction, bool focus, bool warp); static Workspace &getWorkspace(uint num) { return _workspaces[num]; } static Workspace &getActWorkspace() { return _workspaces[_active]; } static void layout(Frame *frame, Window parent=None, int win_layouter_types=0); static void insert(PWinObj* wo, bool raise = true); static void remove(const PWinObj* wo); static void hideAll(uint workspace); static void unhideAll(uint workspace, bool focus); static PWinObj* getLastFocused(uint workspace); static void setLastFocused(uint workspace, PWinObj* wo); static bool raise(PWinObj* wo); static bool lower(PWinObj* wo); static void restack(PWinObj* wo, PWinObj* sibling, long detail); static bool handleFullscreenBeforeRaise(PWinObj* wo); static bool isOccluding(const PWinObj* wo, const PWinObj* sibling); static PWinObj* getTopFocusableWO(uint type_mask); static void updateClientList(void); static void updateClientStackingList(void); static void placeWoInsideScreen(PWinObj *wo); static void giveInputFocus(PWinObj *wo, bool force = false); static void findWOAndFocus(PWinObj *search); static PWinObj *findUnderPointer(void); static PWinObj *findDirectional(PWinObj *wo, DirectionType dir, uint skip = 0); static Frame* getNextFrame(Frame* frame, bool mapped, uint mask = 0); static Frame* getPrevFrame(Frame* frame, bool mapped, uint mask = 0); static void fixStacking(PWinObj *); static void showWorkspaceIndicator(void); static void hideWorkspaceIndicator(void); // list iterators static std::vector::iterator mru_begin(void) { return _mru.begin(); } static std::vector::iterator mru_end(void) { return _mru.end(); } // adds static void addToMRUFront(Frame *frame) { if (frame) { removeFromMRU(frame); _mru.insert(_mru.begin(), frame); } } static void addToMRUBack(Frame *frame) { if (frame) { removeFromMRU(frame); _mru.push_back(frame); } } static void removeFromMRU(Frame *frame) { _mru.erase(std::remove(_mru.begin(), _mru.end(), frame), _mru.end()); } protected: static PWinObj *findWOAndFocusFind(bool stacking); static bool restackTopIf(PWinObj* wo); static bool restackBottomIf(PWinObj* wo); static bool swapInStack(PWinObj* wo_under, PWinObj* wo_over); static bool stackAbove(PWinObj* wo_under, PWinObj* wo_over); static iterator find(const PWinObj *wo); static bool layoutOnHead(PWinObj *wo, int win_layouter_types, Window parent, const Geometry &gm, int ptr_x, int ptr_y); static bool layoutOnHeadTypes(PWinObj *wo, int win_layouter_types, Window parent, const Geometry &gm, int ptr_x, int ptr_y); /** All PWinObjs, the highest stacked PWinObj is kept at the back. */ static std::vector _wobjs; /** The most recently used frame is kept at the front. */ static std::vector _mru; private: static WorkspaceIndicator *getWorkspaceIndicator() { if (_workspace_indicator == nullptr) { _workspace_indicator = new WorkspaceIndicator(); } return _workspace_indicator; } static PWinObj *findWOAndFocusStacking(); static PWinObj *findWOAndFocusMRU(); static void findWOAndFocusRaise(PWinObj *wo); static uint overlapPercent(PWinObj *wo); static bool restack(PWinObj *wo, long detail); static bool restackSibling(PWinObj *wo, PWinObj *sibling, long detail); static void stackAt(iterator it); static void clearLayoutModels(void); static void buildClientList(std::vector &windows, bool report_all); static bool warpToWorkspace(uint num, int dir); static bool lowerFullscreenWindows(Layer new_layer); static std::string getWorkspaceName(uint num); static uint _active; /**< Current active workspace. */ static uint _previous; /**< Previous workspace. */ static uint _per_row; /**< Workspaces per row in layout. */ /** List of layouters tried in sequence when placing windows. */ static std::vector _layout_models; /** Window popping up when switching workspace */ static WorkspaceIndicator *_workspace_indicator; static std::vector _workspaces; static win_layouter_map _win_layouters; }; #endif // _PEKWM_WORKSPACES_HH_ pekwm-0.4.4/src/wm/WinLayouter.cc0000664000175000017500000002300715126136025012333 // // WinLayouter.cc for pekwm // Copyright (C) 2021-2023 Claes Nästén // Copyright © 2012-2013 Andreas Schlick // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "pekwm.hh" #include "Client.hh" #include "Debug.hh" #include "Frame.hh" #include "Util.hh" #include "ManagerWindows.hh" #include "WinLayouter.hh" #include "Workspaces.hh" #include "X11.hh" static Util::StringTo win_layouter_type_map[] = {{"SMART", WIN_LAYOUTER_SMART}, {"CENTERED", WIN_LAYOUTER_CENTERED}, {"CENTEREDONPARENT", WIN_LAYOUTER_CENTEREDONPARENT}, {"MOUSENOTUNDER", WIN_LAYOUTER_MOUSENOTUNDER}, {"MOUSECENTERED", WIN_LAYOUTER_MOUSECENTERED}, {"MOUSETOPLEFT", WIN_LAYOUTER_MOUSECTOPLEFT}, {nullptr, WIN_LAYOUTER_NO}}; static void populateWvec(const PWinObj *wo, std::vector &wvec) { Workspaces::iterator it(Workspaces::begin()); Workspaces::iterator end(Workspaces::end()); for (; it != end; ++it) { // Include standard window objects excluding the provded wo. // Windows that are not mapped, desktop windows and iconified // windows are excludes. enum PWinObj::Type it_type = (*it)->getType(); if (wo == (*it) || ! (*it)->isMapped() || ! (it_type == PWinObj::WO_FRAME || it_type == PWinObj::WO_MENU) || ((*it)->getLayer() == LAYER_DESKTOP)) { continue; } // Skip windows tagged as Maximized as they cause no space // to be found. if ((*it)->isType(PWinObj::WO_FRAME)) { Frame *frame = static_cast(*it); Client *client = frame->getActiveClient(); if (client && (client->isFullscreen() || (client->isMaximizedVert() && client->isMaximizedHorz()))) { continue; } } wvec.push_back(*it); } } static PWinObj* isEmptySpace(int x, int y, const PWinObj* wo, std::vector &wvec) { if (wo == nullptr) { return nullptr; } if (wvec.empty()) { populateWvec(wo, wvec); } for (unsigned i=0; i < wvec.size(); ++i) { // Check if window is on some other windows space if ((wvec[i]->getX() < signed(x + wo->getWidth())) && (signed(wvec[i]->getX() + wvec[i]->getWidth()) > x) && (wvec[i]->getY() < signed(y + wo->getHeight())) && (signed(wvec[i]->getY() + wvec[i]->getHeight()) > y)) { return wvec[i]; } } return nullptr; } /** * Window layouter that tries to find empty space to place the client in * @return true if client got placed, else false */ class LayouterSmart : public WinLayouter { public: LayouterSmart() : WinLayouter(WIN_LAYOUTER_SMART) {} virtual ~LayouterSmart() {} private: virtual bool layout(PWinObj *wo, Window parent, const Geometry &head_gm, int ptr_x, int ptr_y) { PWinObj *wo_e; bool placed = false; std::vector wvec; Config* cfg = pekwm::config(); int step_x = (cfg->getPlacementLtR()) ? 1 : -1; int step_y = (cfg->getPlacementTtB()) ? 1 : -1; int offset_x = (cfg->getPlacementLtR()) ? cfg->getPlacementOffsetX() : -cfg->getPlacementOffsetX(); int offset_y = (cfg->getPlacementTtB()) ? cfg->getPlacementOffsetY() : -cfg->getPlacementOffsetY(); int start_x, start_y, test_x, test_y; // Wrap these up, to get proper checking of space. uint wo_width = wo->getWidth() + cfg->getPlacementOffsetX(); uint wo_height = wo->getHeight() + cfg->getPlacementOffsetY(); start_x = cfg->getPlacementLtR() ? head_gm.x : head_gm.x + head_gm.width - wo_width; start_y = cfg->getPlacementTtB() ? head_gm.y : head_gm.y + head_gm.height - wo_height; if (cfg->getPlacementRow()) { // row placement test_y = start_y; while (! placed && (cfg->getPlacementTtB() ? test_y + wo_height <= head_gm.y + head_gm.height : test_y >= head_gm.y)) { test_x = start_x; while (! placed && (cfg->getPlacementLtR() ? test_x + wo_width <= head_gm.x + head_gm.width : test_x >= head_gm.x)) { // see if we can place the window here wo_e = isEmptySpace(test_x, test_y, wo, wvec); if (wo_e) { placed = false; test_x = cfg->getPlacementLtR() ? wo_e->getX() + wo_e->getWidth() : wo_e->getX() - wo_width; } else { placed = true; wo->move(test_x + offset_x, test_y + offset_y); } } test_y += step_y; } } else { // column placement test_x = start_x; while (! placed && (cfg->getPlacementLtR() ? test_x + wo_width <= head_gm.x + head_gm.width : test_x >= head_gm.x)) { test_y = start_y; while (! placed && (cfg->getPlacementTtB() ? test_y + wo_height <= head_gm.y + head_gm.height : test_y >= head_gm.y)) { // see if we can place the window here wo_e = isEmptySpace(test_x, test_y, wo, wvec); if (wo_e) { placed = false; test_y = cfg->getPlacementTtB() ? wo_e->getY() + wo_e->getHeight() : wo_e->getY() - wo_height; } else { placed = true; wo->move(test_x + offset_x, test_y + offset_y); } } test_x += step_x; } } return placed; } }; /** * Place windows centered on the current head. */ class LayouterCentered : public WinLayouter { public: LayouterCentered(void) : WinLayouter(WIN_LAYOUTER_CENTERED) {} virtual ~LayouterCentered(void) { }; virtual bool layout(PWinObj *wo, Window parent, const Geometry &head_gm, int ptr_x, int ptr_y) { Geometry gm = head_gm.center(wo->getGeometry()); wo->move(gm.x, gm.y); return true; } }; /** * Place window centered on its parent (excluding root as parent) */ class LayouterCenteredOnParent : public WinLayouter { public: LayouterCenteredOnParent(void) : WinLayouter(WIN_LAYOUTER_CENTEREDONPARENT) { } virtual ~LayouterCenteredOnParent(void) { }; virtual bool layout(PWinObj *wo, Window parent, const Geometry &head_gm, int ptr_x, int ptr_y) { if (parent == None || parent == X11::getRoot()) { return false; } PWinObj *parent_wo = PWinObj::findPWinObj(parent); if (parent_wo != nullptr) { const Geometry &parent_gm = parent_wo->getGeometry(); Geometry gm = parent_gm.center(wo->getGeometry()); wo->move(gm.x, gm.y); return true; } return false; } }; /** * Place the window in one of the screen corners where it does not end up under * the pointer. */ class LayouterMouseNotUnder : public WinLayouter { public: LayouterMouseNotUnder() : WinLayouter(WIN_LAYOUTER_MOUSENOTUNDER) {} virtual ~LayouterMouseNotUnder() {} virtual bool layout(PWinObj *wo, Window parent, const Geometry &head_gm, int ptr_x, int ptr_y) { // compensate for head offset ptr_x -= head_gm.x; ptr_y -= head_gm.y; // divide the screen into four rectangles using the pointer as // divider if (wo->getWidth() < unsigned(ptr_x) && wo->getHeight() < head_gm.height) { wo->move(head_gm.x, head_gm.y); return true; } if (wo->getWidth() < head_gm.width && wo->getHeight() < unsigned(ptr_y)) { wo->move(head_gm.x + head_gm.width - wo->getWidth(), head_gm.y); return true; } if (wo->getWidth() < head_gm.width - ptr_x && wo->getHeight() < head_gm.height) { wo->move(head_gm.x + head_gm.width - wo->getWidth(), head_gm.y + head_gm.height - wo->getHeight()); return true; } if (wo->getWidth() < head_gm.width && wo->getHeight() < head_gm.height - ptr_y) { wo->move(head_gm.x, head_gm.y + head_gm.height - wo->getHeight()); return true; } return false; } }; /** * Places the window centered under the mouse */ class LayouterMouseCentred : public WinLayouter { public: LayouterMouseCentred() : WinLayouter(WIN_LAYOUTER_MOUSECENTERED) {} ~LayouterMouseCentred() {} private: virtual bool layout(PWinObj *wo, Window parent, const Geometry &head_gm, int ptr_x, int ptr_y) { Geometry gm(ptr_x - (wo->getWidth() / 2), ptr_y - (wo->getHeight() / 2), wo->getWidth(), wo->getHeight()); pekwm::rootWo()->placeInsideScreen(gm); wo->move(gm.x, gm.y); return true; } }; /** * Places the window like the menu gets placed, top left corner under the * pointer. */ class LayouterMouseTopLeft : public WinLayouter { public: LayouterMouseTopLeft() : WinLayouter(WIN_LAYOUTER_MOUSECTOPLEFT) {} private: virtual bool layout(PWinObj *wo, Window parent, const Geometry &head_gm, int ptr_x, int ptr_y) { Geometry gm(ptr_x, ptr_y, wo->getWidth(), wo->getHeight()); pekwm::rootWo()->placeInsideScreen(gm); wo->move(gm.x, gm.y); return true; } }; enum WinLayouterType win_layouter_type_from_string(const std::string &name) { enum WinLayouterType type = Util::StringToGet(win_layouter_type_map, name); if (type == WIN_LAYOUTER_NO) { USER_WARN("Unknown placement model: " << name); } return type; } /** * Construct a WinLayouter of the provided name. */ WinLayouter* mkWinLayouter(const std::string &name) { return mkWinLayouter(win_layouter_type_from_string(name)); } /** * Construct a WinLayouter of the provided type, caller is responsible for * freeing the returned layouter. */ WinLayouter* mkWinLayouter(enum WinLayouterType type) { switch (type) { case WIN_LAYOUTER_SMART: return new LayouterSmart(); case WIN_LAYOUTER_CENTERED: return new LayouterCentered(); case WIN_LAYOUTER_CENTEREDONPARENT: return new LayouterCenteredOnParent(); case WIN_LAYOUTER_MOUSENOTUNDER: return new LayouterMouseNotUnder(); case WIN_LAYOUTER_MOUSECENTERED: return new LayouterMouseCentred(); case WIN_LAYOUTER_MOUSECTOPLEFT: return new LayouterMouseTopLeft(); default: return nullptr; } } pekwm-0.4.4/src/wm/ActionMenu.cc0000664000175000017500000002124515126136025012115 // // ActionMenu.cc for pekwm // Copyright (C) 2002-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include #include #include "Charset.hh" #include "Debug.hh" #include "PDecor.hh" #include "PMenu.hh" #include "WORefMenu.hh" #include "ActionMenu.hh" #include "Config.hh" #include "ActionHandler.hh" #include "Client.hh" #include "Frame.hh" #include "Util.hh" #include "WmUtil.hh" #include "tk/ImageHandler.hh" #include "tk/PWinObj.hh" #include "tk/TextureHandler.hh" #include "tk/TkGlobals.hh" //! @brief ActionMenu constructor //! @param type Type of menu //! @param title Title of menu //! @param name Name of the menu, empty for dynamic else should be unique //! @param decor_name Name of decor to use, defaults to MENU. ActionMenu::ActionMenu(MenuType type, ActionHandler *act, const std::string &title, const std::string &name, const std::string &decor_name) : WORefMenu(title, name, decor_name), _act(act), _insert_at(0), _has_dynamic(false) { _menu_type = type; if (_menu_type == WINDOWMENU_TYPE) { _action_ok = WINDOWMENU_OK; } else if (_menu_type == ROOTMENU_TYPE || _menu_type == ROOTMENU_STANDALONE_TYPE) { _action_ok = ROOTMENU_OK; } } //! @brief ActionMenu destructor ActionMenu::~ActionMenu(void) { ActionMenu::removeAll(); } // START - PWinObj interface. //! @brief Rebuilds the vmenu and if it has any items after it shows it. void ActionMenu::mapWindow(void) { // find and rebuild the dynamic entries if (! isMapped() && _has_dynamic) { uint size_before = size(); if (size_before != rebuildDynamic()) { buildMenu(); } } PMenu::mapWindow(); } //! @brief Hides and removes all items created by dynamic entries. void ActionMenu::unmapWindow(void) { if (! isMapped()) { return; } if (_has_dynamic) { removeDynamic(); } PMenu::unmapWindow(); } // END - PWinObj interface. //! @brief Handle item exec. void ActionMenu::handleItemExec(PMenu::Item *item) { if (! item) { return; } ActionPerformed ap(getWORef(), item->getAE()); _act->handleAction(&ap); } /** * Re-reads the configuration clearing old entries from the menu. This * adds the ICON_PATH to the ImageHandler before loading to support * loading icons properly. * * @param section CfgParser::Entry with menu configuration */ void ActionMenu::reload(CfgParser::Entry *section) { // Clear menu removeAll(); // Parse section (if any) _insert_at = 0; { WithIconPath with_icon_path(pekwm::config(), pekwm::imageHandler()); parse(section); } // Build menu from parsed content buildMenu(); } //! @brief Checks if we have a position set for where to insert. void ActionMenu::insert(PMenu::Item *item) { if (! item) { return; } checkItemWORef(item); insert(m_begin_non_const() + _insert_at, item); ++_insert_at; } void ActionMenu::insert(std::vector::iterator at, PMenu::Item *item) { WORefMenu::insert(at, item); } void ActionMenu::insert(const std::string &name, bool parse_name, PWinObj *wo_ref, PTexture *icon) { WORefMenu::insert(name, parse_name, wo_ref, icon); } void ActionMenu::insert(const std::string &name, bool parse_name, const ActionEvent &ae, PWinObj *wo_ref, PTexture *icon) { WORefMenu::insert(name, parse_name, ae, wo_ref, icon); } //! @brief Removes a BaseMenuItem from the menu void ActionMenu::remove(PMenu::Item *item) { if (! item) { return; } if (item->getIcon()) { PTexture *icon = item->getIcon(); pekwm::textureHandler()->returnTexture(&icon); } if (item->getWORef() && (item->getWORef()->getType() == WO_MENU)) { delete item->getWORef(); } PMenu::remove(item); } void ActionMenu::removeAll(void) { while (size()) { remove(*m_begin()); } } //! @brief Parse config and push items into menu //! @param cs Section object to read config from //! @param menu BaseMenu object to push object in //! @param has_dynamic If true the menu being parsed is dynamic, defaults to // false. void ActionMenu::parse(CfgParser::Entry *section, PMenu::Item *parent) { if (! section) { return; } if (section->getValue().size()) { const std::string& title(section->getValue()); setTitle(title); _title_base = title; } CfgParser::Entry::entry_cit it = section->begin(); for (; it != section->end(); ++it) { PMenu::Item* item = nullptr; if (*(*it) == "SUBMENU") { item = parseSubmenu((*it)->getSection(), parent, (*it)->getValue()); } else if (*(*it) == "SEPARATOR") { // No icon support on separators. item = new PMenu::Item("", 0, 0); item->setType(PMenu::Item::MENU_ITEM_SEPARATOR); item->setCreator(parent); } else { item = parseItem((*it)->getSection(), parent); } // If an item was successfully created, insert it to the menu. if (item) { insert(item); } } } PMenu::Item* ActionMenu::parseSubmenu(CfgParser::Entry* section, PMenu::Item* parent, const std::string& title) { if (section == nullptr) { USER_WARN("submenu entry does not contain any section"); return nullptr; } PTexture* icon = getIcon(section->findEntry("ICON")); ActionMenu *submenu = new ActionMenu(_menu_type, _act, title, title); submenu->_menu_parent = this; submenu->parse(section, parent); submenu->buildMenu(); const std::string& sub_title = section->getValue(); PMenu::Item* item = new PMenu::Item(sub_title, true, submenu, icon); item->setCreator(parent); return item; } PMenu::Item* ActionMenu::parseItem(CfgParser::Entry* section, PMenu::Item* parent) { PMenu::Item* item = nullptr; if (section == nullptr) { return item; } // Inside of the Entry = "foo" { ... } section, here Actions and Icon // are the valid options. ActionEvent ae; CfgParser::Entry* value = section->findEntry("ACTIONS"); if (value && ActionConfig::parseActions(value->getValue(), ae, _action_ok)) { PTexture* icon = getIcon(section->findEntry("ICON")); const std::string& sub_name = section->getValue(); item = new PMenu::Item(sub_name, true, nullptr, icon); item->setCreator(parent); item->setAE(ae); if (ae.isOnlyAction(ACTION_MENU_DYN)) { _has_dynamic = true; item->setType(PMenu::Item::MENU_ITEM_HIDDEN); } } return item; } /** * Get icon texture from parser value. * * @param value Entry to get icon name from. * @return PTexture if icon was loaded, else 0. */ PTexture* ActionMenu::getIcon(CfgParser::Entry *value) { // Skip blank icons if (! value || ! value->getValue().size()) { return 0; } PTexture *icon = 0; // Try to load the icon as a complete texture specification, if // that fails load is an scaled image. icon = pekwm::textureHandler()->getTexture(value->getValue()); if (! icon) { std::string tex = "IMAGE " + value->getValue() + "#SCALED"; icon = pekwm::textureHandler()->getTexture(tex); } return icon; } /** * Executes all Dynamic entries in the menu. */ uint ActionMenu::rebuildDynamic(void) { PWinObj *wo_ref = getWORef(); // Export environment before to dynamic script. Client *client = 0; if (wo_ref && wo_ref->getType() == WO_CLIENT) { client = static_cast(wo_ref); } Client::setClientEnvironment(client); // Setup icon path before parsing. WithIconPath with_icon_path(pekwm::config(), pekwm::imageHandler()); std::vector::const_iterator it = m_begin(); for (; it != m_end(); ++it) { if ((*it)->getAE().isOnlyAction(ACTION_MENU_DYN)) { _insert_at = it - m_begin(); PMenu::Item* item = *it; CfgParser dynamic(pekwm::configScriptPath()); std::string cmd = (*it)->getAE().action_list.front().getParamS(); CfgParser::Entry *section = runDynamic(dynamic, cmd); if (section != nullptr) { _has_dynamic = true; parse(section, *it); } it = std::find(m_begin(), m_end(), item); } } _insert_at = size(); return _insert_at; } CfgParser::Entry* ActionMenu::runDynamic(CfgParser& parser, const std::string& src) { if (parser.parse(src, CfgParserSource::SOURCE_COMMAND)) { return parser.getEntryRoot()->findSection("DYNAMIC"); } return nullptr; } //! @brief Remove all entries from the menu created by dynamic entries. void ActionMenu::removeDynamic(void) { std::set dynlist; std::vector::const_iterator it = m_begin(); for (; it != m_end(); ++it) { if ((*it)->getType() == PMenu::Item::MENU_ITEM_HIDDEN) { dynlist.insert(*it); } } std::vector items_to_remove; it = m_begin(); for (; it != m_end(); ++it) { if (dynlist.find((*it)->getCreator()) != dynlist.end()) { if ((*it)->getWORef() && ((*it)->getWORef()->getType() == WO_MENU)) { delete (*it)->getWORef(); } items_to_remove.push_back(*it); } } it = items_to_remove.begin(); for (; it != items_to_remove.end(); ++it) { remove(*it); } } pekwm-0.4.4/src/wm/Config.hh0000664000175000017500000003504415164641301011274 // // Config.hh for pekwm // Copyright (C) 2022-2025 Claes Nästén // Copyright (C) 2002-2021 the pekwm development team // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_CONFIG_HH_ #define _PEKWM_CONFIG_HH_ #include "config.h" #include "pekwm.hh" #include "CfgParser.hh" #include "Debug.hh" #include "tk/Action.hh" #include #include #include extern "C" { #include } /** * Enum describing the different limits of a size limit. */ enum SizeLimitType { WIDTH_MIN = 0, WIDTH_MAX, HEIGHT_MIN, HEIGHT_MAX }; /** * Simple class describing size limitations, width and height min and * max sizes. */ class SizeLimits { public: /** SizeLimits constructor setting limits to 0. */ SizeLimits(void) { for (unsigned int i = 0; i < HEIGHT_MAX; ++i) { _limits[i] = 0; } } /** Get limit for limit type. */ unsigned int get(SizeLimitType limit) const { return _limits[limit]; } bool parse(const std::string &minimum, const std::string &maximum); private: bool parseLimit(const std::string &limit, unsigned int &min, unsigned int &max); private: unsigned int _limits[HEIGHT_MAX + 1]; /**< Limits. */ }; // CONV_OPACITY converts percentage to absolute opacity values. // The variable X containing the percent value is changed directly. #define CONV_OPACITY(X) \ X = (X == 100)?EWMH_OPAQUE_WINDOW:X*(EWMH_OPAQUE_WINDOW/100) struct BoundButton { BoundButton(uint _button, uint mod) : button(_button) { mods.push_back(mod); } uint button; std::vector mods; }; /** * Large set of configuration options stored and parsed by the * singleton Config class. */ class Config { public: typedef std::map* > mouse_action_map; Config(void); ~Config(void); bool load(const std::string &config_file); bool loadMouseConfig(const std::string &mouse_file); inline const std::string &getConfigFile(void) const { return _config_file; } // Files const std::string &getKeyFile(void) const { return _files_keys; } const std::string &getMenuFile(void) const { return _files_menu; } const std::string &getStartFile(void) const { return _files_start; } const std::string &getAutoPropsFile(void) const { return _files_autoprops; } const std::string &getThemeFile(void) const { return _files_theme; } const std::string &getThemeVariant(void) const { return _files_theme_variant; } std::string getThemeIconPath(void) const { return _files_theme + "/icons/"; } const std::string &getMouseConfigFile(void) const { return _files_mouse; } const std::string &getIconPath(void) const { return _files_icon_path; } const char *getSystemIconPath(void) const { return DATADIR "/pekwm/icons/"; } // Debug const std::string &getDebugFile() const { return _debug_file; } Debug::Level getDebugLevel() const { return _debug_level; } // Moveresize inline int getEdgeAttract(void) const { return _moveresize_edgeattract; } inline int getEdgeResist(void) const { return _moveresize_edgeresist; } inline int getWOAttract(void) const { return _moveresize_woattract; } inline int getWOResist(void) const { return _moveresize_woresist; } inline bool getOpaqueMove(void) const { return _moveresize_opaquemove; } inline bool getOpaqueResize(void) const { return _moveresize_opaqueresize; } // Screen float getScreenScale() const { if (_screen_scale_override != 0.0) { return _screen_scale_override; } return _screen_scale; } void setScreenScaleOverride(float scale) { _screen_scale_override = scale; } bool getThemeBackground(void) const { return _screen_theme_background; } uint getWorkspaces() const { return _screen_workspaces; } uint getWorkspacesPerRow() const { return _screen_workspaces_per_row; } bool isWorkspacesBackAndForth() const { return _screen_workspaces_back_and_forth; } const std::string &getWorkspaceName(uint num) const { return (num >= _screen_workspace_names.size()) ? _screen_workspace_name_default : _screen_workspace_names[num]; } int getScreenEdgeSize(EdgeType edge) const { return _screen_edge_sizes[edge]; } bool getScreenEdgeIndent(void) const { return _screen_edge_indent; } int getDoubleClickTime(void) const { return _screen_doubleclicktime; } bool isFullscreenAbove(void) const { return _screen_fullscreen_above; } bool isFullscreenDetect(void) const { return _screen_fullscreen_detect; } bool getShowFrameList(void) const { return _screen_showframelist; } bool isShowStatusWindow(void) const { return _screen_show_status_window; } bool isShowStatusWindowOnRoot(void) const { return _screen_show_status_window_on_root; } bool isShowClientID(void) const { return _screen_show_client_id; } int getShowWorkspaceIndicator() const { return _screen_show_workspace_indicator; } void setShowWorkspaceIndicator(int num) { _screen_show_workspace_indicator = num; } int getWorkspaceIndicatorScale() const { return _screen_workspace_indicator_scale; } uint getWorkspaceIndicatorOpacity() const { return _screen_workspace_indicator_opacity; } bool isPlaceNew(void) const { return _screen_place_new; } bool isFocusNew(void) const { return _screen_focus_new; } bool isFocusNewChild(void) const { return _screen_focus_new_child; } bool isOnCloseFocusStacking() const { return _screen_on_close_focus_stacking; } enum OnCloseFocusRaise getOnCloseFocusRaise() const { return _screen_on_close_focus_raise; } uint getFocusStealProtect(void) const { return _screen_focus_steal_protect; } bool isHonourRandr(void) const { return _screen_honour_randr; } bool isHonourAspectRatio(void) const { return _screen_honour_aspectratio; } CurrHeadSelector getCurrHeadSelector(void) const { return _screen_curr_head_selector; } bool isDefaultFontX11(void) const { return _screen_default_font_x11; } const std::string &getFontCharsetOverride(void) const { return _screen_font_charset_override; } bool getPlacementRow(void) const { return _screen_placement_row; } bool getPlacementLtR(void) const { return _screen_placement_ltr; } bool getPlacementTtB(void) const { return _screen_placement_ttb; } int getPlacementOffsetX(void) const { return _screen_placement_offset_x; } int getPlacementOffsetY(void) const { return _screen_placement_offset_y; } bool getClientUniqueName(void) const { return _screen_client_unique_name; } const std::string &getClientUniqueNamePre(void) const { return _screen_client_unique_name_pre; } inline const std::string &getClientUniqueNamePost(void) const { return _screen_client_unique_name_post; } bool isReportAllClients(void) const { return _screen_report_all_clients; } bool isWarpPointerOn(enum WarpOn warp_on) const { return (_screen_warp_pointer_on & warp_on) == warp_on; } // Theme const std::string &getThemeBackgroundOverride() const { return _theme_background_override; } // Menu bool isMenuSelectOn(uint val) const { return (_menu_select_mask&val); } bool isMenuEnterOn(uint val) const { return (_menu_enter_mask&val); } bool isMenuExecOn(uint val) const { return (_menu_exec_mask&val); } bool isDisplayMenuIcons(void) const { return _menu_display_icons; } uint getMenuFocusOpacity(void) const { return _menu_focus_opacity; } uint getMenuUnfocusOpacity(void) const { return _menu_unfocus_opacity; } bool isCmdDialogHistoryUnique(void) const { return _cmd_dialog_history_unique; } int getCmdDialogHistorySize(void) const { return _cmd_dialog_history_size; } const std::string &getCmdDialogHistoryFile(void) const { return _cmd_dialog_history_file; } int getCmdDialogHistorySaveInterval(void) const { return _cmd_dialog_history_save_interval; } int getHarbourDAMinSide(void) const { return _harbour_da_min_s; } int getHarbourDAMaxSide(void) const { return _harbour_da_max_s; } int getHarbourHead(void) const; bool isHarbourOntop(void) const { return _harbour_ontop; } bool isHarbourMaximizeOver(void) const { return _harbour_maximize_over; } uint getHarbourPlacement(void) const { return _harbour_placement; } uint getHarbourOrientation(void) const { return _harbour_orientation; } uint getHarbourOpacity(void) const { return _harbour_opacity; } std::vector *getMouseActionList(MouseActionListName n) { return _mouse_action_map[n]; } const std::vector& getClientMouseActionButtons(void) { return _client_mouse_action_buttons; } std::vector *getBorderListFromPosition(uint pos); std::vector *getEdgeListFromPosition(uint pos); bool isSysEnabled() const { return _sys_enabled; } // map parsing ActionAccessMask getActionAccessMask(const std::string &name); bool parseActionAccessMask(const std::string &action_mask_string, uint &mask); bool parseMoveResizeAction(const std::string &action_string, Action &action); bool parseMoveResizeActions(const std::string &actions, ActionEvent &ae); bool parseMoveResizeEvent(CfgParser::Entry *section, ActionEvent &ae); bool parseInputDialogAction(const std::string &val, Action &action); bool parseInputDialogActions(const std::string &actions, ActionEvent &ae); bool parseInputDialogEvent(CfgParser::Entry *section, ActionEvent &ae); uint getMenuMask(const std::string &mask); /** Return maximum allowed icon width. */ unsigned int getMenuIconLimit(unsigned int value, SizeLimitType limit, const std::string &name) const; bool parseMenuAction(const std::string& action_string, Action& action); bool parseMenuActions(const std::string& actions, ActionEvent& ae); bool parseMenuEvent(CfgParser::Entry *section, ActionEvent& ae); static bool parseOpacity(const std::string& value, uint &focused, uint &unfocused); protected: bool loadDebug(CfgParser::Entry *section); bool loadScreen(CfgParser::Entry *section); bool loadTheme(CfgParser::Entry *section); private: bool tryHardLoadConfig(CfgParser &cfg, std::string &file, std::string &cfg_dir); void copyConfigFiles(const std::string &cfg_dir); bool ensureConfigDirExists(const std::string &cfg_dir); void loadFiles(CfgParser::Entry *section); void loadMoveResize(CfgParser::Entry *section); void loadScreenPlacement(CfgParser::Entry *section); void loadMenu(CfgParser::Entry *section); void loadMenuIcons(CfgParser::Entry *section); void loadCmdDialog(CfgParser::Entry *section); void loadHarbour(CfgParser::Entry *section); bool loadSys(CfgParser::Entry *section); void parseButtons(CfgParser::Entry *section, std::vector* mouse_list, std::vector* mouse_buttons, ActionOk action_ok); std::string _config_file; /**< Path to config file last loaded. */ TimeFiles _cfg_files; TimeFiles _cfg_files_mouse; // files std::string _files_keys; std::string _files_menu; std::string _files_start; std::string _files_autoprops; std::string _files_theme; std::string _files_theme_variant; std::string _files_mouse; std::string _files_icon_path; /**< Path to user icon directory. */ // debug std::string _debug_file; Debug::Level _debug_level; // moveresize int _moveresize_edgeattract, _moveresize_edgeresist; int _moveresize_woattract, _moveresize_woresist; bool _moveresize_opaquemove, _moveresize_opaqueresize; // screen float _screen_scale; float _screen_scale_override; bool _screen_theme_background; uint _screen_workspaces; bool _screen_workspaces_back_and_forth; uint _screen_workspaces_per_row; std::vector _screen_workspace_names; std::string _screen_workspace_name_default; std::vector _screen_edge_sizes; bool _screen_edge_indent; int _screen_doubleclicktime; /** Flag to make fullscreen go above all windows. */ bool _screen_fullscreen_above; /** Flag to make configure request fullscreen detection. */ bool _screen_fullscreen_detect; bool _screen_showframelist; bool _screen_show_status_window; /** If true, center status window relative to current head. */ bool _screen_show_status_window_on_root; bool _screen_show_client_id; //!< Flag to display client ID in title. /** Display workspace indicator for N seconds. */ int _screen_show_workspace_indicator; /** Scale of the workspace indicator head */ int _screen_workspace_indicator_scale; uint _screen_workspace_indicator_opacity; bool _screen_place_new; bool _screen_focus_new; bool _screen_focus_new_child; /** If set to true, use stacking and not MRU order to find window to focus */ bool _screen_on_close_focus_stacking; /** If set to true, raise window being focused after closing a window. */ enum OnCloseFocusRaise _screen_on_close_focus_raise; /** Number of seconds to protect against focus stealing. */ uint _screen_focus_steal_protect; /** Boolean flag if randr information should be honoured. */ bool _screen_honour_randr; /**< if true, pekwm keeps aspect ratio (XSizeHint) */ bool _screen_honour_aspectratio; /** Setting for how current head is determined. */ CurrHeadSelector _screen_curr_head_selector; /** If true, default font is X11 and not Xmb when no type * is specified in theme. */ bool _screen_default_font_x11; /** Charset override for X11/Xmb fonts. */ std::string _screen_font_charset_override; bool _screen_placement_row; bool _screen_placement_ltr; bool _screen_placement_ttb; int _screen_placement_offset_x; int _screen_placement_offset_y; bool _screen_client_unique_name; std::string _screen_client_unique_name_pre; std::string _screen_client_unique_name_post; bool _screen_report_all_clients; int _screen_warp_pointer_on; /** Background override, use instead of theme defined background. */ std::string _theme_background_override; uint _menu_select_mask, _menu_enter_mask, _menu_exec_mask; /** Boolean flag, when true display icons in menus. */ bool _menu_display_icons; uint _menu_focus_opacity, _menu_unfocus_opacity; /** Map of name -> limit for icons in menus */ std::map _menu_icon_limits; /** Boolean flag, when true entries in the CmdDialog history are * unique. */ bool _cmd_dialog_history_unique; /** Number of entries in the history before the last entries are * dropped. */ int _cmd_dialog_history_size; /** Path to cmd dialog history file. */ std::string _cmd_dialog_history_file; /** Save history file each Nth CmdDialog exec. */ int _cmd_dialog_history_save_interval; int _harbour_da_min_s, _harbour_da_max_s; bool _harbour_ontop; bool _harbour_maximize_over; uint _harbour_placement; uint _harbour_orientation; std::string _harbour_head; int _harbour_head_nr; uint _harbour_opacity; mouse_action_map _mouse_action_map; std::vector _client_mouse_action_buttons; // sys bool _sys_enabled; }; namespace pekwm { Config* config(); } #endif // _PEKWM_CONFIG_HH_ pekwm-0.4.4/src/wm/DockApp.hh0000664000175000017500000000345615126136025011412 // // DockApp.hh for pekwm // Copyright (C) 2003-2020 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_DOCKAPP_HH_ #define _PEKWM_DOCKAPP_HH_ #include "config.h" #include "pekwm.hh" #include "AutoProperties.hh" #include "tk/PWinObj.hh" class Theme; //! @brief DockApp handling class. class DockApp : public PWinObj { public: DockApp(Window win); ~DockApp(void); // START - PWinObj interface. virtual void mapWindow(void); virtual void unmapWindow(void); // END - PWinObj interface. //! @brief Returns DockApp client width. inline uint getClientWidth(void) const { return _c_gm.width; } //! @brief Returns DockApp client height. inline uint getClientHeight(void) const { return _c_gm.height; } //! @brief Returns DockApp position. inline int getPosition(void) const { return _position; } //! @brief Sets alive state of DockApp. inline void setAlive(bool alive) { _is_alive = alive; } //! @brief Matches win against DockApp client window(s). inline bool findDockApp(Window win) { if ((win != None) && ((win == _client_window) || (win == _icon_window))) { return true; } return false; } //! @brief Matches win against DockApp window. inline bool findDockAppFromFrame(Window win) { if ((win != None) && (win == _window)) return true; return false; } void kill(void); void resize(uint width, uint height); void loadTheme(void); private: void repaint(void); void updateSize(void); void validateSize(void); void readClassHint(void); void readAutoProperties(void); Window _dockapp_window; Window _client_window, _icon_window; ClassHint _class_hint; Geometry _c_gm; int _position; // used in sorted mode Pixmap _background; bool _is_alive; }; #endif // _PEKWM_DOCKAPP_HH_ pekwm-0.4.4/src/wm/Makefile.am0000664000175000017500000000345215126136025011600 noinst_LIBRARIES = libpekwm_wm.a libpekwm_wm_a_SOURCES = ActionHandler.cc ActionHandler.hh \ ActionMenu.cc ActionMenu.hh \ AppCtrl.hh \ AutoProperties.cc AutoProperties.hh \ Client.cc Client.hh \ ClientMgr.cc ClientMgr.hh \ CmdDialog.cc CmdDialog.hh \ Completer.cc Completer.hh \ Config.cc Config.hh \ DockApp.cc DockApp.hh \ EventLoop.hh \ EventHandler.hh \ FocusToggleEventHandler.cc FocusToggleEventHandler.hh \ Frame.cc Frame.hh \ FrameListMenu.cc FrameListMenu.hh \ Globals.cc \ GroupingDragEventHandler.cc \ GroupingDragEventHandler.hh \ Harbour.cc Harbour.hh \ InputDialog.cc InputDialog.hh \ KeyGrabber.cc KeyGrabber.hh \ KeyboardMoveResizeEventHandler.cc \ KeyboardMoveResizeEventHandler.hh \ ManagerWindows.cc ManagerWindows.hh \ MenuHandler.cc MenuHandler.hh \ MoveEventHandler.cc MoveEventHandler.hh \ PDecor.cc PDecor.hh \ PMenu.cc PMenu.hh \ PWinObjReference.hh \ ResizeEventHandler.cc ResizeEventHandler.hh \ SearchDialog.cc SearchDialog.hh \ StatusWindow.cc StatusWindow.hh \ ThemeGm.cc ThemeGm.hh \ WORefMenu.cc WORefMenu.hh \ WinLayouter.cc WinLayouter.hh \ WindowManager.cc WindowManager.hh \ WmUtil.cc WmUtil.hh \ WorkspaceIndicator.cc WorkspaceIndicator.hh \ Workspaces.cc Workspaces.hh libpekwm_wm_a_CXXFLAGS = $(LIB_CFLAGS) $(TK_CFLAGS) -I../lib -I.. \ -DFEATURES="\"@PEKWM_FEATURES@\"" bin_PROGRAMS = pekwm pekwm_wm pekwm_SOURCES = pekwm.cc pekwm.hh ../pekwm_env.cc ../lib/Compat.cc pekwm_CXXFLAGS = -I../lib -I.. pekwm_wm_SOURCES = pekwm_wm.cc ../pekwm_env.cc pekwm_wm_CXXFLAGS = $(LIB_CFLAGS) $(TK_CFLAGS) -I../lib -I.. \ -DFEATURES="\"@PEKWM_FEATURES@\"" pekwm_wm_LDADD = libpekwm_wm.a ../lib/libpekwm_lib.a ../tk/libpekwm_tk.a \ $(LIB_LIBS) $(TK_LIBS) EXTRA_DIST = CMakeLists.txt pekwm-0.4.4/src/wm/SearchDialog.hh0000664000175000017500000000215115126136025012405 // // SearchDialog.cc for pekwm // Copyright (C) 2009-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_SEARCHDIALOG_HH_ #define _PEKWM_SEARCHDIALOG_HH_ #include "config.h" #include "pekwm.hh" #include "InputDialog.hh" #include "PMenu.hh" #include /** * Search dialog providing a dialog for searching clients together * with a menu that shows clients matching the search. */ class SearchDialog : public InputDialog { public: SearchDialog(); virtual ~SearchDialog(void); virtual void unmapWindow(void); protected: virtual ActionEvent *exec(void); virtual void bufChanged(void); virtual void histNext(void); virtual void histPrev(void); virtual void updateSize(const Geometry &head); private: SearchDialog(const SearchDialog&); SearchDialog& operator=(const SearchDialog&); uint findClients(const std::string &search); PMenu *_result_menu; /**< Menu for displaying results. */ /** Buffer with previous search string. */ std::string _previous_search; }; #endif // _PEKWM_SEARCHDIALOG_HH_ pekwm-0.4.4/src/wm/FrameListMenu.hh0000664000175000017500000000224715126136025012601 // // FrameListMenu.hh for pekwm // Copyright (C) 2003-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_FRAMELISTMENU_HH_ #define _PEKWM_FRAMELISTMENU_HH_ #include "config.h" #include "pekwm.hh" #include "PMenu.hh" #include "WORefMenu.hh" #include #include class Frame; class Client; class FrameListMenu : public WORefMenu { public: FrameListMenu(MenuType type, const std::string &title, const std::string &name, const std::string &decor_name = "MENU"); virtual ~FrameListMenu(void); // START - PWinObj interface. virtual void mapWindow(void); virtual void unmapWindow(void); // END - PWinObj interface. virtual void handleItemExec(PMenu::Item *item); private: void updateFrameListMenu(void); private: void buildName(Frame *frame, std::string &name); void buildFrameNames(Frame *frame, const std::string &pre_name, bool insert_separator); void handleGotomenu(Client *client); void handleIconmenu(Client *client); void handleAttach(Client *client_to, Client *client_from, bool frame); }; #endif // _PEKWM_FRAMELISTMENU_HH_ pekwm-0.4.4/src/wm/MoveEventHandler.cc0000664000175000017500000001145315126136025013261 // // MoveEvenHandler.cc for pekwm // Copyright (C) 2021 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "Debug.hh" #include "ActionHandler.hh" #include "MoveEventHandler.hh" MoveEventHandler::MoveEventHandler(Config* cfg, PDecor* decor, int x_root, int y_root) : _cfg(cfg), _outline(!cfg->getOpaqueMove()), _show_status_window(cfg->isShowStatusWindow()), _center_on_root(cfg->isShowStatusWindowOnRoot()), _curr_edge(SCREEN_EDGE_NO), _init(false), _decor(decor) { decor->getGeometry(_gm); decor->getGeometry(_last_gm); _x = x_root - _gm.x; _y = y_root - _gm.y; _decor_shaded = decor->isShaded() ? _gm.height : 0; pekwm::observerMapping()->addObserver(decor, this, 100); } MoveEventHandler::~MoveEventHandler(void) { if (_decor) { pekwm::observerMapping()->removeObserver(_decor, this); } stopMove(); } void MoveEventHandler::notify(Observable *observable, Observation *observation) { if (observation == &PWinObj::pwin_obj_deleted && observable == _decor) { P_TRACE("decor " << _decor << " lost while moving"); _decor = nullptr; } } bool MoveEventHandler::initEventHandler(void) { if (! _decor || ! _decor->allowMove() || ! X11::grabPointer(X11::getRoot(), ButtonMotionMask|ButtonReleaseMask, CURSOR_MOVE)) { return false; } // Grab server to avoid any events causing garbage on the // screen as the outline is drawed as an inverted rectangle. if (_outline) { X11::grabServer(); drawOutline(); } updateStatusWindow(true); _init = true; return true; } EventHandler::Result MoveEventHandler::handleButtonPressEvent(XButtonEvent*) { // mark as processed disabling wm processing of these events. return EventHandler::EVENT_PROCESSED; } EventHandler::Result MoveEventHandler::handleButtonReleaseEvent(XButtonEvent*) { stopMove(); if (_decor) { _decor->move(_gm.x, _gm.y); } return EventHandler::EVENT_STOP_PROCESSED; } EventHandler::Result MoveEventHandler::handleExposeEvent(XExposeEvent*) { return EventHandler::EVENT_SKIP; } EventHandler::Result MoveEventHandler::handleKeyEvent(XKeyEvent*) { // mark as processed disabling wm processing of these events. return EventHandler::EVENT_PROCESSED; } EventHandler::Result MoveEventHandler::handleMotionNotifyEvent(XMotionEvent *ev) { if (! _decor) { return stopMove(); } drawOutline(); //clear // Flush all pointer motion, no need to redraw and redraw. X11::removeMotionEvents(); _gm.x = ev->x_root - _x; _gm.y = ev->y_root - _y; PDecor::checkSnap(_decor, _gm); if (! _outline && _gm != _last_gm) { _last_gm = _gm; X11::moveWindow(_decor->getWindow(), _gm.x, _gm.y); } EdgeType edge = doMoveEdgeFind(ev->x_root, ev->y_root); if (edge != _curr_edge) { _curr_edge = edge; if (edge != SCREEN_EDGE_NO) { doMoveEdgeAction(ev, edge); } } updateStatusWindow(false); drawOutline(); return EventHandler::EVENT_PROCESSED; } EventHandler::Result MoveEventHandler::stopMove(void) { if (_init) { if (_show_status_window) { pekwm::statusWindow()->unmapWindow(); } if (_outline) { drawOutline(); // clear X11::ungrabServer(true); } X11::ungrabPointer(); _init = false; } return EventHandler::EVENT_STOP_SKIP; } void MoveEventHandler::drawOutline(void) { if (_outline) { PDecor::drawOutline(_gm, _decor_shaded); } } void MoveEventHandler::updateStatusWindow(bool map) { if (_show_status_window) { char buf[128]; _decor->getDecorInfo(buf, 128, _gm); StatusWindow *sw = pekwm::statusWindow(); Geometry *sw_gm = _center_on_root ? nullptr : &_gm; if (map) { // draw before map to avoid resize right after the // window is mapped. sw->draw(buf, true, sw_gm); sw->mapWindowRaised(); } sw->draw(buf, true, sw_gm); } } EdgeType MoveEventHandler::doMoveEdgeFind(int x, int y) { EdgeType edge = SCREEN_EDGE_NO; if (x <= signed(pekwm::config()->getScreenEdgeSize(SCREEN_EDGE_LEFT))) { edge = SCREEN_EDGE_LEFT; } else if (x >= signed(X11::getWidth() - _cfg->getScreenEdgeSize(SCREEN_EDGE_RIGHT))) { edge = SCREEN_EDGE_RIGHT; } else if (y <= signed(_cfg->getScreenEdgeSize(SCREEN_EDGE_TOP))) { edge = SCREEN_EDGE_TOP; } else if (y >= signed(X11::getHeight() - _cfg->getScreenEdgeSize(SCREEN_EDGE_BOTTOM))) { edge = SCREEN_EDGE_BOTTOM; } return edge; } void MoveEventHandler::doMoveEdgeAction(XMotionEvent *ev, EdgeType edge) { uint button = X11::getButtonFromState(ev->state); std::vector *edge_actions = _cfg->getEdgeListFromPosition(edge); ActionEvent *ae = ActionHandler::findMouseAction(button, ev->state, MOUSE_EVENT_ENTER_MOVING, edge_actions); if (ae) { ActionPerformedWithOffset ap(_decor, *ae, _x, _y); ap.type = ev->type; ap.event.motion = ev; pekwm::actionHandler()->handleAction(&ap); } } pekwm-0.4.4/src/wm/PDecor.hh0000664000175000017500000003272615126136025011247 // // PDecor.hh for pekwm // Copyright (C) 2004-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PDECOR_HH_ #define _PEKWM_PDECOR_HH_ #include "config.h" #include "Config.hh" #include "tk/PWinObj.hh" #include "tk/PPixmapSurface.hh" #include "ThemeGm.hh" class ActionEvent; class PFont; /** * Create window attributes. */ class CreateWindowParams { public: CreateWindowParams(bool override_redirect) { attr.override_redirect = override_redirect; } bool override_redirect; int depth; long mask; XSetWindowAttributes attr; Visual *visual; }; //! @brief PWinObj container class with fancy decor. class PDecor : public PWinObj, public ThemeGm, public ThemeState { public: //! @brief Decor title button class. class Button : public PWinObj { public: Button(PWinObj *parent, Theme::PDecorButtonData *data, uint width, uint height); ~Button(void); const ActionEvent *findAction(XButtonEvent *ev); ButtonState getState(void) const { return _state; } void setState(ButtonState state); /** Returns wheter the button is positioned relative the left title edge. */ bool isLeft(void) const { return _left; } private: Theme::PDecorButtonData *_data; ButtonState _state; bool _left; }; //! @brief Decor title item class. class TitleItem { public: //! Info bitmask enum. enum Info { INFO_MARKED = (1 << 1), INFO_ID = (1 << 2) }; TitleItem(void); inline const std::string &getVisible(void) const { return _visible; } inline const std::string &getReal(void) const { return _real; } inline const std::string &getCustom(void) const { return _custom; } inline const std::string &getUser(void) const { return _user; } inline uint getCount(void) const { return _count; } inline uint getId(void) const { return _id; } inline bool isUserSet(void) const { return _user.size() > 0; } inline bool isCustom(void) const { return _custom.size() > 0; } inline uint getWidth(void) const { return _width; } void infoAdd(enum Info info); void infoRemove(enum Info info); bool infoIs(enum Info info); void setReal(const std::string &real) { _real = real; if (! isUserSet() && ! isCustom()) { updateVisible(); } } void setCustom(const std::string &custom) { _custom = custom; if (_custom.size() > 0 && ! isUserSet()) { updateVisible(); } } void setUser(const std::string &user) { _user = user; updateVisible(); } void setCount(uint count) { _count = count; } void setId(uint id) { _id = id; } inline void setWidth(uint width) { _width = width; } void updateVisible(void); private: std::string _visible; //!< Visible version of title std::string _real; //!< Title from client /** Custom (title rule) set version of title */ std::string _custom; std::string _user; //!< User set version of title uint _count; //!< Number of title uint _id; //!< ID of title uint _info; //!< Info bitmask for extra title info uint _width; }; PDecor(const Window child_window, bool override_redirect, bool init, const std::string &decor_name = DEFAULT_DECOR_NAME); virtual ~PDecor(void); // START - PWinObj interface. virtual void mapWindow(void); virtual void mapWindowRaised(void); virtual void unmapWindow(void); virtual void move(int x, int y); virtual void resize(uint width, uint height); virtual void moveResize(int x, int y, uint width, uint height); virtual void raise(void); virtual void lower(void); void moveResize(const Geometry &geometry, int gm_mask); virtual void setFocused(bool focused); virtual void setWorkspace(uint workspace); virtual void giveInputFocus(); virtual void warpPointer(); virtual const ActionEvent *handleButtonPress(XButtonEvent *ev); virtual const ActionEvent *handleButtonRelease(XButtonEvent *ev); virtual const ActionEvent *handleMotionEvent(XMotionEvent *ev); virtual const ActionEvent *handleEnterEvent(XCrossingEvent *ev); virtual const ActionEvent *handleLeaveEvent(XCrossingEvent *ev); virtual bool operator == (const Window &window); virtual bool operator != (const Window &window); // END - PWinObj interface. // START - PDecor interface. virtual bool allowMove(void) const { return true; } virtual void addChild(PWinObj *child, std::vector::iterator *it = 0); virtual void removeChild(PWinObj *child, bool do_delete = true); virtual void activateChild(PWinObj *child); virtual void updatedChildOrder(void) { } virtual void updatedActiveChild(void) { } virtual void getDecorInfo(char *buf, uint size, const Geometry& gm); virtual bool setShaded(StateAction sa); virtual void setSkip(uint skip) { _skip = skip; } virtual std::string getDecorName(void); // END - PDecor interface. uint getSkip() const { return _skip; } bool isSkip(uint skip) const { return _skip & skip; } static std::vector::const_iterator pdecor_begin(void) { return _pdecors.begin(); } static std::vector::const_iterator pdecor_end(void) { return _pdecors.end(); } bool isAnyFill() const { return _fill_state; } void clearFill() { _fill_state = 0; } virtual void clearFillStateAfterResize() { } bool isMaximizedVert() const { return _fill_state & FILL_STATE_MAXIMIZED_VERT; } bool isMaximizedHorz() const { return _fill_state & FILL_STATE_MAXIMIZED_HORZ; } void setMaximized(bool horz, bool vert) { _fill_state = (horz ? FILL_STATE_MAXIMIZED_HORZ : 0) | (vert ? FILL_STATE_MAXIMIZED_VERT : 0); } void setFullscreen(bool fullscreen) { _fill_state = fullscreen ? FILL_STATE_FULLSCREEN : 0; } bool isFullscreen() const { return _fill_state & FILL_STATE_FULLSCREEN; } OrientationType getEdgeFilled() const { if (_fill_state & FILL_STATE_EDGE) { return _edge_filled; } return NO_EDGE; } void setEdgeFilled(OrientationType edge) { _fill_state = (edge != NO_EDGE ? FILL_STATE_EDGE : 0); _edge_filled = edge; } void addDecor(PDecor *decor); /** * Updates _decor_name to represent decor state * \return true if decor was changed */ bool updateDecor(void); void setDecorOverride(StateAction sa, const std::string &name); void loadDecor(void); //! @brief Returns title Window. inline Window getTitleWindow(void) const { return _title_wo.getWindow(); } PDecor::Button *findButton(Window win); uint getRealHeight(void) const; uint getChildWidth(void) const; uint getChildHeight(void) const; // child list actions //! @brief Returns number of children in PDecor. inline uint size(void) const { return _children.size(); } //! @brief Returns iterator to the first child in PDecor. std::vector::const_iterator begin(void) { return _children.begin(); } //! @brief Returns iterator to the last+1 child in PDecor. std::vector::const_iterator end(void) { return _children.end(); } //! @brief Returns pointer to active PWinObj. inline PWinObj *getActiveChild() const { return _child; } PWinObj *getChildFromPos(int x); void activateChildNum(uint num); void activateChildRel(int off); // +/- relative from active void moveChildRel(int off); // +/- relative from active // title //! @brief Adds TitleItem to title list. inline void titleAdd(PDecor::TitleItem *ct) { _titles.push_back(ct); } //! @brief Removes all TitleItems from title list. inline void titleClear(void) { _titles.clear(); } //! @brief Sets active TitleItem. void titleSetActive(uint num) { _title_active = (num > _titles.size()) ? 0 : num; } // move and resize relative to the child instead of decor void moveChild(int x, int y); void resizeChild(uint width, uint height); // decor state /** Returns whether we have a border or not. */ virtual bool hasBorder(void) const { return _border; } /** @brief Returns whether we have a title bar or not. */ virtual bool hasTitlebar(void) const { return _titlebar; } /** @brief Returns whether we are shaded or not. */ virtual bool isShaded(void) const { return _shaded; } bool setBorder(StateAction sa); bool setTitlebar(StateAction sa); bool demandAttention(void) const { return _attention; } void incrAttention(void) { ++_attention; } void decrAttention(void) { if (_attention && ! --_attention) { updateDecor(); } } //! @brief Returns border position Window win is at. inline BorderPosition getBorderPosition(Window win) const { for (uint i = 0; i < BORDER_NO_POS; ++i) { if (_border_win[i] == win) { return BorderPosition(i); } } return BORDER_NO_POS; } void deiconify(void); static void drawOutline(const Geometry &gm, uint shaded); static void checkSnap(PWinObj *skip_wo, Geometry &gm); protected: // START - PDecor interface. virtual void renderTitle(void); virtual void renderButtons(void); virtual void renderBorder(void); virtual void setBorderShape(void); // shapes border corners // called after loadDecor, render child virtual void loadTheme(void) { } // called after decor change (theme change, decor type change, // border state etc) virtual void decorUpdated(void) { } // END - PDecor interface. #ifdef PEKWM_HAVE_SHAPE void applyBorderShape(int kind=ShapeBounding); void applyBorderShapeNormal(int kind, bool client_shape); void applyBorderShapeShaded(int kind); void applyBorderShapeBorder(int kind, Window shape); #else void applyBorderShape(int kind=0) {} #endif // PEKWM_HAVE_SHAPE void resizeTitle(void); static void checkWOSnap(const PWinObj *skip_wo, Geometry &gm); static void checkEdgeSnap(Geometry &gm); void alignChild(PWinObj *child); FocusedState getFocusedState(bool selected) const { if (selected) { return _focused ? FOCUSED_STATE_FOCUSED_SELECTED : FOCUSED_STATE_UNFOCUSED_SELECTED; } return _focused ? FOCUSED_STATE_FOCUSED : FOCUSED_STATE_UNFOCUSED; } private: void init(Window child_window, bool override_redirect); void createParentWindow(CreateWindowParams ¶ms, Window child_window); void createTitle(CreateWindowParams ¶ms); void createBorder(CreateWindowParams ¶ms); void setDataFromDecorName(const std::string &decor_name); void unloadDecor(void); const ActionEvent *handleButtonPressDecor(XButtonEvent *ev); const ActionEvent *handleButtonReleaseDecor(XButtonEvent *ev); const ActionEvent *handleButtonPressButton(XButtonEvent *ev, PDecor::Button *button); const ActionEvent *handleButtonReleaseButton(XButtonEvent *ev, PDecor::Button *button); const ActionEvent *handleButtonPressBorder(XButtonEvent *ev); const ActionEvent *handleButtonReleaseBorder(XButtonEvent *ev); void placeButtons(void); void placeBorder(void); void shapeBorder(void); void restackBorder(void); // shaded, borderless, no border visible void getBorderSize(BorderPosition pos, uint &width, uint &height); uint calcTitleWidth(void); uint calcTitleWidthDynamic(void); void calcTabsWidth(void); void calcTabsGetAvailAndTabWidth(uint &width_avail, uint &tab_width, int &off); void calcTabsWidthSymetric(void); void calcTabsWidthAsymetric(void); void calcTabsWidthAsymetricGrow(uint width_avail, uint width_total, uint tab_width); void calcTabsWidthAsymetricShrink(uint width_avail, uint tab_width); protected: std::string _decor_name; //!< Name of the active decoration /** Original decor name if it is temp. overridden */ std::string _decor_name_saved; PWinObj *_child; //!< Pointer to active child in PDecor. std::vector _children; //!< List of children in PDecor. PDecor::Button *_button; /**< Active title button in PDecor. */ /** Active border window, for button release handling. */ Window _button_press_win; // used for treshold calculation int _pointer_x; //!< Last click x root position. int _pointer_y; //!< Last click y root position. int _click_x; //!< Last click x window position. int _click_y; //!< Last click y window position. /** Boolean to set wheter ::move is overloaded. */ bool _decor_cfg_child_move_overloaded; /** Boolean to configure wheter to call XReplayPointer on clicks. */ bool _decor_cfg_bpr_replay_pointer; /** What list to search for child actions. */ MouseActionListName _decor_cfg_bpr_al_child; /** What list to search for title actions. */ MouseActionListName _decor_cfg_bpr_al_title; /** Default decor name in normal state. */ static const std::string DEFAULT_DECOR_NAME; /** Default decor name in borderless state. */ static const std::string DEFAULT_DECOR_NAME_BORDERLESS; /** Default decor name in titlebarless state. */ static const std::string DEFAULT_DECOR_NAME_TITLEBARLESS; /** Default decor name for demands attention state. */ static const std::string DEFAULT_DECOR_NAME_ATTENTION; Window _border_win[BORDER_NO_POS]; /** Array of border windows. */ private: void renderTitleTextBackground(PPixmapSurface &title_bg, PFont *font, int x, uint width, const std::string &text, PFont::TrimType trim, PTexture *tex); Theme::PDecorData *_data; enum fill_state { FILL_STATE_MAXIMIZED_VERT = 1 << 0, FILL_STATE_MAXIMIZED_HORZ = 1 << 1, FILL_STATE_FULLSCREEN = 1 << 2, FILL_STATE_EDGE = 1 << 3 }; // state int _fill_state; OrientationType _edge_filled; uint _skip; // decor state bool _border; bool _titlebar; bool _shaded; uint _attention; // Number of children that demand attention bool _need_shape; uint _real_height; PWinObj _title_wo; std::vector _buttons; // variable decor data uint _title_active; std::vector _titles; uint _titles_left, _titles_right; // area where to put titles static std::vector _pdecors; /**< List of all PDecors */ }; #endif // _PEKWM_PDECOR_HH_ pekwm-0.4.4/src/wm/pekwm.hh0000664000175000017500000000146715126136025011214 // // pekwm.hh for pekwm // Copyright (C) 2003-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_PEKWM_HH_ #define _PEKWM_PEKWM_HH_ #include "config.h" #include #include "AppCtrl.hh" #include "EventLoop.hh" #include "Os.hh" #include "Timeouts.hh" class Config; class RootWO; namespace pekwm { void initNoDisplay(void); void cleanupNoDisplay(void); bool init(AppCtrl* app_ctrl, EventLoop* event_loop, Os *os, Display* dpy, const std::string& config_file, bool replace, bool synchronous, bool standalone); void cleanup(void); bool isStarting(void); void setStarted(void); Timeouts *timeouts(); void setConfig(Config* cfg); void setRootWO(RootWO* root_wo); } #endif // _PEKWM_PEKWM_HH_ pekwm-0.4.4/src/wm/FrameListMenu.cc0000664000175000017500000001555315126136025012573 // // FrameListMenu.cc for pekwm // Copyright (C) 2002-2023 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include #include #include #include "Compat.hh" #include "PDecor.hh" #include "PMenu.hh" #include "WORefMenu.hh" #include "FrameListMenu.hh" #include "Config.hh" #include "Client.hh" #include "Frame.hh" #include "Workspaces.hh" #include "tk/PWinObj.hh" //! @brief FrameListMenu constructor. //! @param theme Pointer to Theme //! @param type Type of menu. //! @param title Title of menu. //! @param name Name of menu //! @param decor_name Decor name, defaults to MENU FrameListMenu::FrameListMenu(MenuType type, const std::string &title, const std::string &name, const std::string &decor_name) : WORefMenu(title, name, decor_name) { _menu_type = type; } //! @brief FrameListMenu destructor FrameListMenu::~FrameListMenu(void) { } // START - PWinObj interface. /** * Rebuilds the menu and if it has any items after it shows it. */ void FrameListMenu::mapWindow(void) { updateFrameListMenu(); if (size() > 0) { WORefMenu::mapWindow(); } } /** * Remove all items when unmapping the menu, no point in holding on to * the resources. */ void FrameListMenu::unmapWindow(void) { removeAll(); WORefMenu::unmapWindow(); } // END - PWinObj interface. /** * Execute item execution. */ void FrameListMenu::handleItemExec(PMenu::Item *item) { if (! item) { return; } Client *item_client = dynamic_cast(item->getWORef()); Client *wo_ref_client = dynamic_cast(getWORef()); switch (_menu_type) { case GOTOMENU_TYPE: case GOTOCLIENTMENU_TYPE: handleGotomenu(item_client); break; case ICONMENU_TYPE: handleIconmenu(item_client); break; case ATTACH_CLIENT_TYPE: case ATTACH_FRAME_TYPE: handleAttach(wo_ref_client, item_client, (_menu_type == ATTACH_FRAME_TYPE)); break; case ATTACH_CLIENT_IN_FRAME_TYPE: case ATTACH_FRAME_IN_FRAME_TYPE: handleAttach(item_client, wo_ref_client, (_menu_type == ATTACH_FRAME_IN_FRAME_TYPE)); break; default: // do nothing break; } } //! @brief Rebuilds the menu. void FrameListMenu::updateFrameListMenu(void) { removeAll(); char buf[16]; std::string name; // need to add an action, otherwise it looks as if we don't have // anything to exec and thus it doesn't get handled. Action action; ActionEvent ae; ae.action_list.push_back(action); // Decide wheter to show clients and iconified. bool show_clients = false, show_iconified_only = false; if (_menu_type == ATTACH_CLIENT_TYPE || _menu_type == GOTOCLIENTMENU_TYPE) { show_clients = true; } else if (_menu_type == ICONMENU_TYPE) { show_iconified_only = true; } // if we have 1 workspace, we won't put an workspace indicator buf[0] = '\0'; std::vector::const_iterator it; for (uint i = 0; i < Workspaces::size(); ++i) { if (Workspaces::size() > 1) { snprintf(buf, sizeof(buf), "<%u> ", i + 1); } for (it = Frame::frame_begin(); it != Frame::frame_end(); ++it) { if (((*it)->getWorkspace() == i) && // sort by workspace // don't include ourselves if we're not doing a // gotoclient menu ((_menu_type != GOTOCLIENTMENU_TYPE) ? ((*it)->getActiveChild() != getWORef()) : true) && (show_iconified_only ? (*it)->isIconified() : !(*it)->isSkip(SKIP_MENUS))) { name = buf; if (show_clients) { bool is_last = (it + 1) == Frame::frame_end(); buildFrameNames(*it, name, !is_last); } else { buildName(*it, name); Client *client = static_cast( (*it)->getActiveChild()); name.append("] "); name.append(client->getTitle() ->getVisible()); insert(name, false, ae, client, client->getIcon()); } } } } buildMenu(); } //! @brief Builds the name for the frame. void FrameListMenu::buildName(Frame* frame, std::string &name) { name.append("["); if (frame->isSticky()) { name.append("*"); } if (frame->isIconified()) { name.append("."); } if (frame->isShaded()) { name.append("^"); } if (frame->getActiveChild()->getLayer() > LAYER_NORMAL) { name.append("+"); } else if (frame->getActiveChild()->getLayer() < LAYER_NORMAL) { name.append("-"); } } //! @brief Builds names for all the clients in a frame. void FrameListMenu::buildFrameNames(Frame *frame, const std::string &pre_name, bool insert_separator) { std::string status_name; // need to add an action, otherwise it looks as if we don't have // anything to exec and thus it doesn't get handled. Action action; ActionEvent ae; ae.action_list.push_back(action); buildName(frame, status_name); // add states to the name std::vector::const_iterator it = frame->begin(); for (; it != frame->end(); ++it) { std::string name = pre_name; name.append(status_name); if (frame->getActiveChild() == *it) { name.append("A"); } name.append("] "); Client* client = static_cast(*it); name.append(client->getTitle()->getVisible()); insert(name, false, ae, *it, static_cast(*it)->getIcon()); } // add separator if (insert_separator) { PMenu::Item *item = new PMenu::Item("", false); item->setType(PMenu::Item::MENU_ITEM_SEPARATOR); insert(item); } } //! @brief Handles gotomeu presses void FrameListMenu::handleGotomenu(Client *client) { if (! client) { return; } Frame *frame = static_cast(client->getParent()); // make sure it's on correct workspace if (! frame->isSticky() && (frame->getWorkspace() != Workspaces::getActive())) { Workspaces::setWorkspace(frame->getWorkspace(), false); } // make sure it isn't hidden if (! frame->isMapped()) { frame->mapWindow(); } frame->activateChild(client); frame->raise(); Workspaces::giveInputFocus(frame); } //! @brief Handles iconmenu presses void FrameListMenu::handleIconmenu(Client *client) { if (! client) { return; } Frame *frame = static_cast(client->getParent()); // make sure it's on the current workspace if (frame->getWorkspace() != Workspaces::getActive()) { frame->setWorkspace(Workspaces::getActive()); } frame->raise(); frame->mapWindow(); Workspaces::giveInputFocus(frame); } //! @brief Handles attach*menu presses void FrameListMenu::handleAttach(Client *client_to, Client *client_from, bool frame) { if (! client_to || ! client_from) { return; } Frame *frame_to = static_cast(client_to->getParent()); Frame *frame_from = static_cast(client_from->getParent()); // insert frame if (frame) { frame_to->addDecor(frame_from); // insert client } else if (frame_to != frame_from) { frame_from->removeChild(client_from); client_from->setWorkspace(frame_to->getWorkspace()); frame_to->addChild(client_from); frame_to->activateChild(client_from); Workspaces::giveInputFocus(frame_to); } } pekwm-0.4.4/src/wm/EventHandler.hh0000664000175000017500000000175015126136025012443 // // EvenHandler.hh for pekwm // Copyright (C) 2021 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_EVENTHANDLER_HH_ #define _PEKWM_EVENTHANDLER_HH_ #include "X11.hh" /** * EventHandler interface for implementing event handling overriding * default event handling to support operations such as move drag from * the main event loop. */ class EventHandler { public: enum Result { EVENT_PROCESSED, EVENT_SKIP, EVENT_STOP_PROCESSED, EVENT_STOP_SKIP }; virtual ~EventHandler(void) { } virtual bool initEventHandler(void) = 0; virtual Result handleButtonPressEvent(XButtonEvent*) = 0; virtual Result handleButtonReleaseEvent(XButtonEvent*) = 0; virtual Result handleExposeEvent(XExposeEvent*) = 0; virtual Result handleKeyEvent(XKeyEvent*) = 0; virtual Result handleMotionNotifyEvent(XMotionEvent*) = 0; protected: EventHandler(void) { } }; #endif // _PEKWM_EVENTHANDLER_HH_ pekwm-0.4.4/src/wm/Makefile.in0000664000175000017500000033422415164641454011626 # Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) am__rm_f = rm -f $(am__rm_f_notfound) am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = pekwm$(EXEEXT) pekwm_wm$(EXEEXT) subdir = src/wm ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cr AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libpekwm_wm_a_AR = $(AR) $(ARFLAGS) libpekwm_wm_a_RANLIB = $(RANLIB) libpekwm_wm_a_LIBADD = am_libpekwm_wm_a_OBJECTS = libpekwm_wm_a-ActionHandler.$(OBJEXT) \ libpekwm_wm_a-ActionMenu.$(OBJEXT) \ libpekwm_wm_a-AutoProperties.$(OBJEXT) \ libpekwm_wm_a-Client.$(OBJEXT) \ libpekwm_wm_a-ClientMgr.$(OBJEXT) \ libpekwm_wm_a-CmdDialog.$(OBJEXT) \ libpekwm_wm_a-Completer.$(OBJEXT) \ libpekwm_wm_a-Config.$(OBJEXT) libpekwm_wm_a-DockApp.$(OBJEXT) \ libpekwm_wm_a-FocusToggleEventHandler.$(OBJEXT) \ libpekwm_wm_a-Frame.$(OBJEXT) \ libpekwm_wm_a-FrameListMenu.$(OBJEXT) \ libpekwm_wm_a-Globals.$(OBJEXT) \ libpekwm_wm_a-GroupingDragEventHandler.$(OBJEXT) \ libpekwm_wm_a-Harbour.$(OBJEXT) \ libpekwm_wm_a-InputDialog.$(OBJEXT) \ libpekwm_wm_a-KeyGrabber.$(OBJEXT) \ libpekwm_wm_a-KeyboardMoveResizeEventHandler.$(OBJEXT) \ libpekwm_wm_a-ManagerWindows.$(OBJEXT) \ libpekwm_wm_a-MenuHandler.$(OBJEXT) \ libpekwm_wm_a-MoveEventHandler.$(OBJEXT) \ libpekwm_wm_a-PDecor.$(OBJEXT) libpekwm_wm_a-PMenu.$(OBJEXT) \ libpekwm_wm_a-ResizeEventHandler.$(OBJEXT) \ libpekwm_wm_a-SearchDialog.$(OBJEXT) \ libpekwm_wm_a-StatusWindow.$(OBJEXT) \ libpekwm_wm_a-ThemeGm.$(OBJEXT) \ libpekwm_wm_a-WORefMenu.$(OBJEXT) \ libpekwm_wm_a-WinLayouter.$(OBJEXT) \ libpekwm_wm_a-WindowManager.$(OBJEXT) \ libpekwm_wm_a-WmUtil.$(OBJEXT) \ libpekwm_wm_a-WorkspaceIndicator.$(OBJEXT) \ libpekwm_wm_a-Workspaces.$(OBJEXT) libpekwm_wm_a_OBJECTS = $(am_libpekwm_wm_a_OBJECTS) am__dirstamp = $(am__leading_dot)dirstamp am_pekwm_OBJECTS = pekwm-pekwm.$(OBJEXT) ../pekwm-pekwm_env.$(OBJEXT) \ ../lib/pekwm-Compat.$(OBJEXT) pekwm_OBJECTS = $(am_pekwm_OBJECTS) pekwm_LDADD = $(LDADD) pekwm_LINK = $(CXXLD) $(pekwm_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am_pekwm_wm_OBJECTS = pekwm_wm-pekwm_wm.$(OBJEXT) \ ../pekwm_wm-pekwm_env.$(OBJEXT) pekwm_wm_OBJECTS = $(am_pekwm_wm_OBJECTS) am__DEPENDENCIES_1 = pekwm_wm_DEPENDENCIES = libpekwm_wm.a ../lib/libpekwm_lib.a \ ../tk/libpekwm_tk.a $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) pekwm_wm_LINK = $(CXXLD) $(pekwm_wm_CXXFLAGS) $(CXXFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ../$(DEPDIR)/pekwm-pekwm_env.Po \ ../$(DEPDIR)/pekwm_wm-pekwm_env.Po \ ../lib/$(DEPDIR)/pekwm-Compat.Po \ ./$(DEPDIR)/libpekwm_wm_a-ActionHandler.Po \ ./$(DEPDIR)/libpekwm_wm_a-ActionMenu.Po \ ./$(DEPDIR)/libpekwm_wm_a-AutoProperties.Po \ ./$(DEPDIR)/libpekwm_wm_a-Client.Po \ ./$(DEPDIR)/libpekwm_wm_a-ClientMgr.Po \ ./$(DEPDIR)/libpekwm_wm_a-CmdDialog.Po \ ./$(DEPDIR)/libpekwm_wm_a-Completer.Po \ ./$(DEPDIR)/libpekwm_wm_a-Config.Po \ ./$(DEPDIR)/libpekwm_wm_a-DockApp.Po \ ./$(DEPDIR)/libpekwm_wm_a-FocusToggleEventHandler.Po \ ./$(DEPDIR)/libpekwm_wm_a-Frame.Po \ ./$(DEPDIR)/libpekwm_wm_a-FrameListMenu.Po \ ./$(DEPDIR)/libpekwm_wm_a-Globals.Po \ ./$(DEPDIR)/libpekwm_wm_a-GroupingDragEventHandler.Po \ ./$(DEPDIR)/libpekwm_wm_a-Harbour.Po \ ./$(DEPDIR)/libpekwm_wm_a-InputDialog.Po \ ./$(DEPDIR)/libpekwm_wm_a-KeyGrabber.Po \ ./$(DEPDIR)/libpekwm_wm_a-KeyboardMoveResizeEventHandler.Po \ ./$(DEPDIR)/libpekwm_wm_a-ManagerWindows.Po \ ./$(DEPDIR)/libpekwm_wm_a-MenuHandler.Po \ ./$(DEPDIR)/libpekwm_wm_a-MoveEventHandler.Po \ ./$(DEPDIR)/libpekwm_wm_a-PDecor.Po \ ./$(DEPDIR)/libpekwm_wm_a-PMenu.Po \ ./$(DEPDIR)/libpekwm_wm_a-ResizeEventHandler.Po \ ./$(DEPDIR)/libpekwm_wm_a-SearchDialog.Po \ ./$(DEPDIR)/libpekwm_wm_a-StatusWindow.Po \ ./$(DEPDIR)/libpekwm_wm_a-ThemeGm.Po \ ./$(DEPDIR)/libpekwm_wm_a-WORefMenu.Po \ ./$(DEPDIR)/libpekwm_wm_a-WinLayouter.Po \ ./$(DEPDIR)/libpekwm_wm_a-WindowManager.Po \ ./$(DEPDIR)/libpekwm_wm_a-WmUtil.Po \ ./$(DEPDIR)/libpekwm_wm_a-WorkspaceIndicator.Po \ ./$(DEPDIR)/libpekwm_wm_a-Workspaces.Po \ ./$(DEPDIR)/pekwm-pekwm.Po ./$(DEPDIR)/pekwm_wm-pekwm_wm.Po am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libpekwm_wm_a_SOURCES) $(pekwm_SOURCES) \ $(pekwm_wm_SOURCES) DIST_SOURCES = $(libpekwm_wm_a_SOURCES) $(pekwm_SOURCES) \ $(pekwm_wm_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIB_CFLAGS = @LIB_CFLAGS@ LIB_LIBS = @LIB_LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PEKWM_FEATURES = @PEKWM_FEATURES@ PEKWM_SH = @PEKWM_SH@ PEKWM_THEMES = @PEKWM_THEMES@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TK_CFLAGS = @TK_CFLAGS@ TK_LIBS = @TK_LIBS@ VERSION = @VERSION@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ am__xargs_n = @am__xargs_n@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libcurl_CFLAGS = @libcurl_CFLAGS@ libcurl_LIBS = @libcurl_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ libjpeg_CFLAGS = @libjpeg_CFLAGS@ libjpeg_LIBS = @libjpeg_LIBS@ libpng_CFLAGS = @libpng_CFLAGS@ libpng_LIBS = @libpng_LIBS@ libudev_CFLAGS = @libudev_CFLAGS@ libudev_LIBS = @libudev_LIBS@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pango_CFLAGS = @pango_CFLAGS@ pango_LIBS = @pango_LIBS@ pangocairo_CFLAGS = @pangocairo_CFLAGS@ pangocairo_LIBS = @pangocairo_LIBS@ pangoxft_CFLAGS = @pangoxft_CFLAGS@ pangoxft_LIBS = @pangoxft_LIBS@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ xext_CFLAGS = @xext_CFLAGS@ xext_LIBS = @xext_LIBS@ xft_CFLAGS = @xft_CFLAGS@ xft_LIBS = @xft_LIBS@ xinerama_CFLAGS = @xinerama_CFLAGS@ xinerama_LIBS = @xinerama_LIBS@ xpm_CFLAGS = @xpm_CFLAGS@ xpm_LIBS = @xpm_LIBS@ xrandr_CFLAGS = @xrandr_CFLAGS@ xrandr_LIBS = @xrandr_LIBS@ noinst_LIBRARIES = libpekwm_wm.a libpekwm_wm_a_SOURCES = ActionHandler.cc ActionHandler.hh \ ActionMenu.cc ActionMenu.hh \ AppCtrl.hh \ AutoProperties.cc AutoProperties.hh \ Client.cc Client.hh \ ClientMgr.cc ClientMgr.hh \ CmdDialog.cc CmdDialog.hh \ Completer.cc Completer.hh \ Config.cc Config.hh \ DockApp.cc DockApp.hh \ EventLoop.hh \ EventHandler.hh \ FocusToggleEventHandler.cc FocusToggleEventHandler.hh \ Frame.cc Frame.hh \ FrameListMenu.cc FrameListMenu.hh \ Globals.cc \ GroupingDragEventHandler.cc \ GroupingDragEventHandler.hh \ Harbour.cc Harbour.hh \ InputDialog.cc InputDialog.hh \ KeyGrabber.cc KeyGrabber.hh \ KeyboardMoveResizeEventHandler.cc \ KeyboardMoveResizeEventHandler.hh \ ManagerWindows.cc ManagerWindows.hh \ MenuHandler.cc MenuHandler.hh \ MoveEventHandler.cc MoveEventHandler.hh \ PDecor.cc PDecor.hh \ PMenu.cc PMenu.hh \ PWinObjReference.hh \ ResizeEventHandler.cc ResizeEventHandler.hh \ SearchDialog.cc SearchDialog.hh \ StatusWindow.cc StatusWindow.hh \ ThemeGm.cc ThemeGm.hh \ WORefMenu.cc WORefMenu.hh \ WinLayouter.cc WinLayouter.hh \ WindowManager.cc WindowManager.hh \ WmUtil.cc WmUtil.hh \ WorkspaceIndicator.cc WorkspaceIndicator.hh \ Workspaces.cc Workspaces.hh libpekwm_wm_a_CXXFLAGS = $(LIB_CFLAGS) $(TK_CFLAGS) -I../lib -I.. \ -DFEATURES="\"@PEKWM_FEATURES@\"" pekwm_SOURCES = pekwm.cc pekwm.hh ../pekwm_env.cc ../lib/Compat.cc pekwm_CXXFLAGS = -I../lib -I.. pekwm_wm_SOURCES = pekwm_wm.cc ../pekwm_env.cc pekwm_wm_CXXFLAGS = $(LIB_CFLAGS) $(TK_CFLAGS) -I../lib -I.. \ -DFEATURES="\"@PEKWM_FEATURES@\"" pekwm_wm_LDADD = libpekwm_wm.a ../lib/libpekwm_lib.a ../tk/libpekwm_tk.a \ $(LIB_LIBS) $(TK_LIBS) EXTRA_DIST = CMakeLists.txt all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/wm/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/wm/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files clean-binPROGRAMS: -$(am__rm_f) $(bin_PROGRAMS) clean-noinstLIBRARIES: -$(am__rm_f) $(noinst_LIBRARIES) libpekwm_wm.a: $(libpekwm_wm_a_OBJECTS) $(libpekwm_wm_a_DEPENDENCIES) $(EXTRA_libpekwm_wm_a_DEPENDENCIES) $(AM_V_at)-rm -f libpekwm_wm.a $(AM_V_AR)$(libpekwm_wm_a_AR) libpekwm_wm.a $(libpekwm_wm_a_OBJECTS) $(libpekwm_wm_a_LIBADD) $(AM_V_at)$(libpekwm_wm_a_RANLIB) libpekwm_wm.a ../$(am__dirstamp): @$(MKDIR_P) .. @: >>../$(am__dirstamp) ../$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ../$(DEPDIR) @: >>../$(DEPDIR)/$(am__dirstamp) ../pekwm-pekwm_env.$(OBJEXT): ../$(am__dirstamp) \ ../$(DEPDIR)/$(am__dirstamp) ../lib/$(am__dirstamp): @$(MKDIR_P) ../lib @: >>../lib/$(am__dirstamp) ../lib/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ../lib/$(DEPDIR) @: >>../lib/$(DEPDIR)/$(am__dirstamp) ../lib/pekwm-Compat.$(OBJEXT): ../lib/$(am__dirstamp) \ ../lib/$(DEPDIR)/$(am__dirstamp) pekwm$(EXEEXT): $(pekwm_OBJECTS) $(pekwm_DEPENDENCIES) $(EXTRA_pekwm_DEPENDENCIES) @rm -f pekwm$(EXEEXT) $(AM_V_CXXLD)$(pekwm_LINK) $(pekwm_OBJECTS) $(pekwm_LDADD) $(LIBS) ../pekwm_wm-pekwm_env.$(OBJEXT): ../$(am__dirstamp) \ ../$(DEPDIR)/$(am__dirstamp) pekwm_wm$(EXEEXT): $(pekwm_wm_OBJECTS) $(pekwm_wm_DEPENDENCIES) $(EXTRA_pekwm_wm_DEPENDENCIES) @rm -f pekwm_wm$(EXEEXT) $(AM_V_CXXLD)$(pekwm_wm_LINK) $(pekwm_wm_OBJECTS) $(pekwm_wm_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f ../*.$(OBJEXT) -rm -f ../lib/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@../$(DEPDIR)/pekwm-pekwm_env.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../$(DEPDIR)/pekwm_wm-pekwm_env.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../lib/$(DEPDIR)/pekwm-Compat.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-ActionHandler.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-ActionMenu.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-AutoProperties.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-Client.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-ClientMgr.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-CmdDialog.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-Completer.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-Config.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-DockApp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-FocusToggleEventHandler.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-Frame.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-FrameListMenu.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-Globals.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-GroupingDragEventHandler.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-Harbour.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-InputDialog.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-KeyGrabber.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-KeyboardMoveResizeEventHandler.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-ManagerWindows.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-MenuHandler.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-MoveEventHandler.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-PDecor.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-PMenu.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-ResizeEventHandler.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-SearchDialog.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-StatusWindow.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-ThemeGm.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-WORefMenu.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-WinLayouter.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-WindowManager.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-WmUtil.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-WorkspaceIndicator.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpekwm_wm_a-Workspaces.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm-pekwm.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pekwm_wm-pekwm_wm.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @: >>$@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` libpekwm_wm_a-ActionHandler.o: ActionHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-ActionHandler.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-ActionHandler.Tpo -c -o libpekwm_wm_a-ActionHandler.o `test -f 'ActionHandler.cc' || echo '$(srcdir)/'`ActionHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-ActionHandler.Tpo $(DEPDIR)/libpekwm_wm_a-ActionHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ActionHandler.cc' object='libpekwm_wm_a-ActionHandler.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-ActionHandler.o `test -f 'ActionHandler.cc' || echo '$(srcdir)/'`ActionHandler.cc libpekwm_wm_a-ActionHandler.obj: ActionHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-ActionHandler.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-ActionHandler.Tpo -c -o libpekwm_wm_a-ActionHandler.obj `if test -f 'ActionHandler.cc'; then $(CYGPATH_W) 'ActionHandler.cc'; else $(CYGPATH_W) '$(srcdir)/ActionHandler.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-ActionHandler.Tpo $(DEPDIR)/libpekwm_wm_a-ActionHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ActionHandler.cc' object='libpekwm_wm_a-ActionHandler.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-ActionHandler.obj `if test -f 'ActionHandler.cc'; then $(CYGPATH_W) 'ActionHandler.cc'; else $(CYGPATH_W) '$(srcdir)/ActionHandler.cc'; fi` libpekwm_wm_a-ActionMenu.o: ActionMenu.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-ActionMenu.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-ActionMenu.Tpo -c -o libpekwm_wm_a-ActionMenu.o `test -f 'ActionMenu.cc' || echo '$(srcdir)/'`ActionMenu.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-ActionMenu.Tpo $(DEPDIR)/libpekwm_wm_a-ActionMenu.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ActionMenu.cc' object='libpekwm_wm_a-ActionMenu.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-ActionMenu.o `test -f 'ActionMenu.cc' || echo '$(srcdir)/'`ActionMenu.cc libpekwm_wm_a-ActionMenu.obj: ActionMenu.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-ActionMenu.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-ActionMenu.Tpo -c -o libpekwm_wm_a-ActionMenu.obj `if test -f 'ActionMenu.cc'; then $(CYGPATH_W) 'ActionMenu.cc'; else $(CYGPATH_W) '$(srcdir)/ActionMenu.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-ActionMenu.Tpo $(DEPDIR)/libpekwm_wm_a-ActionMenu.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ActionMenu.cc' object='libpekwm_wm_a-ActionMenu.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-ActionMenu.obj `if test -f 'ActionMenu.cc'; then $(CYGPATH_W) 'ActionMenu.cc'; else $(CYGPATH_W) '$(srcdir)/ActionMenu.cc'; fi` libpekwm_wm_a-AutoProperties.o: AutoProperties.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-AutoProperties.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-AutoProperties.Tpo -c -o libpekwm_wm_a-AutoProperties.o `test -f 'AutoProperties.cc' || echo '$(srcdir)/'`AutoProperties.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-AutoProperties.Tpo $(DEPDIR)/libpekwm_wm_a-AutoProperties.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AutoProperties.cc' object='libpekwm_wm_a-AutoProperties.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-AutoProperties.o `test -f 'AutoProperties.cc' || echo '$(srcdir)/'`AutoProperties.cc libpekwm_wm_a-AutoProperties.obj: AutoProperties.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-AutoProperties.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-AutoProperties.Tpo -c -o libpekwm_wm_a-AutoProperties.obj `if test -f 'AutoProperties.cc'; then $(CYGPATH_W) 'AutoProperties.cc'; else $(CYGPATH_W) '$(srcdir)/AutoProperties.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-AutoProperties.Tpo $(DEPDIR)/libpekwm_wm_a-AutoProperties.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AutoProperties.cc' object='libpekwm_wm_a-AutoProperties.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-AutoProperties.obj `if test -f 'AutoProperties.cc'; then $(CYGPATH_W) 'AutoProperties.cc'; else $(CYGPATH_W) '$(srcdir)/AutoProperties.cc'; fi` libpekwm_wm_a-Client.o: Client.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Client.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Client.Tpo -c -o libpekwm_wm_a-Client.o `test -f 'Client.cc' || echo '$(srcdir)/'`Client.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Client.Tpo $(DEPDIR)/libpekwm_wm_a-Client.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Client.cc' object='libpekwm_wm_a-Client.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Client.o `test -f 'Client.cc' || echo '$(srcdir)/'`Client.cc libpekwm_wm_a-Client.obj: Client.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Client.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Client.Tpo -c -o libpekwm_wm_a-Client.obj `if test -f 'Client.cc'; then $(CYGPATH_W) 'Client.cc'; else $(CYGPATH_W) '$(srcdir)/Client.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Client.Tpo $(DEPDIR)/libpekwm_wm_a-Client.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Client.cc' object='libpekwm_wm_a-Client.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Client.obj `if test -f 'Client.cc'; then $(CYGPATH_W) 'Client.cc'; else $(CYGPATH_W) '$(srcdir)/Client.cc'; fi` libpekwm_wm_a-ClientMgr.o: ClientMgr.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-ClientMgr.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-ClientMgr.Tpo -c -o libpekwm_wm_a-ClientMgr.o `test -f 'ClientMgr.cc' || echo '$(srcdir)/'`ClientMgr.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-ClientMgr.Tpo $(DEPDIR)/libpekwm_wm_a-ClientMgr.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ClientMgr.cc' object='libpekwm_wm_a-ClientMgr.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-ClientMgr.o `test -f 'ClientMgr.cc' || echo '$(srcdir)/'`ClientMgr.cc libpekwm_wm_a-ClientMgr.obj: ClientMgr.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-ClientMgr.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-ClientMgr.Tpo -c -o libpekwm_wm_a-ClientMgr.obj `if test -f 'ClientMgr.cc'; then $(CYGPATH_W) 'ClientMgr.cc'; else $(CYGPATH_W) '$(srcdir)/ClientMgr.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-ClientMgr.Tpo $(DEPDIR)/libpekwm_wm_a-ClientMgr.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ClientMgr.cc' object='libpekwm_wm_a-ClientMgr.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-ClientMgr.obj `if test -f 'ClientMgr.cc'; then $(CYGPATH_W) 'ClientMgr.cc'; else $(CYGPATH_W) '$(srcdir)/ClientMgr.cc'; fi` libpekwm_wm_a-CmdDialog.o: CmdDialog.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-CmdDialog.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-CmdDialog.Tpo -c -o libpekwm_wm_a-CmdDialog.o `test -f 'CmdDialog.cc' || echo '$(srcdir)/'`CmdDialog.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-CmdDialog.Tpo $(DEPDIR)/libpekwm_wm_a-CmdDialog.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CmdDialog.cc' object='libpekwm_wm_a-CmdDialog.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-CmdDialog.o `test -f 'CmdDialog.cc' || echo '$(srcdir)/'`CmdDialog.cc libpekwm_wm_a-CmdDialog.obj: CmdDialog.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-CmdDialog.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-CmdDialog.Tpo -c -o libpekwm_wm_a-CmdDialog.obj `if test -f 'CmdDialog.cc'; then $(CYGPATH_W) 'CmdDialog.cc'; else $(CYGPATH_W) '$(srcdir)/CmdDialog.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-CmdDialog.Tpo $(DEPDIR)/libpekwm_wm_a-CmdDialog.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CmdDialog.cc' object='libpekwm_wm_a-CmdDialog.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-CmdDialog.obj `if test -f 'CmdDialog.cc'; then $(CYGPATH_W) 'CmdDialog.cc'; else $(CYGPATH_W) '$(srcdir)/CmdDialog.cc'; fi` libpekwm_wm_a-Completer.o: Completer.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Completer.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Completer.Tpo -c -o libpekwm_wm_a-Completer.o `test -f 'Completer.cc' || echo '$(srcdir)/'`Completer.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Completer.Tpo $(DEPDIR)/libpekwm_wm_a-Completer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Completer.cc' object='libpekwm_wm_a-Completer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Completer.o `test -f 'Completer.cc' || echo '$(srcdir)/'`Completer.cc libpekwm_wm_a-Completer.obj: Completer.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Completer.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Completer.Tpo -c -o libpekwm_wm_a-Completer.obj `if test -f 'Completer.cc'; then $(CYGPATH_W) 'Completer.cc'; else $(CYGPATH_W) '$(srcdir)/Completer.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Completer.Tpo $(DEPDIR)/libpekwm_wm_a-Completer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Completer.cc' object='libpekwm_wm_a-Completer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Completer.obj `if test -f 'Completer.cc'; then $(CYGPATH_W) 'Completer.cc'; else $(CYGPATH_W) '$(srcdir)/Completer.cc'; fi` libpekwm_wm_a-Config.o: Config.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Config.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Config.Tpo -c -o libpekwm_wm_a-Config.o `test -f 'Config.cc' || echo '$(srcdir)/'`Config.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Config.Tpo $(DEPDIR)/libpekwm_wm_a-Config.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Config.cc' object='libpekwm_wm_a-Config.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Config.o `test -f 'Config.cc' || echo '$(srcdir)/'`Config.cc libpekwm_wm_a-Config.obj: Config.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Config.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Config.Tpo -c -o libpekwm_wm_a-Config.obj `if test -f 'Config.cc'; then $(CYGPATH_W) 'Config.cc'; else $(CYGPATH_W) '$(srcdir)/Config.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Config.Tpo $(DEPDIR)/libpekwm_wm_a-Config.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Config.cc' object='libpekwm_wm_a-Config.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Config.obj `if test -f 'Config.cc'; then $(CYGPATH_W) 'Config.cc'; else $(CYGPATH_W) '$(srcdir)/Config.cc'; fi` libpekwm_wm_a-DockApp.o: DockApp.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-DockApp.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-DockApp.Tpo -c -o libpekwm_wm_a-DockApp.o `test -f 'DockApp.cc' || echo '$(srcdir)/'`DockApp.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-DockApp.Tpo $(DEPDIR)/libpekwm_wm_a-DockApp.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DockApp.cc' object='libpekwm_wm_a-DockApp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-DockApp.o `test -f 'DockApp.cc' || echo '$(srcdir)/'`DockApp.cc libpekwm_wm_a-DockApp.obj: DockApp.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-DockApp.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-DockApp.Tpo -c -o libpekwm_wm_a-DockApp.obj `if test -f 'DockApp.cc'; then $(CYGPATH_W) 'DockApp.cc'; else $(CYGPATH_W) '$(srcdir)/DockApp.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-DockApp.Tpo $(DEPDIR)/libpekwm_wm_a-DockApp.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DockApp.cc' object='libpekwm_wm_a-DockApp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-DockApp.obj `if test -f 'DockApp.cc'; then $(CYGPATH_W) 'DockApp.cc'; else $(CYGPATH_W) '$(srcdir)/DockApp.cc'; fi` libpekwm_wm_a-FocusToggleEventHandler.o: FocusToggleEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-FocusToggleEventHandler.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-FocusToggleEventHandler.Tpo -c -o libpekwm_wm_a-FocusToggleEventHandler.o `test -f 'FocusToggleEventHandler.cc' || echo '$(srcdir)/'`FocusToggleEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-FocusToggleEventHandler.Tpo $(DEPDIR)/libpekwm_wm_a-FocusToggleEventHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FocusToggleEventHandler.cc' object='libpekwm_wm_a-FocusToggleEventHandler.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-FocusToggleEventHandler.o `test -f 'FocusToggleEventHandler.cc' || echo '$(srcdir)/'`FocusToggleEventHandler.cc libpekwm_wm_a-FocusToggleEventHandler.obj: FocusToggleEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-FocusToggleEventHandler.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-FocusToggleEventHandler.Tpo -c -o libpekwm_wm_a-FocusToggleEventHandler.obj `if test -f 'FocusToggleEventHandler.cc'; then $(CYGPATH_W) 'FocusToggleEventHandler.cc'; else $(CYGPATH_W) '$(srcdir)/FocusToggleEventHandler.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-FocusToggleEventHandler.Tpo $(DEPDIR)/libpekwm_wm_a-FocusToggleEventHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FocusToggleEventHandler.cc' object='libpekwm_wm_a-FocusToggleEventHandler.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-FocusToggleEventHandler.obj `if test -f 'FocusToggleEventHandler.cc'; then $(CYGPATH_W) 'FocusToggleEventHandler.cc'; else $(CYGPATH_W) '$(srcdir)/FocusToggleEventHandler.cc'; fi` libpekwm_wm_a-Frame.o: Frame.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Frame.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Frame.Tpo -c -o libpekwm_wm_a-Frame.o `test -f 'Frame.cc' || echo '$(srcdir)/'`Frame.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Frame.Tpo $(DEPDIR)/libpekwm_wm_a-Frame.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Frame.cc' object='libpekwm_wm_a-Frame.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Frame.o `test -f 'Frame.cc' || echo '$(srcdir)/'`Frame.cc libpekwm_wm_a-Frame.obj: Frame.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Frame.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Frame.Tpo -c -o libpekwm_wm_a-Frame.obj `if test -f 'Frame.cc'; then $(CYGPATH_W) 'Frame.cc'; else $(CYGPATH_W) '$(srcdir)/Frame.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Frame.Tpo $(DEPDIR)/libpekwm_wm_a-Frame.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Frame.cc' object='libpekwm_wm_a-Frame.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Frame.obj `if test -f 'Frame.cc'; then $(CYGPATH_W) 'Frame.cc'; else $(CYGPATH_W) '$(srcdir)/Frame.cc'; fi` libpekwm_wm_a-FrameListMenu.o: FrameListMenu.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-FrameListMenu.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-FrameListMenu.Tpo -c -o libpekwm_wm_a-FrameListMenu.o `test -f 'FrameListMenu.cc' || echo '$(srcdir)/'`FrameListMenu.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-FrameListMenu.Tpo $(DEPDIR)/libpekwm_wm_a-FrameListMenu.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FrameListMenu.cc' object='libpekwm_wm_a-FrameListMenu.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-FrameListMenu.o `test -f 'FrameListMenu.cc' || echo '$(srcdir)/'`FrameListMenu.cc libpekwm_wm_a-FrameListMenu.obj: FrameListMenu.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-FrameListMenu.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-FrameListMenu.Tpo -c -o libpekwm_wm_a-FrameListMenu.obj `if test -f 'FrameListMenu.cc'; then $(CYGPATH_W) 'FrameListMenu.cc'; else $(CYGPATH_W) '$(srcdir)/FrameListMenu.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-FrameListMenu.Tpo $(DEPDIR)/libpekwm_wm_a-FrameListMenu.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='FrameListMenu.cc' object='libpekwm_wm_a-FrameListMenu.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-FrameListMenu.obj `if test -f 'FrameListMenu.cc'; then $(CYGPATH_W) 'FrameListMenu.cc'; else $(CYGPATH_W) '$(srcdir)/FrameListMenu.cc'; fi` libpekwm_wm_a-Globals.o: Globals.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Globals.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Globals.Tpo -c -o libpekwm_wm_a-Globals.o `test -f 'Globals.cc' || echo '$(srcdir)/'`Globals.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Globals.Tpo $(DEPDIR)/libpekwm_wm_a-Globals.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Globals.cc' object='libpekwm_wm_a-Globals.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Globals.o `test -f 'Globals.cc' || echo '$(srcdir)/'`Globals.cc libpekwm_wm_a-Globals.obj: Globals.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Globals.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Globals.Tpo -c -o libpekwm_wm_a-Globals.obj `if test -f 'Globals.cc'; then $(CYGPATH_W) 'Globals.cc'; else $(CYGPATH_W) '$(srcdir)/Globals.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Globals.Tpo $(DEPDIR)/libpekwm_wm_a-Globals.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Globals.cc' object='libpekwm_wm_a-Globals.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Globals.obj `if test -f 'Globals.cc'; then $(CYGPATH_W) 'Globals.cc'; else $(CYGPATH_W) '$(srcdir)/Globals.cc'; fi` libpekwm_wm_a-GroupingDragEventHandler.o: GroupingDragEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-GroupingDragEventHandler.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-GroupingDragEventHandler.Tpo -c -o libpekwm_wm_a-GroupingDragEventHandler.o `test -f 'GroupingDragEventHandler.cc' || echo '$(srcdir)/'`GroupingDragEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-GroupingDragEventHandler.Tpo $(DEPDIR)/libpekwm_wm_a-GroupingDragEventHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GroupingDragEventHandler.cc' object='libpekwm_wm_a-GroupingDragEventHandler.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-GroupingDragEventHandler.o `test -f 'GroupingDragEventHandler.cc' || echo '$(srcdir)/'`GroupingDragEventHandler.cc libpekwm_wm_a-GroupingDragEventHandler.obj: GroupingDragEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-GroupingDragEventHandler.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-GroupingDragEventHandler.Tpo -c -o libpekwm_wm_a-GroupingDragEventHandler.obj `if test -f 'GroupingDragEventHandler.cc'; then $(CYGPATH_W) 'GroupingDragEventHandler.cc'; else $(CYGPATH_W) '$(srcdir)/GroupingDragEventHandler.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-GroupingDragEventHandler.Tpo $(DEPDIR)/libpekwm_wm_a-GroupingDragEventHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='GroupingDragEventHandler.cc' object='libpekwm_wm_a-GroupingDragEventHandler.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-GroupingDragEventHandler.obj `if test -f 'GroupingDragEventHandler.cc'; then $(CYGPATH_W) 'GroupingDragEventHandler.cc'; else $(CYGPATH_W) '$(srcdir)/GroupingDragEventHandler.cc'; fi` libpekwm_wm_a-Harbour.o: Harbour.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Harbour.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Harbour.Tpo -c -o libpekwm_wm_a-Harbour.o `test -f 'Harbour.cc' || echo '$(srcdir)/'`Harbour.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Harbour.Tpo $(DEPDIR)/libpekwm_wm_a-Harbour.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Harbour.cc' object='libpekwm_wm_a-Harbour.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Harbour.o `test -f 'Harbour.cc' || echo '$(srcdir)/'`Harbour.cc libpekwm_wm_a-Harbour.obj: Harbour.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Harbour.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Harbour.Tpo -c -o libpekwm_wm_a-Harbour.obj `if test -f 'Harbour.cc'; then $(CYGPATH_W) 'Harbour.cc'; else $(CYGPATH_W) '$(srcdir)/Harbour.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Harbour.Tpo $(DEPDIR)/libpekwm_wm_a-Harbour.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Harbour.cc' object='libpekwm_wm_a-Harbour.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Harbour.obj `if test -f 'Harbour.cc'; then $(CYGPATH_W) 'Harbour.cc'; else $(CYGPATH_W) '$(srcdir)/Harbour.cc'; fi` libpekwm_wm_a-InputDialog.o: InputDialog.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-InputDialog.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-InputDialog.Tpo -c -o libpekwm_wm_a-InputDialog.o `test -f 'InputDialog.cc' || echo '$(srcdir)/'`InputDialog.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-InputDialog.Tpo $(DEPDIR)/libpekwm_wm_a-InputDialog.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='InputDialog.cc' object='libpekwm_wm_a-InputDialog.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-InputDialog.o `test -f 'InputDialog.cc' || echo '$(srcdir)/'`InputDialog.cc libpekwm_wm_a-InputDialog.obj: InputDialog.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-InputDialog.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-InputDialog.Tpo -c -o libpekwm_wm_a-InputDialog.obj `if test -f 'InputDialog.cc'; then $(CYGPATH_W) 'InputDialog.cc'; else $(CYGPATH_W) '$(srcdir)/InputDialog.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-InputDialog.Tpo $(DEPDIR)/libpekwm_wm_a-InputDialog.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='InputDialog.cc' object='libpekwm_wm_a-InputDialog.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-InputDialog.obj `if test -f 'InputDialog.cc'; then $(CYGPATH_W) 'InputDialog.cc'; else $(CYGPATH_W) '$(srcdir)/InputDialog.cc'; fi` libpekwm_wm_a-KeyGrabber.o: KeyGrabber.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-KeyGrabber.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-KeyGrabber.Tpo -c -o libpekwm_wm_a-KeyGrabber.o `test -f 'KeyGrabber.cc' || echo '$(srcdir)/'`KeyGrabber.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-KeyGrabber.Tpo $(DEPDIR)/libpekwm_wm_a-KeyGrabber.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='KeyGrabber.cc' object='libpekwm_wm_a-KeyGrabber.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-KeyGrabber.o `test -f 'KeyGrabber.cc' || echo '$(srcdir)/'`KeyGrabber.cc libpekwm_wm_a-KeyGrabber.obj: KeyGrabber.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-KeyGrabber.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-KeyGrabber.Tpo -c -o libpekwm_wm_a-KeyGrabber.obj `if test -f 'KeyGrabber.cc'; then $(CYGPATH_W) 'KeyGrabber.cc'; else $(CYGPATH_W) '$(srcdir)/KeyGrabber.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-KeyGrabber.Tpo $(DEPDIR)/libpekwm_wm_a-KeyGrabber.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='KeyGrabber.cc' object='libpekwm_wm_a-KeyGrabber.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-KeyGrabber.obj `if test -f 'KeyGrabber.cc'; then $(CYGPATH_W) 'KeyGrabber.cc'; else $(CYGPATH_W) '$(srcdir)/KeyGrabber.cc'; fi` libpekwm_wm_a-KeyboardMoveResizeEventHandler.o: KeyboardMoveResizeEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-KeyboardMoveResizeEventHandler.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-KeyboardMoveResizeEventHandler.Tpo -c -o libpekwm_wm_a-KeyboardMoveResizeEventHandler.o `test -f 'KeyboardMoveResizeEventHandler.cc' || echo '$(srcdir)/'`KeyboardMoveResizeEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-KeyboardMoveResizeEventHandler.Tpo $(DEPDIR)/libpekwm_wm_a-KeyboardMoveResizeEventHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='KeyboardMoveResizeEventHandler.cc' object='libpekwm_wm_a-KeyboardMoveResizeEventHandler.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-KeyboardMoveResizeEventHandler.o `test -f 'KeyboardMoveResizeEventHandler.cc' || echo '$(srcdir)/'`KeyboardMoveResizeEventHandler.cc libpekwm_wm_a-KeyboardMoveResizeEventHandler.obj: KeyboardMoveResizeEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-KeyboardMoveResizeEventHandler.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-KeyboardMoveResizeEventHandler.Tpo -c -o libpekwm_wm_a-KeyboardMoveResizeEventHandler.obj `if test -f 'KeyboardMoveResizeEventHandler.cc'; then $(CYGPATH_W) 'KeyboardMoveResizeEventHandler.cc'; else $(CYGPATH_W) '$(srcdir)/KeyboardMoveResizeEventHandler.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-KeyboardMoveResizeEventHandler.Tpo $(DEPDIR)/libpekwm_wm_a-KeyboardMoveResizeEventHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='KeyboardMoveResizeEventHandler.cc' object='libpekwm_wm_a-KeyboardMoveResizeEventHandler.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-KeyboardMoveResizeEventHandler.obj `if test -f 'KeyboardMoveResizeEventHandler.cc'; then $(CYGPATH_W) 'KeyboardMoveResizeEventHandler.cc'; else $(CYGPATH_W) '$(srcdir)/KeyboardMoveResizeEventHandler.cc'; fi` libpekwm_wm_a-ManagerWindows.o: ManagerWindows.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-ManagerWindows.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-ManagerWindows.Tpo -c -o libpekwm_wm_a-ManagerWindows.o `test -f 'ManagerWindows.cc' || echo '$(srcdir)/'`ManagerWindows.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-ManagerWindows.Tpo $(DEPDIR)/libpekwm_wm_a-ManagerWindows.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ManagerWindows.cc' object='libpekwm_wm_a-ManagerWindows.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-ManagerWindows.o `test -f 'ManagerWindows.cc' || echo '$(srcdir)/'`ManagerWindows.cc libpekwm_wm_a-ManagerWindows.obj: ManagerWindows.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-ManagerWindows.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-ManagerWindows.Tpo -c -o libpekwm_wm_a-ManagerWindows.obj `if test -f 'ManagerWindows.cc'; then $(CYGPATH_W) 'ManagerWindows.cc'; else $(CYGPATH_W) '$(srcdir)/ManagerWindows.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-ManagerWindows.Tpo $(DEPDIR)/libpekwm_wm_a-ManagerWindows.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ManagerWindows.cc' object='libpekwm_wm_a-ManagerWindows.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-ManagerWindows.obj `if test -f 'ManagerWindows.cc'; then $(CYGPATH_W) 'ManagerWindows.cc'; else $(CYGPATH_W) '$(srcdir)/ManagerWindows.cc'; fi` libpekwm_wm_a-MenuHandler.o: MenuHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-MenuHandler.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-MenuHandler.Tpo -c -o libpekwm_wm_a-MenuHandler.o `test -f 'MenuHandler.cc' || echo '$(srcdir)/'`MenuHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-MenuHandler.Tpo $(DEPDIR)/libpekwm_wm_a-MenuHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='MenuHandler.cc' object='libpekwm_wm_a-MenuHandler.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-MenuHandler.o `test -f 'MenuHandler.cc' || echo '$(srcdir)/'`MenuHandler.cc libpekwm_wm_a-MenuHandler.obj: MenuHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-MenuHandler.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-MenuHandler.Tpo -c -o libpekwm_wm_a-MenuHandler.obj `if test -f 'MenuHandler.cc'; then $(CYGPATH_W) 'MenuHandler.cc'; else $(CYGPATH_W) '$(srcdir)/MenuHandler.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-MenuHandler.Tpo $(DEPDIR)/libpekwm_wm_a-MenuHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='MenuHandler.cc' object='libpekwm_wm_a-MenuHandler.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-MenuHandler.obj `if test -f 'MenuHandler.cc'; then $(CYGPATH_W) 'MenuHandler.cc'; else $(CYGPATH_W) '$(srcdir)/MenuHandler.cc'; fi` libpekwm_wm_a-MoveEventHandler.o: MoveEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-MoveEventHandler.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-MoveEventHandler.Tpo -c -o libpekwm_wm_a-MoveEventHandler.o `test -f 'MoveEventHandler.cc' || echo '$(srcdir)/'`MoveEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-MoveEventHandler.Tpo $(DEPDIR)/libpekwm_wm_a-MoveEventHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='MoveEventHandler.cc' object='libpekwm_wm_a-MoveEventHandler.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-MoveEventHandler.o `test -f 'MoveEventHandler.cc' || echo '$(srcdir)/'`MoveEventHandler.cc libpekwm_wm_a-MoveEventHandler.obj: MoveEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-MoveEventHandler.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-MoveEventHandler.Tpo -c -o libpekwm_wm_a-MoveEventHandler.obj `if test -f 'MoveEventHandler.cc'; then $(CYGPATH_W) 'MoveEventHandler.cc'; else $(CYGPATH_W) '$(srcdir)/MoveEventHandler.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-MoveEventHandler.Tpo $(DEPDIR)/libpekwm_wm_a-MoveEventHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='MoveEventHandler.cc' object='libpekwm_wm_a-MoveEventHandler.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-MoveEventHandler.obj `if test -f 'MoveEventHandler.cc'; then $(CYGPATH_W) 'MoveEventHandler.cc'; else $(CYGPATH_W) '$(srcdir)/MoveEventHandler.cc'; fi` libpekwm_wm_a-PDecor.o: PDecor.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-PDecor.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-PDecor.Tpo -c -o libpekwm_wm_a-PDecor.o `test -f 'PDecor.cc' || echo '$(srcdir)/'`PDecor.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-PDecor.Tpo $(DEPDIR)/libpekwm_wm_a-PDecor.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PDecor.cc' object='libpekwm_wm_a-PDecor.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-PDecor.o `test -f 'PDecor.cc' || echo '$(srcdir)/'`PDecor.cc libpekwm_wm_a-PDecor.obj: PDecor.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-PDecor.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-PDecor.Tpo -c -o libpekwm_wm_a-PDecor.obj `if test -f 'PDecor.cc'; then $(CYGPATH_W) 'PDecor.cc'; else $(CYGPATH_W) '$(srcdir)/PDecor.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-PDecor.Tpo $(DEPDIR)/libpekwm_wm_a-PDecor.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PDecor.cc' object='libpekwm_wm_a-PDecor.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-PDecor.obj `if test -f 'PDecor.cc'; then $(CYGPATH_W) 'PDecor.cc'; else $(CYGPATH_W) '$(srcdir)/PDecor.cc'; fi` libpekwm_wm_a-PMenu.o: PMenu.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-PMenu.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-PMenu.Tpo -c -o libpekwm_wm_a-PMenu.o `test -f 'PMenu.cc' || echo '$(srcdir)/'`PMenu.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-PMenu.Tpo $(DEPDIR)/libpekwm_wm_a-PMenu.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PMenu.cc' object='libpekwm_wm_a-PMenu.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-PMenu.o `test -f 'PMenu.cc' || echo '$(srcdir)/'`PMenu.cc libpekwm_wm_a-PMenu.obj: PMenu.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-PMenu.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-PMenu.Tpo -c -o libpekwm_wm_a-PMenu.obj `if test -f 'PMenu.cc'; then $(CYGPATH_W) 'PMenu.cc'; else $(CYGPATH_W) '$(srcdir)/PMenu.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-PMenu.Tpo $(DEPDIR)/libpekwm_wm_a-PMenu.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PMenu.cc' object='libpekwm_wm_a-PMenu.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-PMenu.obj `if test -f 'PMenu.cc'; then $(CYGPATH_W) 'PMenu.cc'; else $(CYGPATH_W) '$(srcdir)/PMenu.cc'; fi` libpekwm_wm_a-ResizeEventHandler.o: ResizeEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-ResizeEventHandler.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-ResizeEventHandler.Tpo -c -o libpekwm_wm_a-ResizeEventHandler.o `test -f 'ResizeEventHandler.cc' || echo '$(srcdir)/'`ResizeEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-ResizeEventHandler.Tpo $(DEPDIR)/libpekwm_wm_a-ResizeEventHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResizeEventHandler.cc' object='libpekwm_wm_a-ResizeEventHandler.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-ResizeEventHandler.o `test -f 'ResizeEventHandler.cc' || echo '$(srcdir)/'`ResizeEventHandler.cc libpekwm_wm_a-ResizeEventHandler.obj: ResizeEventHandler.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-ResizeEventHandler.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-ResizeEventHandler.Tpo -c -o libpekwm_wm_a-ResizeEventHandler.obj `if test -f 'ResizeEventHandler.cc'; then $(CYGPATH_W) 'ResizeEventHandler.cc'; else $(CYGPATH_W) '$(srcdir)/ResizeEventHandler.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-ResizeEventHandler.Tpo $(DEPDIR)/libpekwm_wm_a-ResizeEventHandler.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResizeEventHandler.cc' object='libpekwm_wm_a-ResizeEventHandler.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-ResizeEventHandler.obj `if test -f 'ResizeEventHandler.cc'; then $(CYGPATH_W) 'ResizeEventHandler.cc'; else $(CYGPATH_W) '$(srcdir)/ResizeEventHandler.cc'; fi` libpekwm_wm_a-SearchDialog.o: SearchDialog.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-SearchDialog.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-SearchDialog.Tpo -c -o libpekwm_wm_a-SearchDialog.o `test -f 'SearchDialog.cc' || echo '$(srcdir)/'`SearchDialog.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-SearchDialog.Tpo $(DEPDIR)/libpekwm_wm_a-SearchDialog.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SearchDialog.cc' object='libpekwm_wm_a-SearchDialog.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-SearchDialog.o `test -f 'SearchDialog.cc' || echo '$(srcdir)/'`SearchDialog.cc libpekwm_wm_a-SearchDialog.obj: SearchDialog.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-SearchDialog.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-SearchDialog.Tpo -c -o libpekwm_wm_a-SearchDialog.obj `if test -f 'SearchDialog.cc'; then $(CYGPATH_W) 'SearchDialog.cc'; else $(CYGPATH_W) '$(srcdir)/SearchDialog.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-SearchDialog.Tpo $(DEPDIR)/libpekwm_wm_a-SearchDialog.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SearchDialog.cc' object='libpekwm_wm_a-SearchDialog.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-SearchDialog.obj `if test -f 'SearchDialog.cc'; then $(CYGPATH_W) 'SearchDialog.cc'; else $(CYGPATH_W) '$(srcdir)/SearchDialog.cc'; fi` libpekwm_wm_a-StatusWindow.o: StatusWindow.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-StatusWindow.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-StatusWindow.Tpo -c -o libpekwm_wm_a-StatusWindow.o `test -f 'StatusWindow.cc' || echo '$(srcdir)/'`StatusWindow.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-StatusWindow.Tpo $(DEPDIR)/libpekwm_wm_a-StatusWindow.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='StatusWindow.cc' object='libpekwm_wm_a-StatusWindow.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-StatusWindow.o `test -f 'StatusWindow.cc' || echo '$(srcdir)/'`StatusWindow.cc libpekwm_wm_a-StatusWindow.obj: StatusWindow.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-StatusWindow.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-StatusWindow.Tpo -c -o libpekwm_wm_a-StatusWindow.obj `if test -f 'StatusWindow.cc'; then $(CYGPATH_W) 'StatusWindow.cc'; else $(CYGPATH_W) '$(srcdir)/StatusWindow.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-StatusWindow.Tpo $(DEPDIR)/libpekwm_wm_a-StatusWindow.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='StatusWindow.cc' object='libpekwm_wm_a-StatusWindow.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-StatusWindow.obj `if test -f 'StatusWindow.cc'; then $(CYGPATH_W) 'StatusWindow.cc'; else $(CYGPATH_W) '$(srcdir)/StatusWindow.cc'; fi` libpekwm_wm_a-ThemeGm.o: ThemeGm.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-ThemeGm.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-ThemeGm.Tpo -c -o libpekwm_wm_a-ThemeGm.o `test -f 'ThemeGm.cc' || echo '$(srcdir)/'`ThemeGm.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-ThemeGm.Tpo $(DEPDIR)/libpekwm_wm_a-ThemeGm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ThemeGm.cc' object='libpekwm_wm_a-ThemeGm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-ThemeGm.o `test -f 'ThemeGm.cc' || echo '$(srcdir)/'`ThemeGm.cc libpekwm_wm_a-ThemeGm.obj: ThemeGm.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-ThemeGm.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-ThemeGm.Tpo -c -o libpekwm_wm_a-ThemeGm.obj `if test -f 'ThemeGm.cc'; then $(CYGPATH_W) 'ThemeGm.cc'; else $(CYGPATH_W) '$(srcdir)/ThemeGm.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-ThemeGm.Tpo $(DEPDIR)/libpekwm_wm_a-ThemeGm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ThemeGm.cc' object='libpekwm_wm_a-ThemeGm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-ThemeGm.obj `if test -f 'ThemeGm.cc'; then $(CYGPATH_W) 'ThemeGm.cc'; else $(CYGPATH_W) '$(srcdir)/ThemeGm.cc'; fi` libpekwm_wm_a-WORefMenu.o: WORefMenu.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-WORefMenu.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-WORefMenu.Tpo -c -o libpekwm_wm_a-WORefMenu.o `test -f 'WORefMenu.cc' || echo '$(srcdir)/'`WORefMenu.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-WORefMenu.Tpo $(DEPDIR)/libpekwm_wm_a-WORefMenu.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WORefMenu.cc' object='libpekwm_wm_a-WORefMenu.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-WORefMenu.o `test -f 'WORefMenu.cc' || echo '$(srcdir)/'`WORefMenu.cc libpekwm_wm_a-WORefMenu.obj: WORefMenu.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-WORefMenu.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-WORefMenu.Tpo -c -o libpekwm_wm_a-WORefMenu.obj `if test -f 'WORefMenu.cc'; then $(CYGPATH_W) 'WORefMenu.cc'; else $(CYGPATH_W) '$(srcdir)/WORefMenu.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-WORefMenu.Tpo $(DEPDIR)/libpekwm_wm_a-WORefMenu.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WORefMenu.cc' object='libpekwm_wm_a-WORefMenu.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-WORefMenu.obj `if test -f 'WORefMenu.cc'; then $(CYGPATH_W) 'WORefMenu.cc'; else $(CYGPATH_W) '$(srcdir)/WORefMenu.cc'; fi` libpekwm_wm_a-WinLayouter.o: WinLayouter.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-WinLayouter.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-WinLayouter.Tpo -c -o libpekwm_wm_a-WinLayouter.o `test -f 'WinLayouter.cc' || echo '$(srcdir)/'`WinLayouter.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-WinLayouter.Tpo $(DEPDIR)/libpekwm_wm_a-WinLayouter.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WinLayouter.cc' object='libpekwm_wm_a-WinLayouter.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-WinLayouter.o `test -f 'WinLayouter.cc' || echo '$(srcdir)/'`WinLayouter.cc libpekwm_wm_a-WinLayouter.obj: WinLayouter.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-WinLayouter.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-WinLayouter.Tpo -c -o libpekwm_wm_a-WinLayouter.obj `if test -f 'WinLayouter.cc'; then $(CYGPATH_W) 'WinLayouter.cc'; else $(CYGPATH_W) '$(srcdir)/WinLayouter.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-WinLayouter.Tpo $(DEPDIR)/libpekwm_wm_a-WinLayouter.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WinLayouter.cc' object='libpekwm_wm_a-WinLayouter.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-WinLayouter.obj `if test -f 'WinLayouter.cc'; then $(CYGPATH_W) 'WinLayouter.cc'; else $(CYGPATH_W) '$(srcdir)/WinLayouter.cc'; fi` libpekwm_wm_a-WindowManager.o: WindowManager.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-WindowManager.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-WindowManager.Tpo -c -o libpekwm_wm_a-WindowManager.o `test -f 'WindowManager.cc' || echo '$(srcdir)/'`WindowManager.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-WindowManager.Tpo $(DEPDIR)/libpekwm_wm_a-WindowManager.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WindowManager.cc' object='libpekwm_wm_a-WindowManager.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-WindowManager.o `test -f 'WindowManager.cc' || echo '$(srcdir)/'`WindowManager.cc libpekwm_wm_a-WindowManager.obj: WindowManager.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-WindowManager.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-WindowManager.Tpo -c -o libpekwm_wm_a-WindowManager.obj `if test -f 'WindowManager.cc'; then $(CYGPATH_W) 'WindowManager.cc'; else $(CYGPATH_W) '$(srcdir)/WindowManager.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-WindowManager.Tpo $(DEPDIR)/libpekwm_wm_a-WindowManager.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WindowManager.cc' object='libpekwm_wm_a-WindowManager.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-WindowManager.obj `if test -f 'WindowManager.cc'; then $(CYGPATH_W) 'WindowManager.cc'; else $(CYGPATH_W) '$(srcdir)/WindowManager.cc'; fi` libpekwm_wm_a-WmUtil.o: WmUtil.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-WmUtil.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-WmUtil.Tpo -c -o libpekwm_wm_a-WmUtil.o `test -f 'WmUtil.cc' || echo '$(srcdir)/'`WmUtil.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-WmUtil.Tpo $(DEPDIR)/libpekwm_wm_a-WmUtil.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WmUtil.cc' object='libpekwm_wm_a-WmUtil.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-WmUtil.o `test -f 'WmUtil.cc' || echo '$(srcdir)/'`WmUtil.cc libpekwm_wm_a-WmUtil.obj: WmUtil.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-WmUtil.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-WmUtil.Tpo -c -o libpekwm_wm_a-WmUtil.obj `if test -f 'WmUtil.cc'; then $(CYGPATH_W) 'WmUtil.cc'; else $(CYGPATH_W) '$(srcdir)/WmUtil.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-WmUtil.Tpo $(DEPDIR)/libpekwm_wm_a-WmUtil.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WmUtil.cc' object='libpekwm_wm_a-WmUtil.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-WmUtil.obj `if test -f 'WmUtil.cc'; then $(CYGPATH_W) 'WmUtil.cc'; else $(CYGPATH_W) '$(srcdir)/WmUtil.cc'; fi` libpekwm_wm_a-WorkspaceIndicator.o: WorkspaceIndicator.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-WorkspaceIndicator.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-WorkspaceIndicator.Tpo -c -o libpekwm_wm_a-WorkspaceIndicator.o `test -f 'WorkspaceIndicator.cc' || echo '$(srcdir)/'`WorkspaceIndicator.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-WorkspaceIndicator.Tpo $(DEPDIR)/libpekwm_wm_a-WorkspaceIndicator.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WorkspaceIndicator.cc' object='libpekwm_wm_a-WorkspaceIndicator.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-WorkspaceIndicator.o `test -f 'WorkspaceIndicator.cc' || echo '$(srcdir)/'`WorkspaceIndicator.cc libpekwm_wm_a-WorkspaceIndicator.obj: WorkspaceIndicator.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-WorkspaceIndicator.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-WorkspaceIndicator.Tpo -c -o libpekwm_wm_a-WorkspaceIndicator.obj `if test -f 'WorkspaceIndicator.cc'; then $(CYGPATH_W) 'WorkspaceIndicator.cc'; else $(CYGPATH_W) '$(srcdir)/WorkspaceIndicator.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-WorkspaceIndicator.Tpo $(DEPDIR)/libpekwm_wm_a-WorkspaceIndicator.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='WorkspaceIndicator.cc' object='libpekwm_wm_a-WorkspaceIndicator.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-WorkspaceIndicator.obj `if test -f 'WorkspaceIndicator.cc'; then $(CYGPATH_W) 'WorkspaceIndicator.cc'; else $(CYGPATH_W) '$(srcdir)/WorkspaceIndicator.cc'; fi` libpekwm_wm_a-Workspaces.o: Workspaces.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Workspaces.o -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Workspaces.Tpo -c -o libpekwm_wm_a-Workspaces.o `test -f 'Workspaces.cc' || echo '$(srcdir)/'`Workspaces.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Workspaces.Tpo $(DEPDIR)/libpekwm_wm_a-Workspaces.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Workspaces.cc' object='libpekwm_wm_a-Workspaces.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Workspaces.o `test -f 'Workspaces.cc' || echo '$(srcdir)/'`Workspaces.cc libpekwm_wm_a-Workspaces.obj: Workspaces.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -MT libpekwm_wm_a-Workspaces.obj -MD -MP -MF $(DEPDIR)/libpekwm_wm_a-Workspaces.Tpo -c -o libpekwm_wm_a-Workspaces.obj `if test -f 'Workspaces.cc'; then $(CYGPATH_W) 'Workspaces.cc'; else $(CYGPATH_W) '$(srcdir)/Workspaces.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpekwm_wm_a-Workspaces.Tpo $(DEPDIR)/libpekwm_wm_a-Workspaces.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Workspaces.cc' object='libpekwm_wm_a-Workspaces.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpekwm_wm_a_CXXFLAGS) $(CXXFLAGS) -c -o libpekwm_wm_a-Workspaces.obj `if test -f 'Workspaces.cc'; then $(CYGPATH_W) 'Workspaces.cc'; else $(CYGPATH_W) '$(srcdir)/Workspaces.cc'; fi` pekwm-pekwm.o: pekwm.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_CXXFLAGS) $(CXXFLAGS) -MT pekwm-pekwm.o -MD -MP -MF $(DEPDIR)/pekwm-pekwm.Tpo -c -o pekwm-pekwm.o `test -f 'pekwm.cc' || echo '$(srcdir)/'`pekwm.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm-pekwm.Tpo $(DEPDIR)/pekwm-pekwm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pekwm.cc' object='pekwm-pekwm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_CXXFLAGS) $(CXXFLAGS) -c -o pekwm-pekwm.o `test -f 'pekwm.cc' || echo '$(srcdir)/'`pekwm.cc pekwm-pekwm.obj: pekwm.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_CXXFLAGS) $(CXXFLAGS) -MT pekwm-pekwm.obj -MD -MP -MF $(DEPDIR)/pekwm-pekwm.Tpo -c -o pekwm-pekwm.obj `if test -f 'pekwm.cc'; then $(CYGPATH_W) 'pekwm.cc'; else $(CYGPATH_W) '$(srcdir)/pekwm.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm-pekwm.Tpo $(DEPDIR)/pekwm-pekwm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pekwm.cc' object='pekwm-pekwm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_CXXFLAGS) $(CXXFLAGS) -c -o pekwm-pekwm.obj `if test -f 'pekwm.cc'; then $(CYGPATH_W) 'pekwm.cc'; else $(CYGPATH_W) '$(srcdir)/pekwm.cc'; fi` ../pekwm-pekwm_env.o: ../pekwm_env.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_CXXFLAGS) $(CXXFLAGS) -MT ../pekwm-pekwm_env.o -MD -MP -MF ../$(DEPDIR)/pekwm-pekwm_env.Tpo -c -o ../pekwm-pekwm_env.o `test -f '../pekwm_env.cc' || echo '$(srcdir)/'`../pekwm_env.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../$(DEPDIR)/pekwm-pekwm_env.Tpo ../$(DEPDIR)/pekwm-pekwm_env.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../pekwm_env.cc' object='../pekwm-pekwm_env.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_CXXFLAGS) $(CXXFLAGS) -c -o ../pekwm-pekwm_env.o `test -f '../pekwm_env.cc' || echo '$(srcdir)/'`../pekwm_env.cc ../pekwm-pekwm_env.obj: ../pekwm_env.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_CXXFLAGS) $(CXXFLAGS) -MT ../pekwm-pekwm_env.obj -MD -MP -MF ../$(DEPDIR)/pekwm-pekwm_env.Tpo -c -o ../pekwm-pekwm_env.obj `if test -f '../pekwm_env.cc'; then $(CYGPATH_W) '../pekwm_env.cc'; else $(CYGPATH_W) '$(srcdir)/../pekwm_env.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../$(DEPDIR)/pekwm-pekwm_env.Tpo ../$(DEPDIR)/pekwm-pekwm_env.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../pekwm_env.cc' object='../pekwm-pekwm_env.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_CXXFLAGS) $(CXXFLAGS) -c -o ../pekwm-pekwm_env.obj `if test -f '../pekwm_env.cc'; then $(CYGPATH_W) '../pekwm_env.cc'; else $(CYGPATH_W) '$(srcdir)/../pekwm_env.cc'; fi` ../lib/pekwm-Compat.o: ../lib/Compat.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_CXXFLAGS) $(CXXFLAGS) -MT ../lib/pekwm-Compat.o -MD -MP -MF ../lib/$(DEPDIR)/pekwm-Compat.Tpo -c -o ../lib/pekwm-Compat.o `test -f '../lib/Compat.cc' || echo '$(srcdir)/'`../lib/Compat.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/pekwm-Compat.Tpo ../lib/$(DEPDIR)/pekwm-Compat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../lib/Compat.cc' object='../lib/pekwm-Compat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_CXXFLAGS) $(CXXFLAGS) -c -o ../lib/pekwm-Compat.o `test -f '../lib/Compat.cc' || echo '$(srcdir)/'`../lib/Compat.cc ../lib/pekwm-Compat.obj: ../lib/Compat.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_CXXFLAGS) $(CXXFLAGS) -MT ../lib/pekwm-Compat.obj -MD -MP -MF ../lib/$(DEPDIR)/pekwm-Compat.Tpo -c -o ../lib/pekwm-Compat.obj `if test -f '../lib/Compat.cc'; then $(CYGPATH_W) '../lib/Compat.cc'; else $(CYGPATH_W) '$(srcdir)/../lib/Compat.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/pekwm-Compat.Tpo ../lib/$(DEPDIR)/pekwm-Compat.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../lib/Compat.cc' object='../lib/pekwm-Compat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_CXXFLAGS) $(CXXFLAGS) -c -o ../lib/pekwm-Compat.obj `if test -f '../lib/Compat.cc'; then $(CYGPATH_W) '../lib/Compat.cc'; else $(CYGPATH_W) '$(srcdir)/../lib/Compat.cc'; fi` pekwm_wm-pekwm_wm.o: pekwm_wm.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_wm_CXXFLAGS) $(CXXFLAGS) -MT pekwm_wm-pekwm_wm.o -MD -MP -MF $(DEPDIR)/pekwm_wm-pekwm_wm.Tpo -c -o pekwm_wm-pekwm_wm.o `test -f 'pekwm_wm.cc' || echo '$(srcdir)/'`pekwm_wm.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_wm-pekwm_wm.Tpo $(DEPDIR)/pekwm_wm-pekwm_wm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pekwm_wm.cc' object='pekwm_wm-pekwm_wm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_wm_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_wm-pekwm_wm.o `test -f 'pekwm_wm.cc' || echo '$(srcdir)/'`pekwm_wm.cc pekwm_wm-pekwm_wm.obj: pekwm_wm.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_wm_CXXFLAGS) $(CXXFLAGS) -MT pekwm_wm-pekwm_wm.obj -MD -MP -MF $(DEPDIR)/pekwm_wm-pekwm_wm.Tpo -c -o pekwm_wm-pekwm_wm.obj `if test -f 'pekwm_wm.cc'; then $(CYGPATH_W) 'pekwm_wm.cc'; else $(CYGPATH_W) '$(srcdir)/pekwm_wm.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pekwm_wm-pekwm_wm.Tpo $(DEPDIR)/pekwm_wm-pekwm_wm.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pekwm_wm.cc' object='pekwm_wm-pekwm_wm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_wm_CXXFLAGS) $(CXXFLAGS) -c -o pekwm_wm-pekwm_wm.obj `if test -f 'pekwm_wm.cc'; then $(CYGPATH_W) 'pekwm_wm.cc'; else $(CYGPATH_W) '$(srcdir)/pekwm_wm.cc'; fi` ../pekwm_wm-pekwm_env.o: ../pekwm_env.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_wm_CXXFLAGS) $(CXXFLAGS) -MT ../pekwm_wm-pekwm_env.o -MD -MP -MF ../$(DEPDIR)/pekwm_wm-pekwm_env.Tpo -c -o ../pekwm_wm-pekwm_env.o `test -f '../pekwm_env.cc' || echo '$(srcdir)/'`../pekwm_env.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../$(DEPDIR)/pekwm_wm-pekwm_env.Tpo ../$(DEPDIR)/pekwm_wm-pekwm_env.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../pekwm_env.cc' object='../pekwm_wm-pekwm_env.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_wm_CXXFLAGS) $(CXXFLAGS) -c -o ../pekwm_wm-pekwm_env.o `test -f '../pekwm_env.cc' || echo '$(srcdir)/'`../pekwm_env.cc ../pekwm_wm-pekwm_env.obj: ../pekwm_env.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_wm_CXXFLAGS) $(CXXFLAGS) -MT ../pekwm_wm-pekwm_env.obj -MD -MP -MF ../$(DEPDIR)/pekwm_wm-pekwm_env.Tpo -c -o ../pekwm_wm-pekwm_env.obj `if test -f '../pekwm_env.cc'; then $(CYGPATH_W) '../pekwm_env.cc'; else $(CYGPATH_W) '$(srcdir)/../pekwm_env.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ../$(DEPDIR)/pekwm_wm-pekwm_env.Tpo ../$(DEPDIR)/pekwm_wm-pekwm_env.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='../pekwm_env.cc' object='../pekwm_wm-pekwm_env.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pekwm_wm_CXXFLAGS) $(CXXFLAGS) -c -o ../pekwm_wm-pekwm_env.obj `if test -f '../pekwm_env.cc'; then $(CYGPATH_W) '../pekwm_env.cc'; else $(CYGPATH_W) '$(srcdir)/../pekwm_env.cc'; fi` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(LIBRARIES) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -$(am__rm_f) $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) -$(am__rm_f) ../$(DEPDIR)/$(am__dirstamp) -$(am__rm_f) ../$(am__dirstamp) -$(am__rm_f) ../lib/$(DEPDIR)/$(am__dirstamp) -$(am__rm_f) ../lib/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-noinstLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ../$(DEPDIR)/pekwm-pekwm_env.Po -rm -f ../$(DEPDIR)/pekwm_wm-pekwm_env.Po -rm -f ../lib/$(DEPDIR)/pekwm-Compat.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-ActionHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-ActionMenu.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-AutoProperties.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Client.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-ClientMgr.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-CmdDialog.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Completer.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Config.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-DockApp.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-FocusToggleEventHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Frame.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-FrameListMenu.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Globals.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-GroupingDragEventHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Harbour.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-InputDialog.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-KeyGrabber.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-KeyboardMoveResizeEventHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-ManagerWindows.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-MenuHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-MoveEventHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-PDecor.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-PMenu.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-ResizeEventHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-SearchDialog.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-StatusWindow.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-ThemeGm.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-WORefMenu.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-WinLayouter.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-WindowManager.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-WmUtil.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-WorkspaceIndicator.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Workspaces.Po -rm -f ./$(DEPDIR)/pekwm-pekwm.Po -rm -f ./$(DEPDIR)/pekwm_wm-pekwm_wm.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ../$(DEPDIR)/pekwm-pekwm_env.Po -rm -f ../$(DEPDIR)/pekwm_wm-pekwm_env.Po -rm -f ../lib/$(DEPDIR)/pekwm-Compat.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-ActionHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-ActionMenu.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-AutoProperties.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Client.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-ClientMgr.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-CmdDialog.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Completer.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Config.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-DockApp.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-FocusToggleEventHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Frame.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-FrameListMenu.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Globals.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-GroupingDragEventHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Harbour.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-InputDialog.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-KeyGrabber.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-KeyboardMoveResizeEventHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-ManagerWindows.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-MenuHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-MoveEventHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-PDecor.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-PMenu.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-ResizeEventHandler.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-SearchDialog.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-StatusWindow.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-ThemeGm.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-WORefMenu.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-WinLayouter.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-WindowManager.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-WmUtil.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-WorkspaceIndicator.Po -rm -f ./$(DEPDIR)/libpekwm_wm_a-Workspaces.Po -rm -f ./$(DEPDIR)/pekwm-pekwm.Po -rm -f ./$(DEPDIR)/pekwm_wm-pekwm_wm.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-binPROGRAMS clean-generic clean-noinstLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: # Tell GNU make to disable its built-in pattern rules. %:: %,v %:: RCS/%,v %:: RCS/% %:: s.% %:: SCCS/s.% pekwm-0.4.4/src/wm/WorkspaceIndicator.cc0000664000175000017500000001305215126136025013643 // // WorkspaceIndicator.cc for pekwm // Copyright (C) 2021-2024 Claes Nästén // Copyright (C) 2009-2020 the pekwm development team // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include #include "Config.hh" #include "Workspaces.hh" #include "WorkspaceIndicator.hh" #include "X11.hh" #include "tk/X11Util.hh" /** * Display constructor */ WorkspaceIndicator::Display::Display(PWinObj *parent) : PWinObj(false) { _parent = parent; // Do not give the indicator focus, it doesn't handle input _focusable = false; long event_mask = ButtonPressMask|ButtonReleaseMask|ButtonMotionMask| FocusChangeMask|KeyPressMask|KeyReleaseMask; _window = X11::createWmWindow(_parent->getWindow(), 0, 0, 1, 1, InputOutput, event_mask); } /** * Display destructor */ WorkspaceIndicator::Display::~Display(void) { X11::destroyWindow(_window); } /** * Get required size to render workspaces. */ bool WorkspaceIndicator::Display::getSizeRequest(Geometry &gm) { Geometry head; uint head_nr = X11::getNearestHead(_parent->getX(), _parent->getY()); X11::getHeadInfo(head_nr, head); uint head_size = std::min(head.width, head.height) / pekwm::config()->getWorkspaceIndicatorScale(); gm.x = gm.y = 0; gm.width = head_size * Workspaces::getPerRow() + getPaddingHorizontal(); gm.height = head_size * Workspaces::getRows() + getPaddingVertical(); return true; } /** * Render workspace view to pixmap */ void WorkspaceIndicator::Display::render(void) { Theme::WorkspaceIndicatorData *data = pekwm::theme()->getWorkspaceIndicatorData(); // Make sure surface has correct size _surface.resize(_gm.width, _gm.height); // Render background data->texture_background->render(&_surface, 0, 0, _gm.width, _gm.height); // Render workspace grid, then active workspace fill and end with // rendering active workspace number and name renderWorkspaces(data->edge_padding, data->edge_padding, _gm.width - getPaddingHorizontal(), _gm.height - getPaddingVertical()); data->font->setColor(data->font_color); uint width_used; data->font->draw(&_surface, data->edge_padding, _gm.height - data->edge_padding - data->font->getHeight(), Workspaces::getActWorkspace().getName(), width_used, _gm.width - data->edge_padding * 2 /* max_width */); // Refresh X11::setWindowBackgroundPixmap(_window, _surface.getDrawable()); X11::clearWindow(_window); } /** * Render workspace part of indication * * @param x X offset on drawable * @param y Y offset on drawable * @param width Allowed width to use * @param height Allowed height to use */ void WorkspaceIndicator::Display::renderWorkspaces(int x, int y, uint width, uint height) { Theme::WorkspaceIndicatorData *data = pekwm::theme()->getWorkspaceIndicatorData(); uint per_row = Workspaces::getPerRow(); uint rows = Workspaces::getRows(); uint ws_width = width / per_row; uint ws_height = height / rows; // Starting positions of the workspace squares uint x_pos = x; uint y_pos = y; std::vector::size_type i=0; for (uint row = 0; i < Workspaces::size(); ++i) { // Check for next row if (Workspaces::getRow(i) > row) { row = Workspaces::getRow(i); x_pos = x; y_pos += ws_height + data->workspace_padding; } PTexture *tex = i == Workspaces::getActive() ? data->texture_workspace_act : data->texture_workspace; tex->render(&_surface, x_pos, y_pos, ws_width, ws_height); x_pos += ws_width + data->workspace_padding; } } /** * Get horizontal padding for window around workspaces. */ uint WorkspaceIndicator::Display::getPaddingHorizontal(void) { Theme::WorkspaceIndicatorData *data = pekwm::theme()->getWorkspaceIndicatorData(); return (data->edge_padding * 2 + data->workspace_padding * (Workspaces::getPerRow() - 1)); } /** * Get vertical padding for window around workspaces. */ uint WorkspaceIndicator::Display::getPaddingVertical(void) { Theme::WorkspaceIndicatorData *data = pekwm::theme()->getWorkspaceIndicatorData(); return (data->edge_padding * 3 + data->font->getHeight() + data->workspace_padding * (Workspaces::getRows() - 1)); } /** * WorkspaceIndicator constructor */ WorkspaceIndicator::WorkspaceIndicator() : PDecor(None, true, true, "WORKSPACEINDICATOR"), _display_wo(this) { _type = PWinObj::WO_WORKSPACE_INDICATOR; setLayer(LAYER_NONE); // Make sure this goes on top of everything _hidden = true; // Do not include in workspace handling etc // Add title titleAdd(&_title); titleSetActive(0); _title.setReal("Workspace"); // Add display window addChild(&_display_wo); activateChild(&_display_wo); _display_wo.mapWindow(); // Load theme data, horay for pretty colors loadTheme(); // Register ourselves Workspaces::insert(this); woListAdd(this); _wo_map[_window] = this; setOpacity(pekwm::config()->getWorkspaceIndicatorOpacity()); } /** * WorkspaceIndicator destructor */ WorkspaceIndicator::~WorkspaceIndicator(void) { removeChild(&_display_wo, false); // Un-register ourselves Workspaces::remove(this); _wo_map.erase(_window); woListRemove(this); } /** * Resize indicator and render */ void WorkspaceIndicator::render(void) { // Center on head Geometry head, request; CurrHeadSelector chs = pekwm::config()->getCurrHeadSelector(); X11::getHeadInfo(X11Util::getCurrHead(chs), head); _display_wo.getSizeRequest(request); resizeChild(request.width, request.height); move(head.x + (head.width - _gm.width) / 2, head.y + (head.height - _gm.height) / 2); // Render workspaces _display_wo.render(); } pekwm-0.4.4/src/wm/ThemeGm.cc0000664000175000017500000000603615126136025011402 // // ThemeGm.cc for pekwm // Copyright (C) 2021 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "ThemeGm.hh" uint ThemeGm::decorWidth(const ThemeState *state) const { return bdLeft(state) + bdRight(state); } uint ThemeGm::decorHeight(const ThemeState *state) const { return bdTop(state) + bdBottom(state) + titleHeight(state); } PFont* ThemeGm::getFont(FocusedState state) const { return _data->getFont(state); } /** * Calculate title width (for given title) */ uint ThemeGm::titleWidth(const ThemeState *state, const std::string& str) const { return getFont(state->getFocusedState(false))->getWidth(str) + _data->getPad(PAD_LEFT) + _data->getPad(PAD_RIGHT) + titleLeftOffset(state) + titleRightOffset(state); } /** Calculate title height, 0 if titlebar is disabled. */ uint ThemeGm::titleHeight(const ThemeState *state) const { if (! _data || ! state->hasTitlebar()) { return 0; } if (_data->isTitleHeightAdapt()) { return getFont(state->getFocusedState(false))->getHeight() + _data->getPad(PAD_UP) + _data->getPad(PAD_DOWN); } else { return _data->getTitleHeight(); } } /** * Offset for top border, if non full width the border is placed * below the titlebar. */ uint ThemeGm::bdTopOffset(const ThemeState *state) const { return _data->getTitleWidthMin() ? titleHeight(state) : 0; } uint ThemeGm::bdTop(const ThemeState *state) const { return getBorder(state, BORDER_TOP)->getHeight(); } uint ThemeGm::bdTopLeft(const ThemeState *state) const { return getBorder(state, BORDER_TOP_LEFT)->getWidth(); } uint ThemeGm::bdTopLeftHeight(const ThemeState *state) const { return getBorder(state, BORDER_TOP_LEFT)->getHeight(); } uint ThemeGm::bdTopRight(const ThemeState *state) const { return getBorder(state, BORDER_TOP_RIGHT)->getWidth(); } uint ThemeGm::bdTopRightHeight(const ThemeState *state) const { return getBorder(state, BORDER_TOP_RIGHT)->getHeight(); } uint ThemeGm::bdBottom(const ThemeState *state) const { return getBorder(state, BORDER_BOTTOM)->getHeight(); } uint ThemeGm::bdBottomLeft(const ThemeState *state) const { return getBorder(state, BORDER_BOTTOM_LEFT)->getWidth(); } uint ThemeGm::bdBottomLeftHeight(const ThemeState *state) const { return getBorder(state, BORDER_BOTTOM_LEFT)->getHeight(); } uint ThemeGm::bdBottomRight(const ThemeState *state) const { return getBorder(state, BORDER_BOTTOM_RIGHT)->getWidth(); } uint ThemeGm::bdBottomRightHeight(const ThemeState *state) const { return getBorder(state, BORDER_BOTTOM_RIGHT)->getHeight(); } uint ThemeGm::bdLeft(const ThemeState *state) const { return getBorder(state, BORDER_LEFT)->getWidth(); } uint ThemeGm::bdRight(const ThemeState *state) const { return getBorder(state, BORDER_RIGHT)->getWidth(); } const PTexture* ThemeGm::getBorder(const ThemeState *state, BorderPosition pos) const { if (! _data || ! state->hasBorder()) { return &_empty; } FocusedState focused_state = state->getFocusedState(false); return _data->getBorderTexture(focused_state, pos); } pekwm-0.4.4/src/wm/WmUtil.hh0000664000175000017500000000105515126136025011303 // // WmUtil.hh for pekwm // Copyright (C) 2021 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _PEKWM_WMUTIL_HH_ #define _PEKWM_WMUTIL_HH_ class Config; class ImageHandler; /** * Resource handling for image loading paths including icon paths for * the current theme. */ class WithIconPath { public: WithIconPath(const Config *cfg, ImageHandler *image_handler); ~WithIconPath(void); private: ImageHandler *_image_handler; }; #endif // _PEKWM_WMUTIL_HH_ pekwm-0.4.4/src/wm/ActionHandler.cc0000664000175000017500000011164715126226753012604 // // ActionHandler.cc for pekwm // Copyright (C) 2002-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include "ActionHandler.hh" #include "Debug.hh" #include "PMenu.hh" #include "Frame.hh" #include "Client.hh" #include "ClientMgr.hh" #include "Config.hh" #include "Workspaces.hh" #include "Util.hh" #include "RegexString.hh" #include "Harbour.hh" #include "MenuHandler.hh" #include "PDecor.hh" #include "PMenu.hh" #include "WORefMenu.hh" #include "ActionMenu.hh" #include "FrameListMenu.hh" #include "ManagerWindows.hh" #include "WindowManager.hh" #include "X11.hh" #include "FocusToggleEventHandler.hh" #include "GroupingDragEventHandler.hh" #include "MoveEventHandler.hh" #include "KeyboardMoveResizeEventHandler.hh" #include "ResizeEventHandler.hh" #include "tk/PWinObj.hh" #include "tk/X11Util.hh" ActionHandler::ActionHandler(AppCtrl* app_ctrl, EventLoop* event_loop, Os* os) : _app_ctrl(app_ctrl), _event_loop(event_loop), _os(os), _sys_process(nullptr) { // Initialize state_to_keycode map for (uint i = 0; i < X11::MODIFIER_TO_MASK_NUM; ++i) { uint modifier = X11::MODIFIER_TO_MASK[i]; _state_to_keycode[modifier] = X11::getKeycodeFromMask(modifier); } } //! @brief ActionHandler destructor ActionHandler::~ActionHandler(void) { } //! @brief Executes an ActionPerformed event. void ActionHandler::handleAction(const ActionPerformed *ap) { // go through the list of actions and execute them ActionEvent::it it = ap->ae.action_list.begin(); for (; it != ap->ae.action_list.end(); ++it) { handleAction(ap, it); } } void ActionHandler::handleAction(const ActionPerformed* ap, ActionEvent::it it) { PWinObj *wo = ap->wo; Client *client = nullptr; Frame *frame = nullptr; PMenu *menu = nullptr; PDecor *decor = nullptr; // Determine what type if any of the window object that is focused // and check if it is still alive. lookupWindowObjects(&wo, &client, &frame, &menu, &decor); P_TRACE("start action " << ActionConfig::getActionName(it->getAction()) << " wo " << wo); // actions valid for all PWinObjs bool matched; if (wo) { matched = handleWoAction(ap, it); } else { matched = false; } // actions valid for Clients and Frames if (! matched && frame) { matched = handleFrameAction(ap, it, client, frame); } // Actions valid for Menus if (! matched && menu) { matched = handleMenuAction(ap, it, menu); } // actions valid for pdecor if (! matched && decor) { matched = handleDecorAction(ap, it, decor); } // Actions valid from everywhere if (! matched) { handleAnyAction(ap, it, client, frame); } P_TRACE("end action " << ActionConfig::getActionName(it->getAction()) << " wo " << wo); } bool ActionHandler::handleWoAction(const ActionPerformed *ap, ActionEvent::it it) { switch (it->getAction()) { case ACTION_FOCUS: // not using Workspaces::giveInputFocus here as warping the // pointer on sloppy focus makes for a very confusing user // experience when the pointer enters a frame and then is // warped. if (ap->wo->isFocusable()) { ap->wo->giveInputFocus(); } break; case ACTION_UNFOCUS: PWinObj::getRootPWinObj()->giveInputFocus(); break; case ACTION_FOCUS_DIRECTIONAL: actionFocusDirectional(ap->wo, DirectionType(it->getParamI(0)), it->getParamI(1)); break; case ACTION_SEND_KEY: actionSendKey(ap->wo, it->getParamS()); break; default: return false; }; return true; } bool ActionHandler::handleFrameAction(const ActionPerformed* ap, ActionEvent::it it, Client* client, Frame* frame) { switch (it->getAction()) { case ACTION_GROUPING_DRAG: actionGroupingDrag(ap, frame, client, it->getParamI(0)); break; case ACTION_ACTIVATE_CLIENT: if (ap->type == ButtonPress || ap->type == ButtonRelease) { int x = ap->event.button->x; PWinObj *child = frame->getChildFromPos(x); frame->activateChild(child); } break; case ACTION_GOTO_CLIENT: gotoClient(client); break; case ACTION_MAXFILL: frame->setStateMaximized(STATE_SET, it->getParamI(0), it->getParamI(1), true); break; case ACTION_GROW_DIRECTION: frame->growDirection(it->getParamI(0)); break; case ACTION_RESIZE: actionResize(ap, frame, client, static_cast( it->getParamI(0, BORDER_NO_POS))); break; case ACTION_MOVE_RESIZE: actionMoveResize(frame); break; case ACTION_CLOSE: client->close(); break; case ACTION_CLOSE_FRAME: frame->close(); break; case ACTION_KILL: client->kill(); break; case ACTION_SET_GEOMETRY: frame->setGeometry(it->getParamS(), it->getParamI(0), it->getParamI(1) == 1); break; case ACTION_RAISE: if (it->getParamI(0)) { ClientMgr::familyRaiseLower(client, true); } else { frame->raise(); } break; case ACTION_LOWER: if (it->getParamI(0)) { ClientMgr::familyRaiseLower(client, false); } else { frame->lower(); } break; case ACTION_ACTIVATE_OR_RAISE: if ((ap->type == ButtonPress || ap->type == ButtonRelease) && (ap->event.button->window == frame->getTitleWindow())) { int x = ap->event.button->x; PWinObj *child = frame->getChildFromPos(x); frame->activateChild(child); } if (frame->isFocused()) { frame->raise(); } else { Workspaces::giveInputFocus(ap->wo); } break; case ACTION_MOVE_TO_HEAD: frame->moveToHead(it->getParamS(0)); break; case ACTION_MOVE_TO_EDGE: actionMoveToEdge(frame, OrientationType(it->getParamI(0))); break; case ACTION_FILL_EDGE: actionFillEdge(frame, OrientationType(it->getParamI(0)), it->getParamI(1)); break; case ACTION_ACTIVATE_CLIENT_REL: frame->activateChildRel(it->getParamI(0)); break; case ACTION_MOVE_CLIENT_REL: frame->moveChildRel(it->getParamI(0)); break; case ACTION_ACTIVATE_CLIENT_NUM: frame->activateChildNum(it->getParamI(0)); break; case ACTION_SEND_TO_WORKSPACE: actionSendToWorkspace(frame, it->getParamI(0), calcWorkspaceNum(*it, 1)); break; case ACTION_DETACH: frame->detachClient(client, frame->getX(), frame->getY()); break; case ACTION_DETACH_SPLIT_HORZ: actionDetachClientSplit(frame, client, it->getParamI(0), true); break; case ACTION_DETACH_SPLIT_VERT: actionDetachClientSplit(frame, client, it->getParamI(0), false); break; case ACTION_ATTACH_MARKED: attachMarked(frame); break; case ACTION_ATTACH_CLIENT_IN_NEXT_FRAME: attachInNextPrevFrame(client, false, true); break; case ACTION_ATTACH_CLIENT_IN_PREV_FRAME: attachInNextPrevFrame(client, false, false); break; case ACTION_ATTACH_FRAME_IN_NEXT_FRAME: attachInNextPrevFrame(client, true, true); break; case ACTION_ATTACH_FRAME_IN_PREV_FRAME: attachInNextPrevFrame(client, true, false); break; case ACTION_SET_OPACITY: actionSetOpacity(client, frame, it->getParamI(0), it->getParamI(1)); break; default: return false; } return true; } bool ActionHandler::handleMenuAction(const ActionPerformed* ap, ActionEvent::it it, PMenu* menu) { switch (it->getAction()) { // menu navigation case ACTION_MENU_NEXT: menu->selectNextItem(); break; case ACTION_MENU_PREV: menu->selectPrevItem(); break; case ACTION_MENU_GOTO: menu->selectItemNum(it->getParamI(0)); break; case ACTION_MENU_SELECT: case ACTION_MENU_ENTER_SUBMENU: if (menu->getItemCurr() && menu->getItemCurr()->getWORef() && (menu->getItemCurr()->getWORef()->getType() == PWinObj::WO_MENU)) { PWinObj *wo_ref = menu->getItemCurr()->getWORef(); menu->mapSubmenu(static_cast(wo_ref), true); } else if (it->getAction() == ACTION_MENU_SELECT) { menu->exec(menu->getItemCurr()); // special case: execItem can cause an reload to be // issued, if that's the case it causes the list (ae) // to change and therefore it can't be used anymore return true; } break; case ACTION_MENU_LEAVE_SUBMENU: menu->gotoParentMenu(); break; case ACTION_CLOSE: menu->unmapAll(); Workspaces::findWOAndFocus(nullptr); break; default: return false; } return true; } bool ActionHandler::handleDecorAction(const ActionPerformed* ap, ActionEvent::it it, PDecor* decor) { switch (it->getAction()) { case ACTION_MOVE: { int x_root, y_root; if (it->numParamI() == 2) { x_root = it->getParamI(0); y_root = it->getParamI(1); } else { // Get root position, previously used event position // but was error prone on Xinerama setups X11::getMousePosition(x_root, y_root); } EventHandler *event_handler = new MoveEventHandler(pekwm::config(), decor, x_root, y_root); setEventHandler(event_handler); break; } case ACTION_CLOSE: decor->unmapWindow(); if (decor->getType() == PWinObj::WO_CMD_DIALOG || decor->getType() == PWinObj::WO_SEARCH_DIALOG) { Workspaces::findWOAndFocus(nullptr); } break; case ACTION_WARP_TO_WORKSPACE: actionWarpToWorkspace(ap, decor, calcWorkspaceNum(*it)); break; default: return false; } return true; } bool ActionHandler::handleAnyAction(const ActionPerformed* ap, ActionEvent::it it, Client* client, Frame* frame) { switch (it->getAction()) { case ACTION_FOCUS_WITH_SELECTOR: actionFocusWithSelector(*it); break; case ACTION_SET: case ACTION_UNSET: case ACTION_TOGGLE: handleStateAction(*it, ap->wo, client, frame); break; case ACTION_NEXT_FRAME: case ACTION_NEXT_FRAME_MRU: case ACTION_PREV_FRAME: case ACTION_PREV_FRAME_MRU: { bool mru = it->getAction() == ACTION_NEXT_FRAME_MRU || it->getAction() == ACTION_PREV_FRAME_MRU; int dir = (it->getAction() == ACTION_NEXT_FRAME || it->getAction() == ACTION_NEXT_FRAME_MRU) ? 1 : -1; EventHandler *event_handler = new FocusToggleEventHandler(pekwm::config(), ap->ae.sym, it->getParamI(0), dir, it->getParamI(1), mru); setEventHandler(event_handler); break; } case ACTION_GOTO_WORKSPACE: actionGotoWorkspace(*it, ap->type); break; case ACTION_FIND_CLIENT: actionFindClient(it->getParamS()); break; case ACTION_GOTO_CLIENT_ID: actionGotoClientID(it->getParamI(0)); break; case ACTION_EXEC: actionExec(client, it->getParamS(), false); break; case ACTION_SETENV: actionSetenv(it->getParamS(0), it->getParamS(1)); break; case ACTION_SHELL_EXEC: actionExec(client, it->getParamS(), true); break; case ACTION_SHOW_MENU: actionShowMenu(it->getParamS(), it->getParamI(0), ap->type, client ? client : ap->wo); break; case ACTION_HIDE_ALL_MENUS: MenuHandler::hideAllMenus(); break; case ACTION_RELOAD: _app_ctrl->reload(); break; case ACTION_RESTART: _app_ctrl->restart(); break; case ACTION_RESTART_OTHER: if (it->getParamS().size()) _app_ctrl->restart(it->getParamS()); break; case ACTION_EXIT: _app_ctrl->shutdown(); break; case ACTION_SHOW_CMD_DIALOG: actionShowInputDialog(&_cmd_dialog, it->getParamS(), frame, ap->wo); break; case ACTION_SHOW_SEARCH_DIALOG: actionShowInputDialog(&_search_dialog, it->getParamS(), frame, ap->wo); break; case ACTION_DEBUG: Debug::doAction(it->getParamS()); break; case ACTION_SYS: actionSys(it->getParamS()); break; case ACTION_WM_SET: actionWmSet(it->getParamS()); break; case ACTION_WARP_POINTER: actionWarpPointer(it->getParamI(0), it->getParamI(1)); break; case ACTION_HIDE_WORKSPACE_INDICATOR: Workspaces::hideWorkspaceIndicator(); break; default: return false; } return true; } void ActionHandler::lookupWindowObjects(PWinObj **wo, Client **client, Frame **frame, PMenu **menu, PDecor **decor) { *client = nullptr; *frame = nullptr; *menu = nullptr; *decor = nullptr; if (PWinObj::windowObjectExists(*wo)) { if ((*wo)->getType() == PWinObj::WO_CLIENT) { *client = static_cast(*wo); *frame = static_cast((*client)->getParent()); *decor = static_cast(*frame); } else if ((*wo)->getType() == PWinObj::WO_FRAME) { *frame = static_cast(*wo); PWinObj *active_child = (*frame)->getActiveChild(); *client = static_cast(active_child); *decor = static_cast(*wo); } else if ((*wo)->getType() == PWinObj::WO_MENU) { *menu = static_cast(*wo); *decor = static_cast(*wo); } else { *decor = dynamic_cast(*wo); } } else { *wo = 0; } } //! @brief Handles state actions void ActionHandler::handleStateAction(const Action &action, PWinObj *wo, Client *client, Frame *frame) { StateAction sa = static_cast(action.getAction()); bool matched = false; // check for frame actions if (frame) { matched = true; switch (action.getParamI(0)) { case ACTION_STATE_MAXIMIZED: frame->setStateMaximized(sa, action.getParamI(1), action.getParamI(2), false); break; case ACTION_STATE_FULLSCREEN: frame->setStateFullscreen(sa); break; case ACTION_STATE_SHADED: frame->setShaded(sa); break; case ACTION_STATE_STICKY: frame->setStateSticky(sa); break; case ACTION_STATE_ALWAYS_ONTOP: frame->setStateAlwaysOnTop(sa); break; case ACTION_STATE_ALWAYS_BELOW: frame->setStateAlwaysBelow(sa); break; case ACTION_STATE_DECOR_BORDER: frame->setStateDecorBorder(sa); break; case ACTION_STATE_DECOR_TITLEBAR: frame->setStateDecorTitlebar(sa); break; case ACTION_STATE_ICONIFIED: frame->setStateIconified(sa); break; case ACTION_STATE_TAGGED: frame->setStateTagged(sa, action.getParamI(1)); break; case ACTION_STATE_MARKED: frame->setStateMarked(sa, client); break; case ACTION_STATE_SKIP: frame->setStateSkip(sa, action.getParamI(1)); break; case ACTION_STATE_CFG_DENY: client->setStateCfgDeny(sa, action.getParamI(1)); break; case ACTION_STATE_DECOR: frame->setDecorOverride(sa, action.getParamS()); break; case ACTION_STATE_TITLE: frame->setStateTitle(sa, client, action.getParamS()); break; case ACTION_STATE_OPAQUE: frame->setStateOpaque(sa); break; default: matched = false; break; } } // check for menu actions if (! matched && wo && (wo->getType() == PWinObj::WO_MENU)) { matched = true; switch (action.getParamI(0)) { case ACTION_STATE_STICKY: wo->toggleSticky(); break; default: matched = false; break; } } if (! matched) { switch (action.getParamI(0)) { case ACTION_STATE_HARBOUR_HIDDEN: pekwm::harbour()->setStateHidden(sa); break; case ACTION_STATE_GLOBAL_GROUPING: ClientMgr::setStateGlobalGrouping(sa); break; default: break; } } } //! @brief Checks if motion threshold is within bounds. bool ActionHandler::checkAEThreshold(int x, int y, int x_t, int y_t, uint t) { if (((x > x_t) ? (x > (x_t + signed(t))) : (x < (x_t - signed(t)))) || ((y > y_t) ? (y > (y_t + signed(t))) : (y < (y_t - signed(t))))) { return true; } return false; } //! @brief Searches the actions list for an matching event ActionEvent* ActionHandler::findMouseAction(uint button, uint state, MouseEventType type, std::vector *actions) { if (! actions) { return 0; } X11::stripStateModifiers(&state); X11::stripButtonModifiers(&state); std::vector::iterator it = actions->begin(); for (; it != actions->end(); ++it) { if ((it->type == unsigned(type)) && ((it->mod == MOD_ANY) || (it->mod == state)) && ((it->sym == BUTTON_ANY) || (it->sym == button))) { return &*it; } } return 0; } /** * Execute action, setting client environment before (if any). */ void ActionHandler::actionExec(Client *client, const std::string &command, bool use_shell) { if (! command.size()) { USER_WARN("empty Exec/ShellExec command"); return; } Client::setClientEnvironment(client); if (use_shell) { Util::forkExec(command); } else { std::vector args = StringUtil::shell_split(command); _os->processExec(args); } } /** * Set or delete environment variable. */ void ActionHandler::actionSetenv(const std::string &name, const std::string &value) { Util::setEnv(name, value); } /** * Move the Frame to the screen edge orientation with the struts taken into * account. */ bool ActionHandler::actionMoveToEdge(PWinObj *wo, OrientationType edge) { uint head_nr = X11Util::getNearestHead(*wo); Geometry real_head; X11::getHeadInfo(head_nr, real_head); Geometry head; pekwm::rootWo()->getHeadInfoWithEdge(head_nr, head); int x, y; switch (edge) { case TOP_LEFT: x = head.x; y = head.y; break; case TOP_EDGE: x = wo->getX(); y = head.y; break; case TOP_CENTER_EDGE: x = real_head.x + ((real_head.width - wo->getWidth()) / 2); y = head.y; break; case TOP_RIGHT: x = head.x + head.width - wo->getWidth(); y = head.y; break; case BOTTOM_RIGHT: x = head.x + head.width - wo->getWidth(); y = head.y + head.height - wo->getHeight(); break; case BOTTOM_EDGE: x = wo->getX(); y = head.y + head.height - wo->getHeight(); break; case BOTTOM_CENTER_EDGE: x = real_head.x + ((real_head.width - wo->getWidth()) / 2); y = head.y + head.height - wo->getHeight(); break; case BOTTOM_LEFT: x = head.x; y = head.y + head.height - wo->getHeight(); break; case LEFT_EDGE: x = head.x; y = wo->getY(); break; case LEFT_CENTER_EDGE: x = head.x; y = real_head.y + ((real_head.height - wo->getHeight()) / 2); break; case RIGHT_EDGE: x = head.x + head.width - wo->getWidth(); y = wo->getY(); break; case RIGHT_CENTER_EDGE: x = head.x + head.width - wo->getWidth(); y = real_head.y + ((real_head.height - wo->getHeight()) / 2); break; case CENTER: x = real_head.x + ((real_head.width - wo->getWidth()) / 2); y = real_head.y + ((real_head.height - wo->getHeight()) / 2); break; default: return false; } wo->move(x, y); return true; } /** * Make the window object fill select parts of the current head. * * ---------------------- * | 1 | 2 | 3 | * ---------------------- * | 4 | 5 | 6 | * ---------------------- * | 7 | 8 | 9 | * ---------------------- * * TL: 1 T: 1,2,3 TR: 3 * L: 1,4,7 R: 3,6,9 * BL: 7 B: 7,8,9 BR: 9 * C: 5 * * Default size of each part of the grid is 33% of width x 33% of the height, * this is comes as the percent argument. */ bool ActionHandler::actionFillEdge(Frame *frame, OrientationType edge, int percent) { // doing fill edge, on the opposite edge of the current edge will // reset the fill and move the frame back to its pre-fill position. OrientationType old_edge = frame->getEdgeFilled(); if (old_edge != NO_EDGE && isOrientationOpposites(old_edge, edge)) { Geometry gm(frame->getOldGeometry()); frame->moveResize(gm.x, gm.y, gm.width, gm.height); frame->clearFillStateAfterResize(); return true; } uint head_nr = X11Util::getNearestHead(*frame); Geometry head; pekwm::rootWo()->getHeadInfoWithEdge(head_nr, head); Geometry gm; if (! fillEdgeGeometry(head, edge, percent, gm)) { return false; } P_TRACE("FillEdge " << edge << " " << gm); if (! frame->isAnyFill()) { frame->setOldGeometry(frame->getGeometry()); } frame->moveResize(gm.x, gm.y, gm.width, gm.height); frame->setEdgeFilled(edge); return true; } bool ActionHandler::fillEdgeGeometry(const Geometry &head, OrientationType edge, int percent, Geometry &gm) { if (percent < 1) { percent = 1; } else if (percent > 100) { percent = 100; } float fpercent = static_cast(percent) / 100.0; gm = head; switch (edge) { case TOP_EDGE: case BOTTOM_EDGE: gm.height = static_cast(fpercent * gm.height); break; case LEFT_EDGE: case RIGHT_EDGE: gm.width = static_cast(fpercent * gm.width); break; case NO_EDGE: return false; default: gm.width = static_cast(fpercent * gm.width); gm.height = static_cast(fpercent * gm.height); break; } switch (edge) { case TOP_CENTER_EDGE: gm.x = head.x + gm.width; break; case TOP_RIGHT: gm.x = head.rx() - gm.width; break; case BOTTOM_RIGHT: gm.x = head.rx() - gm.width; gm.y = head.by() - gm.height; break; case BOTTOM_EDGE: gm.y = head.by() - gm.height; break; case BOTTOM_CENTER_EDGE: gm.x = head.x + gm.width; gm.y = head.by() - gm.height; break; case BOTTOM_LEFT: gm.y = head.by() - gm.height; break; case LEFT_CENTER_EDGE: gm.y = head.y + gm.height; break; case RIGHT_EDGE: gm.x = head.rx() - gm.width; break; case RIGHT_CENTER_EDGE: gm.x = head.rx() - gm.width; gm.y = head.y + gm.height; break; case CENTER: gm.x = head.x + gm.width; gm.y = head.y + gm.height; break; case NO_EDGE: return false; case TOP_LEFT: case TOP_EDGE: case LEFT_EDGE: // do nothing break; } return true; } bool ActionHandler::isOrientationOpposites(OrientationType lhs, OrientationType rhs) { return abs(static_cast(lhs) - static_cast(rhs)) == 10; } //! @brief Searches for a client matching titles and makes it visible void ActionHandler::actionFindClient(const std::string &title) { Client *client = findClientFromTitle(title); if (client) { gotoClient(client); } } //! @brief Goto workspace //! @param workspace Workspace to got to //! @param warp If true, warp pointer as well void ActionHandler::actionGotoWorkspace(const Action &action, int type) { uint workspace = calcWorkspaceNum(action); bool focus = action.getParamI(action.numParamI() - 1); // events caused by a motion event ( dragging frame to the // edge ) or enter event ( moving the pointer to the edge ) // should warp the pointer. bool warp = type == MotionNotify || type == EnterNotify; Workspaces::gotoWorkspace(workspace, focus, warp); } //! @brief Focus client with id. //! @param id Client id. void ActionHandler::actionGotoClientID(uint id) { Client *client = Client::findClientFromID(id); if (client) { gotoClient(client); } } /** * Initiate grouping drag. */ void ActionHandler::actionGroupingDrag(const ActionPerformed *ap, Frame *frame, Client *client, bool behind) { if (ap->type != MotionNotify) { return; } int x = ap->event.motion->x_root; int y = ap->event.motion->y_root; EventHandler *event_handler = new GroupingDragEventHandler(frame, client, x, y, behind); setEventHandler(event_handler); } /** * Initiate resize of provided Frame/Client. */ void ActionHandler::actionResize(const ActionPerformed *ap, Frame *frame, Client *client, BorderPosition pos) { bool resize = true; bool left = false, top = false, x = false, y = false; if (ap->type == MotionNotify && pos == BORDER_NO_POS) { // figure out which part of the window we are in left = ap->event.motion->x < signed(frame->getWidth() / 2); top = ap->event.motion->y < signed(frame->getHeight() / 2); x = true; y = true; } else { switch (pos) { case BORDER_TOP_LEFT: x = y = left = top = true; break; case BORDER_TOP: y = top = true; break; case BORDER_TOP_RIGHT: x = y = top = true; break; case BORDER_LEFT: x = left = true; break; case BORDER_RIGHT: x = true; break; case BORDER_BOTTOM_LEFT: x = y = left = true; break; case BORDER_BOTTOM: y = true; break; case BORDER_BOTTOM_RIGHT: x = y = true; break; default: resize = false; break; } } if (resize) { EventHandler *event_handler = new ResizeEventHandler(pekwm::config(), frame, client, left, x, top, y); setEventHandler(event_handler); } } /** * Initiate keyboard move resize of the provided Decor. */ void ActionHandler::actionMoveResize(PDecor *decor) { EventHandler *event_handler = new KeyboardMoveResizeEventHandler(pekwm::config(), pekwm::keyGrabber(), decor); setEventHandler(event_handler); } //! @brief Sends client to specified workspace //! @param focus make the window "last focused" in the new workspace //! @param direction Workspace to send to, or special meaning relative space. void ActionHandler::actionSendToWorkspace(PDecor *decor, bool focus, int direction) { // Convenience const uint per_row = Workspaces::getPerRow(); const uint cur_row = Workspaces::getRow(); const uint cur_act = Workspaces::getActive(); const uint row_min = Workspaces::getRowMin(); const uint row_max = Workspaces::getRowMax(); const uint udirection = static_cast(direction); // Initialized to silence compiler warning uint new_workspace = cur_act; switch (static_cast(direction)) { case WORKSPACE_LEFT: case WORKSPACE_PREV: if (cur_act > row_min) { new_workspace = cur_act - 1; } else if (udirection == WORKSPACE_PREV) { new_workspace = row_max; } break; case WORKSPACE_NEXT: case WORKSPACE_RIGHT: if (cur_act < row_max) { new_workspace = cur_act + 1; } else if (udirection == WORKSPACE_NEXT) { new_workspace = row_min; } break; case WORKSPACE_PREV_V: case WORKSPACE_UP: if (cur_act >= per_row) { new_workspace = cur_act - per_row; } else if (udirection == WORKSPACE_PREV_V) { // Bottom left + column new_workspace = Workspaces::size() - per_row + cur_act - cur_row * per_row; } break; case WORKSPACE_NEXT_V: case WORKSPACE_DOWN: if ((cur_act + per_row) < Workspaces::size()) { new_workspace = cur_act + per_row; } else if (udirection == WORKSPACE_NEXT_V) { new_workspace = cur_act - cur_row * per_row; } break; case WORKSPACE_LAST: new_workspace = Workspaces::getPrevious(); break; default: new_workspace = direction; break; } decor->setWorkspace(new_workspace); if (focus) { Workspaces::setLastFocused(new_workspace, decor); } } void ActionHandler::actionWarpToWorkspace(const ActionPerformed *ap, PDecor *decor, uint direction) { const ActionPerformedWithOffset *ap_o = dynamic_cast(ap); if (ap_o == nullptr) { return; } // Removing the already accumulated motion events can help // to avoid skipping workspaces (see task #77). X11::removeMotionEvents(); // actually did move if (Workspaces::gotoWorkspace(DirectionType(direction), false, true)) { int x, y; X11::getMousePosition(x, y); decor->move(x + ap_o->offset_x, y + ap_o->offset_y); decor->setWorkspace(Workspaces::getActive()); } } /** * Forward command to the pekwm_sys process if it is running. */ void ActionHandler::actionSys(const std::string &cmd) { if (! _sys_process || cmd.empty()) { return; } uint32_t len = cmd.size(); _sys_process->write(reinterpret_cast(&len), sizeof(len)); _sys_process->write(cmd); P_TRACE("sent " << cmd << " to pekwm_sys"); } /** * Handling of dynamic configurations such as Scale. */ void ActionHandler::actionWmSet(const std::string &args_str) { std::vector args = StringUtil::shell_split(args_str); if (pekwm::ascii_ncase_equal("SCALE", args[0])) { actionWmSetScale(args); } else if (pekwm::ascii_ncase_equal("WORKSPACENAME", args[0])) { actionWmSetWorkspaceName(args); } else { P_TRACE("unknown WmSet command " << args_str); } } void ActionHandler::actionWmSetScale(const std::vector &args) { if (args.size() != 2) { return; } double scale; try { scale = std::stod(args[1]); } catch (std::invalid_argument&) { return; } double old_scale = pekwm::config()->getScreenScale(); pekwm::config()->setScreenScaleOverride(scale); pekwm::windowManager()->setScale(old_scale, scale); } void ActionHandler::actionWmSetWorkspaceName(const std::vector &args) { if (args.size() == 2) { Workspaces::getActWorkspace().setNameOverride(args[1]); pekwm::rootWo()->setEwmhDesktopNames(); } } /** * Find window object under the pointer and give it focus, if none is * found use fallback. */ void ActionHandler::actionFocusWithSelector(const Action& action) { PWinObj *wo_focus = nullptr; for (size_t i = 0; i < action.numParamI() && ! wo_focus; i++) { switch (action.getParamI(i)) { case FOCUS_SELECTOR_POINTER: wo_focus = Workspaces::findUnderPointer(); break; case FOCUS_SELECTOR_WORKSPACE_LAST_FOCUSED: { int active = Workspaces::getActive(); wo_focus = Workspaces::getLastFocused(active); break; } case FOCUS_SELECTOR_TOP: { int mask = PWinObj::WO_FRAME |PWinObj::WO_MENU |PWinObj::WO_CMD_DIALOG |PWinObj::WO_SEARCH_DIALOG; wo_focus = Workspaces::getTopFocusableWO(mask); break; } case FOCUS_SELECTOR_ROOT: wo_focus = pekwm::rootWo(); break; default: // should not happen, validated during parse break; } } if (wo_focus != nullptr) { Workspaces::giveInputFocus(wo_focus); } } //! @brief Finds a window in direction and gives it focus void ActionHandler::actionFocusDirectional(PWinObj *wo, DirectionType dir, bool raise) { PWinObj *wo_focus = Workspaces::findDirectional(wo, dir, SKIP_FOCUS_TOGGLE); if (wo_focus) { if (raise) { wo_focus->raise(); } Workspaces::giveInputFocus(wo_focus); } } /** * Parse key information and send to wo. * * To handle this smoothly first all state modifiers are pressed one * by one adding to the state, then the real key is pressed and * released, then the state modifiers are released. * * @param win Window to send key to. * @param key_str String definition of key to send. * @return true if key was parsed ok, no validation of sending is done. */ bool ActionHandler::actionSendKey(PWinObj *wo, const std::string &key_str) { uint mod, key; if (! ActionConfig::parseKey(key_str, mod, key)) { return false; } XEvent ev; initSendKeyEvent(ev, wo); // Press state modifiers std::map::iterator it; for (it = _state_to_keycode.begin(); it != _state_to_keycode.end(); ++it) { if (mod & it->first) { ev.xkey.keycode = it->second; X11::sendEvent(wo->getWindow(), True, KeyPressMask, &ev); ev.xkey.state |= it->first; } } // Send press and release of main key ev.xkey.keycode = key; XSendEvent(X11::getDpy(), wo->getWindow(), True, KeyPressMask, &ev); ev.type = KeyRelease; XSendEvent(X11::getDpy(), wo->getWindow(), True, KeyPressMask, &ev); // Release state modifiers for (it = _state_to_keycode.begin(); it != _state_to_keycode.end(); ++it) { if (mod & it->first) { ev.xkey.keycode = it->second; X11::sendEvent(wo->getWindow(), True, KeyPressMask, &ev); ev.xkey.state &= ~it->first; } } return true; } void ActionHandler::actionSetOpacity(PWinObj *client, PWinObj *frame, uint focus, uint unfocus) { if (! unfocus) { unfocus = focus; } CONV_OPACITY(focus); CONV_OPACITY(unfocus); client->setOpacity(focus, unfocus); frame->setOpacity(client); } //! @brief Toggles visibility of menu. //! @param name Name of menu to toggle visibilty of //! @param stick Stick menu when showing //! @param e_type Event type triggered this action //! @param wo_ref Reference to active window object void ActionHandler::actionShowMenu(const std::string &name, bool stick, uint e_type, PWinObj *wo_ref) { PMenu *menu = MenuHandler::getMenu(name); if (! menu) { return; } if (menu->isMapped()) { menu->unmapAll(); } else { // if it's a WORefMenu, set referencing client WORefMenu *wo_ref_menu = dynamic_cast(menu); if (wo_ref_menu // Do not set reference on these, we don't want a funky // title && (wo_ref_menu->getMenuType() != ROOTMENU_TYPE) && (wo_ref_menu->getMenuType() != ROOTMENU_STANDALONE_TYPE) ) { wo_ref_menu->setWORef(wo_ref); } // Mapping can fail because of empty menu, like iconmenu, so we // check menu->mapUnderMouse(); if (menu->isMapped()) { Workspaces::giveInputFocus(menu); if (stick) { menu->setSticky(true); } // If we opened the menu with the keyboard, select the // first item if (e_type == KeyPress) { menu->selectItemNum(0); } } } } void ActionHandler::actionShowInputDialog(InputDialog *dialog, const std::string &initial, Frame *frame, PWinObj *wo) { if (dialog->isMapped()) { dialog->unmapWindow(); return; } Geometry gm; if (frame) { frame->getGeometry(gm); } else { CurrHeadSelector chs = pekwm::config()->getCurrHeadSelector(); X11::getHeadInfo(X11Util::getCurrHead(chs), gm); } // skip leave events for the focused window object displaying // the input dialog, it should get the focus PWinObj *focused_wo = PWinObj::getFocusedPWinObj(); if (focused_wo && focused_wo->getType() == PWinObj::WO_MENU) { PWinObj::setSkipEnterAfter(focused_wo); } dialog->mapCentered(initial, gm, frame ? frame : wo); } bool ActionHandler::actionWarpPointer(int x, int y) { if (x < 0 || y < 0 || static_cast(x) > X11::getScreenGeometry().width || static_cast(y) > X11::getScreenGeometry().height) { return false; } X11::warpPointer(x, y); return true; } //! @brief Searches the client list for a client with a title matching title Client* ActionHandler::findClientFromTitle(const std::string &or_title) { RegexString o_rs; if (o_rs.parse_match(or_title, true)) { Client::client_cit it = Client::client_begin(); for (; it != Client::client_end(); ++it) { if (o_rs == (*it)->getTitle()->getVisible()) { return (*it); } } } return 0; } //! @brief Makes sure Client gets visible and focus it. //! @param client Client to activate. void ActionHandler::gotoClient(Client *client) { Frame *frame = dynamic_cast(client->getParent()); if (! frame) { P_WARN("parent is not a Frame"); return; } // Make sure it's visible if (! frame->isSticky() && (frame->getWorkspace() != Workspaces::getActive())) { Workspaces::setWorkspace(frame->getWorkspace(), false); Workspaces::addToMRUFront(frame); } if (! frame->isMapped()) { frame->mapWindow(); } // Activate it within the Frame. frame->activateChild(client); frame->raise(); Workspaces::giveInputFocus(frame); } /** * Initialize XEvent for sending KeyPress/KeyRelease events. * * @param ev Reference to event. * @param wo PWinObj key event is aimed for. */ void ActionHandler::initSendKeyEvent(XEvent &ev, PWinObj *wo) { ev.type = KeyPress; ev.xkey.display = X11::getDpy(); ev.xkey.root = X11::getRoot(); ev.xkey.window = wo->getWindow(); ev.xkey.time = CurrentTime; ev.xkey.x = 1; ev.xkey.y = 1; X11::getMousePosition(ev.xkey.x_root, ev.xkey.y_root); ev.xkey.same_screen = True; ev.xkey.type = KeyPress; ev.xkey.state = 0; } void ActionHandler::actionDetachClientSplit(Frame *frame, Client *client, int percent, bool horz) { if (percent < 5 || percent > 95) { USER_WARN("split size percent must be between 5-95%"); return; } float new_aspect = static_cast(percent) / 100; Frame *new_frame = frame->detachClient(client, frame->getX(), frame->getY()); if (new_frame != nullptr && horz) { actionDetachClientSplitHorz(frame, new_frame, new_aspect); } else if (new_frame != nullptr) { actionDetachClientSplitVert(frame, new_frame, new_aspect); } } void ActionHandler::actionDetachClientSplitHorz(PWinObj *oldf, PWinObj *newf, float new_aspect) { int new_height = static_cast(new_aspect * oldf->getHeight()); int old_y = oldf->getY() + new_height; int old_height = static_cast((1.0 - new_aspect) * oldf->getHeight()); newf->moveResize(oldf->getX(), oldf->getY(), oldf->getWidth(), new_height); oldf->moveResize(oldf->getX(), old_y, oldf->getWidth(), old_height); } void ActionHandler::actionDetachClientSplitVert(PWinObj *oldf, PWinObj *newf, float new_aspect) { int new_width = static_cast(new_aspect * oldf->getWidth()); int old_x = oldf->getX() + new_width; int old_width = static_cast((1.0 - new_aspect) * oldf->getWidth()); newf->moveResize(oldf->getX(), oldf->getY(), new_width, oldf->getHeight()); oldf->moveResize(old_x, oldf->getY(), old_width, oldf->getHeight()); } /** * Attaches all marked clients to frame */ void ActionHandler::attachMarked(Frame *frame) { Client::client_cit it = Client::client_begin(); for (; it != Client::client_end(); ++it) { if (! (*it)->isMarked()) { continue; } if ((*it)->getParent() != frame) { Frame *parent = static_cast((*it)->getParent()); parent->removeChild(*it); (*it)->setWorkspace(frame->getWorkspace()); frame->addChild(*it); } (*it)->setStateMarked(STATE_UNSET); } } /** * Attaches the Client/Frame into the Next/Prev Frame */ void ActionHandler::attachInNextPrevFrame(Client *client, bool frame, bool next) { if (client == nullptr) { return; } Frame *new_frame; Frame *parent = static_cast(client->getParent()); if (next) { new_frame = Workspaces::getNextFrame(parent, true, SKIP_FOCUS_TOGGLE); } else { new_frame = Workspaces::getPrevFrame(parent, true, SKIP_FOCUS_TOGGLE); } if (new_frame) { if (frame) { new_frame->addDecor(parent); } else { parent->setFocused(false); parent->removeChild(client); new_frame->addChild(client); new_frame->activateChild(client); Workspaces::giveInputFocus(new_frame); } } } /** * Get worksapce number for Warp/Send/Goto Workspace actions, either * in form of 3 integer arguments (-1, row, col) or 1 integer where * the number is already set. */ int ActionHandler::calcWorkspaceNum(const Action& action, int index) { if (action.getParamI(index) == -1) { return pekwm::config()->getWorkspacesPerRow() * action.getParamI(index + 1) + action.getParamI(index + 2); } return action.getParamI(index); } void ActionHandler::setEventHandler(EventHandler *event_handler) { if (! _event_loop->isEventHandler() && event_handler->initEventHandler()) { _event_loop->setEventHandler(event_handler); } else { delete event_handler; } } pekwm-0.4.4/src/wm/FocusToggleEventHandler.cc0000664000175000017500000001422715126136025014576 // // FocusToggleEventHandler.cc for pekwm // Copyright (C) 2021-2025 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "Debug.hh" #include "FocusToggleEventHandler.hh" #include "Workspaces.hh" FocusToggleEventHandler::FocusToggleEventHandler(Config* cfg, uint button, uint raise, int off, bool show_iconified, bool mru) : _cfg(cfg), _button(button), _raise(raise), _off(off), _show_iconified(show_iconified), _mru(mru), _menu(nullptr), _fo_wo(nullptr), _was_iconified(false) { } FocusToggleEventHandler::~FocusToggleEventHandler(void) { setFocusedWo(nullptr); delete _menu; } void FocusToggleEventHandler::notify(Observable *observable, Observation *observation) { if (observation == &PWinObj::pwin_obj_deleted && observable == _fo_wo) { P_TRACE("decor " << _fo_wo << " lost while moving"); _fo_wo = nullptr; } } bool FocusToggleEventHandler::initEventHandler(void) { _menu = createNextPrevMenu(); // no clients in the list if (_menu->size() == 0) { return false; } // unable to grab keyboard if (! X11::grabKeyboard(X11::getRoot())) { return false; } // find the focused window object if (PWinObj::isFocusedPWinObj(PWinObj::WO_CLIENT)) { PWinObj *fo_wo = PWinObj::getFocusedPWinObj()->getParent(); PMenu::item_cit it(_menu->m_begin()); for (; it != _menu->m_end(); ++it) { if ((*it)->getWORef() == fo_wo) { _menu->selectItem(it); break; } } fo_wo->setFocused(false); } if (_cfg->getShowFrameList()) { _menu->buildMenu(); Geometry head; CurrHeadSelector chs = pekwm::config()->getCurrHeadSelector(); X11::getHeadInfo(X11Util::getCurrHead(chs), head); _menu->move(head.x + ((head.width - _menu->getWidth()) / 2), head.y + ((head.height - _menu->getHeight()) / 2)); _menu->setFocused(true); _menu->mapWindowRaised(); PWinObj::setSkipEnterAfter(_menu); } _menu->selectItemRel(_off); setFocusedWo(_menu->getItemCurr()->getWORef()); return true; } EventHandler::Result FocusToggleEventHandler::handleButtonPressEvent(XButtonEvent*) { // mark as processed disabling wm processing of these events. return EventHandler::EVENT_PROCESSED; } EventHandler::Result FocusToggleEventHandler::handleButtonReleaseEvent(XButtonEvent*) { // mark as processed disabling wm processing of these events. return EventHandler::EVENT_PROCESSED; } EventHandler::Result FocusToggleEventHandler::handleExposeEvent(XExposeEvent *ev) { if (_menu->isMapped() && *_menu == ev->window) { _menu->handleExposeEvent(ev); return EventHandler::EVENT_PROCESSED; } return EventHandler::EVENT_SKIP; } EventHandler::Result FocusToggleEventHandler::handleMotionNotifyEvent(XMotionEvent*) { // mark as processed disabling wm processing of these events. return EventHandler::EVENT_PROCESSED; } EventHandler::Result FocusToggleEventHandler::handleKeyEvent(XKeyEvent *ev) { if (ev->type == KeyRelease) { if (IsModifierKey(X11::getKeysymFromKeycode(ev->keycode))) { return stop(); } return EventHandler::EVENT_PROCESSED; } if (ev->keycode == _button) { if (_fo_wo) { if (_raise == TEMP_RAISE) { Workspaces::fixStacking(_fo_wo); } // Restore iconified state if (_was_iconified) { _was_iconified = false; _fo_wo->iconify(); } _fo_wo->setFocused(false); } _menu->selectItemRel(_off); setFocusedWo(_menu->getItemCurr()->getWORef()); return EventHandler::EVENT_PROCESSED; } return stop(); } EventHandler::Result FocusToggleEventHandler::stop(void) { X11::ungrabKeyboard(); // Got something to focus if (_fo_wo) { if (_raise == TEMP_RAISE) { _fo_wo->raise(); _fo_wo->setFocused(true); } // De-iconify if iconified, user probably wants this if (_fo_wo->isIconified()) { // If the window was iconfied, and sticky _fo_wo->setWorkspace(Workspaces::getActive()); _fo_wo->mapWindow(); _fo_wo->raise(); } else if (_raise == END_RAISE) { _fo_wo->raise(); } // Give focus Workspaces::giveInputFocus(_fo_wo, true); } return EventHandler::EVENT_STOP_PROCESSED; } void FocusToggleEventHandler::setFocusedWo(PWinObj *fo_wo) { if (_fo_wo) { pekwm::observerMapping()->removeObserver(_fo_wo, this); } _fo_wo = fo_wo; if (_fo_wo) { pekwm::observerMapping()->addObserver(_fo_wo, this, 100); if (pekwm::config()->isWarpPointerOn(WARP_ON_FOCUS_CHANGE)) { _fo_wo->warpPointer(); } _fo_wo->setFocused(true); if (_raise == ALWAYS_RAISE) { // Make sure it's not iconified if raise is on. if (_fo_wo->isIconified()) { _was_iconified = true; _fo_wo->mapWindow(); } _fo_wo->raise(); } else if (_raise == TEMP_RAISE) { std::vector winlist; winlist.push_back(_menu->getWindow()); winlist.push_back(_fo_wo->getWindow()); X11::stackWindows(winlist); } } } /** * Creates a menu containing a list of Frames currently visible * @param show_iconified Flag to show/hide iconified windows * @param mru Whether MRU order should be used or not. */ PMenu* FocusToggleEventHandler::createNextPrevMenu(void) { PMenu *menu = new PMenu(_mru ? "MRU Windows" : "Windows", ""); Frame::frame_cit it, end; if (_mru) { it = Workspaces::mru_begin(); end = Workspaces::mru_end(); } else { it = Frame::frame_begin(); end = Frame::frame_end(); } for (; it != end; ++it) { Frame *frame = *it; if (createMenuInclude(frame, _show_iconified)) { Client *client = static_cast(frame->getActiveChild()); menu->insert(client->getTitle()->getVisible(), false, ActionEvent(), frame, client->getIcon()); } } return menu; } /** * Helper to decide wheter or not to include Frame in menu * * @param frame Frame to check * @param show_iconified Wheter or not to include iconified windows * @return true if it should be included, else false */ bool FocusToggleEventHandler::createMenuInclude(Frame *frame, bool show_iconified) { // focw == frame on current workspace bool focw = frame->isSticky() || frame->getWorkspace() == Workspaces::getActive(); // ibs == iconified but should be shown bool ibs = (!frame->isIconified() || show_iconified) && focw; return ! frame->isSkip(SKIP_FOCUS_TOGGLE) && frame->isFocusable() && ibs; } pekwm-0.4.4/src/wm/WindowManager.cc0000664000175000017500000013101315164641301012610 // // WindowManager.cc for pekwm // Copyright (C) 2023-2025 Claes Nästén // Copyright (C) 2002-2021 the pekwm development team // // windowmanager.cc for aewm++ // Copyright (C) 2000 Frank Hale // http://sapphire.sourceforge.net/ // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #include "config.h" #include "Debug.hh" #include "PDecor.hh" #include "Frame.hh" #include "Client.hh" #include "WindowManager.hh" #include "ActionHandler.hh" #include "AutoProperties.hh" #include "Config.hh" #include "Workspaces.hh" #include "Util.hh" #include "X11.hh" #include "Os.hh" #include "RegexString.hh" #include "KeyGrabber.hh" #include "MenuHandler.hh" #include "Harbour.hh" #include "DockApp.hh" #include "CmdDialog.hh" #include "SearchDialog.hh" #include "StatusWindow.hh" #include "WorkspaceIndicator.hh" #include "tk/Color.hh" #include "tk/CfgUtil.hh" #include "tk/FontHandler.hh" #include "tk/Hooks.hh" #include "tk/PFont.hh" #include "tk/PTexture.hh" #include "tk/PWinObj.hh" #include "tk/TextureHandler.hh" #include "tk/Theme.hh" #include "tk/X11Util.hh" #include #include #include #include extern "C" { #include #include #include #include #include #include #include #include #include } // include after all includes to get ifndefs right #include "Compat.hh" extern "C" { static bool is_signal = false; static bool is_signal_hup = false; static bool is_signal_int_term = false; static bool is_signal_chld = false; /** * Signal handler setting signal flags. */ static void sigHandler(int signal) { is_signal = true; switch (signal) { case SIGHUP: is_signal_hup = true; break; case SIGINT: case SIGTERM: is_signal_int_term = true; break; case SIGCHLD: is_signal_chld = true; break; } } } // extern "C" // WindowManager static WindowManager *_wm = nullptr; /** * Create window manager instance and run main routine. */ WindowManager* WindowManager::start(const std::string &bin_dir, const std::string &config_file, bool replace, bool skip_start, bool synchronous, bool standalone) { Display *dpy = XOpenDisplay(0); if (! dpy) { std::cerr << "Can not open display!" << std::endl << "Your DISPLAY variable currently is set to: " << Util::getEnv("DISPLAY") << std::endl; return nullptr; } // Setup window manager Os *os = mkOs(); WindowManager *wm = new WindowManager(bin_dir, os, standalone); Workspaces::init(); if (! pekwm::init(wm, wm, os, dpy, config_file, replace, synchronous, standalone)) { delete wm; wm = nullptr; } else { P_DBG("pekwm_wm " << getpid() << " starting") wm->setupDisplay(); wm->scanWindows(); Frame::resetFrameIDs(); pekwm::rootWo()->setEwmhDesktopNames(); pekwm::rootWo()->setEwmhDesktopLayout(); Workspaces::updateClientList(); // add all frames to the MRU list Frame::frame_cit it = Frame::frame_begin(); for (; it != Frame::frame_end(); ++it) { Workspaces::addToMRUBack(*it); } wm->startSys(); wm->startBackground(pekwm::theme()->getThemeDir(), pekwm::theme()->getBackground()); wm->execStartFile(skip_start); } return wm; } WindowManager::WindowManager(const std::string &bin_dir, Os *os, bool standalone) : _os(os), _bin_dir(bin_dir), _standalone(standalone), _shutdown(false), _reload(false), _restart(false), _select(mkOsSelect()), _bg_pid(-1), _sys_process(nullptr), _event_handler(nullptr), _skip_enter(false) { if (! _bin_dir.empty() && _bin_dir[_bin_dir.size() - 1] != '/') { _bin_dir += '/'; } _screen_edges[0] = 0; _screen_edges[1] = 0; _screen_edges[2] = 0; _screen_edges[3] = 0; struct sigaction act; // Set up the signal handlers. act.sa_handler = sigHandler; act.sa_mask = sigset_t(); act.sa_flags = SA_NOCLDSTOP | SA_NODEFER; sigaction(SIGTERM, &act, 0); sigaction(SIGINT, &act, 0); sigaction(SIGHUP, &act, 0); sigaction(SIGCHLD, &act, 0); _wm = this; } //! @brief WindowManager destructor WindowManager::~WindowManager(void) { cleanup(); MenuHandler::deleteMenus(); Workspaces::cleanup(); delete _sys_process; delete _select; delete _os; _wm = nullptr; } /** * Checks if the start file is executable then runs it if skip_start is not * set to true. */ void WindowManager::execStartFile(bool skip_start) { std::string start_file(pekwm::config()->getStartFile()); if (skip_start || start_file.empty()) { return; } bool exec = Util::isExecutable(start_file); if (! exec) { start_file = SYSCONFDIR "/start"; exec = Util::isExecutable(start_file); } if (exec) { Util::forkExec(start_file); } } //! @brief Cleans up, Maps windows etc. void WindowManager::cleanup(void) { stopBackground(); stopSys(); // update all nonactive clients properties Frame::frame_cit it_f(Frame::frame_begin()); for (; it_f != Frame::frame_end(); ++it_f) { (*it_f)->updateInactiveChildInfo(); } if (pekwm::harbour()) { pekwm::harbour()->removeAllDockApps(); } // To preserve stacking order when destroying the frames, we go through // the PWinObj list from the Workspaces and put all Frames into our own // list, then we delete the frames in order. std::vector frame_list; Workspaces::iterator it_w(Workspaces::begin()); for (; it_w != Workspaces::end(); ++it_w) { if ((*it_w)->getType() == PWinObj::WO_FRAME) { frame_list.push_back(static_cast(*it_w)); } } // Delete all Frames. This reparents the Clients. for (it_f = frame_list.begin(); it_f != frame_list.end(); ++it_f) { delete *it_f; } // Delete all Clients. while (Client::client_begin() != Client::client_end()) { delete *Client::client_begin(); } if (pekwm::keyGrabber()) { pekwm::keyGrabber()->ungrabKeys(X11::getRoot()); } // destroy screen edge for (int i=0; i < 4; ++i) { Workspaces::remove(_screen_edges[i]); delete _screen_edges[i]; _screen_edges[i]=0; } if (X11::getDpy()) { XInstallColormap(X11::getDpy(), X11::getColormap()); X11::setInputFocus(PointerRoot); } } /** * Setup display and claim resources. */ void WindowManager::setupDisplay() { _select->add(X11::getFd(), OsSelect::OS_SELECT_READ); pekwm::autoProperties()->load(); Workspaces::setSize(pekwm::config()->getWorkspaces()); Workspaces::setPerRow(pekwm::config()->getWorkspacesPerRow()); XDefineCursor(X11::getDpy(), X11::getRoot(), X11::getCursor(CURSOR_ARROW)); X11::selectXRandrInput(); // Create screen edge windows screenEdgeCreate(); screenEdgeMapUnmap(); } /** * Goes through the window and creates Clients/DockApps. */ void WindowManager::scanWindows(void) { // only done once when we start if (! pekwm::isStarting()) { return; } // Lets create a list of windows on the display Window root, parent; std::vector win_list; X11::queryTree(X11::getRoot(), root, parent, win_list); // Filter out all windows with the the IconWindowHint set not pointing // to themselves, making DockApps work as they are supposed to. XWMHints wm_hints; std::vector::iterator it(win_list.begin()); for (; it != win_list.end(); ++it) { if (*it == None) { continue; } if (X11::getWMHints(*it, wm_hints) && (wm_hints.flags&IconWindowHint) && (wm_hints.icon_window != *it)) { std::vector::iterator i_it(std::find(win_list.begin(), win_list.end(), wm_hints.icon_window)); if (i_it != win_list.end()) { *i_it = None; } } } for (it = win_list.begin(); it != win_list.end(); ++it) { if (*it != None) { createClient(*it, false); } } // Try to focus the ontop window, if no window we give root focus PWinObj *wo = Workspaces::getTopFocusableWO(PWinObj::WO_FRAME); if (wo) { Workspaces::giveInputFocus(wo); } else { pekwm::rootWo()->giveInputFocus(); } // Try to find transients for all clients, on restarts ordering might // not be correct. Client::client_cit it_client = Client::client_begin(); for (; it_client != Client::client_end(); ++it_client) { if ((*it_client)->isTransient() && ! (*it_client)->getTransientForClient()) { (*it_client)->findAndRaiseIfTransient(); } } // Update client list _once_ after creating all clients Workspaces::updateClientList(); // Discard on start autoproperties, will not be used until next start // of pekwm. pekwm::autoProperties()->removeApplyOnStart(); pekwm::setStarted(); } /** * Creates and places screen edge */ void WindowManager::screenEdgeCreate(void) { bool indent = pekwm::config()->getScreenEdgeIndent(); Config *cfg = pekwm::config(); RootWO *root_wo = pekwm::rootWo(); _screen_edges[0] = new EdgeWO(root_wo, SCREEN_EDGE_LEFT, indent && (cfg->getScreenEdgeSize(SCREEN_EDGE_LEFT) > 0), cfg); _screen_edges[1] = new EdgeWO(root_wo, SCREEN_EDGE_RIGHT, indent && (cfg->getScreenEdgeSize(SCREEN_EDGE_RIGHT) > 0), cfg); _screen_edges[2] = new EdgeWO(root_wo, SCREEN_EDGE_TOP, indent && (cfg->getScreenEdgeSize(SCREEN_EDGE_TOP) > 0), cfg); _screen_edges[3] = new EdgeWO(root_wo, SCREEN_EDGE_BOTTOM, indent && (cfg->getScreenEdgeSize(SCREEN_EDGE_BOTTOM) > 0), cfg); // make sure the edge stays ontop for (int i=0; i < 4; ++i) { Workspaces::insert(_screen_edges[i]); } screenEdgeResize(); } void WindowManager::screenEdgeResize(void) { Config *cfg = pekwm::config(); uint l_size = std::max(cfg->getScreenEdgeSize(SCREEN_EDGE_LEFT), 1); uint r_size = std::max(cfg->getScreenEdgeSize(SCREEN_EDGE_RIGHT), 1); uint t_size = std::max(cfg->getScreenEdgeSize(SCREEN_EDGE_TOP), 1); uint b_size = std::max(cfg->getScreenEdgeSize(SCREEN_EDGE_BOTTOM), 1); // Left edge _screen_edges[0]->moveResize(0, 0, l_size, X11::getHeight()); // Right edge _screen_edges[1]->moveResize(X11::getWidth() - r_size, 0, r_size, X11::getHeight()); // Top edge _screen_edges[2]->moveResize(l_size, 0, X11::getWidth() - l_size - r_size, t_size); // Bottom edge _screen_edges[3]->moveResize(l_size, X11::getHeight() - b_size, X11::getWidth() - l_size - r_size, b_size); for (int i = 0; i < 4; ++i) { int indent = cfg->getScreenEdgeIndent(); int size = cfg->getScreenEdgeSize(_screen_edges[i]->getEdge()); _screen_edges[i]->configureStrut(indent && size > 0); } pekwm::rootWo()->updateStrut(); } void WindowManager::screenEdgeMapUnmap(void) { for (int i=0; i<4; ++i) { EdgeWO *edge = _screen_edges[i]; Config *cfg = pekwm::config(); if (cfg->getScreenEdgeSize(edge->getEdge()) > 0 && cfg->getEdgeListFromPosition(edge->getEdge())->size() > 0) { edge->mapWindow(); } else { edge->unmapWindow(); } } } //! @brief Reloads configuration and updates states. void WindowManager::doReload(void) { bool scale_changed = false; doReloadConfig(scale_changed); doReloadTheme(scale_changed /* force if scale changed */); doReloadMouse(); doReloadKeygrabber(); doReloadAutoproperties(); MenuHandler::reloadMenus(pekwm::actionHandler()); doReloadHarbour(); pekwm::rootWo()->setEwmhDesktopNames(); pekwm::rootWo()->setEwmhDesktopLayout(); // (re)start pekwm_sys if it is enabled and not running, either because // a crash or it was not previously enabled. if (pekwm::config()->isSysEnabled()) { if (! startSys()) { // already running, send reload writeSysCommand("RELOAD"); } } else { stopSys(); } _reload = false; } /** * Reload main config file. */ void WindowManager::doReloadConfig(bool &scale_changed) { scale_changed = false; Config *cfg = pekwm::config(); // If any of these changes, re-fetch of all names is required float old_screen_scale = cfg->getScreenScale(); bool old_client_unique_name = cfg->getClientUniqueName(); std::string old_client_unique_name_pre(cfg->getClientUniqueNamePre()); std::string old_client_unique_name_post(cfg->getClientUniqueNamePost()); // Reload configuration if (! cfg->load(cfg->getConfigFile())) { return; } scale_changed = setScale(old_screen_scale, cfg->getScreenScale(), false); // Update what might have changed in the cfg touching the hints Workspaces::setSize(cfg->getWorkspaces()); Workspaces::setPerRow(cfg->getWorkspacesPerRow()); Workspaces::setNames(); // Update the ClientUniqueNames if needed if ((old_client_unique_name != cfg->getClientUniqueName()) || (old_client_unique_name_pre != cfg->getClientUniqueNamePre()) || (old_client_unique_name_post != cfg->getClientUniqueNamePost())) { Client::client_cit it = Client::client_begin(); for (; it != Client::client_end(); ++it) { (*it)->readName(); } } // Resize the screen edge screenEdgeResize(); screenEdgeMapUnmap(); pekwm::rootWo()->updateStrut(); } bool WindowManager::setScale(double old_scale, double new_scale, bool reload) { bool scale_changed = old_scale != new_scale; if (scale_changed) { X11::setString(X11::getRoot(), PEKWM_THEME_SCALE, std::to_string(new_scale)); pekwm::fontHandler()->setScale(new_scale); pekwm::imageHandler()->setScale(new_scale); pekwm::textureHandler()->setScale(new_scale); if (reload) { doReloadTheme(true); } } return scale_changed; } /** * Reload theme file and update decorations. */ void WindowManager::doReloadTheme(bool force) { Config *cfg = pekwm::config(); Theme *theme = pekwm::theme(); // auto theme variant handling std::string variant = cfg->getThemeVariant(); CfgUtil::lookupThemeVariant(cfg->getThemeFile(), variant); // reload the theme, reloading the decors only if the theme changed. bool loaded = theme->load(cfg->getThemeFile(), variant, force); // always start the background as the override texture can change // without the theme changing startBackground(theme->getThemeDir(), theme->getBackground()); if (loaded) { doReloadThemeDecors(); writeSysCommand("THEME " + theme->getThemeFile()); } else { P_TRACE("not reloading decors, theme not changed"); } } void WindowManager::doReloadThemeDecors() { // Reload the themes on all decors std::vector::const_iterator it = PDecor::pdecor_begin(); for (; it != PDecor::pdecor_end(); ++it) { (*it)->loadDecor(); } } void WindowManager::startBackground(const std::string& theme_dir, const std::string& theme_texture) { const std::string &override_texture = pekwm::config()->getThemeBackgroundOverride(); const std::string &texture = override_texture.empty() ? theme_texture : override_texture; if (pekwm::config()->getThemeBackground() && ! texture.empty()) { std::string bg_args = theme_dir + texture; if (bg_args != _bg_args || ! _os->isProcessAlive(_bg_pid)) { stopBackground(); std::vector args; args.push_back(_bin_dir + "pekwm_bg"); args.push_back("--load-dir"); args.push_back(theme_dir + "/backgrounds"); args.push_back(texture); _bg_pid = _os->processExec(args); _bg_args = bg_args; P_LOG("started " << _bin_dir << "pekwm_bg --load-dir " << theme_dir + "/backgrounds " << texture << " -> pid " << _bg_pid); } } else { stopBackground(); } } void WindowManager::stopBackground(void) { if (_bg_pid != -1) { // SIGCHILD will take care of waiting for the child P_LOG("stopping pekwm_bg pid " << _bg_pid); _os->processSignal(_bg_pid, SIGKILL); } _bg_pid = -1; _bg_args = ""; } /** * Start pekwm_sys process if it is enabled in the configuration. */ bool WindowManager::startSys() { if (! pekwm::config()->isSysEnabled() || _sys_process) { return false; } std::vector args; args.push_back(_bin_dir + "pekwm_sys"); args.push_back("--theme"); args.push_back(pekwm::theme()->getThemeFile()); _sys_process = _os->childExec(args, ChildProcess::CHILD_IO_ALL); if (_sys_process) { P_LOG("started " << _bin_dir << "pekwm_sys -> pid " << _sys_process->getPid()); pekwm::actionHandler()->setSysProcess(_sys_process); } return true; } void WindowManager::stopSys() { if (_sys_process) { // SIGCHILD will take care of waiting for the child P_LOG("stopping pekwm_sys pid " << _sys_process->getPid()); _os->processSignal(_sys_process->getPid(), SIGKILL); } } void WindowManager::writeSysCommand(const std::string &cmd) { if (_sys_process) { uint32_t len = cmd.size(); _sys_process->write(reinterpret_cast(&len), sizeof(len)); _sys_process->write(cmd); P_TRACE("sent " << cmd << " to pekwm_sys"); } } /** * Reload mouse configuration and re-grab buttons on all windows. */ void WindowManager::doReloadMouse(void) { Config *cfg = pekwm::config(); if (! cfg->loadMouseConfig(cfg->getMouseConfigFile())) { return; } Client::client_cit it = Client::client_begin(); for (; it != Client::client_end(); ++it) { (*it)->grabButtons(); } } /** * Reload keygrabber configuration and re-grab keys on all windows. */ void WindowManager::doReloadKeygrabber(bool force) { // Reload the keygrabber if (! pekwm::keyGrabber()->load(pekwm::config()->getKeyFile(), force)) { return; } pekwm::keyGrabber()->ungrabKeys(X11::getRoot()); pekwm::keyGrabber()->grabKeys(X11::getRoot()); // Regrab keys and buttons Client::client_cit c_it(Client::client_begin()); for (; c_it != Client::client_end(); ++c_it) { (*c_it)->grabButtons(); pekwm::keyGrabber()->ungrabKeys((*c_it)->getWindow()); pekwm::keyGrabber()->grabKeys((*c_it)->getWindow()); } } /** * Reload autoproperties. */ void WindowManager::doReloadAutoproperties(void) { if (! pekwm::autoProperties()->load()) { return; } // NOTE: we need to load autoproperties after decor have been updated // as otherwise old theme data pointer will be used and sig 11 pekwm. Client::client_cit it_c(Client::client_begin()); for (; it_c != Client::client_end(); ++it_c) { (*it_c)->readAutoprops(APPLY_ON_RELOAD); } Frame::frame_cit it_f(Frame::frame_begin()); for (; it_f != Frame::frame_end(); ++it_f) { (*it_f)->readAutoprops(APPLY_ON_RELOAD); } } /** * Reload harbour configuration. */ void WindowManager::doReloadHarbour(void) { pekwm::harbour()->loadTheme(); pekwm::harbour()->rearrange(); pekwm::harbour()->restack(); pekwm::harbour()->updateHarbourSize(); } /** * Reload Xrm Resources and update resource dependent parts (if any at * the time). */ void WindowManager::doReloadResources(void) { P_TRACE("RESOURCE_MANAGER changed, reloading resources"); X11::loadXrmResources(); if (isResourcesChanged()) { P_TRACE("used resources changed, reloading theme"); doReloadTheme(true); } } bool WindowManager::isResourcesChanged(void) { const std::map &resources = X11::getRefResources(); std::map::const_iterator it = resources.begin(); for (; it != resources.end(); ++it) { P_TRACE("check referenced resource " << it->first); std::string val; X11::getXrmString(it->first, val); if (val != it->second) { return true; } } return false; } /** * Exit pekwm and restart with the command command */ void WindowManager::restart(std::string command) { if (! command.empty()) { _restart_command = command; } _restart = true; _shutdown = true; } // Event handling routins beneath this ===================================== void WindowManager::handleSignals(void) { // SIGHUP if (is_signal_hup) { P_TRACE("handle SIGHUP or reload"); is_signal_hup = false; _reload = true; } // Wait for children if a SIGCHLD was received if (is_signal_chld) { P_TRACE("handle SIGCHLD"); pid_t pid; do { pid = waitpid(WAIT_ANY, nullptr, WNOHANG); if (pid == -1) { if (errno == EINTR) { P_TRACE("waitpid interrupted, " "retrying"); } } else if (pid == 0) { P_TRACE("no more finished child processes"); } else if (pid == _bg_pid) { P_WARN("pekwm_bg stopped unexpectedly"); showDialog("pekwm_bg error", "Stopped unexpectedly, reload pekwm" " to trigger restart"); _bg_pid = -1; } else if (_sys_process && pid == _sys_process->getPid()) { P_WARN("pekwm_sys stopped unexpectedly"); showDialog("pekwm_sys error", "Stopped unexpectedly, reload pekwm" " to trigger restart"); delete _sys_process; _sys_process = nullptr; pekwm::actionHandler()->setSysProcess(nullptr); } else { P_TRACE("child process " << pid << " finished"); } } while (pid > 0 || (pid == -1 && errno == EINTR)); is_signal_chld = false; } } void WindowManager::doEventLoop(void) { while (! _shutdown && ! is_signal_int_term) { if (is_signal) { handleSignals(); is_signal = false; } if (_reload) { doReload(); } XEvent ev; if (getEvent(ev) && ! handleEventHandlerEvent(ev)) { handleEvent(ev); } } } /** * Get next X11 event, handling timeout actions if any. */ bool WindowManager::getEvent(XEvent &ev) { if (X11::pending() > 0) { X11::getNextEvent(ev); return true; } TimeoutAction ta; struct timeval *tv; if (pekwm::timeouts()->getNextTimeout(&tv, ta)) { ActionHandler *action_handler = pekwm::actionHandler(); ActionEvent ae(1, static_cast(ta.getKey())); ActionPerformed ap(nullptr, ae); action_handler->handleAction(&ap); } else if (_select->wait(tv)) { if (_select->isSet(X11::getFd(), OsSelect::OS_SELECT_READ)) { return X11::getNextEvent(ev); } } return false; } bool WindowManager::handleEventHandlerEvent(XEvent &ev) { if (_event_handler == nullptr) { return false; } EventHandler::Result res; switch (ev.type) { case ButtonPress: res = _event_handler->handleButtonPressEvent(&ev.xbutton); break; case ButtonRelease: res = _event_handler->handleButtonReleaseEvent(&ev.xbutton); break; case Expose: res = _event_handler->handleExposeEvent(&ev.xexpose); break; case KeyPress: case KeyRelease: res = _event_handler->handleKeyEvent(&ev.xkey); break; case MotionNotify: res = _event_handler->handleMotionNotifyEvent(&ev.xmotion); break; default: res = EventHandler::EVENT_SKIP; } switch (res) { case EventHandler::EVENT_STOP_PROCESSED: case EventHandler::EVENT_STOP_SKIP: P_TRACE("removing event handler " << _event_handler); setEventHandler(nullptr); return res == EventHandler::EVENT_STOP_PROCESSED; default: return res == EventHandler::EVENT_PROCESSED; } } void WindowManager::handleEvent(XEvent &ev) { static ScreenChangeNotification scn; switch (ev.type) { case MapRequest: handleMapRequestEvent(&ev.xmaprequest); break; case UnmapNotify: handleUnmapEvent(&ev.xunmap); break; case DestroyNotify: handleDestroyWindowEvent(&ev.xdestroywindow); break; case ConfigureRequest: handleConfigureRequestEvent(&ev.xconfigurerequest); break; case ClientMessage: handleClientMessageEvent(&ev.xclient); break; case ColormapNotify: handleColormapEvent(&ev.xcolormap); break; case PropertyNotify: X11::setLastEventTime(ev.xproperty.time); handlePropertyEvent(&ev.xproperty); break; case MappingNotify: handleMappingEvent(&ev.xmapping); break; case Expose: handleExposeEvent(&ev.xexpose); break; case KeyPress: case KeyRelease: X11::setLastEventTime(ev.xkey.time); handleKeyEvent(&ev.xkey); break; case ButtonPress: X11::setLastEventTime(ev.xbutton.time); handleButtonPressEvent(&ev.xbutton); break; case ButtonRelease: X11::setLastEventTime(ev.xbutton.time); handleButtonReleaseEvent(&ev.xbutton); break; case MotionNotify: X11::setLastEventTime(ev.xmotion.time); handleMotionEvent(&ev.xmotion); break; case EnterNotify: X11::setLastEventTime(ev.xcrossing.time); handleEnterNotify(&ev.xcrossing); break; case LeaveNotify: X11::setLastEventTime(ev.xcrossing.time); handleLeaveNotify(&ev.xcrossing); break; case FocusIn: handleFocusInEvent(&ev.xfocus); break; case FocusOut: break; case SelectionClear: // Another window P_LOG("being replaced by another WM"); _shutdown = true; break; default: #ifdef PEKWM_HAVE_SHAPE if (X11::hasExtensionShape() && ev.type == X11::getEventShape()) { XShapeEvent *sev = reinterpret_cast(&ev); X11::setLastEventTime(sev->time); Client *client = Client::findClient(sev->window); if (client) { client->handleShapeEvent(sev); } } #endif // PEKWM_HAVE_SHAPE if (X11::getScreenChangeNotification(&ev, scn)) { pekwm::rootWo()->updateGeometry(scn.width, scn.height); pekwm::harbour()->updateGeometry(); screenEdgeResize(); // Make sure windows are visible after re-size std::vector::const_iterator it = PDecor::pdecor_begin(); for (; it != PDecor::pdecor_end(); ++it) { Workspaces::placeWoInsideScreen(*it); } std::map args; pekwm::hooks()->run( PEKWM_HOOK_ON_MONITOR_CONFIGURATION_CHANGE, args); } break; } } //! @brief Handle XKeyEvents void WindowManager::handleKeyEvent(XKeyEvent *ev) { bool matched = false; const ActionEvent *ae = nullptr; PWinObj *wo = PWinObj::getFocusedPWinObj(); PWinObj *wo_orig = wo; PWinObj::Type type = (wo) ? wo->getType() : PWinObj::WO_SCREEN_ROOT; if (wo && wo->getWindow() == ev->window) { wo->setLastActivity(ev->time); } switch (type) { case PWinObj::WO_CLIENT: case PWinObj::WO_FRAME: case PWinObj::WO_SCREEN_ROOT: case PWinObj::WO_MENU: if (ev->type == KeyPress) { ae = pekwm::keyGrabber()->findAction(ev, type, matched); if (ae == nullptr && type == PWinObj::WO_MENU) { ae = wo->handleKeyPress(ev); } } break; case PWinObj::WO_CMD_DIALOG: case PWinObj::WO_SEARCH_DIALOG: if (ev->type == KeyPress) { ae = wo->handleKeyPress(ev); } else { ae = wo->handleKeyRelease(ev); } wo = static_cast(wo)->getWORef(); break; default: if (wo) { if (ev->type == KeyPress) { ae = wo->handleKeyPress(ev); } else { ae = wo->handleKeyRelease(ev); } } break; } if (ae) { handleKeyEventAction(ev, ae, wo, wo_orig); } // Flush Enter events caused by keygrabbing if (matched) { XEvent e; while (X11::checkTypedEvent(EnterNotify, &e)) { if (! e.xcrossing.send_event) { X11::setLastEventTime(e.xcrossing.time); } } } } void WindowManager::handleKeyEventAction(XKeyEvent *ev, const ActionEvent *ae, PWinObj *wo, PWinObj *wo_orig) { // HACK: Always close CmdDialog and SearchDialog before actions if (wo_orig && (wo_orig->getType() == PWinObj::WO_CMD_DIALOG || wo_orig->getType() == PWinObj::WO_SEARCH_DIALOG)) { ::Action close_action; ActionEvent close_ae; close_ae.action_list.push_back(close_action); close_ae.action_list.back().setAction(ACTION_CLOSE); ActionPerformed close_ap(wo_orig, close_ae); pekwm::actionHandler()->handleAction(&close_ap); } ActionPerformed ap(wo, *ae); ap.type = ev->type; ap.event.key = ev; pekwm::actionHandler()->handleAction(&ap); } void WindowManager::handleButtonPressEvent(XButtonEvent *ev) { const ActionEvent *ae = nullptr; PWinObj *wo = PWinObj::findPWinObj(ev->window); if (wo == pekwm::rootWo() && ev->subwindow != None) { wo = PWinObj::findPWinObj(ev->subwindow); } if (wo) { wo->setLastActivity(ev->time); // in case the event causes the wo to go away, update it // before handling the event. PWinObj *orig_wo = wo; wo = updateWoForFrameClick(ev, orig_wo); ae = orig_wo->handleButtonPress(ev); } if (ae) { ActionPerformed ap(wo, *ae); ap.type = ev->type; ap.event.button = ev; pekwm::actionHandler()->handleAction(&ap); } else { Harbour *harbour = pekwm::harbour(); DockApp *da = harbour->findDockAppFromFrame(ev->window); if (da) { harbour->handleButtonEvent(ev, da); } } } void WindowManager::handleButtonReleaseEvent(XButtonEvent *ev) { const ActionEvent *ae = nullptr; PWinObj *wo = PWinObj::findPWinObj(ev->window); if (wo == pekwm::rootWo() && ev->subwindow != None) { wo = PWinObj::findPWinObj(ev->subwindow); } if (wo) { wo->setLastActivity(ev->time); // in case the event causes the wo to go away, update it // before handling the event. PWinObj *orig_wo = wo; wo = updateWoForFrameClick(ev, orig_wo); ae = orig_wo->handleButtonRelease(ev); } if (ae) { ActionPerformed ap(wo, *ae); ap.type = ev->type; ap.event.button = ev; pekwm::actionHandler()->handleAction(&ap); } else { Harbour *harbour = pekwm::harbour(); DockApp *da = harbour->findDockAppFromFrame(ev->window); if (da) { harbour->handleButtonEvent(ev, da); } } } PWinObj* WindowManager::updateWoForFrameClick(XButtonEvent *ev, PWinObj *wo) { if (wo->getType() != PWinObj::WO_FRAME) { return wo; } // update selected window object with the one clicked // on the titlebar (if any), subwindow check is there // to skip titlebar button press Frame *frame = static_cast(wo); if (ev->subwindow == None && ev->window == frame->getTitleWindow()) { wo = frame->getChildFromPos(ev->x); } else { wo = frame->getActiveChild(); } if (wo) { wo->setLastActivity(ev->time); } return wo; } void WindowManager::handleConfigureRequestEvent(XConfigureRequestEvent *ev) { Client *client = Client::findClientFromWindow(ev->window); if (client) { Frame* frame = static_cast(client->getParent()); frame->handleConfigureRequest(ev, client); } else { DockApp *da = pekwm::harbour()->findDockApp(ev->window); if (da) { pekwm::harbour()->handleConfigureRequestEvent(ev, da); } else { // Since this window isn't yet a client lets delegate // the configure request back to the window so it can // use it. XWindowChanges wc; wc.x = ev->x; wc.y = ev->y; wc.width = ev->width; wc.height = ev->height; wc.sibling = ev->above; wc.stack_mode = ev->detail; XConfigureWindow(X11::getDpy(), ev->window, ev->value_mask, &wc); } } } /** * Handle motion event, match on event window expect when event window * is root and subwindow is set then also match on menus. */ void WindowManager::handleMotionEvent(XMotionEvent *ev) { PWinObj *wo = PWinObj::findPWinObj(ev->window); if (wo == pekwm::rootWo() && ev->subwindow != None) { wo = PWinObj::findPWinObj(ev->subwindow); } if (wo) { const ActionEvent *ae = nullptr; if (wo->getType() == PWinObj::WO_CLIENT) { ae = wo->getParent()->handleMotionEvent(ev); } else if (wo->getType() == PWinObj::WO_FRAME) { ae = wo->handleMotionEvent(ev); // this is done so that clicking the titlebar executes // action on the client clicked on Frame* frame = static_cast(wo); if (ev->subwindow != None) { wo = frame->getActiveChild(); } else { wo = frame->getChildFromPos(ev->x); } } else { ae = wo->handleMotionEvent(ev); } if (ae) { ActionPerformed ap(wo, *ae); ap.type = ev->type; ap.event.motion = ev; pekwm::actionHandler()->handleAction(&ap); } } else { DockApp* da = pekwm::harbour()->findDockAppFromFrame(ev->window); if (da) { pekwm::harbour()->handleMotionNotifyEvent(ev, da); } } } void WindowManager::handleMapRequestEvent(XMapRequestEvent *ev) { PWinObj *wo = PWinObj::findPWinObj(ev->window); if (wo) { wo->handleMapRequest(ev); } else { createClient(ev->window, true); } } void WindowManager::handleUnmapEvent(XUnmapEvent *ev) { PWinObj *wo = PWinObj::findPWinObj(ev->window); PWinObj *wo_search = 0; PWinObj::Type wo_type = PWinObj::WO_NO_TYPE; if (wo) { wo_type = wo->getType(); if (wo_type == PWinObj::WO_CLIENT) { wo_search = wo->getParent(); } wo->handleUnmapEvent(ev); if (wo == PWinObj::getFocusedPWinObj()) { PWinObj::setFocusedPWinObj(0); } } else { DockApp *da = pekwm::harbour()->findDockApp(ev->window); if (da) { if (ev->window == ev->event) { pekwm::harbour()->removeDockApp(da); } } } if (wo_type != PWinObj::WO_MENU && wo_type != PWinObj::WO_CMD_DIALOG && wo_type != PWinObj::WO_SEARCH_DIALOG && ! PWinObj::getFocusedPWinObj()) { Workspaces::findWOAndFocus(wo_search); } } void WindowManager::handleDestroyWindowEvent(XDestroyWindowEvent *ev) { Client *client = Client::findClientFromWindow(ev->window); if (client) { PWinObj *wo_search = client->getParent(); client->handleDestroyEvent(ev); if (! PWinObj::getFocusedPWinObj()) { Workspaces::findWOAndFocus(wo_search); } } else { DockApp *da = pekwm::harbour()->findDockApp(ev->window); if (da) { da->setAlive(false); pekwm::harbour()->removeDockApp(da); } } } void WindowManager::handleEnterNotify(XCrossingEvent *ev) { // Window being entered is marked to cause the upcoming enter // event to have no effect, multiple consequitive enter events on // this window just keeps on making the next enter event being // marked to be skipped. if (PWinObj::isSkipEnterAfter(ev->window)) { _skip_enter = true; return; } PWinObj::setSkipEnterAfter(nullptr); if (_skip_enter) { _skip_enter = false; return; } // Clear event queue while (X11::checkTypedEvent(EnterNotify, reinterpret_cast(ev))) { if (! ev->send_event) { X11::setLastEventTime(ev->time); } } if ((ev->mode == NotifyGrab) || (ev->mode == NotifyUngrab)) { return; } PWinObj *wo = PWinObj::findPWinObj(ev->window); if (wo) { if (wo->getType() == PWinObj::WO_CLIENT) { wo = wo->getParent(); } const ActionEvent *ae = wo->handleEnterEvent(ev); if (ae) { ActionPerformed ap(wo, *ae); ap.type = ev->type; ap.event.crossing = ev; pekwm::actionHandler()->handleAction(&ap); } } } void WindowManager::handleLeaveNotify(XCrossingEvent *ev) { // Clear event queue while (X11::checkTypedEvent(LeaveNotify, reinterpret_cast(ev))) { if (! ev->send_event) { X11::setLastEventTime(ev->time); } } if ((ev->mode == NotifyGrab) || (ev->mode == NotifyUngrab)) { return; } PWinObj *wo = PWinObj::findPWinObj(ev->window); if (wo) { const ActionEvent *ae = wo->handleLeaveEvent(ev); if (ae) { ActionPerformed ap(wo, *ae); ap.type = ev->type; ap.event.crossing = ev; pekwm::actionHandler()->handleAction(&ap); } } } //! @brief Handles FocusIn Events. void WindowManager::handleFocusInEvent(XFocusChangeEvent *ev) { if (ev->mode == NotifyGrab || ev->mode == NotifyUngrab || ev->detail == NotifyPointer || ev->detail == NotifyVirtual || ev->detail == NotifyNonlinearVirtual) { return; } PWinObj *wo = PWinObj::findPWinObj(ev->window); if (wo == nullptr) { return; } // To simplify logic, changing client in frame wouldn't update the // focused window because wo != focused_wo woule be true. if (wo->getType() == PWinObj::WO_FRAME) { wo = static_cast(wo)->getActiveChild(); } if (! wo->isFocusable() || ! wo->isMapped()) { Workspaces::findWOAndFocus(nullptr); } else if (wo != PWinObj::getFocusedPWinObj()) { // If it's a valid FocusIn event with accepatable target lets // flush all EnterNotify and LeaveNotify as they can interfere // with focusing if Sloppy or Follow like focus model is used. XEvent e_flush; while (X11::checkTypedEvent(EnterNotify, &e_flush)) { if (! e_flush.xcrossing.send_event) { X11::setLastEventTime(e_flush.xcrossing.time); } } while (X11::checkTypedEvent(LeaveNotify, &e_flush)) { if (! e_flush.xcrossing.send_event) { X11::setLastEventTime(e_flush.xcrossing.time); } } PWinObj *focused_wo = PWinObj::getFocusedPWinObj(); // unfocus last window if (focused_wo) { if (focused_wo->getType() == PWinObj::WO_CLIENT) { focused_wo->getParent()->setFocused(false); } else { focused_wo->setFocused(false); } Workspaces::setLastFocused(Workspaces::getActive(), focused_wo); } PWinObj::setFocusedPWinObj(wo); if (wo->getType() == PWinObj::WO_CLIENT) { wo->getParent()->setFocused(true); pekwm::rootWo()->setEwmhActiveWindow(wo->getWindow()); // update the MRU list (except for skip focus windows, // see #297) Client* client = static_cast(wo); if (! client->isSkip(SKIP_FOCUS_TOGGLE)) { Frame *frame = static_cast(wo->getParent()); Workspaces::addToMRUFront(frame); } } else { wo->setFocused(true); pekwm::rootWo()->setEwmhActiveWindow(None); } } } /** * Handle XClientMessageEvent events. * * @param ev Event to handle. */ void WindowManager::handleClientMessageEvent(XClientMessageEvent *ev) { P_DBG("XClientMessageEvent window: " << ev->window << " (root: " << (ev->window == X11::getRoot()) << ") message format: " << ev->format << " type: " << ev->message_type << " (" << X11::getAtomIdString(ev->message_type) << ")" << " data.l[0] " << ev->data.l[0]); if (ev->message_type == X11::getAtom(PEKWM_CMD)) { // _PEKWM_CMD is handled independent of client handlePekwmCmd(ev); } if (ev->window == X11::getRoot()) { if (ev->format == 32) { if (ev->message_type == X11::getAtom(NET_CURRENT_DESKTOP)) { Workspaces::setWorkspace(ev->data.l[0], true); } else if (ev->message_type == X11::getAtom(NET_NUMBER_OF_DESKTOPS)) { if (ev->data.l[0] > 0) { Workspaces::setSize(ev->data.l[0]); } } } } else if (ev->message_type == X11::getAtom(NET_RESTACK_WINDOW)) { handleNetRestackWindow(ev); } else if (ev->message_type == X11::getAtom(NET_REQUEST_FRAME_EXTENTS)) { handleNetRequestFrameExtents(ev->window); } else { Client *client = Client::findClientFromWindow(ev->window); if (client) { Frame *frame = static_cast(client->getParent()); const ActionEvent *ae = frame->handleClientMessage(ev, client); if (ae) { ActionPerformed ap(frame, *ae); ap.type = ev->type; ap.event.client = ev; pekwm::actionHandler()->handleAction(&ap); } } } } /** * Handle _NET_RESTACK_WINDOW request: * * window = window to restack * format = 32 * data.l[0] = source indication * data.l[1] = sibling window * data.l[2] = detail * * Used by pagers to re-stack windows instead of using a ConfigureRequest * with CWSibling and CWStackMode as they can be ignored by the window * manager. */ void WindowManager::handleNetRestackWindow(XClientMessageEvent *ev) { if (ev->format != 32) { P_TRACE("invalid _NET_RESTACK_WINDOW request, expected format " "32, got " << ev->format); return; } Window sibling_win = ev->data.l[1]; long detail = ev->data.l[2]; P_TRACE("_NET_RESTACK_WINDOW client=" << ev->window << " sibling=" << sibling_win << " detail=" << detail); Client *client = Client::findClientFromWindow(ev->window); Client *sibling = sibling_win == None ? nullptr : Client::findClientFromWindow(sibling_win); if (client == nullptr || (sibling_win != None && sibling == nullptr)) { return; } Workspaces::restack(client->getParent(), sibling ? sibling->getParent() : nullptr, detail); } void WindowManager::handleNetRequestFrameExtents(Window win) { ThemeState *state; MwmThemeState mwm_state; Client *client = Client::findClientFromWindow(win); if (client == nullptr) { MwmHints hints; X11Util::readMwmHints(win, hints); mwm_state.setHints(hints); state = &mwm_state; } else { state = static_cast(client->getParent()); } // _NET_REQUEST_FRAME_EXTENTS is not a required to be correct, // autoproperties and such are ignored and also the decor type. Theme::PDecorData *data = pekwm::theme()->getPDecorData("DEFAULT"); if (data) { ThemeGm theme_gm(data); Cardinal extents[4]; extents[0] = theme_gm.bdLeft(state); extents[1] = theme_gm.bdRight(state); extents[2] = theme_gm.bdTop(state) + theme_gm.titleHeight(state); extents[3] = theme_gm.bdBottom(state); if (Debug::isLevel(Debug::LEVEL_TRACE)) { std::ostringstream msg; msg << "setting _NET_FRAME_EXTENTS (" << extents[0]; msg << " " << extents[1] << " " << extents[2] << " "; msg << extents[3] << ") on " << win; P_TRACE(msg.str()); } X11::setCardinals(win, NET_FRAME_EXTENTS, extents, 4); } } void WindowManager::handleColormapEvent(XColormapEvent *ev) { Client *client = Client::findClient(ev->window); if (client) { Frame* frame = static_cast(client->getParent()); client = static_cast(frame->getActiveChild()); client->handleColormapChange(ev); } } //! @brief Handles XPropertyEvents void WindowManager::handlePropertyEvent(XPropertyEvent *ev) { if (ev->window == X11::getRoot()) { if (ev->atom == X11::getAtom(RESOURCE_MANAGER)) { doReloadResources(); } else if (ev->atom == X11::getAtom(PEKWM_THEME_VARIANT)) { doReloadTheme(false); } else { return pekwm::rootWo()->handlePropertyChange(ev); } } Client *client = Client::findClientFromWindow(ev->window); if (client) { Frame* frame = static_cast(client->getParent()); frame->handlePropertyChange(ev, client); } } //! @brief Handles XMappingEvent void WindowManager::handleMappingEvent(XMappingEvent *ev) { if (ev->request == MappingKeyboard || ev->request == MappingModifier) { XRefreshKeyboardMapping(ev); X11::setLockKeys(); InputDialog::reloadKeysymMap(); doReloadKeygrabber(true); } } void WindowManager::handleExposeEvent(XExposeEvent *ev) { const ActionEvent *ae = nullptr; PWinObj *wo = PWinObj::findPWinObj(ev->window); if (wo) { ae = wo->handleExposeEvent(ev); } if (ae) { ActionPerformed ap(wo, *ae); ap.type = ev->type; ap.event.expose = ev; pekwm::actionHandler()->handleAction(&ap); } } // Event handling routines stop ============================================ Client* WindowManager::createClient(Window window, bool is_new) { XWindowAttributes attr; X11::getWindowAttributes(window, attr); if (attr.override_redirect || (! is_new && attr.map_state == IsUnmapped)) { return nullptr; } XWMHints wm_hints; if (X11::getWMHints(window, wm_hints) && (wm_hints.flags&StateHint) && (wm_hints.initial_state == WithdrawnState)) { pekwm::harbour()->addDockApp(new DockApp(window)); return nullptr; } ClientInitConfig initConfig; Client *client = new Client(window, initConfig, is_new); if (! client->isAlive()) { delete client; return nullptr; } if (initConfig.parent_is_new) { PWinObj *wo = client->getParent(); Workspaces::handleFullscreenBeforeRaise(wo); Workspaces::insert(wo, true); } if (! pekwm::isStarting()) { // Skip updating client list while starting, it will be done // once after all windows hae been scanned Workspaces::updateClientList(); } // Make sure the window is mapped, this is done after it has been // added to the decor/frame as otherwise IsViewable state won't // be correct and we don't know whether or not to place the window if (initConfig.map) { client->mapWindow(); } // Focus was requested by the configuration, look out for // focus stealing. if (initConfig.focus) { PWinObj *wo = PWinObj::getFocusedPWinObj(); Config *cfg = pekwm::config(); Time time_protect = static_cast