diff --git a/Makefile b/Makefile index e9fc71f..81417a0 100644 --- a/Makefile +++ b/Makefile @@ -8,23 +8,32 @@ # -convert test target to a shell script # -figure out of lipo is the best way to make a universal binary on cmdline -PREFIX=/usr/local +PREFIX=/usr +IDENTIFIER=net.alkalay.screenresolution ORIG_RES=1920x1200x32 TEST_RES=800x600x32 -VERSION=1.7dev +VERSION=2.2 CC=clang PACKAGE_BUILD=/usr/bin/pkgbuild ARCH_FLAGS=-arch i386 -arch x86_64 .PHONY: build -build: screenresolution +build: screenresolution SwitchResolution.app screenresolution: main.o cg_utils.o $(CC) $(CPPFLAGS) $(CFLAGS) $(ARCH_FLAGS) -framework Foundation -framework ApplicationServices $^ -o $@ +%.icns: %.png + sips -s format icns $< --out $@ + +SwitchResolution.app: SwitchResolution.applescript resolution.icns + osacompile -o $@ $< + mv resolution.icns $@/Contents/Resources/applet.icns + + %.o: %.c version.h $(CC) $(CPPFLAGS) $(CFLAGS) $(ARCH_FLAGS) $< -c -o $@ @@ -34,7 +43,9 @@ version.h: clean: rm -f screenresolution *.o \ screenresolution-$(VERSION).pkg screenresolution-$(VERSION).dmg \ - version.h + version.h \ + resolution.icns + rm -rf SwitchResolution.app rm -rf pkgroot dmgroot reallyclean: clean @@ -73,11 +84,13 @@ install: screenresolution install -s -m 0755 screenresolution \ $(DESTDIR)/$(PREFIX)/bin/ -pkg: screenresolution +pkg: screenresolution SwitchResolution.app mkdir -p pkgroot/$(PREFIX)/bin + mkdir -p pkgroot/Applications install -s -m 0755 screenresolution \ pkgroot/$(PREFIX)/bin - $(PACKAGE_BUILD) --root pkgroot/ --identifier com.johnhford.screenresolution \ + mv SwitchResolution.app pkgroot/Applications/ + $(PACKAGE_BUILD) --root pkgroot/ --identifier $(IDENTIFIER) \ --version $(VERSION) "screenresolution-$(VERSION).pkg" rm -f screenresolution.pkg ln -s screenresolution-$(VERSION).pkg screenresolution.pkg diff --git a/README b/README.md similarity index 51% rename from README rename to README.md index f4735e8..98a9017 100644 --- a/README +++ b/README.md @@ -1,47 +1,35 @@ -This is a tool that can be used to determine current resolution, -list available resolutions and set resolutions for active displays -on Mac OS 10.6, and possibly above. I have only tested 10.6. +# This software is now obsolete -I used clang for development, but the code seems to compile -just fine with gcc. The code might not be as well layed out -as it could be, feel free to send a pull request. +It doesn't know how to handle HiDPI resolutions and the GUI is limited. +[RDM](https://github.com/avibrazil/RDM) is a better and more advanced solutions. -Build+Install -==================== -Running the following commands in Terminal.app will result in -dmg with a pkg file being created if the system has Xcode 4. - - git clone github.com:jhford/screenresolution - cd screenresolution - make dmg +This is a set of tools (GUI and command line) that let you use MacBook Pro Retina's +highest and unsupported resolutions. As an example, a Retina MacBook Pro 13" can be set +to 2560×1600 maximum resolution, as opposed to Apple's max supported 1650×1050. -At this point, I'd recommend testing that things work! I have -written a 'test' makefile target. Because this script expects two -monitors that both use the same resolution, it mightn't work -properly for you if you only have one +![chose resolution](https://cloud.githubusercontent.com/assets/3484242/7044411/8c3d8532-ddc9-11e4-85fc-5301aee68b40.png) - make test ORIG_RES=1920x1200x32 +The SwitchResolution GUI app will show you the 3 highest resolutions to chose. While +the screenresolution command lets you list available resolutions get current and set a +new one. They were all tested on Yosemite. -This will cause your screen to flicker as it changes the mode a -couple times on each monitor. +The screenresolution command was developed in C, while the SwitchResolution app is a +very simple AppleScript compiled into an app. -The makefiles support the DESTDIR (alternate root) and PREFIX -variables. If you don't know what those are, you probably don't -want them. +MacBook Pro Retina machines always use the maximum hardware resolution. The screen +resolution manipulated by this tools is what is actually presented to apps. This way text, +widgets, menus and screen real estate are increased an decreased for optimal use. -This will create a DMG file and a PKG file. If you know or care -about the differences, you probably know what to do at this point. -If you want to install this program on the system you built it on, -you can run - - open screenresolution.pkg +Fast change resolution with SwitchResolution +============================================ -If you want to put this program on another system, you can choose -between the pkg file, the dmg file, the binaries or use the -install make target with DESTDIR to specify an alternate root. +The SwitchResolution app purpose is to give fast one-click access to highest resolutions. +Best way to use it is to fix it on your dock because you will find that different +resolutions fit better for different kinds of work. You will prefer highest resolutions +when working with many windows and lower resolutions when simply reading text. -Running -==================== +Running the command line tool +============================= There are three commands that this program supports: get, list and set. All three modes operate on active displays [1]. @@ -70,26 +58,59 @@ This keyword will cause the first display to be skipped. If you specify more resolutions than you have active screens, the extra resolutions will be ignored. -Example 1: - This example works with one or more screens +This example works with one or more screens + $ screenresolution set 800x600x32 -Result 1: - The main display will change to 800x600x32, second screen - will not be changed -Example 2: - This example assumes two screens +Result: the main display will change to 800x600x32, second screen will not be changed + +This example assumes two screens + $ screenresolution set 800x600x32 800x600x32 -Result 2: - The first and second monitor on the system will be set to - 800x600x32 -Example 3: - This example assumes two screens +Result: The first and second monitor on the system will be set to 800x600x32 + +This example assumes two screens + $ screen resolution set skip 800x600x32 - This will not touch the first screen but will set the second - screen to 800x600x32 +This will not touch the first screen but will set the second screen to 800x600x32 + +Build+Install +==================== +Running the following commands will result in +dmg with a pkg file being created if the system has Xcode 4. + + git clone github.com:avibrazil/screenresolution + cd screenresolution + make dmg + +or, change the last command to a more economical + + make pkg + +At this point, I'd recommend testing that things work! I have +written a 'test' makefile target. Because this script expects two +monitors that both use the same resolution, it mightn't work +properly for you if you only have one + + make test ORIG_RES=1920x1200x32 + +This will cause your screen to flicker as it changes the mode a +couple times on each monitor. + +The makefiles support the DESTDIR (alternate root) and PREFIX +variables. If you don't know what those are, you probably don't +want them. + +This will create a DMG file and a PKG file. If you know or care +about the differences, you probably know what to do at this point. +If you want to install this program on the system you built it on, +you can run + + open screenresolution.pkg + +Or simply double click on the PKG file to install it on your system. [1]See discussion point for explanation of what active display means. http://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/Quartz_Services_Ref/Reference/reference.html#//apple_ref/c/func/CGGetActiveDisplayList diff --git a/SwitchResolution.applescript b/SwitchResolution.applescript new file mode 100644 index 0000000..1582ecc --- /dev/null +++ b/SwitchResolution.applescript @@ -0,0 +1,37 @@ +-- Simple dialog that asks for some MacBook Pro Retina 13" resolutions and sets the display size + +-- Avi Alkalay +-- Mar 2015 +-- São Paulo, Brazil + +set ScreenResolutionCommand to "/usr/bin/screenresolution" + +set AppleScript's text item delimiters to "|" +set res to text items of (do shell script ScreenResolutionCommand & " list 2>/dev/null | grep x | sed -e 's/x /x/g' | xargs echo | tr ' ' '\n' | sort -run | head -3 | perl -e '$i=0; while (<>) {$i++; chop; m^(.*)x(.*)x(.*)^; print \"|\" if ($i>1); print \"$1×$2^$_\"};'") + +set AppleScript's text item delimiters to "^" +set resolutions to {} +repeat with i in res + set r to text items of i + set end of resolutions to r +end repeat + +set names to {} +repeat with i in resolutions + set thename to item 1 of i + set end of names to thename +end repeat + +-- choose from list names with prompt "Choose from the list." + +display dialog "Chose Resolution" buttons names + +set the button_pressed to the button returned of the result + +repeat with i in resolutions + set thename to item 1 of i + set theresolution to item 2 of i + if the button_pressed is thename then + do shell script ScreenResolutionCommand & " set " & theresolution + end if +end repeat \ No newline at end of file diff --git a/main.c b/main.c index 339dd42..2615463 100644 --- a/main.c +++ b/main.c @@ -164,11 +164,13 @@ unsigned int listAvailableModes(CGDirectDisplayID display, int displayNum) { CGDisplayModeRef mode; - int modesPerColumn = numModes / MODES_PER_LINE; + int lastRowNum = (numModes - 1) / MODES_PER_LINE; + int lastRowColumnSize = numModes % MODES_PER_LINE; for (i = 0; (i < numModes) && returncode; i++) { - int rowNumber = (i / MODES_PER_LINE); - int idxDisplayMode = (i % MODES_PER_LINE) * modesPerColumn + rowNumber; + int rowNumber = i / MODES_PER_LINE; + int columnNumber = i % MODES_PER_LINE; + int idxDisplayMode = columnNumber * lastRowNum + MIN(lastRowColumnSize, columnNumber) + rowNumber; // if there are an even number of display modes to display, // the last mode must have it's index decremented by 1 diff --git a/resolution.png b/resolution.png new file mode 100644 index 0000000..da1bc0f Binary files /dev/null and b/resolution.png differ