diff options
author | Niraj Modi | 2018-08-14 05:30:27 +0000 |
---|---|---|
committer | Niraj Modi | 2018-08-14 11:20:07 +0000 |
commit | 504c1f01f5fd7ad629d4d8642615b94b82d09857 (patch) | |
tree | b559e30ce374a902de11b359da5649c9a2ec7c03 | |
parent | b2cc595001b5dd056392e50a7db32df73516d8e4 (diff) | |
download | eclipse.platform.swt-504c1f01f5fd7ad629d4d8642615b94b82d09857.tar.gz eclipse.platform.swt-504c1f01f5fd7ad629d4d8642615b94b82d09857.tar.xz eclipse.platform.swt-504c1f01f5fd7ad629d4d8642615b94b82d09857.zip |
Bug 515502 - [HiDPI][Win10] SWT to receive/handle DPI changeI20180814-0900
notification from OS
Change-Id: Ic0b851b76cbd5b270f4d4337de6ac6f2fb81812c
Signed-off-by: Niraj Modi <niraj.modi@in.ibm.com>
5 files changed, 313 insertions, 3 deletions
diff --git a/bundles/org.eclipse.swt/.settings/.api_filters b/bundles/org.eclipse.swt/.settings/.api_filters index bcc9c37500..2b7877280c 100644 --- a/bundles/org.eclipse.swt/.settings/.api_filters +++ b/bundles/org.eclipse.swt/.settings/.api_filters @@ -1227,6 +1227,12 @@ <message_argument value="OpenUrl"/> </message_arguments> </filter> + <filter id="336658481"> + <message_arguments> + <message_argument value="org.eclipse.swt.SWT"/> + <message_argument value="ZoomChanged"/> + </message_arguments> + </filter> <filter comment="@since 3.8 is valid in the 3.100 stream" id="1141899266"> <message_arguments> <message_argument value="3.8"/> diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java index a7c4c48119..a9de9f7239 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -1885,6 +1885,7 @@ public class OS extends C { public static final int WM_CUT = 0x300; public static final int WM_DEADCHAR = 0x103; public static final int WM_DESTROY = 0x2; + public static final int WM_DPICHANGED = 0x02E0; public static final int WM_DRAWITEM = 0x2b; public static final int WM_ENDSESSION = 0x16; public static final int WM_ENTERIDLE = 0x121; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java index ea709c0fb6..bec63ae242 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -856,6 +856,26 @@ public class SWT { */ public static final int OpenUrl = 54; + /** + * The SWT zoom change event type (value is 55). + * + * <p> + * This event is sent on <code>Shell</code> when the SWT zoom has changed. SWT + * zoom changes when the system DPI or scale factor changes dynamically. + * </p> + * <p> + * Note: This operation is a hint and is not supported on platforms that do not + * have this concept. Currently supported on Windows10 only. + * </p> + * + * @see org.eclipse.swt.widgets.Widget#addListener + * @see org.eclipse.swt.widgets.Display#addFilter + * @see org.eclipse.swt.widgets.Event + * + * @since 3.108 + */ + public static final int ZoomChanged = 55; + /* Event Details */ /** diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java index e4e50d9bc5..a759761064 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -4855,6 +4855,7 @@ long /*int*/ windowProc (long /*int*/ hwnd, int msg, long /*int*/ wParam, long / case OS.WM_XBUTTONDBLCLK: result = WM_XBUTTONDBLCLK (wParam, lParam); break; case OS.WM_XBUTTONDOWN: result = WM_XBUTTONDOWN (wParam, lParam); break; case OS.WM_XBUTTONUP: result = WM_XBUTTONUP (wParam, lParam); break; + case OS.WM_DPICHANGED: result = WM_DPICHANGED (wParam, lParam); break; } if (result != null) return result.value; // widget could be disposed at this point @@ -4937,6 +4938,25 @@ LRESULT WM_DESTROY (long /*int*/ wParam, long /*int*/ lParam) { return null; } +LRESULT WM_DPICHANGED (long /*int*/ wParam, long /*int*/ lParam) { + // Map DPI to Zoom and compare + int nativeZoom = DPIUtil.mapDPIToZoom (OS.HIWORD (wParam)); + int newSWTZoom = DPIUtil.getZoomForAutoscaleProperty (nativeZoom); + int oldSWTZoom = DPIUtil.getDeviceZoom(); + + // Throw the DPI change event if zoom value changes + if (newSWTZoom != oldSWTZoom) { + Event event = new Event(); + event.type = SWT.ZoomChanged; + event.widget = this; + event.detail = newSWTZoom; + event.doit = true; + notifyListeners(SWT.ZoomChanged, event); + return LRESULT.ZERO; + } + return LRESULT.ONE; +} + LRESULT WM_DRAWITEM (long /*int*/ wParam, long /*int*/ lParam) { DRAWITEMSTRUCT struct = new DRAWITEMSTRUCT (); OS.MoveMemory (struct, lParam, DRAWITEMSTRUCT.sizeof); diff --git a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet373.java b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet373.java new file mode 100644 index 0000000000..718ede0d6d --- /dev/null +++ b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet373.java @@ -0,0 +1,263 @@ +package org.eclipse.swt.snippets; + +/******************************************************************************* + * Copyright (c) 2018 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +import org.eclipse.swt.*; +import org.eclipse.swt.custom.*; +import org.eclipse.swt.events.*; +/* + * Snippet to display/refresh Monitor DPI dynamically if supported by OS. + * + * For a list of all SWT example snippets see + * http://www.eclipse.org/swt/snippets/ + * + * @since 3.0 + */ +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.layout.*; +import org.eclipse.swt.widgets.*; + +/** + * Dynamic DPI with restart example snippet Display current monitors zoom + * + * For a list of all SWT example snippets see + * http://www.eclipse.org/swt/snippets/ + */ +public class Snippet373 { + private static final String IMAGE_100 = "eclipse16.png"; + private static final String IMAGE_150 = "eclipse24.png"; + private static final String IMAGE_200 = "eclipse32.png"; + + private static final String IMAGES_ROOT = "bin/org/eclipse/swt/snippets/"; + + private static final String IMAGE_PATH_100 = IMAGES_ROOT + IMAGE_100; + private static final String IMAGE_PATH_150 = IMAGES_ROOT + IMAGE_150; + private static final String IMAGE_PATH_200 = IMAGES_ROOT + IMAGE_200; + static final ImageFileNameProvider filenameProvider = zoom -> { + String path = null; + switch (zoom) { + case 150: + path = IMAGE_PATH_150; + break; + case 200: + path = IMAGE_PATH_200; + break; + default: + path = IMAGE_PATH_100; + } + return path; + }; + + public static void main(String[] args) { + System.setProperty("swt.autoScale", "quarter"); + Display display = new Display(); + final Image eclipse = new Image(display, filenameProvider); + final Image eclipseToolBar1 = new Image(display, filenameProvider); + final Image eclipseToolBar2 = new Image(display, filenameProvider); + final Image eclipseTableHeader = new Image(display, filenameProvider); + final Image eclipseTableItem = new Image(display, filenameProvider); + final Image eclipseTree1 = new Image(display, filenameProvider); + final Image eclipseTree2 = new Image(display, filenameProvider); + final Image eclipseCTab1 = new Image(display, filenameProvider); + final Image eclipseCTab2 = new Image(display, filenameProvider); + + Shell shell = new Shell(display); + shell.setImage(eclipse); + shell.setText("DynamicDPI @ " + DPIUtil.getDeviceZoom()); + shell.setLayout(new RowLayout(SWT.VERTICAL)); + shell.setLocation(100, 100); + shell.setSize(500, 600); + shell.addListener(SWT.ZoomChanged, new Listener() { + @Override + public void handleEvent(Event e) { + if (display.getPrimaryMonitor().equals(shell.getMonitor())) { + MessageBox box = new MessageBox(shell, SWT.PRIMARY_MODAL | SWT.OK | SWT.CANCEL); + box.setText(shell.getText()); + box.setMessage("DPI changed, do you want to exit & restart ?"); + e.doit = (box.open() == SWT.OK); + if (e.doit) { + shell.close(); + System.out.println("Program exit."); + } + } + } + }); + + // Menu + Menu bar = new Menu(shell, SWT.BAR); + shell.setMenuBar(bar); + MenuItem fileItem = new MenuItem(bar, SWT.CASCADE); + fileItem.setText("&File"); + fileItem.setImage(eclipse); + Menu submenu = new Menu(shell, SWT.DROP_DOWN); + fileItem.setMenu(submenu); + MenuItem subItem = new MenuItem(submenu, SWT.PUSH); + subItem.addListener(SWT.Selection, e -> System.out.println("Select All")); + subItem.setText("Select &All\tCtrl+A"); + subItem.setAccelerator(SWT.MOD1 + 'A'); + subItem.setImage(eclipse); + + // CTabFolder + CTabFolder folder = new CTabFolder(shell, SWT.BORDER); + for (int i = 0; i < 2; i++) { + CTabItem cTabItem = new CTabItem(folder, i % 2 == 0 ? SWT.CLOSE : SWT.NONE); + cTabItem.setText("Item " + i); + Text textMsg = new Text(folder, SWT.MULTI); + textMsg.setText("Content for Item " + i); + cTabItem.setControl(textMsg); + cTabItem.setImage((i % 2 == 1) ? eclipseCTab1 : eclipseCTab2); + } + + // PerMonitorV2 setting +// Label label = new Label (shell, SWT.BORDER); +// label.setText("PerMonitorV2 value before:after:Error"); +// Text text = new Text(shell, SWT.BORDER); +// text.setText(DPIUtil.BEFORE + ":" + DPIUtil.AFTER + ":" + DPIUtil.RESULT); + + // Composite for Label, Button, Tool-bar + Composite composite = new Composite(shell, SWT.BORDER); + composite.setLayout(new RowLayout(SWT.HORIZONTAL)); + + // Label with Image + Label label1 = new Label(composite, SWT.BORDER); + label1.setImage(eclipse); + + // Label with text only + Label label2 = new Label(composite, SWT.BORDER); + label2.setText("No Image"); + + // Button with text + Old Image Constructor + Button oldButton1 = new Button(composite, SWT.PUSH); + oldButton1.setText("Old Img"); + oldButton1.setImage(new Image(display, IMAGE_PATH_100)); + + // Button with Old Image Constructor +// Button oldButton2 = new Button(composite, SWT.PUSH); +// oldButton2.setImage(new Image(display, filenameProvider.getImagePath(100))); + + // Button with Image + Button createDialog = new Button(composite, SWT.PUSH); + createDialog.setText("Child Dialog"); + createDialog.setImage(eclipse); + createDialog.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent event) { + final Shell dialog = new Shell(shell, SWT.DIALOG_TRIM | SWT.RESIZE); + dialog.setText("Child Dialog"); + RowLayout rowLayout = new RowLayout(SWT.VERTICAL); + dialog.setLayout(rowLayout); + Label label = new Label(dialog, SWT.BORDER); + label.setImage(eclipse); + Point location = shell.getLocation(); + dialog.setLocation(location.x + 250, location.y + 50); + dialog.pack(); + dialog.open(); + } + }); + + // Toolbar with Image + ToolBar toolBar = new ToolBar(composite, SWT.FLAT | SWT.BORDER); + Rectangle clientArea = shell.getClientArea(); + toolBar.setLocation(clientArea.x, clientArea.y); + for (int i = 0; i < 2; i++) { + int style = i % 2 == 1 ? SWT.DROP_DOWN : SWT.PUSH; + ToolItem toolItem = new ToolItem(toolBar, style); + toolItem.setImage((i % 2 == 0) ? eclipseToolBar1 : eclipseToolBar2); + toolItem.setEnabled(i % 2 == 0); + } + toolBar.pack(); + + Button button = new Button(shell, SWT.PUSH); + button.setText("Refresh-Current Monitor : Zoom"); + Text text1 = new Text(shell, SWT.BORDER); + Monitor monitor = button.getMonitor(); + text1.setText("" + monitor.getZoom()); + button.addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + Monitor monitor = button.getMonitor(); + text1.setText("" + monitor.getZoom()); + } + }); + Button button2 = new Button(shell, SWT.PUSH); + button2.setText("Refresh-Both Monitors : Zoom"); + Text text2 = new Text(shell, SWT.BORDER); + Monitor[] monitors = display.getMonitors(); + StringBuffer text2String = new StringBuffer(); + for (int i = 0; i < monitors.length; i++) { + text2String.append(monitors[i].getZoom() + (i < (monitors.length - 1) ? " - " : "")); + } + text2.setText(text2String.toString()); + button2.addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + Monitor[] monitors = display.getMonitors(); + StringBuffer text2String = new StringBuffer(); + for (int i = 0; i < monitors.length; i++) { + text2String.append(monitors[i].getZoom() + (i < (monitors.length - 1) ? " - " : "")); + } + text2.setText(text2String.toString()); + } + }); + + // Table + Table table = new Table(shell, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION); + table.setLinesVisible(true); + table.setHeaderVisible(true); + String titles[] = { "Title 1" }; + for (int i = 0; i < titles.length; i++) { + TableColumn column = new TableColumn(table, SWT.NONE); + column.setText(titles[i]); + column.setImage(eclipseTableHeader); + } + for (int i = 0; i < 1; i++) { + TableItem item = new TableItem(table, SWT.NONE); + item.setText(0, "Data " + i); + item.setImage(0, eclipseTableItem); + } + for (int i = 0; i < titles.length; i++) { + table.getColumn(i).pack(); + } + + // Tree + final Tree tree = new Tree(shell, SWT.BORDER); + for (int i = 0; i < 1; i++) { + TreeItem iItem = new TreeItem(tree, 0); + iItem.setText("TreeItem (0) -" + i); + iItem.setImage(eclipseTree1); + TreeItem jItem = null; + for (int j = 0; j < 1; j++) { + jItem = new TreeItem(iItem, 0); + jItem.setText("TreeItem (1) -" + j); + jItem.setImage(eclipseTree2); + jItem.setExpanded(true); + } + tree.select(jItem); + } + + // Shell Location + Monitor primary = display.getPrimaryMonitor(); + Rectangle bounds = primary.getBounds(); + Rectangle rect = shell.getBounds(); + int x = bounds.x + (bounds.width - rect.width) / 2; + int y = bounds.y + (bounds.height - rect.height) / 2; + shell.setLocation(x, y); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + display.dispose(); + } +} |