diff --git a/src/main/java/net/betterthanadventure/utils/ColorizerGenerator.java b/src/main/java/net/betterthanadventure/utils/ColorizerGenerator.java
index 6eda87c4a..801b6ca02 100644
--- a/src/main/java/net/betterthanadventure/utils/ColorizerGenerator.java
+++ b/src/main/java/net/betterthanadventure/utils/ColorizerGenerator.java
@@ -1,114 +1,117 @@
 package net.betterthanadventure.utils;
-import net.minecraft.core.util.helper.Color;
-import org.lwjgl.opengl.Display;
-import org.lwjgl.opengl.DisplayMode;
-import org.lwjgl.opengl.PixelFormat;
 
+import static org.lwjgl.glfw.GLFW.*;
 import static org.lwjgl.opengl.GL11.*;
 
+import org.lwjgl.opengl.GL;
+
+import net.minecraft.core.util.helper.Color;
+
 public class ColorizerGenerator {
 
-    // Desert = 0.749, 0.718, 0.333
-    // Cold = 0.502, 0.706, 0.592
-    // Midpoint = 0.486, 0.741, 0.42
-    // Temperate = 0.278, 0.804, 0.2
-
-    private static float getFloatColor(int color){
-        return (float) color / 255F;
-    }
-    // Summer
-//        static int colorColdI = 0x80b497;
-//        static int colorMidI = 0x7cbd6b;
-//        static int colorTemperateI = 0x47cd33;
-//        static int colorDryI = 0xbfb755;
-
-    //Fall
-//        static int colorColdI = 0x85b088;
-//        static int colorMidI = 0xafbb5d;
-//        static int colorTemperateI = 0x8bc540;
-//        static int colorDryI = 0xbfb755;
-
-    // Winter
-//    static int colorColdI = 0x93b5ac;
-//    static int colorMidI = 0x81b496;
-//    static int colorTemperateI = 0xb0aa72;
-//    static int colorDryI = 0x8cc047;
-
-    static int colorColdI = 0x85be9e;
-    static int colorMidI = 0x82c96f;
-    static int colorTemperateI = 0x4bde36;
-    static int colorDryI = 0x8cc047;
-
-    static Color colorCold = new Color().setARGB(colorColdI);
-    static Color colorMid = new Color().setARGB(colorMidI);
-    static Color colorTemperate = new Color().setARGB(colorTemperateI);
-    static Color colorDry = new Color().setARGB(colorDryI);
-    private static void drawVertex(Color color){
-        glColor3d(getFloatColor(color.getRed()), getFloatColor(color.getGreen()), getFloatColor(color.getBlue()));
-    }
-    public static void main(String[] args) throws Exception {
-        Display.setDisplayMode(new DisplayMode(257, 257));
-        Display.setTitle("Gradient");
-        Display.create(new PixelFormat());
-        Display.setVSyncEnabled(true);
-
-
-
-        while(!Display.isCloseRequested()) {
-            glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
-            glClear(GL_COLOR_BUFFER_BIT);
-            glLoadIdentity();
-            glOrtho(0, 1, 0, 1, -1, 1);
-
-            System.out.println(colorCold.getRed());
-
-            // Originals
-//            glBegin(GL_TRIANGLES);
+	// Desert = 0.749, 0.718, 0.333
+	// Cold = 0.502, 0.706, 0.592
+	// Midpoint = 0.486, 0.741, 0.42
+	// Temperate = 0.278, 0.804, 0.2
+
+	private static float getFloatColor(int color) {
+		return color / 255.0f;
+	}
+
+	// Summer
+//	static int colorColdI = 0x80b497;
+//	static int colorMidI = 0x7cbd6b;
+//	static int colorTemperateI = 0x47cd33;
+//	static int colorDryI = 0xbfb755;
+
+	// Fall
+//	static int colorColdI = 0x85b088;
+//	static int colorMidI = 0xafbb5d;
+//	static int colorTemperateI = 0x8bc540;
+//	static int colorDryI = 0xbfb755;
+
+	// Winter
+//	static int colorColdI = 0x93b5ac;
+//	static int colorMidI = 0x81b496;
+//	static int colorTemperateI = 0xb0aa72;
+//	static int colorDryI = 0x8cc047;
+
+	static int colorColdI = 0x85be9e;
+	static int colorMidI = 0x82c96f;
+	static int colorTemperateI = 0x4bde36;
+	static int colorDryI = 0x8cc047;
+
+	static Color colorCold = new Color().setARGB(colorColdI);
+	static Color colorMid = new Color().setARGB(colorMidI);
+	static Color colorTemperate = new Color().setARGB(colorTemperateI);
+	static Color colorDry = new Color().setARGB(colorDryI);
+
+	private static void drawVertex(Color color) {
+		glColor3d(getFloatColor(color.getRed()), getFloatColor(color.getGreen()), getFloatColor(color.getBlue()));
+	}
+
+	public static void main(String[] args) throws Exception {
+		glfwInit();
+
+		long windowHandle = glfwCreateWindow(257, 257, "Gradient", 0, 0);
+
+		glfwMakeContextCurrent(windowHandle);
+		GL.createCapabilities();
+
+		while(!glfwWindowShouldClose(windowHandle)) {
+			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+			glClear(GL_COLOR_BUFFER_BIT);
+			glLoadIdentity();
+			glOrtho(0, 1, 0, 1, -1, 1);
+
+			// Originals
+//			glBegin(GL_TRIANGLES);
 //
-//            glColor3d(0.749, 0.718, 0.333);
-//            glVertex2d(0.0, 0.0);
+//			glColor3d(0.749, 0.718, 0.333);
+//			glVertex2d(0.0, 0.0);
 //
-//            glColor3d(0.278, 0.804, 0.2);
-//            glVertex2d(0.0, 1.0);
+//			glColor3d(0.278, 0.804, 0.2);
+//			glVertex2d(0.0, 1.0);
 //
-//            glColor3d(0.486, 0.741, 0.42);
-//            glVertex2d(0.5, 0.5);
-//            glColor3d(0.749, 0.718, 0.333);
-//            glVertex2d(0.0, 0.0);
+//			glColor3d(0.486, 0.741, 0.42);
+//			glVertex2d(0.5, 0.5);
+//			glColor3d(0.749, 0.718, 0.333);
+//			glVertex2d(0.0, 0.0);
 //
-//            glColor3d(0.486, 0.741, 0.42);
-//            glVertex2d(0.5, 0.5);
+//			glColor3d(0.486, 0.741, 0.42);
+//			glVertex2d(0.5, 0.5);
 //
-//            glColor3d(0.502, 0.706, 0.592);
-//            glVertex2d(1.0, 0.0);
+//			glColor3d(0.502, 0.706, 0.592);
+//			glVertex2d(1.0, 0.0);
 //
-//            glEnd();
+//			glEnd();
 
-            glBegin(GL_TRIANGLES);
+			glBegin(GL_TRIANGLES);
 
-            // tri 1
-            drawVertex(colorDry);
-            glVertex2d(0.0, 0.0);
+			// tri 1
+			drawVertex(colorDry);
+			glVertex2d(0.0, 0.0);
 
-            drawVertex(colorTemperate);
-            glVertex2d(0.0, 1.0);
+			drawVertex(colorTemperate);
+			glVertex2d(0.0, 1.0);
 
-            drawVertex(colorMid);
-            glVertex2d(0.5, 0.5);
+			drawVertex(colorMid);
+			glVertex2d(0.5, 0.5);
 
-            // tri 2
-            drawVertex(colorDry);
-            glVertex2d(0.0, 0.0);
+			// tri 2
+			drawVertex(colorDry);
+			glVertex2d(0.0, 0.0);
 
-            drawVertex(colorMid);
-            glVertex2d(0.5, 0.5);
+			drawVertex(colorMid);
+			glVertex2d(0.5, 0.5);
 
-            drawVertex(colorCold);
-            glVertex2d(1.0, 0.0);
+			drawVertex(colorCold);
+			glVertex2d(1.0, 0.0);
 
-            glEnd();
+			glEnd();
 
-            Display.update();
-        }
-    }
+			glfwPollEvents();
+			glfwSwapBuffers(windowHandle);
+		}
+	}
 }
diff --git a/src/main/java/net/minecraft/client/FullscreenHelper.java b/src/main/java/net/minecraft/client/FullscreenHelper.java
deleted file mode 100644
index 876891f62..000000000
--- a/src/main/java/net/minecraft/client/FullscreenHelper.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package net.minecraft.client;
-
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
-import java.awt.Rectangle;
-
-import org.lwjgl.LWJGLException;
-import org.lwjgl.opengl.Display;
-import org.lwjgl.opengl.DisplayMode;
-
-import net.minecraft.core.enums.EnumOS;
-
-public class FullscreenHelper {
-	
-	private final Minecraft mc;
-	
-	private int previousX = 0;
-	private int previousY = 0;
-	
-	private int previousWidth = 0;
-	private int previousHeight = 0;
-	
-	private boolean isBorderless;
-	private boolean isFullscreen;
-	
-	public FullscreenHelper(Minecraft minecraft) {
-		this.mc = minecraft;
-	}
-
-	public void toggleFullscreen() {
-		mc.gameSettings.fullscreen.toggle();
-		updateWindowState();
-	}
-	
-	public void updateWindowState() {
-		try {
-			update();
-			
-			mc.resize();
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-	
-	private void update() throws Exception {
-		boolean fullscreen = mc.gameSettings.fullscreen.value;
-		boolean borderless = mc.gameSettings.borderlessFullscreen.value;
-		DisplayMode resolution = null;
-		
-		if(!isFullscreen) {
-			previousWidth = Display.getWidth();
-			previousHeight = Display.getHeight();
-			
-			previousX = Display.getX();
-			previousY = Display.getY();
-		}
-		
-		if(fullscreen) {
-			if(resolution == null && borderless) {
-				if(Display.isFullscreen()) {
-					Display.setFullscreen(false);
-				}
-				
-				if(!isBorderless) {
-					setBorderless(true);
-					isBorderless = true;
-				}
-
-				Rectangle rectangle = getDisplay();
-				System.out.println("Set Borderless Fullscreen: " + rectangle.getWidth() + " x " + rectangle.getHeight());
-				setPositionAndSize(rectangle);
-			}else {
-				if(resolution == null) {
-					resolution = Display.getDesktopDisplayMode();
-				}
-				
-				System.out.println("Set Fullscreen: " + resolution.getWidth() + " x " + resolution.getHeight());
-				Display.setDisplayModeAndFullscreen(resolution);
-			}
-			
-			isFullscreen = true;
-			return;
-		}else {
-			if(!isFullscreen) {
-				return;
-			}
-			
-			if(isBorderless) {
-				setBorderless(false);
-				isBorderless = false;
-			}
-			
-			if(Display.isFullscreen()) {
-				Display.setFullscreen(false);
-			}
-			
-			setPositionAndSize(previousX, previousY, previousWidth, previousHeight);
-			setResizable();
-			
-			isFullscreen = false;
-			return;
-		}
-	}
-	
-	public void setPositionAndSize(Rectangle rectangle) throws LWJGLException {
-		setSize((int) rectangle.getWidth(), (int) rectangle.getHeight());
-		setPosition((int) rectangle.getX(), (int) rectangle.getY());
-	}
-	
-	public void setPositionAndSize(int x, int y, int w, int h) throws LWJGLException {
-		setSize(w, h);
-		setPosition(x, y);
-	}
-	
-	public void setSize(int width, int height) throws LWJGLException {
-		Display.setDisplayMode(new DisplayMode(width, height));
-	}
-	
-	public void setPosition(int x, int y) {
-		Display.setLocation(x, y);
-	}
-	
-	public void setResizable() {
-		// Crashes on Mac OS, but its resizable anyway?
-		if(Minecraft.getOs() != EnumOS.macos && !mc.gameSettings.disableResize.value) {
-			//Set it to false first because of a bug in LWJGL
-			Display.setResizable(false);
-			Display.setResizable(true);
-		}
-	}
-	
-	public Rectangle getDisplay() {
-		int centerX = Display.getX() + Display.getWidth() / 2;
-		int centerY = Display.getY() + Display.getHeight() / 2;
-		
-		return getDisplayAt(centerX, centerY);
-	}
-	
-	public Rectangle getDisplayAt(int x, int y) {
-		try {
-			GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
-			for(GraphicsDevice device : devices) {
-				Rectangle rect = device.getDefaultConfiguration().getBounds();
-				if(rect.contains(x, y)) {
-					return rect;
-				}
-			}
-			return null;
-		}catch (Exception e) {
-			e.printStackTrace();
-			DisplayMode displayMode = Display.getDesktopDisplayMode();
-			
-			return new Rectangle(0, 0, displayMode.getWidth(), displayMode.getHeight());
-		}
-	}
-	
-	public void setBorderless(boolean b) {
-		System.setProperty("org.lwjgl.opengl.Window.undecorated", String.valueOf(b));
-	}
-	
-}
diff --git a/src/main/java/net/minecraft/client/GameResolution.java b/src/main/java/net/minecraft/client/GameResolution.java
index a2641ae0d..85b24e0b4 100644
--- a/src/main/java/net/minecraft/client/GameResolution.java
+++ b/src/main/java/net/minecraft/client/GameResolution.java
@@ -2,10 +2,6 @@ package net.minecraft.client;
 
 import static java.lang.Math.*;
 
-import org.lwjgl.opengl.Display;
-
-import net.minecraft.client.Minecraft;
-
 public class GameResolution {
 	
 	public static int defaultWidth = 854;
@@ -33,8 +29,8 @@ public class GameResolution {
 	}
 	
 	public void update() {
-		this.width = Display.getWidth();
-		this.height = Display.getHeight();
+		this.width = minecraft.gameWindow.getWidth();
+		this.height = minecraft.gameWindow.getHeight();
 		
 		setSize(width, height);
 		
diff --git a/src/main/java/net/minecraft/client/Minecraft.java b/src/main/java/net/minecraft/client/Minecraft.java
index b8ad20dc3..20c495e07 100644
--- a/src/main/java/net/minecraft/client/Minecraft.java
+++ b/src/main/java/net/minecraft/client/Minecraft.java
@@ -1,31 +1,34 @@
 package net.minecraft.client;
 
-import java.awt.*;
+import static net.minecraft.core.Global.*;
+import static org.lwjgl.opengl.GL11.*;
+
+import java.awt.Cursor;
+import java.awt.Desktop;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.io.File;
 import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
 import java.util.ArrayList;
-import java.util.List;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Random;
 
-import com.mojang.nbt.CompoundTag;
-import net.minecraft.client.entity.ClientSkinVariantList;
-import net.minecraft.client.gui.toasts.GuiHudToasts;
-import net.minecraft.client.option.enums.Difficulty;
-import net.minecraft.core.achievement.Achievements;
-import net.minecraft.core.world.SpawnerMobs;
-import net.minecraft.core.world.save.*;
-import net.minecraft.core.world.type.WorldType;
-import net.minecraft.core.world.type.WorldTypeGroups;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+
 import org.lwjgl.LWJGLException;
-import org.lwjgl.Version;
 import org.lwjgl.input.Keyboard;
 import org.lwjgl.input.Mouse;
 import org.lwjgl.opengl.Display;
+import org.lwjgl.opengl.GL11;
+
+import com.mojang.nbt.CompoundTag;
+
 import net.minecraft.client.discord.RichPresenceHandlerThread;
+import net.minecraft.client.entity.ClientSkinVariantList;
 import net.minecraft.client.entity.player.LocalPlayer;
 import net.minecraft.client.entity.player.MultiplayerLocalPlayer;
 import net.minecraft.client.gui.GuiBadJavaArch;
@@ -50,6 +53,7 @@ import net.minecraft.client.gui.GuiSleepSP;
 import net.minecraft.client.gui.MainMenuBackground;
 import net.minecraft.client.gui.modelviewer.GuiModelViewer;
 import net.minecraft.client.gui.popup.GuiPopup;
+import net.minecraft.client.gui.toasts.GuiHudToasts;
 import net.minecraft.client.input.InputDevice;
 import net.minecraft.client.input.InputHandler;
 import net.minecraft.client.input.InputType;
@@ -85,11 +89,11 @@ import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.client.render.item.model.ItemModelDispatcher;
 import net.minecraft.client.render.shader.Shaders;
 import net.minecraft.client.render.shader.ShadersRenderer;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
+import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.client.render.texturepack.TexturePackList;
 import net.minecraft.client.render.window.GameWindow;
-import net.minecraft.client.render.window.GameWindowLWJGL2;
+import net.minecraft.client.render.window.GameWindowGLFW;
 import net.minecraft.client.sound.SoundEngine;
 import net.minecraft.client.util.debug.Debug;
 import net.minecraft.client.util.debug.DebugRender;
@@ -102,6 +106,7 @@ import net.minecraft.core.MinecraftError;
 import net.minecraft.core.MinecraftException;
 import net.minecraft.core.Timer;
 import net.minecraft.core.UnexpectedThrowable;
+import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.achievement.stat.StatList;
 import net.minecraft.core.achievement.stat.StatsCounter;
 import net.minecraft.core.block.BaseLeavesBlock;
@@ -132,37 +137,23 @@ import net.minecraft.core.util.phys.HitResult;
 import net.minecraft.core.util.phys.Vec3;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.PortalHandler;
+import net.minecraft.core.world.SpawnerMobs;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.biome.provider.BiomeProviderOverworld;
 import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.world.chunk.IChunkLoader;
 import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.save.DimensionData;
+import net.minecraft.core.world.save.ISaveConverter;
+import net.minecraft.core.world.save.ISaveFormat;
+import net.minecraft.core.world.save.LevelData;
+import net.minecraft.core.world.save.LevelStorage;
+import net.minecraft.core.world.save.SaveConverters;
+import net.minecraft.core.world.save.SaveFormats;
 import net.minecraft.core.world.save.mcregion.SaveFormat19134;
-import org.lwjgl.opengl.GL11;
-
-import javax.swing.*;
-import java.net.HttpURLConnection;
-import java.net.URL;
-
-import static net.minecraft.core.Global.CURRENT_SAVE_VERSION;
-import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST;
-import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
-import static org.lwjgl.opengl.GL11.glAlphaFunc;
-import static org.lwjgl.opengl.GL11.glClear;
-import static org.lwjgl.opengl.GL11.glClearColor;
-import static org.lwjgl.opengl.GL11.glClearDepth;
-import static org.lwjgl.opengl.GL11.glColor4f;
-import static org.lwjgl.opengl.GL11.glCullFace;
-import static org.lwjgl.opengl.GL11.glDepthFunc;
-import static org.lwjgl.opengl.GL11.glDisable;
-import static org.lwjgl.opengl.GL11.glEnable;
-import static org.lwjgl.opengl.GL11.glLoadIdentity;
-import static org.lwjgl.opengl.GL11.glMatrixMode;
-import static org.lwjgl.opengl.GL11.glOrtho;
-import static org.lwjgl.opengl.GL11.glShadeModel;
-import static org.lwjgl.opengl.GL11.glTranslatef;
-import static org.lwjgl.opengl.GL11.glViewport;
+import net.minecraft.core.world.type.WorldType;
+import net.minecraft.core.world.type.WorldTypeGroups;
 
 // Referenced classes of package net.minecraft.client:
 //            MinecraftApplet
@@ -424,11 +415,6 @@ public class Minecraft
 		resolution.getSetGuiScale();
 		resolution.update();
 		
-		Display.setVSyncEnabled(gameSettings.enableVsync.value);
-		if (!gameSettings.disableResize.value) {
-			gameWindow.setResizable(true);
-		}
-        
         OpenGLHelper.testCapabilities(this);
         
         if(Shaders.enableShaders) {
@@ -650,7 +636,7 @@ public class Minecraft
         glDisable(GL11.GL_FOG);
         glEnable(GL11.GL_ALPHA_TEST);
         glAlphaFunc(516, 0.1F);
-        Display.swapBuffers();
+        gameWindow.update();
     }
 
     public void drawMojangLogoVertices(int minX, int minY, int minU, int minV, int width, int height)
@@ -828,10 +814,7 @@ public class Minecraft
 			if(sndManager != null) {
 				sndManager.destroy();
 			}
-			Mouse.destroy();
-			Keyboard.destroy();
 		}finally {
-			Display.destroy();
 		}
 		System.gc();
 		if(!hasCrashed) {
@@ -873,7 +856,7 @@ public class Minecraft
                     AABB.initializePool();
                     Vec3.initializePool();
                     
-                    if(Display.isCloseRequested()) shutdown();
+                    if(gameWindow.shouldClose()) shutdown();
                     if(isGamePaused && theWorld != null && !(currentScreen instanceof GuiModelViewer))
                     {
                         float temp = timer.partialTicks;
@@ -936,7 +919,7 @@ public class Minecraft
                     }
 
                     Debug.change("displayupdate"); // 2
-                    Display.update();
+                    gameWindow.update();
                     
                     Debug.change("render"); // 2
                     Debug.push("post"); // 3
@@ -955,7 +938,7 @@ public class Minecraft
                     }
                     
                     if(gameSettings.pauseOnLostFocus.value) {
-                        if(!Display.isActive()) {
+                        if(!gameWindow.isFocused()) {
                             if(System.currentTimeMillis() > lastFocusTime + 250) {
                                 displayInGameMenu();
                             }
@@ -963,7 +946,7 @@ public class Minecraft
                             lastFocusTime = System.currentTimeMillis();
                         }
                     }
-                    sndManager.setMuted(gameSettings.muteOnLostFocus.value && !Display.isActive());
+                    sndManager.setMuted(gameSettings.muteOnLostFocus.value && !gameWindow.isFocused());
                     guiAchievementToast.render(timer.partialTicks);
 
                     Debug.change("post");  // 3
@@ -974,7 +957,7 @@ public class Minecraft
                     
                     Debug.change("misc");
                     
-                    if(Display.wasResized()) {
+                    if(gameWindow.wasResized()) {
                         resize();
                     }
                     OpenGLHelper.checkError("post render");
@@ -1087,7 +1070,7 @@ public class Minecraft
 
     public void setIngameFocus()
     {
-        if(!Display.isActive())
+        if(!gameWindow.isFocused())
         {
             return;
         }
@@ -2490,7 +2473,7 @@ public class Minecraft
     {
         boolean flag = false;
         String sessionUsername = username;
-        GameWindow gameWindow = new GameWindowLWJGL2();
+        GameWindow gameWindow = new GameWindowGLFW();
         Minecraft mc = new Minecraft(gameWindow);
         Thread thread = new Thread(mc, "Client-Main");
         thread.setPriority(10);
diff --git a/src/main/java/net/minecraft/client/MinecraftApplet.java b/src/main/java/net/minecraft/client/MinecraftApplet.java
index 59f2c09b7..9eac7fd98 100644
--- a/src/main/java/net/minecraft/client/MinecraftApplet.java
+++ b/src/main/java/net/minecraft/client/MinecraftApplet.java
@@ -1,82 +1,12 @@
 package net.minecraft.client;
 
 import java.applet.Applet;
-import java.awt.BorderLayout;
-import java.awt.Canvas;
-import java.awt.Graphics;
-
-import net.minecraft.client.render.window.GameWindow;
-import net.minecraft.client.render.window.GameWindowApplet;
-import net.minecraft.core.player.Session;
 
 @SuppressWarnings("serial")
 public class MinecraftApplet extends Applet {
 	
-	/*
-	 * #####  #####  #####  #####
-	 * #        #    #   #  #   #
-	 * #####    #    #   #  #####
-	 *     #    #    #   #  #
-	 * #####    #    #####  #
-	 * 
-	 * Do not add any fields to this class, or babric will not work!
-	 */
-	
-	private Canvas minecraftCanvas = new MinecraftCanvas();
-	private Minecraft mc;
-	private Thread minecraftThread;
-	
-	@Override
-	public void init() {
-		String username = getParameter("username");
-		String sessionid = getParameter("sessionid");
-		
-		if(username == null) username = "Player";
-		if(sessionid == null) sessionid = "-";
-		
-		GameWindow window = new GameWindowApplet(this);
-		
-		mc = new Minecraft(window);
-		mc.session = new Session(username, sessionid);
-		
-		setLayout(new BorderLayout());
-		add(minecraftCanvas, "Center");
-		minecraftCanvas.setFocusable(true);
-		validate();
-	}
-	
-	public Canvas getCanvas() {
-		return minecraftCanvas;
-	}
-	
-	public void startMainThread() {
-		System.out.println("Start Main Thread!");
-		if(minecraftThread != null) {
-			return;
-		}
-		
-		minecraftThread = new Thread(mc, "Minecraft main thread");
-		minecraftThread.start();
-	}
-	
-	class MinecraftCanvas extends Canvas {
-		
-		@Override
-		public synchronized void addNotify() {
-			super.addNotify();
-			startMainThread();
-		}
-		
-		@Override
-		public synchronized void removeNotify() {
-			super.removeNotify();
-		}
-		
-		@Override
-		public void paint(Graphics g) {
-			super.paint(g);
-		}
-		
+	public MinecraftApplet() {
+		throw new RuntimeException("Applet wrapper is not supported!");
 	}
 	
 }
diff --git a/src/main/java/net/minecraft/client/gui/options/components/FramerateOptionComponent.java b/src/main/java/net/minecraft/client/gui/options/components/FramerateOptionComponent.java
index 407bde2c9..cd0b246c4 100644
--- a/src/main/java/net/minecraft/client/gui/options/components/FramerateOptionComponent.java
+++ b/src/main/java/net/minecraft/client/gui/options/components/FramerateOptionComponent.java
@@ -2,7 +2,7 @@ package net.minecraft.client.gui.options.components;
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.option.RangeOption;
-import net.minecraft.client.render.window.GameWindowLWJGL2;
+import net.minecraft.client.render.window.GameWindowGLFW;
 
 public class FramerateOptionComponent extends ToggleableOptionComponent<Integer>{
     public FramerateOptionComponent(RangeOption option) {
@@ -11,8 +11,8 @@ public class FramerateOptionComponent extends ToggleableOptionComponent<Integer>
     @Override
     protected void renderButton(int x, int y, int relativeButtonX, int relativeButtonY, int buttonWidth, int buttonHeight, int relativeMouseX, int relativeMouseY)
     {
-        if (mc.gameSettings.enableVsync.value && mc.gameWindow instanceof GameWindowLWJGL2){
-            slider.sliderValue = ((GameWindowLWJGL2) mc.gameWindow).defaultDisplayMode.getFrequency();
+        if (mc.gameSettings.enableVsync.value && mc.gameWindow instanceof GameWindowGLFW) {
+        	slider.sliderValue = mc.gameWindow.getFrequency();
             slider.displayString = this.option.getDisplayStringValue();
             slider.enabled = false;
         }else {
@@ -33,8 +33,8 @@ public class FramerateOptionComponent extends ToggleableOptionComponent<Integer>
     @Override
     public void init(Minecraft mc){
         slider.sliderValue = option.getValueIndex();
-        if (mc.gameSettings.enableVsync.value && mc.gameWindow instanceof GameWindowLWJGL2){
-            slider.sliderValue = ((GameWindowLWJGL2) mc.gameWindow).defaultDisplayMode.getFrequency();
+        if (mc.gameSettings.enableVsync.value && mc.gameWindow instanceof GameWindowGLFW) {
+            slider.sliderValue = mc.gameWindow.getFrequency();
             slider.enabled = false;
         }
         this.slider.displayString = this.option.getDisplayStringValue();
diff --git a/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java b/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
index a5bd35a0e..246088f51 100644
--- a/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
+++ b/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
@@ -269,7 +269,6 @@ public abstract class OptionsPages
             .withComponent(new BooleanOptionComponent(mc.gameSettings.showItemDebugInfo))
             .withComponent(new BooleanOptionComponent(mc.gameSettings.disableJInput))
             .withComponent(new BooleanOptionComponent(mc.gameSettings.disableCrashHandler))
-            .withComponent(new BooleanOptionComponent(mc.gameSettings.disableResize))
             .withComponent(new BooleanOptionComponent(mc.gameSettings.startInFullscreen))
             .withComponent(new BooleanOptionComponent(mc.gameSettings.disableShaders))
             .withComponent(new BooleanOptionComponent(mc.gameSettings.loadAllSounds))
diff --git a/src/main/java/net/minecraft/client/input/InputHandler.java b/src/main/java/net/minecraft/client/input/InputHandler.java
index cb36ff0fc..473e3a096 100644
--- a/src/main/java/net/minecraft/client/input/InputHandler.java
+++ b/src/main/java/net/minecraft/client/input/InputHandler.java
@@ -1,13 +1,11 @@
 package net.minecraft.client.input;
 
-import net.minecraft.client.input.glfw.GlfwGamepad;
-import net.minecraft.client.input.glfw.GlfwJoystick;
 import org.lwjgl.glfw.GLFW;
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.input.Mouse;
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.input.controller.ControllerInput;
+import net.minecraft.client.input.glfw.GlfwGamepad;
+import net.minecraft.client.input.glfw.GlfwJoystick;
 
 public abstract class InputHandler {
 	private static Minecraft minecraft;
@@ -15,10 +13,7 @@ public abstract class InputHandler {
 	
 	public static void init(Minecraft minecraft) throws Exception{
 		InputHandler.minecraft = minecraft;
-    	System.out.println("Creating Keyboard & Mouse");
-    	Keyboard.create();
-    	Mouse.create();
-        
+		
         if(!minecraft.gameSettings.disableJInput.value) {
         	try {
         		initJInput(minecraft);
diff --git a/src/main/java/net/minecraft/client/option/GameSettings.java b/src/main/java/net/minecraft/client/option/GameSettings.java
index 088b94af0..9a34f85c1 100644
--- a/src/main/java/net/minecraft/client/option/GameSettings.java
+++ b/src/main/java/net/minecraft/client/option/GameSettings.java
@@ -10,8 +10,6 @@ import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.lwjgl.opengl.Display;
-
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.discord.RichPresenceHandlerThread;
 import net.minecraft.client.gui.hud.HudComponents;
@@ -23,7 +21,6 @@ import net.minecraft.client.option.enums.MipmapType;
 import net.minecraft.client.option.enums.RenderDistance;
 import net.minecraft.client.option.enums.RenderScale;
 import net.minecraft.client.option.enums.TooltipStyle;
-import net.minecraft.client.render.window.GameWindowLWJGL2;
 import net.minecraft.core.enums.PlacementMode;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.sound.SoundCategory;
@@ -121,7 +118,6 @@ public class GameSettings {
 	public FloatOption colorCorrection = new FloatOption(this, "colorCorrection", 0.5f);
 	public BooleanOption sneakToggle = new BooleanOption(this, "sneakToggle", false);
 	public FloatOption autosaveTimer = new FloatOption(this, "autosaveTimer", 0.04166666666F);
-	public BooleanOption disableResize = new BooleanOption(this, "disableResize", false);
 	public BooleanOption enableItemDragging = new BooleanOption(this, "enableItemDragging", true);
 	public RangeOption bloom = new RangeOption(this, "bloom", 0, 3);
 	public EnumOption<RenderScale> renderScale = new EnumOption<>(this, "renderScale", RenderScale.class, RenderScale.SCALE_100);
@@ -274,9 +270,6 @@ public class GameSettings {
 	public String getDisplayString(Option<?> option) {
 		if (option == null) return "";
 		I18n trans = I18n.getInstance();
-		if(option == borderlessFullscreen && !mc.gameWindow.isBorderlessFullscreenSupported()) {
-			return trans.translateKey("options.borderlessFullscreen.unavailable");
-		}
 		if (option instanceof FloatOption) {
 			FloatOption floatOption = (FloatOption) option;
 			float value = floatOption.value;
@@ -353,9 +346,7 @@ public class GameSettings {
 			int value = customFpsLimit.value;
 			int maxValue = 240;
 			if (enableVsync.value){
-				if(mc.gameWindow instanceof GameWindowLWJGL2){
-					return String.valueOf(((GameWindowLWJGL2) mc.gameWindow).defaultDisplayMode.getFrequency());
-				}
+				return String.valueOf(mc.gameWindow.getFrequency());
 			}
 			if(value > maxValue){
 				customFpsLimit.set(maxValue);
@@ -419,7 +410,7 @@ public class GameSettings {
 				mc.theWorld.setDifficulty(difficulty.value, false);
 			}
 		}
-		if(option == enableVsync) Display.setVSyncEnabled(enableVsync.value);
+		if(option == enableVsync) mc.gameWindow.setVsync(enableVsync.value);
 		if(option == fancyGraphics) mc.renderGlobal.loadRenderers();
 		if(option == ambientOcclusion) mc.renderGlobal.loadRenderers();
 		if(option == advancedOpenGL) mc.renderGlobal.loadRenderers();
@@ -433,7 +424,8 @@ public class GameSettings {
 			mc.renderEngine.refreshTexturesAndDisplayErrors();
 			mc.renderEngine.updateDynamicTextures(false);
 		}
-		if(option == fullscreen || option == borderlessFullscreen) mc.gameWindow.updateWindowState();
+		if(option == fullscreen) mc.gameWindow.updateWindowState();
+		if(option == borderlessFullscreen && fullscreen.value) mc.gameWindow.updateWindowState();
 		if(option == guiScale) {
 			int max = mc.resolution.getMaxScale();
 			guiScale.value = (guiScale.value + max) % max;
diff --git a/src/main/java/net/minecraft/client/render/ChunkRenderer.java b/src/main/java/net/minecraft/client/render/ChunkRenderer.java
index 80f657931..0fdef71bc 100644
--- a/src/main/java/net/minecraft/client/render/ChunkRenderer.java
+++ b/src/main/java/net/minecraft/client/render/ChunkRenderer.java
@@ -157,7 +157,7 @@ public class ChunkRenderer
                             tessellator.setTranslation(-this.x, -this.y, -this.z);
                             
                             if(LightmapHelper.isLightmapEnabled()) {
-                            	// Make sure it's active
+                            	// Make sure it's active to prevent crash if a model doesnt enable it
                             	tessellator.setLightmapCoord(LightmapHelper.getLightmapCoord(15, 15));
                             }
                         }
diff --git a/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java b/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java
index 63d489866..879719c49 100644
--- a/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java
+++ b/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java
@@ -1,21 +1,20 @@
 package net.minecraft.client.render;
 
-import net.minecraft.client.Minecraft;
-
 import static org.lwjgl.opengl.GL11.*;
 
+import java.util.List;
+import java.util.Random;
+
+import org.lwjgl.opengl.GL11;
+
+import net.minecraft.client.Minecraft;
 import net.minecraft.client.option.KeyBinding;
 import net.minecraft.client.render.tessellator.Tessellator;
+import net.minecraft.core.MinecraftError;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.command.TextFormatting;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.ProgressListener;
-import net.minecraft.core.MinecraftError;
-import org.lwjgl.opengl.Display;
-import org.lwjgl.opengl.GL11;
-
-import java.util.List;
-import java.util.Random;
 
 public class LoadingScreenRenderer
     implements ProgressListener
@@ -216,11 +215,6 @@ public class LoadingScreenRenderer
         
         minecraft.renderer.endRenderGame(1.0f);
         
-        Display.update();
-        try
-        {
-            Thread.yield();
-        }
-        catch(Exception ignored) { }
+        minecraft.gameWindow.update();
     }
 }
diff --git a/src/main/java/net/minecraft/client/render/RenderGlobal.java b/src/main/java/net/minecraft/client/render/RenderGlobal.java
index 1fdd7fd59..0289d6990 100644
--- a/src/main/java/net/minecraft/client/render/RenderGlobal.java
+++ b/src/main/java/net/minecraft/client/render/RenderGlobal.java
@@ -1248,6 +1248,10 @@ public class RenderGlobal
             tessellator.startDrawingQuads();
             tessellator.setTranslation(-x, -y, -z);
             tessellator.lockColor();
+            if(LightmapHelper.isLightmapEnabled()) {
+            	// Make sure it's active to prevent crash if a model doesnt enable it
+            	tessellator.setLightmapCoord(LightmapHelper.getLightmapCoord(15, 0));
+            }
             BlockModel.setRenderBlocks(globalRenderBlocks);
             BlockModelDispatcher.getInstance().getDispatch(block).renderWithOverrideTexture(tessellator, hitResult.x, hitResult.y, hitResult.z, breakingAnimation[MathHelper.clamp((int)(damagePartialTime * 10F), 0, breakingAnimation.length)] );
             tessellator.draw();
diff --git a/src/main/java/net/minecraft/client/render/WorldRenderer.java b/src/main/java/net/minecraft/client/render/WorldRenderer.java
index 126cee60b..eccac0135 100644
--- a/src/main/java/net/minecraft/client/render/WorldRenderer.java
+++ b/src/main/java/net/minecraft/client/render/WorldRenderer.java
@@ -31,7 +31,6 @@ import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.client.render.culling.Frustum;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
-import net.minecraft.client.render.window.GameWindowLWJGL2;
 import net.minecraft.client.util.debug.Debug;
 import net.minecraft.client.world.chunk.provider.ChunkProviderStatic;
 import net.minecraft.core.util.phys.HitResult;
@@ -495,9 +494,7 @@ public class WorldRenderer
         int c = 200;
         if(mc.gameSettings.enableVsync.value) // VSync
         {
-            if(mc.gameWindow instanceof GameWindowLWJGL2){
-                c = ((GameWindowLWJGL2) mc.gameWindow).defaultDisplayMode.getFrequency() + 20; // Cap fps when minimized
-            }
+        	c = mc.gameWindow.getFrequency(); // Cap fps when minimized
         } else {
             c = mc.gameSettings.customFpsLimit.value;
         }
diff --git a/src/main/java/net/minecraft/client/render/window/GameWindow.java b/src/main/java/net/minecraft/client/render/window/GameWindow.java
index d2d02b3ad..74e81f5e6 100644
--- a/src/main/java/net/minecraft/client/render/window/GameWindow.java
+++ b/src/main/java/net/minecraft/client/render/window/GameWindow.java
@@ -1,22 +1,32 @@
 package net.minecraft.client.render.window;
 
-import org.lwjgl.LWJGLException;
-
 import net.minecraft.client.Minecraft;
 import net.minecraft.core.UnexpectedThrowable;
 
 public interface GameWindow {
 	
-	public void init(Minecraft minecraft) throws LWJGLException;
+	public void init(Minecraft minecraft);
 	
 	public void toggleFullscreen();
 	
 	public void updateWindowState();
 	
-	public void setResizable(boolean resizable);
+	public void displayCrashReport(UnexpectedThrowable unexpectedThrowable, int cause);
 	
-	public boolean isBorderlessFullscreenSupported();
+	public int getFrequency();
 	
-	public void displayCrashReport(UnexpectedThrowable unexpectedThrowable, int cause);
+	public void update();
+	
+	public boolean shouldClose();
+	
+	public int getWidth();
+	
+	public int getHeight();
+	
+	public boolean isFocused();
+	
+	public boolean wasResized();
+	
+	public void setVsync(boolean vsync);
 
 }
diff --git a/src/main/java/net/minecraft/client/render/window/GameWindowApplet.java b/src/main/java/net/minecraft/client/render/window/GameWindowApplet.java
deleted file mode 100644
index fc3cbc6c7..000000000
--- a/src/main/java/net/minecraft/client/render/window/GameWindowApplet.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package net.minecraft.client.render.window;
-
-import java.awt.BorderLayout;
-import java.awt.Canvas;
-import java.awt.Color;
-import java.awt.Graphics;
-
-import org.lwjgl.LWJGLException;
-import org.lwjgl.opengl.Display;
-import org.lwjgl.opengl.PixelFormat;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.MinecraftApplet;
-import net.minecraft.client.render.PanelCrashReport;
-import net.minecraft.core.UnexpectedThrowable;
-
-public class GameWindowApplet implements GameWindow {
-
-	private MinecraftApplet applet;
-	private Minecraft mc;
-	private Canvas canvas;
-	
-	public GameWindowApplet(MinecraftApplet minecraftApplet) {
-		this.applet = minecraftApplet;
-	}
-	
-	@Override
-	public void init(Minecraft minecraft) throws LWJGLException {
-		this.mc = minecraft;
-		
-		canvas = applet.getCanvas();
-		
-		Graphics g = canvas.getGraphics();
-		g.setColor(Color.black);
-		g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
-		g.dispose();
-		
-		Display.setParent(canvas);
-		
-		try {
-	        //Bit Depth Fix
-			Display.create(new PixelFormat().withDepthBits(24));
-		}catch (Exception e) {
-			e.printStackTrace();
-			
-			try {
-				Thread.sleep(1000);
-			}catch (Exception ex) {}
-			
-			Display.create();
-		}
-	}
-
-	@Override
-	public boolean isBorderlessFullscreenSupported() {
-		return false;
-	}
-
-	@Override
-	public void setResizable(boolean resizable) {
-		
-	}
-
-	@Override
-	public void toggleFullscreen() {
-		mc.gameSettings.fullscreen.toggle();
-		updateWindowState();
-	}
-
-	@Override
-	public void updateWindowState() {
-		boolean fullscreen = mc.gameSettings.fullscreen.value;
-		try {
-			if(fullscreen) {
-				Display.setDisplayMode(Display.getDesktopDisplayMode());
-				Display.setFullscreen(true);
-			}else {
-				Display.setFullscreen(false);
-			}
-			
-			mc.resize();
-		}catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-	
-	@Override
-	public void displayCrashReport(UnexpectedThrowable unexpectedThrowable, int cause) {
-		applet.removeAll();
-		applet.setLayout(new BorderLayout());
-		applet.add(new PanelCrashReport(mc, unexpectedThrowable, cause), "Center");
-		applet.validate();
-	}
-
-}
diff --git a/src/main/java/net/minecraft/client/render/window/GameWindowGLFW.java b/src/main/java/net/minecraft/client/render/window/GameWindowGLFW.java
new file mode 100644
index 000000000..46eb62b1a
--- /dev/null
+++ b/src/main/java/net/minecraft/client/render/window/GameWindowGLFW.java
@@ -0,0 +1,279 @@
+package net.minecraft.client.render.window;
+
+import static org.lwjgl.glfw.GLFW.*;
+
+import java.awt.Panel;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javax.swing.JFrame;
+
+import org.lwjgl.PointerBuffer;
+import org.lwjgl.glfw.GLFWVidMode;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.input.Mouse;
+import org.lwjgl.opengl.Display;
+import org.lwjgl.opengl.GL;
+
+import com.github.zarzelcow.legacylwjgl3.implementation.glfw.GLFWKeyboardImplementation;
+import com.github.zarzelcow.legacylwjgl3.implementation.glfw.GLFWMouseImplementation;
+import com.github.zarzelcow.legacylwjgl3.implementation.input.CombinedInputImplementation;
+import com.github.zarzelcow.legacylwjgl3.implementation.input.InputImplementation;
+
+import net.minecraft.client.GameResolution;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.render.PanelCrashReport;
+import net.minecraft.core.UnexpectedThrowable;
+
+public class GameWindowGLFW implements GameWindow {
+	
+	public Minecraft mc;
+	
+	public long window;
+	
+	public int width = GameResolution.defaultWidth;
+	public int height = GameResolution.defaultHeight;
+	
+	private boolean wasResized = false;
+	private boolean isFullscreen = false;
+	
+	private int windowPosX;
+	private int windowPosY;
+	private int windowWidth;
+	private int windowHeight;
+	
+	@Override
+	public void init(Minecraft minecraft) {
+		mc = minecraft;
+		
+		System.out.println("GLFW Init");
+		if(!glfwInit()) {
+			throw new RuntimeException("GLFW Init failed!");
+		}
+		
+		// Set window hints
+		glfwWindowHint(GLFW_RESIZABLE, 1);
+		glfwWindowHint(GLFW_VISIBLE, 0);
+		glfwWindowHint(GLFW_AUTO_ICONIFY, 1);
+		glfwWindowHint(GLFW_DECORATED, 1);
+		
+		// Create window
+		window = glfwCreateWindow(width, height, "Minecraft", 0, 0);
+		
+		// Center window
+		MonitorInfo monitor = new MonitorInfo(glfwGetPrimaryMonitor());
+		glfwSetWindowPos(window, (monitor.width - width) / 2, (monitor.height - height) / 2);
+		
+		// Setup callbacks
+		glfwSetWindowSizeCallback(window, (window, width, height) -> {
+			this.width = Math.max(1, width);
+			this.height = Math.max(1, height);
+			wasResized = true;
+		});
+		
+		// Show window
+		glfwShowWindow(window);
+		
+		// OpenGL setup
+		glfwMakeContextCurrent(window);
+		GL.createCapabilities();
+
+		// Input setup
+		Display.setWindow(this);
+		
+		Method createKeyboard = null;
+		Method createMouse = null;
+		
+		try {
+			createKeyboard = Keyboard.class.getDeclaredMethod("create", InputImplementation.class);
+			createKeyboard.setAccessible(true);
+			
+			createMouse = Mouse.class.getDeclaredMethod("create", InputImplementation.class);
+			createMouse.setAccessible(true);
+			
+			GLFWKeyboardImplementation keyboardImplementation = new GLFWKeyboardImplementation();
+			GLFWMouseImplementation mouseImplementation = new GLFWMouseImplementation();
+			
+			CombinedInputImplementation inputImplementation = new CombinedInputImplementation(keyboardImplementation, mouseImplementation);
+			
+			createKeyboard.invoke(null, inputImplementation);
+			createMouse.invoke(null, inputImplementation);
+		}catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException e) {
+			// only catch reflection errors
+			throw new RuntimeException(e);
+		}
+		
+		// Set Vsync
+		setVsync(mc.gameSettings.enableVsync.value);
+	}
+
+	@Override
+	public void toggleFullscreen() {
+		mc.gameSettings.fullscreen.value = !mc.gameSettings.fullscreen.value;
+		
+		updateWindowState();
+	}
+
+	@Override
+	public void updateWindowState() {
+		if(!isFullscreen) {
+			int[] x = new int[1];
+			int[] y = new int[1];
+			glfwGetWindowPos(window, x, y);
+			
+			int[] w = new int[1];
+			int[] h = new int[1];
+			glfwGetWindowSize(window, w, h);
+			
+			this.windowPosX = x[0];
+			this.windowPosY = y[0];
+			this.windowWidth = w[0];
+			this.windowHeight = h[0];
+		}
+		
+		boolean fullscreen = mc.gameSettings.fullscreen.value;
+		boolean borderless = mc.gameSettings.borderlessFullscreen.value;
+		
+		glfwHideWindow(window);
+		
+		if(fullscreen && !borderless) {
+			System.out.println("Change to Fullscreen");
+			int x = windowPosX + windowWidth / 2;
+			int y = windowPosY + windowHeight / 2;
+			MonitorInfo monitor = getMonitorAt(x, y);
+			
+			// Enable GLFW Fullscreen
+			glfwSetWindowMonitor(window, monitor.handle, monitor.posX, monitor.posY, monitor.width, monitor.height, monitor.refreshRate);
+			isFullscreen = true;
+		}else {
+			// Disable GLFW Fullscreen
+			glfwSetWindowMonitor(window, 0, windowPosX, windowPosY, windowWidth, windowHeight, 0);
+			
+			if(fullscreen && borderless) {
+				System.out.println("Change to Borderless Fullscreen");
+				int x = windowPosX + windowWidth / 2;
+				int y = windowPosY + windowHeight / 2;
+				MonitorInfo monitor = getMonitorAt(x, y);
+				
+				glfwSetWindowAttrib(window, GLFW_DECORATED, 0);
+				glfwSetWindowPos(window, monitor.posX, monitor.posY);
+				glfwSetWindowSize(window, monitor.width, monitor.height);
+				isFullscreen = true;
+			}else {
+				System.out.println("Change to Windowed");
+				glfwSetWindowAttrib(window, GLFW_DECORATED, 1);
+				isFullscreen = false;
+			}
+		}
+		
+		glfwShowWindow(window);
+	}
+	
+	public MonitorInfo getMonitorAt(int x, int y) {
+		PointerBuffer monitorPointers = glfwGetMonitors();
+		
+		for(int i = monitorPointers.position(); i < monitorPointers.limit(); i++) {
+			long monitor = monitorPointers.get(i);
+			
+			MonitorInfo info = new MonitorInfo(monitor);
+			if(x >= info.posX && y >= info.posY && x < info.posX + info.width && y < info.posY + info.height) {
+				return info;
+			}
+		}
+		
+		return new MonitorInfo(glfwGetPrimaryMonitor());
+	}
+	
+	@Override
+	public void displayCrashReport(UnexpectedThrowable unexpectedThrowable, int cause) {
+		JFrame frame = new JFrame();
+		Panel panel = new PanelCrashReport(mc, unexpectedThrowable, cause);
+
+		panel.setPreferredSize(new java.awt.Dimension(1280, 720));
+
+		frame.add(panel);
+		frame.pack();
+		frame.setLocationRelativeTo(null);
+		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+		frame.setVisible(true);
+	}
+
+	@Override
+	public int getFrequency() {
+		return glfwGetVideoMode(window).refreshRate();
+	}
+	
+	@Override
+	public void update() {
+		glfwPollEvents();
+		
+		Keyboard.poll();
+		Mouse.poll();
+		
+		glfwSwapBuffers(window);
+	}
+
+	@Override
+	public boolean shouldClose() {
+		return glfwWindowShouldClose(window);
+	}
+
+	@Override
+	public int getWidth() {
+		return width;
+	}
+
+	@Override
+	public int getHeight() {
+		return height;
+	}
+
+	@Override
+	public boolean isFocused() {
+		return true;
+	}
+
+	@Override
+	public boolean wasResized() {
+		if(wasResized) {
+			wasResized = false;
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public void setVsync(boolean vsync) {
+		if(vsync) {
+			glfwSwapInterval(1);	
+		}else {
+			glfwSwapInterval(0);
+		}
+	}
+	
+	class MonitorInfo {
+		
+		public final long handle;
+		public final int posX;
+		public final int posY;
+		public final int width;
+		public final int height;
+		public final int refreshRate;
+		
+		public MonitorInfo(long monitor) {
+			this.handle = monitor;
+			
+			GLFWVidMode vidmode = glfwGetVideoMode(monitor);
+			
+			int[] x = new int[1];
+			int[] y = new int[1];
+			glfwGetMonitorPos(monitor, x, y);
+			posX = x[0];
+			posY = y[0];
+			
+			width = vidmode.width();
+			height = vidmode.height();
+			refreshRate = vidmode.refreshRate();
+		}
+	}
+}
diff --git a/src/main/java/net/minecraft/client/render/window/GameWindowLWJGL2.java b/src/main/java/net/minecraft/client/render/window/GameWindowLWJGL2.java
deleted file mode 100644
index 778539a67..000000000
--- a/src/main/java/net/minecraft/client/render/window/GameWindowLWJGL2.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package net.minecraft.client.render.window;
-
-import net.minecraft.client.FullscreenHelper;
-import net.minecraft.client.GameResolution;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.render.PanelCrashReport;
-import net.minecraft.core.Global;
-import net.minecraft.core.UnexpectedThrowable;
-import net.minecraft.core.enums.EnumOS;
-
-import org.lwjgl.LWJGLException;
-import org.lwjgl.opengl.Display;
-import org.lwjgl.opengl.DisplayMode;
-import org.lwjgl.opengl.PixelFormat;
-
-import javax.imageio.ImageIO;
-import javax.swing.JFrame;
-
-import java.awt.Panel;
-import java.awt.image.BufferedImage;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-
-public class GameWindowLWJGL2 implements GameWindow {
-	
-	public Minecraft mc;
-    public FullscreenHelper fullscreenHelper;
-	public DisplayMode defaultDisplayMode;
-    
-    public GameWindowLWJGL2() {
-	}
-    
-	@Override
-	public void init(Minecraft minecraft) throws LWJGLException {
-		this.mc = minecraft;
-		this.fullscreenHelper = new FullscreenHelper(minecraft);
-		this.defaultDisplayMode = Display.getDisplayMode();
-		
-		if(Minecraft.getOs() == EnumOS.macos && minecraft.gameSettings.osxFullscreenModeAPI.value) {
-			System.setProperty("org.lwjgl.opengl.Display.enableOSXFullscreenModeAPI", "true");
-		}
-		
-		Display.setDisplayMode(new DisplayMode(GameResolution.defaultWidth, GameResolution.defaultHeight));
-		Display.setTitle("Better than Adventure! " + Global.VERSION);
-      
-        setIcon();
-        
-        //Bit Depth Fix
-        try {
-            PixelFormat pixelformat = new PixelFormat();
-            pixelformat = pixelformat.withDepthBits(24);
-            Display.create(pixelformat);
-        } catch(LWJGLException lwjglexception) {
-            lwjglexception.printStackTrace();
-            try
-            {
-                Thread.sleep(1000L);
-            }
-            catch(InterruptedException ignored) { }
-            Display.create(new PixelFormat());
-        }
-	}
-
-	@Override
-	public void toggleFullscreen() {
-		fullscreenHelper.toggleFullscreen();
-	}
-
-	@Override
-	public void updateWindowState() {
-		fullscreenHelper.updateWindowState();
-	}
-
-	@Override
-	public boolean isBorderlessFullscreenSupported() {
-		return true;
-	}
-    
-    private void setIcon() {
-    	int[] resolutions = new int[] {16, 32, 64, 128, 256};
-    	ByteBuffer[] buffers = new ByteBuffer[resolutions.length];
-    	
-    	for(int i=0; i < resolutions.length; i++) {
-    		int resolution = resolutions[i];
-    		
-    		String texturePath = "/icon/" + resolution + ".png";
-    		InputStream stream = null;
-    		BufferedImage image;
-    		try {
-				stream = getClass().getResourceAsStream(texturePath);
-				image = ImageIO.read(stream);
-    		}catch (Exception e) {
-    			e.printStackTrace();
-    			return;
-			}finally {
-				try {
-					stream.close();
-				}catch (Exception e) {}
-			}
-    		
-    		if(image.getWidth() != resolution || image.getHeight() != resolution) {
-    			System.out.println("Icon '" + texturePath + "' has the wrong resolution. Expected " + resolution + " x " + resolution + ", but got " + image.getWidth() + "x " + image.getHeight() + "!");
-    			return;
-    		}
-    		
-    		ByteBuffer buffer = ByteBuffer.allocate(resolution * resolution * 4);
-    		buffer.position(0).limit(buffer.capacity());
-    		for(int y = 0; y < resolution; y++) {
-    			for(int x = 0; x < resolution; x++) {
-    				int color = image.getRGB(x, y);
-
-    				int a = color >> 24 & 0xFF;
-					int r = color >> 16 & 0xFF;
-					int g = color >>  8 & 0xFF;
-					int b = color >>  0 & 0xFF;
-					
-					buffer.put((byte) r);
-					buffer.put((byte) g);
-					buffer.put((byte) b);
-					buffer.put((byte) a);
-    			}
-    		}
-    		buffer.position(0);
-    		buffers[i] = buffer;
-    	}
-    	
-    	try{
-    		Display.setIcon(buffers);
-    	}catch (Exception e) {
-    		e.printStackTrace();
-		}
-    }
-
-	@Override
-	public void setResizable(boolean resizable) {
-		fullscreenHelper.setResizable();
-	}
-	
-	@Override
-	public void displayCrashReport(UnexpectedThrowable unexpectedThrowable, int cause) {
-		JFrame frame = new JFrame();
-		Panel panel = new PanelCrashReport(mc, unexpectedThrowable, cause);
-
-		panel.setPreferredSize(new java.awt.Dimension(1280, 720));
-
-		frame.add(panel);
-		frame.pack();
-		frame.setLocationRelativeTo(null);
-		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
-		frame.setVisible(true);
-	}
-
-}
diff --git a/src/main/java/net/minecraft/client/util/debug/DebugRender.java b/src/main/java/net/minecraft/client/util/debug/DebugRender.java
index ada5836f7..999f6a95c 100644
--- a/src/main/java/net/minecraft/client/util/debug/DebugRender.java
+++ b/src/main/java/net/minecraft/client/util/debug/DebugRender.java
@@ -2,11 +2,10 @@ package net.minecraft.client.util.debug;
 
 import static org.lwjgl.opengl.GL11.*;
 
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.render.window.GameWindowLWJGL2;
 import org.lwjgl.input.Keyboard;
 import org.lwjgl.opengl.Display;
 
+import net.minecraft.client.Minecraft;
 import net.minecraft.client.render.FontRenderer;
 import net.minecraft.client.render.tessellator.Tessellator;
 import net.minecraft.client.util.debug.Debug.Profiler;
@@ -183,9 +182,7 @@ public class DebugRender {
 			tessellator.setColorOpaque_I(0x00FF00);
 			int fps = 0;
 			if (mc.gameSettings.enableVsync.value){
-				if(mc.gameWindow instanceof GameWindowLWJGL2){
-					fps = ((GameWindowLWJGL2) mc.gameWindow).defaultDisplayMode.getFrequency(); // Cap fps when minimized
-				}
+				fps = mc.gameWindow.getFrequency(); // Cap fps when minimized
 			} else {
 				fps = mc.gameSettings.customFpsLimit.value;
 			}
diff --git a/src/main/java/org/lwjgl/opengl/Display.java b/src/main/java/org/lwjgl/opengl/Display.java
index 30ee29765..260bf6337 100644
--- a/src/main/java/org/lwjgl/opengl/Display.java
+++ b/src/main/java/org/lwjgl/opengl/Display.java
@@ -1,301 +1,32 @@
 package org.lwjgl.opengl;
 
-import org.lwjgl.BufferUtils;
-import org.lwjgl.LWJGLException;
-import org.lwjgl.glfw.*;
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.input.Mouse;
-
-import java.awt.*;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
+import net.minecraft.client.render.window.GameWindow;
+import net.minecraft.client.render.window.GameWindowGLFW;
 
 public abstract class Display {
-    private static String title = "";
-    private static long handle = -1;
-    private static boolean resizable = false;
-    private static DisplayMode displayMode = new DisplayMode(640, 480, 24, 60);
-    private static int width = 0;
-    private static int height = 0;
-    private static int xPos = 0;
-    private static int yPos = 0;
-    private static boolean windowResized = false;
-    private static GLFWWindowSizeCallback sizeCallback = null;
-    private static ByteBuffer[] cachedIcons = null;
-    private static Canvas parent = null;
-
-    public static void create() throws LWJGLException {
-        create(new PixelFormat());
-    }
-
-    public static long getHandle() {
-        return handle;
-    }
-
-    public static void create(PixelFormat pixel_format) throws LWJGLException {
-        GLFWErrorCallback.createPrint(System.err).set();
-        if (!GLFW.glfwInit()) {
-            throw new IllegalStateException("Unable to initialize GLFW");
-        }
-        GLFW.glfwDefaultWindowHints();
-        GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
-        GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, resizable ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE);
-        handle = GLFW.glfwCreateWindow(displayMode.getWidth(), displayMode.getHeight(), title, 0, 0);
-        width = displayMode.getWidth();
-        height = displayMode.getHeight();
-        GLFW.glfwMakeContextCurrent(handle);
-        GL.createCapabilities();
-        sizeCallback = GLFWWindowSizeCallback.create(Display::resizeCallback);
-        GLFW.glfwSetWindowSizeCallback(handle, sizeCallback);
-        Mouse.create();
-        Keyboard.create();
-        GLFW.glfwShowWindow(handle);
-        if (cachedIcons != null) {
-            setIcon(cachedIcons);
-        }
-    }
-
-    private static void resizeCallback(long window, int width, int height) {
-        if (window == handle) {
-            Display.width = width;
-            Display.height = height;
-            windowResized = true;
-        }
-    }
-
-    private static void destroyWindow() {
-        sizeCallback.free();
-        Mouse.destroy();
-        Keyboard.destroy();
-        GLFW.glfwDestroyWindow(handle);
-    }
-
-    public static void destroy() {
-        destroyWindow();
-        GLFW.glfwTerminate();
-        GLFW.glfwSetErrorCallback(null).free();
-    }
-
-    public static DisplayMode[] getAvailableDisplayModes() {
-        long primaryMonitor = GLFW.glfwGetPrimaryMonitor();
-        if (primaryMonitor == 0) {
-            return new DisplayMode[0];
-        }
-        GLFWVidMode.Buffer videoModes = GLFW.glfwGetVideoModes(primaryMonitor);
-        if (videoModes == null) {
-            return new DisplayMode[0];
-        }
-
-        DisplayMode[] modes = new DisplayMode[videoModes.capacity()];
-        for (int i = 0; i < videoModes.capacity(); i++) {
-            GLFWVidMode videoMode = videoModes.get(i);
-            modes[i] = new DisplayMode(videoMode.width(), videoMode.height(), videoMode.redBits() + videoMode.greenBits() + videoMode.blueBits(), videoMode.refreshRate());
-        }
-        return modes;
-    }
-
-    public static DisplayMode getDesktopDisplayMode() {
-        GLFWVidMode videoMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
-        if (videoMode == null) {
-            DisplayMode[] displayModes = getAvailableDisplayModes();
-            if (displayModes.length == 0) {
-                return null;
-            }
-            DisplayMode largest = displayModes[0];
-            for (DisplayMode mode : displayModes) {
-                if (mode.getWidth() * mode.getHeight() > largest.getWidth() * largest.getHeight()) {
-                    largest = mode;
-                }
-            }
-
-            return largest;
-        } else {
-            return new DisplayMode(videoMode.width(), videoMode.height(), videoMode.redBits() + videoMode.greenBits() + videoMode.blueBits(), videoMode.refreshRate());
-        }
-    }
-
-    public static DisplayMode getDisplayMode() {
-        return displayMode;
-    }
-
-    public static int getHeight() {
-        return height;
-    }
-
-    public static Canvas getParent() {
-        return parent;
-    }
-
-    public static String getTitle() {
-        return title;
-    }
-
-    public static int getWidth() {
-        return width;
-    }
-
-    public static int getX() {
-        return xPos;
-    }
-
-    public static int getY() {
-        return yPos;
-    }
-
-    public static boolean isActive() {
-        return GLFW.glfwGetWindowAttrib(handle, GLFW.GLFW_FOCUSED) == GLFW.GLFW_TRUE;
-    }
-
-    public static boolean isCloseRequested() {
-        return GLFW.glfwWindowShouldClose(handle);
-    }
-
-    public static boolean isCreated() {
-        return handle != -1;
-    }
-
-    public static boolean isFullscreen() {
-        return GLFW.glfwGetWindowMonitor(handle) != 0;
-    }
-
-    public static boolean isResizable() {
-        return resizable;
-    }
-
-    public static boolean isVisible() {
-        return GLFW.glfwGetWindowAttrib(handle, GLFW.GLFW_VISIBLE) == GLFW.GLFW_TRUE;
-    }
-
-    public static void setDisplayMode(DisplayMode mode) throws LWJGLException {
-        displayMode = mode;
-        if (isCreated()) {
-            GLFW.glfwSetWindowSize(handle, mode.getWidth(), mode.getHeight());
-        }
-    }
-
-    public static void setDisplayModeAndFullscreen(DisplayMode mode) throws LWJGLException {
-        setDisplayMode(mode);
-        setFullscreen(true);
-    }
-
-    public static void setFullscreen(boolean fullscreen) throws LWJGLException {
-        try {
-            resizeCallback(handle, displayMode.getWidth(), displayMode.getHeight());
-            if (fullscreen) {
-                long monitor = GLFW.glfwGetPrimaryMonitor();
-
-                GLFW.glfwSetWindowMonitor(
-                    handle,
-                    monitor,
-                    0,
-                    0,
-                    getWidth(),
-                    getHeight(),
-                    displayMode.getFrequency()
-                );
-                xPos = displayMode.getWidth() / 2;
-                yPos = displayMode.getHeight() / 2;
-            } else {
-                xPos -= width / 2;
-                yPos -= height / 2;
-                GLFW.glfwSetWindowMonitor(
-                    handle,
-                    0L,
-                    xPos,
-                    yPos,
-                    getWidth(),
-                    getHeight(),
-                    -1
-                );
-            }
-            GLFW.glfwSetWindowSize(handle, getWidth(), getHeight());
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    public static int setIcon(ByteBuffer[] icons) {
-        if (isCreated()) {
-            GLFW.glfwSetWindowIcon(handle, iconsToGLFWBuffer(icons));
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-
-    private static ByteBuffer cloneByteBuffer(ByteBuffer original) {
-        ByteBuffer clone = BufferUtils.createByteBuffer(original.capacity());
-        int oldPosition = original.position();
-        clone.put(original);
-        ((Buffer) original).position(oldPosition);
-        ((Buffer) clone).flip();
-
-        return clone;
-    }
-
-    private static GLFWImage.Buffer iconsToGLFWBuffer(ByteBuffer[] icons) {
-        GLFWImage.Buffer buffer = GLFWImage.create(icons.length);
-        for (ByteBuffer icon : icons) {
-            int size = icon.limit() / 4;
-            int dimension = (int)(Math.sqrt(size));
-            GLFWImage image = GLFWImage.malloc();
-            buffer.put(image.set(dimension, dimension, icon));
-        }
-        buffer.flip();
-        return buffer;
-    }
-
-    public static void setLocation(int x, int y) {
-        xPos = x;
-        yPos = y;
-        if (isCreated()) {
-            GLFW.glfwSetWindowPos(handle, x, y);
-        }
-    }
-
-    public static void setParent(Canvas parent) throws LWJGLException {
-        Display.parent = parent;
-    }
-
-    public static void setResizable(boolean resizable) {
-        Display.resizable = resizable;
-        if (isCreated()) {
-            GLFW.glfwSetWindowAttrib(handle, GLFW.GLFW_RESIZABLE, resizable ? GLFW.GLFW_TRUE : GLFW.GLFW_FALSE);
-        }
-    }
-
-    public static void setSwapInterval(int interval) {
-        GLFW.glfwSwapInterval(interval);
-    }
-
-    public static void setTitle(String title) {
-        Display.title = title;
-        if (isCreated()) {
-            GLFW.glfwSetWindowTitle(handle, title);
-        }
-    }
-
-    public static void setVSyncEnabled(boolean sync) {
-        setSwapInterval(sync ? 1 : 0);
-    }
-
-    public static void swapBuffers() throws LWJGLException {
-        GLFW.glfwSwapBuffers(handle);
-    }
-
-    public static void update() {
-        windowResized = false;
-        GLFW.glfwPollEvents();
-        if (Mouse.isCreated()) {
-            Mouse.poll();
-        }
-        if (Keyboard.isCreated()) {
-            Keyboard.poll();
-        }
-        GLFW.glfwSwapBuffers(handle);
-    }
+	
+	private static GameWindowGLFW window;
+	
+	public static void setWindow(GameWindowGLFW window) {
+		Display.window = window;
+	}
+	
+	public static GameWindow getWindow() {
+		return window;
+	}
+	
+	// These are used in legacy-lwjgl's input implementation
+	
+	public static int getWidth() {
+		return window.getWidth();
+	}
+	
+	public static int getHeight() {
+		return window.getHeight();
+	}
+	
+	public static long getHandle() {
+		return window.window;
+	}
 
-    public static boolean wasResized() {
-        return windowResized;
-    }
 }
